@headless-lms/core 0.6.0 → 0.7.0
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/dist/automations/index.d.ts +4 -4
- package/dist/automations/notifications/delivery.d.ts +3 -3
- package/dist/automations/notifications/delivery.js +1 -1
- package/dist/automations/notifications/delivery.js.map +1 -1
- package/dist/automations/ports.d.ts +2 -2
- package/dist/automations/service.d.ts +1 -8
- package/dist/automations/service.js +0 -8
- package/dist/automations/service.js.map +1 -1
- package/dist/content/events.d.ts +13 -13
- package/dist/types/automations.d.ts +5 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/schemas/content.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Page } from "../types/shared.js";
|
|
2
2
|
import { Automation, AutomationAction, AutomationActionResult, AutomationKind, AutomationRun, AutomationRunStatus, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
3
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
3
|
+
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, DeliveryExecutor, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
4
4
|
import { ACTION_FAILED, ActionFailedError, AutomationKindMismatchError, InvalidTriggerError, ReservedActionError, actionFailureMessage } from "./model.js";
|
|
5
5
|
import "./types.js";
|
|
6
6
|
import { AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsUnitOfWork, ChatDebounce, ListedNotification, NewAutomation, NewAutomationRun, NewDelivery, NewNotification, NotificationCategories, NotificationPage, NotificationReads, NotificationsRepository, NotificationsService, RecipientRule, UnreadCounts } from "./ports.js";
|
|
7
7
|
import { CommunityMailReads, GrantWriter } from "./community-mail.js";
|
|
8
8
|
import { AutomationActionFailed, AutomationCreated, AutomationDeleted, AutomationDisabled, AutomationEnabled, AutomationEvent, AutomationRunCompleted, AutomationRunFailed, AutomationRunStarted, AutomationUpdated, automationEvents } from "./events.js";
|
|
9
|
-
import { CHANNEL_NOT_CONFIGURED, NOT_ACCEPTED, NO_ADDRESS, NotificationDelivery } from "./notifications/delivery.js";
|
|
10
|
-
import { DEVICE_WINDOW_MS, IN_APP, MESSAGE_SENT, NotificationProcessor, PUSH } from "./notifications/processor.js";
|
|
11
9
|
import { AutomationsServiceImpl } from "./service.js";
|
|
12
10
|
import { cronMatches } from "./schedule.js";
|
|
13
11
|
import { NotificationsServiceImpl } from "./notifications/service.js";
|
|
12
|
+
import { CHANNEL_NOT_CONFIGURED, NOT_ACCEPTED, NO_ADDRESS, NotificationDelivery } from "./notifications/delivery.js";
|
|
13
|
+
import { DEVICE_WINDOW_MS, IN_APP, MESSAGE_SENT, NotificationProcessor, PUSH } from "./notifications/processor.js";
|
|
14
14
|
import { CHAT_QUIET_MS, FLUSH_JOB, SchedulerChatDebounce, flushKey, notificationJobs } from "./notifications/debounce.js";
|
|
15
15
|
import { RECIPIENT_RULES } from "./notifications/rules/index.js";
|
|
16
16
|
import { NOTIFICATION_TYPES } from "./notifications/types.js";
|
|
17
17
|
import { DEFAULT_COMMUNITY_CATEGORIES, DEFAULT_ORG_CATEGORIES } from "./notifications/defaults.js";
|
|
18
18
|
import { applicableCategories } from "./notifications/applicable.js";
|
|
19
|
-
export { ACTION_FAILED, ActionFailedError, type Automation, type AutomationAction, type AutomationActionFailed, type AutomationActionResult, type AutomationCreated, type AutomationDeleted, type AutomationDisabled, type AutomationDispatch, type AutomationEnabled, type AutomationEngine, type AutomationEvent, type AutomationExecutor, type AutomationKind, AutomationKindMismatchError, type AutomationRun, type AutomationRunCompleted, type AutomationRunFailed, type AutomationRunStarted, type AutomationRunStatus, type AutomationRunsQuery, type AutomationRunsRepository, type AutomationTrigger, type AutomationUpdated, type AutomationsQuery, type AutomationsRepository, type AutomationsService, AutomationsServiceImpl, type AutomationsUnitOfWork, type AvailableAction, type AvailableActions, type AvailableTriggers, CHANNEL_NOT_CONFIGURED, CHAT_QUIET_MS, type ChatDebounce, type CommunityMailReads, type CreateAutomationInput, type CreateWebhookInput, type CreatedWebhook, DEFAULT_COMMUNITY_CATEGORIES, DEFAULT_ORG_CATEGORIES, DEVICE_WINDOW_MS, type DeliveryDispatch, FLUSH_JOB, type GrantWriter, IN_APP, InvalidTriggerError, type ListedNotification, MESSAGE_SENT, NOTIFICATION_TYPES, NOT_ACCEPTED, NO_ADDRESS, type NewAutomation, type NewAutomationRun, type NewDelivery, type NewNotification, type NotificationCategories, NotificationDelivery, type NotificationPage, NotificationProcessor, type NotificationReads, type NotificationsRepository, type NotificationsService, NotificationsServiceImpl, PUSH, type Page, RECIPIENT_RULES, type RecipientRule, ReservedActionError, SchedulerChatDebounce, type UnreadCounts, type UpdateAutomationInput, type UpdateWebhookInput, type Webhook, type WebhookRequest, type WebhookResponse, type WebhookSecret, type WebhookSender, actionFailureMessage, applicableCategories, automationEvents, cronMatches, flushKey, notificationJobs };
|
|
19
|
+
export { ACTION_FAILED, ActionFailedError, type Automation, type AutomationAction, type AutomationActionFailed, type AutomationActionResult, type AutomationCreated, type AutomationDeleted, type AutomationDisabled, type AutomationDispatch, type AutomationEnabled, type AutomationEngine, type AutomationEvent, type AutomationExecutor, type AutomationKind, AutomationKindMismatchError, type AutomationRun, type AutomationRunCompleted, type AutomationRunFailed, type AutomationRunStarted, type AutomationRunStatus, type AutomationRunsQuery, type AutomationRunsRepository, type AutomationTrigger, type AutomationUpdated, type AutomationsQuery, type AutomationsRepository, type AutomationsService, AutomationsServiceImpl, type AutomationsUnitOfWork, type AvailableAction, type AvailableActions, type AvailableTriggers, CHANNEL_NOT_CONFIGURED, CHAT_QUIET_MS, type ChatDebounce, type CommunityMailReads, type CreateAutomationInput, type CreateWebhookInput, type CreatedWebhook, DEFAULT_COMMUNITY_CATEGORIES, DEFAULT_ORG_CATEGORIES, DEVICE_WINDOW_MS, type DeliveryDispatch, type DeliveryExecutor, FLUSH_JOB, type GrantWriter, IN_APP, InvalidTriggerError, type ListedNotification, MESSAGE_SENT, NOTIFICATION_TYPES, NOT_ACCEPTED, NO_ADDRESS, type NewAutomation, type NewAutomationRun, type NewDelivery, type NewNotification, type NotificationCategories, NotificationDelivery, type NotificationPage, NotificationProcessor, type NotificationReads, type NotificationsRepository, type NotificationsService, NotificationsServiceImpl, PUSH, type Page, RECIPIENT_RULES, type RecipientRule, ReservedActionError, SchedulerChatDebounce, type UnreadCounts, type UpdateAutomationInput, type UpdateWebhookInput, type Webhook, type WebhookRequest, type WebhookResponse, type WebhookSecret, type WebhookSender, actionFailureMessage, applicableCategories, automationEvents, cronMatches, flushKey, notificationJobs };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Logger } from "../../types/ports.js";
|
|
2
|
-
import { DeliveryDispatch } from "../../types/automations.js";
|
|
2
|
+
import { DeliveryDispatch, DeliveryExecutor } from "../../types/automations.js";
|
|
3
3
|
import "../../types/index.js";
|
|
4
4
|
import { ChannelRegistry } from "../../shared/ports.js";
|
|
5
5
|
import { DevicesService } from "../../identity/ports.js";
|
|
@@ -15,13 +15,13 @@ type NotificationDeliveryParams = {
|
|
|
15
15
|
devices: Pick<DevicesService, 'removeDead'>;
|
|
16
16
|
logger?: Logger;
|
|
17
17
|
};
|
|
18
|
-
declare class NotificationDelivery {
|
|
18
|
+
declare class NotificationDelivery implements DeliveryExecutor {
|
|
19
19
|
private readonly repo;
|
|
20
20
|
private readonly channels;
|
|
21
21
|
private readonly devices;
|
|
22
22
|
private readonly logger;
|
|
23
23
|
constructor(params: NotificationDeliveryParams);
|
|
24
|
-
|
|
24
|
+
runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void>;
|
|
25
25
|
}
|
|
26
26
|
//#endregion
|
|
27
27
|
export { CHANNEL_NOT_CONFIGURED, NOT_ACCEPTED, NO_ADDRESS, NotificationDelivery, NotificationDeliveryParams };
|
|
@@ -17,7 +17,7 @@ var NotificationDelivery = class {
|
|
|
17
17
|
this.devices = params.devices;
|
|
18
18
|
this.logger = params.logger ?? noopLogger;
|
|
19
19
|
}
|
|
20
|
-
async
|
|
20
|
+
async runDelivery(d, lastAttempt) {
|
|
21
21
|
const found = await this.repo.findDelivery(d.orgId, d.deliveryId);
|
|
22
22
|
if (!found || found.delivery.status !== "pending") {
|
|
23
23
|
this.logger.debug("notification delivery skipped", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.js","names":[],"sources":["../../../src/automations/notifications/delivery.ts"],"sourcesContent":["import type { DevicesService } from '../../identity/index.js';\nimport { noopLogger } from '../../shared/logger.js';\nimport type { ChannelRegistry, Logger } from '../../shared/ports.js';\nimport type { ChannelRecipient, DeliveryDispatch, DeliveryResult } from '../../types/index.js';\nimport type { NotificationsRepository } from '../ports.js';\n\nexport const CHANNEL_NOT_CONFIGURED = 'channel not configured';\nexport const NO_ADDRESS = 'no address';\nexport const NOT_ACCEPTED = 'not accepted';\n\nexport type NotificationDeliveryParams = {\n repo: Pick<NotificationsRepository, 'findDelivery' | 'markSent' | 'recordError' | 'markFailed'>;\n channels: Pick<ChannelRegistry, 'get'>;\n devices: Pick<DevicesService, 'removeDead'>;\n logger?: Logger;\n};\n\nfunction messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nexport class NotificationDelivery {\n private readonly repo: NotificationDeliveryParams['repo'];\n private readonly channels: Pick<ChannelRegistry, 'get'>;\n private readonly devices: Pick<DevicesService, 'removeDead'>;\n private readonly logger: Logger;\n\n constructor(params: NotificationDeliveryParams) {\n this.repo = params.repo;\n this.channels = params.channels;\n this.devices = params.devices;\n this.logger = params.logger ?? noopLogger;\n }\n\n async
|
|
1
|
+
{"version":3,"file":"delivery.js","names":[],"sources":["../../../src/automations/notifications/delivery.ts"],"sourcesContent":["import type { DevicesService } from '../../identity/index.js';\nimport { noopLogger } from '../../shared/logger.js';\nimport type { ChannelRegistry, Logger } from '../../shared/ports.js';\nimport type { ChannelRecipient, DeliveryDispatch, DeliveryResult } from '../../types/index.js';\nimport type { DeliveryExecutor, NotificationsRepository } from '../ports.js';\n\nexport const CHANNEL_NOT_CONFIGURED = 'channel not configured';\nexport const NO_ADDRESS = 'no address';\nexport const NOT_ACCEPTED = 'not accepted';\n\nexport type NotificationDeliveryParams = {\n repo: Pick<NotificationsRepository, 'findDelivery' | 'markSent' | 'recordError' | 'markFailed'>;\n channels: Pick<ChannelRegistry, 'get'>;\n devices: Pick<DevicesService, 'removeDead'>;\n logger?: Logger;\n};\n\nfunction messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nexport class NotificationDelivery implements DeliveryExecutor {\n private readonly repo: NotificationDeliveryParams['repo'];\n private readonly channels: Pick<ChannelRegistry, 'get'>;\n private readonly devices: Pick<DevicesService, 'removeDead'>;\n private readonly logger: Logger;\n\n constructor(params: NotificationDeliveryParams) {\n this.repo = params.repo;\n this.channels = params.channels;\n this.devices = params.devices;\n this.logger = params.logger ?? noopLogger;\n }\n\n async runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void> {\n const found = await this.repo.findDelivery(d.orgId, d.deliveryId);\n if (!found || found.delivery.status !== 'pending') {\n this.logger.debug('notification delivery skipped', {\n orgId: d.orgId,\n deliveryId: d.deliveryId,\n status: found?.delivery.status ?? null,\n });\n return;\n }\n const { delivery, notification } = found;\n const log = {\n orgId: d.orgId,\n deliveryId: d.deliveryId,\n notificationId: notification.id,\n channel: delivery.channel,\n type: notification.type,\n };\n const channel = this.channels.get(delivery.channel);\n if (!channel) {\n await this.repo.markFailed(d.orgId, d.deliveryId, CHANNEL_NOT_CONFIGURED);\n this.logger.warn('notification delivery failed: channel not configured', log);\n return;\n }\n let to: ChannelRecipient | null;\n let result: DeliveryResult;\n try {\n to = await channel.recipient(d.orgId, notification.userId);\n if (!to) {\n await this.repo.markFailed(d.orgId, d.deliveryId, NO_ADDRESS);\n this.logger.info('notification delivery failed: no address', log);\n return;\n }\n result = await channel.deliver(notification, to);\n } catch (err) {\n const error = messageOf(err);\n if (lastAttempt) {\n await this.repo.markFailed(d.orgId, d.deliveryId, error);\n this.logger.warn('notification delivery failed on its last attempt', { ...log, err });\n return;\n }\n await this.repo.recordError(d.orgId, d.deliveryId, error);\n this.logger.warn('notification delivery attempt failed', { ...log, err });\n throw err;\n }\n if (result.deadDeviceIds.length > 0) {\n await this.devices.removeDead(d.orgId, result.deadDeviceIds);\n }\n if (!result.accepted) {\n const error = result.error ?? NOT_ACCEPTED;\n await this.repo.markFailed(d.orgId, d.deliveryId, error);\n this.logger.info('notification delivery failed: not accepted', { ...log, error });\n return;\n }\n await this.repo.markSent(d.orgId, d.deliveryId, new Date());\n this.logger.info('notification delivered', log);\n }\n}\n"],"mappings":";;AAMA,MAAa,yBAAyB;AACtC,MAAa,aAAa;AAC1B,MAAa,eAAe;AAS5B,SAAS,UAAU,KAAsB;CACvC,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACxD;AAEA,IAAa,uBAAb,MAA8D;CAC5D;CACA;CACA;CACA;CAEA,YAAY,QAAoC;EAC9C,KAAK,OAAO,OAAO;EACnB,KAAK,WAAW,OAAO;EACvB,KAAK,UAAU,OAAO;EACtB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,MAAM,YAAY,GAAqB,aAAqC;EAC1E,MAAM,QAAQ,MAAM,KAAK,KAAK,aAAa,EAAE,OAAO,EAAE,UAAU;EAChE,IAAI,CAAC,SAAS,MAAM,SAAS,WAAW,WAAW;GACjD,KAAK,OAAO,MAAM,iCAAiC;IACjD,OAAO,EAAE;IACT,YAAY,EAAE;IACd,QAAQ,OAAO,SAAS,UAAU;GACpC,CAAC;GACD;EACF;EACA,MAAM,EAAE,UAAU,iBAAiB;EACnC,MAAM,MAAM;GACV,OAAO,EAAE;GACT,YAAY,EAAE;GACd,gBAAgB,aAAa;GAC7B,SAAS,SAAS;GAClB,MAAM,aAAa;EACrB;EACA,MAAM,UAAU,KAAK,SAAS,IAAI,SAAS,OAAO;EAClD,IAAI,CAAC,SAAS;GACZ,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,sBAAsB;GACxE,KAAK,OAAO,KAAK,wDAAwD,GAAG;GAC5E;EACF;EACA,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,KAAK,MAAM,QAAQ,UAAU,EAAE,OAAO,aAAa,MAAM;GACzD,IAAI,CAAC,IAAI;IACP,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,UAAU;IAC5D,KAAK,OAAO,KAAK,4CAA4C,GAAG;IAChE;GACF;GACA,SAAS,MAAM,QAAQ,QAAQ,cAAc,EAAE;EACjD,SAAS,KAAK;GACZ,MAAM,QAAQ,UAAU,GAAG;GAC3B,IAAI,aAAa;IACf,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,KAAK;IACvD,KAAK,OAAO,KAAK,oDAAoD;KAAE,GAAG;KAAK;IAAI,CAAC;IACpF;GACF;GACA,MAAM,KAAK,KAAK,YAAY,EAAE,OAAO,EAAE,YAAY,KAAK;GACxD,KAAK,OAAO,KAAK,wCAAwC;IAAE,GAAG;IAAK;GAAI,CAAC;GACxE,MAAM;EACR;EACA,IAAI,OAAO,cAAc,SAAS,GAChC,MAAM,KAAK,QAAQ,WAAW,EAAE,OAAO,OAAO,aAAa;EAE7D,IAAI,CAAC,OAAO,UAAU;GACpB,MAAM,QAAQ,OAAO,SAAA;GACrB,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,KAAK;GACvD,KAAK,OAAO,KAAK,8CAA8C;IAAE,GAAG;IAAK;GAAM,CAAC;GAChF;EACF;EACA,MAAM,KAAK,KAAK,SAAS,EAAE,OAAO,EAAE,4BAAY,IAAI,KAAK,CAAC;EAC1D,KAAK,OAAO,KAAK,0BAA0B,GAAG;CAChD;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DomainEvent, Page } from "../types/shared.js";
|
|
2
2
|
import { Event } from "../types/schemas/content.js";
|
|
3
3
|
import { Automation, AutomationKind, AutomationRun, AutomationRunsQuery, AutomationsQuery, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
4
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
4
|
+
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, DeliveryExecutor, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
5
5
|
import { Delivery, NotificationCategory, NotificationFilter, RecipientList, StoredNotification, SubjectRef } from "../types/notifications.js";
|
|
6
6
|
import "../types/index.js";
|
|
7
7
|
import { Actor } from "../shared/actor.js";
|
|
@@ -184,5 +184,5 @@ interface AutomationsTxScope {
|
|
|
184
184
|
}
|
|
185
185
|
type AutomationsUnitOfWork = UnitOfWork<AutomationsTxScope>;
|
|
186
186
|
//#endregion
|
|
187
|
-
export { type AutomationDispatch, type AutomationEngine, type AutomationExecutor, AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsTxScope, AutomationsUnitOfWork, ChatDebounce, type DeliveryDispatch, ListedNotification, NewAutomation, NewAutomationRun, NewDelivery, NewNotification, NotificationCategories, NotificationPage, NotificationReads, NotificationsRepository, NotificationsService, RecipientRule, UnreadCounts, type WebhookRequest, type WebhookResponse, type WebhookSender };
|
|
187
|
+
export { type AutomationDispatch, type AutomationEngine, type AutomationExecutor, AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsTxScope, AutomationsUnitOfWork, ChatDebounce, type DeliveryDispatch, type DeliveryExecutor, ListedNotification, NewAutomation, NewAutomationRun, NewDelivery, NewNotification, NotificationCategories, NotificationPage, NotificationReads, NotificationsRepository, NotificationsService, RecipientRule, UnreadCounts, type WebhookRequest, type WebhookResponse, type WebhookSender };
|
|
188
188
|
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DomainEvent, Page } from "../types/shared.js";
|
|
2
2
|
import { Logger } from "../types/ports.js";
|
|
3
3
|
import { Automation, AutomationActionResult, AutomationRun, AutomationRunsQuery, AutomationsQuery, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
4
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor,
|
|
4
|
+
import { AutomationDispatch, AutomationEngine, AutomationExecutor, ScheduledAutomation, WebhookSender } from "../types/automations.js";
|
|
5
5
|
import "../types/index.js";
|
|
6
6
|
import { Actor } from "../shared/actor.js";
|
|
7
7
|
import { CredentialStore } from "../shared/ports.js";
|
|
@@ -10,8 +10,6 @@ import { Mailer, MailerLookups } from "../shared/mailer.js";
|
|
|
10
10
|
import "./types.js";
|
|
11
11
|
import { AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsUnitOfWork } from "./ports.js";
|
|
12
12
|
import { CommunityMailReads, GrantWriter } from "./community-mail.js";
|
|
13
|
-
import { NotificationDelivery } from "./notifications/delivery.js";
|
|
14
|
-
import { NotificationProcessor } from "./notifications/processor.js";
|
|
15
13
|
import { IntegrationsService } from "../integrations/ports.js";
|
|
16
14
|
import "../integrations/index.js";
|
|
17
15
|
//#region src/automations/service.d.ts
|
|
@@ -30,8 +28,6 @@ type AutomationsServiceParams = {
|
|
|
30
28
|
webhooks: WebhookSender;
|
|
31
29
|
mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;
|
|
32
30
|
grants: GrantWriter;
|
|
33
|
-
delivery: Pick<NotificationDelivery, 'run'>;
|
|
34
|
-
processor: Pick<NotificationProcessor, 'process'>;
|
|
35
31
|
logger?: Logger;
|
|
36
32
|
};
|
|
37
33
|
declare class AutomationsServiceImpl implements AutomationsService, AutomationExecutor {
|
|
@@ -47,8 +43,6 @@ declare class AutomationsServiceImpl implements AutomationsService, AutomationEx
|
|
|
47
43
|
private readonly webhooks;
|
|
48
44
|
private readonly mail;
|
|
49
45
|
private readonly grants;
|
|
50
|
-
private readonly delivery;
|
|
51
|
-
private readonly processor;
|
|
52
46
|
private readonly logger;
|
|
53
47
|
constructor(params: AutomationsServiceParams);
|
|
54
48
|
handle(event: DomainEvent): Promise<void>;
|
|
@@ -60,7 +54,6 @@ declare class AutomationsServiceImpl implements AutomationsService, AutomationEx
|
|
|
60
54
|
/** Best-effort: logs and never rethrows, so an org automation never fails `handle`. */
|
|
61
55
|
private recordFailure;
|
|
62
56
|
runAction(d: AutomationDispatch, index: number): Promise<AutomationActionResult>;
|
|
63
|
-
runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void>;
|
|
64
57
|
listSchedules(): Promise<ScheduledAutomation[]>;
|
|
65
58
|
fireSchedule(orgId: string, automationId: string, at: Date): Promise<void>;
|
|
66
59
|
finalize(d: AutomationDispatch, results: AutomationActionResult[]): Promise<void>;
|
|
@@ -134,8 +134,6 @@ var AutomationsServiceImpl = class {
|
|
|
134
134
|
webhooks;
|
|
135
135
|
mail;
|
|
136
136
|
grants;
|
|
137
|
-
delivery;
|
|
138
|
-
processor;
|
|
139
137
|
logger;
|
|
140
138
|
constructor(params) {
|
|
141
139
|
this.repo = params.repo;
|
|
@@ -153,8 +151,6 @@ var AutomationsServiceImpl = class {
|
|
|
153
151
|
recentMessageRecipients: (orgId, automationId, chatId, since) => this.runsRepo.recentRecipients(orgId, automationId, chatId, since)
|
|
154
152
|
};
|
|
155
153
|
this.grants = params.grants;
|
|
156
|
-
this.delivery = params.delivery;
|
|
157
|
-
this.processor = params.processor;
|
|
158
154
|
this.logger = params.logger ?? noopLogger;
|
|
159
155
|
}
|
|
160
156
|
async handle(event) {
|
|
@@ -172,7 +168,6 @@ var AutomationsServiceImpl = class {
|
|
|
172
168
|
}
|
|
173
169
|
await this.dispatchOne(automation, event);
|
|
174
170
|
}
|
|
175
|
-
await this.processor.process(event);
|
|
176
171
|
}
|
|
177
172
|
async reconcileSchedules(orgId) {
|
|
178
173
|
try {
|
|
@@ -317,9 +312,6 @@ var AutomationsServiceImpl = class {
|
|
|
317
312
|
...failed.length > 0 ? { error: `delivery failed for ${failed.length} recipients: ${failed.join(", ")}` } : {}
|
|
318
313
|
};
|
|
319
314
|
}
|
|
320
|
-
runDelivery(d, lastAttempt) {
|
|
321
|
-
return this.delivery.run(d, lastAttempt);
|
|
322
|
-
}
|
|
323
315
|
async listSchedules() {
|
|
324
316
|
return this.repo.listSchedules();
|
|
325
317
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../src/automations/service.ts"],"sourcesContent":["// automations context — service implementation (inbound port) and the\n// AutomationExecutor the engine drives.\n//\n// `handle` is subscribed to all events on the EventBus: it matches an event\n// against enabled automations for its trigger, opens one run per match, and\n// hands it to the injected AutomationEngine, which calls back into\n// `runAction`/`finalize`.\nimport { assertGrantsAllowed, assertReadsEvents } from './event-permissions.js';\nimport {\n catalogActions,\n catalogTriggers,\n DELIVER_WEBHOOK_ACTION,\n publicDataSchema,\n} from './catalog.js';\nimport { executeAction, type ActionOutcome } from './actions.js';\nimport { generateWebhookSecret } from './webhook-signing.js';\nimport type { CommunityMailReads, GrantWriter } from './community-mail.js';\nimport type { NotificationDelivery } from './notifications/delivery.js';\nimport type { NotificationProcessor } from './notifications/processor.js';\nimport { cronSupported } from './schedule.js';\nimport {\n ActionFailedError,\n AutomationKindMismatchError,\n InvalidTriggerError,\n ReservedActionError,\n type Automation,\n type AutomationAction,\n type AutomationActionResult,\n type AutomationRun,\n type CreatedWebhook,\n type DeliverWebhookInput,\n type Page,\n type Webhook,\n type WebhookSecret,\n} from './model.js';\nimport type {\n AutomationRunsQuery,\n AutomationsQuery,\n AvailableActions,\n AvailableTriggers,\n CreateAutomationInput,\n CreateWebhookInput,\n UpdateAutomationInput,\n UpdateWebhookInput,\n} from './types.js';\nimport type {\n AutomationDispatch,\n AutomationEngine,\n AutomationExecutor,\n AutomationRunsRepository,\n AutomationsRepository,\n AutomationsService,\n AutomationsUnitOfWork,\n DeliveryDispatch,\n WebhookSender,\n} from './ports.js';\nimport type { CredentialStore, DomainEvent, Logger } from '../shared/ports.js';\nimport type { JsonValue, ScheduledAutomation } from '../types/index.js';\nimport { deliverWebhookInputSchema } from '../types/schemas/index.js';\nimport { ConflictError, InvalidInputError, NotFoundError } from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\nimport type { Mailer, MailerLookups } from '../shared/mailer.js';\nimport type { IntegrationsService } from '../integrations/index.js';\nimport type { Actor } from '../shared/actor.js';\nimport { automationEvents } from './events.js';\n\n/** True only when `input` sets `enabled` and nothing else — emits automation.enabled|disabled instead of automation.updated. */\nfunction isEnabledOnlyUpdate<T extends { enabled?: boolean }>(\n input: T,\n): input is T & { enabled: boolean } {\n if (input.enabled === undefined) {\n return false;\n }\n const { enabled: _enabled, ...rest } = input;\n return Object.values(rest).every((v) => v === undefined);\n}\n\nfunction floorMinute(at: Date): number {\n const copy = new Date(at);\n copy.setUTCSeconds(0, 0);\n return copy.getTime();\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction filterMatches(filter: Record<string, JsonValue> | null, data: unknown): boolean {\n if (filter == null) {\n return true;\n }\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n return false;\n }\n const record = data as Record<string, unknown>;\n return Object.entries(filter).every(([key, expected]) => {\n if (!Object.prototype.hasOwnProperty.call(record, key)) {\n return false;\n }\n return JSON.stringify(record[key]) === JSON.stringify(expected);\n });\n}\n\nfunction assertAuthorableTriggers(triggers: string[]): void {\n for (const trigger of triggers) {\n if (trigger.startsWith('automation.')) {\n throw new InvalidTriggerError(trigger);\n }\n if (trigger.startsWith('schedule:') && !cronSupported(trigger.slice('schedule:'.length))) {\n throw new InvalidTriggerError(trigger, 'schedule');\n }\n }\n}\n\nfunction assertCatalogTriggers(triggers: string[], schedules: boolean): void {\n assertAuthorableTriggers(triggers);\n const known = new Set(catalogTriggers().map((t) => t.type));\n for (const trigger of triggers) {\n if (!(schedules && trigger.startsWith('schedule:')) && !known.has(trigger)) {\n throw new InvalidTriggerError(trigger, 'unknown');\n }\n }\n}\n\nconst REMOVED_ACTIONS = new Set([\n 'notify',\n 'publishDuePosts',\n 'expireDueGrants',\n 'sendDigest',\n 'removeUnattachedUploads',\n]);\n\nfunction assertAuthorableActions(actions: AutomationAction[]): void {\n for (const action of actions) {\n if (action.type === DELIVER_WEBHOOK_ACTION) {\n throw new ReservedActionError(action.type);\n }\n if (REMOVED_ACTIONS.has(action.type)) {\n throw new InvalidInputError(`The action \"${action.type}\" is no longer available`);\n }\n }\n}\n\nconst SCHEDULE_FIRED = 'automation.schedule.fired';\n\nfunction publicEventData(event: DomainEvent): JsonValue {\n const parsed =\n event.type === SCHEDULE_FIRED\n ? { success: true as const, data: event.data }\n : publicDataSchema(event.type)?.safeParse(event.data);\n return parsed?.success ? (JSON.parse(JSON.stringify(parsed.data)) as JsonValue) : null;\n}\n\n/** A run as callers see it: its event carries only what a webhook of that event would. */\nfunction toRunView(run: AutomationRun): AutomationRun {\n const { type, version, id, orgId, occurredAt } = run.event;\n return {\n ...run,\n event: { type, version, id, orgId, occurredAt, data: publicEventData(run.event) },\n };\n}\n\n/** An automation as callers see it: a webhook's credential reference stays internal. */\nfunction toAutomationView(automation: Automation): Automation {\n return {\n ...automation,\n actions: automation.actions.map((action) => {\n if (action.type !== DELIVER_WEBHOOK_ACTION) {\n return action;\n }\n const { secretRef: _secretRef, ...input } = action.input;\n return { ...action, input };\n }),\n };\n}\n\nfunction webhookTarget(automation: Automation): DeliverWebhookInput {\n return deliverWebhookInputSchema.parse(automation.actions[0]?.input);\n}\n\nfunction toWebhook(automation: Automation): Webhook {\n return {\n orgId: automation.orgId,\n id: automation.id,\n url: webhookTarget(automation).url,\n events: automation.triggers,\n description: automation.description,\n enabled: automation.enabled,\n createdAt: automation.createdAt,\n updatedAt: automation.updatedAt,\n };\n}\n\nfunction updateEvent(orgId: string, input: { enabled?: boolean }, updated: Automation) {\n if (isEnabledOnlyUpdate(input)) {\n return input.enabled\n ? automationEvents.automationEnabled.make({ orgId, data: updated })\n : automationEvents.automationDisabled.make({ orgId, data: updated });\n }\n return automationEvents.automationUpdated.make({ orgId, data: updated });\n}\n\nexport type AutomationsServiceParams = {\n /** Read-only access (list/get/available) — runs outside any transaction. */\n repo: AutomationsRepository;\n runsRepo: AutomationRunsRepository;\n /** Atomic write scope: tx-bound repos + credential store + outbox appender. */\n uow: AutomationsUnitOfWork;\n engine: AutomationEngine;\n mailer: Pick<Mailer, 'send'>;\n lookups: MailerLookups;\n integrations: Pick<IntegrationsService, 'available'>;\n systemActor: (orgId: string) => Actor;\n credentials: CredentialStore;\n webhooks: WebhookSender;\n mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;\n grants: GrantWriter;\n delivery: Pick<NotificationDelivery, 'run'>;\n processor: Pick<NotificationProcessor, 'process'>;\n logger?: Logger;\n};\n\nexport class AutomationsServiceImpl implements AutomationsService, AutomationExecutor {\n private readonly repo: AutomationsRepository;\n private readonly runsRepo: AutomationRunsRepository;\n private readonly uow: AutomationsUnitOfWork;\n private readonly engine: AutomationEngine;\n private readonly mailer: Pick<Mailer, 'send'>;\n private readonly lookups: MailerLookups;\n private readonly integrations: Pick<IntegrationsService, 'available'>;\n private readonly systemActor: (orgId: string) => Actor;\n private readonly credentials: CredentialStore;\n private readonly webhooks: WebhookSender;\n private readonly mail: CommunityMailReads;\n private readonly grants: GrantWriter;\n private readonly delivery: Pick<NotificationDelivery, 'run'>;\n private readonly processor: Pick<NotificationProcessor, 'process'>;\n private readonly logger: Logger;\n\n constructor(params: AutomationsServiceParams) {\n this.repo = params.repo;\n this.runsRepo = params.runsRepo;\n this.uow = params.uow;\n this.engine = params.engine;\n this.mailer = params.mailer;\n this.lookups = params.lookups;\n this.integrations = params.integrations;\n this.systemActor = params.systemActor;\n this.credentials = params.credentials;\n this.webhooks = params.webhooks;\n this.mail = {\n ...params.mail,\n recentMessageRecipients: (orgId, automationId, chatId, since) =>\n this.runsRepo.recentRecipients(orgId, automationId, chatId, since),\n };\n this.grants = params.grants;\n this.delivery = params.delivery;\n this.processor = params.processor;\n this.logger = params.logger ?? noopLogger;\n }\n\n async handle(event: DomainEvent): Promise<void> {\n // automation.* events are this service's own output — matching one as a trigger would self-loop.\n if (event.type.startsWith('automation.')) {\n return;\n }\n const automations = await this.safeListByTrigger(event);\n for (const automation of automations) {\n const matches = filterMatches(automation.filter, event.data);\n if (!automation.enabled || !matches) {\n if (automation.enabled && !matches) {\n this.logger.debug('automation filter skipped', {\n orgId: event.orgId,\n automationId: automation.id,\n trigger: event.type,\n });\n }\n continue;\n }\n await this.dispatchOne(automation, event);\n }\n await this.processor.process(event);\n }\n\n private async reconcileSchedules(orgId: string): Promise<void> {\n try {\n await this.engine.syncSchedules?.();\n } catch (err) {\n this.logger.error('automation schedules not reconciled', { orgId, err });\n }\n }\n\n private async safeListByTrigger(event: DomainEvent): Promise<Automation[]> {\n try {\n return await this.repo.listByTrigger(event.orgId, event.type);\n } catch (err) {\n this.logger.error('automations: failed to load trigger matches', {\n orgId: event.orgId,\n trigger: event.type,\n err,\n });\n return [];\n }\n }\n\n private async dispatchOne(automation: Automation, event: DomainEvent): Promise<void> {\n let run: AutomationRun | null = null;\n try {\n run = await this.openRun(automation, event);\n if (!run) {\n // At-least-once redelivery of a trigger event already run for this automation — no-op.\n return;\n }\n await this.engine.dispatch(this.dispatchFor(automation, run, event));\n } catch (err) {\n this.logger.error('automation run failed', {\n orgId: event.orgId,\n automationId: automation.id,\n runId: run?.id,\n trigger: event.type,\n eventId: event.id,\n err,\n });\n if (run) {\n await this.recordFailure(run, err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n private openRun(automation: Automation, event: DomainEvent): Promise<AutomationRun | null> {\n const now = new Date();\n return this.uow.run(async ({ runs, outbox }) => {\n const inserted = await runs.insert(event.orgId, {\n orgId: event.orgId,\n automationId: automation.id,\n trigger: event.type,\n event,\n status: 'running',\n actionResults: [],\n startedAt: now,\n finishedAt: null,\n createdAt: now,\n updatedAt: now,\n });\n if (!inserted) {\n return null;\n }\n await outbox.append([\n automationEvents.runStarted.make({\n orgId: event.orgId,\n data: inserted,\n }),\n ]);\n return inserted;\n });\n }\n\n private dispatchFor(\n automation: Automation,\n run: AutomationRun,\n event: DomainEvent,\n ): AutomationDispatch {\n return {\n runId: run.id,\n orgId: event.orgId,\n automationId: automation.id,\n actions: automation.actions,\n event,\n };\n }\n\n /** Best-effort: logs and never rethrows, so an org automation never fails `handle`. */\n private async recordFailure(run: AutomationRun, error: string): Promise<AutomationRun | null> {\n try {\n return await this.uow.run(async ({ runs, outbox }) => {\n const failed = await runs.recordOutcome(run.orgId, run.id, {\n status: 'failed',\n actionResults: run.actionResults,\n finishedAt: new Date(),\n });\n if (failed) {\n await outbox.append([\n automationEvents.runFailed.make({\n orgId: run.orgId,\n data: failed,\n }),\n ]);\n }\n return failed;\n });\n } catch (err) {\n this.logger.error('failed to record automation run failure', {\n orgId: run.orgId,\n automationId: run.automationId,\n runId: run.id,\n err,\n originalError: error,\n });\n return null;\n }\n }\n\n async runAction(d: AutomationDispatch, index: number): Promise<AutomationActionResult> {\n const action = d.actions[index];\n if (!action) {\n throw new Error(`automation ${d.automationId} run ${d.runId}: no action at index ${index}`);\n }\n let outcome: ActionOutcome;\n try {\n outcome = await executeAction(action, d.event, {\n mailer: this.mailer,\n lookups: this.lookups,\n credentials: this.credentials,\n webhooks: this.webhooks,\n mail: this.mail,\n grants: this.grants,\n automationId: d.automationId,\n actionInput: action.input,\n logger: this.logger,\n });\n } catch (err) {\n this.logger.error('automation action failed', {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n trigger: d.event.type,\n index,\n type: action.type,\n err,\n });\n throw err instanceof ActionFailedError ? err : new ActionFailedError();\n }\n const { recipients, failed } = outcome;\n this.logger.info('automation action completed', {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n type: action.type,\n recipients: recipients.length,\n failed: failed.length,\n });\n return {\n index,\n type: action.type,\n status: 'completed',\n ...(recipients.length > 0 ? { recipients } : {}),\n ...(failed.length > 0\n ? { error: `delivery failed for ${failed.length} recipients: ${failed.join(', ')}` }\n : {}),\n };\n }\n\n runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void> {\n return this.delivery.run(d, lastAttempt);\n }\n\n async listSchedules(): Promise<ScheduledAutomation[]> {\n return this.repo.listSchedules();\n }\n\n async fireSchedule(orgId: string, automationId: string, at: Date): Promise<void> {\n const firedAt = new Date(floorMinute(at));\n const automation = await this.repo.findById(orgId, automationId);\n if (!automation?.enabled || firedAt.getTime() < floorMinute(automation.createdAt)) {\n this.logger.debug('schedule skipped', { orgId, automationId });\n return;\n }\n const event: DomainEvent = {\n type: SCHEDULE_FIRED,\n id: `schedule_${automationId}_${firedAt.toISOString()}`,\n orgId,\n version: 1,\n occurredAt: firedAt.toISOString(),\n data: { automationId, firedAt: firedAt.toISOString() },\n };\n await this.dispatchOne(automation, event);\n }\n\n async finalize(d: AutomationDispatch, results: AutomationActionResult[]): Promise<void> {\n const status: 'completed' | 'failed' =\n results.length === d.actions.length && results.every((r) => r.status === 'completed')\n ? 'completed'\n : 'failed';\n await this.uow.run(async ({ runs, outbox }) => {\n const run = await runs.recordOutcome(d.orgId, d.runId, {\n status,\n actionResults: results,\n finishedAt: new Date(),\n });\n if (!run) {\n return;\n }\n const runEvent =\n status === 'completed'\n ? automationEvents.runCompleted.make({ orgId: d.orgId, data: run })\n : automationEvents.runFailed.make({ orgId: d.orgId, data: run });\n const actionFailedEvents = results\n .filter((r) => r.status === 'failed')\n .map((result) => ({\n ...automationEvents.actionFailed.make({\n orgId: d.orgId,\n data: result,\n }),\n }));\n await outbox.append([runEvent, ...actionFailedEvents]);\n });\n this.logOutcome(d, status, results);\n }\n\n private logOutcome(\n d: AutomationDispatch,\n status: 'completed' | 'failed',\n results: AutomationActionResult[],\n ): void {\n const run = {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n trigger: d.event.type,\n eventId: d.event.id,\n };\n if (status === 'failed') {\n const failed = results.find((r) => r.status === 'failed');\n const index = failed?.index ?? results.length;\n this.logger.error('automation run failed', {\n ...run,\n index,\n action: failed?.type ?? d.actions[index]?.type,\n error: failed?.error ?? 'not every action ran',\n });\n return;\n }\n const partial = results.filter((r) => r.error !== undefined);\n if (partial.length > 0) {\n this.logger.warn('automation run completed with failed deliveries', {\n ...run,\n actions: partial.map(({ index, type, error }) => ({ index, type, error })),\n });\n }\n }\n\n async create(input: CreateAutomationInput, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n assertCatalogTriggers(input.triggers, true);\n assertAuthorableActions(input.actions);\n assertGrantsAllowed(actor, input.actions);\n const automation = await this.uow.run(async ({ automations, outbox }) => {\n const created = await automations.insert(orgId, {\n ...input,\n triggers: unique(input.triggers),\n kind: 'workflow',\n });\n await outbox.append([automationEvents.automationCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('automation created', {\n orgId,\n automationId: automation.id,\n actorId: actor.id,\n });\n await this.reconcileSchedules(orgId);\n return automation;\n }\n\n async update(id: string, input: UpdateAutomationInput, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n if (input.triggers !== undefined) {\n assertCatalogTriggers(input.triggers, true);\n }\n if (input.actions !== undefined) {\n assertAuthorableActions(input.actions);\n assertGrantsAllowed(actor, input.actions);\n }\n const existing = await this.repo.findById(orgId, id);\n if (!existing) {\n throw new NotFoundError('Automation', id);\n }\n if (existing.kind !== 'workflow') {\n throw new AutomationKindMismatchError(id, existing.kind);\n }\n const patch =\n input.triggers === undefined ? input : { ...input, triggers: unique(input.triggers) };\n const automation = await this.uow.run(async ({ automations, outbox }) => {\n const updated = await automations.update(orgId, id, patch);\n if (!updated) {\n return null;\n }\n await outbox.append([updateEvent(orgId, input, updated)]);\n return updated;\n });\n if (!automation) {\n throw new NotFoundError('Automation', id);\n }\n this.logger.info('automation updated', { orgId, automationId: id });\n await this.reconcileSchedules(orgId);\n return automation;\n }\n\n async delete(id: string, actor: Actor): Promise<void> {\n actor.permissions.require('automations:delete');\n const orgId = actor.orgId;\n const existing = await this.repo.findById(orgId, id);\n if (!existing) {\n throw new NotFoundError('Automation', id);\n }\n if (existing.kind !== 'workflow') {\n throw new AutomationKindMismatchError(id, existing.kind);\n }\n const deleted = await this.uow.run(async ({ automations, outbox }) => {\n const removed = await automations.delete(orgId, id);\n if (!removed) {\n return null;\n }\n await outbox.append([automationEvents.automationDeleted.make({ orgId, data: removed })]);\n return removed;\n });\n if (!deleted) {\n throw new NotFoundError('Automation', id);\n }\n this.logger.info('automation deleted', { orgId, automationId: id });\n await this.reconcileSchedules(orgId);\n }\n\n async list(query: AutomationsQuery | undefined, actor: Actor): Promise<Automation[]> {\n actor.permissions.require('automations:read');\n const automations = await this.repo.listByOrg(actor.orgId, query?.kind);\n return automations.map(toAutomationView);\n }\n\n async get(id: string, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:read');\n const automation = await this.repo.findById(actor.orgId, id);\n if (!automation) {\n throw new NotFoundError('Automation', id);\n }\n return toAutomationView(automation);\n }\n\n async listRuns(\n automationId: string,\n query: AutomationRunsQuery,\n actor: Actor,\n ): Promise<Page<AutomationRun>> {\n actor.permissions.require('automations:read');\n const page = await this.runsRepo.list(actor.orgId, automationId, query);\n return { ...page, rows: page.rows.map(toRunView) };\n }\n\n async rerun(automationId: string, runId: string, actor: Actor): Promise<AutomationRun> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.runsRepo.findById(orgId, runId);\n if (!existing || existing.automationId !== automationId) {\n throw new NotFoundError('Automation run', runId);\n }\n const automation = await this.repo.findById(orgId, automationId);\n if (!automation) {\n throw new NotFoundError('Automation', automationId);\n }\n assertGrantsAllowed(actor, automation.actions);\n const run = await this.uow.run(async ({ runs, outbox }) => {\n const restarted = await runs.restart(orgId, runId, new Date());\n if (!restarted) {\n return null;\n }\n await outbox.append([automationEvents.runStarted.make({ orgId, data: restarted })]);\n return restarted;\n });\n if (!run) {\n throw new ConflictError(`automation run ${runId} is still running`);\n }\n try {\n await this.engine.dispatch(this.dispatchFor(automation, run, run.event));\n } catch (err) {\n this.logger.error('automation rerun failed', {\n orgId,\n automationId,\n runId: run.id,\n trigger: run.trigger,\n err,\n });\n const failed = await this.recordFailure(\n run,\n err instanceof Error ? err.message : String(err),\n );\n return toRunView(failed ?? run);\n }\n this.logger.info('automation rerun started', { orgId, automationId, runId: run.id });\n return toRunView(run);\n }\n\n async listWebhooks(actor: Actor): Promise<Webhook[]> {\n actor.permissions.require('automations:read');\n const automations = await this.repo.listByOrg(actor.orgId, 'webhook');\n return automations.map(toWebhook);\n }\n\n async getWebhook(id: string, actor: Actor): Promise<Webhook> {\n actor.permissions.require('automations:read');\n return toWebhook(await this.requireWebhook(actor.orgId, id));\n }\n\n async createWebhook(input: CreateWebhookInput, actor: Actor): Promise<CreatedWebhook> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const events = unique(input.events);\n assertCatalogTriggers(events, false);\n assertReadsEvents(actor, events);\n const secret = generateWebhookSecret();\n const automation = await this.uow.run(async ({ automations, credentials, outbox }) => {\n const secretRef = await credentials.store(orgId, { secret });\n const created = await automations.insert(orgId, {\n kind: 'webhook',\n name: input.url,\n description: input.description,\n triggers: events,\n actions: [{ type: DELIVER_WEBHOOK_ACTION, input: { url: input.url, secretRef } }],\n });\n await outbox.append([automationEvents.automationCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('webhook created', { orgId, automationId: automation.id });\n return { ...toWebhook(automation), secret };\n }\n\n async updateWebhook(id: string, input: UpdateWebhookInput, actor: Actor): Promise<Webhook> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const events = input.events === undefined ? undefined : unique(input.events);\n if (events) {\n assertCatalogTriggers(events, false);\n assertReadsEvents(actor, events);\n }\n const { secretRef } = webhookTarget(existing);\n const patch: UpdateAutomationInput = {\n name: input.url,\n description: input.description,\n triggers: events,\n actions:\n input.url === undefined\n ? undefined\n : [{ type: DELIVER_WEBHOOK_ACTION, input: { url: input.url, secretRef } }],\n enabled: input.enabled,\n };\n const updated = await this.uow.run(async ({ automations, outbox }) => {\n const row = await automations.update(orgId, id, patch);\n if (!row) {\n return null;\n }\n await outbox.append([updateEvent(orgId, input, row)]);\n return row;\n });\n if (!updated) {\n throw new NotFoundError('Webhook', id);\n }\n this.logger.info('webhook updated', { orgId, automationId: id });\n return toWebhook(updated);\n }\n\n async deleteWebhook(id: string, actor: Actor): Promise<void> {\n actor.permissions.require('automations:delete');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const { secretRef } = webhookTarget(existing);\n const deleted = await this.uow.run(async ({ automations, credentials, outbox }) => {\n const removed = await automations.delete(orgId, id);\n if (!removed) {\n return null;\n }\n await credentials.destroy(orgId, secretRef);\n await outbox.append([automationEvents.automationDeleted.make({ orgId, data: removed })]);\n return removed;\n });\n if (!deleted) {\n throw new NotFoundError('Webhook', id);\n }\n this.logger.info('webhook deleted', { orgId, automationId: id });\n }\n\n async revealWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const secrets = await this.credentials.reveal(orgId, webhookTarget(existing).secretRef);\n const secret = secrets?.['secret'];\n if (typeof secret !== 'string') {\n throw new Error(`webhook ${id}: signing secret is missing`);\n }\n return { secret };\n }\n\n async rotateWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const secret = generateWebhookSecret();\n await this.credentials.update(orgId, webhookTarget(existing).secretRef, { secret });\n this.logger.info('webhook secret rotated', { orgId, automationId: id });\n return { secret };\n }\n\n private async requireWebhook(orgId: string, id: string): Promise<Automation> {\n const automation = await this.repo.findById(orgId, id);\n if (automation?.kind !== 'webhook') {\n throw new NotFoundError('Webhook', id);\n }\n return automation;\n }\n\n availableActions(actor: Actor): AvailableActions {\n actor.permissions.require('automations:read');\n return [\n ...catalogActions(),\n ...this.integrations.available(this.systemActor(actor.orgId)).flatMap((integration) =>\n integration.actions.map((action) => ({\n type: `${integration.id}.${action.id}`,\n description: action.description,\n inputSchema: action.inputSchema as Record<string, JsonValue>,\n source: integration.id,\n })),\n ),\n ];\n }\n\n availableTriggers(actor: Actor): AvailableTriggers {\n actor.permissions.require('automations:read');\n return { triggers: catalogTriggers() };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../src/automations/service.ts"],"sourcesContent":["// automations context — service implementation (inbound port) and the\n// AutomationExecutor the engine drives.\n//\n// `handle` is subscribed to all events on the EventBus: it matches an event\n// against enabled automations for its trigger, opens one run per match, and\n// hands it to the injected AutomationEngine, which calls back into\n// `runAction`/`finalize`.\nimport { assertGrantsAllowed, assertReadsEvents } from './event-permissions.js';\nimport {\n catalogActions,\n catalogTriggers,\n DELIVER_WEBHOOK_ACTION,\n publicDataSchema,\n} from './catalog.js';\nimport { executeAction, type ActionOutcome } from './actions.js';\nimport { generateWebhookSecret } from './webhook-signing.js';\nimport type { CommunityMailReads, GrantWriter } from './community-mail.js';\nimport { cronSupported } from './schedule.js';\nimport {\n ActionFailedError,\n AutomationKindMismatchError,\n InvalidTriggerError,\n ReservedActionError,\n type Automation,\n type AutomationAction,\n type AutomationActionResult,\n type AutomationRun,\n type CreatedWebhook,\n type DeliverWebhookInput,\n type Page,\n type Webhook,\n type WebhookSecret,\n} from './model.js';\nimport type {\n AutomationRunsQuery,\n AutomationsQuery,\n AvailableActions,\n AvailableTriggers,\n CreateAutomationInput,\n CreateWebhookInput,\n UpdateAutomationInput,\n UpdateWebhookInput,\n} from './types.js';\nimport type {\n AutomationDispatch,\n AutomationEngine,\n AutomationExecutor,\n AutomationRunsRepository,\n AutomationsRepository,\n AutomationsService,\n AutomationsUnitOfWork,\n WebhookSender,\n} from './ports.js';\nimport type { CredentialStore, DomainEvent, Logger } from '../shared/ports.js';\nimport type { JsonValue, ScheduledAutomation } from '../types/index.js';\nimport { deliverWebhookInputSchema } from '../types/schemas/index.js';\nimport { ConflictError, InvalidInputError, NotFoundError } from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\nimport type { Mailer, MailerLookups } from '../shared/mailer.js';\nimport type { IntegrationsService } from '../integrations/index.js';\nimport type { Actor } from '../shared/actor.js';\nimport { automationEvents } from './events.js';\n\n/** True only when `input` sets `enabled` and nothing else — emits automation.enabled|disabled instead of automation.updated. */\nfunction isEnabledOnlyUpdate<T extends { enabled?: boolean }>(\n input: T,\n): input is T & { enabled: boolean } {\n if (input.enabled === undefined) {\n return false;\n }\n const { enabled: _enabled, ...rest } = input;\n return Object.values(rest).every((v) => v === undefined);\n}\n\nfunction floorMinute(at: Date): number {\n const copy = new Date(at);\n copy.setUTCSeconds(0, 0);\n return copy.getTime();\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction filterMatches(filter: Record<string, JsonValue> | null, data: unknown): boolean {\n if (filter == null) {\n return true;\n }\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n return false;\n }\n const record = data as Record<string, unknown>;\n return Object.entries(filter).every(([key, expected]) => {\n if (!Object.prototype.hasOwnProperty.call(record, key)) {\n return false;\n }\n return JSON.stringify(record[key]) === JSON.stringify(expected);\n });\n}\n\nfunction assertAuthorableTriggers(triggers: string[]): void {\n for (const trigger of triggers) {\n if (trigger.startsWith('automation.')) {\n throw new InvalidTriggerError(trigger);\n }\n if (trigger.startsWith('schedule:') && !cronSupported(trigger.slice('schedule:'.length))) {\n throw new InvalidTriggerError(trigger, 'schedule');\n }\n }\n}\n\nfunction assertCatalogTriggers(triggers: string[], schedules: boolean): void {\n assertAuthorableTriggers(triggers);\n const known = new Set(catalogTriggers().map((t) => t.type));\n for (const trigger of triggers) {\n if (!(schedules && trigger.startsWith('schedule:')) && !known.has(trigger)) {\n throw new InvalidTriggerError(trigger, 'unknown');\n }\n }\n}\n\nconst REMOVED_ACTIONS = new Set([\n 'notify',\n 'publishDuePosts',\n 'expireDueGrants',\n 'sendDigest',\n 'removeUnattachedUploads',\n]);\n\nfunction assertAuthorableActions(actions: AutomationAction[]): void {\n for (const action of actions) {\n if (action.type === DELIVER_WEBHOOK_ACTION) {\n throw new ReservedActionError(action.type);\n }\n if (REMOVED_ACTIONS.has(action.type)) {\n throw new InvalidInputError(`The action \"${action.type}\" is no longer available`);\n }\n }\n}\n\nconst SCHEDULE_FIRED = 'automation.schedule.fired';\n\nfunction publicEventData(event: DomainEvent): JsonValue {\n const parsed =\n event.type === SCHEDULE_FIRED\n ? { success: true as const, data: event.data }\n : publicDataSchema(event.type)?.safeParse(event.data);\n return parsed?.success ? (JSON.parse(JSON.stringify(parsed.data)) as JsonValue) : null;\n}\n\n/** A run as callers see it: its event carries only what a webhook of that event would. */\nfunction toRunView(run: AutomationRun): AutomationRun {\n const { type, version, id, orgId, occurredAt } = run.event;\n return {\n ...run,\n event: { type, version, id, orgId, occurredAt, data: publicEventData(run.event) },\n };\n}\n\n/** An automation as callers see it: a webhook's credential reference stays internal. */\nfunction toAutomationView(automation: Automation): Automation {\n return {\n ...automation,\n actions: automation.actions.map((action) => {\n if (action.type !== DELIVER_WEBHOOK_ACTION) {\n return action;\n }\n const { secretRef: _secretRef, ...input } = action.input;\n return { ...action, input };\n }),\n };\n}\n\nfunction webhookTarget(automation: Automation): DeliverWebhookInput {\n return deliverWebhookInputSchema.parse(automation.actions[0]?.input);\n}\n\nfunction toWebhook(automation: Automation): Webhook {\n return {\n orgId: automation.orgId,\n id: automation.id,\n url: webhookTarget(automation).url,\n events: automation.triggers,\n description: automation.description,\n enabled: automation.enabled,\n createdAt: automation.createdAt,\n updatedAt: automation.updatedAt,\n };\n}\n\nfunction updateEvent(orgId: string, input: { enabled?: boolean }, updated: Automation) {\n if (isEnabledOnlyUpdate(input)) {\n return input.enabled\n ? automationEvents.automationEnabled.make({ orgId, data: updated })\n : automationEvents.automationDisabled.make({ orgId, data: updated });\n }\n return automationEvents.automationUpdated.make({ orgId, data: updated });\n}\n\nexport type AutomationsServiceParams = {\n /** Read-only access (list/get/available) — runs outside any transaction. */\n repo: AutomationsRepository;\n runsRepo: AutomationRunsRepository;\n /** Atomic write scope: tx-bound repos + credential store + outbox appender. */\n uow: AutomationsUnitOfWork;\n engine: AutomationEngine;\n mailer: Pick<Mailer, 'send'>;\n lookups: MailerLookups;\n integrations: Pick<IntegrationsService, 'available'>;\n systemActor: (orgId: string) => Actor;\n credentials: CredentialStore;\n webhooks: WebhookSender;\n mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;\n grants: GrantWriter;\n logger?: Logger;\n};\n\nexport class AutomationsServiceImpl implements AutomationsService, AutomationExecutor {\n private readonly repo: AutomationsRepository;\n private readonly runsRepo: AutomationRunsRepository;\n private readonly uow: AutomationsUnitOfWork;\n private readonly engine: AutomationEngine;\n private readonly mailer: Pick<Mailer, 'send'>;\n private readonly lookups: MailerLookups;\n private readonly integrations: Pick<IntegrationsService, 'available'>;\n private readonly systemActor: (orgId: string) => Actor;\n private readonly credentials: CredentialStore;\n private readonly webhooks: WebhookSender;\n private readonly mail: CommunityMailReads;\n private readonly grants: GrantWriter;\n private readonly logger: Logger;\n\n constructor(params: AutomationsServiceParams) {\n this.repo = params.repo;\n this.runsRepo = params.runsRepo;\n this.uow = params.uow;\n this.engine = params.engine;\n this.mailer = params.mailer;\n this.lookups = params.lookups;\n this.integrations = params.integrations;\n this.systemActor = params.systemActor;\n this.credentials = params.credentials;\n this.webhooks = params.webhooks;\n this.mail = {\n ...params.mail,\n recentMessageRecipients: (orgId, automationId, chatId, since) =>\n this.runsRepo.recentRecipients(orgId, automationId, chatId, since),\n };\n this.grants = params.grants;\n this.logger = params.logger ?? noopLogger;\n }\n\n async handle(event: DomainEvent): Promise<void> {\n // automation.* events are this service's own output — matching one as a trigger would self-loop.\n if (event.type.startsWith('automation.')) {\n return;\n }\n const automations = await this.safeListByTrigger(event);\n for (const automation of automations) {\n const matches = filterMatches(automation.filter, event.data);\n if (!automation.enabled || !matches) {\n if (automation.enabled && !matches) {\n this.logger.debug('automation filter skipped', {\n orgId: event.orgId,\n automationId: automation.id,\n trigger: event.type,\n });\n }\n continue;\n }\n await this.dispatchOne(automation, event);\n }\n }\n\n private async reconcileSchedules(orgId: string): Promise<void> {\n try {\n await this.engine.syncSchedules?.();\n } catch (err) {\n this.logger.error('automation schedules not reconciled', { orgId, err });\n }\n }\n\n private async safeListByTrigger(event: DomainEvent): Promise<Automation[]> {\n try {\n return await this.repo.listByTrigger(event.orgId, event.type);\n } catch (err) {\n this.logger.error('automations: failed to load trigger matches', {\n orgId: event.orgId,\n trigger: event.type,\n err,\n });\n return [];\n }\n }\n\n private async dispatchOne(automation: Automation, event: DomainEvent): Promise<void> {\n let run: AutomationRun | null = null;\n try {\n run = await this.openRun(automation, event);\n if (!run) {\n // At-least-once redelivery of a trigger event already run for this automation — no-op.\n return;\n }\n await this.engine.dispatch(this.dispatchFor(automation, run, event));\n } catch (err) {\n this.logger.error('automation run failed', {\n orgId: event.orgId,\n automationId: automation.id,\n runId: run?.id,\n trigger: event.type,\n eventId: event.id,\n err,\n });\n if (run) {\n await this.recordFailure(run, err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n private openRun(automation: Automation, event: DomainEvent): Promise<AutomationRun | null> {\n const now = new Date();\n return this.uow.run(async ({ runs, outbox }) => {\n const inserted = await runs.insert(event.orgId, {\n orgId: event.orgId,\n automationId: automation.id,\n trigger: event.type,\n event,\n status: 'running',\n actionResults: [],\n startedAt: now,\n finishedAt: null,\n createdAt: now,\n updatedAt: now,\n });\n if (!inserted) {\n return null;\n }\n await outbox.append([\n automationEvents.runStarted.make({\n orgId: event.orgId,\n data: inserted,\n }),\n ]);\n return inserted;\n });\n }\n\n private dispatchFor(\n automation: Automation,\n run: AutomationRun,\n event: DomainEvent,\n ): AutomationDispatch {\n return {\n runId: run.id,\n orgId: event.orgId,\n automationId: automation.id,\n actions: automation.actions,\n event,\n };\n }\n\n /** Best-effort: logs and never rethrows, so an org automation never fails `handle`. */\n private async recordFailure(run: AutomationRun, error: string): Promise<AutomationRun | null> {\n try {\n return await this.uow.run(async ({ runs, outbox }) => {\n const failed = await runs.recordOutcome(run.orgId, run.id, {\n status: 'failed',\n actionResults: run.actionResults,\n finishedAt: new Date(),\n });\n if (failed) {\n await outbox.append([\n automationEvents.runFailed.make({\n orgId: run.orgId,\n data: failed,\n }),\n ]);\n }\n return failed;\n });\n } catch (err) {\n this.logger.error('failed to record automation run failure', {\n orgId: run.orgId,\n automationId: run.automationId,\n runId: run.id,\n err,\n originalError: error,\n });\n return null;\n }\n }\n\n async runAction(d: AutomationDispatch, index: number): Promise<AutomationActionResult> {\n const action = d.actions[index];\n if (!action) {\n throw new Error(`automation ${d.automationId} run ${d.runId}: no action at index ${index}`);\n }\n let outcome: ActionOutcome;\n try {\n outcome = await executeAction(action, d.event, {\n mailer: this.mailer,\n lookups: this.lookups,\n credentials: this.credentials,\n webhooks: this.webhooks,\n mail: this.mail,\n grants: this.grants,\n automationId: d.automationId,\n actionInput: action.input,\n logger: this.logger,\n });\n } catch (err) {\n this.logger.error('automation action failed', {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n trigger: d.event.type,\n index,\n type: action.type,\n err,\n });\n throw err instanceof ActionFailedError ? err : new ActionFailedError();\n }\n const { recipients, failed } = outcome;\n this.logger.info('automation action completed', {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n type: action.type,\n recipients: recipients.length,\n failed: failed.length,\n });\n return {\n index,\n type: action.type,\n status: 'completed',\n ...(recipients.length > 0 ? { recipients } : {}),\n ...(failed.length > 0\n ? { error: `delivery failed for ${failed.length} recipients: ${failed.join(', ')}` }\n : {}),\n };\n }\n\n async listSchedules(): Promise<ScheduledAutomation[]> {\n return this.repo.listSchedules();\n }\n\n async fireSchedule(orgId: string, automationId: string, at: Date): Promise<void> {\n const firedAt = new Date(floorMinute(at));\n const automation = await this.repo.findById(orgId, automationId);\n if (!automation?.enabled || firedAt.getTime() < floorMinute(automation.createdAt)) {\n this.logger.debug('schedule skipped', { orgId, automationId });\n return;\n }\n const event: DomainEvent = {\n type: SCHEDULE_FIRED,\n id: `schedule_${automationId}_${firedAt.toISOString()}`,\n orgId,\n version: 1,\n occurredAt: firedAt.toISOString(),\n data: { automationId, firedAt: firedAt.toISOString() },\n };\n await this.dispatchOne(automation, event);\n }\n\n async finalize(d: AutomationDispatch, results: AutomationActionResult[]): Promise<void> {\n const status: 'completed' | 'failed' =\n results.length === d.actions.length && results.every((r) => r.status === 'completed')\n ? 'completed'\n : 'failed';\n await this.uow.run(async ({ runs, outbox }) => {\n const run = await runs.recordOutcome(d.orgId, d.runId, {\n status,\n actionResults: results,\n finishedAt: new Date(),\n });\n if (!run) {\n return;\n }\n const runEvent =\n status === 'completed'\n ? automationEvents.runCompleted.make({ orgId: d.orgId, data: run })\n : automationEvents.runFailed.make({ orgId: d.orgId, data: run });\n const actionFailedEvents = results\n .filter((r) => r.status === 'failed')\n .map((result) => ({\n ...automationEvents.actionFailed.make({\n orgId: d.orgId,\n data: result,\n }),\n }));\n await outbox.append([runEvent, ...actionFailedEvents]);\n });\n this.logOutcome(d, status, results);\n }\n\n private logOutcome(\n d: AutomationDispatch,\n status: 'completed' | 'failed',\n results: AutomationActionResult[],\n ): void {\n const run = {\n orgId: d.orgId,\n automationId: d.automationId,\n runId: d.runId,\n trigger: d.event.type,\n eventId: d.event.id,\n };\n if (status === 'failed') {\n const failed = results.find((r) => r.status === 'failed');\n const index = failed?.index ?? results.length;\n this.logger.error('automation run failed', {\n ...run,\n index,\n action: failed?.type ?? d.actions[index]?.type,\n error: failed?.error ?? 'not every action ran',\n });\n return;\n }\n const partial = results.filter((r) => r.error !== undefined);\n if (partial.length > 0) {\n this.logger.warn('automation run completed with failed deliveries', {\n ...run,\n actions: partial.map(({ index, type, error }) => ({ index, type, error })),\n });\n }\n }\n\n async create(input: CreateAutomationInput, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n assertCatalogTriggers(input.triggers, true);\n assertAuthorableActions(input.actions);\n assertGrantsAllowed(actor, input.actions);\n const automation = await this.uow.run(async ({ automations, outbox }) => {\n const created = await automations.insert(orgId, {\n ...input,\n triggers: unique(input.triggers),\n kind: 'workflow',\n });\n await outbox.append([automationEvents.automationCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('automation created', {\n orgId,\n automationId: automation.id,\n actorId: actor.id,\n });\n await this.reconcileSchedules(orgId);\n return automation;\n }\n\n async update(id: string, input: UpdateAutomationInput, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n if (input.triggers !== undefined) {\n assertCatalogTriggers(input.triggers, true);\n }\n if (input.actions !== undefined) {\n assertAuthorableActions(input.actions);\n assertGrantsAllowed(actor, input.actions);\n }\n const existing = await this.repo.findById(orgId, id);\n if (!existing) {\n throw new NotFoundError('Automation', id);\n }\n if (existing.kind !== 'workflow') {\n throw new AutomationKindMismatchError(id, existing.kind);\n }\n const patch =\n input.triggers === undefined ? input : { ...input, triggers: unique(input.triggers) };\n const automation = await this.uow.run(async ({ automations, outbox }) => {\n const updated = await automations.update(orgId, id, patch);\n if (!updated) {\n return null;\n }\n await outbox.append([updateEvent(orgId, input, updated)]);\n return updated;\n });\n if (!automation) {\n throw new NotFoundError('Automation', id);\n }\n this.logger.info('automation updated', { orgId, automationId: id });\n await this.reconcileSchedules(orgId);\n return automation;\n }\n\n async delete(id: string, actor: Actor): Promise<void> {\n actor.permissions.require('automations:delete');\n const orgId = actor.orgId;\n const existing = await this.repo.findById(orgId, id);\n if (!existing) {\n throw new NotFoundError('Automation', id);\n }\n if (existing.kind !== 'workflow') {\n throw new AutomationKindMismatchError(id, existing.kind);\n }\n const deleted = await this.uow.run(async ({ automations, outbox }) => {\n const removed = await automations.delete(orgId, id);\n if (!removed) {\n return null;\n }\n await outbox.append([automationEvents.automationDeleted.make({ orgId, data: removed })]);\n return removed;\n });\n if (!deleted) {\n throw new NotFoundError('Automation', id);\n }\n this.logger.info('automation deleted', { orgId, automationId: id });\n await this.reconcileSchedules(orgId);\n }\n\n async list(query: AutomationsQuery | undefined, actor: Actor): Promise<Automation[]> {\n actor.permissions.require('automations:read');\n const automations = await this.repo.listByOrg(actor.orgId, query?.kind);\n return automations.map(toAutomationView);\n }\n\n async get(id: string, actor: Actor): Promise<Automation> {\n actor.permissions.require('automations:read');\n const automation = await this.repo.findById(actor.orgId, id);\n if (!automation) {\n throw new NotFoundError('Automation', id);\n }\n return toAutomationView(automation);\n }\n\n async listRuns(\n automationId: string,\n query: AutomationRunsQuery,\n actor: Actor,\n ): Promise<Page<AutomationRun>> {\n actor.permissions.require('automations:read');\n const page = await this.runsRepo.list(actor.orgId, automationId, query);\n return { ...page, rows: page.rows.map(toRunView) };\n }\n\n async rerun(automationId: string, runId: string, actor: Actor): Promise<AutomationRun> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.runsRepo.findById(orgId, runId);\n if (!existing || existing.automationId !== automationId) {\n throw new NotFoundError('Automation run', runId);\n }\n const automation = await this.repo.findById(orgId, automationId);\n if (!automation) {\n throw new NotFoundError('Automation', automationId);\n }\n assertGrantsAllowed(actor, automation.actions);\n const run = await this.uow.run(async ({ runs, outbox }) => {\n const restarted = await runs.restart(orgId, runId, new Date());\n if (!restarted) {\n return null;\n }\n await outbox.append([automationEvents.runStarted.make({ orgId, data: restarted })]);\n return restarted;\n });\n if (!run) {\n throw new ConflictError(`automation run ${runId} is still running`);\n }\n try {\n await this.engine.dispatch(this.dispatchFor(automation, run, run.event));\n } catch (err) {\n this.logger.error('automation rerun failed', {\n orgId,\n automationId,\n runId: run.id,\n trigger: run.trigger,\n err,\n });\n const failed = await this.recordFailure(\n run,\n err instanceof Error ? err.message : String(err),\n );\n return toRunView(failed ?? run);\n }\n this.logger.info('automation rerun started', { orgId, automationId, runId: run.id });\n return toRunView(run);\n }\n\n async listWebhooks(actor: Actor): Promise<Webhook[]> {\n actor.permissions.require('automations:read');\n const automations = await this.repo.listByOrg(actor.orgId, 'webhook');\n return automations.map(toWebhook);\n }\n\n async getWebhook(id: string, actor: Actor): Promise<Webhook> {\n actor.permissions.require('automations:read');\n return toWebhook(await this.requireWebhook(actor.orgId, id));\n }\n\n async createWebhook(input: CreateWebhookInput, actor: Actor): Promise<CreatedWebhook> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const events = unique(input.events);\n assertCatalogTriggers(events, false);\n assertReadsEvents(actor, events);\n const secret = generateWebhookSecret();\n const automation = await this.uow.run(async ({ automations, credentials, outbox }) => {\n const secretRef = await credentials.store(orgId, { secret });\n const created = await automations.insert(orgId, {\n kind: 'webhook',\n name: input.url,\n description: input.description,\n triggers: events,\n actions: [{ type: DELIVER_WEBHOOK_ACTION, input: { url: input.url, secretRef } }],\n });\n await outbox.append([automationEvents.automationCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('webhook created', { orgId, automationId: automation.id });\n return { ...toWebhook(automation), secret };\n }\n\n async updateWebhook(id: string, input: UpdateWebhookInput, actor: Actor): Promise<Webhook> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const events = input.events === undefined ? undefined : unique(input.events);\n if (events) {\n assertCatalogTriggers(events, false);\n assertReadsEvents(actor, events);\n }\n const { secretRef } = webhookTarget(existing);\n const patch: UpdateAutomationInput = {\n name: input.url,\n description: input.description,\n triggers: events,\n actions:\n input.url === undefined\n ? undefined\n : [{ type: DELIVER_WEBHOOK_ACTION, input: { url: input.url, secretRef } }],\n enabled: input.enabled,\n };\n const updated = await this.uow.run(async ({ automations, outbox }) => {\n const row = await automations.update(orgId, id, patch);\n if (!row) {\n return null;\n }\n await outbox.append([updateEvent(orgId, input, row)]);\n return row;\n });\n if (!updated) {\n throw new NotFoundError('Webhook', id);\n }\n this.logger.info('webhook updated', { orgId, automationId: id });\n return toWebhook(updated);\n }\n\n async deleteWebhook(id: string, actor: Actor): Promise<void> {\n actor.permissions.require('automations:delete');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const { secretRef } = webhookTarget(existing);\n const deleted = await this.uow.run(async ({ automations, credentials, outbox }) => {\n const removed = await automations.delete(orgId, id);\n if (!removed) {\n return null;\n }\n await credentials.destroy(orgId, secretRef);\n await outbox.append([automationEvents.automationDeleted.make({ orgId, data: removed })]);\n return removed;\n });\n if (!deleted) {\n throw new NotFoundError('Webhook', id);\n }\n this.logger.info('webhook deleted', { orgId, automationId: id });\n }\n\n async revealWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const secrets = await this.credentials.reveal(orgId, webhookTarget(existing).secretRef);\n const secret = secrets?.['secret'];\n if (typeof secret !== 'string') {\n throw new Error(`webhook ${id}: signing secret is missing`);\n }\n return { secret };\n }\n\n async rotateWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret> {\n actor.permissions.require('automations:write');\n const orgId = actor.orgId;\n const existing = await this.requireWebhook(orgId, id);\n const secret = generateWebhookSecret();\n await this.credentials.update(orgId, webhookTarget(existing).secretRef, { secret });\n this.logger.info('webhook secret rotated', { orgId, automationId: id });\n return { secret };\n }\n\n private async requireWebhook(orgId: string, id: string): Promise<Automation> {\n const automation = await this.repo.findById(orgId, id);\n if (automation?.kind !== 'webhook') {\n throw new NotFoundError('Webhook', id);\n }\n return automation;\n }\n\n availableActions(actor: Actor): AvailableActions {\n actor.permissions.require('automations:read');\n return [\n ...catalogActions(),\n ...this.integrations.available(this.systemActor(actor.orgId)).flatMap((integration) =>\n integration.actions.map((action) => ({\n type: `${integration.id}.${action.id}`,\n description: action.description,\n inputSchema: action.inputSchema as Record<string, JsonValue>,\n source: integration.id,\n })),\n ),\n ];\n }\n\n availableTriggers(actor: Actor): AvailableTriggers {\n actor.permissions.require('automations:read');\n return { triggers: catalogTriggers() };\n }\n}\n"],"mappings":"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"}
|
package/dist/content/events.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ declare const contentEvents: {
|
|
|
58
58
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
59
59
|
title: z.ZodString;
|
|
60
60
|
description: z.ZodString;
|
|
61
|
+
category: z.ZodString;
|
|
61
62
|
settings: z.ZodObject<{
|
|
62
63
|
transcriptDownloads: z.ZodBoolean;
|
|
63
64
|
comments: z.ZodOptional<z.ZodObject<{
|
|
@@ -68,7 +69,6 @@ declare const contentEvents: {
|
|
|
68
69
|
}, z.core.$strict>>;
|
|
69
70
|
}, z.core.$strict>;
|
|
70
71
|
slug: z.ZodString;
|
|
71
|
-
category: z.ZodString;
|
|
72
72
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
73
73
|
}, z.core.$strip>>;
|
|
74
74
|
courseUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -125,6 +125,7 @@ declare const contentEvents: {
|
|
|
125
125
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
126
126
|
title: z.ZodString;
|
|
127
127
|
description: z.ZodString;
|
|
128
|
+
category: z.ZodString;
|
|
128
129
|
settings: z.ZodObject<{
|
|
129
130
|
transcriptDownloads: z.ZodBoolean;
|
|
130
131
|
comments: z.ZodOptional<z.ZodObject<{
|
|
@@ -135,7 +136,6 @@ declare const contentEvents: {
|
|
|
135
136
|
}, z.core.$strict>>;
|
|
136
137
|
}, z.core.$strict>;
|
|
137
138
|
slug: z.ZodString;
|
|
138
|
-
category: z.ZodString;
|
|
139
139
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
140
140
|
}, z.core.$strip>>;
|
|
141
141
|
courseDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -192,6 +192,7 @@ declare const contentEvents: {
|
|
|
192
192
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
193
193
|
title: z.ZodString;
|
|
194
194
|
description: z.ZodString;
|
|
195
|
+
category: z.ZodString;
|
|
195
196
|
settings: z.ZodObject<{
|
|
196
197
|
transcriptDownloads: z.ZodBoolean;
|
|
197
198
|
comments: z.ZodOptional<z.ZodObject<{
|
|
@@ -202,7 +203,6 @@ declare const contentEvents: {
|
|
|
202
203
|
}, z.core.$strict>>;
|
|
203
204
|
}, z.core.$strict>;
|
|
204
205
|
slug: z.ZodString;
|
|
205
|
-
category: z.ZodString;
|
|
206
206
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
207
207
|
}, z.core.$strip>>;
|
|
208
208
|
moduleCreated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -328,9 +328,9 @@ declare const contentEvents: {
|
|
|
328
328
|
id: z.ZodString;
|
|
329
329
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
330
330
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
331
|
+
moduleId: z.ZodString;
|
|
331
332
|
courseId: z.ZodString;
|
|
332
333
|
seq: z.ZodNumber;
|
|
333
|
-
moduleId: z.ZodString;
|
|
334
334
|
}, z.core.$strip>>;
|
|
335
335
|
activityUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
336
336
|
orgId: string;
|
|
@@ -355,9 +355,9 @@ declare const contentEvents: {
|
|
|
355
355
|
id: z.ZodString;
|
|
356
356
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
357
357
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
358
|
+
moduleId: z.ZodString;
|
|
358
359
|
courseId: z.ZodString;
|
|
359
360
|
seq: z.ZodNumber;
|
|
360
|
-
moduleId: z.ZodString;
|
|
361
361
|
}, z.core.$strip>>;
|
|
362
362
|
activityDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
363
363
|
orgId: string;
|
|
@@ -382,9 +382,9 @@ declare const contentEvents: {
|
|
|
382
382
|
id: z.ZodString;
|
|
383
383
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
384
384
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
385
|
+
moduleId: z.ZodString;
|
|
385
386
|
courseId: z.ZodString;
|
|
386
387
|
seq: z.ZodNumber;
|
|
387
|
-
moduleId: z.ZodString;
|
|
388
388
|
}, z.core.$strip>>;
|
|
389
389
|
activityPublished: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
390
390
|
activityId: string;
|
|
@@ -460,8 +460,8 @@ declare const contentEvents: {
|
|
|
460
460
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
461
461
|
title: z.ZodString;
|
|
462
462
|
description: z.ZodString;
|
|
463
|
-
slug: z.ZodString;
|
|
464
463
|
category: z.ZodString;
|
|
464
|
+
slug: z.ZodString;
|
|
465
465
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
466
466
|
}, z.core.$strip>>;
|
|
467
467
|
downloadUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -500,8 +500,8 @@ declare const contentEvents: {
|
|
|
500
500
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
501
501
|
title: z.ZodString;
|
|
502
502
|
description: z.ZodString;
|
|
503
|
-
slug: z.ZodString;
|
|
504
503
|
category: z.ZodString;
|
|
504
|
+
slug: z.ZodString;
|
|
505
505
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
506
506
|
}, z.core.$strip>>;
|
|
507
507
|
downloadDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -540,8 +540,8 @@ declare const contentEvents: {
|
|
|
540
540
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
541
541
|
title: z.ZodString;
|
|
542
542
|
description: z.ZodString;
|
|
543
|
-
slug: z.ZodString;
|
|
544
543
|
category: z.ZodString;
|
|
544
|
+
slug: z.ZodString;
|
|
545
545
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
546
546
|
}, z.core.$strip>>;
|
|
547
547
|
downloadAssetAdded: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
@@ -576,8 +576,8 @@ declare const contentEvents: {
|
|
|
576
576
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
577
577
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
578
578
|
seq: z.ZodNumber;
|
|
579
|
-
downloadId: z.ZodString;
|
|
580
579
|
assetId: z.ZodString;
|
|
580
|
+
downloadId: z.ZodString;
|
|
581
581
|
displayName: z.ZodNullable<z.ZodString>;
|
|
582
582
|
}, z.core.$strip>>;
|
|
583
583
|
}, z.core.$strip>>;
|
|
@@ -613,8 +613,8 @@ declare const contentEvents: {
|
|
|
613
613
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
614
614
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
615
615
|
seq: z.ZodNumber;
|
|
616
|
-
downloadId: z.ZodString;
|
|
617
616
|
assetId: z.ZodString;
|
|
617
|
+
downloadId: z.ZodString;
|
|
618
618
|
displayName: z.ZodNullable<z.ZodString>;
|
|
619
619
|
}, z.core.$strip>>;
|
|
620
620
|
}, z.core.$strip>>;
|
|
@@ -650,8 +650,8 @@ declare const contentEvents: {
|
|
|
650
650
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
651
651
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
652
652
|
seq: z.ZodNumber;
|
|
653
|
-
downloadId: z.ZodString;
|
|
654
653
|
assetId: z.ZodString;
|
|
654
|
+
downloadId: z.ZodString;
|
|
655
655
|
displayName: z.ZodNullable<z.ZodString>;
|
|
656
656
|
}, z.core.$strip>>;
|
|
657
657
|
}, z.core.$strip>>;
|
|
@@ -687,8 +687,8 @@ declare const contentEvents: {
|
|
|
687
687
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
688
688
|
updatedAt: z.ZodCoercedDate<unknown>;
|
|
689
689
|
seq: z.ZodNumber;
|
|
690
|
-
downloadId: z.ZodString;
|
|
691
690
|
assetId: z.ZodString;
|
|
691
|
+
downloadId: z.ZodString;
|
|
692
692
|
displayName: z.ZodNullable<z.ZodString>;
|
|
693
693
|
}, z.core.$strip>>;
|
|
694
694
|
}, z.core.$strip>>;
|
|
@@ -20,12 +20,15 @@ interface ScheduledAutomation {
|
|
|
20
20
|
interface AutomationExecutor {
|
|
21
21
|
runAction(d: AutomationDispatch, index: number): Promise<AutomationActionResult>;
|
|
22
22
|
finalize(d: AutomationDispatch, results: AutomationActionResult[]): Promise<void>;
|
|
23
|
-
runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void>;
|
|
24
23
|
listSchedules?(): Promise<ScheduledAutomation[]>;
|
|
25
24
|
fireSchedule?(orgId: string, automationId: string, firedAt: Date): Promise<void>;
|
|
26
25
|
}
|
|
26
|
+
interface DeliveryExecutor {
|
|
27
|
+
runDelivery(d: DeliveryDispatch, lastAttempt: boolean): Promise<void>;
|
|
28
|
+
}
|
|
27
29
|
interface AutomationEngine {
|
|
28
30
|
register(executor: AutomationExecutor): void;
|
|
31
|
+
registerDeliveries(executor: DeliveryExecutor): void;
|
|
29
32
|
dispatch(d: AutomationDispatch): Promise<void>;
|
|
30
33
|
deliver(d: DeliveryDispatch): Promise<void>;
|
|
31
34
|
start(): Promise<void>;
|
|
@@ -44,5 +47,5 @@ interface WebhookSender {
|
|
|
44
47
|
send(request: WebhookRequest): Promise<WebhookResponse>;
|
|
45
48
|
}
|
|
46
49
|
//#endregion
|
|
47
|
-
export { type Automation, type AutomationAction, type AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, type AutomationKind, type AutomationRun, type AutomationRunStatus, type AutomationRunsQuery, type AutomationTrigger, type AutomationsQuery, type AvailableAction, type AvailableActions, type AvailableTriggers, type CreateAutomationInput, type CreateWebhookInput, type CreatedWebhook, type DeliverWebhookInput, DeliveryDispatch, ScheduledAutomation, type UpdateAutomationInput, type UpdateWebhookInput, type Webhook, WebhookRequest, WebhookResponse, type WebhookSecret, WebhookSender };
|
|
50
|
+
export { type Automation, type AutomationAction, type AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, type AutomationKind, type AutomationRun, type AutomationRunStatus, type AutomationRunsQuery, type AutomationTrigger, type AutomationsQuery, type AvailableAction, type AvailableActions, type AvailableTriggers, type CreateAutomationInput, type CreateWebhookInput, type CreatedWebhook, type DeliverWebhookInput, DeliveryDispatch, DeliveryExecutor, ScheduledAutomation, type UpdateAutomationInput, type UpdateWebhookInput, type Webhook, WebhookRequest, WebhookResponse, type WebhookSecret, WebhookSender };
|
|
48
51
|
//# sourceMappingURL=automations.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -17,8 +17,8 @@ import "./assets.js";
|
|
|
17
17
|
import { ConfigureInput, ConnectInput, Connection, Validation } from "./schemas/integrations.js";
|
|
18
18
|
import { Action, ActionContext, Integration } from "./integrations.js";
|
|
19
19
|
import { Automation, AutomationAction, AutomationActionResult, AutomationKind, AutomationRun, AutomationRunStatus, AutomationRunsQuery, AutomationTrigger, AutomationsQuery, AvailableAction, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, DeliverWebhookInput, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "./schemas/automations.js";
|
|
20
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "./automations.js";
|
|
20
|
+
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, DeliveryExecutor, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "./automations.js";
|
|
21
21
|
import { ActivityCommentsRule, BlockedUser, Chat, ChatKind, ChatLastMessage, ChatLiveEvent, ChatStatus, ChatUnreadSummary, ChatUser, CommentFlagResolution, CommentListItem, CommentReaction, CommentReportSummary, CommentSettings, CommentStatus, CommentView, CommentsConfig, DigestRun, FlaggedComment, FlaggedCommentView, ListCommentsQuery, LiveMessage, Mention, MentionItemType, MentionView, Message, MessageAttachment, MessageFile, MessageFlag, MessageFlagResolution, MessageReaction, MessageView, Post, PostBookmark, PostFlag, PostFlagResolution, PostReaction, PostStatus, PostView, ReactionCounts, ReactionEmoji, Subscription, SubscriptionItemType, SubscriptionState, SubscriptionView } from "./schemas/discussion.js";
|
|
22
22
|
import { Comment, CommentAuthor, CommentReport } from "./discussion.js";
|
|
23
23
|
import { ChannelRecipient, Delivery, DeliveryResult, DeliveryStatus, DeviceView, NotificationCategory, NotificationFilter, NotificationTypeDeclaration, PushConfig, PushDevice, PushMessage, PushProvider, Reason, RecipientList, Scope, SettingsScope, StoredNotification, StoredSetting, SubjectRef } from "./notifications.js";
|
|
24
|
-
export { type AcceptInviteInput, AccessGrant, AccessRequest, AccessTokenVerifier, AccountProvisioner, Action, ActionContext, ActiveSession, type Activity, type ActivityAsset, type ActivityCommentsRule, type ActivitySettings, type ActivityView, type AddDownloadAssetInput, type AddEventAssetInput, type AddOrgUserInput, type AddSpaceLinkInput, ApiKeySummary, type Asset, type AssetKind, type AssetSource, type AssetStatus, type AssetUrls, type AssetView, type AssetsQuery, type Automation, type AutomationAction, type AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, type AutomationKind, type AutomationRun, type AutomationRunStatus, type AutomationRunsQuery, type AutomationTrigger, type AutomationsQuery, type AvailableAction, type AvailableActions, type AvailableTriggers, type BlockedUser, type Bundle, type BundleItem, ChannelRecipient, type Chat, type ChatKind, type ChatLastMessage, type ChatLiveEvent, type ChatStatus, type ChatUnreadSummary, type ChatUser, Comment, CommentAuthor, type CommentFlagResolution, type CommentListItem, type CommentReaction, CommentReport, type CommentReportSummary, type CommentSettings, type CommentStatus, type CommentView, type CommentsConfig, type Community, type CommunitySettings, type CommunityStatus, type CommunityView, type ConfigureInput, type ConnectInput, ConnectedApp, type Connection, ContentId, type ContentItem, type ContentType, ContractNewDomainEvent, type Course, type CourseSettings, type CourseStatus, type CourseView, type CreateAutomationInput, type CreateBundleInput, type CreateCommunityInput, type CreateCourseInput, type CreateDownloadInput, type CreateEventInput, type CreateInviteInput, type CreateOrgUserInput, CreateOrganizationInput, type CreateSpaceInput, type CreateUserInput, type CreateWebhookInput, CreatedApiKey, type CreatedWebhook, CredentialLimit, type DeliverWebhookInput, Delivery, DeliveryDispatch, DeliveryResult, DeliveryStatus, DeviceView, type DigestCadence, type DigestRun, type DigestSchedule, type DmSettings, DomainEvent, type Download, type DownloadAsset, type DownloadFile, type DownloadStatus, type DownloadView, EmailContent, EmailMessage, EmailSender, EmailTemplateId, EmailTemplateParams, type Entitlement, type EntitlementStatus, type EntitlementsQuery, type Event, type EventAddress, type EventAnalytics, type EventAsset, type EventAttendee, type EventAttendeeFace, type EventAttendeeSource, EventDefinition, EventEmailParams, type EventFile, type EventLead, type EventLocation, EventMetadata, type EventOnline, EventParseResult, type EventRecording, type EventSettings, type EventSort, type EventStatus, type EventType, type EventVenue, type EventView, type FlaggedComment, type FlaggedCommentView, type GrantEntitlementInput, type GrantSource, HeaderBag, Integration, type Invite, InviteId, type InviteInput, JsonValue, type Level, type ListBundlesQuery, type ListCommentsQuery, type ListCommunitiesQuery, type ListCoursesQuery, type ListDownloadsQuery, type ListEventsQuery, type LiveMessage, Logger, MakeEventInput, type MemberEvent, type MemberEventSummary, type MemberEventViewer, type MemberEventsQuery, type Mention, type MentionItemType, type MentionView, type Message, type MessageAttachment, type MessageFile, type MessageFlag, type MessageFlagResolution, type MessageReaction, type MessageView, type Module, NewDomainEvent, type NewOrganizationInput, NotificationCategory, NotificationFilter, NotificationTypeDeclaration, ObjectStorage, type OrgRoleRow, type OrgUser, OrgUserId, type OrgUserInput, type OrgUserProfile, type OrgUserStatus, type Organization, OrganizationId, type OrganizationInput, type OrganizationMetadata, PUBLIC_CACHE_CONTROL, PUBLIC_PREFIX, Page, type PatchCommunitySettingsInput, type PatchDmSettingsInput, type Permission, type Post, type PostBookmark, type PostFlag, type PostFlagResolution, type PostReaction, type PostStatus, type PostView, PresignDownloadInput, PresignedUpload, ProgressId, type ProgressRecord, type ProgressRecordInput, type ProgressReportItem, type ProgressTarget, type ProgressTargetType, type ProvisionUserInput, PushConfig, PushDevice, PushMessage, PushProvider, type ReactionCounts, type ReactionEmoji, Reason, RecipientList, type ReorderDownloadAssetsInput, type ReorderEventAssetsInput, type ReportProgressInput, type RequestUploadInput, type RoleAssignment, type RoleKey, type SaveActivityInput, ScheduledAutomation, Scope, SessionVerifier, type SetSpaceTopicsInput, SettingsScope, type Space, type SpaceAccessRule, type SpaceDetail, type SpaceImage, type SpaceLink, type SpaceMember, type SpaceMemberSource, type SpaceMemberStatus, type SpaceSettings, type SpaceTopic, type SpaceView, StoredNotification, StoredObjectInfo, StoredSetting, SubjectRef, type Subscription, type SubscriptionItemType, type SubscriptionState, type SubscriptionView, TemplateContext, TemplateRenderer, type UpdateAutomationInput, type UpdateBundleInput, type UpdateCommunityInput, type UpdateCourseInput, type UpdateDownloadInput, type UpdateEventInput, type UpdateOrgUserInput, type UpdateSpaceInput, type UpdateUserInput, type UpdateWebhookInput, type UploadTicket, User, UserId, type UserProfile, type UserProfileView, type Validation, type Webhook, WebhookRequest, WebhookResponse, type WebhookSecret, WebhookSender };
|
|
24
|
+
export { type AcceptInviteInput, AccessGrant, AccessRequest, AccessTokenVerifier, AccountProvisioner, Action, ActionContext, ActiveSession, type Activity, type ActivityAsset, type ActivityCommentsRule, type ActivitySettings, type ActivityView, type AddDownloadAssetInput, type AddEventAssetInput, type AddOrgUserInput, type AddSpaceLinkInput, ApiKeySummary, type Asset, type AssetKind, type AssetSource, type AssetStatus, type AssetUrls, type AssetView, type AssetsQuery, type Automation, type AutomationAction, type AutomationActionResult, AutomationDispatch, AutomationEngine, AutomationExecutor, type AutomationKind, type AutomationRun, type AutomationRunStatus, type AutomationRunsQuery, type AutomationTrigger, type AutomationsQuery, type AvailableAction, type AvailableActions, type AvailableTriggers, type BlockedUser, type Bundle, type BundleItem, ChannelRecipient, type Chat, type ChatKind, type ChatLastMessage, type ChatLiveEvent, type ChatStatus, type ChatUnreadSummary, type ChatUser, Comment, CommentAuthor, type CommentFlagResolution, type CommentListItem, type CommentReaction, CommentReport, type CommentReportSummary, type CommentSettings, type CommentStatus, type CommentView, type CommentsConfig, type Community, type CommunitySettings, type CommunityStatus, type CommunityView, type ConfigureInput, type ConnectInput, ConnectedApp, type Connection, ContentId, type ContentItem, type ContentType, ContractNewDomainEvent, type Course, type CourseSettings, type CourseStatus, type CourseView, type CreateAutomationInput, type CreateBundleInput, type CreateCommunityInput, type CreateCourseInput, type CreateDownloadInput, type CreateEventInput, type CreateInviteInput, type CreateOrgUserInput, CreateOrganizationInput, type CreateSpaceInput, type CreateUserInput, type CreateWebhookInput, CreatedApiKey, type CreatedWebhook, CredentialLimit, type DeliverWebhookInput, Delivery, DeliveryDispatch, DeliveryExecutor, DeliveryResult, DeliveryStatus, DeviceView, type DigestCadence, type DigestRun, type DigestSchedule, type DmSettings, DomainEvent, type Download, type DownloadAsset, type DownloadFile, type DownloadStatus, type DownloadView, EmailContent, EmailMessage, EmailSender, EmailTemplateId, EmailTemplateParams, type Entitlement, type EntitlementStatus, type EntitlementsQuery, type Event, type EventAddress, type EventAnalytics, type EventAsset, type EventAttendee, type EventAttendeeFace, type EventAttendeeSource, EventDefinition, EventEmailParams, type EventFile, type EventLead, type EventLocation, EventMetadata, type EventOnline, EventParseResult, type EventRecording, type EventSettings, type EventSort, type EventStatus, type EventType, type EventVenue, type EventView, type FlaggedComment, type FlaggedCommentView, type GrantEntitlementInput, type GrantSource, HeaderBag, Integration, type Invite, InviteId, type InviteInput, JsonValue, type Level, type ListBundlesQuery, type ListCommentsQuery, type ListCommunitiesQuery, type ListCoursesQuery, type ListDownloadsQuery, type ListEventsQuery, type LiveMessage, Logger, MakeEventInput, type MemberEvent, type MemberEventSummary, type MemberEventViewer, type MemberEventsQuery, type Mention, type MentionItemType, type MentionView, type Message, type MessageAttachment, type MessageFile, type MessageFlag, type MessageFlagResolution, type MessageReaction, type MessageView, type Module, NewDomainEvent, type NewOrganizationInput, NotificationCategory, NotificationFilter, NotificationTypeDeclaration, ObjectStorage, type OrgRoleRow, type OrgUser, OrgUserId, type OrgUserInput, type OrgUserProfile, type OrgUserStatus, type Organization, OrganizationId, type OrganizationInput, type OrganizationMetadata, PUBLIC_CACHE_CONTROL, PUBLIC_PREFIX, Page, type PatchCommunitySettingsInput, type PatchDmSettingsInput, type Permission, type Post, type PostBookmark, type PostFlag, type PostFlagResolution, type PostReaction, type PostStatus, type PostView, PresignDownloadInput, PresignedUpload, ProgressId, type ProgressRecord, type ProgressRecordInput, type ProgressReportItem, type ProgressTarget, type ProgressTargetType, type ProvisionUserInput, PushConfig, PushDevice, PushMessage, PushProvider, type ReactionCounts, type ReactionEmoji, Reason, RecipientList, type ReorderDownloadAssetsInput, type ReorderEventAssetsInput, type ReportProgressInput, type RequestUploadInput, type RoleAssignment, type RoleKey, type SaveActivityInput, ScheduledAutomation, Scope, SessionVerifier, type SetSpaceTopicsInput, SettingsScope, type Space, type SpaceAccessRule, type SpaceDetail, type SpaceImage, type SpaceLink, type SpaceMember, type SpaceMemberSource, type SpaceMemberStatus, type SpaceSettings, type SpaceTopic, type SpaceView, StoredNotification, StoredObjectInfo, StoredSetting, SubjectRef, type Subscription, type SubscriptionItemType, type SubscriptionState, type SubscriptionView, TemplateContext, TemplateRenderer, type UpdateAutomationInput, type UpdateBundleInput, type UpdateCommunityInput, type UpdateCourseInput, type UpdateDownloadInput, type UpdateEventInput, type UpdateOrgUserInput, type UpdateSpaceInput, type UpdateUserInput, type UpdateWebhookInput, type UploadTicket, User, UserId, type UserProfile, type UserProfileView, type Validation, type Webhook, WebhookRequest, WebhookResponse, type WebhookSecret, WebhookSender };
|
|
@@ -1066,6 +1066,7 @@ declare const memberEventSchema: z.ZodObject<{
|
|
|
1066
1066
|
title: z.ZodString;
|
|
1067
1067
|
description: z.ZodString;
|
|
1068
1068
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
1069
|
+
thumbnailUrl: z.ZodNullable<z.ZodString>;
|
|
1069
1070
|
timeZone: z.ZodString;
|
|
1070
1071
|
startsAt: z.ZodCoercedDate<unknown>;
|
|
1071
1072
|
endsAt: z.ZodCoercedDate<unknown>;
|
|
@@ -1073,7 +1074,6 @@ declare const memberEventSchema: z.ZodObject<{
|
|
|
1073
1074
|
url: z.ZodURL;
|
|
1074
1075
|
details: z.ZodNullable<z.ZodString>;
|
|
1075
1076
|
}, z.core.$strict>>;
|
|
1076
|
-
thumbnailUrl: z.ZodNullable<z.ZodString>;
|
|
1077
1077
|
location: z.ZodNullable<z.ZodObject<{
|
|
1078
1078
|
venue: z.ZodNullable<z.ZodObject<{
|
|
1079
1079
|
name: z.ZodString;
|
|
@@ -1152,6 +1152,7 @@ declare const memberEventSummarySchema: z.ZodObject<{
|
|
|
1152
1152
|
replay: z.ZodBoolean;
|
|
1153
1153
|
}, z.core.$strict>;
|
|
1154
1154
|
thumbnailAssetId: z.ZodNullable<z.ZodString>;
|
|
1155
|
+
thumbnailUrl: z.ZodNullable<z.ZodString>;
|
|
1155
1156
|
timeZone: z.ZodString;
|
|
1156
1157
|
location: z.ZodNullable<z.ZodObject<{
|
|
1157
1158
|
venue: z.ZodNullable<z.ZodObject<{
|
|
@@ -1176,7 +1177,6 @@ declare const memberEventSummarySchema: z.ZodObject<{
|
|
|
1176
1177
|
url: z.ZodURL;
|
|
1177
1178
|
details: z.ZodNullable<z.ZodString>;
|
|
1178
1179
|
}, z.core.$strict>>;
|
|
1179
|
-
thumbnailUrl: z.ZodNullable<z.ZodString>;
|
|
1180
1180
|
attendeeCount: z.ZodNumber;
|
|
1181
1181
|
attendees: z.ZodArray<z.ZodObject<{
|
|
1182
1182
|
name: z.ZodString;
|