@webiny/api-headless-cms-tasks 0.0.0-unstable.3bc8100a7f
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 +15 -0
- package/index.d.ts +3 -0
- package/index.js +19 -0
- package/index.js.map +1 -0
- package/package.json +48 -0
- package/tasks/deleteModel/DeleteModelRunner.d.ts +19 -0
- package/tasks/deleteModel/DeleteModelRunner.js +139 -0
- package/tasks/deleteModel/DeleteModelRunner.js.map +1 -0
- package/tasks/deleteModel/constants.d.ts +1 -0
- package/tasks/deleteModel/constants.js +9 -0
- package/tasks/deleteModel/constants.js.map +1 -0
- package/tasks/deleteModel/graphql/attachLifecycleEvents.d.ts +5 -0
- package/tasks/deleteModel/graphql/attachLifecycleEvents.js +40 -0
- package/tasks/deleteModel/graphql/attachLifecycleEvents.js.map +1 -0
- package/tasks/deleteModel/graphql/cancelDeleteModel.d.ts +7 -0
- package/tasks/deleteModel/graphql/cancelDeleteModel.js +64 -0
- package/tasks/deleteModel/graphql/cancelDeleteModel.js.map +1 -0
- package/tasks/deleteModel/graphql/crud.d.ts +3 -0
- package/tasks/deleteModel/graphql/crud.js +82 -0
- package/tasks/deleteModel/graphql/crud.js.map +1 -0
- package/tasks/deleteModel/graphql/fullyDeleteModel.d.ts +7 -0
- package/tasks/deleteModel/graphql/fullyDeleteModel.js +57 -0
- package/tasks/deleteModel/graphql/fullyDeleteModel.js.map +1 -0
- package/tasks/deleteModel/graphql/getDeleteModelProgress.d.ts +7 -0
- package/tasks/deleteModel/graphql/getDeleteModelProgress.js +66 -0
- package/tasks/deleteModel/graphql/getDeleteModelProgress.js.map +1 -0
- package/tasks/deleteModel/graphql/index.d.ts +3 -0
- package/tasks/deleteModel/graphql/index.js +166 -0
- package/tasks/deleteModel/graphql/index.js.map +1 -0
- package/tasks/deleteModel/graphql/isModelBeingDeleted.d.ts +5 -0
- package/tasks/deleteModel/graphql/isModelBeingDeleted.js +15 -0
- package/tasks/deleteModel/graphql/isModelBeingDeleted.js.map +1 -0
- package/tasks/deleteModel/graphql/status.d.ts +3 -0
- package/tasks/deleteModel/graphql/status.js +24 -0
- package/tasks/deleteModel/graphql/status.js.map +1 -0
- package/tasks/deleteModel/helpers/confirmation.d.ts +6 -0
- package/tasks/deleteModel/helpers/confirmation.js +23 -0
- package/tasks/deleteModel/helpers/confirmation.js.map +1 -0
- package/tasks/deleteModel/helpers/store.d.ts +10 -0
- package/tasks/deleteModel/helpers/store.js +26 -0
- package/tasks/deleteModel/helpers/store.js.map +1 -0
- package/tasks/deleteModel/index.d.ts +3 -0
- package/tasks/deleteModel/index.js +50 -0
- package/tasks/deleteModel/index.js.map +1 -0
- package/tasks/deleteModel/types.d.ts +33 -0
- package/tasks/deleteModel/types.js +15 -0
- package/tasks/deleteModel/types.js.map +1 -0
- package/types.d.ts +14 -0
- package/types.js +7 -0
- package/types.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Webiny
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @webiny/api-headless-cms-tasks
|
|
2
|
+
[](https://www.npmjs.com/package/@webiny/api-headless-cms-tasks)
|
|
3
|
+
[](https://www.npmjs.com/package/@webiny/api-headless-cms-tasks)
|
|
4
|
+
[](https://github.com/prettier/prettier)
|
|
5
|
+
[](http://makeapullrequest.com)
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
```
|
|
9
|
+
npm install --save @webiny/api-headless-cms-tasks
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or if you prefer yarn:
|
|
13
|
+
```
|
|
14
|
+
yarn add @webiny/api-headless-cms-tasks
|
|
15
|
+
```
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { createDeleteModelTask } from "./tasks/deleteModel";
|
|
2
|
+
export { createDeleteModelTask };
|
|
3
|
+
export declare const createHcmsTasks: () => (import("@webiny/tasks").TaskDefinitionPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext, import("@webiny/api-headless-cms-bulk-actions/types").IEmptyTrashBinsInput, import("@webiny/tasks").ITaskResponseDoneResultOutput> | (import("@webiny/api").ContextPlugin<import("./types").HcmsTasksContext> | import("@webiny/tasks").TaskDefinitionPlugin<import("./types").HcmsTasksContext, import("./tasks/deleteModel/types").IDeleteModelTaskInput, import("./tasks/deleteModel/types").IDeleteModelTaskOutput>)[] | (import("@webiny/api").ContextPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext> | (import("@webiny/handler-aws").EventBridgeEventHandler<"WebinyEmptyTrashBin", Record<string, any>, any> | import("@webiny/handler").HandlerOnRequestPlugin<import("@webiny/handler/types").Context>)[])[] | (import("@webiny/api").ContextPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext> | (import("@webiny/tasks").TaskDefinitionPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext, import("@webiny/api-headless-cms-bulk-actions/types").IBulkActionOperationByModelInput, import("@webiny/api-headless-cms-bulk-actions/types").IBulkActionOperationByModelOutput> | import("@webiny/tasks").TaskDefinitionPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext, import("@webiny/api-headless-cms-bulk-actions/types").IBulkActionOperationInput, import("@webiny/api-headless-cms-bulk-actions/types").IBulkActionOperationOutput>)[])[][] | import("@webiny/plugins/types").Plugin[])[];
|
package/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "createDeleteModelTask", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _deleteModel.createDeleteModelTask;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.createHcmsTasks = void 0;
|
|
13
|
+
var _apiHeadlessCmsBulkActions = require("@webiny/api-headless-cms-bulk-actions");
|
|
14
|
+
var _apiHeadlessCmsImportExport = require("@webiny/api-headless-cms-import-export");
|
|
15
|
+
var _deleteModel = require("./tasks/deleteModel");
|
|
16
|
+
const createHcmsTasks = () => [(0, _apiHeadlessCmsBulkActions.createHcmsBulkActions)(), (0, _apiHeadlessCmsBulkActions.createBulkActionEntriesTasks)(), (0, _apiHeadlessCmsBulkActions.createEmptyTrashBinsTask)(), (0, _apiHeadlessCmsImportExport.createHeadlessCmsImportExport)(), (0, _deleteModel.createDeleteModelTask)()];
|
|
17
|
+
exports.createHcmsTasks = createHcmsTasks;
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_apiHeadlessCmsBulkActions","require","_apiHeadlessCmsImportExport","_deleteModel","createHcmsTasks","createHcmsBulkActions","createBulkActionEntriesTasks","createEmptyTrashBinsTask","createHeadlessCmsImportExport","createDeleteModelTask","exports"],"sources":["index.ts"],"sourcesContent":["import {\n createBulkActionEntriesTasks,\n createEmptyTrashBinsTask,\n createHcmsBulkActions\n} from \"@webiny/api-headless-cms-bulk-actions\";\nimport { createHeadlessCmsImportExport } from \"@webiny/api-headless-cms-import-export\";\nimport { createDeleteModelTask } from \"~/tasks/deleteModel\";\n\nexport { createDeleteModelTask };\n\nexport const createHcmsTasks = () => [\n createHcmsBulkActions(),\n createBulkActionEntriesTasks(),\n createEmptyTrashBinsTask(),\n createHeadlessCmsImportExport(),\n createDeleteModelTask()\n];\n"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,0BAAA,GAAAC,OAAA;AAKA,IAAAC,2BAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA;AAIO,MAAMG,eAAe,GAAGA,CAAA,KAAM,CACjC,IAAAC,gDAAqB,EAAC,CAAC,EACvB,IAAAC,uDAA4B,EAAC,CAAC,EAC9B,IAAAC,mDAAwB,EAAC,CAAC,EAC1B,IAAAC,yDAA6B,EAAC,CAAC,EAC/B,IAAAC,kCAAqB,EAAC,CAAC,CAC1B;AAACC,OAAA,CAAAN,eAAA,GAAAA,eAAA","ignoreList":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@webiny/api-headless-cms-tasks",
|
|
3
|
+
"version": "0.0.0-unstable.3bc8100a7f",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"description": "Background tasks for Webiny Headless CMS",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"api-headless-cms-tasks:base"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/webiny/webiny-js.git",
|
|
12
|
+
"directory": "packages/api-headless-cms-tasks"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@webiny/api": "0.0.0-unstable.3bc8100a7f",
|
|
17
|
+
"@webiny/api-aco": "0.0.0-unstable.3bc8100a7f",
|
|
18
|
+
"@webiny/api-headless-cms": "0.0.0-unstable.3bc8100a7f",
|
|
19
|
+
"@webiny/api-headless-cms-bulk-actions": "0.0.0-unstable.3bc8100a7f",
|
|
20
|
+
"@webiny/api-headless-cms-import-export": "0.0.0-unstable.3bc8100a7f",
|
|
21
|
+
"@webiny/db": "0.0.0-unstable.3bc8100a7f",
|
|
22
|
+
"@webiny/error": "0.0.0-unstable.3bc8100a7f",
|
|
23
|
+
"@webiny/handler-graphql": "0.0.0-unstable.3bc8100a7f",
|
|
24
|
+
"@webiny/tasks": "0.0.0-unstable.3bc8100a7f",
|
|
25
|
+
"@webiny/utils": "0.0.0-unstable.3bc8100a7f",
|
|
26
|
+
"zod": "3.23.8"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@webiny/api-i18n": "0.0.0-unstable.3bc8100a7f",
|
|
30
|
+
"@webiny/api-security": "0.0.0-unstable.3bc8100a7f",
|
|
31
|
+
"@webiny/api-tenancy": "0.0.0-unstable.3bc8100a7f",
|
|
32
|
+
"@webiny/api-wcp": "0.0.0-unstable.3bc8100a7f",
|
|
33
|
+
"@webiny/handler": "0.0.0-unstable.3bc8100a7f",
|
|
34
|
+
"@webiny/handler-aws": "0.0.0-unstable.3bc8100a7f",
|
|
35
|
+
"@webiny/plugins": "0.0.0-unstable.3bc8100a7f",
|
|
36
|
+
"@webiny/project-utils": "0.0.0-unstable.3bc8100a7f",
|
|
37
|
+
"typescript": "5.3.3"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "node ../cli/bin.js run build",
|
|
41
|
+
"watch": "node ../cli/bin.js run watch"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"directory": "dist"
|
|
46
|
+
},
|
|
47
|
+
"gitHead": "3bc8100a7f1fb3a8d6a3454a2765f8ef377c279e"
|
|
48
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ITaskResponse, ITaskResponseResult, ITaskRunParams } from "@webiny/tasks";
|
|
2
|
+
import type { HcmsTasksContext } from "../../types";
|
|
3
|
+
import type { IDeleteModelTaskInput, IDeleteModelTaskOutput } from "./types";
|
|
4
|
+
export interface IDeleteModelRunnerParams<C extends HcmsTasksContext, I extends IDeleteModelTaskInput, O extends IDeleteModelTaskOutput> {
|
|
5
|
+
taskId: string;
|
|
6
|
+
context: C;
|
|
7
|
+
response: ITaskResponse<I, O>;
|
|
8
|
+
}
|
|
9
|
+
export type IExecuteParams<C extends HcmsTasksContext, I extends IDeleteModelTaskInput, O extends IDeleteModelTaskOutput> = Omit<ITaskRunParams<C, I, O>, "context" | "response" | "store" | "timer" | "trigger">;
|
|
10
|
+
export declare class DeleteModelRunner<C extends HcmsTasksContext, I extends IDeleteModelTaskInput, O extends IDeleteModelTaskOutput> {
|
|
11
|
+
private readonly taskId;
|
|
12
|
+
private readonly context;
|
|
13
|
+
private readonly response;
|
|
14
|
+
constructor(params: IDeleteModelRunnerParams<C, I, O>);
|
|
15
|
+
execute(params: IExecuteParams<C, I, O>): Promise<ITaskResponseResult<I, O>>;
|
|
16
|
+
private getModel;
|
|
17
|
+
private removeBeingDeleted;
|
|
18
|
+
}
|
|
19
|
+
export declare const createDeleteModelRunner: <C extends HcmsTasksContext, I extends IDeleteModelTaskInput, O extends IDeleteModelTaskOutput>(params: IDeleteModelRunnerParams<C, I, O>) => DeleteModelRunner<C, I, O>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createDeleteModelRunner = exports.DeleteModelRunner = void 0;
|
|
7
|
+
var _store = require("./helpers/store");
|
|
8
|
+
class DeleteModelRunner {
|
|
9
|
+
constructor(params) {
|
|
10
|
+
this.taskId = params.taskId;
|
|
11
|
+
this.context = params.context;
|
|
12
|
+
this.response = params.response;
|
|
13
|
+
}
|
|
14
|
+
async execute(params) {
|
|
15
|
+
const {
|
|
16
|
+
input,
|
|
17
|
+
isCloseToTimeout,
|
|
18
|
+
isAborted
|
|
19
|
+
} = params;
|
|
20
|
+
const model = await this.getModel(input.modelId);
|
|
21
|
+
let hasMoreItems = false;
|
|
22
|
+
let lastDeletedId = input.lastDeletedId;
|
|
23
|
+
do {
|
|
24
|
+
if (isAborted()) {
|
|
25
|
+
/**
|
|
26
|
+
* If the task was aborted, we need to remove the task tag from the model.
|
|
27
|
+
*/
|
|
28
|
+
await this.removeBeingDeleted(model);
|
|
29
|
+
return this.response.aborted();
|
|
30
|
+
} else if (isCloseToTimeout()) {
|
|
31
|
+
return this.response.continue({
|
|
32
|
+
...input,
|
|
33
|
+
lastDeletedId
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const where = {
|
|
37
|
+
latest: true
|
|
38
|
+
};
|
|
39
|
+
if (lastDeletedId) {
|
|
40
|
+
where.entryId_gte = lastDeletedId;
|
|
41
|
+
}
|
|
42
|
+
const {
|
|
43
|
+
items,
|
|
44
|
+
hasMoreItems: metaHasMoreItems
|
|
45
|
+
} = await this.context.cms.storageOperations.entries.list(model, {
|
|
46
|
+
limit: 1000,
|
|
47
|
+
where,
|
|
48
|
+
sort: ["entryId_ASC"]
|
|
49
|
+
});
|
|
50
|
+
for (const item of items) {
|
|
51
|
+
try {
|
|
52
|
+
await this.context.cms.deleteEntry(model, item.id, {
|
|
53
|
+
permanently: true,
|
|
54
|
+
force: true
|
|
55
|
+
});
|
|
56
|
+
} catch (ex) {
|
|
57
|
+
console.error("Failed to delete entry.", {
|
|
58
|
+
model: model.modelId,
|
|
59
|
+
id: item.id
|
|
60
|
+
});
|
|
61
|
+
return this.response.error(new Error(`Failed to delete entry "${item.id}". Cannot continue.`));
|
|
62
|
+
}
|
|
63
|
+
lastDeletedId = item.entryId;
|
|
64
|
+
}
|
|
65
|
+
hasMoreItems = metaHasMoreItems;
|
|
66
|
+
} while (hasMoreItems);
|
|
67
|
+
/**
|
|
68
|
+
* Let's do one more check. If there are items, continue the task with 5 seconds delay.
|
|
69
|
+
*/
|
|
70
|
+
const {
|
|
71
|
+
items
|
|
72
|
+
} = await this.context.cms.storageOperations.entries.list(model, {
|
|
73
|
+
limit: 1,
|
|
74
|
+
where: {
|
|
75
|
+
latest: true
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (items.length > 0) {
|
|
79
|
+
console.log("There are still items to be deleted. Continuing the task.");
|
|
80
|
+
return this.response.continue({
|
|
81
|
+
...input
|
|
82
|
+
}, {
|
|
83
|
+
seconds: 5
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
let hasMoreFolders = false;
|
|
87
|
+
do {
|
|
88
|
+
const [items, meta] = await this.context.aco.folder.list({
|
|
89
|
+
where: {
|
|
90
|
+
type: `cms:${model.modelId}`
|
|
91
|
+
},
|
|
92
|
+
limit: 1000
|
|
93
|
+
});
|
|
94
|
+
for (const item of items) {
|
|
95
|
+
try {
|
|
96
|
+
await this.context.aco.folder.delete(item.id);
|
|
97
|
+
} catch (ex) {
|
|
98
|
+
console.error(`Failed to delete folder "${item.id}".`, ex);
|
|
99
|
+
return this.response.error(ex);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
hasMoreFolders = meta.hasMoreItems;
|
|
103
|
+
} while (hasMoreFolders);
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* When there is no more records to be deleted, let's delete the model, if it's not a plugin.
|
|
107
|
+
*/
|
|
108
|
+
await this.removeBeingDeleted(model);
|
|
109
|
+
if (model.isPlugin) {
|
|
110
|
+
return this.response.done();
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
await this.context.cms.deleteModel(model.modelId);
|
|
114
|
+
} catch (ex) {
|
|
115
|
+
const message = `Failed to delete model "${model.modelId}".`;
|
|
116
|
+
console.error(message);
|
|
117
|
+
return this.response.error(ex);
|
|
118
|
+
}
|
|
119
|
+
return this.response.done();
|
|
120
|
+
}
|
|
121
|
+
async getModel(modelId) {
|
|
122
|
+
const model = await this.context.cms.getModel(modelId);
|
|
123
|
+
if (!model) {
|
|
124
|
+
throw new Error(`Model "${modelId}" not found.`);
|
|
125
|
+
}
|
|
126
|
+
return model;
|
|
127
|
+
}
|
|
128
|
+
async removeBeingDeleted(model) {
|
|
129
|
+
const key = (0, _store.createStoreKey)(model);
|
|
130
|
+
await this.context.db.store.removeValue(key);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.DeleteModelRunner = DeleteModelRunner;
|
|
134
|
+
const createDeleteModelRunner = params => {
|
|
135
|
+
return new DeleteModelRunner(params);
|
|
136
|
+
};
|
|
137
|
+
exports.createDeleteModelRunner = createDeleteModelRunner;
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=DeleteModelRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_store","require","DeleteModelRunner","constructor","params","taskId","context","response","execute","input","isCloseToTimeout","isAborted","model","getModel","modelId","hasMoreItems","lastDeletedId","removeBeingDeleted","aborted","continue","where","latest","entryId_gte","items","metaHasMoreItems","cms","storageOperations","entries","list","limit","sort","item","deleteEntry","id","permanently","force","ex","console","error","Error","entryId","length","log","seconds","hasMoreFolders","meta","aco","folder","type","delete","isPlugin","done","deleteModel","message","key","createStoreKey","db","store","removeValue","exports","createDeleteModelRunner"],"sources":["DeleteModelRunner.ts"],"sourcesContent":["import type { ITaskResponse, ITaskResponseResult, ITaskRunParams } from \"@webiny/tasks\";\nimport type { HcmsTasksContext } from \"~/types\";\nimport type { IDeleteModelTaskInput, IDeleteModelTaskOutput } from \"./types\";\nimport type { CmsEntryListWhere, CmsModel } from \"@webiny/api-headless-cms/types\";\nimport { createStoreKey } from \"~/tasks/deleteModel/helpers/store\";\n\nexport interface IDeleteModelRunnerParams<\n C extends HcmsTasksContext,\n I extends IDeleteModelTaskInput,\n O extends IDeleteModelTaskOutput\n> {\n taskId: string;\n context: C;\n response: ITaskResponse<I, O>;\n}\n\nexport type IExecuteParams<\n C extends HcmsTasksContext,\n I extends IDeleteModelTaskInput,\n O extends IDeleteModelTaskOutput\n> = Omit<ITaskRunParams<C, I, O>, \"context\" | \"response\" | \"store\" | \"timer\" | \"trigger\">;\n\nexport class DeleteModelRunner<\n C extends HcmsTasksContext,\n I extends IDeleteModelTaskInput,\n O extends IDeleteModelTaskOutput\n> {\n private readonly taskId: string;\n private readonly context: C;\n private readonly response: ITaskResponse<I, O>;\n\n public constructor(params: IDeleteModelRunnerParams<C, I, O>) {\n this.taskId = params.taskId;\n this.context = params.context;\n this.response = params.response;\n }\n\n public async execute(params: IExecuteParams<C, I, O>): Promise<ITaskResponseResult<I, O>> {\n const { input, isCloseToTimeout, isAborted } = params;\n\n const model = await this.getModel(input.modelId);\n\n let hasMoreItems = false;\n let lastDeletedId: string | undefined = input.lastDeletedId;\n do {\n if (isAborted()) {\n /**\n * If the task was aborted, we need to remove the task tag from the model.\n */\n await this.removeBeingDeleted(model);\n return this.response.aborted();\n } else if (isCloseToTimeout()) {\n return this.response.continue({\n ...input,\n lastDeletedId\n });\n }\n const where: CmsEntryListWhere = {\n latest: true\n };\n if (lastDeletedId) {\n where.entryId_gte = lastDeletedId;\n }\n const { items, hasMoreItems: metaHasMoreItems } =\n await this.context.cms.storageOperations.entries.list(model, {\n limit: 1000,\n where,\n sort: [\"entryId_ASC\"]\n });\n for (const item of items) {\n try {\n await this.context.cms.deleteEntry(model, item.id, {\n permanently: true,\n force: true\n });\n } catch (ex) {\n console.error(\"Failed to delete entry.\", {\n model: model.modelId,\n id: item.id\n });\n return this.response.error(\n new Error(`Failed to delete entry \"${item.id}\". Cannot continue.`)\n );\n }\n lastDeletedId = item.entryId;\n }\n\n hasMoreItems = metaHasMoreItems;\n } while (hasMoreItems);\n /**\n * Let's do one more check. If there are items, continue the task with 5 seconds delay.\n */\n const { items } = await this.context.cms.storageOperations.entries.list(model, {\n limit: 1,\n where: {\n latest: true\n }\n });\n if (items.length > 0) {\n console.log(\"There are still items to be deleted. Continuing the task.\");\n return this.response.continue(\n {\n ...input\n },\n {\n seconds: 5\n }\n );\n }\n\n let hasMoreFolders = false;\n do {\n const [items, meta] = await this.context.aco.folder.list({\n where: {\n type: `cms:${model.modelId}`\n },\n limit: 1000\n });\n for (const item of items) {\n try {\n await this.context.aco.folder.delete(item.id);\n } catch (ex) {\n console.error(`Failed to delete folder \"${item.id}\".`, ex);\n return this.response.error(ex);\n }\n }\n\n hasMoreFolders = meta.hasMoreItems;\n } while (hasMoreFolders);\n\n /**\n * When there is no more records to be deleted, let's delete the model, if it's not a plugin.\n */\n await this.removeBeingDeleted(model);\n if (model.isPlugin) {\n return this.response.done();\n }\n try {\n await this.context.cms.deleteModel(model.modelId);\n } catch (ex) {\n const message = `Failed to delete model \"${model.modelId}\".`;\n console.error(message);\n return this.response.error(ex);\n }\n\n return this.response.done();\n }\n\n private async getModel(modelId: string): Promise<CmsModel> {\n const model = await this.context.cms.getModel(modelId);\n if (!model) {\n throw new Error(`Model \"${modelId}\" not found.`);\n }\n return model;\n }\n\n private async removeBeingDeleted(\n model: Pick<CmsModel, \"modelId\" | \"tenant\" | \"locale\">\n ): Promise<void> {\n const key = createStoreKey(model);\n await this.context.db.store.removeValue(key);\n }\n}\n\nexport const createDeleteModelRunner = <\n C extends HcmsTasksContext,\n I extends IDeleteModelTaskInput,\n O extends IDeleteModelTaskOutput\n>(\n params: IDeleteModelRunnerParams<C, I, O>\n) => {\n return new DeleteModelRunner<C, I, O>(params);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DELETE_MODEL_TASK = "deleteModelAndEntries";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DELETE_MODEL_TASK","exports"],"sources":["constants.ts"],"sourcesContent":["export const DELETE_MODEL_TASK = \"deleteModelAndEntries\";\n"],"mappings":";;;;;;AAAO,MAAMA,iBAAiB,GAAAC,OAAA,CAAAD,iBAAA,GAAG,uBAAuB","ignoreList":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.attachLifecycleEvents = void 0;
|
|
7
|
+
var _error = require("@webiny/error");
|
|
8
|
+
const attachLifecycleEvents = ({
|
|
9
|
+
context
|
|
10
|
+
}) => {
|
|
11
|
+
const blockActionOnEvent = async params => {
|
|
12
|
+
const {
|
|
13
|
+
model
|
|
14
|
+
} = params;
|
|
15
|
+
const isBeingDeleted = await context.cms.isModelBeingDeleted(model.modelId);
|
|
16
|
+
if (!isBeingDeleted) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
throw new _error.WebinyError(`Model "${model.name}" is being deleted and you cannot create, update or delete any entries of this model.`);
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Entry actions.
|
|
23
|
+
*/
|
|
24
|
+
context.cms.onEntryBeforeCreate.subscribe(blockActionOnEvent);
|
|
25
|
+
context.cms.onEntryRevisionBeforeCreate.subscribe(blockActionOnEvent);
|
|
26
|
+
context.cms.onEntryBeforeUpdate.subscribe(blockActionOnEvent);
|
|
27
|
+
context.cms.onEntryBeforeUnpublish.subscribe(blockActionOnEvent);
|
|
28
|
+
context.cms.onEntryBeforePublish.subscribe(blockActionOnEvent);
|
|
29
|
+
context.cms.onEntryBeforeRepublish.subscribe(blockActionOnEvent);
|
|
30
|
+
context.cms.onEntryBeforeRestoreFromBin.subscribe(blockActionOnEvent);
|
|
31
|
+
context.cms.onEntryBeforeMove.subscribe(blockActionOnEvent);
|
|
32
|
+
/**
|
|
33
|
+
* Model actions.
|
|
34
|
+
*/
|
|
35
|
+
context.cms.onModelBeforeUpdate.subscribe(blockActionOnEvent);
|
|
36
|
+
context.cms.onModelBeforeCreateFrom.subscribe(blockActionOnEvent);
|
|
37
|
+
};
|
|
38
|
+
exports.attachLifecycleEvents = attachLifecycleEvents;
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=attachLifecycleEvents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_error","require","attachLifecycleEvents","context","blockActionOnEvent","params","model","isBeingDeleted","cms","isModelBeingDeleted","modelId","WebinyError","name","onEntryBeforeCreate","subscribe","onEntryRevisionBeforeCreate","onEntryBeforeUpdate","onEntryBeforeUnpublish","onEntryBeforePublish","onEntryBeforeRepublish","onEntryBeforeRestoreFromBin","onEntryBeforeMove","onModelBeforeUpdate","onModelBeforeCreateFrom","exports"],"sources":["attachLifecycleEvents.ts"],"sourcesContent":["import type { CmsModel } from \"@webiny/api-headless-cms/types\";\nimport { WebinyError } from \"@webiny/error\";\nimport type { HcmsTasksContext } from \"~/types\";\n\nexport interface IAttachLifecycleEventsParams {\n context: HcmsTasksContext;\n}\n\ninterface ICbParams {\n model: Pick<CmsModel, \"modelId\" | \"name\">;\n}\n\nexport const attachLifecycleEvents = ({ context }: IAttachLifecycleEventsParams): void => {\n const blockActionOnEvent = async (params: ICbParams): Promise<void> => {\n const { model } = params;\n const isBeingDeleted = await context.cms.isModelBeingDeleted(model.modelId);\n if (!isBeingDeleted) {\n return;\n }\n\n throw new WebinyError(\n `Model \"${model.name}\" is being deleted and you cannot create, update or delete any entries of this model.`\n );\n };\n /**\n * Entry actions.\n */\n context.cms.onEntryBeforeCreate.subscribe(blockActionOnEvent);\n\n context.cms.onEntryRevisionBeforeCreate.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforeUpdate.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforeUnpublish.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforePublish.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforeRepublish.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforeRestoreFromBin.subscribe(blockActionOnEvent);\n\n context.cms.onEntryBeforeMove.subscribe(blockActionOnEvent);\n /**\n * Model actions.\n */\n context.cms.onModelBeforeUpdate.subscribe(blockActionOnEvent);\n\n context.cms.onModelBeforeCreateFrom.subscribe(blockActionOnEvent);\n};\n"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AAWO,MAAMC,qBAAqB,GAAGA,CAAC;EAAEC;AAAsC,CAAC,KAAW;EACtF,MAAMC,kBAAkB,GAAG,MAAOC,MAAiB,IAAoB;IACnE,MAAM;MAAEC;IAAM,CAAC,GAAGD,MAAM;IACxB,MAAME,cAAc,GAAG,MAAMJ,OAAO,CAACK,GAAG,CAACC,mBAAmB,CAACH,KAAK,CAACI,OAAO,CAAC;IAC3E,IAAI,CAACH,cAAc,EAAE;MACjB;IACJ;IAEA,MAAM,IAAII,kBAAW,CACjB,UAAUL,KAAK,CAACM,IAAI,uFACxB,CAAC;EACL,CAAC;EACD;AACJ;AACA;EACIT,OAAO,CAACK,GAAG,CAACK,mBAAmB,CAACC,SAAS,CAACV,kBAAkB,CAAC;EAE7DD,OAAO,CAACK,GAAG,CAACO,2BAA2B,CAACD,SAAS,CAACV,kBAAkB,CAAC;EAErED,OAAO,CAACK,GAAG,CAACQ,mBAAmB,CAACF,SAAS,CAACV,kBAAkB,CAAC;EAE7DD,OAAO,CAACK,GAAG,CAACS,sBAAsB,CAACH,SAAS,CAACV,kBAAkB,CAAC;EAEhED,OAAO,CAACK,GAAG,CAACU,oBAAoB,CAACJ,SAAS,CAACV,kBAAkB,CAAC;EAE9DD,OAAO,CAACK,GAAG,CAACW,sBAAsB,CAACL,SAAS,CAACV,kBAAkB,CAAC;EAEhED,OAAO,CAACK,GAAG,CAACY,2BAA2B,CAACN,SAAS,CAACV,kBAAkB,CAAC;EAErED,OAAO,CAACK,GAAG,CAACa,iBAAiB,CAACP,SAAS,CAACV,kBAAkB,CAAC;EAC3D;AACJ;AACA;EACID,OAAO,CAACK,GAAG,CAACc,mBAAmB,CAACR,SAAS,CAACV,kBAAkB,CAAC;EAE7DD,OAAO,CAACK,GAAG,CAACe,uBAAuB,CAACT,SAAS,CAACV,kBAAkB,CAAC;AACrE,CAAC;AAACoB,OAAA,CAAAtB,qBAAA,GAAAA,qBAAA","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HcmsTasksContext } from "../../../types";
|
|
2
|
+
import type { IDeleteCmsModelTask } from "../types";
|
|
3
|
+
export interface ICancelDeleteModelParams {
|
|
4
|
+
readonly context: Pick<HcmsTasksContext, "cms" | "tasks" | "db">;
|
|
5
|
+
readonly modelId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const cancelDeleteModel: (params: ICancelDeleteModelParams) => Promise<IDeleteCmsModelTask>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cancelDeleteModel = void 0;
|
|
7
|
+
var _constants = require("../constants");
|
|
8
|
+
var _error = require("@webiny/error");
|
|
9
|
+
var _status = require("./status");
|
|
10
|
+
var _store = require("../helpers/store");
|
|
11
|
+
const cancelDeleteModel = async params => {
|
|
12
|
+
const {
|
|
13
|
+
context,
|
|
14
|
+
modelId
|
|
15
|
+
} = params;
|
|
16
|
+
const model = await context.cms.getModel(modelId);
|
|
17
|
+
await context.cms.accessControl.ensureCanAccessModel({
|
|
18
|
+
model,
|
|
19
|
+
rwd: "d"
|
|
20
|
+
});
|
|
21
|
+
await context.cms.accessControl.ensureCanAccessEntry({
|
|
22
|
+
model,
|
|
23
|
+
rwd: "w"
|
|
24
|
+
});
|
|
25
|
+
const storeKey = (0, _store.createStoreKey)(model);
|
|
26
|
+
const result = await context.db.store.getValue(storeKey);
|
|
27
|
+
const taskId = result.data?.task;
|
|
28
|
+
await context.db.store.removeValue(storeKey);
|
|
29
|
+
if (!taskId) {
|
|
30
|
+
if (result.error) {
|
|
31
|
+
throw _error.WebinyError.from(result.error, {
|
|
32
|
+
code: "DELETE_MODEL_NO_TASK_DEFINED"
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
throw new _error.WebinyError({
|
|
36
|
+
message: `Model "${modelId}" is not being deleted.`,
|
|
37
|
+
code: "MODEL_NOT_BEING_DELETED"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const task = await context.tasks.getTask(taskId);
|
|
41
|
+
if (task?.definitionId !== _constants.DELETE_MODEL_TASK) {
|
|
42
|
+
throw new _error.WebinyError({
|
|
43
|
+
message: `The task which is deleting a model cannot be found. Please check Step Functions for more info. Task id: ${taskId}`,
|
|
44
|
+
code: "DELETE_MODEL_TASK_NOT_FOUND",
|
|
45
|
+
data: {
|
|
46
|
+
model: model.modelId,
|
|
47
|
+
task: taskId
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const canceledTask = await context.tasks.abort({
|
|
52
|
+
id: task.id,
|
|
53
|
+
message: "User canceled the task."
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
id: canceledTask.id,
|
|
57
|
+
status: (0, _status.getStatus)(canceledTask.taskStatus),
|
|
58
|
+
total: canceledTask.output?.total || 0,
|
|
59
|
+
deleted: canceledTask.output?.deleted || 0
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
exports.cancelDeleteModel = cancelDeleteModel;
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=cancelDeleteModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_constants","require","_error","_status","_store","cancelDeleteModel","params","context","modelId","model","cms","getModel","accessControl","ensureCanAccessModel","rwd","ensureCanAccessEntry","storeKey","createStoreKey","result","db","store","getValue","taskId","data","task","removeValue","error","WebinyError","from","code","message","tasks","getTask","definitionId","DELETE_MODEL_TASK","canceledTask","abort","id","status","getStatus","taskStatus","total","output","deleted","exports"],"sources":["cancelDeleteModel.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types\";\nimport type {\n IDeleteCmsModelTask,\n IDeleteModelTaskInput,\n IDeleteModelTaskOutput,\n IStoreValue\n} from \"~/tasks/deleteModel/types\";\nimport { DELETE_MODEL_TASK } from \"~/tasks/deleteModel/constants\";\nimport { WebinyError } from \"@webiny/error\";\nimport { getStatus } from \"~/tasks/deleteModel/graphql/status\";\nimport { createStoreKey } from \"~/tasks/deleteModel/helpers/store\";\n\nexport interface ICancelDeleteModelParams {\n readonly context: Pick<HcmsTasksContext, \"cms\" | \"tasks\" | \"db\">;\n readonly modelId: string;\n}\n\nexport const cancelDeleteModel = async (\n params: ICancelDeleteModelParams\n): Promise<IDeleteCmsModelTask> => {\n const { context, modelId } = params;\n\n const model = await context.cms.getModel(modelId);\n\n await context.cms.accessControl.ensureCanAccessModel({\n model,\n rwd: \"d\"\n });\n\n await context.cms.accessControl.ensureCanAccessEntry({\n model,\n rwd: \"w\"\n });\n\n const storeKey = createStoreKey(model);\n\n const result = await context.db.store.getValue<IStoreValue>(storeKey);\n\n const taskId = result.data?.task;\n\n await context.db.store.removeValue(storeKey);\n if (!taskId) {\n if (result.error) {\n throw WebinyError.from(result.error, {\n code: \"DELETE_MODEL_NO_TASK_DEFINED\"\n });\n }\n throw new WebinyError({\n message: `Model \"${modelId}\" is not being deleted.`,\n code: \"MODEL_NOT_BEING_DELETED\"\n });\n }\n\n const task = await context.tasks.getTask<IDeleteModelTaskInput, IDeleteModelTaskOutput>(taskId);\n if (task?.definitionId !== DELETE_MODEL_TASK) {\n throw new WebinyError({\n message: `The task which is deleting a model cannot be found. Please check Step Functions for more info. Task id: ${taskId}`,\n code: \"DELETE_MODEL_TASK_NOT_FOUND\",\n data: {\n model: model.modelId,\n task: taskId\n }\n });\n }\n\n const canceledTask = await context.tasks.abort<IDeleteModelTaskInput, IDeleteModelTaskOutput>({\n id: task.id,\n message: \"User canceled the task.\"\n });\n\n return {\n id: canceledTask.id,\n status: getStatus(canceledTask.taskStatus),\n total: canceledTask.output?.total || 0,\n deleted: canceledTask.output?.deleted || 0\n };\n};\n"],"mappings":";;;;;;AAOA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAOO,MAAMI,iBAAiB,GAAG,MAC7BC,MAAgC,IACD;EAC/B,MAAM;IAAEC,OAAO;IAAEC;EAAQ,CAAC,GAAGF,MAAM;EAEnC,MAAMG,KAAK,GAAG,MAAMF,OAAO,CAACG,GAAG,CAACC,QAAQ,CAACH,OAAO,CAAC;EAEjD,MAAMD,OAAO,CAACG,GAAG,CAACE,aAAa,CAACC,oBAAoB,CAAC;IACjDJ,KAAK;IACLK,GAAG,EAAE;EACT,CAAC,CAAC;EAEF,MAAMP,OAAO,CAACG,GAAG,CAACE,aAAa,CAACG,oBAAoB,CAAC;IACjDN,KAAK;IACLK,GAAG,EAAE;EACT,CAAC,CAAC;EAEF,MAAME,QAAQ,GAAG,IAAAC,qBAAc,EAACR,KAAK,CAAC;EAEtC,MAAMS,MAAM,GAAG,MAAMX,OAAO,CAACY,EAAE,CAACC,KAAK,CAACC,QAAQ,CAAcL,QAAQ,CAAC;EAErE,MAAMM,MAAM,GAAGJ,MAAM,CAACK,IAAI,EAAEC,IAAI;EAEhC,MAAMjB,OAAO,CAACY,EAAE,CAACC,KAAK,CAACK,WAAW,CAACT,QAAQ,CAAC;EAC5C,IAAI,CAACM,MAAM,EAAE;IACT,IAAIJ,MAAM,CAACQ,KAAK,EAAE;MACd,MAAMC,kBAAW,CAACC,IAAI,CAACV,MAAM,CAACQ,KAAK,EAAE;QACjCG,IAAI,EAAE;MACV,CAAC,CAAC;IACN;IACA,MAAM,IAAIF,kBAAW,CAAC;MAClBG,OAAO,EAAE,UAAUtB,OAAO,yBAAyB;MACnDqB,IAAI,EAAE;IACV,CAAC,CAAC;EACN;EAEA,MAAML,IAAI,GAAG,MAAMjB,OAAO,CAACwB,KAAK,CAACC,OAAO,CAAgDV,MAAM,CAAC;EAC/F,IAAIE,IAAI,EAAES,YAAY,KAAKC,4BAAiB,EAAE;IAC1C,MAAM,IAAIP,kBAAW,CAAC;MAClBG,OAAO,EAAE,2GAA2GR,MAAM,EAAE;MAC5HO,IAAI,EAAE,6BAA6B;MACnCN,IAAI,EAAE;QACFd,KAAK,EAAEA,KAAK,CAACD,OAAO;QACpBgB,IAAI,EAAEF;MACV;IACJ,CAAC,CAAC;EACN;EAEA,MAAMa,YAAY,GAAG,MAAM5B,OAAO,CAACwB,KAAK,CAACK,KAAK,CAAgD;IAC1FC,EAAE,EAAEb,IAAI,CAACa,EAAE;IACXP,OAAO,EAAE;EACb,CAAC,CAAC;EAEF,OAAO;IACHO,EAAE,EAAEF,YAAY,CAACE,EAAE;IACnBC,MAAM,EAAE,IAAAC,iBAAS,EAACJ,YAAY,CAACK,UAAU,CAAC;IAC1CC,KAAK,EAAEN,YAAY,CAACO,MAAM,EAAED,KAAK,IAAI,CAAC;IACtCE,OAAO,EAAER,YAAY,CAACO,MAAM,EAAEC,OAAO,IAAI;EAC7C,CAAC;AACL,CAAC;AAACC,OAAA,CAAAvC,iBAAA,GAAAA,iBAAA","ignoreList":[]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createDeleteModelCrud = void 0;
|
|
7
|
+
var _fullyDeleteModel = require("./fullyDeleteModel");
|
|
8
|
+
var _cancelDeleteModel = require("./cancelDeleteModel");
|
|
9
|
+
var _getDeleteModelProgress = require("./getDeleteModelProgress");
|
|
10
|
+
var _utils = require("@webiny/api-headless-cms/utils");
|
|
11
|
+
var _store = require("../helpers/store");
|
|
12
|
+
var _api = require("@webiny/api");
|
|
13
|
+
var _attachLifecycleEvents = require("./attachLifecycleEvents");
|
|
14
|
+
const createDeleteModelCrud = () => {
|
|
15
|
+
const plugin = new _api.ContextPlugin(async context => {
|
|
16
|
+
(0, _attachLifecycleEvents.attachLifecycleEvents)({
|
|
17
|
+
context
|
|
18
|
+
});
|
|
19
|
+
const getLocale = () => {
|
|
20
|
+
return context.cms.getLocale().code;
|
|
21
|
+
};
|
|
22
|
+
const getTenant = () => {
|
|
23
|
+
return context.tenancy.getCurrentTenant().id;
|
|
24
|
+
};
|
|
25
|
+
const cache = (0, _utils.createMemoryCache)();
|
|
26
|
+
context.cms.listModelsBeingDeleted = async () => {
|
|
27
|
+
const locale = getLocale();
|
|
28
|
+
const tenant = getTenant();
|
|
29
|
+
const cacheKey = (0, _utils.createCacheKey)({
|
|
30
|
+
tenant: getTenant(),
|
|
31
|
+
locale: getLocale(),
|
|
32
|
+
type: "deleteModel"
|
|
33
|
+
});
|
|
34
|
+
const result = await cache.getOrSet(cacheKey, async () => {
|
|
35
|
+
const beginsWith = (0, _store.createStoreNamespace)({
|
|
36
|
+
tenant,
|
|
37
|
+
locale
|
|
38
|
+
});
|
|
39
|
+
return await context.db.store.listValues({
|
|
40
|
+
beginsWith
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
if (result.error) {
|
|
44
|
+
throw result.error;
|
|
45
|
+
} else if (!result.data) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
return Object.values(result.data);
|
|
49
|
+
};
|
|
50
|
+
context.cms.isModelBeingDeleted = async modelId => {
|
|
51
|
+
const items = await context.cms.listModelsBeingDeleted();
|
|
52
|
+
return items.some(item => item.modelId === modelId);
|
|
53
|
+
};
|
|
54
|
+
context.cms.fullyDeleteModel = async modelId => {
|
|
55
|
+
const result = await (0, _fullyDeleteModel.fullyDeleteModel)({
|
|
56
|
+
context,
|
|
57
|
+
modelId
|
|
58
|
+
});
|
|
59
|
+
cache.clear();
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
context.cms.cancelFullyDeleteModel = async modelId => {
|
|
63
|
+
const result = await (0, _cancelDeleteModel.cancelDeleteModel)({
|
|
64
|
+
context,
|
|
65
|
+
modelId
|
|
66
|
+
});
|
|
67
|
+
cache.clear();
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
context.cms.getDeleteModelProgress = async modelId => {
|
|
71
|
+
return await (0, _getDeleteModelProgress.getDeleteModelProgress)({
|
|
72
|
+
context,
|
|
73
|
+
modelId
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
plugin.name = "headlessCms.context.cms.fullyDeleteModel";
|
|
78
|
+
return plugin;
|
|
79
|
+
};
|
|
80
|
+
exports.createDeleteModelCrud = createDeleteModelCrud;
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=crud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_fullyDeleteModel","require","_cancelDeleteModel","_getDeleteModelProgress","_utils","_store","_api","_attachLifecycleEvents","createDeleteModelCrud","plugin","ContextPlugin","context","attachLifecycleEvents","getLocale","cms","code","getTenant","tenancy","getCurrentTenant","id","cache","createMemoryCache","listModelsBeingDeleted","locale","tenant","cacheKey","createCacheKey","type","result","getOrSet","beginsWith","createStoreNamespace","db","store","listValues","error","data","Object","values","isModelBeingDeleted","modelId","items","some","item","fullyDeleteModel","fullyDeleteModelMethod","clear","cancelFullyDeleteModel","cancelDeleteModel","getDeleteModelProgress","getDeleteModelProgressMethod","name","exports"],"sources":["crud.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types\";\nimport { fullyDeleteModel as fullyDeleteModelMethod } from \"./fullyDeleteModel\";\nimport { cancelDeleteModel } from \"./cancelDeleteModel\";\nimport { getDeleteModelProgress as getDeleteModelProgressMethod } from \"./getDeleteModelProgress\";\nimport { createCacheKey, createMemoryCache } from \"@webiny/api-headless-cms/utils\";\nimport type { IStoreValue, ListStoreKeysResult } from \"../types\";\nimport { createStoreNamespace } from \"~/tasks/deleteModel/helpers/store\";\nimport type { GenericRecord } from \"@webiny/api/types\";\nimport { ContextPlugin } from \"@webiny/api\";\nimport { attachLifecycleEvents } from \"./attachLifecycleEvents\";\n\nexport const createDeleteModelCrud = () => {\n const plugin = new ContextPlugin<HcmsTasksContext>(async context => {\n attachLifecycleEvents({\n context\n });\n const getLocale = (): string => {\n return context.cms.getLocale().code;\n };\n const getTenant = (): string => {\n return context.tenancy.getCurrentTenant().id;\n };\n\n const cache = createMemoryCache<ListStoreKeysResult>();\n\n context.cms.listModelsBeingDeleted = async () => {\n const locale = getLocale();\n const tenant = getTenant();\n const cacheKey = createCacheKey({\n tenant: getTenant(),\n locale: getLocale(),\n type: \"deleteModel\"\n });\n\n const result = await cache.getOrSet(cacheKey, async () => {\n const beginsWith = createStoreNamespace({\n tenant,\n locale\n });\n return await context.db.store.listValues<GenericRecord<string, IStoreValue>>({\n beginsWith\n });\n });\n\n if (result.error) {\n throw result.error;\n } else if (!result.data) {\n return [];\n }\n return Object.values(result.data);\n };\n\n context.cms.isModelBeingDeleted = async (modelId: string) => {\n const items = await context.cms.listModelsBeingDeleted();\n return items.some(item => item.modelId === modelId);\n };\n context.cms.fullyDeleteModel = async (modelId: string) => {\n const result = await fullyDeleteModelMethod({\n context,\n modelId\n });\n cache.clear();\n return result;\n };\n\n context.cms.cancelFullyDeleteModel = async (modelId: string) => {\n const result = await cancelDeleteModel({\n context,\n modelId\n });\n cache.clear();\n return result;\n };\n\n context.cms.getDeleteModelProgress = async (modelId: string) => {\n return await getDeleteModelProgressMethod({\n context,\n modelId\n });\n };\n });\n\n plugin.name = \"headlessCms.context.cms.fullyDeleteModel\";\n\n return plugin;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HcmsTasksContext } from "../../../types";
|
|
2
|
+
import type { IDeleteCmsModelTask } from "../types";
|
|
3
|
+
export interface IFullyDeleteModelParams {
|
|
4
|
+
readonly context: Pick<HcmsTasksContext, "cms" | "tasks" | "db" | "security">;
|
|
5
|
+
readonly modelId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const fullyDeleteModel: (params: IFullyDeleteModelParams) => Promise<IDeleteCmsModelTask>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.fullyDeleteModel = void 0;
|
|
7
|
+
var _constants = require("../constants");
|
|
8
|
+
var _status = require("./status");
|
|
9
|
+
var _store = require("../helpers/store");
|
|
10
|
+
const fullyDeleteModel = async params => {
|
|
11
|
+
const {
|
|
12
|
+
context,
|
|
13
|
+
modelId
|
|
14
|
+
} = params;
|
|
15
|
+
const model = await context.cms.getModel(modelId);
|
|
16
|
+
if (model.isPrivate) {
|
|
17
|
+
throw new Error(`Cannot delete private model.`);
|
|
18
|
+
}
|
|
19
|
+
await context.cms.accessControl.ensureCanAccessModel({
|
|
20
|
+
model,
|
|
21
|
+
rwd: "d"
|
|
22
|
+
});
|
|
23
|
+
await context.cms.accessControl.ensureCanAccessEntry({
|
|
24
|
+
model,
|
|
25
|
+
rwd: "w"
|
|
26
|
+
});
|
|
27
|
+
if (!model) {
|
|
28
|
+
throw new Error(`Model "${modelId}" not found.`);
|
|
29
|
+
}
|
|
30
|
+
const storeKey = (0, _store.createStoreKey)(model);
|
|
31
|
+
const result = await context.db.store.getValue(storeKey);
|
|
32
|
+
const taskId = result.data?.task;
|
|
33
|
+
if (taskId) {
|
|
34
|
+
throw new Error(`Model "${modelId}" is already getting deleted. Task id: ${taskId}.`);
|
|
35
|
+
}
|
|
36
|
+
const task = await context.tasks.trigger({
|
|
37
|
+
input: {
|
|
38
|
+
modelId
|
|
39
|
+
},
|
|
40
|
+
definition: _constants.DELETE_MODEL_TASK,
|
|
41
|
+
name: `Fully delete model: ${modelId}`
|
|
42
|
+
});
|
|
43
|
+
await context.db.store.storeValue(storeKey, (0, _store.createStoreValue)({
|
|
44
|
+
...model,
|
|
45
|
+
identity: context.security.getIdentity(),
|
|
46
|
+
task: task.id
|
|
47
|
+
}));
|
|
48
|
+
return {
|
|
49
|
+
id: task.id,
|
|
50
|
+
status: (0, _status.getStatus)(task.taskStatus),
|
|
51
|
+
total: 0,
|
|
52
|
+
deleted: 0
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
exports.fullyDeleteModel = fullyDeleteModel;
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=fullyDeleteModel.js.map
|