Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../server/api/.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# ee-shared
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build ee-shared` to build the library.

View File

@@ -0,0 +1,5 @@
{
"name": "@activepieces/ee-shared",
"version": "0.0.11",
"type": "commonjs"
}

View File

@@ -0,0 +1,23 @@
{
"name": "ee-shared",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/ee/shared/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/packages/ee/shared",
"main": "packages/ee/shared/src/index.ts",
"tsConfig": "packages/ee/shared/tsconfig.lib.json",
"assets": ["packages/ee/shared/*.md"]
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
}
},
"tags": []
}

View File

@@ -0,0 +1,18 @@
export * from './lib/billing'
export * from './lib/audit-events'
export * from './lib/git-repo'
export * from './lib/api-key'
export * from './lib/billing'
export * from './lib/project/project-requests'
export * from './lib/custom-domains'
export * from './lib/project-members/project-member-request'
export * from './lib/project-members/project-member'
export * from './lib/template'
export * from './lib/product-embed/app-credentials/index'
export * from './lib/product-embed/connection-keys/index'
export * from './lib/signing-key'
export * from './lib/managed-authn'
export * from './lib/oauth-apps'
export * from './lib/otp'
export * from './lib/authn'
export * from './lib/alerts'

View File

@@ -0,0 +1,16 @@
import { ApId, BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export enum AlertChannel {
EMAIL = 'EMAIL',
}
export const Alert = Type.Object({
...BaseModelSchema,
projectId: ApId,
channel: Type.Enum(AlertChannel),
receiver: Type.String({}),
})
export type Alert = Static<typeof Alert>

View File

@@ -0,0 +1,18 @@
import { ApId } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
import { AlertChannel } from './alerts-dto'
export const ListAlertsParams = Type.Object({
projectId: ApId,
cursor: Type.Optional(Type.String()),
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 100 })),
})
export type ListAlertsParams = Static<typeof ListAlertsParams>
export const CreateAlertParams = Type.Object({
projectId: ApId,
channel: Type.Enum(AlertChannel),
receiver: Type.String({}),
})
export type CreateAlertParams = Static<typeof CreateAlertParams>

View File

@@ -0,0 +1,2 @@
export * from './alerts-dto'
export * from './alerts-requests'

View File

@@ -0,0 +1,34 @@
import { ApId, BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export const ApiKey = Type.Object({
...BaseModelSchema,
platformId: ApId,
displayName: Type.String(),
hashedValue: Type.String(),
truncatedValue: Type.String(),
lastUsedAt: Type.Optional(Type.String()),
})
export type ApiKey = Static<typeof ApiKey>
export const ApiKeyResponseWithValue = Type.Composite([
Type.Omit(ApiKey, ['hashedValue']),
Type.Object({
value: Type.String(),
}),
])
export type ApiKeyResponseWithValue = Static<typeof ApiKeyResponseWithValue>
export const ApiKeyResponseWithoutValue = Type.Omit(ApiKey, ['hashedValue'])
export type ApiKeyResponseWithoutValue = Static<typeof ApiKeyResponseWithoutValue>
export const CreateApiKeyRequest = Type.Object({
displayName: Type.String(),
})
export type CreateApiKeyRequest = Static<typeof CreateApiKeyRequest>

View File

@@ -0,0 +1,384 @@
import {
AppConnectionWithoutSensitiveData,
BaseModelSchema,
Flow,
FlowOperationRequest,
FlowOperationType,
FlowRun,
FlowVersion,
Folder,
Project,
ProjectRelease,
ProjectRole,
User,
} from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
import { SigningKey } from '../signing-key'
export const ListAuditEventsRequest = Type.Object({
limit: Type.Optional(Type.Number()),
cursor: Type.Optional(Type.String()),
action: Type.Optional(Type.Array(Type.String())),
projectId: Type.Optional(Type.Array(Type.String())),
userId: Type.Optional(Type.String()),
createdBefore: Type.Optional(Type.String()),
createdAfter: Type.Optional(Type.String()),
})
export type ListAuditEventsRequest = Static<typeof ListAuditEventsRequest>
const UserMeta = Type.Pick(User, ['email', 'id', 'firstName', 'lastName'])
export enum ApplicationEventName {
FLOW_CREATED = 'flow.created',
FLOW_DELETED = 'flow.deleted',
FLOW_UPDATED = 'flow.updated',
FLOW_RUN_RESUMED = 'flow.run.resumed',
FLOW_RUN_STARTED = 'flow.run.started',
FLOW_RUN_FINISHED = 'flow.run.finished',
FOLDER_CREATED = 'folder.created',
FOLDER_UPDATED = 'folder.updated',
FOLDER_DELETED = 'folder.deleted',
CONNECTION_UPSERTED = 'connection.upserted',
CONNECTION_DELETED = 'connection.deleted',
USER_SIGNED_UP = 'user.signed.up',
USER_SIGNED_IN = 'user.signed.in',
USER_PASSWORD_RESET = 'user.password.reset',
USER_EMAIL_VERIFIED = 'user.email.verified',
SIGNING_KEY_CREATED = 'signing.key.created',
PROJECT_ROLE_CREATED = 'project.role.created',
PROJECT_ROLE_DELETED = 'project.role.deleted',
PROJECT_ROLE_UPDATED = 'project.role.updated',
PROJECT_RELEASE_CREATED = 'project.release.created',
}
const BaseAuditEventProps = {
...BaseModelSchema,
platformId: Type.String(),
projectId: Type.Optional(Type.String()),
projectDisplayName: Type.Optional(Type.String()),
userId: Type.Optional(Type.String()),
userEmail: Type.Optional(Type.String()),
ip: Type.Optional(Type.String()),
}
export const ConnectionEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([
Type.Literal(ApplicationEventName.CONNECTION_DELETED),
Type.Literal(ApplicationEventName.CONNECTION_UPSERTED),
]),
data: Type.Object({
connection: Type.Pick(AppConnectionWithoutSensitiveData, [
'displayName',
'externalId',
'pieceName',
'status',
'type',
'id',
'created',
'updated',
]),
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type ConnectionEvent = Static<typeof ConnectionEvent>
export const FolderEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([
Type.Literal(ApplicationEventName.FOLDER_UPDATED),
Type.Literal(ApplicationEventName.FOLDER_CREATED),
Type.Literal(ApplicationEventName.FOLDER_DELETED),
]),
data: Type.Object({
folder: Type.Pick(Folder, ['id', 'displayName', 'created', 'updated']),
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type FolderEvent = Static<typeof FolderEvent>
export const FlowRunEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([
Type.Literal(ApplicationEventName.FLOW_RUN_STARTED),
Type.Literal(ApplicationEventName.FLOW_RUN_FINISHED),
Type.Literal(ApplicationEventName.FLOW_RUN_RESUMED),
]),
data: Type.Object({
flowRun: Type.Pick(FlowRun, [
'id',
'startTime',
'finishTime',
'duration',
'environment',
'flowId',
'flowVersionId',
'flowDisplayName',
'status',
]),
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type FlowRunEvent = Static<typeof FlowRunEvent>
export const FlowCreatedEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Literal(ApplicationEventName.FLOW_CREATED),
data: Type.Object({
flow: Type.Pick(Flow, ['id', 'created', 'updated']),
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type FlowCreatedEvent = Static<typeof FlowCreatedEvent>
export const FlowDeletedEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Literal(ApplicationEventName.FLOW_DELETED),
data: Type.Object({
flow: Type.Pick(Flow, ['id', 'created', 'updated']),
flowVersion: Type.Pick(FlowVersion, [
'id',
'displayName',
'flowId',
'created',
'updated',
]),
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type FlowDeletedEvent = Static<typeof FlowDeletedEvent>
export const FlowUpdatedEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Literal(ApplicationEventName.FLOW_UPDATED),
data: Type.Object({
flowVersion: Type.Pick(FlowVersion, [
'id',
'displayName',
'flowId',
'created',
'updated',
]),
request: FlowOperationRequest,
project: Type.Optional(Type.Pick(Project, ['displayName'])),
}),
})
export type FlowUpdatedEvent = Static<typeof FlowUpdatedEvent>
export const AuthenticationEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([
Type.Literal(ApplicationEventName.USER_SIGNED_IN),
Type.Literal(ApplicationEventName.USER_PASSWORD_RESET),
Type.Literal(ApplicationEventName.USER_EMAIL_VERIFIED),
]),
data: Type.Object({
user: Type.Optional(UserMeta),
}),
})
export type AuthenticationEvent = Static<typeof AuthenticationEvent>
export const SignUpEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Literal(ApplicationEventName.USER_SIGNED_UP),
data: Type.Object({
source: Type.Union([
Type.Literal('credentials'),
Type.Literal('sso'),
Type.Literal('managed'),
]),
user: Type.Optional(UserMeta),
}),
})
export type SignUpEvent = Static<typeof SignUpEvent>
export const SigningKeyEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([Type.Literal(ApplicationEventName.SIGNING_KEY_CREATED)]),
data: Type.Object({
signingKey: Type.Pick(SigningKey, [
'id',
'created',
'updated',
'displayName',
]),
}),
})
export type SigningKeyEvent = Static<typeof SigningKeyEvent>
export const ProjectRoleEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Union([
Type.Literal(ApplicationEventName.PROJECT_ROLE_CREATED),
Type.Literal(ApplicationEventName.PROJECT_ROLE_UPDATED),
Type.Literal(ApplicationEventName.PROJECT_ROLE_DELETED),
]),
data: Type.Object({
projectRole: Type.Pick(ProjectRole, [
'id',
'created',
'updated',
'name',
'permissions',
'platformId',
]),
}),
})
export type ProjectRoleEvent = Static<typeof ProjectRoleEvent>
export const ProjectReleaseEvent = Type.Object({
...BaseAuditEventProps,
action: Type.Literal(ApplicationEventName.PROJECT_RELEASE_CREATED),
data: Type.Object({
release: Type.Pick(ProjectRelease, ['name', 'description', 'type', 'projectId', 'importedByUser']),
}),
})
export type ProjectReleaseEvent = Static<typeof ProjectReleaseEvent>
export const ApplicationEvent = Type.Union([
ConnectionEvent,
FlowCreatedEvent,
FlowDeletedEvent,
FlowUpdatedEvent,
FlowRunEvent,
AuthenticationEvent,
FolderEvent,
SignUpEvent,
SigningKeyEvent,
ProjectRoleEvent,
ProjectReleaseEvent,
])
export type ApplicationEvent = Static<typeof ApplicationEvent>
export function summarizeApplicationEvent(event: ApplicationEvent) {
switch (event.action) {
case ApplicationEventName.FLOW_UPDATED: {
return convertUpdateActionToDetails(event)
}
case ApplicationEventName.FLOW_RUN_STARTED:
return `Flow run ${event.data.flowRun.id} is started`
case ApplicationEventName.FLOW_RUN_FINISHED: {
return `Flow run ${event.data.flowRun.id} is finished`
}
case ApplicationEventName.FLOW_RUN_RESUMED: {
return `Flow run ${event.data.flowRun.id} is resumed`
}
case ApplicationEventName.FLOW_CREATED:
return `Flow ${event.data.flow.id} is created`
case ApplicationEventName.FLOW_DELETED:
return `Flow ${event.data.flow.id} (${event.data.flowVersion.displayName}) is deleted`
case ApplicationEventName.FOLDER_CREATED:
return `${event.data.folder.displayName} is created`
case ApplicationEventName.FOLDER_UPDATED:
return `${event.data.folder.displayName} is updated`
case ApplicationEventName.FOLDER_DELETED:
return `${event.data.folder.displayName} is deleted`
case ApplicationEventName.CONNECTION_UPSERTED:
return `${event.data.connection.displayName} (${event.data.connection.externalId}) is updated`
case ApplicationEventName.CONNECTION_DELETED:
return `${event.data.connection.displayName} (${event.data.connection.externalId}) is deleted`
case ApplicationEventName.USER_SIGNED_IN:
return `User ${event.userEmail} signed in`
case ApplicationEventName.USER_PASSWORD_RESET:
return `User ${event.userEmail} reset password`
case ApplicationEventName.USER_EMAIL_VERIFIED:
return `User ${event.userEmail} verified email`
case ApplicationEventName.USER_SIGNED_UP:
return `User ${event.userEmail} signed up using email from ${event.data.source}`
case ApplicationEventName.SIGNING_KEY_CREATED:
return `${event.data.signingKey.displayName} is created`
case ApplicationEventName.PROJECT_ROLE_CREATED:
return `${event.data.projectRole.name} is created`
case ApplicationEventName.PROJECT_ROLE_UPDATED:
return `${event.data.projectRole.name} is updated`
case ApplicationEventName.PROJECT_ROLE_DELETED:
return `${event.data.projectRole.name} is deleted`
case ApplicationEventName.PROJECT_RELEASE_CREATED:
return `${event.data.release.name} is created`
}
}
function convertUpdateActionToDetails(event: FlowUpdatedEvent) {
switch (event.data.request.type) {
case FlowOperationType.ADD_ACTION:
return `Added action "${event.data.request.request.action.displayName}" to "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.UPDATE_ACTION:
return `Updated action "${event.data.request.request.displayName}" in "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.DELETE_ACTION:
{
const request = event.data.request.request
const names = request.names
return `Deleted actions "${names.join(', ')}" from "${event.data.flowVersion.displayName}" Flow.`
}
case FlowOperationType.CHANGE_NAME:
return `Renamed flow "${event.data.flowVersion.displayName}" to "${event.data.request.request.displayName}".`
case FlowOperationType.LOCK_AND_PUBLISH:
return `Locked and published flow "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.USE_AS_DRAFT:
return `Unlocked and unpublished flow "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.MOVE_ACTION:
return `Moved action "${event.data.request.request.name}" to after "${event.data.request.request.newParentStep}".`
case FlowOperationType.LOCK_FLOW:
return `Locked flow "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.CHANGE_STATUS:
return `Changed status of flow "${event.data.flowVersion.displayName}" Flow to "${event.data.request.request.status}".`
case FlowOperationType.DUPLICATE_ACTION:
return `Duplicated action "${event.data.request.request.stepName}" in "${event.data.flowVersion.displayName}" Flow.`
case FlowOperationType.IMPORT_FLOW:
return `Imported flow in "${event.data.request.request.displayName}" Flow.`
case FlowOperationType.UPDATE_TRIGGER:
return `Updated trigger in "${event.data.flowVersion.displayName}" Flow to "${event.data.request.request.displayName}".`
case FlowOperationType.CHANGE_FOLDER:
return `Moved flow "${event.data.flowVersion.displayName}" to folder id ${event.data.request.request.folderId}.`
case FlowOperationType.DELETE_BRANCH: {
return `Deleted branch number ${
event.data.request.request.branchIndex + 1
} in flow "${event.data.flowVersion.displayName}" for the step "${
event.data.request.request.stepName
}".`
}
case FlowOperationType.SAVE_SAMPLE_DATA: {
return `Saved sample data for step "${event.data.request.request.stepName}" in flow "${event.data.flowVersion.displayName}".`
}
case FlowOperationType.DUPLICATE_BRANCH: {
return `Duplicated branch number ${
event.data.request.request.branchIndex + 1
} in flow "${event.data.flowVersion.displayName}" for the step "${
event.data.request.request.stepName
}".`
}
case FlowOperationType.ADD_BRANCH:
return `Added branch number ${
event.data.request.request.branchIndex + 1
} in flow "${event.data.flowVersion.displayName}" for the step "${
event.data.request.request.stepName
}".`
case FlowOperationType.SET_SKIP_ACTION:
{
const request = event.data.request.request
const names = request.names
return `Updated actions "${names.join(', ')}" in "${event.data.flowVersion.displayName}" Flow to skip.`
}
case FlowOperationType.UPDATE_METADATA:
return `Updated metadata for flow "${event.data.flowVersion.displayName}".`
case FlowOperationType.UPDATE_MINUTES_SAVED:
return `Updated minutes saved for flow "${event.data.flowVersion.displayName}".`
case FlowOperationType.MOVE_BRANCH:
return `Moved branch number ${
event.data.request.request.sourceBranchIndex + 1
} to ${
event.data.request.request.targetBranchIndex + 1
} in flow "${event.data.flowVersion.displayName}" for the step "${
event.data.request.request.stepName
}".`
}
}

View File

@@ -0,0 +1,82 @@
import { DefaultProjectRole, Permission } from '@activepieces/shared'
export const rolePermissions: Record<DefaultProjectRole, Permission[]> = {
[DefaultProjectRole.ADMIN]: [
Permission.READ_APP_CONNECTION,
Permission.WRITE_APP_CONNECTION,
Permission.READ_FLOW,
Permission.WRITE_FLOW,
Permission.UPDATE_FLOW_STATUS,
Permission.READ_PROJECT_MEMBER,
Permission.WRITE_PROJECT_MEMBER,
Permission.WRITE_INVITATION,
Permission.READ_INVITATION,
Permission.WRITE_PROJECT_RELEASE,
Permission.READ_PROJECT_RELEASE,
Permission.READ_RUN,
Permission.WRITE_RUN,
Permission.WRITE_ALERT,
Permission.READ_ALERT,
Permission.WRITE_PROJECT,
Permission.READ_PROJECT,
Permission.WRITE_FOLDER,
Permission.READ_FOLDER,
Permission.READ_TODOS,
Permission.WRITE_TODOS,
Permission.READ_TABLE,
Permission.WRITE_TABLE,
Permission.READ_MCP,
Permission.WRITE_MCP,
],
[DefaultProjectRole.EDITOR]: [
Permission.READ_APP_CONNECTION,
Permission.WRITE_APP_CONNECTION,
Permission.READ_FLOW,
Permission.WRITE_FLOW,
Permission.UPDATE_FLOW_STATUS,
Permission.READ_PROJECT_MEMBER,
Permission.READ_INVITATION,
Permission.WRITE_PROJECT_RELEASE,
Permission.READ_PROJECT_RELEASE,
Permission.READ_RUN,
Permission.WRITE_RUN,
Permission.READ_PROJECT,
Permission.WRITE_FOLDER,
Permission.READ_FOLDER,
Permission.READ_TODOS,
Permission.WRITE_TODOS,
Permission.READ_TABLE,
Permission.WRITE_TABLE,
Permission.READ_MCP,
Permission.WRITE_MCP,
],
[DefaultProjectRole.OPERATOR]: [
Permission.READ_APP_CONNECTION,
Permission.WRITE_APP_CONNECTION,
Permission.READ_FLOW,
Permission.UPDATE_FLOW_STATUS,
Permission.READ_PROJECT_MEMBER,
Permission.READ_INVITATION,
Permission.READ_PROJECT_RELEASE,
Permission.READ_RUN,
Permission.WRITE_RUN,
Permission.READ_PROJECT,
Permission.READ_FOLDER,
Permission.READ_TODOS,
Permission.WRITE_TODOS,
Permission.READ_TABLE,
Permission.READ_MCP,
],
[DefaultProjectRole.VIEWER]: [
Permission.READ_APP_CONNECTION,
Permission.READ_FLOW,
Permission.READ_PROJECT_MEMBER,
Permission.READ_INVITATION,
Permission.READ_PROJECT,
Permission.READ_RUN,
Permission.READ_FOLDER,
Permission.READ_TODOS,
Permission.READ_TABLE,
Permission.READ_MCP,
],
}

View File

@@ -0,0 +1 @@
export * from './requests'

View File

@@ -0,0 +1,25 @@
import { ApId, SignUpRequest } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export const VerifyEmailRequestBody = Type.Object({
identityId: ApId,
otp: Type.String(),
})
export type VerifyEmailRequestBody = Static<typeof VerifyEmailRequestBody>
export const ResetPasswordRequestBody = Type.Object({
identityId: ApId,
otp: Type.String(),
newPassword: Type.String(),
})
export type ResetPasswordRequestBody = Static<typeof ResetPasswordRequestBody>
export const SignUpAndAcceptRequestBody = Type.Composite([
Type.Omit(SignUpRequest, ['referringUserId', 'email']),
Type.Object({
invitationToken: Type.String(),
}),
])
export type SignUpAndAcceptRequestBody = Static<typeof SignUpAndAcceptRequestBody>

View File

@@ -0,0 +1,2 @@
export * from './enterprise-local-authn'
export * from './access-control-list'

View File

@@ -0,0 +1,135 @@
import { AiOverageState, isNil, PiecesFilterType, PlanName, PlatformPlanWithOnlyLimits, PlatformUsageMetric, TeamProjectsLimit } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export const PRICE_PER_EXTRA_ACTIVE_FLOWS = 5
export const AI_CREDITS_USAGE_THRESHOLD = 15000
export type ProjectPlanLimits = {
nickname?: string
locked?: boolean
pieces?: string[]
aiCredits?: number | null
piecesFilterType?: PiecesFilterType
}
export enum ApSubscriptionStatus {
ACTIVE = 'active',
CANCELED = 'canceled',
}
export const METRIC_TO_LIMIT_MAPPING = {
[PlatformUsageMetric.ACTIVE_FLOWS]: 'activeFlowsLimit',
} as const
export const METRIC_TO_USAGE_MAPPING = {
[PlatformUsageMetric.ACTIVE_FLOWS]: 'activeFlows',
} as const
export const SetAiCreditsOverageLimitParamsSchema = Type.Object({
limit: Type.Number({ minimum: 10 }),
})
export type SetAiCreditsOverageLimitParams = Static<typeof SetAiCreditsOverageLimitParamsSchema>
export const ToggleAiCreditsOverageEnabledParamsSchema = Type.Object({
state: Type.Enum(AiOverageState),
})
export type ToggleAiCreditsOverageEnabledParams = Static<typeof ToggleAiCreditsOverageEnabledParamsSchema>
export const UpdateActiveFlowsAddonParamsSchema = Type.Object({
newActiveFlowsLimit: Type.Number(),
})
export type UpdateActiveFlowsAddonParams = Static<typeof UpdateActiveFlowsAddonParamsSchema>
export const CreateCheckoutSessionParamsSchema = Type.Object({
newActiveFlowsLimit: Type.Number(),
})
export type CreateSubscriptionParams = Static<typeof CreateCheckoutSessionParamsSchema>
export enum PRICE_NAMES {
AI_CREDITS = 'ai-credit',
ACTIVE_FLOWS = 'active-flow',
}
export const PRICE_ID_MAP = {
[PRICE_NAMES.AI_CREDITS]: {
dev: 'price_1RnbNPQN93Aoq4f8GLiZbJFj',
prod: 'price_1Rnj5bKZ0dZRqLEKQx2gwL7s',
},
[PRICE_NAMES.ACTIVE_FLOWS]: {
dev: 'price_1SQbbYQN93Aoq4f8WK2JC4sf',
prod: 'price_1SQbcvKZ0dZRqLEKHV5UepRx',
},
}
export const STANDARD_CLOUD_PLAN: PlatformPlanWithOnlyLimits = {
plan: 'standard',
includedAiCredits: 200,
aiCreditsOverageLimit: undefined,
aiCreditsOverageState: AiOverageState.ALLOWED_BUT_OFF,
activeFlowsLimit: 10,
projectsLimit: 1,
agentsEnabled: true,
tablesEnabled: true,
todosEnabled: true,
mcpsEnabled: true,
embeddingEnabled: false,
globalConnectionsEnabled: false,
customRolesEnabled: false,
environmentsEnabled: false,
analyticsEnabled: true,
showPoweredBy: false,
auditLogEnabled: false,
managePiecesEnabled: false,
manageTemplatesEnabled: false,
customAppearanceEnabled: false,
teamProjectsLimit: TeamProjectsLimit.ONE,
projectRolesEnabled: false,
customDomainsEnabled: false,
apiKeysEnabled: false,
ssoEnabled: false,
}
export const OPEN_SOURCE_PLAN: PlatformPlanWithOnlyLimits = {
embeddingEnabled: false,
globalConnectionsEnabled: false,
customRolesEnabled: false,
mcpsEnabled: true,
tablesEnabled: true,
todosEnabled: true,
agentsEnabled: true,
includedAiCredits: 0,
aiCreditsOverageLimit: undefined,
aiCreditsOverageState: AiOverageState.NOT_ALLOWED,
environmentsEnabled: false,
analyticsEnabled: true,
showPoweredBy: false,
auditLogEnabled: false,
managePiecesEnabled: false,
manageTemplatesEnabled: false,
customAppearanceEnabled: false,
teamProjectsLimit: TeamProjectsLimit.NONE,
projectRolesEnabled: false,
customDomainsEnabled: false,
apiKeysEnabled: false,
ssoEnabled: false,
stripeCustomerId: undefined,
stripeSubscriptionId: undefined,
stripeSubscriptionStatus: undefined,
}
export const APPSUMO_PLAN = (planName: PlanName): PlatformPlanWithOnlyLimits => ({
...STANDARD_CLOUD_PLAN,
plan: planName,
activeFlowsLimit: undefined,
})
export const isCloudPlanButNotEnterprise = (plan?: string): boolean => {
if (isNil(plan)) {
return false
}
return plan === PlanName.STANDARD
}

View File

@@ -0,0 +1,32 @@
import { BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export enum CustomDomainStatus {
ACTIVE = 'ACTIVE',
PENDING = 'PENDING',
}
export const CustomDomain = Type.Object({
...BaseModelSchema,
domain: Type.String(),
platformId: Type.String(),
status: Type.Enum(CustomDomainStatus),
})
export type CustomDomain = Static<typeof CustomDomain>
export const AddDomainRequest = Type.Object({
domain: Type.String({
pattern: '^(?!.*\\.example\\.com$)(?!.*\\.example\\.net$).*',
}),
})
export type AddDomainRequest = Static<typeof AddDomainRequest>
export const ListCustomDomainsRequest = Type.Object({
limit: Type.Optional(Type.Number()),
cursor: Type.Optional(Type.String()),
})
export type ListCustomDomainsRequest = Static<typeof ListCustomDomainsRequest>

View File

@@ -0,0 +1,83 @@
import { BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export enum GitBranchType {
PRODUCTION = 'PRODUCTION',
DEVELOPMENT = 'DEVELOPMENT',
}
export const GitRepo = Type.Object({
...BaseModelSchema,
remoteUrl: Type.String(),
branch: Type.String(),
branchType: Type.Enum(GitBranchType),
projectId: Type.String(),
sshPrivateKey: Type.String(),
slug: Type.String(),
})
export type GitRepo = Static<typeof GitRepo>
export const GitRepoWithoutSensitiveData = Type.Omit(GitRepo, ['sshPrivateKey'])
export type GitRepoWithoutSensitiveData = Static<typeof GitRepoWithoutSensitiveData>
export enum GitPushOperationType {
PUSH_FLOW = 'PUSH_FLOW',
DELETE_FLOW = 'DELETE_FLOW',
PUSH_TABLE = 'PUSH_TABLE',
DELETE_TABLE = 'DELETE_TABLE',
PUSH_EVERYTHING = 'PUSH_EVERYTHING',
}
export const PushFlowsGitRepoRequest = Type.Object({
type: Type.Union([Type.Literal(GitPushOperationType.PUSH_FLOW), Type.Literal(GitPushOperationType.DELETE_FLOW)]),
commitMessage: Type.String({
minLength: 1,
}),
externalFlowIds: Type.Array(Type.String()),
})
export type PushFlowsGitRepoRequest = Static<typeof PushFlowsGitRepoRequest>
export const PushTablesGitRepoRequest = Type.Object({
type: Type.Union([Type.Literal(GitPushOperationType.PUSH_TABLE), Type.Literal(GitPushOperationType.DELETE_TABLE)]),
commitMessage: Type.String({
minLength: 1,
}),
externalTableIds: Type.Array(Type.String()),
})
export type PushTablesGitRepoRequest = Static<typeof PushTablesGitRepoRequest>
export const PushEverythingGitRepoRequest = Type.Object({
type: Type.Literal(GitPushOperationType.PUSH_EVERYTHING),
commitMessage: Type.String({
minLength: 1,
}),
})
export type PushEverythingGitRepoRequest = Static<typeof PushEverythingGitRepoRequest>
export const PushGitRepoRequest = Type.Union([PushFlowsGitRepoRequest, PushTablesGitRepoRequest, PushEverythingGitRepoRequest])
export type PushGitRepoRequest = Static<typeof PushGitRepoRequest>
export const ConfigureRepoRequest = Type.Object({
projectId: Type.String({
minLength: 1,
}),
remoteUrl: Type.String({
pattern: '^git@',
}),
branch: Type.String({
minLength: 1,
}),
branchType: Type.Enum(GitBranchType),
sshPrivateKey: Type.String({
minLength: 1,
}),
slug: Type.String({
minLength: 1,
}),
})
export type ConfigureRepoRequest = Static<typeof ConfigureRepoRequest>

View File

@@ -0,0 +1 @@
export * from './managed-authn-requests'

View File

@@ -0,0 +1,8 @@
import { Static, Type } from '@sinclair/typebox'
export const ManagedAuthnRequestBody = Type.Object({
//if you change this you need to update the embed-sdk I can't import it there because it can't have dependencies
externalAccessToken: Type.String(),
})
export type ManagedAuthnRequestBody = Static<typeof ManagedAuthnRequestBody>

View File

@@ -0,0 +1 @@
export * from './oauth-app'

View File

@@ -0,0 +1,26 @@
import { BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export const OAuthApp = Type.Object({
...BaseModelSchema,
pieceName: Type.String(),
platformId: Type.String(),
clientId: Type.String(),
})
export type OAuthApp = Static<typeof OAuthApp>
export const UpsertOAuth2AppRequest = Type.Object({
pieceName: Type.String(),
clientId: Type.String(),
clientSecret: Type.String(),
})
export type UpsertOAuth2AppRequest = Static<typeof UpsertOAuth2AppRequest>
export const ListOAuth2AppRequest = Type.Object({
limit: Type.Optional(Type.Number()),
cursor: Type.Optional(Type.String()),
})
export type ListOAuth2AppRequest = Static<typeof ListOAuth2AppRequest>

View File

@@ -0,0 +1,3 @@
export * from './otp-model'
export * from './otp-requests'
export * from './otp-type'

View File

@@ -0,0 +1,20 @@
import { ApId, BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
import { OtpType } from './otp-type'
export type OtpId = ApId
export enum OtpState {
PENDING = 'PENDING',
CONFIRMED = 'CONFIRMED',
}
export const OtpModel = Type.Object({
...BaseModelSchema,
type: Type.Enum(OtpType),
identityId: ApId,
value: Type.String(),
state: Type.Enum(OtpState),
})
export type OtpModel = Static<typeof OtpModel>

View File

@@ -0,0 +1,11 @@
import { Static, Type } from '@sinclair/typebox'
import { OtpType } from './otp-type'
export const CreateOtpRequestBody = Type.Object({
email: Type.String(),
type: Type.Enum(OtpType),
})
export type CreateOtpRequestBody = Static<typeof CreateOtpRequestBody>

View File

@@ -0,0 +1,4 @@
export enum OtpType {
EMAIL_VERIFICATION = 'EMAIL_VERIFICATION',
PASSWORD_RESET = 'PASSWORD_RESET',
}

View File

@@ -0,0 +1,38 @@
import { Static, Type } from '@sinclair/typebox'
import { AppCredentialType } from './app-credentials'
export const ListAppCredentialsRequest = Type.Object({
projectId: Type.String(),
appName: Type.Optional(Type.String()),
limit: Type.Optional(Type.Number()),
cursor: Type.Optional(Type.String({})),
})
export type ListAppCredentialsRequest = Static<typeof ListAppCredentialsRequest>
export const UpsertApiKeyCredentialRequest = Type.Object({
id: Type.Optional(Type.String()),
appName: Type.String(),
settings: Type.Object({
type: Type.Literal(AppCredentialType.API_KEY),
}),
})
export const UpsertOAuth2CredentialRequest = Type.Object({
id: Type.Optional(Type.String()),
appName: Type.String(),
settings: Type.Object({
type: Type.Literal(AppCredentialType.OAUTH2),
authUrl: Type.String({}),
scope: Type.String(),
tokenUrl: Type.String({}),
clientId: Type.String({}),
clientSecret: Type.String({}),
}),
})
export const UpsertAppCredentialRequest = Type.Union([UpsertOAuth2CredentialRequest, UpsertApiKeyCredentialRequest])
export type UpsertAppCredentialRequest = Static<typeof UpsertAppCredentialRequest>

View File

@@ -0,0 +1,29 @@
import { BaseModel, OAuth2GrantType, ProjectId } from '@activepieces/shared'
export type AppCredentialId = string
export type AppOAuth2Settings = {
type: AppCredentialType.OAUTH2
authUrl: string
tokenUrl: string
grantType: OAuth2GrantType
clientId: string
clientSecret?: string
scope: string
}
export type AppApiKeySettings = {
type: AppCredentialType.API_KEY
}
export type AppCredential = {
appName: string
projectId: ProjectId
settings: AppOAuth2Settings | AppApiKeySettings
} & BaseModel<AppCredentialId>
export enum AppCredentialType {
OAUTH2 = 'OAUTH2',
API_KEY = 'API_KEY',
}

View File

@@ -0,0 +1,2 @@
export * from './app-credentials'
export * from './app-credentials-requests'

View File

@@ -0,0 +1,18 @@
import { BaseModel, ProjectId } from '@activepieces/shared'
export type ConnectionKeyId = string
export type ConnectionKey = {
projectId: ProjectId
settings: SigningKeyConnection
} & BaseModel<ConnectionKeyId>
export type SigningKeyConnection = {
type: ConnectionKeyType.SIGNING_KEY
publicKey: string
privateKey?: string
}
export enum ConnectionKeyType {
SIGNING_KEY = 'SIGNING_KEY',
}

View File

@@ -0,0 +1,49 @@
import { Static, Type } from '@sinclair/typebox'
import { ConnectionKeyType } from './connection-key'
export const GetOrDeleteConnectionFromTokenRequest = Type.Object({
projectId: Type.String(),
token: Type.String(),
appName: Type.String(),
})
export type GetOrDeleteConnectionFromTokenRequest = Static<typeof GetOrDeleteConnectionFromTokenRequest>
export const ListConnectionKeysRequest = Type.Object({
limit: Type.Optional(Type.Number()),
cursor: Type.Optional(Type.String({})),
})
export type ListConnectionKeysRequest = Static<typeof ListConnectionKeysRequest>
export const UpsertApiKeyConnectionFromToken = Type.Object({
appCredentialId: Type.String(),
apiKey: Type.String(),
token: Type.String(),
})
export type UpsertApiKeyConnectionFromToken = Static<typeof UpsertApiKeyConnectionFromToken>
export const UpsertOAuth2ConnectionFromToken = Type.Object({
appCredentialId: Type.String(),
props: Type.Record(Type.String(), Type.Any()),
token: Type.String(),
code: Type.String(),
redirectUrl: Type.String(),
})
export type UpsertOAuth2ConnectionFromToken = Static<typeof UpsertOAuth2ConnectionFromToken>
export const UpsertConnectionFromToken = Type.Union([UpsertApiKeyConnectionFromToken, UpsertOAuth2ConnectionFromToken])
export type UpsertConnectionFromToken = Static<typeof UpsertConnectionFromToken>
export const UpsertSigningKeyConnection = Type.Object({
settings: Type.Object({
type: Type.Literal(ConnectionKeyType.SIGNING_KEY),
}),
})
export type UpsertSigningKeyConnection = Static<typeof UpsertSigningKeyConnection>

View File

@@ -0,0 +1,2 @@
export * from './connection-key'
export * from './connection-requests'

View File

@@ -0,0 +1,28 @@
import { Static, Type } from '@sinclair/typebox'
export const AcceptInvitationRequest = Type.Object({
token: Type.String(),
})
export type AcceptInvitationRequest = Static<typeof AcceptInvitationRequest>
export const ListProjectMembersRequestQuery = Type.Object({
projectId: Type.String(),
projectRoleId: Type.Optional(Type.String()),
cursor: Type.Optional(Type.String()),
limit: Type.Optional(Type.Number()),
})
export type ListProjectMembersRequestQuery = Static<typeof ListProjectMembersRequestQuery>
export const AcceptProjectResponse = Type.Object({
registered: Type.Boolean(),
})
export type AcceptProjectResponse = Static<typeof AcceptProjectResponse>
export const UpdateProjectMemberRoleRequestBody = Type.Object({
role: Type.String(),
})
export type UpdateProjectMemberRoleRequestBody = Static<typeof UpdateProjectMemberRoleRequestBody>

View File

@@ -0,0 +1,24 @@
import { ApId, BaseModelSchema, ProjectMetaData, ProjectRole, UserWithMetaInformation } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export type ProjectMemberId = string
export const ProjectMember = Type.Object({
...BaseModelSchema,
platformId: ApId,
userId: ApId,
projectId: Type.String(),
projectRoleId: ApId,
}, {
description: 'Project member is which user is assigned to a project.',
})
export type ProjectMember = Static<typeof ProjectMember>
export const ProjectMemberWithUser = Type.Composite([ProjectMember, Type.Object({
user: UserWithMetaInformation,
projectRole: ProjectRole,
project: ProjectMetaData,
})])
export type ProjectMemberWithUser = Static<typeof ProjectMemberWithUser>

View File

@@ -0,0 +1,39 @@
import { Metadata, Nullable, PiecesFilterType, ProjectIcon, ProjectType, SAFE_STRING_PATTERN } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export const UpdateProjectPlatformRequest = Type.Object({
releasesEnabled: Type.Optional(Type.Boolean()),
displayName: Type.Optional(Type.String({
pattern: SAFE_STRING_PATTERN,
})),
externalId: Type.Optional(Type.String()),
metadata: Type.Optional(Metadata),
icon: Type.Optional(ProjectIcon),
plan: Type.Optional(Type.Object({
pieces: Type.Optional(Type.Array(Type.String({}))),
piecesFilterType: Type.Optional(Type.Enum(PiecesFilterType)),
})),
})
export type UpdateProjectPlatformRequest = Static<typeof UpdateProjectPlatformRequest>
export const CreatePlatformProjectRequest = Type.Object({
displayName: Type.String({
pattern: SAFE_STRING_PATTERN,
}),
externalId: Nullable(Type.String()),
metadata: Nullable(Metadata),
maxConcurrentJobs: Nullable(Type.Number()),
})
export type CreatePlatformProjectRequest = Static<typeof CreatePlatformProjectRequest>
export const ListProjectRequestForPlatformQueryParams = Type.Object({
externalId: Type.Optional(Type.String()),
limit: Type.Optional(Type.Number({})),
cursor: Type.Optional(Type.String({})),
displayName: Type.Optional(Type.String()),
types: Type.Optional(Type.Array(Type.Enum(ProjectType))),
})
export type ListProjectRequestForPlatformQueryParams = Static<typeof ListProjectRequestForPlatformQueryParams>

View File

@@ -0,0 +1,3 @@
export * from './signing-key-model'
export * from './signing-key-response'
export * from './signing-key.request'

View File

@@ -0,0 +1,19 @@
import { ApId, BaseModelSchema } from '@activepieces/shared'
import { Static, Type } from '@sinclair/typebox'
export enum KeyAlgorithm {
RSA = 'RSA',
}
export type SigningKeyId = ApId
export const SigningKey = Type.Object({
...BaseModelSchema,
platformId: ApId,
publicKey: Type.String(),
displayName: Type.String(),
/* algorithm used to generate this key pair */
algorithm: Type.Enum(KeyAlgorithm),
})
export type SigningKey = Static<typeof SigningKey>

View File

@@ -0,0 +1,5 @@
import { SigningKey } from './signing-key-model'
export type AddSigningKeyResponse = SigningKey & {
privateKey: string
}

View File

@@ -0,0 +1,7 @@
import { Static, Type } from '@sinclair/typebox'
export const AddSigningKeyRequestBody = Type.Object({
displayName: Type.String(),
})
export type AddSigningKeyRequestBody = Static<typeof AddSigningKeyRequestBody>

View File

@@ -0,0 +1,9 @@
import { Static, Type } from '@sinclair/typebox'
export const GetFlowTemplateRequestQuery = Type.Object({
versionId: Type.Optional(Type.String()),
})
export type GetFlowTemplateRequestQuery = Static<typeof GetFlowTemplateRequestQuery>

View File

@@ -0,0 +1 @@
export * from './flow-template.request'

View File

@@ -0,0 +1 @@
export * from './flow-template'

View File

@@ -0,0 +1,19 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}