@headless-lms/core 0.4.0 → 0.6.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/assets/events.d.ts +15 -9
- package/dist/assets/file-urls.d.ts +14 -7
- package/dist/assets/file-urls.js +15 -4
- package/dist/assets/file-urls.js.map +1 -1
- package/dist/assets/index.d.ts +4 -4
- package/dist/assets/index.js +3 -3
- package/dist/assets/ports.d.ts +34 -15
- package/dist/assets/service.d.ts +30 -14
- package/dist/assets/service.js +233 -54
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.js +68 -3
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.js +16 -16
- package/dist/automations/community-derivations.js.map +1 -1
- package/dist/automations/community-mail.d.ts +34 -4
- package/dist/automations/community-mail.js +32 -4
- package/dist/automations/community-mail.js.map +1 -1
- package/dist/automations/event-permissions.d.ts +12 -0
- package/dist/automations/event-permissions.js +38 -0
- package/dist/automations/event-permissions.js.map +1 -0
- package/dist/automations/index.d.ts +2 -1
- package/dist/automations/index.js +2 -1
- package/dist/automations/notifications/applicable.d.ts +8 -0
- package/dist/automations/notifications/applicable.js +12 -0
- package/dist/automations/notifications/applicable.js.map +1 -0
- package/dist/automations/notifications/debounce.js +1 -1
- package/dist/automations/notifications/debounce.js.map +1 -1
- package/dist/automations/notifications/defaults.js +33 -3
- package/dist/automations/notifications/defaults.js.map +1 -1
- package/dist/automations/notifications/processor.js +1 -1
- package/dist/automations/notifications/processor.js.map +1 -1
- package/dist/automations/notifications/rules/content.js +60 -3
- package/dist/automations/notifications/rules/content.js.map +1 -1
- package/dist/automations/notifications/rules/discussion.js +29 -29
- package/dist/automations/notifications/rules/discussion.js.map +1 -1
- package/dist/automations/notifications/rules/entitlements.js +36 -9
- package/dist/automations/notifications/rules/entitlements.js.map +1 -1
- package/dist/automations/notifications/rules/events.d.ts +9 -0
- package/dist/automations/notifications/rules/events.js +27 -0
- package/dist/automations/notifications/rules/events.js.map +1 -0
- package/dist/automations/notifications/rules/organizations.js +17 -10
- package/dist/automations/notifications/rules/organizations.js.map +1 -1
- package/dist/automations/notifications/rules/recipients.js +0 -1
- package/dist/automations/notifications/rules/recipients.js.map +1 -1
- package/dist/automations/notifications/service.d.ts +8 -6
- package/dist/automations/notifications/service.js +12 -12
- package/dist/automations/notifications/service.js.map +1 -1
- package/dist/automations/notifications/types.js +94 -7
- package/dist/automations/notifications/types.js.map +1 -1
- package/dist/automations/ports.d.ts +30 -31
- package/dist/automations/service.d.ts +20 -17
- package/dist/automations/service.js +90 -61
- package/dist/automations/service.js.map +1 -1
- package/dist/content/event-sight.d.ts +11 -0
- package/dist/content/event-sight.js +11 -0
- package/dist/content/event-sight.js.map +1 -0
- package/dist/content/events.d.ts +465 -88
- package/dist/content/events.js +34 -1
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +6 -4
- package/dist/content/index.js +3 -1
- package/dist/content/jobs.d.ts +16 -0
- package/dist/content/jobs.js +37 -0
- package/dist/content/jobs.js.map +1 -0
- package/dist/content/model.d.ts +2 -2
- package/dist/content/notification-categories.d.ts +5 -4
- package/dist/content/notification-categories.js +15 -6
- package/dist/content/notification-categories.js.map +1 -1
- package/dist/content/ports.d.ts +113 -68
- package/dist/content/service.d.ts +103 -67
- package/dist/content/service.js +739 -152
- package/dist/content/service.js.map +1 -1
- package/dist/content/titles.d.ts +6 -3
- package/dist/content/titles.js +37 -24
- package/dist/content/titles.js.map +1 -1
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +4 -2
- package/dist/discussion/authors.js +9 -5
- package/dist/discussion/authors.js.map +1 -1
- package/dist/discussion/chats.d.ts +56 -37
- package/dist/discussion/chats.js +392 -160
- package/dist/discussion/chats.js.map +1 -1
- package/dist/discussion/events.d.ts +85 -47
- package/dist/discussion/events.js +41 -3
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +8 -5
- package/dist/discussion/index.js +5 -3
- package/dist/discussion/live.d.ts +106 -0
- package/dist/discussion/live.js +642 -0
- package/dist/discussion/live.js.map +1 -0
- package/dist/discussion/mentions.js +2 -2
- package/dist/discussion/mentions.js.map +1 -1
- package/dist/discussion/ports.d.ts +182 -100
- package/dist/discussion/ports.js.map +1 -1
- package/dist/discussion/posts.d.ts +45 -39
- package/dist/discussion/posts.js +266 -152
- package/dist/discussion/posts.js.map +1 -1
- package/dist/discussion/rules.d.ts +18 -0
- package/dist/discussion/rules.js +22 -0
- package/dist/discussion/rules.js.map +1 -0
- package/dist/discussion/service.d.ts +37 -31
- package/dist/discussion/service.js +250 -186
- package/dist/discussion/service.js.map +1 -1
- package/dist/discussion/subscriptions.d.ts +8 -8
- package/dist/discussion/subscriptions.js +28 -12
- package/dist/discussion/subscriptions.js.map +1 -1
- package/dist/discussion/titles.d.ts +4 -2
- package/dist/discussion/titles.js +27 -13
- package/dist/discussion/titles.js.map +1 -1
- package/dist/entitlements/events.d.ts +58 -58
- package/dist/entitlements/index.d.ts +4 -4
- package/dist/entitlements/index.js +2 -2
- package/dist/entitlements/model.d.ts +2 -2
- package/dist/entitlements/ports.d.ts +65 -39
- package/dist/entitlements/rules.d.ts +3 -6
- package/dist/entitlements/rules.js +5 -10
- package/dist/entitlements/rules.js.map +1 -1
- package/dist/entitlements/service.d.ts +40 -28
- package/dist/entitlements/service.js +369 -162
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/devices.d.ts +3 -3
- package/dist/identity/devices.js +6 -4
- package/dist/identity/devices.js.map +1 -1
- package/dist/identity/index.d.ts +2 -2
- package/dist/identity/index.js +2 -2
- package/dist/identity/notification-settings.d.ts +1 -1
- package/dist/identity/notification-settings.js +2 -1
- package/dist/identity/notification-settings.js.map +1 -1
- package/dist/identity/ports.d.ts +7 -7
- package/dist/identity/service.d.ts +8 -7
- package/dist/identity/service.js +16 -12
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +3 -3
- package/dist/integrations/ports.d.ts +9 -8
- package/dist/integrations/service.d.ts +9 -8
- package/dist/integrations/service.js +31 -14
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/default-roles.d.ts +22 -0
- package/dist/organizations/default-roles.js +89 -0
- package/dist/organizations/default-roles.js.map +1 -0
- package/dist/organizations/effective-permissions.d.ts +47 -0
- package/dist/organizations/effective-permissions.js +118 -0
- package/dist/organizations/effective-permissions.js.map +1 -0
- package/dist/organizations/events.d.ts +326 -181
- package/dist/organizations/events.js +90 -18
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +14 -10
- package/dist/organizations/index.js +7 -3
- package/dist/organizations/members.d.ts +66 -8
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/model.d.ts +2 -2
- package/dist/organizations/notification-catalog.d.ts +31 -0
- package/dist/organizations/notification-catalog.js +32 -0
- package/dist/organizations/notification-catalog.js.map +1 -0
- package/dist/organizations/notification-categories.d.ts +6 -4
- package/dist/organizations/notification-categories.js +25 -10
- package/dist/organizations/notification-categories.js.map +1 -1
- package/dist/organizations/org-roles.d.ts +33 -0
- package/dist/organizations/org-roles.js +49 -0
- package/dist/organizations/org-roles.js.map +1 -0
- package/dist/organizations/permissions.d.ts +311 -0
- package/dist/organizations/permissions.js +327 -0
- package/dist/organizations/permissions.js.map +1 -0
- package/dist/organizations/ports.d.ts +187 -65
- package/dist/organizations/service.d.ts +102 -35
- package/dist/organizations/service.js +1254 -327
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/testing.d.ts +18 -0
- package/dist/organizations/testing.js +37 -0
- package/dist/organizations/testing.js.map +1 -0
- package/dist/organizations/types.d.ts +5 -16
- package/dist/progress/events.d.ts +14 -14
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +11 -3
- package/dist/progress/service.d.ts +6 -5
- package/dist/progress/service.js +21 -6
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +6 -4
- package/dist/reporting/admin/model.d.ts +36 -3
- package/dist/reporting/admin/ports.d.ts +39 -14
- package/dist/reporting/admin/service.d.ts +32 -11
- package/dist/reporting/admin/service.js +102 -18
- package/dist/reporting/admin/service.js.map +1 -1
- package/dist/reporting/events/index.d.ts +27 -0
- package/dist/reporting/events/index.js +20 -0
- package/dist/reporting/events/index.js.map +1 -0
- package/dist/reporting/member/calendar.d.ts +11 -0
- package/dist/reporting/member/calendar.js +75 -0
- package/dist/reporting/member/calendar.js.map +1 -0
- package/dist/reporting/member/index.d.ts +3 -2
- package/dist/reporting/member/model.d.ts +29 -5
- package/dist/reporting/member/ports.d.ts +49 -29
- package/dist/reporting/member/service.d.ts +57 -29
- package/dist/reporting/member/service.js +345 -114
- package/dist/reporting/member/service.js.map +1 -1
- package/dist/shared/actor.d.ts +23 -3
- package/dist/shared/errors.d.ts +2 -1
- package/dist/shared/errors.js +3 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/id.d.ts +4 -0
- package/dist/shared/id.js +4 -0
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/logger.d.ts +2 -1
- package/dist/shared/logger.js +10 -1
- package/dist/shared/logger.js.map +1 -1
- package/dist/shared/ports.d.ts +25 -5
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +4 -5
- package/dist/types/email-templates.d.ts +22 -3
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/identity.d.ts +13 -16
- package/dist/types/index.d.ts +9 -9
- package/dist/types/index.js +2 -1
- package/dist/types/notifications.d.ts +4 -4
- package/dist/types/organizations.d.ts +3 -2
- package/dist/types/ports.d.ts +8 -1
- package/dist/types/ports.js +7 -1
- package/dist/types/ports.js.map +1 -0
- package/dist/types/schemas/assets.d.ts +5 -5
- package/dist/types/schemas/assets.js +4 -3
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/content.d.ts +599 -13
- package/dist/types/schemas/content.js +219 -8
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +280 -57
- package/dist/types/schemas/discussion.js +77 -3
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +21 -8
- package/dist/types/schemas/entitlements.js +11 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/index.d.ts +5 -5
- package/dist/types/schemas/index.js +5 -5
- package/dist/types/schemas/notifications.d.ts +11 -10
- package/dist/types/schemas/notifications.js +3 -2
- package/dist/types/schemas/notifications.js.map +1 -1
- package/dist/types/schemas/organizations.d.ts +99 -60
- package/dist/types/schemas/organizations.js +80 -27
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +3 -4
- package/dist/types/schemas/progress.js +0 -1
- package/dist/types/schemas/progress.js.map +1 -1
- package/package.json +1 -1
- package/dist/organizations/access-scopes.d.ts +0 -19
- package/dist/organizations/access-scopes.js +0 -89
- package/dist/organizations/access-scopes.js.map +0 -1
- package/dist/organizations/roles.d.ts +0 -19
- package/dist/organizations/roles.js +0 -82
- package/dist/organizations/roles.js.map +0 -1
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { DomainEvent, Page } from "../types/shared.js";
|
|
2
|
+
import { Event } from "../types/schemas/content.js";
|
|
2
3
|
import { Automation, AutomationKind, AutomationRun, AutomationRunsQuery, AutomationsQuery, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
3
4
|
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
4
5
|
import { Delivery, NotificationCategory, NotificationFilter, RecipientList, StoredNotification, SubjectRef } from "../types/notifications.js";
|
|
5
6
|
import "../types/index.js";
|
|
7
|
+
import { Actor } from "../shared/actor.js";
|
|
6
8
|
import { CredentialStore, OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
7
9
|
import "./model.js";
|
|
10
|
+
import "../content/index.js";
|
|
8
11
|
import "./types.js";
|
|
12
|
+
import { MemberActor } from "../identity/ports.js";
|
|
13
|
+
import "../identity/index.js";
|
|
9
14
|
import { CommunityMailReads } from "./community-mail.js";
|
|
10
15
|
//#region src/automations/ports.d.ts
|
|
11
16
|
type NewAutomation = CreateAutomationInput & {
|
|
@@ -19,7 +24,9 @@ interface NotificationReads extends Omit<CommunityMailReads, 'recentMessageRecip
|
|
|
19
24
|
mutedAmong(orgId: string, item: SubjectRef, orgUserIds: string[], at: Date): Promise<string[]>;
|
|
20
25
|
communityMembers(orgId: string, communityId: string): Promise<string[]>;
|
|
21
26
|
switchedOn(orgId: string, communityId: string, category: string, spaceId: string | null): Promise<string[]>;
|
|
22
|
-
|
|
27
|
+
courseMembers(orgId: string, courseId: string): Promise<string[]>;
|
|
28
|
+
event(orgId: string, eventId: string): Promise<Event | null>;
|
|
29
|
+
eventAttendees(orgId: string, eventId: string): Promise<string[]>;
|
|
23
30
|
contentLostBy(orgId: string, grant: {
|
|
24
31
|
orgUserId: string;
|
|
25
32
|
contentId: string | null;
|
|
@@ -33,14 +40,6 @@ interface NotificationReads extends Omit<CommunityMailReads, 'recentMessageRecip
|
|
|
33
40
|
} | null>;
|
|
34
41
|
userIdsOf(orgId: string, orgUserIds: string[]): Promise<Record<string, string>>;
|
|
35
42
|
emailOf(orgId: string, userId: string): Promise<string | null>;
|
|
36
|
-
contentInfo(orgId: string, item: {
|
|
37
|
-
contentId: string;
|
|
38
|
-
} | {
|
|
39
|
-
bundleId: string;
|
|
40
|
-
}): Promise<{
|
|
41
|
-
title: string;
|
|
42
|
-
type: string;
|
|
43
|
-
} | null>;
|
|
44
43
|
message(orgId: string, messageId: string): Promise<{
|
|
45
44
|
orgUserId: string;
|
|
46
45
|
chatId: string;
|
|
@@ -93,14 +92,14 @@ interface UnreadCounts {
|
|
|
93
92
|
}[];
|
|
94
93
|
}
|
|
95
94
|
interface NotificationsService {
|
|
96
|
-
list(
|
|
95
|
+
list(filter: NotificationFilter, page: {
|
|
97
96
|
page: number;
|
|
98
97
|
pageSize: number;
|
|
99
|
-
}): Promise<NotificationPage>;
|
|
100
|
-
get(
|
|
101
|
-
unreadCounts(
|
|
102
|
-
markRead(
|
|
103
|
-
markAllRead(
|
|
98
|
+
}, actor: MemberActor): Promise<NotificationPage>;
|
|
99
|
+
get(notificationId: string, actor: MemberActor): Promise<ListedNotification | null>;
|
|
100
|
+
unreadCounts(communityIds: string[], actor: MemberActor): Promise<UnreadCounts>;
|
|
101
|
+
markRead(notificationId: string, actor: MemberActor): Promise<void>;
|
|
102
|
+
markAllRead(filter: NotificationFilter, actor: MemberActor): Promise<{
|
|
104
103
|
marked: number;
|
|
105
104
|
}>;
|
|
106
105
|
}
|
|
@@ -131,23 +130,23 @@ interface AutomationsService {
|
|
|
131
130
|
/** Dispatches a run per enabled automation the event matches, then runs the notification process; throws only when the notification process fails, so the outbox redelivers. */
|
|
132
131
|
handle(event: DomainEvent): Promise<void>;
|
|
133
132
|
/** Built-in action types plus every loaded integration's declared actions. */
|
|
134
|
-
availableActions(): AvailableActions;
|
|
133
|
+
availableActions(actor: Actor): AvailableActions;
|
|
135
134
|
/** The domain event types an automation may react to. */
|
|
136
|
-
availableTriggers(): AvailableTriggers;
|
|
137
|
-
list(
|
|
138
|
-
get(
|
|
139
|
-
create(
|
|
140
|
-
update(
|
|
141
|
-
delete(
|
|
142
|
-
listRuns(
|
|
143
|
-
rerun(
|
|
144
|
-
listWebhooks(
|
|
145
|
-
getWebhook(
|
|
146
|
-
createWebhook(
|
|
147
|
-
updateWebhook(
|
|
148
|
-
deleteWebhook(
|
|
149
|
-
revealWebhookSecret(
|
|
150
|
-
rotateWebhookSecret(
|
|
135
|
+
availableTriggers(actor: Actor): AvailableTriggers;
|
|
136
|
+
list(query: AutomationsQuery | undefined, actor: Actor): Promise<Automation[]>;
|
|
137
|
+
get(id: string, actor: Actor): Promise<Automation>;
|
|
138
|
+
create(input: CreateAutomationInput, actor: Actor): Promise<Automation>;
|
|
139
|
+
update(id: string, input: UpdateAutomationInput, actor: Actor): Promise<Automation>;
|
|
140
|
+
delete(id: string, actor: Actor): Promise<void>;
|
|
141
|
+
listRuns(automationId: string, query: AutomationRunsQuery, actor: Actor): Promise<Page<AutomationRun>>;
|
|
142
|
+
rerun(automationId: string, runId: string, actor: Actor): Promise<AutomationRun>;
|
|
143
|
+
listWebhooks(actor: Actor): Promise<Webhook[]>;
|
|
144
|
+
getWebhook(id: string, actor: Actor): Promise<Webhook>;
|
|
145
|
+
createWebhook(input: CreateWebhookInput, actor: Actor): Promise<CreatedWebhook>;
|
|
146
|
+
updateWebhook(id: string, input: UpdateWebhookInput, actor: Actor): Promise<Webhook>;
|
|
147
|
+
deleteWebhook(id: string, actor: Actor): Promise<void>;
|
|
148
|
+
revealWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret>;
|
|
149
|
+
rotateWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret>;
|
|
151
150
|
}
|
|
152
151
|
interface AutomationsRepository {
|
|
153
152
|
insert(orgId: string, input: NewAutomation): Promise<Automation>;
|
|
@@ -3,6 +3,7 @@ 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
4
|
import { AutomationDispatch, AutomationEngine, AutomationExecutor, DeliveryDispatch, ScheduledAutomation, WebhookSender } from "../types/automations.js";
|
|
5
5
|
import "../types/index.js";
|
|
6
|
+
import { Actor } from "../shared/actor.js";
|
|
6
7
|
import { CredentialStore } from "../shared/ports.js";
|
|
7
8
|
import "./model.js";
|
|
8
9
|
import { Mailer, MailerLookups } from "../shared/mailer.js";
|
|
@@ -24,6 +25,7 @@ type AutomationsServiceParams = {
|
|
|
24
25
|
mailer: Pick<Mailer, 'send'>;
|
|
25
26
|
lookups: MailerLookups;
|
|
26
27
|
integrations: Pick<IntegrationsService, 'available'>;
|
|
28
|
+
systemActor: (orgId: string) => Actor;
|
|
27
29
|
credentials: CredentialStore;
|
|
28
30
|
webhooks: WebhookSender;
|
|
29
31
|
mail: Omit<CommunityMailReads, 'recentMessageRecipients'>;
|
|
@@ -40,6 +42,7 @@ declare class AutomationsServiceImpl implements AutomationsService, AutomationEx
|
|
|
40
42
|
private readonly mailer;
|
|
41
43
|
private readonly lookups;
|
|
42
44
|
private readonly integrations;
|
|
45
|
+
private readonly systemActor;
|
|
43
46
|
private readonly credentials;
|
|
44
47
|
private readonly webhooks;
|
|
45
48
|
private readonly mail;
|
|
@@ -62,23 +65,23 @@ declare class AutomationsServiceImpl implements AutomationsService, AutomationEx
|
|
|
62
65
|
fireSchedule(orgId: string, automationId: string, at: Date): Promise<void>;
|
|
63
66
|
finalize(d: AutomationDispatch, results: AutomationActionResult[]): Promise<void>;
|
|
64
67
|
private logOutcome;
|
|
65
|
-
create(
|
|
66
|
-
update(
|
|
67
|
-
delete(
|
|
68
|
-
list(
|
|
69
|
-
get(
|
|
70
|
-
listRuns(
|
|
71
|
-
rerun(
|
|
72
|
-
listWebhooks(
|
|
73
|
-
getWebhook(
|
|
74
|
-
createWebhook(
|
|
75
|
-
updateWebhook(
|
|
76
|
-
deleteWebhook(
|
|
77
|
-
revealWebhookSecret(
|
|
78
|
-
rotateWebhookSecret(
|
|
79
|
-
private
|
|
80
|
-
availableActions(): AvailableActions;
|
|
81
|
-
availableTriggers(): AvailableTriggers;
|
|
68
|
+
create(input: CreateAutomationInput, actor: Actor): Promise<Automation>;
|
|
69
|
+
update(id: string, input: UpdateAutomationInput, actor: Actor): Promise<Automation>;
|
|
70
|
+
delete(id: string, actor: Actor): Promise<void>;
|
|
71
|
+
list(query: AutomationsQuery | undefined, actor: Actor): Promise<Automation[]>;
|
|
72
|
+
get(id: string, actor: Actor): Promise<Automation>;
|
|
73
|
+
listRuns(automationId: string, query: AutomationRunsQuery, actor: Actor): Promise<Page<AutomationRun>>;
|
|
74
|
+
rerun(automationId: string, runId: string, actor: Actor): Promise<AutomationRun>;
|
|
75
|
+
listWebhooks(actor: Actor): Promise<Webhook[]>;
|
|
76
|
+
getWebhook(id: string, actor: Actor): Promise<Webhook>;
|
|
77
|
+
createWebhook(input: CreateWebhookInput, actor: Actor): Promise<CreatedWebhook>;
|
|
78
|
+
updateWebhook(id: string, input: UpdateWebhookInput, actor: Actor): Promise<Webhook>;
|
|
79
|
+
deleteWebhook(id: string, actor: Actor): Promise<void>;
|
|
80
|
+
revealWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret>;
|
|
81
|
+
rotateWebhookSecret(id: string, actor: Actor): Promise<WebhookSecret>;
|
|
82
|
+
private requireWebhook;
|
|
83
|
+
availableActions(actor: Actor): AvailableActions;
|
|
84
|
+
availableTriggers(actor: Actor): AvailableTriggers;
|
|
82
85
|
}
|
|
83
86
|
//#endregion
|
|
84
87
|
export { AutomationsServiceImpl, AutomationsServiceParams };
|
|
@@ -5,6 +5,7 @@ import { ActionFailedError, AutomationKindMismatchError, InvalidTriggerError, Re
|
|
|
5
5
|
import { DELIVER_WEBHOOK_ACTION, catalogActions, catalogTriggers, publicDataSchema } from "./catalog.js";
|
|
6
6
|
import { generateWebhookSecret } from "./webhook-signing.js";
|
|
7
7
|
import { executeAction } from "./actions.js";
|
|
8
|
+
import { assertGrantsAllowed, assertReadsEvents } from "./event-permissions.js";
|
|
8
9
|
import { automationEvents } from "./events.js";
|
|
9
10
|
import { cronSupported } from "./schedule.js";
|
|
10
11
|
//#region src/automations/service.ts
|
|
@@ -128,6 +129,7 @@ var AutomationsServiceImpl = class {
|
|
|
128
129
|
mailer;
|
|
129
130
|
lookups;
|
|
130
131
|
integrations;
|
|
132
|
+
systemActor;
|
|
131
133
|
credentials;
|
|
132
134
|
webhooks;
|
|
133
135
|
mail;
|
|
@@ -143,6 +145,7 @@ var AutomationsServiceImpl = class {
|
|
|
143
145
|
this.mailer = params.mailer;
|
|
144
146
|
this.lookups = params.lookups;
|
|
145
147
|
this.integrations = params.integrations;
|
|
148
|
+
this.systemActor = params.systemActor;
|
|
146
149
|
this.credentials = params.credentials;
|
|
147
150
|
this.webhooks = params.webhooks;
|
|
148
151
|
this.mail = {
|
|
@@ -396,9 +399,12 @@ var AutomationsServiceImpl = class {
|
|
|
396
399
|
}))
|
|
397
400
|
});
|
|
398
401
|
}
|
|
399
|
-
async create(
|
|
402
|
+
async create(input, actor) {
|
|
403
|
+
actor.permissions.require("automations:write");
|
|
404
|
+
const orgId = actor.orgId;
|
|
400
405
|
assertCatalogTriggers(input.triggers, true);
|
|
401
406
|
assertAuthorableActions(input.actions);
|
|
407
|
+
assertGrantsAllowed(actor, input.actions);
|
|
402
408
|
const automation = await this.uow.run(async ({ automations, outbox }) => {
|
|
403
409
|
const created = await automations.insert(orgId, {
|
|
404
410
|
...input,
|
|
@@ -413,16 +419,22 @@ var AutomationsServiceImpl = class {
|
|
|
413
419
|
});
|
|
414
420
|
this.logger.info("automation created", {
|
|
415
421
|
orgId,
|
|
416
|
-
automationId: automation.id
|
|
422
|
+
automationId: automation.id,
|
|
423
|
+
actorId: actor.id
|
|
417
424
|
});
|
|
418
425
|
await this.reconcileSchedules(orgId);
|
|
419
426
|
return automation;
|
|
420
427
|
}
|
|
421
|
-
async update(
|
|
428
|
+
async update(id, input, actor) {
|
|
429
|
+
actor.permissions.require("automations:write");
|
|
430
|
+
const orgId = actor.orgId;
|
|
422
431
|
if (input.triggers !== void 0) assertCatalogTriggers(input.triggers, true);
|
|
423
|
-
if (input.actions !== void 0)
|
|
432
|
+
if (input.actions !== void 0) {
|
|
433
|
+
assertAuthorableActions(input.actions);
|
|
434
|
+
assertGrantsAllowed(actor, input.actions);
|
|
435
|
+
}
|
|
424
436
|
const existing = await this.repo.findById(orgId, id);
|
|
425
|
-
if (!existing)
|
|
437
|
+
if (!existing) throw new NotFoundError("Automation", id);
|
|
426
438
|
if (existing.kind !== "workflow") throw new AutomationKindMismatchError(id, existing.kind);
|
|
427
439
|
const patch = input.triggers === void 0 ? input : {
|
|
428
440
|
...input,
|
|
@@ -434,20 +446,21 @@ var AutomationsServiceImpl = class {
|
|
|
434
446
|
await outbox.append([updateEvent(orgId, input, updated)]);
|
|
435
447
|
return updated;
|
|
436
448
|
});
|
|
437
|
-
if (automation)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
449
|
+
if (!automation) throw new NotFoundError("Automation", id);
|
|
450
|
+
this.logger.info("automation updated", {
|
|
451
|
+
orgId,
|
|
452
|
+
automationId: id
|
|
453
|
+
});
|
|
454
|
+
await this.reconcileSchedules(orgId);
|
|
444
455
|
return automation;
|
|
445
456
|
}
|
|
446
|
-
async delete(
|
|
457
|
+
async delete(id, actor) {
|
|
458
|
+
actor.permissions.require("automations:delete");
|
|
459
|
+
const orgId = actor.orgId;
|
|
447
460
|
const existing = await this.repo.findById(orgId, id);
|
|
448
|
-
if (!existing)
|
|
461
|
+
if (!existing) throw new NotFoundError("Automation", id);
|
|
449
462
|
if (existing.kind !== "workflow") throw new AutomationKindMismatchError(id, existing.kind);
|
|
450
|
-
|
|
463
|
+
if (!await this.uow.run(async ({ automations, outbox }) => {
|
|
451
464
|
const removed = await automations.delete(orgId, id);
|
|
452
465
|
if (!removed) return null;
|
|
453
466
|
await outbox.append([automationEvents.automationDeleted.make({
|
|
@@ -455,35 +468,39 @@ var AutomationsServiceImpl = class {
|
|
|
455
468
|
data: removed
|
|
456
469
|
})]);
|
|
457
470
|
return removed;
|
|
471
|
+
})) throw new NotFoundError("Automation", id);
|
|
472
|
+
this.logger.info("automation deleted", {
|
|
473
|
+
orgId,
|
|
474
|
+
automationId: id
|
|
458
475
|
});
|
|
459
|
-
|
|
460
|
-
this.logger.info("automation deleted", {
|
|
461
|
-
orgId,
|
|
462
|
-
automationId: id
|
|
463
|
-
});
|
|
464
|
-
await this.reconcileSchedules(orgId);
|
|
465
|
-
}
|
|
466
|
-
return deleted !== null;
|
|
476
|
+
await this.reconcileSchedules(orgId);
|
|
467
477
|
}
|
|
468
|
-
async list(
|
|
469
|
-
|
|
478
|
+
async list(query, actor) {
|
|
479
|
+
actor.permissions.require("automations:read");
|
|
480
|
+
return (await this.repo.listByOrg(actor.orgId, query?.kind)).map(toAutomationView);
|
|
470
481
|
}
|
|
471
|
-
async get(
|
|
472
|
-
|
|
473
|
-
|
|
482
|
+
async get(id, actor) {
|
|
483
|
+
actor.permissions.require("automations:read");
|
|
484
|
+
const automation = await this.repo.findById(actor.orgId, id);
|
|
485
|
+
if (!automation) throw new NotFoundError("Automation", id);
|
|
486
|
+
return toAutomationView(automation);
|
|
474
487
|
}
|
|
475
|
-
async listRuns(
|
|
476
|
-
|
|
488
|
+
async listRuns(automationId, query, actor) {
|
|
489
|
+
actor.permissions.require("automations:read");
|
|
490
|
+
const page = await this.runsRepo.list(actor.orgId, automationId, query);
|
|
477
491
|
return {
|
|
478
492
|
...page,
|
|
479
493
|
rows: page.rows.map(toRunView)
|
|
480
494
|
};
|
|
481
495
|
}
|
|
482
|
-
async rerun(
|
|
496
|
+
async rerun(automationId, runId, actor) {
|
|
497
|
+
actor.permissions.require("automations:write");
|
|
498
|
+
const orgId = actor.orgId;
|
|
483
499
|
const existing = await this.runsRepo.findById(orgId, runId);
|
|
484
500
|
if (!existing || existing.automationId !== automationId) throw new NotFoundError("Automation run", runId);
|
|
485
501
|
const automation = await this.repo.findById(orgId, automationId);
|
|
486
502
|
if (!automation) throw new NotFoundError("Automation", automationId);
|
|
503
|
+
assertGrantsAllowed(actor, automation.actions);
|
|
487
504
|
const run = await this.uow.run(async ({ runs, outbox }) => {
|
|
488
505
|
const restarted = await runs.restart(orgId, runId, /* @__PURE__ */ new Date());
|
|
489
506
|
if (!restarted) return null;
|
|
@@ -513,16 +530,20 @@ var AutomationsServiceImpl = class {
|
|
|
513
530
|
});
|
|
514
531
|
return toRunView(run);
|
|
515
532
|
}
|
|
516
|
-
async listWebhooks(
|
|
517
|
-
|
|
533
|
+
async listWebhooks(actor) {
|
|
534
|
+
actor.permissions.require("automations:read");
|
|
535
|
+
return (await this.repo.listByOrg(actor.orgId, "webhook")).map(toWebhook);
|
|
518
536
|
}
|
|
519
|
-
async getWebhook(
|
|
520
|
-
|
|
521
|
-
return
|
|
537
|
+
async getWebhook(id, actor) {
|
|
538
|
+
actor.permissions.require("automations:read");
|
|
539
|
+
return toWebhook(await this.requireWebhook(actor.orgId, id));
|
|
522
540
|
}
|
|
523
|
-
async createWebhook(
|
|
541
|
+
async createWebhook(input, actor) {
|
|
542
|
+
actor.permissions.require("automations:write");
|
|
543
|
+
const orgId = actor.orgId;
|
|
524
544
|
const events = unique(input.events);
|
|
525
545
|
assertCatalogTriggers(events, false);
|
|
546
|
+
assertReadsEvents(actor, events);
|
|
526
547
|
const secret = generateWebhookSecret();
|
|
527
548
|
const automation = await this.uow.run(async ({ automations, credentials, outbox }) => {
|
|
528
549
|
const secretRef = await credentials.store(orgId, { secret });
|
|
@@ -554,11 +575,15 @@ var AutomationsServiceImpl = class {
|
|
|
554
575
|
secret
|
|
555
576
|
};
|
|
556
577
|
}
|
|
557
|
-
async updateWebhook(
|
|
558
|
-
|
|
559
|
-
|
|
578
|
+
async updateWebhook(id, input, actor) {
|
|
579
|
+
actor.permissions.require("automations:write");
|
|
580
|
+
const orgId = actor.orgId;
|
|
581
|
+
const existing = await this.requireWebhook(orgId, id);
|
|
560
582
|
const events = input.events === void 0 ? void 0 : unique(input.events);
|
|
561
|
-
if (events)
|
|
583
|
+
if (events) {
|
|
584
|
+
assertCatalogTriggers(events, false);
|
|
585
|
+
assertReadsEvents(actor, events);
|
|
586
|
+
}
|
|
562
587
|
const { secretRef } = webhookTarget(existing);
|
|
563
588
|
const patch = {
|
|
564
589
|
name: input.url,
|
|
@@ -579,18 +604,18 @@ var AutomationsServiceImpl = class {
|
|
|
579
604
|
await outbox.append([updateEvent(orgId, input, row)]);
|
|
580
605
|
return row;
|
|
581
606
|
});
|
|
582
|
-
if (!updated)
|
|
607
|
+
if (!updated) throw new NotFoundError("Webhook", id);
|
|
583
608
|
this.logger.info("webhook updated", {
|
|
584
609
|
orgId,
|
|
585
610
|
automationId: id
|
|
586
611
|
});
|
|
587
612
|
return toWebhook(updated);
|
|
588
613
|
}
|
|
589
|
-
async deleteWebhook(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const { secretRef } = webhookTarget(
|
|
593
|
-
|
|
614
|
+
async deleteWebhook(id, actor) {
|
|
615
|
+
actor.permissions.require("automations:delete");
|
|
616
|
+
const orgId = actor.orgId;
|
|
617
|
+
const { secretRef } = webhookTarget(await this.requireWebhook(orgId, id));
|
|
618
|
+
if (!await this.uow.run(async ({ automations, credentials, outbox }) => {
|
|
594
619
|
const removed = await automations.delete(orgId, id);
|
|
595
620
|
if (!removed) return null;
|
|
596
621
|
await credentials.destroy(orgId, secretRef);
|
|
@@ -599,23 +624,24 @@ var AutomationsServiceImpl = class {
|
|
|
599
624
|
data: removed
|
|
600
625
|
})]);
|
|
601
626
|
return removed;
|
|
602
|
-
});
|
|
603
|
-
|
|
627
|
+
})) throw new NotFoundError("Webhook", id);
|
|
628
|
+
this.logger.info("webhook deleted", {
|
|
604
629
|
orgId,
|
|
605
630
|
automationId: id
|
|
606
631
|
});
|
|
607
|
-
return deleted !== null;
|
|
608
632
|
}
|
|
609
|
-
async revealWebhookSecret(
|
|
610
|
-
|
|
611
|
-
|
|
633
|
+
async revealWebhookSecret(id, actor) {
|
|
634
|
+
actor.permissions.require("automations:write");
|
|
635
|
+
const orgId = actor.orgId;
|
|
636
|
+
const existing = await this.requireWebhook(orgId, id);
|
|
612
637
|
const secret = (await this.credentials.reveal(orgId, webhookTarget(existing).secretRef))?.["secret"];
|
|
613
638
|
if (typeof secret !== "string") throw new Error(`webhook ${id}: signing secret is missing`);
|
|
614
639
|
return { secret };
|
|
615
640
|
}
|
|
616
|
-
async rotateWebhookSecret(
|
|
617
|
-
|
|
618
|
-
|
|
641
|
+
async rotateWebhookSecret(id, actor) {
|
|
642
|
+
actor.permissions.require("automations:write");
|
|
643
|
+
const orgId = actor.orgId;
|
|
644
|
+
const existing = await this.requireWebhook(orgId, id);
|
|
619
645
|
const secret = generateWebhookSecret();
|
|
620
646
|
await this.credentials.update(orgId, webhookTarget(existing).secretRef, { secret });
|
|
621
647
|
this.logger.info("webhook secret rotated", {
|
|
@@ -624,19 +650,22 @@ var AutomationsServiceImpl = class {
|
|
|
624
650
|
});
|
|
625
651
|
return { secret };
|
|
626
652
|
}
|
|
627
|
-
async
|
|
653
|
+
async requireWebhook(orgId, id) {
|
|
628
654
|
const automation = await this.repo.findById(orgId, id);
|
|
629
|
-
|
|
655
|
+
if (automation?.kind !== "webhook") throw new NotFoundError("Webhook", id);
|
|
656
|
+
return automation;
|
|
630
657
|
}
|
|
631
|
-
availableActions() {
|
|
632
|
-
|
|
658
|
+
availableActions(actor) {
|
|
659
|
+
actor.permissions.require("automations:read");
|
|
660
|
+
return [...catalogActions(), ...this.integrations.available(this.systemActor(actor.orgId)).flatMap((integration) => integration.actions.map((action) => ({
|
|
633
661
|
type: `${integration.id}.${action.id}`,
|
|
634
662
|
description: action.description,
|
|
635
663
|
inputSchema: action.inputSchema,
|
|
636
664
|
source: integration.id
|
|
637
665
|
})))];
|
|
638
666
|
}
|
|
639
|
-
availableTriggers() {
|
|
667
|
+
availableTriggers(actor) {
|
|
668
|
+
actor.permissions.require("automations:read");
|
|
640
669
|
return { triggers: catalogTriggers() };
|
|
641
670
|
}
|
|
642
671
|
};
|