@webiny/api-scheduler 0.0.0-unstable.61c048f412
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/LICENSE +21 -0
- package/README.md +11 -0
- package/constants.d.ts +8 -0
- package/constants.js +10 -0
- package/constants.js.map +1 -0
- package/context.d.ts +7 -0
- package/context.js +41 -0
- package/context.js.map +1 -0
- package/createEventHandler.d.ts +13 -0
- package/createEventHandler.js +50 -0
- package/createEventHandler.js.map +1 -0
- package/createScheduler.d.ts +6 -0
- package/createScheduler.js +11 -0
- package/createScheduler.js.map +1 -0
- package/domain/SchedulePrivateModel.d.ts +8 -0
- package/domain/SchedulePrivateModel.js +29 -0
- package/domain/SchedulePrivateModel.js.map +1 -0
- package/domain/ScheduledActionId.d.ts +8 -0
- package/domain/ScheduledActionId.js +9 -0
- package/domain/ScheduledActionId.js.map +1 -0
- package/domain/ScheduledActionIdWithVersion.d.ts +3 -0
- package/domain/ScheduledActionIdWithVersion.js +10 -0
- package/domain/ScheduledActionIdWithVersion.js.map +1 -0
- package/domain/errors.d.ts +37 -0
- package/domain/errors.js +63 -0
- package/domain/errors.js.map +1 -0
- package/domain/isValidDate.d.ts +6 -0
- package/domain/isValidDate.js +13 -0
- package/domain/isValidDate.js.map +1 -0
- package/features/CancelScheduledAction/CancelScheduledActionUseCase.d.ts +26 -0
- package/features/CancelScheduledAction/CancelScheduledActionUseCase.js +74 -0
- package/features/CancelScheduledAction/CancelScheduledActionUseCase.js.map +1 -0
- package/features/CancelScheduledAction/abstractions.d.ts +24 -0
- package/features/CancelScheduledAction/abstractions.js +13 -0
- package/features/CancelScheduledAction/abstractions.js.map +1 -0
- package/features/CancelScheduledAction/feature.d.ts +7 -0
- package/features/CancelScheduledAction/feature.js +17 -0
- package/features/CancelScheduledAction/feature.js.map +1 -0
- package/features/CancelScheduledAction/index.d.ts +1 -0
- package/features/CancelScheduledAction/index.js +3 -0
- package/features/CancelScheduledAction/index.js.map +1 -0
- package/features/ExecuteScheduledAction/ExecuteScheduledActionUseCase.d.ts +33 -0
- package/features/ExecuteScheduledAction/ExecuteScheduledActionUseCase.js +106 -0
- package/features/ExecuteScheduledAction/ExecuteScheduledActionUseCase.js.map +1 -0
- package/features/ExecuteScheduledAction/ScheduledActionHandlerComposite.d.ts +19 -0
- package/features/ExecuteScheduledAction/ScheduledActionHandlerComposite.js +32 -0
- package/features/ExecuteScheduledAction/ScheduledActionHandlerComposite.js.map +1 -0
- package/features/ExecuteScheduledAction/abstractions.d.ts +46 -0
- package/features/ExecuteScheduledAction/abstractions.js +41 -0
- package/features/ExecuteScheduledAction/abstractions.js.map +1 -0
- package/features/ExecuteScheduledAction/feature.d.ts +7 -0
- package/features/ExecuteScheduledAction/feature.js +19 -0
- package/features/ExecuteScheduledAction/feature.js.map +1 -0
- package/features/ExecuteScheduledAction/index.d.ts +1 -0
- package/features/ExecuteScheduledAction/index.js +3 -0
- package/features/ExecuteScheduledAction/index.js.map +1 -0
- package/features/GetScheduledAction/GetScheduledActionUseCase.d.ts +24 -0
- package/features/GetScheduledAction/GetScheduledActionUseCase.js +49 -0
- package/features/GetScheduledAction/GetScheduledActionUseCase.js.map +1 -0
- package/features/GetScheduledAction/abstractions.d.ts +26 -0
- package/features/GetScheduledAction/abstractions.js +14 -0
- package/features/GetScheduledAction/abstractions.js.map +1 -0
- package/features/GetScheduledAction/feature.d.ts +7 -0
- package/features/GetScheduledAction/feature.js +17 -0
- package/features/GetScheduledAction/feature.js.map +1 -0
- package/features/GetScheduledAction/index.d.ts +1 -0
- package/features/GetScheduledAction/index.js +3 -0
- package/features/GetScheduledAction/index.js.map +1 -0
- package/features/ListScheduledActions/ListScheduledActionsUseCase.d.ts +27 -0
- package/features/ListScheduledActions/ListScheduledActionsUseCase.js +77 -0
- package/features/ListScheduledActions/ListScheduledActionsUseCase.js.map +1 -0
- package/features/ListScheduledActions/abstractions.d.ts +49 -0
- package/features/ListScheduledActions/abstractions.js +15 -0
- package/features/ListScheduledActions/abstractions.js.map +1 -0
- package/features/ListScheduledActions/feature.d.ts +7 -0
- package/features/ListScheduledActions/feature.js +17 -0
- package/features/ListScheduledActions/feature.js.map +1 -0
- package/features/ListScheduledActions/index.d.ts +1 -0
- package/features/ListScheduledActions/index.js +3 -0
- package/features/ListScheduledActions/index.js.map +1 -0
- package/features/RunAction/RunActionUseCase.d.ts +23 -0
- package/features/RunAction/RunActionUseCase.js +37 -0
- package/features/RunAction/RunActionUseCase.js.map +1 -0
- package/features/RunAction/abstractions.d.ts +35 -0
- package/features/RunAction/abstractions.js +15 -0
- package/features/RunAction/abstractions.js.map +1 -0
- package/features/RunAction/feature.d.ts +7 -0
- package/features/RunAction/feature.js +17 -0
- package/features/RunAction/feature.js.map +1 -0
- package/features/RunAction/index.d.ts +1 -0
- package/features/RunAction/index.js +3 -0
- package/features/RunAction/index.js.map +1 -0
- package/features/ScheduleAction/ScheduleActionUseCase.d.ts +45 -0
- package/features/ScheduleAction/ScheduleActionUseCase.js +164 -0
- package/features/ScheduleAction/ScheduleActionUseCase.js.map +1 -0
- package/features/ScheduleAction/abstractions.d.ts +35 -0
- package/features/ScheduleAction/abstractions.js +13 -0
- package/features/ScheduleAction/abstractions.js.map +1 -0
- package/features/ScheduleAction/feature.d.ts +7 -0
- package/features/ScheduleAction/feature.js +17 -0
- package/features/ScheduleAction/feature.js.map +1 -0
- package/features/ScheduleAction/index.d.ts +1 -0
- package/features/ScheduleAction/index.js +3 -0
- package/features/ScheduleAction/index.js.map +1 -0
- package/features/SchedulerFeature.d.ts +8 -0
- package/features/SchedulerFeature.js +29 -0
- package/features/SchedulerFeature.js.map +1 -0
- package/features/SchedulerService/EventBridgeSchedulerService.d.ts +26 -0
- package/features/SchedulerService/EventBridgeSchedulerService.js +131 -0
- package/features/SchedulerService/EventBridgeSchedulerService.js.map +1 -0
- package/features/SchedulerService/VoidSchedulerService.d.ts +15 -0
- package/features/SchedulerService/VoidSchedulerService.js +31 -0
- package/features/SchedulerService/VoidSchedulerService.js.map +1 -0
- package/index.d.ts +10 -0
- package/index.js +13 -0
- package/index.js.map +1 -0
- package/manifest.d.ts +17 -0
- package/manifest.js +39 -0
- package/manifest.js.map +1 -0
- package/package.json +55 -0
- package/shared/abstractions.d.ts +77 -0
- package/shared/abstractions.js +32 -0
- package/shared/abstractions.js.map +1 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { ListLatestEntriesUseCase } from "@webiny/api-headless-cms/features/contentEntry/ListEntries/abstractions.js";
|
|
3
|
+
import { ListScheduledActionsUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
4
|
+
import { ScheduledActionModel } from "../../shared/abstractions.js";
|
|
5
|
+
import { ScheduledActionPersistenceError } from "../../domain/errors.js";
|
|
6
|
+
import { CmsSortMapper, CmsWhereMapper } from "@webiny/api-headless-cms";
|
|
7
|
+
/**
|
|
8
|
+
* Lists scheduled actions with optional filtering
|
|
9
|
+
*
|
|
10
|
+
* Flow:
|
|
11
|
+
* 1. Build query filters based on where params (namespace, actionType, targetId, etc.)
|
|
12
|
+
* 2. Fetch entries from CMS storage with pagination and sorting
|
|
13
|
+
* 3. Transform CMS entries to IScheduledAction format
|
|
14
|
+
* 4. Return paginated results with metadata
|
|
15
|
+
*/
|
|
16
|
+
class ListScheduledActionsUseCaseImpl {
|
|
17
|
+
constructor(listEntriesUseCase, model, cmsWhereMapper, cmsSortMapper) {
|
|
18
|
+
this.listEntriesUseCase = listEntriesUseCase;
|
|
19
|
+
this.model = model;
|
|
20
|
+
this.cmsWhereMapper = cmsWhereMapper;
|
|
21
|
+
this.cmsSortMapper = cmsSortMapper;
|
|
22
|
+
}
|
|
23
|
+
async execute(params) {
|
|
24
|
+
const {
|
|
25
|
+
where,
|
|
26
|
+
sort: sortInput,
|
|
27
|
+
limit,
|
|
28
|
+
after
|
|
29
|
+
} = params;
|
|
30
|
+
const sort = this.cmsSortMapper.map({
|
|
31
|
+
input: sortInput,
|
|
32
|
+
fields: this.model.fields
|
|
33
|
+
});
|
|
34
|
+
// List entries from CMS
|
|
35
|
+
const listResult = await this.listEntriesUseCase.execute(this.model, {
|
|
36
|
+
where: this.cmsWhereMapper.map({
|
|
37
|
+
input: where,
|
|
38
|
+
fields: this.model.fields
|
|
39
|
+
}),
|
|
40
|
+
sort,
|
|
41
|
+
limit,
|
|
42
|
+
after
|
|
43
|
+
});
|
|
44
|
+
if (listResult.isFail()) {
|
|
45
|
+
return Result.fail(new ScheduledActionPersistenceError(listResult.error));
|
|
46
|
+
}
|
|
47
|
+
const {
|
|
48
|
+
entries,
|
|
49
|
+
meta
|
|
50
|
+
} = listResult.value;
|
|
51
|
+
|
|
52
|
+
// Transform entries to IScheduledAction format
|
|
53
|
+
const scheduledActions = entries.map(entry => {
|
|
54
|
+
return {
|
|
55
|
+
id: entry.entryId,
|
|
56
|
+
title: entry.values.title,
|
|
57
|
+
namespace: entry.values.namespace,
|
|
58
|
+
actionType: entry.values.actionType,
|
|
59
|
+
targetId: entry.values.targetId,
|
|
60
|
+
scheduledBy: entry.values.scheduledBy,
|
|
61
|
+
scheduledFor: entry.values.scheduledFor,
|
|
62
|
+
payload: entry.values.payload,
|
|
63
|
+
error: entry.values.error
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
return Result.ok({
|
|
67
|
+
items: scheduledActions,
|
|
68
|
+
meta
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const ListScheduledActionsUseCase = UseCaseAbstraction.createImplementation({
|
|
73
|
+
implementation: ListScheduledActionsUseCaseImpl,
|
|
74
|
+
dependencies: [ListLatestEntriesUseCase, ScheduledActionModel, CmsWhereMapper, CmsSortMapper]
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=ListScheduledActionsUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Result","ListLatestEntriesUseCase","ListScheduledActionsUseCase","UseCaseAbstraction","ScheduledActionModel","ScheduledActionPersistenceError","CmsSortMapper","CmsWhereMapper","ListScheduledActionsUseCaseImpl","constructor","listEntriesUseCase","model","cmsWhereMapper","cmsSortMapper","execute","params","where","sort","sortInput","limit","after","map","input","fields","listResult","isFail","fail","error","entries","meta","value","scheduledActions","entry","id","entryId","title","values","namespace","actionType","targetId","scheduledBy","scheduledFor","payload","ok","items","createImplementation","implementation","dependencies"],"sources":["ListScheduledActionsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { ListLatestEntriesUseCase } from \"@webiny/api-headless-cms/features/contentEntry/ListEntries/abstractions.js\";\nimport {\n IListScheduledActionsParams,\n IListScheduledActionsResponse,\n ListScheduledActionsUseCase as UseCaseAbstraction\n} from \"./abstractions.js\";\nimport type { IScheduledAction } from \"~/shared/abstractions.js\";\nimport { ScheduledActionModel } from \"~/shared/abstractions.js\";\nimport { ScheduledActionPersistenceError } from \"~/domain/errors.js\";\nimport { CmsSortMapper, CmsWhereMapper } from \"@webiny/api-headless-cms\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\n/**\n * Lists scheduled actions with optional filtering\n *\n * Flow:\n * 1. Build query filters based on where params (namespace, actionType, targetId, etc.)\n * 2. Fetch entries from CMS storage with pagination and sorting\n * 3. Transform CMS entries to IScheduledAction format\n * 4. Return paginated results with metadata\n */\nclass ListScheduledActionsUseCaseImpl implements UseCaseAbstraction.Interface {\n constructor(\n private listEntriesUseCase: ListLatestEntriesUseCase.Interface,\n private model: ScheduledActionModel.Interface,\n private cmsWhereMapper: CmsWhereMapper.Interface,\n private cmsSortMapper: CmsSortMapper.Interface\n ) {}\n\n async execute<T extends GenericRecord>(\n params: IListScheduledActionsParams\n ): Promise<Result<IListScheduledActionsResponse<T>, UseCaseAbstraction.Error>> {\n const { where, sort: sortInput, limit, after } = params;\n\n const sort = this.cmsSortMapper.map({\n input: sortInput,\n fields: this.model.fields\n });\n // List entries from CMS\n const listResult = await this.listEntriesUseCase.execute<IScheduledAction<T>>(this.model, {\n where: this.cmsWhereMapper.map({\n input: where,\n fields: this.model.fields\n }),\n sort,\n limit,\n after\n });\n\n if (listResult.isFail()) {\n return Result.fail(new ScheduledActionPersistenceError(listResult.error));\n }\n\n const { entries, meta } = listResult.value;\n\n // Transform entries to IScheduledAction format\n const scheduledActions: IScheduledAction<T>[] = entries.map(entry => {\n return {\n id: entry.entryId,\n title: entry.values.title,\n namespace: entry.values.namespace,\n actionType: entry.values.actionType,\n targetId: entry.values.targetId,\n scheduledBy: entry.values.scheduledBy,\n scheduledFor: entry.values.scheduledFor,\n payload: entry.values.payload,\n error: entry.values.error\n };\n });\n\n return Result.ok({\n items: scheduledActions,\n meta\n });\n }\n}\n\nexport const ListScheduledActionsUseCase = UseCaseAbstraction.createImplementation({\n implementation: ListScheduledActionsUseCaseImpl,\n dependencies: [ListLatestEntriesUseCase, ScheduledActionModel, CmsWhereMapper, CmsSortMapper]\n});\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,qBAAqB;AAC5C,SAASC,wBAAwB,QAAQ,4EAA4E;AACrH,SAGIC,2BAA2B,IAAIC,kBAAkB;AAGrD,SAASC,oBAAoB;AAC7B,SAASC,+BAA+B;AACxC,SAASC,aAAa,EAAEC,cAAc,QAAQ,0BAA0B;AAGxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,+BAA+B,CAAyC;EAC1EC,WAAWA,CACCC,kBAAsD,EACtDC,KAAqC,EACrCC,cAAwC,EACxCC,aAAsC,EAChD;IAAA,KAJUH,kBAAsD,GAAtDA,kBAAsD;IAAA,KACtDC,KAAqC,GAArCA,KAAqC;IAAA,KACrCC,cAAwC,GAAxCA,cAAwC;IAAA,KACxCC,aAAsC,GAAtCA,aAAsC;EAC/C;EAEH,MAAMC,OAAOA,CACTC,MAAmC,EACwC;IAC3E,MAAM;MAAEC,KAAK;MAAEC,IAAI,EAAEC,SAAS;MAAEC,KAAK;MAAEC;IAAM,CAAC,GAAGL,MAAM;IAEvD,MAAME,IAAI,GAAG,IAAI,CAACJ,aAAa,CAACQ,GAAG,CAAC;MAChCC,KAAK,EAAEJ,SAAS;MAChBK,MAAM,EAAE,IAAI,CAACZ,KAAK,CAACY;IACvB,CAAC,CAAC;IACF;IACA,MAAMC,UAAU,GAAG,MAAM,IAAI,CAACd,kBAAkB,CAACI,OAAO,CAAsB,IAAI,CAACH,KAAK,EAAE;MACtFK,KAAK,EAAE,IAAI,CAACJ,cAAc,CAACS,GAAG,CAAC;QAC3BC,KAAK,EAAEN,KAAK;QACZO,MAAM,EAAE,IAAI,CAACZ,KAAK,CAACY;MACvB,CAAC,CAAC;MACFN,IAAI;MACJE,KAAK;MACLC;IACJ,CAAC,CAAC;IAEF,IAAII,UAAU,CAACC,MAAM,CAAC,CAAC,EAAE;MACrB,OAAOzB,MAAM,CAAC0B,IAAI,CAAC,IAAIrB,+BAA+B,CAACmB,UAAU,CAACG,KAAK,CAAC,CAAC;IAC7E;IAEA,MAAM;MAAEC,OAAO;MAAEC;IAAK,CAAC,GAAGL,UAAU,CAACM,KAAK;;IAE1C;IACA,MAAMC,gBAAuC,GAAGH,OAAO,CAACP,GAAG,CAACW,KAAK,IAAI;MACjE,OAAO;QACHC,EAAE,EAAED,KAAK,CAACE,OAAO;QACjBC,KAAK,EAAEH,KAAK,CAACI,MAAM,CAACD,KAAK;QACzBE,SAAS,EAAEL,KAAK,CAACI,MAAM,CAACC,SAAS;QACjCC,UAAU,EAAEN,KAAK,CAACI,MAAM,CAACE,UAAU;QACnCC,QAAQ,EAAEP,KAAK,CAACI,MAAM,CAACG,QAAQ;QAC/BC,WAAW,EAAER,KAAK,CAACI,MAAM,CAACI,WAAW;QACrCC,YAAY,EAAET,KAAK,CAACI,MAAM,CAACK,YAAY;QACvCC,OAAO,EAAEV,KAAK,CAACI,MAAM,CAACM,OAAO;QAC7Bf,KAAK,EAAEK,KAAK,CAACI,MAAM,CAACT;MACxB,CAAC;IACL,CAAC,CAAC;IAEF,OAAO3B,MAAM,CAAC2C,EAAE,CAAC;MACbC,KAAK,EAAEb,gBAAgB;MACvBF;IACJ,CAAC,CAAC;EACN;AACJ;AAEA,OAAO,MAAM3B,2BAA2B,GAAGC,kBAAkB,CAAC0C,oBAAoB,CAAC;EAC/EC,cAAc,EAAEtC,+BAA+B;EAC/CuC,YAAY,EAAE,CAAC9C,wBAAwB,EAAEG,oBAAoB,EAAEG,cAAc,EAAED,aAAa;AAChG,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import type { IScheduledAction } from "../../shared/abstractions.js";
|
|
3
|
+
import { ScheduledActionPersistenceError } from "../../domain/errors.js";
|
|
4
|
+
import type { CmsEntryListSort, CmsEntryMeta } from "@webiny/api-headless-cms/types/index.js";
|
|
5
|
+
import type { GenericRecord } from "@webiny/api/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* ListScheduledActionsUseCase - List scheduled actions with optional filtering
|
|
8
|
+
*
|
|
9
|
+
* Used to retrieve all scheduled actions for a namespace (e.g., all actions for Article model)
|
|
10
|
+
* or all actions of a specific type across namespaces.
|
|
11
|
+
*
|
|
12
|
+
* This is critical for CMS CRUD views where we need to show ALL scheduled actions
|
|
13
|
+
* (publish, unpublish, delete) for a specific content model.
|
|
14
|
+
*/
|
|
15
|
+
export type DateISOString = `${number}-${number}-${number}T${number}:${number}:${number}.${number}Z`;
|
|
16
|
+
export interface IListScheduledActionsWhere {
|
|
17
|
+
namespace?: string;
|
|
18
|
+
namespace_startsWith?: string;
|
|
19
|
+
actionType?: string;
|
|
20
|
+
targetId?: string;
|
|
21
|
+
targetId_startsWith?: string;
|
|
22
|
+
scheduledBy?: string;
|
|
23
|
+
scheduledFor?: DateISOString;
|
|
24
|
+
scheduledFor_gte?: DateISOString;
|
|
25
|
+
scheduledFor_lte?: DateISOString;
|
|
26
|
+
}
|
|
27
|
+
export interface IListScheduledActionsParams {
|
|
28
|
+
where: IListScheduledActionsWhere;
|
|
29
|
+
sort?: CmsEntryListSort;
|
|
30
|
+
limit?: number;
|
|
31
|
+
after?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface IListScheduledActionsResponse<T extends GenericRecord> {
|
|
34
|
+
items: IScheduledAction<T>[];
|
|
35
|
+
meta: CmsEntryMeta;
|
|
36
|
+
}
|
|
37
|
+
export interface IListScheduledActionsErrors {
|
|
38
|
+
persistence: ScheduledActionPersistenceError;
|
|
39
|
+
}
|
|
40
|
+
type ListScheduledActionsError = IListScheduledActionsErrors[keyof IListScheduledActionsErrors];
|
|
41
|
+
export interface IListScheduledActionsUseCase {
|
|
42
|
+
execute<T extends GenericRecord>(params: IListScheduledActionsParams): Promise<Result<IListScheduledActionsResponse<T>, ListScheduledActionsError>>;
|
|
43
|
+
}
|
|
44
|
+
export declare const ListScheduledActionsUseCase: import("@webiny/di").Abstraction<IListScheduledActionsUseCase>;
|
|
45
|
+
export declare namespace ListScheduledActionsUseCase {
|
|
46
|
+
type Interface = IListScheduledActionsUseCase;
|
|
47
|
+
type Error = ListScheduledActionsError;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createAbstraction } from "@webiny/feature/api";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ListScheduledActionsUseCase - List scheduled actions with optional filtering
|
|
5
|
+
*
|
|
6
|
+
* Used to retrieve all scheduled actions for a namespace (e.g., all actions for Article model)
|
|
7
|
+
* or all actions of a specific type across namespaces.
|
|
8
|
+
*
|
|
9
|
+
* This is critical for CMS CRUD views where we need to show ALL scheduled actions
|
|
10
|
+
* (publish, unpublish, delete) for a specific content model.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const ListScheduledActionsUseCase = createAbstraction("ListScheduledActionsUseCase");
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=abstractions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAbstraction","ListScheduledActionsUseCase"],"sources":["abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { IScheduledAction } from \"~/shared/abstractions.js\";\nimport { ScheduledActionPersistenceError } from \"~/domain/errors.js\";\nimport type { CmsEntryListSort, CmsEntryMeta } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\n/**\n * ListScheduledActionsUseCase - List scheduled actions with optional filtering\n *\n * Used to retrieve all scheduled actions for a namespace (e.g., all actions for Article model)\n * or all actions of a specific type across namespaces.\n *\n * This is critical for CMS CRUD views where we need to show ALL scheduled actions\n * (publish, unpublish, delete) for a specific content model.\n */\n\nexport type DateISOString =\n `${number}-${number}-${number}T${number}:${number}:${number}.${number}Z`;\n\nexport interface IListScheduledActionsWhere {\n namespace?: string;\n namespace_startsWith?: string;\n actionType?: string;\n targetId?: string;\n targetId_startsWith?: string;\n scheduledBy?: string;\n scheduledFor?: DateISOString;\n scheduledFor_gte?: DateISOString;\n scheduledFor_lte?: DateISOString;\n}\n\nexport interface IListScheduledActionsParams {\n where: IListScheduledActionsWhere;\n sort?: CmsEntryListSort;\n limit?: number;\n after?: string;\n}\n\nexport interface IListScheduledActionsResponse<T extends GenericRecord> {\n items: IScheduledAction<T>[];\n meta: CmsEntryMeta;\n}\n\nexport interface IListScheduledActionsErrors {\n persistence: ScheduledActionPersistenceError;\n}\n\ntype ListScheduledActionsError = IListScheduledActionsErrors[keyof IListScheduledActionsErrors];\n\nexport interface IListScheduledActionsUseCase {\n execute<T extends GenericRecord>(\n params: IListScheduledActionsParams\n ): Promise<Result<IListScheduledActionsResponse<T>, ListScheduledActionsError>>;\n}\n\nexport const ListScheduledActionsUseCase = createAbstraction<IListScheduledActionsUseCase>(\n \"ListScheduledActionsUseCase\"\n);\n\nexport namespace ListScheduledActionsUseCase {\n export type Interface = IListScheduledActionsUseCase;\n export type Error = ListScheduledActionsError;\n}\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,qBAAqB;;AAOvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyCA,OAAO,MAAMC,2BAA2B,GAAGD,iBAAiB,CACxD,6BACJ,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ListScheduledActions Feature
|
|
3
|
+
*
|
|
4
|
+
* Provides the ability to list scheduled actions with optional filtering by namespace or actionType.
|
|
5
|
+
* Critical for CMS CRUD views showing all scheduled actions for a content model.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ListScheduledActionsFeature: import("@webiny/feature/api/createFeature.js").FeatureDefinition<unknown>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { ListScheduledActionsUseCase } from "./ListScheduledActionsUseCase.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ListScheduledActions Feature
|
|
6
|
+
*
|
|
7
|
+
* Provides the ability to list scheduled actions with optional filtering by namespace or actionType.
|
|
8
|
+
* Critical for CMS CRUD views showing all scheduled actions for a content model.
|
|
9
|
+
*/
|
|
10
|
+
export const ListScheduledActionsFeature = createFeature({
|
|
11
|
+
name: "ListScheduledActions",
|
|
12
|
+
register(container) {
|
|
13
|
+
container.register(ListScheduledActionsUseCase);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createFeature","ListScheduledActionsUseCase","ListScheduledActionsFeature","name","register","container"],"sources":["feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { ListScheduledActionsUseCase } from \"./ListScheduledActionsUseCase.js\";\n\n/**\n * ListScheduledActions Feature\n *\n * Provides the ability to list scheduled actions with optional filtering by namespace or actionType.\n * Critical for CMS CRUD views showing all scheduled actions for a content model.\n */\nexport const ListScheduledActionsFeature = createFeature({\n name: \"ListScheduledActions\",\n register(container) {\n container.register(ListScheduledActionsUseCase);\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,2BAA2B;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,2BAA2B,GAAGF,aAAa,CAAC;EACrDG,IAAI,EAAE,sBAAsB;EAC5BC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACD,QAAQ,CAACH,2BAA2B,CAAC;EACnD;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./abstractions.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./abstractions.js\";\n"],"mappings":"AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { RunActionUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
3
|
+
import { ScheduleActionUseCase } from "../../features/ScheduleAction/abstractions.js";
|
|
4
|
+
import type { IScheduledAction } from "../../shared/abstractions.js";
|
|
5
|
+
import type { GenericRecord } from "@webiny/api/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Schedules an action for immediate execution
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* 1. Calculate the closest possible execution time
|
|
11
|
+
* 2. Delegate to ScheduleAction use case with calculated time
|
|
12
|
+
*
|
|
13
|
+
* Note: We add a small buffer to ensure EventBridge has time to process the schedule
|
|
14
|
+
*/
|
|
15
|
+
declare class RunActionUseCaseImpl implements UseCaseAbstraction.Interface {
|
|
16
|
+
private scheduleActionUseCase;
|
|
17
|
+
constructor(scheduleActionUseCase: ScheduleActionUseCase.Interface);
|
|
18
|
+
execute<T extends GenericRecord>(params: UseCaseAbstraction.Params<T>): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>>;
|
|
19
|
+
}
|
|
20
|
+
export declare const RunActionUseCase: typeof RunActionUseCaseImpl & {
|
|
21
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IRunActionUseCase>;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { RunActionUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
3
|
+
import { ScheduleActionUseCase } from "../ScheduleAction/abstractions.js";
|
|
4
|
+
/**
|
|
5
|
+
* Schedules an action for immediate execution
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Calculate the closest possible execution time
|
|
9
|
+
* 2. Delegate to ScheduleAction use case with calculated time
|
|
10
|
+
*
|
|
11
|
+
* Note: We add a small buffer to ensure EventBridge has time to process the schedule
|
|
12
|
+
*/
|
|
13
|
+
class RunActionUseCaseImpl {
|
|
14
|
+
constructor(scheduleActionUseCase) {
|
|
15
|
+
this.scheduleActionUseCase = scheduleActionUseCase;
|
|
16
|
+
}
|
|
17
|
+
async execute(params) {
|
|
18
|
+
// Delegate to ScheduleAction
|
|
19
|
+
const result = await this.scheduleActionUseCase.execute({
|
|
20
|
+
...params,
|
|
21
|
+
title: "Unknown title",
|
|
22
|
+
// Calculate the soonest possible execution time.
|
|
23
|
+
// Add at least 90 seconds of buffer to ensure EventBridge can process the schedule.
|
|
24
|
+
scheduleFor: new Date(Date.now() + 90000).toISOString()
|
|
25
|
+
});
|
|
26
|
+
if (result.isFail()) {
|
|
27
|
+
return Result.fail(result.error);
|
|
28
|
+
}
|
|
29
|
+
return Result.ok(result.value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export const RunActionUseCase = UseCaseAbstraction.createImplementation({
|
|
33
|
+
implementation: RunActionUseCaseImpl,
|
|
34
|
+
dependencies: [ScheduleActionUseCase]
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=RunActionUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Result","RunActionUseCase","UseCaseAbstraction","ScheduleActionUseCase","RunActionUseCaseImpl","constructor","scheduleActionUseCase","execute","params","result","title","scheduleFor","Date","now","toISOString","isFail","fail","error","ok","value","createImplementation","implementation","dependencies"],"sources":["RunActionUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { RunActionUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { ScheduleActionUseCase } from \"~/features/ScheduleAction/abstractions.js\";\nimport type { IScheduledAction } from \"~/shared/abstractions.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\n/**\n * Schedules an action for immediate execution\n *\n * Flow:\n * 1. Calculate the closest possible execution time\n * 2. Delegate to ScheduleAction use case with calculated time\n *\n * Note: We add a small buffer to ensure EventBridge has time to process the schedule\n */\nclass RunActionUseCaseImpl implements UseCaseAbstraction.Interface {\n constructor(private scheduleActionUseCase: ScheduleActionUseCase.Interface) {}\n\n async execute<T extends GenericRecord>(\n params: UseCaseAbstraction.Params<T>\n ): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>> {\n // Delegate to ScheduleAction\n const result = await this.scheduleActionUseCase.execute({\n ...params,\n title: \"Unknown title\",\n // Calculate the soonest possible execution time.\n // Add at least 90 seconds of buffer to ensure EventBridge can process the schedule.\n scheduleFor: new Date(Date.now() + 90000).toISOString()\n });\n\n if (result.isFail()) {\n return Result.fail(result.error);\n }\n\n return Result.ok(result.value);\n }\n}\n\nexport const RunActionUseCase = UseCaseAbstraction.createImplementation({\n implementation: RunActionUseCaseImpl,\n dependencies: [ScheduleActionUseCase]\n});\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,qBAAqB;AAC5C,SAASC,gBAAgB,IAAIC,kBAAkB;AAC/C,SAASC,qBAAqB;AAI9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,oBAAoB,CAAyC;EAC/DC,WAAWA,CAASC,qBAAsD,EAAE;IAAA,KAAxDA,qBAAsD,GAAtDA,qBAAsD;EAAG;EAE7E,MAAMC,OAAOA,CACTC,MAAoC,EAC0B;IAC9D;IACA,MAAMC,MAAM,GAAG,MAAM,IAAI,CAACH,qBAAqB,CAACC,OAAO,CAAC;MACpD,GAAGC,MAAM;MACTE,KAAK,EAAE,eAAe;MACtB;MACA;MACAC,WAAW,EAAE,IAAIC,IAAI,CAACA,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAACC,WAAW,CAAC;IAC1D,CAAC,CAAC;IAEF,IAAIL,MAAM,CAACM,MAAM,CAAC,CAAC,EAAE;MACjB,OAAOf,MAAM,CAACgB,IAAI,CAACP,MAAM,CAACQ,KAAK,CAAC;IACpC;IAEA,OAAOjB,MAAM,CAACkB,EAAE,CAACT,MAAM,CAACU,KAAK,CAAC;EAClC;AACJ;AAEA,OAAO,MAAMlB,gBAAgB,GAAGC,kBAAkB,CAACkB,oBAAoB,CAAC;EACpEC,cAAc,EAAEjB,oBAAoB;EACpCkB,YAAY,EAAE,CAACnB,qBAAqB;AACxC,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import type { IScheduledAction } from "../../shared/abstractions.js";
|
|
3
|
+
import { InvalidScheduleDateError, ScheduledActionPersistenceError, SchedulerServiceError } from "../../domain/errors.js";
|
|
4
|
+
import type { GenericRecord } from "@webiny/api/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* RunActionUseCase - Schedule an action for immediate execution
|
|
7
|
+
*
|
|
8
|
+
* This is a convenience use case that wraps ScheduleAction and automatically
|
|
9
|
+
* calculates the closest possible execution time (current time + small buffer).
|
|
10
|
+
*
|
|
11
|
+
* Use this when you want to execute an action "immediately" without having to manually
|
|
12
|
+
* calculate the schedule date.
|
|
13
|
+
*/
|
|
14
|
+
export interface IRunActionErrors {
|
|
15
|
+
persistence: ScheduledActionPersistenceError;
|
|
16
|
+
invalidDate: InvalidScheduleDateError;
|
|
17
|
+
schedulerService: SchedulerServiceError;
|
|
18
|
+
}
|
|
19
|
+
type RunActionError = IRunActionErrors[keyof IRunActionErrors];
|
|
20
|
+
interface IRunActionParams<T extends GenericRecord> {
|
|
21
|
+
namespace: string;
|
|
22
|
+
actionType: string;
|
|
23
|
+
targetId: string;
|
|
24
|
+
payload: T;
|
|
25
|
+
}
|
|
26
|
+
export interface IRunActionUseCase {
|
|
27
|
+
execute<T extends GenericRecord>(params: IRunActionParams<T>): Promise<Result<IScheduledAction<T>, RunActionError>>;
|
|
28
|
+
}
|
|
29
|
+
export declare const RunActionUseCase: import("@webiny/di").Abstraction<IRunActionUseCase>;
|
|
30
|
+
export declare namespace RunActionUseCase {
|
|
31
|
+
type Interface = IRunActionUseCase;
|
|
32
|
+
type Params<T extends GenericRecord> = IRunActionParams<T>;
|
|
33
|
+
type Error = RunActionError;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createAbstraction } from "@webiny/feature/api";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RunActionUseCase - Schedule an action for immediate execution
|
|
5
|
+
*
|
|
6
|
+
* This is a convenience use case that wraps ScheduleAction and automatically
|
|
7
|
+
* calculates the closest possible execution time (current time + small buffer).
|
|
8
|
+
*
|
|
9
|
+
* Use this when you want to execute an action "immediately" without having to manually
|
|
10
|
+
* calculate the schedule date.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const RunActionUseCase = createAbstraction("RunActionUseCase");
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=abstractions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAbstraction","RunActionUseCase"],"sources":["abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { IScheduledAction } from \"~/shared/abstractions.js\";\nimport {\n InvalidScheduleDateError,\n ScheduledActionPersistenceError,\n SchedulerServiceError\n} from \"~/domain/errors.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\n/**\n * RunActionUseCase - Schedule an action for immediate execution\n *\n * This is a convenience use case that wraps ScheduleAction and automatically\n * calculates the closest possible execution time (current time + small buffer).\n *\n * Use this when you want to execute an action \"immediately\" without having to manually\n * calculate the schedule date.\n */\n\nexport interface IRunActionErrors {\n persistence: ScheduledActionPersistenceError;\n invalidDate: InvalidScheduleDateError;\n schedulerService: SchedulerServiceError;\n}\n\ntype RunActionError = IRunActionErrors[keyof IRunActionErrors];\n\ninterface IRunActionParams<T extends GenericRecord> {\n namespace: string;\n actionType: string;\n targetId: string;\n payload: T;\n}\n\nexport interface IRunActionUseCase {\n execute<T extends GenericRecord>(\n params: IRunActionParams<T>\n ): Promise<Result<IScheduledAction<T>, RunActionError>>;\n}\n\nexport const RunActionUseCase = createAbstraction<IRunActionUseCase>(\"RunActionUseCase\");\n\nexport namespace RunActionUseCase {\n export type Interface = IRunActionUseCase;\n export type Params<T extends GenericRecord> = IRunActionParams<T>;\n export type Error = RunActionError;\n}\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAgB,qBAAqB;;AAS/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuBA,OAAO,MAAMC,gBAAgB,GAAGD,iBAAiB,CAAoB,kBAAkB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunAction Feature
|
|
3
|
+
*
|
|
4
|
+
* Provides the ability to schedule an action for immediate execution
|
|
5
|
+
* without having to manually calculate the schedule date.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RunActionFeature: import("@webiny/feature/api/createFeature.js").FeatureDefinition<unknown>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { RunActionUseCase } from "./RunActionUseCase.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* RunAction Feature
|
|
6
|
+
*
|
|
7
|
+
* Provides the ability to schedule an action for immediate execution
|
|
8
|
+
* without having to manually calculate the schedule date.
|
|
9
|
+
*/
|
|
10
|
+
export const RunActionFeature = createFeature({
|
|
11
|
+
name: "RunAction",
|
|
12
|
+
register(container) {
|
|
13
|
+
container.register(RunActionUseCase);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createFeature","RunActionUseCase","RunActionFeature","name","register","container"],"sources":["feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { RunActionUseCase } from \"./RunActionUseCase.js\";\n\n/**\n * RunAction Feature\n *\n * Provides the ability to schedule an action for immediate execution\n * without having to manually calculate the schedule date.\n */\nexport const RunActionFeature = createFeature({\n name: \"RunAction\",\n register(container) {\n container.register(RunActionUseCase);\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,gBAAgB;;AAEzB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,gBAAgB,GAAGF,aAAa,CAAC;EAC1CG,IAAI,EAAE,WAAW;EACjBC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACD,QAAQ,CAACH,gBAAgB,CAAC;EACxC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./abstractions.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./abstractions.js\";\n"],"mappings":"AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
3
|
+
import { CreateEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/CreateEntry/index.js";
|
|
4
|
+
import { UpdateEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/UpdateEntry/index.js";
|
|
5
|
+
import { DeleteEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/DeleteEntry/index.js";
|
|
6
|
+
import { ScheduleActionUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
7
|
+
import { GetScheduledActionUseCase } from "../../features/GetScheduledAction/abstractions.js";
|
|
8
|
+
import type { IScheduledAction } from "../../shared/abstractions.js";
|
|
9
|
+
import { ScheduledActionModel, SchedulerService } from "../../shared/abstractions.js";
|
|
10
|
+
import type { GenericRecord } from "@webiny/api/types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Schedules an action for future execution
|
|
13
|
+
*
|
|
14
|
+
* Flow:
|
|
15
|
+
* 1. Generate unique schedule ID from namespace+actionType+targetId
|
|
16
|
+
* 2. Check if schedule already exists (for rescheduling logic)
|
|
17
|
+
* 3. If exists: UPDATE schedule entry + EventBridge schedule
|
|
18
|
+
* 4. If new: CREATE schedule entry + EventBridge schedule
|
|
19
|
+
* 5. Rollback schedule entry if EventBridge fails
|
|
20
|
+
*
|
|
21
|
+
* Note: Does NOT handle immediate execution - apps use direct use cases for that
|
|
22
|
+
*/
|
|
23
|
+
declare class ScheduleActionUseCaseImpl implements UseCaseAbstraction.Interface {
|
|
24
|
+
private identityContext;
|
|
25
|
+
private model;
|
|
26
|
+
private schedulerService;
|
|
27
|
+
private getScheduledAction;
|
|
28
|
+
private createEntryUseCase;
|
|
29
|
+
private updateEntryUseCase;
|
|
30
|
+
private deleteEntryUseCase;
|
|
31
|
+
constructor(identityContext: IdentityContext.Interface, model: ScheduledActionModel.Interface, schedulerService: SchedulerService.Interface, getScheduledAction: GetScheduledActionUseCase.Interface, createEntryUseCase: CreateEntryUseCase.Interface, updateEntryUseCase: UpdateEntryUseCase.Interface, deleteEntryUseCase: DeleteEntryUseCase.Interface);
|
|
32
|
+
execute<T extends GenericRecord>(params: UseCaseAbstraction.Params<T>): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>>;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new schedule
|
|
35
|
+
*/
|
|
36
|
+
private createSchedule;
|
|
37
|
+
/**
|
|
38
|
+
* Updates an existing schedule (reschedule)
|
|
39
|
+
*/
|
|
40
|
+
private reschedule;
|
|
41
|
+
}
|
|
42
|
+
export declare const ScheduleActionUseCase: typeof ScheduleActionUseCaseImpl & {
|
|
43
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IScheduleActionUseCase>;
|
|
44
|
+
};
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
3
|
+
import { CreateEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/CreateEntry/index.js";
|
|
4
|
+
import { UpdateEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/UpdateEntry/index.js";
|
|
5
|
+
import { DeleteEntryUseCase } from "@webiny/api-headless-cms/features/contentEntry/DeleteEntry/index.js";
|
|
6
|
+
import { parseIdentifier } from "@webiny/utils";
|
|
7
|
+
import { ScheduleActionUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
8
|
+
import { GetScheduledActionUseCase } from "../GetScheduledAction/abstractions.js";
|
|
9
|
+
import { ScheduledActionModel, SchedulerService } from "../../shared/abstractions.js";
|
|
10
|
+
import { InvalidScheduleDateError, ScheduledActionPersistenceError, SchedulerServiceError } from "../../domain/errors.js";
|
|
11
|
+
import { ScheduledActionId } from "../../domain/ScheduledActionId.js";
|
|
12
|
+
import { ScheduledActionIdWithVersion } from "../../domain/ScheduledActionIdWithVersion.js";
|
|
13
|
+
import { isValidDate } from "../../domain/isValidDate.js";
|
|
14
|
+
/**
|
|
15
|
+
* Schedules an action for future execution
|
|
16
|
+
*
|
|
17
|
+
* Flow:
|
|
18
|
+
* 1. Generate unique schedule ID from namespace+actionType+targetId
|
|
19
|
+
* 2. Check if schedule already exists (for rescheduling logic)
|
|
20
|
+
* 3. If exists: UPDATE schedule entry + EventBridge schedule
|
|
21
|
+
* 4. If new: CREATE schedule entry + EventBridge schedule
|
|
22
|
+
* 5. Rollback schedule entry if EventBridge fails
|
|
23
|
+
*
|
|
24
|
+
* Note: Does NOT handle immediate execution - apps use direct use cases for that
|
|
25
|
+
*/
|
|
26
|
+
class ScheduleActionUseCaseImpl {
|
|
27
|
+
constructor(identityContext, model, schedulerService, getScheduledAction, createEntryUseCase, updateEntryUseCase, deleteEntryUseCase) {
|
|
28
|
+
this.identityContext = identityContext;
|
|
29
|
+
this.model = model;
|
|
30
|
+
this.schedulerService = schedulerService;
|
|
31
|
+
this.getScheduledAction = getScheduledAction;
|
|
32
|
+
this.createEntryUseCase = createEntryUseCase;
|
|
33
|
+
this.updateEntryUseCase = updateEntryUseCase;
|
|
34
|
+
this.deleteEntryUseCase = deleteEntryUseCase;
|
|
35
|
+
}
|
|
36
|
+
async execute(params) {
|
|
37
|
+
const identity = this.identityContext.getIdentity();
|
|
38
|
+
if (!isValidDate(params.scheduleFor)) {
|
|
39
|
+
return Result.fail(new InvalidScheduleDateError(params.scheduleFor));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Generate unique schedule ID
|
|
43
|
+
const actionId = ScheduledActionId.from(params);
|
|
44
|
+
const scheduleId = ScheduledActionIdWithVersion.from(actionId);
|
|
45
|
+
const existingResult = await this.getScheduledAction.execute(scheduleId);
|
|
46
|
+
if (existingResult.isFail()) {
|
|
47
|
+
const error = existingResult.error;
|
|
48
|
+
|
|
49
|
+
// NotFound means the action was not yet scheduled
|
|
50
|
+
if (error.code === "Scheduler/ScheduledAction/NotFound") {
|
|
51
|
+
return this.createSchedule(scheduleId, params.title, params.namespace, params.actionType, params.targetId, params.scheduleFor, identity, params.payload);
|
|
52
|
+
}
|
|
53
|
+
if (error.code === "Scheduler/ScheduledAction/PersistenceError") {
|
|
54
|
+
return Result.fail(error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Reschedule existing action
|
|
59
|
+
const scheduledAction = existingResult.value;
|
|
60
|
+
return this.reschedule(scheduledAction, params.scheduleFor, identity, params.payload);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a new schedule
|
|
65
|
+
*/
|
|
66
|
+
async createSchedule(id, title, namespace, actionType, targetId, scheduleFor, identity, payload) {
|
|
67
|
+
const {
|
|
68
|
+
id: scheduleId
|
|
69
|
+
} = parseIdentifier(id);
|
|
70
|
+
const scheduledAction = {
|
|
71
|
+
id: scheduleId,
|
|
72
|
+
title,
|
|
73
|
+
namespace,
|
|
74
|
+
actionType,
|
|
75
|
+
targetId,
|
|
76
|
+
scheduledBy: {
|
|
77
|
+
id: identity.id,
|
|
78
|
+
type: identity.type,
|
|
79
|
+
displayName: identity.displayName
|
|
80
|
+
},
|
|
81
|
+
scheduledFor: scheduleFor,
|
|
82
|
+
payload
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Create CMS entry
|
|
86
|
+
const createResult = await this.createEntryUseCase.execute(this.model, {
|
|
87
|
+
id: scheduleId,
|
|
88
|
+
values: scheduledAction
|
|
89
|
+
});
|
|
90
|
+
if (createResult.isFail()) {
|
|
91
|
+
return Result.fail(new ScheduledActionPersistenceError(new Error(createResult.error.message)));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Create EventBridge schedule
|
|
95
|
+
try {
|
|
96
|
+
await this.schedulerService.create({
|
|
97
|
+
id: scheduleId,
|
|
98
|
+
scheduleFor: new Date(scheduleFor)
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
// Rollback - delete CMS entry if EventBridge fails
|
|
102
|
+
console.error(`Failed to create EventBridge schedule: ${scheduleId}. Rolling back...`);
|
|
103
|
+
await this.deleteEntryUseCase.execute(this.model, scheduleId, {
|
|
104
|
+
force: true,
|
|
105
|
+
permanently: true
|
|
106
|
+
});
|
|
107
|
+
return Result.fail(new SchedulerServiceError(error));
|
|
108
|
+
}
|
|
109
|
+
return Result.ok(scheduledAction);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Updates an existing schedule (reschedule)
|
|
114
|
+
*/
|
|
115
|
+
async reschedule(existing, scheduleFor, identity, payload) {
|
|
116
|
+
// Make sure we don't unset the existing payload.
|
|
117
|
+
if (!payload && existing.payload) {
|
|
118
|
+
payload = existing.payload;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Update CMS entry
|
|
122
|
+
const existingEntryId = ScheduledActionIdWithVersion.from(existing.id);
|
|
123
|
+
const updateResult = await this.updateEntryUseCase.execute(this.model, existingEntryId, {
|
|
124
|
+
values: {
|
|
125
|
+
scheduledBy: {
|
|
126
|
+
id: identity.id,
|
|
127
|
+
type: identity.type,
|
|
128
|
+
displayName: identity.displayName
|
|
129
|
+
},
|
|
130
|
+
scheduledFor: scheduleFor,
|
|
131
|
+
payload
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
if (updateResult.isFail()) {
|
|
135
|
+
return Result.fail(new ScheduledActionPersistenceError(new Error(updateResult.error.message)));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Update EventBridge schedule
|
|
139
|
+
try {
|
|
140
|
+
await this.schedulerService.update({
|
|
141
|
+
id: existing.id,
|
|
142
|
+
scheduleFor: new Date(scheduleFor)
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return Result.fail(new SchedulerServiceError(error));
|
|
146
|
+
}
|
|
147
|
+
return Result.ok({
|
|
148
|
+
...existing,
|
|
149
|
+
scheduledBy: {
|
|
150
|
+
id: identity.id,
|
|
151
|
+
type: identity.type,
|
|
152
|
+
displayName: identity.displayName
|
|
153
|
+
},
|
|
154
|
+
scheduledFor: scheduleFor,
|
|
155
|
+
payload
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
export const ScheduleActionUseCase = UseCaseAbstraction.createImplementation({
|
|
160
|
+
implementation: ScheduleActionUseCaseImpl,
|
|
161
|
+
dependencies: [IdentityContext, ScheduledActionModel, SchedulerService, GetScheduledActionUseCase, CreateEntryUseCase, UpdateEntryUseCase, DeleteEntryUseCase]
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=ScheduleActionUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Result","IdentityContext","CreateEntryUseCase","UpdateEntryUseCase","DeleteEntryUseCase","parseIdentifier","ScheduleActionUseCase","UseCaseAbstraction","GetScheduledActionUseCase","ScheduledActionModel","SchedulerService","InvalidScheduleDateError","ScheduledActionPersistenceError","SchedulerServiceError","ScheduledActionId","ScheduledActionIdWithVersion","isValidDate","ScheduleActionUseCaseImpl","constructor","identityContext","model","schedulerService","getScheduledAction","createEntryUseCase","updateEntryUseCase","deleteEntryUseCase","execute","params","identity","getIdentity","scheduleFor","fail","actionId","from","scheduleId","existingResult","isFail","error","code","createSchedule","title","namespace","actionType","targetId","payload","scheduledAction","value","reschedule","id","scheduledBy","type","displayName","scheduledFor","createResult","values","Error","message","create","Date","console","force","permanently","ok","existing","existingEntryId","updateResult","update","createImplementation","implementation","dependencies"],"sources":["ScheduleActionUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { CreateEntryUseCase } from \"@webiny/api-headless-cms/features/contentEntry/CreateEntry/index.js\";\nimport { UpdateEntryUseCase } from \"@webiny/api-headless-cms/features/contentEntry/UpdateEntry/index.js\";\nimport { DeleteEntryUseCase } from \"@webiny/api-headless-cms/features/contentEntry/DeleteEntry/index.js\";\nimport { parseIdentifier } from \"@webiny/utils\";\nimport { ScheduleActionUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport { GetScheduledActionUseCase } from \"~/features/GetScheduledAction/abstractions.js\";\nimport type { Identity, IScheduledAction } from \"~/shared/abstractions.js\";\nimport { ScheduledActionModel, SchedulerService } from \"~/shared/abstractions.js\";\nimport {\n InvalidScheduleDateError,\n ScheduledActionPersistenceError,\n SchedulerServiceError\n} from \"~/domain/errors.js\";\nimport { ScheduledActionId } from \"~/domain/ScheduledActionId.js\";\nimport { ScheduledActionIdWithVersion } from \"~/domain/ScheduledActionIdWithVersion.js\";\nimport { isValidDate } from \"~/domain/isValidDate.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\n/**\n * Schedules an action for future execution\n *\n * Flow:\n * 1. Generate unique schedule ID from namespace+actionType+targetId\n * 2. Check if schedule already exists (for rescheduling logic)\n * 3. If exists: UPDATE schedule entry + EventBridge schedule\n * 4. If new: CREATE schedule entry + EventBridge schedule\n * 5. Rollback schedule entry if EventBridge fails\n *\n * Note: Does NOT handle immediate execution - apps use direct use cases for that\n */\nclass ScheduleActionUseCaseImpl implements UseCaseAbstraction.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private model: ScheduledActionModel.Interface,\n private schedulerService: SchedulerService.Interface,\n private getScheduledAction: GetScheduledActionUseCase.Interface,\n private createEntryUseCase: CreateEntryUseCase.Interface,\n private updateEntryUseCase: UpdateEntryUseCase.Interface,\n private deleteEntryUseCase: DeleteEntryUseCase.Interface\n ) {}\n\n async execute<T extends GenericRecord>(\n params: UseCaseAbstraction.Params<T>\n ): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>> {\n const identity = this.identityContext.getIdentity();\n\n if (!isValidDate(params.scheduleFor)) {\n return Result.fail(new InvalidScheduleDateError(params.scheduleFor));\n }\n\n // Generate unique schedule ID\n const actionId = ScheduledActionId.from(params);\n const scheduleId = ScheduledActionIdWithVersion.from(actionId);\n\n const existingResult = await this.getScheduledAction.execute(scheduleId);\n\n if (existingResult.isFail()) {\n const error = existingResult.error;\n\n // NotFound means the action was not yet scheduled\n if (error.code === \"Scheduler/ScheduledAction/NotFound\") {\n return this.createSchedule(\n scheduleId,\n params.title,\n params.namespace,\n params.actionType,\n params.targetId,\n params.scheduleFor,\n identity,\n params.payload\n );\n }\n\n if (error.code === \"Scheduler/ScheduledAction/PersistenceError\") {\n return Result.fail(error);\n }\n }\n\n // Reschedule existing action\n const scheduledAction = existingResult.value;\n\n return this.reschedule(scheduledAction, params.scheduleFor, identity, params.payload);\n }\n\n /**\n * Creates a new schedule\n */\n private async createSchedule<T extends GenericRecord>(\n id: string,\n title: string,\n namespace: string,\n actionType: string,\n targetId: string,\n scheduleFor: string,\n identity: Identity,\n payload: T\n ): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>> {\n const { id: scheduleId } = parseIdentifier(id);\n\n const scheduledAction: IScheduledAction<T> = {\n id: scheduleId,\n title,\n namespace,\n actionType,\n targetId,\n scheduledBy: {\n id: identity.id,\n type: identity.type,\n displayName: identity.displayName\n },\n scheduledFor: scheduleFor,\n payload\n };\n\n // Create CMS entry\n const createResult = await this.createEntryUseCase.execute<IScheduledAction<T>>(\n this.model,\n {\n id: scheduleId,\n values: scheduledAction\n }\n );\n\n if (createResult.isFail()) {\n return Result.fail(\n new ScheduledActionPersistenceError(new Error(createResult.error.message))\n );\n }\n\n // Create EventBridge schedule\n try {\n await this.schedulerService.create({\n id: scheduleId,\n scheduleFor: new Date(scheduleFor)\n });\n } catch (error) {\n // Rollback - delete CMS entry if EventBridge fails\n console.error(`Failed to create EventBridge schedule: ${scheduleId}. Rolling back...`);\n\n await this.deleteEntryUseCase.execute(this.model, scheduleId, {\n force: true,\n permanently: true\n });\n\n return Result.fail(new SchedulerServiceError(error as Error));\n }\n\n return Result.ok(scheduledAction);\n }\n\n /**\n * Updates an existing schedule (reschedule)\n */\n private async reschedule<T extends GenericRecord>(\n existing: IScheduledAction<T>,\n scheduleFor: string,\n identity: Identity,\n payload?: any\n ): Promise<Result<IScheduledAction<T>, UseCaseAbstraction.Error>> {\n // Make sure we don't unset the existing payload.\n if (!payload && existing.payload) {\n payload = existing.payload;\n }\n\n // Update CMS entry\n const existingEntryId = ScheduledActionIdWithVersion.from(existing.id);\n const updateResult = await this.updateEntryUseCase.execute<IScheduledAction<T>>(\n this.model,\n existingEntryId,\n {\n values: {\n scheduledBy: {\n id: identity.id,\n type: identity.type,\n displayName: identity.displayName\n },\n scheduledFor: scheduleFor,\n payload\n }\n }\n );\n\n if (updateResult.isFail()) {\n return Result.fail(\n new ScheduledActionPersistenceError(new Error(updateResult.error.message))\n );\n }\n\n // Update EventBridge schedule\n try {\n await this.schedulerService.update({\n id: existing.id,\n scheduleFor: new Date(scheduleFor)\n });\n } catch (error) {\n return Result.fail(new SchedulerServiceError(error as Error));\n }\n\n return Result.ok({\n ...existing,\n scheduledBy: {\n id: identity.id,\n type: identity.type,\n displayName: identity.displayName\n },\n scheduledFor: scheduleFor,\n payload\n });\n }\n}\n\nexport const ScheduleActionUseCase = UseCaseAbstraction.createImplementation({\n implementation: ScheduleActionUseCaseImpl,\n dependencies: [\n IdentityContext,\n ScheduledActionModel,\n SchedulerService,\n GetScheduledActionUseCase,\n CreateEntryUseCase,\n UpdateEntryUseCase,\n DeleteEntryUseCase\n ]\n});\n"],"mappings":"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","ignoreList":[]}
|