@headless-lms/core 0.1.0 → 0.3.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 +90 -9
- package/dist/assets/events.js +19 -3
- package/dist/assets/events.js.map +1 -1
- package/dist/assets/file-urls.d.ts +20 -0
- package/dist/assets/file-urls.js +25 -0
- package/dist/assets/file-urls.js.map +1 -0
- package/dist/assets/index.d.ts +5 -4
- package/dist/assets/index.js +3 -2
- package/dist/assets/model.d.ts +2 -2
- package/dist/assets/ports.d.ts +45 -15
- package/dist/assets/service.d.ts +39 -7
- package/dist/assets/service.js +292 -37
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.d.ts +12 -15
- package/dist/automations/actions.js +188 -30
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.d.ts +5 -1
- package/dist/automations/catalog.js +514 -197
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.d.ts +14 -0
- package/dist/automations/community-derivations.js +439 -0
- package/dist/automations/community-derivations.js.map +1 -0
- package/dist/automations/community-mail.d.ts +112 -0
- package/dist/automations/community-mail.js +90 -0
- package/dist/automations/community-mail.js.map +1 -0
- package/dist/automations/community-notifications.d.ts +16 -0
- package/dist/automations/community-notifications.js +84 -0
- package/dist/automations/community-notifications.js.map +1 -0
- package/dist/automations/events.d.ts +74 -24
- package/dist/automations/events.js +5 -5
- package/dist/automations/events.js.map +1 -1
- package/dist/automations/index.d.ts +7 -5
- package/dist/automations/index.js +3 -2
- package/dist/automations/model.d.ts +20 -3
- package/dist/automations/model.js +36 -3
- package/dist/automations/model.js.map +1 -1
- package/dist/automations/ports.d.ts +27 -8
- package/dist/automations/schedule.d.ts +6 -0
- package/dist/automations/schedule.js +41 -0
- package/dist/automations/schedule.js.map +1 -0
- package/dist/automations/seeds.d.ts +17 -0
- package/dist/automations/seeds.js +235 -0
- package/dist/automations/seeds.js.map +1 -0
- package/dist/automations/service.d.ts +41 -6
- package/dist/automations/service.js +542 -59
- package/dist/automations/service.js.map +1 -1
- package/dist/automations/types.d.ts +2 -2
- package/dist/automations/webhook-signing.d.ts +7 -0
- package/dist/automations/webhook-signing.js +22 -0
- package/dist/automations/webhook-signing.js.map +1 -0
- package/dist/content/events.d.ts +1013 -25
- package/dist/content/events.js +168 -19
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +5 -5
- package/dist/content/index.js +2 -2
- package/dist/content/model.d.ts +2 -2
- package/dist/content/ports.d.ts +109 -25
- package/dist/content/service.d.ts +68 -23
- package/dist/content/service.js +647 -60
- package/dist/content/service.js.map +1 -1
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +10 -0
- package/dist/discussion/authors.js +23 -0
- package/dist/discussion/authors.js.map +1 -0
- package/dist/discussion/chats.d.ts +104 -0
- package/dist/discussion/chats.js +798 -0
- package/dist/discussion/chats.js.map +1 -0
- package/dist/discussion/events.d.ts +633 -14
- package/dist/discussion/events.js +134 -5
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +7 -3
- package/dist/discussion/index.js +4 -1
- package/dist/discussion/model.d.ts +1 -2
- package/dist/discussion/ports.d.ts +288 -27
- package/dist/discussion/ports.js +6 -1
- package/dist/discussion/ports.js.map +1 -0
- package/dist/discussion/posts.d.ts +103 -0
- package/dist/discussion/posts.js +723 -0
- package/dist/discussion/posts.js.map +1 -0
- package/dist/discussion/service.d.ts +33 -11
- package/dist/discussion/service.js +297 -81
- package/dist/discussion/service.js.map +1 -1
- package/dist/entitlements/events.d.ts +264 -13
- package/dist/entitlements/events.js +49 -5
- package/dist/entitlements/events.js.map +1 -1
- package/dist/entitlements/index.d.ts +5 -4
- package/dist/entitlements/index.js +2 -1
- package/dist/entitlements/model.d.ts +3 -2
- package/dist/entitlements/ports.d.ts +124 -11
- package/dist/entitlements/rules.d.ts +12 -0
- package/dist/entitlements/rules.js +17 -0
- package/dist/entitlements/rules.js.map +1 -0
- package/dist/entitlements/service.d.ts +54 -3
- package/dist/entitlements/service.js +473 -2
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/access.d.ts +6 -0
- package/dist/identity/access.js +7 -0
- package/dist/identity/access.js.map +1 -0
- package/dist/identity/events.d.ts +17 -3
- package/dist/identity/events.js +12 -2
- package/dist/identity/events.js.map +1 -1
- package/dist/identity/index.d.ts +6 -4
- package/dist/identity/index.js +3 -1
- package/dist/identity/model.d.ts +2 -1
- package/dist/identity/notifications.d.ts +27 -0
- package/dist/identity/notifications.js +101 -0
- package/dist/identity/notifications.js.map +1 -0
- package/dist/identity/ports.d.ts +76 -3
- package/dist/identity/service.d.ts +17 -3
- package/dist/identity/service.js +73 -5
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +27 -3
- package/dist/integrations/events.js +15 -3
- package/dist/integrations/events.js.map +1 -1
- package/dist/integrations/model.js +1 -1
- package/dist/integrations/model.js.map +1 -1
- package/dist/integrations/service.js +2 -2
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/access-scopes.d.ts +19 -0
- package/dist/organizations/access-scopes.js +89 -0
- package/dist/organizations/access-scopes.js.map +1 -0
- package/dist/organizations/events.d.ts +234 -25
- package/dist/organizations/events.js +58 -9
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +8 -7
- package/dist/organizations/index.js +4 -3
- package/dist/organizations/members.d.ts +8 -5
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/ports.d.ts +20 -21
- package/dist/organizations/roles.d.ts +6 -10
- package/dist/organizations/roles.js +19 -7
- package/dist/organizations/roles.js.map +1 -1
- package/dist/organizations/service.d.ts +28 -14
- package/dist/organizations/service.js +274 -105
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +2 -11
- package/dist/progress/events.d.ts +34 -2
- package/dist/progress/events.js +15 -2
- package/dist/progress/events.js.map +1 -1
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +6 -1
- package/dist/progress/service.d.ts +5 -3
- package/dist/progress/service.js +9 -3
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +4 -0
- package/dist/reporting/admin/index.js +2 -0
- package/dist/reporting/admin/model.d.ts +108 -0
- package/dist/reporting/admin/ports.d.ts +27 -0
- package/dist/reporting/admin/service.d.ts +22 -0
- package/dist/reporting/admin/service.js +38 -0
- package/dist/reporting/admin/service.js.map +1 -0
- package/dist/reporting/member/index.d.ts +5 -0
- package/dist/reporting/member/index.js +2 -0
- package/dist/reporting/member/model.d.ts +124 -0
- package/dist/reporting/member/ports.d.ts +45 -0
- package/dist/reporting/member/service.d.ts +73 -0
- package/dist/reporting/member/service.js +286 -0
- package/dist/reporting/member/service.js.map +1 -0
- package/dist/shared/actor.d.ts +9 -0
- package/dist/shared/errors.d.ts +7 -1
- package/dist/shared/errors.js +10 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/events.d.ts +5 -3
- package/dist/shared/events.js +1 -0
- package/dist/shared/events.js.map +1 -1
- package/dist/shared/id.d.ts +12 -0
- package/dist/shared/id.js +13 -1
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/mailer.d.ts +6 -1
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/network.d.ts +10 -0
- package/dist/shared/network.js +211 -0
- package/dist/shared/network.js.map +1 -0
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/assets.d.ts +2 -2
- package/dist/types/automations.d.ts +21 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +12 -3
- package/dist/types/email-templates.d.ts +124 -1
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/events.d.ts +3 -3
- package/dist/types/identity.d.ts +48 -2
- package/dist/types/index.d.ts +10 -10
- package/dist/types/organizations.d.ts +2 -2
- package/dist/types/ports.d.ts +7 -1
- package/dist/types/schemas/assets.d.ts +67 -36
- package/dist/types/schemas/assets.js +19 -13
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +88 -4
- package/dist/types/schemas/automations.js +46 -6
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +385 -20
- package/dist/types/schemas/content.js +178 -15
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/credentials.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +379 -4
- package/dist/types/schemas/discussion.js +209 -7
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +44 -4
- package/dist/types/schemas/entitlements.js +32 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +115 -5
- package/dist/types/schemas/identity.js +59 -6
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +9 -9
- package/dist/types/schemas/index.js +9 -9
- package/dist/types/schemas/integrations.js.map +1 -1
- package/dist/types/schemas/organizations.d.ts +27 -5
- package/dist/types/schemas/organizations.js +14 -7
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/outbox.d.ts +1 -0
- package/dist/types/schemas/outbox.js +1 -0
- package/dist/types/schemas/outbox.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +1 -0
- package/dist/types/schemas/progress.js +1 -0
- package/dist/types/schemas/progress.js.map +1 -1
- package/dist/types/schemas/settings.js.map +1 -1
- package/dist/types/schemas/shared.d.ts +4 -1
- package/dist/types/schemas/shared.js +7 -1
- package/dist/types/schemas/shared.js.map +1 -1
- package/dist/types/shared.d.ts +1 -1
- package/package.json +2 -2
- package/dist/reporting/dashboard/index.d.ts +0 -4
- package/dist/reporting/dashboard/index.js +0 -2
- package/dist/reporting/dashboard/model.d.ts +0 -14
- package/dist/reporting/dashboard/ports.d.ts +0 -13
- package/dist/reporting/dashboard/service.d.ts +0 -19
- package/dist/reporting/dashboard/service.js +0 -20
- package/dist/reporting/dashboard/service.js.map +0 -1
- package/dist/reporting/learn/index.d.ts +0 -5
- package/dist/reporting/learn/index.js +0 -2
- package/dist/reporting/learn/model.d.ts +0 -23
- package/dist/reporting/learn/ports.d.ts +0 -42
- package/dist/reporting/learn/service.d.ts +0 -48
- package/dist/reporting/learn/service.js +0 -111
- package/dist/reporting/learn/service.js.map +0 -1
- package/dist/reporting/students/index.d.ts +0 -4
- package/dist/reporting/students/index.js +0 -2
- package/dist/reporting/students/model.d.ts +0 -31
- package/dist/reporting/students/ports.d.ts +0 -13
- package/dist/reporting/students/ports.js +0 -1
- package/dist/reporting/students/service.d.ts +0 -19
- package/dist/reporting/students/service.js +0 -20
- package/dist/reporting/students/service.js.map +0 -1
- /package/dist/reporting/{dashboard → admin}/model.js +0 -0
- /package/dist/reporting/{dashboard → admin}/ports.js +0 -0
- /package/dist/reporting/{learn → member}/model.js +0 -0
- /package/dist/reporting/{learn → member}/ports.js +0 -0
- /package/dist/{reporting/students/model.js → shared/actor.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","names":[],"sources":["../../src/automations/events.ts"],"sourcesContent":["import {\n automationActionResultSchema,\n automationRunSchema,\n automationSchema,\n} from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const automationEvents = {\n automationCreated: defineEvent({\n type: 'automation.created',\n version:
|
|
1
|
+
{"version":3,"file":"events.js","names":[],"sources":["../../src/automations/events.ts"],"sourcesContent":["import {\n automationActionResultSchema,\n automationRunSchema,\n automationSchema,\n} from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const automationEvents = {\n automationCreated: defineEvent({\n type: 'automation.created',\n version: 2,\n data: automationSchema,\n }),\n automationUpdated: defineEvent({\n type: 'automation.updated',\n version: 2,\n data: automationSchema,\n }),\n automationDeleted: defineEvent({\n type: 'automation.deleted',\n version: 2,\n data: automationSchema,\n }),\n automationEnabled: defineEvent({\n type: 'automation.enabled',\n version: 2,\n data: automationSchema,\n }),\n automationDisabled: defineEvent({\n type: 'automation.disabled',\n version: 2,\n data: automationSchema,\n }),\n runStarted: defineEvent({\n type: 'automation.run.started',\n version: 1,\n data: automationRunSchema,\n }),\n runCompleted: defineEvent({\n type: 'automation.run.completed',\n version: 1,\n data: automationRunSchema,\n }),\n runFailed: defineEvent({\n type: 'automation.run.failed',\n version: 1,\n data: automationRunSchema,\n }),\n actionFailed: defineEvent({\n type: 'automation.action.failed',\n version: 1,\n data: automationActionResultSchema,\n }),\n};\n\nexport type AutomationCreated = EventOf<typeof automationEvents.automationCreated>;\nexport type AutomationUpdated = EventOf<typeof automationEvents.automationUpdated>;\nexport type AutomationDeleted = EventOf<typeof automationEvents.automationDeleted>;\nexport type AutomationEnabled = EventOf<typeof automationEvents.automationEnabled>;\nexport type AutomationDisabled = EventOf<typeof automationEvents.automationDisabled>;\nexport type AutomationRunStarted = EventOf<typeof automationEvents.runStarted>;\nexport type AutomationRunCompleted = EventOf<typeof automationEvents.runCompleted>;\nexport type AutomationRunFailed = EventOf<typeof automationEvents.runFailed>;\nexport type AutomationActionFailed = EventOf<typeof automationEvents.actionFailed>;\nexport type AutomationEvent = EventOfValues<typeof automationEvents>;\n"],"mappings":";;;AAOA,MAAa,mBAAmB;CAC9B,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,oBAAoB,YAAY;EAC9B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,YAAY,YAAY;EACtB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,WAAW,YAAY;EACrB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;AACH"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Page } from "../types/shared.js";
|
|
2
|
-
import { Automation, AutomationAction, AutomationActionResult, AutomationRun, AutomationRunStatus, AutomationRunsQuery, AutomationTrigger, AvailableAction, AvailableActions, AvailableTriggers, CreateAutomationInput, UpdateAutomationInput } from "../types/schemas/automations.js";
|
|
3
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor } from "../types/automations.js";
|
|
4
|
-
import { InvalidTriggerError } from "./model.js";
|
|
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, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
4
|
+
import { ACTION_FAILED, ActionFailedError, AutomationKindMismatchError, InvalidTriggerError, ReservedActionError, actionFailureMessage } from "./model.js";
|
|
5
5
|
import "./types.js";
|
|
6
|
+
import { AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsUnitOfWork, NewAutomation, NewAutomationRun } from "./ports.js";
|
|
7
|
+
import { CommunityMailReads, GrantWriter, ScheduledWork } from "./community-mail.js";
|
|
6
8
|
import { AutomationActionFailed, AutomationCreated, AutomationDeleted, AutomationDisabled, AutomationEnabled, AutomationEvent, AutomationRunCompleted, AutomationRunFailed, AutomationRunStarted, AutomationUpdated, automationEvents } from "./events.js";
|
|
7
|
-
import { AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsUnitOfWork, NewAutomationRun } from "./ports.js";
|
|
8
9
|
import { AutomationsServiceImpl } from "./service.js";
|
|
9
|
-
|
|
10
|
+
import { cronMatches } from "./schedule.js";
|
|
11
|
+
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, type CommunityMailReads, type CreateAutomationInput, type CreateWebhookInput, type CreatedWebhook, type GrantWriter, InvalidTriggerError, type NewAutomation, type NewAutomationRun, type Page, ReservedActionError, type ScheduledWork, type UpdateAutomationInput, type UpdateWebhookInput, type Webhook, type WebhookRequest, type WebhookResponse, type WebhookSecret, type WebhookSender, actionFailureMessage, automationEvents, cronMatches };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import { ACTION_FAILED, ActionFailedError, AutomationKindMismatchError, InvalidTriggerError, ReservedActionError, actionFailureMessage } from "./model.js";
|
|
1
2
|
import { automationEvents } from "./events.js";
|
|
2
|
-
import {
|
|
3
|
+
import { cronMatches } from "./schedule.js";
|
|
3
4
|
import { AutomationsServiceImpl } from "./service.js";
|
|
4
|
-
export { AutomationsServiceImpl, InvalidTriggerError, automationEvents };
|
|
5
|
+
export { ACTION_FAILED, ActionFailedError, AutomationKindMismatchError, AutomationsServiceImpl, InvalidTriggerError, ReservedActionError, actionFailureMessage, automationEvents, cronMatches };
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import { Page } from "../types/shared.js";
|
|
2
|
-
import { Automation, AutomationAction, AutomationActionResult, AutomationRun, AutomationRunStatus, AutomationTrigger } from "../types/schemas/automations.js";
|
|
2
|
+
import { Automation, AutomationAction, AutomationActionResult, AutomationKind, AutomationRun, AutomationRunStatus, AutomationTrigger, CreatedWebhook, DeliverWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
3
3
|
import "../types/index.js";
|
|
4
4
|
//#region src/automations/model.d.ts
|
|
5
5
|
/** Rejected at authoring time: automation.* is reserved to avoid a self-triggering loop. */
|
|
6
6
|
declare class InvalidTriggerError extends Error {
|
|
7
7
|
readonly trigger: string;
|
|
8
|
-
|
|
8
|
+
readonly reason: 'reserved' | 'unknown' | 'schedule';
|
|
9
|
+
constructor(trigger: string, reason?: 'reserved' | 'unknown' | 'schedule');
|
|
10
|
+
}
|
|
11
|
+
declare const ACTION_FAILED = "The action failed";
|
|
12
|
+
/** An action failure whose message is safe to record on the run. */
|
|
13
|
+
declare class ActionFailedError extends Error {
|
|
14
|
+
constructor(message?: string);
|
|
15
|
+
}
|
|
16
|
+
/** The message a run records for an action that threw `err`. */
|
|
17
|
+
declare function actionFailureMessage(err: unknown): string;
|
|
18
|
+
declare class ReservedActionError extends Error {
|
|
19
|
+
readonly actionType: string;
|
|
20
|
+
constructor(actionType: string);
|
|
21
|
+
}
|
|
22
|
+
declare class AutomationKindMismatchError extends Error {
|
|
23
|
+
readonly automationId: string;
|
|
24
|
+
readonly kind: AutomationKind;
|
|
25
|
+
constructor(automationId: string, kind: AutomationKind);
|
|
9
26
|
}
|
|
10
27
|
//#endregion
|
|
11
|
-
export { type Automation, type AutomationAction, type AutomationActionResult, type AutomationRun, type AutomationRunStatus, type AutomationTrigger, InvalidTriggerError, type Page };
|
|
28
|
+
export { ACTION_FAILED, ActionFailedError, type Automation, type AutomationAction, type AutomationActionResult, type AutomationKind, AutomationKindMismatchError, type AutomationRun, type AutomationRunStatus, type AutomationTrigger, type CreatedWebhook, type DeliverWebhookInput, InvalidTriggerError, type Page, ReservedActionError, type Webhook, type WebhookSecret, actionFailureMessage };
|
|
12
29
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -2,13 +2,46 @@
|
|
|
2
2
|
/** Rejected at authoring time: automation.* is reserved to avoid a self-triggering loop. */
|
|
3
3
|
var InvalidTriggerError = class extends Error {
|
|
4
4
|
trigger;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
reason;
|
|
6
|
+
constructor(trigger, reason = "reserved") {
|
|
7
|
+
const message = reason === "reserved" ? `trigger "${trigger}" is reserved: automations cannot trigger on automation.* events` : reason === "unknown" ? `trigger "${trigger}" is not an event the system emits` : `trigger "${trigger}" uses a schedule this system cannot match`;
|
|
8
|
+
super(message);
|
|
7
9
|
this.trigger = trigger;
|
|
10
|
+
this.reason = reason;
|
|
8
11
|
this.name = "InvalidTriggerError";
|
|
9
12
|
}
|
|
10
13
|
};
|
|
14
|
+
const ACTION_FAILED = "The action failed";
|
|
15
|
+
/** An action failure whose message is safe to record on the run. */
|
|
16
|
+
var ActionFailedError = class extends Error {
|
|
17
|
+
constructor(message = ACTION_FAILED) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = "ActionFailedError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** The message a run records for an action that threw `err`. */
|
|
23
|
+
function actionFailureMessage(err) {
|
|
24
|
+
return err instanceof ActionFailedError ? err.message : ACTION_FAILED;
|
|
25
|
+
}
|
|
26
|
+
var ReservedActionError = class extends Error {
|
|
27
|
+
actionType;
|
|
28
|
+
constructor(actionType) {
|
|
29
|
+
super(`action "${actionType}" is reserved to webhooks`);
|
|
30
|
+
this.actionType = actionType;
|
|
31
|
+
this.name = "ReservedActionError";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var AutomationKindMismatchError = class extends Error {
|
|
35
|
+
automationId;
|
|
36
|
+
kind;
|
|
37
|
+
constructor(automationId, kind) {
|
|
38
|
+
super(`automation "${automationId}" is a ${kind} and can't be changed through this operation`);
|
|
39
|
+
this.automationId = automationId;
|
|
40
|
+
this.kind = kind;
|
|
41
|
+
this.name = "AutomationKindMismatchError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
11
44
|
//#endregion
|
|
12
|
-
export { InvalidTriggerError };
|
|
45
|
+
export { ACTION_FAILED, ActionFailedError, AutomationKindMismatchError, InvalidTriggerError, ReservedActionError, actionFailureMessage };
|
|
13
46
|
|
|
14
47
|
//# sourceMappingURL=model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","names":[],"sources":["../../src/automations/model.ts"],"sourcesContent":["// automations context — domain entities, owned by @headless-lms/core/types; the\n// domain
|
|
1
|
+
{"version":3,"file":"model.js","names":[],"sources":["../../src/automations/model.ts"],"sourcesContent":["// automations context — domain entities, owned by @headless-lms/core/types; the\n// domain errors below are runtime code and stay in core.\nimport type { AutomationKind } from '../types/index.js';\n\nexport type {\n AutomationTrigger,\n AutomationAction,\n AutomationKind,\n Automation,\n AutomationRunStatus,\n AutomationActionResult,\n AutomationRun,\n Webhook,\n CreatedWebhook,\n WebhookSecret,\n DeliverWebhookInput,\n Page,\n} from '../types/index.js';\n\n/** Rejected at authoring time: automation.* is reserved to avoid a self-triggering loop. */\nexport class InvalidTriggerError extends Error {\n constructor(\n readonly trigger: string,\n readonly reason: 'reserved' | 'unknown' | 'schedule' = 'reserved',\n ) {\n const message =\n reason === 'reserved'\n ? `trigger \"${trigger}\" is reserved: automations cannot trigger on automation.* events`\n : reason === 'unknown'\n ? `trigger \"${trigger}\" is not an event the system emits`\n : `trigger \"${trigger}\" uses a schedule this system cannot match`;\n super(message);\n this.name = 'InvalidTriggerError';\n }\n}\n\nexport const ACTION_FAILED = 'The action failed';\n\n/** An action failure whose message is safe to record on the run. */\nexport class ActionFailedError extends Error {\n constructor(message: string = ACTION_FAILED) {\n super(message);\n this.name = 'ActionFailedError';\n }\n}\n\n/** The message a run records for an action that threw `err`. */\nexport function actionFailureMessage(err: unknown): string {\n return err instanceof ActionFailedError ? err.message : ACTION_FAILED;\n}\n\nexport class ReservedActionError extends Error {\n constructor(readonly actionType: string) {\n super(`action \"${actionType}\" is reserved to webhooks`);\n this.name = 'ReservedActionError';\n }\n}\n\nexport class AutomationKindMismatchError extends Error {\n constructor(\n readonly automationId: string,\n readonly kind: AutomationKind,\n ) {\n super(`automation \"${automationId}\" is a ${kind} and can't be changed through this operation`);\n this.name = 'AutomationKindMismatchError';\n }\n}\n"],"mappings":";;AAoBA,IAAa,sBAAb,cAAyC,MAAM;CAElC;CACA;CAFX,YACE,SACA,SAAuD,YACvD;EACA,MAAM,UACJ,WAAW,aACP,YAAY,QAAQ,oEACpB,WAAW,YACT,YAAY,QAAQ,sCACpB,YAAY,QAAQ;EAC5B,MAAM,OAAO;EATJ,KAAA,UAAA;EACA,KAAA,SAAA;EAST,KAAK,OAAO;CACd;AACF;AAEA,MAAa,gBAAgB;;AAG7B,IAAa,oBAAb,cAAuC,MAAM;CAC3C,YAAY,UAAkB,eAAe;EAC3C,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;AAGA,SAAgB,qBAAqB,KAAsB;CACzD,OAAO,eAAe,oBAAoB,IAAI,UAAU;AAC1D;AAEA,IAAa,sBAAb,cAAyC,MAAM;CACxB;CAArB,YAAY,YAA6B;EACvC,MAAM,WAAW,WAAW,0BAA0B;EADnC,KAAA,aAAA;EAEnB,KAAK,OAAO;CACd;AACF;AAEA,IAAa,8BAAb,cAAiD,MAAM;CAE1C;CACA;CAFX,YACE,cACA,MACA;EACA,MAAM,eAAe,aAAa,SAAS,KAAK,6CAA6C;EAHpF,KAAA,eAAA;EACA,KAAA,OAAA;EAGT,KAAK,OAAO;CACd;AACF"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { DomainEvent, Page } from "../types/shared.js";
|
|
2
|
-
import { Automation, AutomationRun, AutomationRunsQuery, AvailableActions, AvailableTriggers, CreateAutomationInput, UpdateAutomationInput } from "../types/schemas/automations.js";
|
|
3
|
-
import { AutomationDispatch, AutomationEngine, AutomationExecutor } from "../types/automations.js";
|
|
2
|
+
import { Automation, AutomationKind, AutomationRun, AutomationRunsQuery, AutomationsQuery, AvailableActions, AvailableTriggers, CreateAutomationInput, CreateWebhookInput, CreatedWebhook, UpdateAutomationInput, UpdateWebhookInput, Webhook, WebhookSecret } from "../types/schemas/automations.js";
|
|
3
|
+
import { AutomationDispatch, AutomationEngine, AutomationExecutor, ScheduledAutomation, WebhookRequest, WebhookResponse, WebhookSender } from "../types/automations.js";
|
|
4
4
|
import "../types/index.js";
|
|
5
|
-
import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
5
|
+
import { CredentialStore, OutboxAppender, UnitOfWork } from "../shared/ports.js";
|
|
6
6
|
import "./model.js";
|
|
7
7
|
import "./types.js";
|
|
8
8
|
//#region src/automations/ports.d.ts
|
|
9
|
+
type NewAutomation = CreateAutomationInput & {
|
|
10
|
+
kind: AutomationKind;
|
|
11
|
+
source?: 'system' | 'user';
|
|
12
|
+
};
|
|
9
13
|
/** A run row before persistence assigns its id and event_id. */
|
|
10
14
|
type NewAutomationRun = Omit<AutomationRun, 'id' | 'eventId'>;
|
|
11
15
|
interface AutomationsService {
|
|
@@ -15,32 +19,46 @@ interface AutomationsService {
|
|
|
15
19
|
availableActions(): AvailableActions;
|
|
16
20
|
/** The domain event types an automation may react to. */
|
|
17
21
|
availableTriggers(): AvailableTriggers;
|
|
18
|
-
list(orgId: string): Promise<Automation[]>;
|
|
22
|
+
list(orgId: string, query?: AutomationsQuery): Promise<Automation[]>;
|
|
19
23
|
get(orgId: string, id: string): Promise<Automation | null>;
|
|
20
24
|
create(orgId: string, input: CreateAutomationInput): Promise<Automation>;
|
|
21
25
|
update(orgId: string, id: string, input: UpdateAutomationInput): Promise<Automation | null>;
|
|
22
26
|
delete(orgId: string, id: string): Promise<boolean>;
|
|
23
27
|
listRuns(orgId: string, automationId: string, query: AutomationRunsQuery): Promise<Page<AutomationRun>>;
|
|
28
|
+
rerun(orgId: string, automationId: string, runId: string): Promise<AutomationRun>;
|
|
29
|
+
listWebhooks(orgId: string): Promise<Webhook[]>;
|
|
30
|
+
getWebhook(orgId: string, id: string): Promise<Webhook | null>;
|
|
31
|
+
createWebhook(orgId: string, input: CreateWebhookInput): Promise<CreatedWebhook>;
|
|
32
|
+
updateWebhook(orgId: string, id: string, input: UpdateWebhookInput): Promise<Webhook | null>;
|
|
33
|
+
deleteWebhook(orgId: string, id: string): Promise<boolean>;
|
|
34
|
+
revealWebhookSecret(orgId: string, id: string): Promise<WebhookSecret | null>;
|
|
35
|
+
rotateWebhookSecret(orgId: string, id: string): Promise<WebhookSecret | null>;
|
|
24
36
|
}
|
|
25
37
|
interface AutomationsRepository {
|
|
26
|
-
insert(orgId: string, input:
|
|
38
|
+
insert(orgId: string, input: NewAutomation): Promise<Automation>;
|
|
39
|
+
insertSeed(orgId: string, input: NewAutomation): Promise<Automation | null>;
|
|
27
40
|
update(orgId: string, id: string, patch: UpdateAutomationInput): Promise<Automation | null>;
|
|
28
41
|
/** Returns the deleted row (the event snapshot), or null if it didn't exist. */
|
|
29
42
|
delete(orgId: string, id: string): Promise<Automation | null>;
|
|
30
43
|
findById(orgId: string, id: string): Promise<Automation | null>;
|
|
31
|
-
listByOrg(orgId: string): Promise<Automation[]>;
|
|
32
|
-
/** All rows
|
|
44
|
+
listByOrg(orgId: string, kind?: AutomationKind): Promise<Automation[]>;
|
|
45
|
+
/** All rows whose triggers include `trigger`, enabled and disabled alike — the service filters to `enabled`. */
|
|
33
46
|
listByTrigger(orgId: string, trigger: string): Promise<Automation[]>;
|
|
47
|
+
listSchedules(): Promise<ScheduledAutomation[]>;
|
|
34
48
|
}
|
|
35
49
|
interface AutomationRunsRepository {
|
|
36
50
|
/** Keyed by (orgId, automationId, event.id); returns `null` if this event was already run for this automation (duplicate). */
|
|
37
51
|
insert(orgId: string, run: NewAutomationRun): Promise<AutomationRun | null>;
|
|
52
|
+
findById(orgId: string, id: string): Promise<AutomationRun | null>;
|
|
53
|
+
/** Puts a finished run back to running with no results; `null` if it's missing or still running. */
|
|
54
|
+
restart(orgId: string, id: string, startedAt: Date): Promise<AutomationRun | null>;
|
|
38
55
|
recordOutcome(orgId: string, id: string, outcome: {
|
|
39
56
|
status: AutomationRun['status'];
|
|
40
57
|
actionResults: AutomationRun['actionResults'];
|
|
41
58
|
finishedAt: Date;
|
|
42
59
|
}): Promise<AutomationRun | null>;
|
|
43
60
|
list(orgId: string, automationId: string, query: AutomationRunsQuery): Promise<Page<AutomationRun>>;
|
|
61
|
+
recentRecipients(orgId: string, automationId: string, chatId: string, since: Date): Promise<string[]>;
|
|
44
62
|
}
|
|
45
63
|
/** Tx-scoped port bundle for this context's mutating use cases — every member
|
|
46
64
|
* is bound to the UnitOfWork's transaction, so the write(s) and the event
|
|
@@ -48,9 +66,10 @@ interface AutomationRunsRepository {
|
|
|
48
66
|
interface AutomationsTxScope {
|
|
49
67
|
automations: AutomationsRepository;
|
|
50
68
|
runs: AutomationRunsRepository;
|
|
69
|
+
credentials: CredentialStore;
|
|
51
70
|
outbox: OutboxAppender;
|
|
52
71
|
}
|
|
53
72
|
type AutomationsUnitOfWork = UnitOfWork<AutomationsTxScope>;
|
|
54
73
|
//#endregion
|
|
55
|
-
export { type AutomationDispatch, type AutomationEngine, type AutomationExecutor, AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsTxScope, AutomationsUnitOfWork, NewAutomationRun };
|
|
74
|
+
export { type AutomationDispatch, type AutomationEngine, type AutomationExecutor, AutomationRunsRepository, AutomationsRepository, AutomationsService, AutomationsTxScope, AutomationsUnitOfWork, NewAutomation, NewAutomationRun, type WebhookRequest, type WebhookResponse, type WebhookSender };
|
|
56
75
|
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/automations/schedule.d.ts
|
|
2
|
+
declare function cronMatches(expression: string, at: Date): boolean;
|
|
3
|
+
declare function cronSupported(expression: string): boolean;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { cronMatches, cronSupported };
|
|
6
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/automations/schedule.ts
|
|
2
|
+
const FIELD_RANGES = [
|
|
3
|
+
[0, 59],
|
|
4
|
+
[0, 23],
|
|
5
|
+
[1, 31],
|
|
6
|
+
[1, 12],
|
|
7
|
+
[0, 6]
|
|
8
|
+
];
|
|
9
|
+
function cronMatches(expression, at) {
|
|
10
|
+
const fields = expression.trim().split(/\s+/);
|
|
11
|
+
if (fields.length !== 5) return false;
|
|
12
|
+
const parts = [
|
|
13
|
+
at.getUTCMinutes(),
|
|
14
|
+
at.getUTCHours(),
|
|
15
|
+
at.getUTCDate(),
|
|
16
|
+
at.getUTCMonth() + 1,
|
|
17
|
+
at.getUTCDay()
|
|
18
|
+
];
|
|
19
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = fields.map((field, index) => field === "*" || field.split(",").some((piece) => Number(piece) === parts[index]));
|
|
20
|
+
const day = fields[2] !== "*" && fields[4] !== "*" ? dayOfMonth || dayOfWeek : dayOfMonth && dayOfWeek;
|
|
21
|
+
return Boolean(minute && hour && month && day);
|
|
22
|
+
}
|
|
23
|
+
function cronSupported(expression) {
|
|
24
|
+
const fields = expression.trim().split(/\s+/);
|
|
25
|
+
if (fields.length !== 5) return false;
|
|
26
|
+
return fields.every((field, index) => fieldSupported(field, FIELD_RANGES[index]));
|
|
27
|
+
}
|
|
28
|
+
function fieldSupported(field, range) {
|
|
29
|
+
if (field === "*") return true;
|
|
30
|
+
const pieces = field.split(",");
|
|
31
|
+
const [min, max] = range;
|
|
32
|
+
return pieces.length > 0 && pieces.every((piece) => {
|
|
33
|
+
if (!/^\d+$/.test(piece)) return false;
|
|
34
|
+
const value = Number(piece);
|
|
35
|
+
return value >= min && value <= max;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { cronMatches, cronSupported };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","names":[],"sources":["../../src/automations/schedule.ts"],"sourcesContent":["const FIELD_RANGES = [\n [0, 59],\n [0, 23],\n [1, 31],\n [1, 12],\n [0, 6],\n] as const;\n\nexport function cronMatches(expression: string, at: Date): boolean {\n const fields = expression.trim().split(/\\s+/);\n if (fields.length !== 5) {\n return false;\n }\n const parts = [\n at.getUTCMinutes(),\n at.getUTCHours(),\n at.getUTCDate(),\n at.getUTCMonth() + 1,\n at.getUTCDay(),\n ];\n const matches = fields.map(\n (field, index) =>\n field === '*' || field.split(',').some((piece) => Number(piece) === parts[index]),\n );\n const [minute, hour, dayOfMonth, month, dayOfWeek] = matches;\n const day =\n fields[2] !== '*' && fields[4] !== '*' ? dayOfMonth || dayOfWeek : dayOfMonth && dayOfWeek;\n return Boolean(minute && hour && month && day);\n}\n\nexport function cronSupported(expression: string): boolean {\n const fields = expression.trim().split(/\\s+/);\n if (fields.length !== 5) {\n return false;\n }\n return fields.every((field, index) => fieldSupported(field, FIELD_RANGES[index]!));\n}\n\nfunction fieldSupported(field: string, range: readonly [number, number]): boolean {\n if (field === '*') {\n return true;\n }\n const pieces = field.split(',');\n const [min, max] = range;\n return (\n pieces.length > 0 &&\n pieces.every((piece) => {\n if (!/^\\d+$/.test(piece)) {\n return false;\n }\n const value = Number(piece);\n return value >= min && value <= max;\n })\n );\n}\n"],"mappings":";AAAA,MAAM,eAAe;CACnB,CAAC,GAAG,EAAE;CACN,CAAC,GAAG,EAAE;CACN,CAAC,GAAG,EAAE;CACN,CAAC,GAAG,EAAE;CACN,CAAC,GAAG,CAAC;AACP;AAEA,SAAgB,YAAY,YAAoB,IAAmB;CACjE,MAAM,SAAS,WAAW,KAAK,CAAC,CAAC,MAAM,KAAK;CAC5C,IAAI,OAAO,WAAW,GACpB,OAAO;CAET,MAAM,QAAQ;EACZ,GAAG,cAAc;EACjB,GAAG,YAAY;EACf,GAAG,WAAW;EACd,GAAG,YAAY,IAAI;EACnB,GAAG,UAAU;CACf;CAKA,MAAM,CAAC,QAAQ,MAAM,YAAY,OAAO,aAJxB,OAAO,KACpB,OAAO,UACN,UAAU,OAAO,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,MAAM,CAEzB;CAC3D,MAAM,MACJ,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,cAAc,YAAY,cAAc;CACnF,OAAO,QAAQ,UAAU,QAAQ,SAAS,GAAG;AAC/C;AAEA,SAAgB,cAAc,YAA6B;CACzD,MAAM,SAAS,WAAW,KAAK,CAAC,CAAC,MAAM,KAAK;CAC5C,IAAI,OAAO,WAAW,GACpB,OAAO;CAET,OAAO,OAAO,OAAO,OAAO,UAAU,eAAe,OAAO,aAAa,MAAO,CAAC;AACnF;AAEA,SAAS,eAAe,OAAe,OAA2C;CAChF,IAAI,UAAU,KACZ,OAAO;CAET,MAAM,SAAS,MAAM,MAAM,GAAG;CAC9B,MAAM,CAAC,KAAK,OAAO;CACnB,OACE,OAAO,SAAS,KAChB,OAAO,OAAO,UAAU;EACtB,IAAI,CAAC,QAAQ,KAAK,KAAK,GACrB,OAAO;EAET,MAAM,QAAQ,OAAO,KAAK;EAC1B,OAAO,SAAS,OAAO,SAAS;CAClC,CAAC;AAEL"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { JsonValue } from "../types/shared.js";
|
|
2
|
+
import { AutomationAction } from "../types/schemas/automations.js";
|
|
3
|
+
import "../types/index.js";
|
|
4
|
+
import "./model.js";
|
|
5
|
+
//#region src/automations/seeds.d.ts
|
|
6
|
+
interface SeedAutomation {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
triggers: string[];
|
|
10
|
+
actions: AutomationAction[];
|
|
11
|
+
filter: Record<string, JsonValue> | null;
|
|
12
|
+
}
|
|
13
|
+
declare function orgSeeds(): SeedAutomation[];
|
|
14
|
+
declare function communitySeeds(communityId: string): SeedAutomation[];
|
|
15
|
+
//#endregion
|
|
16
|
+
export { SeedAutomation, communitySeeds, orgSeeds };
|
|
17
|
+
//# sourceMappingURL=seeds.d.ts.map
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
//#region src/automations/seeds.ts
|
|
2
|
+
function email(template, communityId) {
|
|
3
|
+
return {
|
|
4
|
+
type: "sendEmail",
|
|
5
|
+
input: communityId === void 0 ? { template } : {
|
|
6
|
+
template,
|
|
7
|
+
communityId
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function notify(kind, communityId) {
|
|
12
|
+
return {
|
|
13
|
+
type: "notify",
|
|
14
|
+
input: communityId === void 0 ? { kind } : {
|
|
15
|
+
kind,
|
|
16
|
+
communityId
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function orgSeeds() {
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
name: "Access granted",
|
|
24
|
+
description: "Email the person when they are granted a content item.",
|
|
25
|
+
triggers: ["entitlement.created"],
|
|
26
|
+
actions: [email("accessGranted")],
|
|
27
|
+
filter: null
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "Access revoked",
|
|
31
|
+
description: "Email the person when a content grant is deleted.",
|
|
32
|
+
triggers: ["entitlement.deleted"],
|
|
33
|
+
actions: [email("accessRevoked")],
|
|
34
|
+
filter: null
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "You are now a moderator",
|
|
38
|
+
description: "Notify the person when they are given the moderator role.",
|
|
39
|
+
triggers: ["organization.user.updated"],
|
|
40
|
+
actions: [notify("youAreNowAModerator")],
|
|
41
|
+
filter: null
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "Publish due posts",
|
|
45
|
+
description: "Submit scheduled posts whose time has passed.",
|
|
46
|
+
triggers: ["schedule:* * * * *"],
|
|
47
|
+
actions: [{
|
|
48
|
+
type: "publishDuePosts",
|
|
49
|
+
input: {}
|
|
50
|
+
}],
|
|
51
|
+
filter: null
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Expire due grants",
|
|
55
|
+
description: "Expire grants whose time has passed and remind those ending within a week.",
|
|
56
|
+
triggers: ["schedule:0 * * * *"],
|
|
57
|
+
actions: [{
|
|
58
|
+
type: "expireDueGrants",
|
|
59
|
+
input: {}
|
|
60
|
+
}],
|
|
61
|
+
filter: null
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "Send digest",
|
|
65
|
+
description: "Open the daily digest for every community.",
|
|
66
|
+
triggers: ["schedule:0 7 * * *"],
|
|
67
|
+
actions: [{
|
|
68
|
+
type: "sendDigest",
|
|
69
|
+
input: {}
|
|
70
|
+
}],
|
|
71
|
+
filter: null
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "Remove unattached uploads",
|
|
75
|
+
description: "Remove member uploads older than an hour that nothing references.",
|
|
76
|
+
triggers: ["schedule:0 * * * *"],
|
|
77
|
+
actions: [{
|
|
78
|
+
type: "removeUnattachedUploads",
|
|
79
|
+
input: {}
|
|
80
|
+
}],
|
|
81
|
+
filter: null
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "Welcome to the community",
|
|
85
|
+
description: "Notify a person when a grant opens a community.",
|
|
86
|
+
triggers: ["entitlement.created"],
|
|
87
|
+
actions: [notify("welcomeToCommunity")],
|
|
88
|
+
filter: null
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "Membership ended",
|
|
92
|
+
description: "Email a person when a grant that opened a community ends.",
|
|
93
|
+
triggers: ["entitlement.expired", "entitlement.deleted"],
|
|
94
|
+
actions: [email("membershipEnded")],
|
|
95
|
+
filter: null
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
function communitySeeds(communityId) {
|
|
100
|
+
const filter = { communityId };
|
|
101
|
+
const scoped = (template) => email(template, communityId);
|
|
102
|
+
const told = (kind) => notify(kind, communityId);
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
name: "Membership ending soon",
|
|
106
|
+
description: "Notify a member a week before this community grant ends.",
|
|
107
|
+
triggers: ["entitlement.ending_soon"],
|
|
108
|
+
actions: [told("membershipEndingSoon")],
|
|
109
|
+
filter: { communityId }
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "New post in a space",
|
|
113
|
+
description: "Notify members who can open the space.",
|
|
114
|
+
triggers: ["discussion.post.published"],
|
|
115
|
+
actions: [told("newPostInSpace")],
|
|
116
|
+
filter
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "Your post was published",
|
|
120
|
+
description: "Notify the author when a pending post is published.",
|
|
121
|
+
triggers: ["discussion.post.published"],
|
|
122
|
+
actions: [told("yourPostWasPublished")],
|
|
123
|
+
filter
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "Your post was removed",
|
|
127
|
+
description: "Notify the author when someone else removes their post.",
|
|
128
|
+
triggers: ["discussion.post.removed"],
|
|
129
|
+
actions: [told("yourPostWasRemoved")],
|
|
130
|
+
filter
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "New comment on a post you follow",
|
|
134
|
+
description: "Notify the author and followers when a comment is published.",
|
|
135
|
+
triggers: ["discussion.comment.created"],
|
|
136
|
+
actions: [told("newCommentOnPost")],
|
|
137
|
+
filter
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "Reply to your comment",
|
|
141
|
+
description: "Notify the parent author when a reply is published.",
|
|
142
|
+
triggers: ["discussion.comment.created"],
|
|
143
|
+
actions: [told("replyToYourComment")],
|
|
144
|
+
filter
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "Your comment was removed",
|
|
148
|
+
description: "Notify the author when someone else removes their comment.",
|
|
149
|
+
triggers: ["discussion.comment.removed"],
|
|
150
|
+
actions: [told("yourCommentWasRemoved")],
|
|
151
|
+
filter
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "Post awaiting review",
|
|
155
|
+
description: "Notify staff and moderators when a post enters review.",
|
|
156
|
+
triggers: ["discussion.post.created", "discussion.post.updated"],
|
|
157
|
+
actions: [told("postAwaitingReview")],
|
|
158
|
+
filter
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "Join request",
|
|
162
|
+
description: "Notify staff and moderators when someone requests a space.",
|
|
163
|
+
triggers: ["entitlement.space_member.created"],
|
|
164
|
+
actions: [told("joinRequest")],
|
|
165
|
+
filter
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "Request approved",
|
|
169
|
+
description: "Notify the member when their request is approved.",
|
|
170
|
+
triggers: ["entitlement.space_member.updated"],
|
|
171
|
+
actions: [told("requestApproved")],
|
|
172
|
+
filter
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "Request declined",
|
|
176
|
+
description: "Notify the person when their request is declined.",
|
|
177
|
+
triggers: ["entitlement.space_member.deleted"],
|
|
178
|
+
actions: [told("requestDeclined")],
|
|
179
|
+
filter
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "Invited to a space",
|
|
183
|
+
description: "Notify the person when they are invited to a space.",
|
|
184
|
+
triggers: ["entitlement.space_member.created"],
|
|
185
|
+
actions: [told("invitedToSpace")],
|
|
186
|
+
filter
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "New message",
|
|
190
|
+
description: "Notify participants who are not muted, at most once per chat per 15 minutes.",
|
|
191
|
+
triggers: ["discussion.message.sent"],
|
|
192
|
+
actions: [told("newMessage")],
|
|
193
|
+
filter
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "Message request",
|
|
197
|
+
description: "Notify the recipient when a direct chat starts as a request.",
|
|
198
|
+
triggers: ["discussion.chat.created"],
|
|
199
|
+
actions: [told("messageRequest")],
|
|
200
|
+
filter
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "Added to a group chat",
|
|
204
|
+
description: "Notify the person added to a group chat.",
|
|
205
|
+
triggers: ["discussion.chat.participant.added"],
|
|
206
|
+
actions: [told("addedToGroupChat")],
|
|
207
|
+
filter
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "Something was flagged",
|
|
211
|
+
description: "Notify staff and moderators when a post or comment is flagged.",
|
|
212
|
+
triggers: ["discussion.post.reported", "discussion.comment.reported"],
|
|
213
|
+
actions: [told("somethingWasFlagged")],
|
|
214
|
+
filter
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "A message was flagged",
|
|
218
|
+
description: "Notify staff when a message is flagged.",
|
|
219
|
+
triggers: ["discussion.message.reported"],
|
|
220
|
+
actions: [told("messageWasFlagged")],
|
|
221
|
+
filter
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: "Digest",
|
|
225
|
+
description: "Email members their unread activity. Not sent until email preferences exist.",
|
|
226
|
+
triggers: ["discussion.digest.due"],
|
|
227
|
+
actions: [scoped("digest")],
|
|
228
|
+
filter
|
|
229
|
+
}
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
export { communitySeeds, orgSeeds };
|
|
234
|
+
|
|
235
|
+
//# sourceMappingURL=seeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeds.js","names":[],"sources":["../../src/automations/seeds.ts"],"sourcesContent":["import type { JsonValue } from '../types/index.js';\nimport type { AutomationAction } from './model.js';\n\nexport interface SeedAutomation {\n name: string;\n description: string;\n triggers: string[];\n actions: AutomationAction[];\n filter: Record<string, JsonValue> | null;\n}\n\nfunction email(template: string, communityId?: string): AutomationAction {\n return {\n type: 'sendEmail',\n input: communityId === undefined ? { template } : { template, communityId },\n };\n}\n\nfunction notify(kind: string, communityId?: string): AutomationAction {\n return {\n type: 'notify',\n input: communityId === undefined ? { kind } : { kind, communityId },\n };\n}\n\nexport function orgSeeds(): SeedAutomation[] {\n return [\n {\n name: 'Access granted',\n description: 'Email the person when they are granted a content item.',\n triggers: ['entitlement.created'],\n actions: [email('accessGranted')],\n filter: null,\n },\n {\n name: 'Access revoked',\n description: 'Email the person when a content grant is deleted.',\n triggers: ['entitlement.deleted'],\n actions: [email('accessRevoked')],\n filter: null,\n },\n {\n name: 'You are now a moderator',\n description: 'Notify the person when they are given the moderator role.',\n triggers: ['organization.user.updated'],\n actions: [notify('youAreNowAModerator')],\n filter: null,\n },\n {\n name: 'Publish due posts',\n description: 'Submit scheduled posts whose time has passed.',\n triggers: ['schedule:* * * * *'],\n actions: [{ type: 'publishDuePosts', input: {} }],\n filter: null,\n },\n {\n name: 'Expire due grants',\n description: 'Expire grants whose time has passed and remind those ending within a week.',\n triggers: ['schedule:0 * * * *'],\n actions: [{ type: 'expireDueGrants', input: {} }],\n filter: null,\n },\n {\n name: 'Send digest',\n description: 'Open the daily digest for every community.',\n triggers: ['schedule:0 7 * * *'],\n actions: [{ type: 'sendDigest', input: {} }],\n filter: null,\n },\n {\n name: 'Remove unattached uploads',\n description: 'Remove member uploads older than an hour that nothing references.',\n triggers: ['schedule:0 * * * *'],\n actions: [{ type: 'removeUnattachedUploads', input: {} }],\n filter: null,\n },\n {\n name: 'Welcome to the community',\n description: 'Notify a person when a grant opens a community.',\n triggers: ['entitlement.created'],\n actions: [notify('welcomeToCommunity')],\n filter: null,\n },\n {\n name: 'Membership ended',\n description: 'Email a person when a grant that opened a community ends.',\n triggers: ['entitlement.expired', 'entitlement.deleted'],\n actions: [email('membershipEnded')],\n filter: null,\n },\n ];\n}\n\nexport function communitySeeds(communityId: string): SeedAutomation[] {\n const filter = { communityId };\n const scoped = (template: string): AutomationAction => email(template, communityId);\n const told = (kind: string): AutomationAction => notify(kind, communityId);\n return [\n {\n name: 'Membership ending soon',\n description: 'Notify a member a week before this community grant ends.',\n triggers: ['entitlement.ending_soon'],\n actions: [told('membershipEndingSoon')],\n filter: { communityId },\n },\n {\n name: 'New post in a space',\n description: 'Notify members who can open the space.',\n triggers: ['discussion.post.published'],\n actions: [told('newPostInSpace')],\n filter,\n },\n {\n name: 'Your post was published',\n description: 'Notify the author when a pending post is published.',\n triggers: ['discussion.post.published'],\n actions: [told('yourPostWasPublished')],\n filter,\n },\n {\n name: 'Your post was removed',\n description: 'Notify the author when someone else removes their post.',\n triggers: ['discussion.post.removed'],\n actions: [told('yourPostWasRemoved')],\n filter,\n },\n {\n name: 'New comment on a post you follow',\n description: 'Notify the author and followers when a comment is published.',\n triggers: ['discussion.comment.created'],\n actions: [told('newCommentOnPost')],\n filter,\n },\n {\n name: 'Reply to your comment',\n description: 'Notify the parent author when a reply is published.',\n triggers: ['discussion.comment.created'],\n actions: [told('replyToYourComment')],\n filter,\n },\n {\n name: 'Your comment was removed',\n description: 'Notify the author when someone else removes their comment.',\n triggers: ['discussion.comment.removed'],\n actions: [told('yourCommentWasRemoved')],\n filter,\n },\n {\n name: 'Post awaiting review',\n description: 'Notify staff and moderators when a post enters review.',\n triggers: ['discussion.post.created', 'discussion.post.updated'],\n actions: [told('postAwaitingReview')],\n filter,\n },\n {\n name: 'Join request',\n description: 'Notify staff and moderators when someone requests a space.',\n triggers: ['entitlement.space_member.created'],\n actions: [told('joinRequest')],\n filter,\n },\n {\n name: 'Request approved',\n description: 'Notify the member when their request is approved.',\n triggers: ['entitlement.space_member.updated'],\n actions: [told('requestApproved')],\n filter,\n },\n {\n name: 'Request declined',\n description: 'Notify the person when their request is declined.',\n triggers: ['entitlement.space_member.deleted'],\n actions: [told('requestDeclined')],\n filter,\n },\n {\n name: 'Invited to a space',\n description: 'Notify the person when they are invited to a space.',\n triggers: ['entitlement.space_member.created'],\n actions: [told('invitedToSpace')],\n filter,\n },\n {\n name: 'New message',\n description: 'Notify participants who are not muted, at most once per chat per 15 minutes.',\n triggers: ['discussion.message.sent'],\n actions: [told('newMessage')],\n filter,\n },\n {\n name: 'Message request',\n description: 'Notify the recipient when a direct chat starts as a request.',\n triggers: ['discussion.chat.created'],\n actions: [told('messageRequest')],\n filter,\n },\n {\n name: 'Added to a group chat',\n description: 'Notify the person added to a group chat.',\n triggers: ['discussion.chat.participant.added'],\n actions: [told('addedToGroupChat')],\n filter,\n },\n {\n name: 'Something was flagged',\n description: 'Notify staff and moderators when a post or comment is flagged.',\n triggers: ['discussion.post.reported', 'discussion.comment.reported'],\n actions: [told('somethingWasFlagged')],\n filter,\n },\n {\n name: 'A message was flagged',\n description: 'Notify staff when a message is flagged.',\n triggers: ['discussion.message.reported'],\n actions: [told('messageWasFlagged')],\n filter,\n },\n {\n name: 'Digest',\n description: 'Email members their unread activity. Not sent until email preferences exist.',\n triggers: ['discussion.digest.due'],\n actions: [scoped('digest')],\n filter,\n },\n ];\n}\n"],"mappings":"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"}
|