alepha 0.19.3 → 0.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/dist/api/audits/index.d.ts +8 -8
- package/dist/api/invitations/index.d.ts +790 -0
- package/dist/api/invitations/index.d.ts.map +1 -0
- package/dist/api/invitations/index.js +665 -0
- package/dist/api/invitations/index.js.map +1 -0
- package/dist/api/jobs/index.browser.js +8 -9
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +99 -43
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +257 -40
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +5 -5
- package/dist/api/notifications/index.browser.js +0 -1
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +3 -3
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +0 -1
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.browser.js +112 -1
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +90 -3
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +79 -12
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/{billing → api/payments}/index.d.ts +67 -49
- package/dist/api/payments/index.d.ts.map +1 -0
- package/dist/{billing → api/payments}/index.js +108 -74
- package/dist/api/payments/index.js.map +1 -0
- package/dist/api/subscriptions/index.d.ts +1692 -0
- package/dist/api/subscriptions/index.d.ts.map +1 -0
- package/dist/api/subscriptions/index.js +1870 -0
- package/dist/api/subscriptions/index.js.map +1 -0
- package/dist/api/users/index.d.ts +18 -2
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +167 -34
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +13 -13
- package/dist/api/workflows/index.browser.js +246 -0
- package/dist/api/workflows/index.browser.js.map +1 -0
- package/dist/api/workflows/index.d.ts +1618 -0
- package/dist/api/workflows/index.d.ts.map +1 -0
- package/dist/api/workflows/index.js +1504 -0
- package/dist/api/workflows/index.js.map +1 -0
- package/dist/cli/core/index.d.ts +44 -28
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +16 -61
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +31 -8
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +79 -24
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/core/index.browser.js +21 -2
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +33 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +21 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +21 -2
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +21 -2
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/email/smtp/index.js +24 -8
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +0 -18
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +0 -17
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +1 -13
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +0 -17
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +3 -3
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +3 -3
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/router/index.browser.js +25 -3
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +16 -1
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +25 -3
- package/dist/react/router/index.js.map +1 -1
- package/dist/security/index.d.ts +28 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +28 -0
- package/dist/security/index.js.map +1 -1
- package/package.json +37 -20
- package/src/api/invitations/__tests__/InvitationService.spec.ts +439 -0
- package/src/api/invitations/controllers/AdminInvitationController.ts +86 -0
- package/src/api/invitations/controllers/InvitationController.ts +84 -0
- package/src/api/invitations/entities/invitations.ts +33 -0
- package/src/api/invitations/index.ts +65 -0
- package/src/api/invitations/jobs/InvitationJobs.ts +37 -0
- package/src/api/invitations/providers/InvitationProvider.ts +45 -0
- package/src/api/invitations/schemas/createInvitationSchema.ts +12 -0
- package/src/api/invitations/schemas/invitationConfigAtom.ts +20 -0
- package/src/api/invitations/schemas/invitationQuerySchema.ts +15 -0
- package/src/api/invitations/schemas/invitationResourceSchema.ts +6 -0
- package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +22 -0
- package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +10 -0
- package/src/api/invitations/services/InvitationService.ts +556 -0
- package/src/api/jobs/__tests__/$job.spec.ts +876 -0
- package/src/api/jobs/controllers/AdminJobController.ts +44 -0
- package/src/api/jobs/entities/jobExecutionEntity.ts +0 -2
- package/src/api/jobs/index.ts +0 -3
- package/src/api/jobs/primitives/$job.ts +22 -11
- package/src/api/jobs/providers/JobProvider.ts +229 -19
- package/src/api/jobs/schemas/jobConfigAtom.ts +4 -0
- package/src/api/jobs/schemas/jobCronInfoSchema.ts +1 -0
- package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +0 -1
- package/src/api/jobs/schemas/jobQueueDepthSchema.ts +1 -0
- package/src/api/jobs/schemas/jobRegistrationSchema.ts +1 -6
- package/src/api/jobs/services/JobService.ts +51 -12
- package/src/api/notifications/schemas/notificationQuerySchema.ts +0 -1
- package/src/api/parameters/__tests__/$parameter.spec.ts +327 -0
- package/src/api/parameters/controllers/AdminParameterController.ts +29 -3
- package/src/api/parameters/index.browser.ts +12 -0
- package/src/api/parameters/primitives/$parameter.ts +20 -3
- package/src/api/parameters/services/ParameterProvider.ts +48 -7
- package/src/{billing → api/payments}/__tests__/PaymentMethodService.spec.ts +32 -6
- package/src/api/payments/__tests__/PaymentService.spec.ts +279 -0
- package/src/{billing/controllers/AdminBillingController.ts → api/payments/controllers/AdminPaymentController.ts} +26 -21
- package/src/{billing/controllers/BillingController.ts → api/payments/controllers/PaymentController.ts} +23 -11
- package/src/{billing → api/payments}/entities/paymentIntents.ts +1 -0
- package/src/{billing/errors/BillingError.ts → api/payments/errors/PaymentError.ts} +1 -1
- package/src/{billing → api/payments}/index.ts +31 -25
- package/src/{billing/providers/MemoryBillingProvider.ts → api/payments/providers/MemoryPaymentProvider.ts} +4 -4
- package/src/{billing/providers/BillingProvider.ts → api/payments/providers/PaymentProvider.ts} +9 -2
- package/src/{billing → api/payments}/services/PaymentMethodService.ts +5 -5
- package/src/{billing/services/BillingService.ts → api/payments/services/PaymentService.ts} +94 -18
- package/src/api/subscriptions/__tests__/BillingService.spec.ts +218 -0
- package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +278 -0
- package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +212 -0
- package/src/api/subscriptions/controllers/SubscriptionController.ts +189 -0
- package/src/api/subscriptions/entities/subscriptionEvents.ts +54 -0
- package/src/api/subscriptions/entities/subscriptions.ts +68 -0
- package/src/api/subscriptions/index.ts +144 -0
- package/src/api/subscriptions/jobs/SubscriptionJobs.ts +382 -0
- package/src/api/subscriptions/middleware/$requireLimit.ts +50 -0
- package/src/api/subscriptions/middleware/$requirePlan.ts +49 -0
- package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +110 -0
- package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +8 -0
- package/src/api/subscriptions/schemas/changePlanSchema.ts +9 -0
- package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +11 -0
- package/src/api/subscriptions/schemas/entitlementsSchema.ts +21 -0
- package/src/api/subscriptions/schemas/mrrSchema.ts +13 -0
- package/src/api/subscriptions/schemas/planDefinitionSchema.ts +71 -0
- package/src/api/subscriptions/schemas/planResourceSchema.ts +25 -0
- package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +8 -0
- package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +19 -0
- package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +6 -0
- package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +32 -0
- package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +23 -0
- package/src/api/subscriptions/services/BillingService.ts +437 -0
- package/src/api/subscriptions/services/SubscriptionConfig.ts +56 -0
- package/src/api/subscriptions/services/SubscriptionService.ts +867 -0
- package/src/api/subscriptions/services/UsageService.ts +118 -0
- package/src/api/users/__tests__/AdminUserController.spec.ts +80 -1
- package/src/api/users/__tests__/CredentialService.spec.ts +177 -0
- package/src/api/users/__tests__/EmailVerification.spec.ts +29 -18
- package/src/api/users/__tests__/PasswordReset.spec.ts +3 -0
- package/src/api/users/__tests__/RegistrationService.spec.ts +148 -1
- package/src/api/users/__tests__/SessionService.spec.ts +142 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -1
- package/src/api/users/controllers/UserController.ts +3 -8
- package/src/api/users/notifications/UserNotifications.ts +23 -0
- package/src/api/users/schemas/loginSchema.ts +1 -1
- package/src/api/users/services/CredentialService.ts +51 -4
- package/src/api/users/services/RegistrationService.ts +38 -9
- package/src/api/users/services/SessionService.ts +62 -9
- package/src/api/users/services/UserService.ts +21 -12
- package/src/api/workflows/__tests__/$workflow.spec.ts +616 -0
- package/src/api/workflows/controllers/AdminWorkflowController.ts +191 -0
- package/src/api/workflows/entities/workflowExecutions.ts +74 -0
- package/src/api/workflows/entities/workflowStepExecutions.ts +74 -0
- package/src/api/workflows/entities/workflowStepLogs.ts +13 -0
- package/src/api/workflows/index.browser.ts +22 -0
- package/src/api/workflows/index.ts +124 -0
- package/src/api/workflows/jobs/WorkflowJobs.ts +77 -0
- package/src/api/workflows/primitives/$workflow.ts +202 -0
- package/src/api/workflows/providers/WorkflowProvider.ts +1284 -0
- package/src/api/workflows/schemas/workflowActivitySchema.ts +15 -0
- package/src/api/workflows/schemas/workflowConfigAtom.ts +51 -0
- package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +18 -0
- package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +26 -0
- package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +30 -0
- package/src/api/workflows/schemas/workflowRegistrationSchema.ts +26 -0
- package/src/api/workflows/schemas/workflowStatsSchema.ts +16 -0
- package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +15 -0
- package/src/api/workflows/services/WorkflowService.ts +382 -0
- package/src/cli/core/templates/webAppRouterTs.ts +5 -58
- package/src/cli/vendor/__tests__/VendorService.spec.ts +283 -178
- package/src/cli/vendor/services/VendorService.ts +126 -27
- package/src/core/__tests__/TypeProvider.spec.ts +4 -2
- package/src/core/providers/SchemaValidator.ts +1 -1
- package/src/core/providers/TypeProvider.ts +46 -3
- package/src/orm/__tests__/enums.spec.ts +22 -29
- package/src/orm/__tests__/orm-showcase-tests.ts +430 -0
- package/src/orm/__tests__/orm-showcase.spec.ts +167 -0
- package/src/orm/core/providers/DatabaseTypeProvider.ts +0 -29
- package/src/orm/postgres/services/PostgresModelBuilder.ts +3 -6
- package/src/react/router/__tests__/$page.browser.spec.tsx +157 -0
- package/src/react/router/providers/ReactBrowserProvider.ts +39 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +22 -0
- package/src/security/__tests__/$secure-combinations.spec.ts +945 -0
- package/src/security/primitives/$secure.ts +28 -0
- package/dist/billing/index.d.ts.map +0 -1
- package/dist/billing/index.js.map +0 -1
- package/src/billing/__tests__/BillingService.spec.ts +0 -136
- /package/src/{billing → api/payments}/entities/paymentMethods.ts +0 -0
- /package/src/{billing → api/payments}/entities/refunds.ts +0 -0
- /package/src/{billing → api/payments}/schemas/intentSchemas.ts +0 -0
- /package/src/{billing → api/payments}/schemas/paymentMethodSchemas.ts +0 -0
- /package/src/{billing → api/payments}/schemas/refundSchemas.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/api/invitations/schemas/invitationQuerySchema.ts","../../../src/api/invitations/entities/invitations.ts","../../../src/api/invitations/schemas/invitationResourceSchema.ts","../../../src/api/invitations/providers/InvitationProvider.ts","../../../src/api/invitations/schemas/invitationConfigAtom.ts","../../../src/api/invitations/services/InvitationService.ts","../../../src/api/invitations/controllers/AdminInvitationController.ts","../../../src/api/invitations/schemas/createInvitationSchema.ts","../../../src/api/invitations/schemas/invitationWithResourceInfoSchema.ts","../../../src/api/invitations/schemas/myInvitationsQuerySchema.ts","../../../src/api/invitations/controllers/InvitationController.ts","../../../src/api/invitations/jobs/InvitationJobs.ts","../../../src/api/invitations/index.ts"],"sourcesContent":["import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const invitationQuerySchema = t.extend(pageQuerySchema, {\n email: t.optional(t.text({ description: \"Filter by invited email\" })),\n resourceType: t.optional(t.text({ description: \"Filter by resource type\" })),\n resourceId: t.optional(t.text({ description: \"Filter by resource ID\" })),\n status: t.optional(\n t.enum([\"pending\", \"accepted\", \"declined\", \"expired\", \"revoked\"]),\n ),\n invitedBy: t.optional(t.uuid()),\n});\n\nexport type InvitationQuery = Static<typeof invitationQuerySchema>;\n","import { type Static, t } from \"alepha\";\nimport { users } from \"alepha/api/users\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const invitations = $entity({\n name: \"invitations\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n version: db.version(),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n invitedBy: db.ref(t.uuid(), () => users.cols.id, { onDelete: \"cascade\" }),\n email: t.string({ format: \"email\" }),\n resourceType: t.text({ minLength: 1, maxLength: 100 }),\n resourceId: t.text({ minLength: 1, maxLength: 255 }),\n status: t.enum([\"pending\", \"accepted\", \"declined\", \"expired\", \"revoked\"]),\n roles: t.optional(t.array(t.text())),\n metadata: t.optional(t.record(t.text(), t.any())),\n token: t.text(),\n expiresAt: t.datetime(),\n resolvedAt: t.optional(t.datetime()),\n resolvedBy: t.optional(db.ref(t.uuid(), () => users.cols.id)),\n }),\n indexes: [\n { columns: [\"email\", \"status\"] },\n { columns: [\"resourceType\", \"resourceId\", \"email\", \"status\"] },\n { columns: [\"invitedBy\"] },\n { columns: [\"expiresAt\"] },\n { columns: [\"token\"], unique: true },\n ],\n});\n\nexport type InvitationEntity = Static<typeof invitations.schema>;\n","import type { Static } from \"alepha\";\nimport { invitations } from \"../entities/invitations.ts\";\n\nexport const invitationResourceSchema = invitations.schema;\n\nexport type InvitationResource = Static<typeof invitationResourceSchema>;\n","import type { InvitationEntity } from \"../entities/invitations.ts\";\n\n/**\n * Abstract provider that apps implement to customize invitation behavior\n * per resource type.\n */\nexport abstract class InvitationProvider {\n /**\n * Validate that the resource exists and the inviter has permission to invite.\n * Throw BadRequestError/ForbiddenError to reject.\n */\n abstract validateResource(\n resourceType: string,\n resourceId: string,\n inviter: { id: string; email?: string },\n ): Promise<void>;\n\n /**\n * Check if the email is already a member of the resource.\n * Return true to reject the invitation as duplicate membership.\n */\n abstract isMember(\n resourceType: string,\n resourceId: string,\n email: string,\n userId?: string,\n ): Promise<boolean>;\n\n /**\n * Called when an invitation is accepted.\n * Create membership records, assign roles, etc.\n */\n abstract onAccept(\n invitation: InvitationEntity,\n acceptedBy: { id: string; email?: string },\n ): Promise<void>;\n\n /**\n * Return display info for the resource (used in API responses).\n */\n abstract getResourceInfo(\n resourceType: string,\n resourceId: string,\n ): Promise<{ name: string; description?: string; url?: string }>;\n}\n","import { $atom, t } from \"alepha\";\n\nexport const invitationConfigAtom = $atom({\n name: \"alepha.api.invitations.config\",\n schema: t.object({\n expirationDays: t.integer({ minimum: 1, maximum: 90 }),\n maxPendingPerResource: t.integer({ minimum: 1, maximum: 500 }),\n maxPendingPerInviter: t.integer({\n minimum: 1,\n maximum: 1000,\n }),\n purgeDays: t.integer({ minimum: 0, maximum: 365 }),\n }),\n default: {\n expirationDays: 7,\n maxPendingPerResource: 50,\n maxPendingPerInviter: 100,\n purgeDays: 90,\n },\n});\n","import { $inject, Alepha } from \"alepha\";\nimport { type UserEntity, users } from \"alepha/api/users\";\nimport { CryptoProvider } from \"alepha/crypto\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { $repository, type Page } from \"alepha/orm\";\nimport { BadRequestError, ForbiddenError } from \"alepha/server\";\nimport { type InvitationEntity, invitations } from \"../entities/invitations.ts\";\nimport { InvitationProvider } from \"../providers/InvitationProvider.ts\";\nimport type { CreateInvitation } from \"../schemas/createInvitationSchema.ts\";\nimport { invitationConfigAtom } from \"../schemas/invitationConfigAtom.ts\";\nimport type { InvitationQuery } from \"../schemas/invitationQuerySchema.ts\";\nimport type { InvitationWithResourceInfo } from \"../schemas/invitationWithResourceInfoSchema.ts\";\nimport type { MyInvitationsQuery } from \"../schemas/myInvitationsQuerySchema.ts\";\n\nexport class InvitationService {\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly repo = $repository(invitations);\n protected readonly users = $repository(users);\n protected readonly crypto = $inject(CryptoProvider);\n protected readonly dateTime = $inject(DateTimeProvider);\n protected readonly provider = $inject(InvitationProvider);\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Get an invitation by ID.\n */\n public async getById(id: string): Promise<InvitationEntity> {\n return this.repo.getById(id);\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Create a new invitation.\n */\n public async create(\n data: CreateInvitation,\n inviter: { id: string; email?: string },\n ): Promise<InvitationEntity> {\n if (data.email === inviter.email) {\n throw new BadRequestError(\"Cannot invite yourself\");\n }\n\n await this.provider.validateResource(\n data.resourceType,\n data.resourceId,\n inviter,\n );\n\n const existingUser = await this.users.findOne({\n where: { email: { eq: data.email } },\n });\n\n if (existingUser) {\n const alreadyMember = await this.provider.isMember(\n data.resourceType,\n data.resourceId,\n data.email,\n existingUser.id,\n );\n\n if (alreadyMember) {\n throw new BadRequestError(\"User is already a member of this resource\");\n }\n }\n\n const pendingForSameTarget = await this.repo.findOne({\n where: {\n resourceType: { eq: data.resourceType },\n resourceId: { eq: data.resourceId },\n email: { eq: data.email },\n status: { eq: \"pending\" },\n },\n });\n\n if (pendingForSameTarget) {\n throw new BadRequestError(\n \"A pending invitation already exists for this email and resource\",\n );\n }\n\n const config = this.alepha.store.get(invitationConfigAtom);\n\n const resourcePendingCount = await this.repo.count({\n resourceType: { eq: data.resourceType },\n resourceId: { eq: data.resourceId },\n status: { eq: \"pending\" },\n });\n\n if (resourcePendingCount >= config.maxPendingPerResource) {\n throw new BadRequestError(\n `Maximum pending invitations per resource reached (${config.maxPendingPerResource})`,\n );\n }\n\n const inviterPendingCount = await this.repo.count({\n invitedBy: { eq: inviter.id },\n status: { eq: \"pending\" },\n });\n\n if (inviterPendingCount >= config.maxPendingPerInviter) {\n throw new BadRequestError(\n `Maximum pending invitations per inviter reached (${config.maxPendingPerInviter})`,\n );\n }\n\n const token = this.crypto.randomUUID();\n const tokenHash = this.crypto.hash(token, \"sha256\");\n const expiresAt = this.dateTime\n .now()\n .add(config.expirationDays, \"days\")\n .toISOString();\n\n const entity = await this.repo.create({\n invitedBy: inviter.id,\n email: data.email,\n resourceType: data.resourceType,\n resourceId: data.resourceId,\n status: \"pending\",\n roles: data.roles,\n metadata: data.metadata,\n token: tokenHash,\n expiresAt,\n });\n\n this.log.info(\"Invitation created\", {\n id: entity.id,\n email: data.email,\n resourceType: data.resourceType,\n resourceId: data.resourceId,\n invitedBy: inviter.id,\n });\n\n await this.alepha.events.emit(\"invitation:created\", {\n invitation: entity,\n token,\n inviter,\n });\n\n return entity;\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Accept a pending invitation.\n */\n public async accept(\n invitationId: string,\n acceptedBy: { id: string; email?: string },\n ): Promise<void> {\n const invitation = await this.repo.getById(invitationId);\n\n if (invitation.status !== \"pending\") {\n throw new BadRequestError(\n `Invitation is not pending (current status: ${invitation.status})`,\n );\n }\n\n if (invitation.email !== acceptedBy.email) {\n throw new ForbiddenError(\"This invitation was sent to a different email\");\n }\n\n const now = this.dateTime.now();\n\n if (now.isAfter(invitation.expiresAt)) {\n await this.repo.updateById(invitationId, {\n status: \"expired\",\n resolvedAt: now.toISOString(),\n });\n throw new BadRequestError(\"Invitation has expired\");\n }\n\n const alreadyMember = await this.provider.isMember(\n invitation.resourceType,\n invitation.resourceId,\n invitation.email,\n acceptedBy.id,\n );\n\n if (alreadyMember) {\n await this.repo.updateById(invitationId, {\n status: \"accepted\",\n resolvedAt: now.toISOString(),\n resolvedBy: acceptedBy.id,\n });\n\n this.log.info(\"Invitation accepted (already member)\", {\n id: invitationId,\n acceptedBy: acceptedBy.id,\n });\n\n return;\n }\n\n await this.provider.onAccept(invitation, acceptedBy);\n\n await this.repo.updateById(invitationId, {\n status: \"accepted\",\n resolvedAt: now.toISOString(),\n resolvedBy: acceptedBy.id,\n });\n\n this.log.info(\"Invitation accepted\", {\n id: invitationId,\n email: invitation.email,\n resourceType: invitation.resourceType,\n resourceId: invitation.resourceId,\n acceptedBy: acceptedBy.id,\n });\n\n await this.alepha.events.emit(\"invitation:accepted\", {\n invitation,\n acceptedBy,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Decline a pending invitation.\n */\n public async decline(\n invitationId: string,\n declinedBy: { id: string; email?: string },\n ): Promise<void> {\n const invitation = await this.repo.getById(invitationId);\n\n if (invitation.status !== \"pending\") {\n throw new BadRequestError(\n `Invitation is not pending (current status: ${invitation.status})`,\n );\n }\n\n if (invitation.email !== declinedBy.email) {\n throw new ForbiddenError(\"This invitation was sent to a different email\");\n }\n\n const now = this.dateTime.now();\n\n await this.repo.updateById(invitationId, {\n status: \"declined\",\n resolvedAt: now.toISOString(),\n resolvedBy: declinedBy.id,\n });\n\n this.log.info(\"Invitation declined\", {\n id: invitationId,\n email: invitation.email,\n resourceType: invitation.resourceType,\n resourceId: invitation.resourceId,\n declinedBy: declinedBy.id,\n });\n\n await this.alepha.events.emit(\"invitation:declined\", {\n invitation,\n declinedBy,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Revoke a pending invitation (by the inviter or admin).\n */\n public async revoke(\n invitationId: string,\n revokedBy: { id: string },\n ): Promise<void> {\n const invitation = await this.repo.getById(invitationId);\n\n if (invitation.status !== \"pending\") {\n throw new BadRequestError(\n `Invitation is not pending (current status: ${invitation.status})`,\n );\n }\n\n const now = this.dateTime.now();\n\n await this.repo.updateById(invitationId, {\n status: \"revoked\",\n resolvedAt: now.toISOString(),\n resolvedBy: revokedBy.id,\n });\n\n this.log.info(\"Invitation revoked\", {\n id: invitationId,\n email: invitation.email,\n resourceType: invitation.resourceType,\n resourceId: invitation.resourceId,\n revokedBy: revokedBy.id,\n });\n\n await this.alepha.events.emit(\"invitation:revoked\", {\n invitation,\n revokedBy,\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Find invitations for a given email with resource info enrichment.\n */\n public async findByEmail(\n email: string,\n query: MyInvitationsQuery = {},\n ): Promise<InvitationWithResourceInfo[]> {\n const where = this.repo.createQueryWhere();\n where.email = { eq: email };\n\n if (query.status) {\n where.status = { eq: query.status };\n }\n\n const results = await this.repo.findMany({\n where,\n orderBy: { column: \"createdAt\", direction: \"desc\" },\n });\n\n const inviterIds = [...new Set(results.map((inv) => inv.invitedBy))];\n const inviters = await this.loadInviters(inviterIds);\n\n const enriched: InvitationWithResourceInfo[] = [];\n\n for (const inv of results) {\n const inviter = inviters.get(inv.invitedBy);\n let resourceName = inv.resourceType;\n let resourceUrl: string | undefined;\n\n try {\n const info = await this.provider.getResourceInfo(\n inv.resourceType,\n inv.resourceId,\n );\n resourceName = info.name;\n resourceUrl = info.url;\n } catch (error) {\n this.log.warn(\"Failed to load resource info for invitation\", {\n invitationId: inv.id,\n resourceType: inv.resourceType,\n resourceId: inv.resourceId,\n error,\n });\n }\n\n enriched.push({\n id: inv.id,\n email: inv.email,\n resourceType: inv.resourceType,\n resourceId: inv.resourceId,\n resourceName,\n resourceUrl,\n invitedBy: inv.invitedBy,\n inviterName: this.formatInviterName(inviter),\n inviterEmail: inviter?.email,\n roles: inv.roles,\n status: inv.status,\n createdAt: inv.createdAt,\n expiresAt: inv.expiresAt,\n });\n }\n\n return enriched;\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Find invitations for a specific resource.\n */\n public async findByResource(\n resourceType: string,\n resourceId: string,\n status?: string,\n ): Promise<InvitationEntity[]> {\n const where = this.repo.createQueryWhere();\n where.resourceType = { eq: resourceType };\n where.resourceId = { eq: resourceId };\n\n if (status) {\n where.status = { eq: status as InvitationEntity[\"status\"] };\n }\n\n return this.repo.findMany({\n where,\n orderBy: { column: \"createdAt\", direction: \"desc\" },\n });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Find invitations with pagination and filtering (admin).\n */\n public async findInvitations(\n query: InvitationQuery = {},\n ): Promise<Page<InvitationEntity>> {\n query.sort ??= \"-createdAt\";\n\n const where = this.repo.createQueryWhere();\n\n if (query.email) {\n where.email = { like: `%${query.email}%` };\n }\n\n if (query.resourceType) {\n where.resourceType = { eq: query.resourceType };\n }\n\n if (query.resourceId) {\n where.resourceId = { eq: query.resourceId };\n }\n\n if (query.status) {\n where.status = { eq: query.status };\n }\n\n if (query.invitedBy) {\n where.invitedBy = { eq: query.invitedBy };\n }\n\n return this.repo.paginate(query, { where }, { count: true });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Delete an invitation (admin). Only non-pending invitations can be deleted.\n */\n public async deleteInvitation(id: string): Promise<void> {\n const invitation = await this.repo.getById(id);\n\n if (invitation.status === \"pending\") {\n throw new BadRequestError(\n \"Cannot delete a pending invitation. Revoke it first.\",\n );\n }\n\n await this.repo.deleteById(id);\n\n this.log.info(\"Invitation deleted\", { id });\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Expire all pending invitations that have passed their expiration date.\n * Returns the number of expired invitations.\n */\n public async expirePending(): Promise<number> {\n const now = this.dateTime.nowISOString();\n\n const expired = await this.repo.findMany({\n where: {\n status: { eq: \"pending\" },\n expiresAt: { lt: now },\n },\n });\n\n if (expired.length === 0) {\n return 0;\n }\n\n const ids = expired.map((inv) => inv.id);\n\n await this.repo.updateMany(\n { id: { inArray: ids } },\n {\n status: \"expired\",\n resolvedAt: now,\n },\n );\n\n for (const inv of expired) {\n await this.alepha.events.emit(\"invitation:expired\", {\n invitation: inv,\n });\n }\n\n this.log.info(\"Expired pending invitations\", { count: expired.length });\n\n return expired.length;\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Purge resolved invitations older than the configured purge days.\n * Returns the number of purged invitations.\n */\n public async purgeResolved(): Promise<number> {\n const config = this.alepha.store.get(invitationConfigAtom);\n\n if (config.purgeDays === 0) {\n return 0;\n }\n\n const cutoff = this.dateTime\n .now()\n .subtract(config.purgeDays, \"days\")\n .toISOString();\n\n const ids = await this.repo.deleteMany({\n status: { inArray: [\"accepted\", \"declined\", \"expired\", \"revoked\"] },\n resolvedAt: { lt: cutoff },\n });\n\n if (ids.length > 0) {\n this.log.info(\"Purged resolved invitations\", { count: ids.length });\n }\n\n return ids.length;\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Load user records for a list of inviter IDs.\n */\n protected async loadInviters(\n ids: string[],\n ): Promise<Map<string, UserEntity>> {\n if (ids.length === 0) {\n return new Map();\n }\n\n const result = await this.users.findMany({\n where: { id: { inArray: ids } },\n });\n\n return new Map(result.map((user) => [user.id, user]));\n }\n\n /**\n * Format inviter display name from user entity.\n */\n protected formatInviterName(user?: UserEntity): string | undefined {\n if (!user) {\n return undefined;\n }\n\n if (user.firstName && user.lastName) {\n return `${user.firstName} ${user.lastName}`;\n }\n\n if (user.firstName) {\n return user.firstName;\n }\n\n return user.username ?? user.email;\n }\n}\n","import { $inject, t } from \"alepha\";\nimport { $secure } from \"alepha/security\";\nimport { $action, okSchema } from \"alepha/server\";\nimport { invitationQuerySchema } from \"../schemas/invitationQuerySchema.ts\";\nimport { invitationResourceSchema } from \"../schemas/invitationResourceSchema.ts\";\nimport { InvitationService } from \"../services/InvitationService.ts\";\n\nexport class AdminInvitationController {\n protected readonly url = \"/invitations\";\n protected readonly group = \"admin:invitations\";\n protected readonly invitationService = $inject(InvitationService);\n\n /**\n * Find invitations with pagination and filtering.\n */\n public readonly findInvitations = $action({\n path: this.url,\n group: this.group,\n use: [$secure({ permissions: [\"admin:invitation:read\"] })],\n description: \"Find invitations with pagination and filtering\",\n schema: {\n query: invitationQuerySchema,\n response: t.page(invitationResourceSchema),\n },\n handler: ({ query }) => this.invitationService.findInvitations(query),\n });\n\n /**\n * Get an invitation by ID.\n */\n public readonly getInvitation = $action({\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:invitation:read\"] })],\n description: \"Get an invitation by ID\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: invitationResourceSchema,\n },\n handler: ({ params }) => this.invitationService.getById(params.id),\n });\n\n /**\n * Revoke a pending invitation.\n */\n public readonly revokeInvitation = $action({\n method: \"POST\",\n path: `${this.url}/:id/revoke`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:invitation:delete\"] })],\n description: \"Revoke a pending invitation\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: okSchema,\n },\n handler: async ({ params, user }) => {\n await this.invitationService.revoke(params.id, { id: user.id });\n return { ok: true };\n },\n });\n\n /**\n * Delete an invitation.\n */\n public readonly deleteInvitation = $action({\n method: \"DELETE\",\n path: `${this.url}/:id`,\n group: this.group,\n use: [$secure({ permissions: [\"admin:invitation:delete\"] })],\n description: \"Delete an invitation\",\n schema: {\n params: t.object({\n id: t.uuid(),\n }),\n response: okSchema,\n },\n handler: async ({ params }) => {\n await this.invitationService.deleteInvitation(params.id);\n return { ok: true, id: params.id };\n },\n });\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const createInvitationSchema = t.object({\n email: t.string({ format: \"email\" }),\n resourceType: t.text({ minLength: 1, maxLength: 100 }),\n resourceId: t.text({ minLength: 1, maxLength: 255 }),\n roles: t.optional(t.array(t.text())),\n metadata: t.optional(t.record(t.text(), t.any())),\n});\n\nexport type CreateInvitation = Static<typeof createInvitationSchema>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const invitationWithResourceInfoSchema = t.object({\n id: t.uuid(),\n email: t.string({ format: \"email\" }),\n resourceType: t.text(),\n resourceId: t.text(),\n resourceName: t.text(),\n resourceUrl: t.optional(t.text()),\n invitedBy: t.uuid(),\n inviterName: t.optional(t.text()),\n inviterEmail: t.optional(t.string({ format: \"email\" })),\n roles: t.optional(t.array(t.text())),\n status: t.enum([\"pending\", \"accepted\", \"declined\", \"expired\", \"revoked\"]),\n createdAt: t.datetime(),\n expiresAt: t.datetime(),\n});\n\nexport type InvitationWithResourceInfo = Static<\n typeof invitationWithResourceInfoSchema\n>;\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const myInvitationsQuerySchema = t.object({\n status: t.optional(\n t.enum([\"pending\", \"accepted\", \"declined\", \"expired\", \"revoked\"]),\n ),\n});\n\nexport type MyInvitationsQuery = Static<typeof myInvitationsQuerySchema>;\n","import { $inject, t } from \"alepha\";\nimport { $secure } from \"alepha/security\";\nimport { $action, okSchema } from \"alepha/server\";\nimport { createInvitationSchema } from \"../schemas/createInvitationSchema.ts\";\nimport { invitationResourceSchema } from \"../schemas/invitationResourceSchema.ts\";\nimport { invitationWithResourceInfoSchema } from \"../schemas/invitationWithResourceInfoSchema.ts\";\nimport { myInvitationsQuerySchema } from \"../schemas/myInvitationsQuerySchema.ts\";\nimport { InvitationService } from \"../services/InvitationService.ts\";\n\nexport class InvitationController {\n protected readonly url = \"/invitations\";\n protected readonly group = \"invitations\";\n protected readonly invitationService = $inject(InvitationService);\n\n /**\n * Create a new invitation.\n */\n public readonly createInvitation = $action({\n method: \"POST\",\n path: this.url,\n group: this.group,\n use: [$secure({ permissions: [\"invitation:create\"] })],\n description: \"Create a new invitation\",\n schema: {\n body: createInvitationSchema,\n response: invitationResourceSchema,\n },\n handler: ({ body, user }) => this.invitationService.create(body, user),\n });\n\n /**\n * List invitations for the current user.\n */\n public readonly getMyInvitations = $action({\n path: `${this.url}/mine`,\n group: this.group,\n use: [$secure()],\n description: \"List invitations for the current user\",\n schema: {\n query: myInvitationsQuerySchema,\n response: t.array(invitationWithResourceInfoSchema),\n },\n handler: ({ query, user }) =>\n this.invitationService.findByEmail(user.email!, query),\n });\n\n /**\n * Accept an invitation.\n */\n public readonly acceptInvitation = $action({\n method: \"POST\",\n path: `${this.url}/:id/accept`,\n group: this.group,\n use: [$secure()],\n description: \"Accept an invitation\",\n schema: {\n params: t.object({ id: t.uuid() }),\n response: okSchema,\n },\n handler: async ({ params, user }) => {\n await this.invitationService.accept(params.id, user);\n return { ok: true };\n },\n });\n\n /**\n * Decline an invitation.\n */\n public readonly declineInvitation = $action({\n method: \"POST\",\n path: `${this.url}/:id/decline`,\n group: this.group,\n use: [$secure()],\n description: \"Decline an invitation\",\n schema: {\n params: t.object({ id: t.uuid() }),\n response: okSchema,\n },\n handler: async ({ params, user }) => {\n await this.invitationService.decline(params.id, user);\n return { ok: true };\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $job } from \"alepha/api/jobs\";\nimport { $logger } from \"alepha/logger\";\nimport { InvitationService } from \"../services/InvitationService.ts\";\n\nexport class InvitationJobs {\n protected readonly log = $logger();\n protected readonly invitationService = $inject(InvitationService);\n\n /**\n * Expire pending invitations that have passed their expiration date.\n */\n public readonly expireInvitations = $job({\n cron: \"0 * * * *\",\n lock: true,\n handler: async () => {\n const count = await this.invitationService.expirePending();\n if (count > 0) {\n this.log.info(`Expired ${count} invitations`);\n }\n },\n });\n\n /**\n * Purge old resolved invitations.\n */\n public readonly purgeInvitations = $job({\n cron: \"0 3 * * *\",\n lock: true,\n handler: async () => {\n const count = await this.invitationService.purgeResolved();\n if (count > 0) {\n this.log.info(`Purged ${count} old invitations`);\n }\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { AdminInvitationController } from \"./controllers/AdminInvitationController.ts\";\nimport { InvitationController } from \"./controllers/InvitationController.ts\";\nimport { InvitationJobs } from \"./jobs/InvitationJobs.ts\";\nimport { InvitationService } from \"./services/InvitationService.ts\";\n\nexport * from \"./controllers/AdminInvitationController.ts\";\nexport * from \"./controllers/InvitationController.ts\";\nexport * from \"./entities/invitations.ts\";\nexport * from \"./jobs/InvitationJobs.ts\";\nexport * from \"./providers/InvitationProvider.ts\";\nexport * from \"./schemas/createInvitationSchema.ts\";\nexport * from \"./schemas/invitationConfigAtom.ts\";\nexport * from \"./schemas/invitationQuerySchema.ts\";\nexport * from \"./schemas/invitationResourceSchema.ts\";\nexport * from \"./schemas/invitationWithResourceInfoSchema.ts\";\nexport * from \"./schemas/myInvitationsQuerySchema.ts\";\nexport * from \"./services/InvitationService.ts\";\n\ndeclare module \"alepha\" {\n interface Hooks {\n \"invitation:created\": {\n invitation: import(\"./entities/invitations.ts\").InvitationEntity;\n token: string;\n inviter: { id: string; email?: string };\n };\n \"invitation:accepted\": {\n invitation: import(\"./entities/invitations.ts\").InvitationEntity;\n acceptedBy: { id: string; email?: string };\n };\n \"invitation:declined\": {\n invitation: import(\"./entities/invitations.ts\").InvitationEntity;\n declinedBy: { id: string; email?: string };\n };\n \"invitation:expired\": {\n invitation: import(\"./entities/invitations.ts\").InvitationEntity;\n };\n \"invitation:revoked\": {\n invitation: import(\"./entities/invitations.ts\").InvitationEntity;\n revokedBy: { id: string };\n };\n }\n}\n\n/**\n * Invitation management module — create, accept, decline, revoke, and expire invitations.\n *\n * @module alepha.api.invitations\n */\nexport const AlephaApiInvitations = $module({\n name: \"alepha.api.invitations\",\n services: [\n InvitationService,\n InvitationJobs,\n InvitationController,\n AdminInvitationController,\n ],\n register: (alepha) => {\n alepha\n .with(InvitationService)\n .with(InvitationJobs)\n .with(InvitationController)\n .with(AdminInvitationController);\n },\n});\n"],"mappings":"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"}
|
|
@@ -17,7 +17,6 @@ const jobExecutionEntity = $entity({
|
|
|
17
17
|
"retrying",
|
|
18
18
|
"running",
|
|
19
19
|
"completed",
|
|
20
|
-
"failed",
|
|
21
20
|
"dead",
|
|
22
21
|
"cancelled"
|
|
23
22
|
]), "pending"),
|
|
@@ -90,7 +89,8 @@ const jobConfig = $atom({
|
|
|
90
89
|
}),
|
|
91
90
|
delayed: t.object({ interval: t.integer({ description: "Sweep interval (ms)." }) }),
|
|
92
91
|
logRetentionDays: t.integer({ description: "Days to keep completed/dead executions." }),
|
|
93
|
-
logMaxEntries: t.integer({ description: "Max log entries captured per execution." })
|
|
92
|
+
logMaxEntries: t.integer({ description: "Max log entries captured per execution." }),
|
|
93
|
+
drainTimeout: t.integer({ description: "Max time (ms) to wait for in-flight jobs during shutdown." })
|
|
94
94
|
}),
|
|
95
95
|
default: {
|
|
96
96
|
recovery: {
|
|
@@ -100,7 +100,8 @@ const jobConfig = $atom({
|
|
|
100
100
|
},
|
|
101
101
|
delayed: { interval: 3e5 },
|
|
102
102
|
logRetentionDays: 30,
|
|
103
|
-
logMaxEntries: 100
|
|
103
|
+
logMaxEntries: 100,
|
|
104
|
+
drainTimeout: 3e4
|
|
104
105
|
}
|
|
105
106
|
});
|
|
106
107
|
//#endregion
|
|
@@ -117,6 +118,7 @@ const jobCronInfoSchema = t.object({
|
|
|
117
118
|
]),
|
|
118
119
|
concurrency: t.integer(),
|
|
119
120
|
hasSchema: t.boolean(),
|
|
121
|
+
paused: t.boolean(),
|
|
120
122
|
lastExecution: t.optional(t.object({
|
|
121
123
|
id: t.uuid(),
|
|
122
124
|
status: t.text(),
|
|
@@ -154,7 +156,6 @@ const jobExecutionQuerySchema = t.extend(pageQuerySchema, {
|
|
|
154
156
|
"retrying",
|
|
155
157
|
"running",
|
|
156
158
|
"completed",
|
|
157
|
-
"failed",
|
|
158
159
|
"dead",
|
|
159
160
|
"cancelled"
|
|
160
161
|
])),
|
|
@@ -183,7 +184,8 @@ const jobQueueDepthSchema = t.object({
|
|
|
183
184
|
scheduled: t.integer(),
|
|
184
185
|
retrying: t.integer(),
|
|
185
186
|
dead: t.integer(),
|
|
186
|
-
concurrency: t.integer()
|
|
187
|
+
concurrency: t.integer(),
|
|
188
|
+
paused: t.boolean()
|
|
187
189
|
});
|
|
188
190
|
//#endregion
|
|
189
191
|
//#region ../../src/api/jobs/schemas/jobRegistrationSchema.ts
|
|
@@ -208,10 +210,7 @@ const jobRegistrationSchema = t.object({
|
|
|
208
210
|
retries: t.integer(),
|
|
209
211
|
hasBackoff: t.boolean()
|
|
210
212
|
})),
|
|
211
|
-
|
|
212
|
-
size: t.integer(),
|
|
213
|
-
window: t.text()
|
|
214
|
-
}))
|
|
213
|
+
paused: t.boolean()
|
|
215
214
|
});
|
|
216
215
|
//#endregion
|
|
217
216
|
//#region ../../src/api/jobs/schemas/jobStatsSchema.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/jobs/entities/jobExecutionEntity.ts","../../../src/api/jobs/entities/jobExecutionLogEntity.ts","../../../src/api/jobs/schemas/jobActivitySchema.ts","../../../src/api/jobs/schemas/jobConfigAtom.ts","../../../src/api/jobs/schemas/jobCronInfoSchema.ts","../../../src/api/jobs/schemas/jobExecutionResourceSchema.ts","../../../src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts","../../../src/api/jobs/schemas/jobExecutionQuerySchema.ts","../../../src/api/jobs/schemas/jobFailureSchema.ts","../../../src/api/jobs/schemas/jobQueueDepthSchema.ts","../../../src/api/jobs/schemas/jobRegistrationSchema.ts","../../../src/api/jobs/schemas/jobStatsSchema.ts","../../../src/api/jobs/schemas/triggerJobSchema.ts","../../../src/api/jobs/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const jobExecutionEntity = $entity({\n name: \"job_executions\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n\n jobName: t.text(),\n key: t.optional(t.nullable(t.text())),\n\n payload: t.optional(t.record(t.text(), t.any())),\n status: db.default(\n t.enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"failed\",\n \"dead\",\n \"cancelled\",\n ]),\n \"pending\",\n ),\n priority: db.default(t.integer({ minimum: 0, maximum: 3 }), 2),\n\n attempt: db.default(t.integer(), 0),\n maxAttempts: db.default(t.integer(), 1),\n\n scheduledAt: t.optional(t.datetime()),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n\n result: t.optional(t.record(t.text(), t.any())),\n error: t.optional(t.text()),\n workerId: t.optional(t.text()),\n\n triggeredBy: t.optional(t.text()),\n triggeredByName: t.optional(t.text()),\n cancelledBy: t.optional(t.text()),\n cancelledByName: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"jobName\", \"status\", \"priority\", \"scheduledAt\"] },\n { columns: [\"jobName\", \"status\", \"startedAt\"] },\n { columns: [\"jobName\", \"completedAt\"] },\n { columns: [\"jobName\", \"key\"], unique: true },\n ],\n});\n\nexport type JobExecutionEntity = Static<typeof jobExecutionEntity.schema>;\n\nexport type JobStatus =\n | \"pending\"\n | \"scheduled\"\n | \"retrying\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"dead\"\n | \"cancelled\";\n","import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const jobExecutionLogEntity = $entity({\n name: \"job_execution_logs\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n logs: t.array(logEntrySchema),\n }),\n});\n\nexport type JobExecutionLogEntity = Static<typeof jobExecutionLogEntity.schema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobActivityPointSchema = t.object({\n date: t.text(),\n completed: t.integer(),\n failed: t.integer(),\n});\n\nexport type JobActivityPoint = Static<typeof jobActivityPointSchema>;\n\nexport const jobActivityQuerySchema = t.object({\n days: t.optional(t.integer({ minimum: 1, maximum: 90 })),\n});\n\nexport type JobActivityQuery = Static<typeof jobActivityQuerySchema>;\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const jobConfig = $atom({\n name: \"alepha.jobs\",\n description: \"Configuration for the $job v2 primitive.\",\n schema: t.object({\n recovery: t.object({\n interval: t.integer({ description: \"Sweep interval (ms).\" }),\n staleThreshold: t.integer({\n description: \"Pending age (ms) before re-dispatch.\",\n }),\n runTimeout: t.integer({\n description:\n \"Running age (ms) before assumed crash. Used as fallback when no per-job timeout is set.\",\n }),\n }),\n delayed: t.object({\n interval: t.integer({ description: \"Sweep interval (ms).\" }),\n }),\n logRetentionDays: t.integer({\n description: \"Days to keep completed/dead executions.\",\n }),\n logMaxEntries: t.integer({\n description: \"Max log entries captured per execution.\",\n }),\n }),\n default: {\n recovery: {\n interval: 300_000,\n staleThreshold: 300_000,\n runTimeout: 1_800_000,\n },\n delayed: {\n interval: 300_000,\n },\n logRetentionDays: 30,\n logMaxEntries: 100,\n },\n});\n\nexport type JobConfig = Static<typeof jobConfig.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [jobConfig.key]: JobConfig;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const jobCronInfoSchema = t.object({\n name: t.text(),\n cron: t.text(),\n lock: t.boolean(),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n concurrency: t.integer(),\n hasSchema: t.boolean(),\n lastExecution: t.optional(\n t.object({\n id: t.uuid(),\n status: t.text(),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n error: t.optional(t.text()),\n }),\n ),\n});\n\nexport type JobCronInfo = Static<typeof jobCronInfoSchema>;\n","import { type Static, t } from \"alepha\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\n\nexport const jobExecutionCanSchema = t.object({\n retry: t.boolean(),\n cancel: t.boolean(),\n});\n\nexport const jobExecutionResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n can: jobExecutionCanSchema,\n },\n {\n title: \"JobExecutionResource\",\n description: \"A job execution resource.\",\n },\n);\n\nexport type JobExecutionResource = Static<typeof jobExecutionResourceSchema>;\n","import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\nimport { jobExecutionCanSchema } from \"./jobExecutionResourceSchema.ts\";\n\nexport const jobExecutionDetailResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n can: jobExecutionCanSchema,\n logs: t.optional(t.array(logEntrySchema)),\n },\n {\n title: \"JobExecutionDetailResource\",\n description: \"A job execution resource with logs.\",\n },\n);\n\nexport type JobExecutionDetailResource = Static<\n typeof jobExecutionDetailResourceSchema\n>;\n","import { type Static, t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const jobExecutionQuerySchema = t.extend(pageQuerySchema, {\n job: t.optional(\n t.text({\n description: \"Filter by job name\",\n }),\n ),\n status: t.optional(\n t.enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"failed\",\n \"dead\",\n \"cancelled\",\n ]),\n ),\n priority: t.optional(t.enum([\"critical\", \"high\", \"normal\", \"low\"])),\n from: t.optional(\n t.datetime({\n description: \"From date (ISO)\",\n }),\n ),\n to: t.optional(\n t.datetime({\n description: \"To date (ISO)\",\n }),\n ),\n});\n\nexport type JobExecutionQuery = Static<typeof jobExecutionQuerySchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobFailureSchema = t.object({\n jobName: t.text(),\n failures: t.integer(),\n lastError: t.optional(t.text()),\n});\n\nexport type JobFailure = Static<typeof jobFailureSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobQueueDepthSchema = t.object({\n jobName: t.text(),\n pending: t.integer(),\n running: t.integer(),\n scheduled: t.integer(),\n retrying: t.integer(),\n dead: t.integer(),\n concurrency: t.integer(),\n});\n\nexport type JobQueueDepth = Static<typeof jobQueueDepthSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobRegistrationSchema = t.object({\n name: t.text(),\n type: t.enum([\"cron\", \"push\", \"both\"]),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n concurrency: t.integer(),\n hasSchema: t.boolean(),\n cron: t.optional(t.text()),\n timeout: t.optional(t.text()),\n retry: t.optional(\n t.object({\n retries: t.integer(),\n hasBackoff: t.boolean(),\n }),\n ),\n batch: t.optional(\n t.object({\n size: t.integer(),\n window: t.text(),\n }),\n ),\n});\n\nexport type JobRegistration = Static<typeof jobRegistrationSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobStatsSchema = t.object({\n registered: t.integer(),\n running: t.integer(),\n pending: t.integer(),\n scheduled: t.integer(),\n retrying: t.integer(),\n dead: t.integer(),\n completed: t.integer(),\n failed: t.integer(),\n});\n\nexport type JobStats = Static<typeof jobStatsSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const triggerJobSchema = t.object({\n name: t.text(),\n payload: t.optional(t.record(t.text(), t.any())),\n});\n\nexport type TriggerJob = Static<typeof triggerJobSchema>;\n","import { $module } from \"alepha\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/jobExecutionEntity.ts\";\nexport * from \"./entities/jobExecutionLogEntity.ts\";\nexport * from \"./schemas/jobActivitySchema.ts\";\nexport * from \"./schemas/jobConfigAtom.ts\";\nexport * from \"./schemas/jobCronInfoSchema.ts\";\nexport * from \"./schemas/jobExecutionDetailResourceSchema.ts\";\nexport * from \"./schemas/jobExecutionQuerySchema.ts\";\nexport * from \"./schemas/jobExecutionResourceSchema.ts\";\nexport * from \"./schemas/jobFailureSchema.ts\";\nexport * from \"./schemas/jobQueueDepthSchema.ts\";\nexport * from \"./schemas/jobRegistrationSchema.ts\";\nexport * from \"./schemas/jobStatsSchema.ts\";\nexport * from \"./schemas/triggerJobSchema.ts\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiJobs = $module({\n name: \"alepha.api.jobs\",\n services: [],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/api/jobs/entities/jobExecutionEntity.ts","../../../src/api/jobs/entities/jobExecutionLogEntity.ts","../../../src/api/jobs/schemas/jobActivitySchema.ts","../../../src/api/jobs/schemas/jobConfigAtom.ts","../../../src/api/jobs/schemas/jobCronInfoSchema.ts","../../../src/api/jobs/schemas/jobExecutionResourceSchema.ts","../../../src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts","../../../src/api/jobs/schemas/jobExecutionQuerySchema.ts","../../../src/api/jobs/schemas/jobFailureSchema.ts","../../../src/api/jobs/schemas/jobQueueDepthSchema.ts","../../../src/api/jobs/schemas/jobRegistrationSchema.ts","../../../src/api/jobs/schemas/jobStatsSchema.ts","../../../src/api/jobs/schemas/triggerJobSchema.ts","../../../src/api/jobs/index.browser.ts"],"sourcesContent":["import { type Static, t } from \"alepha\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const jobExecutionEntity = $entity({\n name: \"job_executions\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n createdAt: db.createdAt(),\n updatedAt: db.updatedAt(),\n\n jobName: t.text(),\n key: t.optional(t.nullable(t.text())),\n\n payload: t.optional(t.record(t.text(), t.any())),\n status: db.default(\n t.enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"dead\",\n \"cancelled\",\n ]),\n \"pending\",\n ),\n priority: db.default(t.integer({ minimum: 0, maximum: 3 }), 2),\n\n attempt: db.default(t.integer(), 0),\n maxAttempts: db.default(t.integer(), 1),\n\n scheduledAt: t.optional(t.datetime()),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n\n result: t.optional(t.record(t.text(), t.any())),\n error: t.optional(t.text()),\n workerId: t.optional(t.text()),\n\n triggeredBy: t.optional(t.text()),\n triggeredByName: t.optional(t.text()),\n cancelledBy: t.optional(t.text()),\n cancelledByName: t.optional(t.text()),\n }),\n indexes: [\n { columns: [\"jobName\", \"status\", \"priority\", \"scheduledAt\"] },\n { columns: [\"jobName\", \"status\", \"startedAt\"] },\n { columns: [\"jobName\", \"completedAt\"] },\n { columns: [\"jobName\", \"key\"], unique: true },\n ],\n});\n\nexport type JobExecutionEntity = Static<typeof jobExecutionEntity.schema>;\n\nexport type JobStatus =\n | \"pending\"\n | \"scheduled\"\n | \"retrying\"\n | \"running\"\n | \"completed\"\n | \"dead\"\n | \"cancelled\";\n","import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { $entity, db } from \"alepha/orm\";\n\nexport const jobExecutionLogEntity = $entity({\n name: \"job_execution_logs\",\n schema: t.object({\n id: db.primaryKey(t.uuid()),\n logs: t.array(logEntrySchema),\n }),\n});\n\nexport type JobExecutionLogEntity = Static<typeof jobExecutionLogEntity.schema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobActivityPointSchema = t.object({\n date: t.text(),\n completed: t.integer(),\n failed: t.integer(),\n});\n\nexport type JobActivityPoint = Static<typeof jobActivityPointSchema>;\n\nexport const jobActivityQuerySchema = t.object({\n days: t.optional(t.integer({ minimum: 1, maximum: 90 })),\n});\n\nexport type JobActivityQuery = Static<typeof jobActivityQuerySchema>;\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const jobConfig = $atom({\n name: \"alepha.jobs\",\n description: \"Configuration for the $job v2 primitive.\",\n schema: t.object({\n recovery: t.object({\n interval: t.integer({ description: \"Sweep interval (ms).\" }),\n staleThreshold: t.integer({\n description: \"Pending age (ms) before re-dispatch.\",\n }),\n runTimeout: t.integer({\n description:\n \"Running age (ms) before assumed crash. Used as fallback when no per-job timeout is set.\",\n }),\n }),\n delayed: t.object({\n interval: t.integer({ description: \"Sweep interval (ms).\" }),\n }),\n logRetentionDays: t.integer({\n description: \"Days to keep completed/dead executions.\",\n }),\n logMaxEntries: t.integer({\n description: \"Max log entries captured per execution.\",\n }),\n drainTimeout: t.integer({\n description: \"Max time (ms) to wait for in-flight jobs during shutdown.\",\n }),\n }),\n default: {\n recovery: {\n interval: 300_000,\n staleThreshold: 300_000,\n runTimeout: 1_800_000,\n },\n delayed: {\n interval: 300_000,\n },\n logRetentionDays: 30,\n logMaxEntries: 100,\n drainTimeout: 30_000,\n },\n});\n\nexport type JobConfig = Static<typeof jobConfig.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [jobConfig.key]: JobConfig;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const jobCronInfoSchema = t.object({\n name: t.text(),\n cron: t.text(),\n lock: t.boolean(),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n concurrency: t.integer(),\n hasSchema: t.boolean(),\n paused: t.boolean(),\n lastExecution: t.optional(\n t.object({\n id: t.uuid(),\n status: t.text(),\n startedAt: t.optional(t.datetime()),\n completedAt: t.optional(t.datetime()),\n error: t.optional(t.text()),\n }),\n ),\n});\n\nexport type JobCronInfo = Static<typeof jobCronInfoSchema>;\n","import { type Static, t } from \"alepha\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\n\nexport const jobExecutionCanSchema = t.object({\n retry: t.boolean(),\n cancel: t.boolean(),\n});\n\nexport const jobExecutionResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n can: jobExecutionCanSchema,\n },\n {\n title: \"JobExecutionResource\",\n description: \"A job execution resource.\",\n },\n);\n\nexport type JobExecutionResource = Static<typeof jobExecutionResourceSchema>;\n","import { type Static, t } from \"alepha\";\nimport { logEntrySchema } from \"alepha/logger\";\nimport { jobExecutionEntity } from \"../entities/jobExecutionEntity.ts\";\nimport { jobExecutionCanSchema } from \"./jobExecutionResourceSchema.ts\";\n\nexport const jobExecutionDetailResourceSchema = t.extend(\n jobExecutionEntity.schema,\n {\n can: jobExecutionCanSchema,\n logs: t.optional(t.array(logEntrySchema)),\n },\n {\n title: \"JobExecutionDetailResource\",\n description: \"A job execution resource with logs.\",\n },\n);\n\nexport type JobExecutionDetailResource = Static<\n typeof jobExecutionDetailResourceSchema\n>;\n","import { type Static, t } from \"alepha\";\nimport { pageQuerySchema } from \"alepha/orm\";\n\nexport const jobExecutionQuerySchema = t.extend(pageQuerySchema, {\n job: t.optional(\n t.text({\n description: \"Filter by job name\",\n }),\n ),\n status: t.optional(\n t.enum([\n \"pending\",\n \"scheduled\",\n \"retrying\",\n \"running\",\n \"completed\",\n \"dead\",\n \"cancelled\",\n ]),\n ),\n priority: t.optional(t.enum([\"critical\", \"high\", \"normal\", \"low\"])),\n from: t.optional(\n t.datetime({\n description: \"From date (ISO)\",\n }),\n ),\n to: t.optional(\n t.datetime({\n description: \"To date (ISO)\",\n }),\n ),\n});\n\nexport type JobExecutionQuery = Static<typeof jobExecutionQuerySchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobFailureSchema = t.object({\n jobName: t.text(),\n failures: t.integer(),\n lastError: t.optional(t.text()),\n});\n\nexport type JobFailure = Static<typeof jobFailureSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobQueueDepthSchema = t.object({\n jobName: t.text(),\n pending: t.integer(),\n running: t.integer(),\n scheduled: t.integer(),\n retrying: t.integer(),\n dead: t.integer(),\n concurrency: t.integer(),\n paused: t.boolean(),\n});\n\nexport type JobQueueDepth = Static<typeof jobQueueDepthSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobRegistrationSchema = t.object({\n name: t.text(),\n type: t.enum([\"cron\", \"push\", \"both\"]),\n priority: t.enum([\"critical\", \"high\", \"normal\", \"low\"]),\n concurrency: t.integer(),\n hasSchema: t.boolean(),\n cron: t.optional(t.text()),\n timeout: t.optional(t.text()),\n retry: t.optional(\n t.object({\n retries: t.integer(),\n hasBackoff: t.boolean(),\n }),\n ),\n paused: t.boolean(),\n});\n\nexport type JobRegistration = Static<typeof jobRegistrationSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const jobStatsSchema = t.object({\n registered: t.integer(),\n running: t.integer(),\n pending: t.integer(),\n scheduled: t.integer(),\n retrying: t.integer(),\n dead: t.integer(),\n completed: t.integer(),\n failed: t.integer(),\n});\n\nexport type JobStats = Static<typeof jobStatsSchema>;\n","import { type Static, t } from \"alepha\";\n\nexport const triggerJobSchema = t.object({\n name: t.text(),\n payload: t.optional(t.record(t.text(), t.any())),\n});\n\nexport type TriggerJob = Static<typeof triggerJobSchema>;\n","import { $module } from \"alepha\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport * from \"./entities/jobExecutionEntity.ts\";\nexport * from \"./entities/jobExecutionLogEntity.ts\";\nexport * from \"./schemas/jobActivitySchema.ts\";\nexport * from \"./schemas/jobConfigAtom.ts\";\nexport * from \"./schemas/jobCronInfoSchema.ts\";\nexport * from \"./schemas/jobExecutionDetailResourceSchema.ts\";\nexport * from \"./schemas/jobExecutionQuerySchema.ts\";\nexport * from \"./schemas/jobExecutionResourceSchema.ts\";\nexport * from \"./schemas/jobFailureSchema.ts\";\nexport * from \"./schemas/jobQueueDepthSchema.ts\";\nexport * from \"./schemas/jobRegistrationSchema.ts\";\nexport * from \"./schemas/jobStatsSchema.ts\";\nexport * from \"./schemas/triggerJobSchema.ts\";\n\n// -----------------------------------------------------------------------------------------------------------------\n\nexport const AlephaApiJobs = $module({\n name: \"alepha.api.jobs\",\n services: [],\n});\n"],"mappings":"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"}
|