@webiny/api-headless-cms-tasks 6.4.5 → 6.6.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HcmsTasksFeature.d.ts +4 -0
- package/HcmsTasksFeature.js +20 -0
- package/HcmsTasksFeature.js.map +1 -0
- package/features/DeleteModelTask/DeleteModel.js +19 -10
- package/features/DeleteModelTask/DeleteModel.js.map +1 -1
- package/features/DeleteModelTask/DeleteModelTask.d.ts +1 -1
- package/features/DeleteModelTask/types.d.ts +0 -3
- package/features/DeleteModelTask/types.js.map +1 -1
- package/features/DisableModel/BlockActionIfModelDisabled.d.ts +2 -2
- package/features/DisableModel/BlockActionIfModelDisabled.js.map +1 -1
- package/features/DisableModel/feature.d.ts +1 -5
- package/features/DisableModel/feature.js +4 -2
- package/features/DisableModel/feature.js.map +1 -1
- package/graphql/deleteModel/abstractions.d.ts +12 -0
- package/graphql/deleteModel/abstractions.js +5 -0
- package/graphql/deleteModel/abstractions.js.map +1 -0
- package/graphql/deleteModel/cancelDeleteModel.d.ts +1 -1
- package/graphql/deleteModel/cancelDeleteModel.js +17 -17
- package/graphql/deleteModel/cancelDeleteModel.js.map +1 -1
- package/graphql/deleteModel/crud.d.ts +2 -3
- package/graphql/deleteModel/crud.js +46 -53
- package/graphql/deleteModel/crud.js.map +1 -1
- package/graphql/deleteModel/fullyDeleteModel.d.ts +1 -1
- package/graphql/deleteModel/fullyDeleteModel.js +18 -11
- package/graphql/deleteModel/fullyDeleteModel.js.map +1 -1
- package/graphql/deleteModel/getDeleteModelProgress.d.ts +1 -1
- package/graphql/deleteModel/getDeleteModelProgress.js +16 -9
- package/graphql/deleteModel/getDeleteModelProgress.js.map +1 -1
- package/graphql/deleteModel/index.d.ts +2 -2
- package/graphql/deleteModel/index.js +65 -62
- package/graphql/deleteModel/index.js.map +1 -1
- package/helpers/store.d.ts +12 -7
- package/helpers/store.js +32 -3
- package/helpers/store.js.map +1 -1
- package/index.d.ts +1 -2
- package/index.js +1 -22
- package/package.json +19 -19
- package/types.d.ts +0 -10
- package/index.js.map +0 -1
|
@@ -1,27 +1,34 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
|
|
2
|
+
import { createDeleteModelStore, createStoreValue } from "../../helpers/store.js";
|
|
2
3
|
import { DELETE_MODEL_TASK } from "../../constants.js";
|
|
3
4
|
import { getStatus } from "./status.js";
|
|
4
5
|
import { NotAuthorizedError } from "@webiny/api-headless-cms/utils/errors.js";
|
|
6
|
+
import { AccessControl } from "@webiny/api-headless-cms/features/shared/abstractions.js";
|
|
7
|
+
import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
|
|
8
|
+
import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/abstractions.js";
|
|
9
|
+
import { TriggerTaskUseCase } from "@webiny/background-tasks/api";
|
|
5
10
|
const fullyDeleteModel = async (params)=>{
|
|
6
11
|
const { context, modelId } = params;
|
|
7
|
-
const
|
|
12
|
+
const modelResult = await context.container.resolve(GetModelUseCase).execute(modelId);
|
|
13
|
+
if (modelResult.isFail()) throw modelResult.error;
|
|
14
|
+
const model = modelResult.value;
|
|
8
15
|
if (model.isPrivate) throw new Error("Cannot delete private model.");
|
|
9
|
-
const
|
|
16
|
+
const accessControl = context.container.resolve(AccessControl);
|
|
17
|
+
const canAccessModel = await accessControl.canAccessModel({
|
|
10
18
|
model,
|
|
11
19
|
rwd: "d"
|
|
12
20
|
});
|
|
13
21
|
if (!canAccessModel) throw new NotAuthorizedError(`Not allowed to access content model "${model.name}".`);
|
|
14
|
-
const canAccessEntry = await
|
|
22
|
+
const canAccessEntry = await accessControl.canAccessEntry({
|
|
15
23
|
model,
|
|
16
24
|
rwd: "w"
|
|
17
25
|
});
|
|
18
26
|
if (!canAccessEntry) throw new NotAuthorizedError(`Not allowed to access "${model.modelId}" entries.`);
|
|
19
27
|
if (!model) throw new Error(`Model "${modelId}" not found.`);
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const triggerResult = await context.tasks.trigger({
|
|
28
|
+
const store = createDeleteModelStore(context.container.resolve(GlobalKeyValueStore), model.tenant);
|
|
29
|
+
const existing = await store.get(model.modelId);
|
|
30
|
+
if (existing?.task) throw new Error(`Model "${modelId}" is already getting deleted. Task id: ${existing.task}.`);
|
|
31
|
+
const triggerResult = await context.container.resolve(TriggerTaskUseCase).execute({
|
|
25
32
|
input: {
|
|
26
33
|
modelId
|
|
27
34
|
},
|
|
@@ -29,8 +36,8 @@ const fullyDeleteModel = async (params)=>{
|
|
|
29
36
|
name: `Fully delete model: ${modelId}`
|
|
30
37
|
});
|
|
31
38
|
const task = triggerResult.value;
|
|
32
|
-
const identity = context.
|
|
33
|
-
await
|
|
39
|
+
const identity = context.container.resolve(IdentityContext).getIdentity();
|
|
40
|
+
await store.set(createStoreValue({
|
|
34
41
|
...model,
|
|
35
42
|
identity: {
|
|
36
43
|
id: identity.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql/deleteModel/fullyDeleteModel.js","sources":["../../../src/graphql/deleteModel/fullyDeleteModel.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types.js\";\nimport type {\n IDeleteCmsModelTask,\n IDeleteModelTaskInput
|
|
1
|
+
{"version":3,"file":"graphql/deleteModel/fullyDeleteModel.js","sources":["../../../src/graphql/deleteModel/fullyDeleteModel.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport type {\n IDeleteCmsModelTask,\n IDeleteModelTaskInput\n} from \"~/features/DeleteModelTask/types.js\";\nimport { createDeleteModelStore, createStoreValue } from \"~/helpers/store.js\";\nimport { DELETE_MODEL_TASK } from \"~/constants.js\";\nimport { getStatus } from \"~/graphql/deleteModel/status.js\";\nimport { NotAuthorizedError } from \"@webiny/api-headless-cms/utils/errors.js\";\nimport { AccessControl } from \"@webiny/api-headless-cms/features/shared/abstractions.js\";\nimport { GetModelUseCase } from \"@webiny/api-headless-cms/features/contentModel/GetModel/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/abstractions.js\";\nimport { TriggerTaskUseCase } from \"@webiny/background-tasks/api\";\n\nexport interface IFullyDeleteModelParams {\n readonly context: Pick<HcmsTasksContext, \"container\">;\n readonly modelId: string;\n}\n\nexport const fullyDeleteModel = async (\n params: IFullyDeleteModelParams\n): Promise<IDeleteCmsModelTask> => {\n const { context, modelId } = params;\n\n const modelResult = await context.container.resolve(GetModelUseCase).execute(modelId);\n if (modelResult.isFail()) {\n throw modelResult.error;\n }\n const model = modelResult.value;\n\n if (model.isPrivate) {\n throw new Error(`Cannot delete private model.`);\n }\n\n const accessControl = context.container.resolve(AccessControl);\n const canAccessModel = await accessControl.canAccessModel({ model, rwd: \"d\" });\n if (!canAccessModel) {\n throw new NotAuthorizedError(`Not allowed to access content model \"${model.name}\".`);\n }\n\n const canAccessEntry = await accessControl.canAccessEntry({ model, rwd: \"w\" });\n if (!canAccessEntry) {\n throw new NotAuthorizedError(`Not allowed to access \"${model.modelId}\" entries.`);\n }\n\n if (!model) {\n throw new Error(`Model \"${modelId}\" not found.`);\n }\n const store = createDeleteModelStore(\n context.container.resolve(GlobalKeyValueStore),\n model.tenant\n );\n const existing = await store.get(model.modelId);\n if (existing?.task) {\n throw new Error(\n `Model \"${modelId}\" is already getting deleted. Task id: ${existing.task}.`\n );\n }\n\n const triggerResult = await context.container\n .resolve(TriggerTaskUseCase)\n .execute<IDeleteModelTaskInput>({\n input: {\n modelId\n },\n definition: DELETE_MODEL_TASK,\n name: `Fully delete model: ${modelId}`\n });\n\n const task = triggerResult.value;\n\n const identity = context.container.resolve(IdentityContext).getIdentity();\n\n await store.set(\n createStoreValue({\n ...model,\n identity: {\n id: identity.id,\n type: identity.type,\n displayName: identity.displayName\n },\n task: task.id\n })\n );\n\n return {\n id: task.id,\n status: getStatus(task.taskStatus),\n total: 0,\n deleted: 0\n };\n};\n"],"names":["fullyDeleteModel","params","context","modelId","modelResult","GetModelUseCase","model","Error","accessControl","AccessControl","canAccessModel","NotAuthorizedError","canAccessEntry","store","createDeleteModelStore","GlobalKeyValueStore","existing","triggerResult","TriggerTaskUseCase","DELETE_MODEL_TASK","task","identity","IdentityContext","createStoreValue","getStatus"],"mappings":";;;;;;;;;AAoBO,MAAMA,mBAAmB,OAC5BC;IAEA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAE,GAAGF;IAE7B,MAAMG,cAAc,MAAMF,QAAQ,SAAS,CAAC,OAAO,CAACG,iBAAiB,OAAO,CAACF;IAC7E,IAAIC,YAAY,MAAM,IAClB,MAAMA,YAAY,KAAK;IAE3B,MAAME,QAAQF,YAAY,KAAK;IAE/B,IAAIE,MAAM,SAAS,EACf,MAAM,IAAIC,MAAM;IAGpB,MAAMC,gBAAgBN,QAAQ,SAAS,CAAC,OAAO,CAACO;IAChD,MAAMC,iBAAiB,MAAMF,cAAc,cAAc,CAAC;QAAEF;QAAO,KAAK;IAAI;IAC5E,IAAI,CAACI,gBACD,MAAM,IAAIC,mBAAmB,CAAC,qCAAqC,EAAEL,MAAM,IAAI,CAAC,EAAE,CAAC;IAGvF,MAAMM,iBAAiB,MAAMJ,cAAc,cAAc,CAAC;QAAEF;QAAO,KAAK;IAAI;IAC5E,IAAI,CAACM,gBACD,MAAM,IAAID,mBAAmB,CAAC,uBAAuB,EAAEL,MAAM,OAAO,CAAC,UAAU,CAAC;IAGpF,IAAI,CAACA,OACD,MAAM,IAAIC,MAAM,CAAC,OAAO,EAAEJ,QAAQ,YAAY,CAAC;IAEnD,MAAMU,QAAQC,uBACVZ,QAAQ,SAAS,CAAC,OAAO,CAACa,sBAC1BT,MAAM,MAAM;IAEhB,MAAMU,WAAW,MAAMH,MAAM,GAAG,CAACP,MAAM,OAAO;IAC9C,IAAIU,UAAU,MACV,MAAM,IAAIT,MACN,CAAC,OAAO,EAAEJ,QAAQ,uCAAuC,EAAEa,SAAS,IAAI,CAAC,CAAC,CAAC;IAInF,MAAMC,gBAAgB,MAAMf,QAAQ,SAAS,CACxC,OAAO,CAACgB,oBACR,OAAO,CAAwB;QAC5B,OAAO;YACHf;QACJ;QACA,YAAYgB;QACZ,MAAM,CAAC,oBAAoB,EAAEhB,SAAS;IAC1C;IAEJ,MAAMiB,OAAOH,cAAc,KAAK;IAEhC,MAAMI,WAAWnB,QAAQ,SAAS,CAAC,OAAO,CAACoB,iBAAiB,WAAW;IAEvE,MAAMT,MAAM,GAAG,CACXU,iBAAiB;QACb,GAAGjB,KAAK;QACR,UAAU;YACN,IAAIe,SAAS,EAAE;YACf,MAAMA,SAAS,IAAI;YACnB,aAAaA,SAAS,WAAW;QACrC;QACA,MAAMD,KAAK,EAAE;IACjB;IAGJ,OAAO;QACH,IAAIA,KAAK,EAAE;QACX,QAAQI,UAAUJ,KAAK,UAAU;QACjC,OAAO;QACP,SAAS;IACb;AACJ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HcmsTasksContext } from "../../types.js";
|
|
2
2
|
import type { IDeleteCmsModelTask } from "../../features/DeleteModelTask/types.js";
|
|
3
3
|
export interface IGetDeleteModelProgress {
|
|
4
|
-
readonly context: Pick<HcmsTasksContext, "
|
|
4
|
+
readonly context: Pick<HcmsTasksContext, "container">;
|
|
5
5
|
readonly modelId: string;
|
|
6
6
|
}
|
|
7
7
|
export declare const getDeleteModelProgress: (params: IGetDeleteModelProgress) => Promise<IDeleteCmsModelTask>;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { WebinyError } from "@webiny/error";
|
|
2
|
-
import { NotFoundError } from "@webiny/
|
|
3
|
-
import {
|
|
2
|
+
import { NotFoundError } from "@webiny/api-graphql";
|
|
3
|
+
import { createDeleteModelStore } from "../../helpers/store.js";
|
|
4
4
|
import { DELETE_MODEL_TASK } from "../../constants.js";
|
|
5
5
|
import { getStatus } from "./status.js";
|
|
6
6
|
import { NotAuthorizedError } from "@webiny/api-headless-cms/utils/errors.js";
|
|
7
|
+
import { AccessControl } from "@webiny/api-headless-cms/features/shared/abstractions.js";
|
|
8
|
+
import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
|
|
9
|
+
import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/abstractions.js";
|
|
10
|
+
import { GetTaskUseCase } from "@webiny/background-tasks/api";
|
|
7
11
|
const getDeleteModelProgress = async (params)=>{
|
|
8
12
|
const { context, modelId } = params;
|
|
9
13
|
let model;
|
|
10
14
|
try {
|
|
11
|
-
|
|
15
|
+
const modelResult = await context.container.resolve(GetModelUseCase).execute(modelId);
|
|
16
|
+
if (modelResult.isFail()) throw modelResult.error;
|
|
17
|
+
model = modelResult.value;
|
|
12
18
|
} catch (ex) {
|
|
13
19
|
if (ex instanceof NotFoundError === false) throw ex;
|
|
14
20
|
throw new WebinyError({
|
|
@@ -19,21 +25,22 @@ const getDeleteModelProgress = async (params)=>{
|
|
|
19
25
|
}
|
|
20
26
|
});
|
|
21
27
|
}
|
|
22
|
-
const
|
|
28
|
+
const accessControl = context.container.resolve(AccessControl);
|
|
29
|
+
const canAccessModel = await accessControl.canAccessModel({
|
|
23
30
|
model,
|
|
24
31
|
rwd: "d"
|
|
25
32
|
});
|
|
26
33
|
if (!canAccessModel) throw new NotAuthorizedError(`Not allowed to access content model "${model.name}".`);
|
|
27
|
-
const canAccessEntry = await
|
|
34
|
+
const canAccessEntry = await accessControl.canAccessEntry({
|
|
28
35
|
model,
|
|
29
36
|
rwd: "w"
|
|
30
37
|
});
|
|
31
38
|
if (!canAccessEntry) throw new NotAuthorizedError(`Not allowed to access "${model.modelId}" entries.`);
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const taskId =
|
|
39
|
+
const store = createDeleteModelStore(context.container.resolve(GlobalKeyValueStore), model.tenant);
|
|
40
|
+
const existing = await store.get(model.modelId);
|
|
41
|
+
const taskId = existing?.task;
|
|
35
42
|
if (!taskId) throw new Error(`Model "${modelId}" is not being deleted.`);
|
|
36
|
-
const task = await context.
|
|
43
|
+
const task = await context.container.resolve(GetTaskUseCase).execute(taskId);
|
|
37
44
|
if (task?.definitionId !== DELETE_MODEL_TASK) throw new WebinyError({
|
|
38
45
|
message: "The task which is deleting a model cannot be found.",
|
|
39
46
|
code: "DELETE_MODEL_TASK_NOT_FOUND",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql/deleteModel/getDeleteModelProgress.js","sources":["../../../src/graphql/deleteModel/getDeleteModelProgress.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types.js\";\nimport { WebinyError } from \"@webiny/error\";\nimport { NotFoundError } from \"@webiny/
|
|
1
|
+
{"version":3,"file":"graphql/deleteModel/getDeleteModelProgress.js","sources":["../../../src/graphql/deleteModel/getDeleteModelProgress.ts"],"sourcesContent":["import type { HcmsTasksContext } from \"~/types.js\";\nimport { WebinyError } from \"@webiny/error\";\nimport { NotFoundError } from \"@webiny/api-graphql\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport type {\n IDeleteCmsModelTask,\n IDeleteModelTaskInput,\n IDeleteModelTaskOutput\n} from \"~/features/DeleteModelTask/types.js\";\nimport { createDeleteModelStore } from \"~/helpers/store.js\";\nimport { DELETE_MODEL_TASK } from \"~/constants.js\";\nimport { getStatus } from \"~/graphql/deleteModel/status.js\";\nimport { NotAuthorizedError } from \"@webiny/api-headless-cms/utils/errors.js\";\nimport { AccessControl } from \"@webiny/api-headless-cms/features/shared/abstractions.js\";\nimport { GetModelUseCase } from \"@webiny/api-headless-cms/features/contentModel/GetModel/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/abstractions.js\";\nimport { GetTaskUseCase } from \"@webiny/background-tasks/api\";\n\nexport interface IGetDeleteModelProgress {\n readonly context: Pick<HcmsTasksContext, \"container\">;\n readonly modelId: string;\n}\n\nexport const getDeleteModelProgress = async (\n params: IGetDeleteModelProgress\n): Promise<IDeleteCmsModelTask> => {\n const { context, modelId } = params;\n\n let model: CmsModel;\n try {\n const modelResult = await context.container.resolve(GetModelUseCase).execute(modelId);\n if (modelResult.isFail()) {\n throw modelResult.error;\n }\n model = modelResult.value;\n } catch (ex) {\n if (ex instanceof NotFoundError === false) {\n throw ex;\n }\n throw new WebinyError({\n message: \"Model not found. It must have been deleted already.\",\n code: \"MODEL_ALREADY_DELETED_FOUND\",\n data: {\n model: modelId\n }\n });\n }\n\n const accessControl = context.container.resolve(AccessControl);\n const canAccessModel = await accessControl.canAccessModel({ model, rwd: \"d\" });\n if (!canAccessModel) {\n throw new NotAuthorizedError(`Not allowed to access content model \"${model.name}\".`);\n }\n\n const canAccessEntry = await accessControl.canAccessEntry({ model, rwd: \"w\" });\n if (!canAccessEntry) {\n throw new NotAuthorizedError(`Not allowed to access \"${model.modelId}\" entries.`);\n }\n\n const store = createDeleteModelStore(\n context.container.resolve(GlobalKeyValueStore),\n model.tenant\n );\n const existing = await store.get(model.modelId);\n\n const taskId = existing?.task;\n if (!taskId) {\n throw new Error(`Model \"${modelId}\" is not being deleted.`);\n }\n\n const task = await context.container\n .resolve(GetTaskUseCase)\n .execute<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.`,\n code: \"DELETE_MODEL_TASK_NOT_FOUND\",\n data: {\n model: model.modelId,\n task: taskId\n }\n });\n }\n return {\n id: task.id,\n status: getStatus(task.taskStatus),\n total: task.output?.total || 0,\n deleted: task.output?.deleted || 0\n };\n};\n"],"names":["getDeleteModelProgress","params","context","modelId","model","modelResult","GetModelUseCase","ex","NotFoundError","WebinyError","accessControl","AccessControl","canAccessModel","NotAuthorizedError","canAccessEntry","store","createDeleteModelStore","GlobalKeyValueStore","existing","taskId","Error","task","GetTaskUseCase","DELETE_MODEL_TASK","getStatus"],"mappings":";;;;;;;;;;AAuBO,MAAMA,yBAAyB,OAClCC;IAEA,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAE,GAAGF;IAE7B,IAAIG;IACJ,IAAI;QACA,MAAMC,cAAc,MAAMH,QAAQ,SAAS,CAAC,OAAO,CAACI,iBAAiB,OAAO,CAACH;QAC7E,IAAIE,YAAY,MAAM,IAClB,MAAMA,YAAY,KAAK;QAE3BD,QAAQC,YAAY,KAAK;IAC7B,EAAE,OAAOE,IAAI;QACT,IAAIA,cAAcC,kBAAkB,OAChC,MAAMD;QAEV,MAAM,IAAIE,YAAY;YAClB,SAAS;YACT,MAAM;YACN,MAAM;gBACF,OAAON;YACX;QACJ;IACJ;IAEA,MAAMO,gBAAgBR,QAAQ,SAAS,CAAC,OAAO,CAACS;IAChD,MAAMC,iBAAiB,MAAMF,cAAc,cAAc,CAAC;QAAEN;QAAO,KAAK;IAAI;IAC5E,IAAI,CAACQ,gBACD,MAAM,IAAIC,mBAAmB,CAAC,qCAAqC,EAAET,MAAM,IAAI,CAAC,EAAE,CAAC;IAGvF,MAAMU,iBAAiB,MAAMJ,cAAc,cAAc,CAAC;QAAEN;QAAO,KAAK;IAAI;IAC5E,IAAI,CAACU,gBACD,MAAM,IAAID,mBAAmB,CAAC,uBAAuB,EAAET,MAAM,OAAO,CAAC,UAAU,CAAC;IAGpF,MAAMW,QAAQC,uBACVd,QAAQ,SAAS,CAAC,OAAO,CAACe,sBAC1Bb,MAAM,MAAM;IAEhB,MAAMc,WAAW,MAAMH,MAAM,GAAG,CAACX,MAAM,OAAO;IAE9C,MAAMe,SAASD,UAAU;IACzB,IAAI,CAACC,QACD,MAAM,IAAIC,MAAM,CAAC,OAAO,EAAEjB,QAAQ,uBAAuB,CAAC;IAG9D,MAAMkB,OAAO,MAAMnB,QAAQ,SAAS,CAC/B,OAAO,CAACoB,gBACR,OAAO,CAAgDH;IAC5D,IAAIE,MAAM,iBAAiBE,mBACvB,MAAM,IAAId,YAAY;QAClB,SAAS;QACT,MAAM;QACN,MAAM;YACF,OAAOL,MAAM,OAAO;YACpB,MAAMe;QACV;IACJ;IAEJ,OAAO;QACH,IAAIE,KAAK,EAAE;QACX,QAAQG,UAAUH,KAAK,UAAU;QACjC,OAAOA,KAAK,MAAM,EAAE,SAAS;QAC7B,SAASA,KAAK,MAAM,EAAE,WAAW;IACrC;AACJ"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RequestContextInitializer } from "@webiny/event-handler-core";
|
|
2
2
|
import type { HcmsTasksContext } from "../../types.js";
|
|
3
|
-
export declare const createDeleteModelGraphQl: <T extends HcmsTasksContext = HcmsTasksContext>() =>
|
|
3
|
+
export declare const createDeleteModelGraphQl: <T extends HcmsTasksContext = HcmsTasksContext>() => RequestContextInitializer.Interface;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import zod from "zod";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { CmsGraphQLSchemaFactory, CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from "@webiny/api-headless-cms";
|
|
3
|
+
import { HeadlessCms } from "@webiny/api-headless-cms/features/shared/abstractions.js";
|
|
4
|
+
import { DeleteModelOperations } from "./abstractions.js";
|
|
5
|
+
import { ErrorResponse, Response, createResolverDecorator, resolve } from "@webiny/api-graphql";
|
|
5
6
|
import { createZodError } from "@webiny/utils";
|
|
6
7
|
import { validateConfirmation } from "../../helpers/confirmation.js";
|
|
7
8
|
const deleteValidation = zod.object({
|
|
@@ -24,12 +25,12 @@ const cancelValidation = zod.object({
|
|
|
24
25
|
const getValidation = zod.object({
|
|
25
26
|
modelId: zod.string()
|
|
26
27
|
}).readonly();
|
|
27
|
-
const createDeleteModelGraphQl = ()=>{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
const createDeleteModelGraphQl = ()=>({
|
|
29
|
+
async init (inputContext) {
|
|
30
|
+
const ready = await isHeadlessCmsReady(inputContext);
|
|
31
|
+
if (!ready || !inputContext.container.resolve(HeadlessCms).MANAGE) return;
|
|
32
|
+
const plugin = new CmsGraphQLSchemaPlugin({
|
|
33
|
+
typeDefs: `
|
|
33
34
|
enum DeleteCmsModelTaskStatus {
|
|
34
35
|
running
|
|
35
36
|
done
|
|
@@ -77,64 +78,66 @@ const createDeleteModelGraphQl = ()=>{
|
|
|
77
78
|
cancelFullyDeleteModel(modelId: ID!): CancelDeleteCmsModelResponse!
|
|
78
79
|
}
|
|
79
80
|
`,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
resolvers: {
|
|
82
|
+
CmsContentModel: {
|
|
83
|
+
isBeingDeleted: async (model, _, context)=>{
|
|
84
|
+
try {
|
|
85
|
+
return await context.container.resolve(DeleteModelOperations).isModelBeingDeleted(model.modelId);
|
|
86
|
+
} catch (ex) {
|
|
87
|
+
console.error(ex);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
87
90
|
}
|
|
88
|
-
|
|
91
|
+
},
|
|
92
|
+
Query: {
|
|
93
|
+
getDeleteModelProgress: async (_, args, context)=>resolve(async ()=>{
|
|
94
|
+
const input = getValidation.safeParse(args);
|
|
95
|
+
if (input.error) throw createZodError(input.error);
|
|
96
|
+
return context.container.resolve(DeleteModelOperations).getDeleteModelProgress(input.data.modelId);
|
|
97
|
+
})
|
|
98
|
+
},
|
|
99
|
+
Mutation: {
|
|
100
|
+
fullyDeleteModel: async (_, args, context)=>resolve(async ()=>{
|
|
101
|
+
const input = deleteValidation.safeParse(args);
|
|
102
|
+
if (input.error) throw createZodError(input.error);
|
|
103
|
+
return context.container.resolve(DeleteModelOperations).fullyDeleteModel(input.data.modelId);
|
|
104
|
+
}),
|
|
105
|
+
cancelFullyDeleteModel: async (_, args, context)=>resolve(async ()=>{
|
|
106
|
+
const input = cancelValidation.safeParse(args);
|
|
107
|
+
if (input.error) throw createZodError(input.error);
|
|
108
|
+
return context.container.resolve(DeleteModelOperations).cancelFullyDeleteModel(input.data.modelId);
|
|
109
|
+
})
|
|
89
110
|
}
|
|
90
111
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
resolverDecorators: {
|
|
113
|
+
["Query.listContentModels"]: [
|
|
114
|
+
createResolverDecorator((resolver)=>async (parent, args, context, info)=>{
|
|
115
|
+
const result = await resolver(parent, args, context, info);
|
|
116
|
+
if (result.error || !Array.isArray(result.data)) return result;
|
|
117
|
+
if (args?.includeBeingDeleted !== false) return result;
|
|
118
|
+
const listed = result.data;
|
|
119
|
+
try {
|
|
120
|
+
const beingDeletedList = await context.container.resolve(DeleteModelOperations).listModelsBeingDeleted();
|
|
121
|
+
return new Response(listed.filter((model)=>{
|
|
122
|
+
if (!model?.modelId) return false;
|
|
123
|
+
if (beingDeletedList.some((item)=>item.modelId === model.modelId)) return false;
|
|
124
|
+
return true;
|
|
125
|
+
}));
|
|
126
|
+
} catch (ex) {
|
|
127
|
+
return new ErrorResponse(ex);
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
]
|
|
109
131
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
const beingDeletedList = await context.cms.listModelsBeingDeleted();
|
|
120
|
-
return new Response(listed.filter((model)=>{
|
|
121
|
-
if (!model?.modelId) return false;
|
|
122
|
-
if (beingDeletedList.some((item)=>item.modelId === model.modelId)) return false;
|
|
123
|
-
return true;
|
|
124
|
-
}));
|
|
125
|
-
} catch (ex) {
|
|
126
|
-
return new ErrorResponse(ex);
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
plugin.name = "headless-cms.graphql.fullyDeleteModel";
|
|
133
|
-
inputContext.plugins.register(plugin);
|
|
132
|
+
});
|
|
133
|
+
plugin.name = "headless-cms.graphql.fullyDeleteModel";
|
|
134
|
+
inputContext.container.registerInstance(CmsGraphQLSchemaFactory, {
|
|
135
|
+
execute: ()=>[
|
|
136
|
+
plugin
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
134
140
|
});
|
|
135
|
-
contextPlugin.name = "headless-cms.context.createDeleteModelGraphQl";
|
|
136
|
-
return contextPlugin;
|
|
137
|
-
};
|
|
138
141
|
export { createDeleteModelGraphQl };
|
|
139
142
|
|
|
140
143
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql/deleteModel/index.js","sources":["../../../src/graphql/deleteModel/index.ts"],"sourcesContent":["import zod from \"zod\";\nimport { ContextPlugin } from \"@webiny/api\";\nimport { CmsGraphQLSchemaPlugin } from \"@webiny/api-headless-cms\";\nimport { isHeadlessCmsReady } from \"@webiny/api-headless-cms\";\nimport type { HcmsTasksContext } from \"~/types.js\";\nimport { createResolverDecorator } from \"@webiny/handler-graphql\";\nimport { ErrorResponse } from \"@webiny/handler-graphql\";\nimport { resolve } from \"@webiny/handler-graphql\";\nimport { Response } from \"@webiny/handler-graphql\";\nimport { createZodError } from \"@webiny/utils\";\nimport type { IDeleteCmsModelTask } from \"~/features/DeleteModelTask/types.js\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { validateConfirmation } from \"~/helpers/confirmation.js\";\n\nconst deleteValidation = zod\n .object({\n modelId: zod.string(),\n confirmation: zod.string()\n })\n .superRefine((value, context) => {\n if (validateConfirmation(value)) {\n return;\n }\n context.addIssue({\n code: zod.ZodIssueCode.custom,\n message: `Confirmation input does not match.`,\n fatal: true,\n path: [\"confirmation\"]\n });\n })\n .readonly();\n\nconst cancelValidation = zod\n .object({\n modelId: zod.string()\n })\n .readonly();\n\nconst getValidation = zod\n .object({\n modelId: zod.string()\n })\n .readonly();\n\nexport const createDeleteModelGraphQl = <T extends HcmsTasksContext = HcmsTasksContext>() => {\n const contextPlugin = new ContextPlugin<T>(async inputContext => {\n const ready = await isHeadlessCmsReady(inputContext);\n\n if (!ready || !inputContext.cms.MANAGE) {\n return;\n }\n\n const plugin = new CmsGraphQLSchemaPlugin<T>({\n typeDefs: /* GraphQL */ `\n enum DeleteCmsModelTaskStatus {\n running\n done\n error\n canceled\n }\n type DeleteCmsModelTask {\n id: ID!\n status: DeleteCmsModelTaskStatus!\n deleted: Int!\n total: Int!\n }\n\n type GetDeleteCmsModelProgressResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n type FullyDeleteCmsModelResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n type CancelDeleteCmsModelResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n extend type CmsContentModel {\n isBeingDeleted: Boolean!\n }\n\n extend type Query {\n getDeleteModelProgress(modelId: ID!): GetDeleteCmsModelProgressResponse!\n listContentModels(\n includeBeingDeleted: Boolean = false\n ): CmsContentModelListResponse\n }\n\n extend type Mutation {\n fullyDeleteModel(\n modelId: ID!\n confirmation: String!\n ): FullyDeleteCmsModelResponse!\n cancelFullyDeleteModel(modelId: ID!): CancelDeleteCmsModelResponse!\n }\n `,\n resolvers: {\n CmsContentModel: {\n isBeingDeleted: async (model: CmsModel, _: unknown, context) => {\n try {\n return await context.cms.isModelBeingDeleted(model.modelId);\n } catch (ex) {\n console.error(ex);\n }\n return true;\n }\n },\n Query: {\n getDeleteModelProgress: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = getValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return await context.cms.getDeleteModelProgress(input.data.modelId);\n });\n }\n },\n Mutation: {\n fullyDeleteModel: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = deleteValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return await context.cms.fullyDeleteModel(input.data.modelId);\n });\n },\n cancelFullyDeleteModel: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = cancelValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return await context.cms.cancelFullyDeleteModel(input.data.modelId);\n });\n }\n }\n },\n resolverDecorators: {\n [\"Query.listContentModels\"]: [\n createResolverDecorator<any, any, HcmsTasksContext>(\n resolver => async (parent, args, context, info) => {\n // TODO @bruno figure out how to fix these types\n const result = (await resolver(parent, args, context, info)) as any;\n if (result.error || !Array.isArray(result.data)) {\n return result;\n }\n\n if (args?.includeBeingDeleted !== false) {\n return result;\n }\n\n const listed = result.data as CmsModel[];\n\n try {\n const beingDeletedList = await context.cms.listModelsBeingDeleted();\n\n return new Response(\n listed.filter(model => {\n if (!model?.modelId) {\n return false;\n } else if (\n beingDeletedList.some(\n item => item.modelId === model.modelId\n )\n ) {\n return false;\n }\n return true;\n })\n );\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n )\n ]\n }\n });\n plugin.name = \"headless-cms.graphql.fullyDeleteModel\";\n inputContext.plugins.register(plugin);\n });\n contextPlugin.name = \"headless-cms.context.createDeleteModelGraphQl\";\n return contextPlugin;\n};\n"],"names":["deleteValidation","zod","value","context","validateConfirmation","cancelValidation","getValidation","createDeleteModelGraphQl","contextPlugin","ContextPlugin","inputContext","ready","isHeadlessCmsReady","plugin","CmsGraphQLSchemaPlugin","model","_","ex","console","args","resolve","input","createZodError","createResolverDecorator","resolver","parent","info","result","Array","listed","beingDeletedList","Response","item","ErrorResponse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"graphql/deleteModel/index.js","sources":["../../../src/graphql/deleteModel/index.ts"],"sourcesContent":["import zod from \"zod\";\nimport type { RequestContextInitializer } from \"@webiny/event-handler-core\";\nimport {\n CmsGraphQLSchemaPlugin,\n CmsGraphQLSchemaFactory,\n isHeadlessCmsReady\n} from \"@webiny/api-headless-cms\";\nimport { HeadlessCms } from \"@webiny/api-headless-cms/features/shared/abstractions.js\";\nimport { DeleteModelOperations } from \"~/graphql/deleteModel/abstractions.js\";\nimport type { HcmsTasksContext } from \"~/types.js\";\nimport { createResolverDecorator } from \"@webiny/api-graphql\";\nimport { ErrorResponse } from \"@webiny/api-graphql\";\nimport { resolve } from \"@webiny/api-graphql\";\nimport { Response } from \"@webiny/api-graphql\";\nimport { createZodError } from \"@webiny/utils\";\nimport type { IDeleteCmsModelTask } from \"~/features/DeleteModelTask/types.js\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { validateConfirmation } from \"~/helpers/confirmation.js\";\n\nconst deleteValidation = zod\n .object({\n modelId: zod.string(),\n confirmation: zod.string()\n })\n .superRefine((value, context) => {\n if (validateConfirmation(value)) {\n return;\n }\n context.addIssue({\n code: zod.ZodIssueCode.custom,\n message: `Confirmation input does not match.`,\n fatal: true,\n path: [\"confirmation\"]\n });\n })\n .readonly();\n\nconst cancelValidation = zod\n .object({\n modelId: zod.string()\n })\n .readonly();\n\nconst getValidation = zod\n .object({\n modelId: zod.string()\n })\n .readonly();\n\nexport const createDeleteModelGraphQl = <\n T extends HcmsTasksContext = HcmsTasksContext\n>(): RequestContextInitializer.Interface => ({\n async init(inputContext: T) {\n const ready = await isHeadlessCmsReady(inputContext);\n\n if (!ready || !inputContext.container.resolve(HeadlessCms).MANAGE) {\n return;\n }\n\n const plugin = new CmsGraphQLSchemaPlugin<T>({\n typeDefs: /* GraphQL */ `\n enum DeleteCmsModelTaskStatus {\n running\n done\n error\n canceled\n }\n type DeleteCmsModelTask {\n id: ID!\n status: DeleteCmsModelTaskStatus!\n deleted: Int!\n total: Int!\n }\n\n type GetDeleteCmsModelProgressResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n type FullyDeleteCmsModelResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n type CancelDeleteCmsModelResponse {\n data: DeleteCmsModelTask\n error: CmsError\n }\n\n extend type CmsContentModel {\n isBeingDeleted: Boolean!\n }\n\n extend type Query {\n getDeleteModelProgress(modelId: ID!): GetDeleteCmsModelProgressResponse!\n listContentModels(\n includeBeingDeleted: Boolean = false\n ): CmsContentModelListResponse\n }\n\n extend type Mutation {\n fullyDeleteModel(\n modelId: ID!\n confirmation: String!\n ): FullyDeleteCmsModelResponse!\n cancelFullyDeleteModel(modelId: ID!): CancelDeleteCmsModelResponse!\n }\n `,\n resolvers: {\n CmsContentModel: {\n isBeingDeleted: async (model: CmsModel, _: unknown, context) => {\n try {\n return await context.container\n .resolve(DeleteModelOperations)\n .isModelBeingDeleted(model.modelId);\n } catch (ex) {\n console.error(ex);\n }\n return true;\n }\n },\n Query: {\n getDeleteModelProgress: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = getValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return context.container\n .resolve(DeleteModelOperations)\n .getDeleteModelProgress(input.data.modelId);\n });\n }\n },\n Mutation: {\n fullyDeleteModel: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = deleteValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return context.container\n .resolve(DeleteModelOperations)\n .fullyDeleteModel(input.data.modelId);\n });\n },\n cancelFullyDeleteModel: async (_: unknown, args: unknown, context) => {\n return resolve<IDeleteCmsModelTask>(async () => {\n const input = cancelValidation.safeParse(args);\n if (input.error) {\n throw createZodError(input.error);\n }\n return context.container\n .resolve(DeleteModelOperations)\n .cancelFullyDeleteModel(input.data.modelId);\n });\n }\n }\n },\n resolverDecorators: {\n [\"Query.listContentModels\"]: [\n createResolverDecorator<any, any, HcmsTasksContext>(\n resolver => async (parent, args, context, info) => {\n // TODO @bruno figure out how to fix these types\n const result = (await resolver(parent, args, context, info)) as any;\n if (result.error || !Array.isArray(result.data)) {\n return result;\n }\n\n if (args?.includeBeingDeleted !== false) {\n return result;\n }\n\n const listed = result.data as CmsModel[];\n\n try {\n const beingDeletedList = await context.container\n .resolve(DeleteModelOperations)\n .listModelsBeingDeleted();\n\n return new Response(\n listed.filter(model => {\n if (!model?.modelId) {\n return false;\n } else if (\n beingDeletedList.some(\n item => item.modelId === model.modelId\n )\n ) {\n return false;\n }\n return true;\n })\n );\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n )\n ]\n }\n });\n plugin.name = \"headless-cms.graphql.fullyDeleteModel\";\n inputContext.container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => [plugin]\n });\n }\n});\n"],"names":["deleteValidation","zod","value","context","validateConfirmation","cancelValidation","getValidation","createDeleteModelGraphQl","inputContext","ready","isHeadlessCmsReady","HeadlessCms","plugin","CmsGraphQLSchemaPlugin","model","_","DeleteModelOperations","ex","console","args","resolve","input","createZodError","createResolverDecorator","resolver","parent","info","result","Array","listed","beingDeletedList","Response","item","ErrorResponse","CmsGraphQLSchemaFactory"],"mappings":"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"}
|
package/helpers/store.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/abstractions.js";
|
|
2
2
|
import type { IStoreValue } from "../features/DeleteModelTask/types.js";
|
|
3
|
-
export interface ICreateStoreKeyParams {
|
|
4
|
-
modelId: string;
|
|
5
|
-
tenant: string;
|
|
6
|
-
}
|
|
7
|
-
export declare const createStoreNamespace: (params: Pick<ICreateStoreKeyParams, "tenant">) => string;
|
|
8
|
-
export declare const createStoreKey: (params: ICreateStoreKeyParams) => StorageKey;
|
|
9
3
|
export declare const createStoreValue: (params: IStoreValue) => IStoreValue;
|
|
4
|
+
export interface IDeleteModelStore {
|
|
5
|
+
list(): Promise<IStoreValue[]>;
|
|
6
|
+
get(modelId: string): Promise<IStoreValue | null>;
|
|
7
|
+
set(value: IStoreValue): Promise<void>;
|
|
8
|
+
remove(modelId: string): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Delete-model tracking store, backed by the flavour-agnostic api-core key-value store (registered
|
|
12
|
+
* by both the DynamoDB and SQL cores). Replaces the old `@webiny/db` `DbInstance.store`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createDeleteModelStore: (store: GlobalKeyValueStore.Interface, tenant: string) => IDeleteModelStore;
|
package/helpers/store.js
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
|
-
const
|
|
2
|
-
const createStoreKey = (params)=>`${createStoreNamespace(params)}${params.modelId}`;
|
|
1
|
+
const STORE_KEY = "cmsModelsBeingDeleted";
|
|
3
2
|
const createStoreValue = (params)=>({
|
|
4
3
|
modelId: params.modelId,
|
|
5
4
|
task: params.task,
|
|
6
5
|
identity: params.identity,
|
|
7
6
|
tenant: params.tenant
|
|
8
7
|
});
|
|
9
|
-
|
|
8
|
+
const createDeleteModelStore = (store, tenant)=>{
|
|
9
|
+
const options = {
|
|
10
|
+
scope: tenant
|
|
11
|
+
};
|
|
12
|
+
const readMap = async ()=>{
|
|
13
|
+
const result = await store.get(STORE_KEY, options);
|
|
14
|
+
return result.isFail() ? {} : result.value ?? {};
|
|
15
|
+
};
|
|
16
|
+
const writeMap = (map)=>store.set(STORE_KEY, map, options).then(()=>void 0);
|
|
17
|
+
return {
|
|
18
|
+
async list () {
|
|
19
|
+
return Object.values(await readMap());
|
|
20
|
+
},
|
|
21
|
+
async get (modelId) {
|
|
22
|
+
const map = await readMap();
|
|
23
|
+
return map[modelId] ?? null;
|
|
24
|
+
},
|
|
25
|
+
async set (value) {
|
|
26
|
+
const map = await readMap();
|
|
27
|
+
map[value.modelId] = value;
|
|
28
|
+
await writeMap(map);
|
|
29
|
+
},
|
|
30
|
+
async remove (modelId) {
|
|
31
|
+
const map = await readMap();
|
|
32
|
+
if (!(modelId in map)) return;
|
|
33
|
+
delete map[modelId];
|
|
34
|
+
await writeMap(map);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export { createDeleteModelStore, createStoreValue };
|
|
10
39
|
|
|
11
40
|
//# sourceMappingURL=store.js.map
|
package/helpers/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers/store.js","sources":["../../src/helpers/store.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"helpers/store.js","sources":["../../src/helpers/store.ts"],"sourcesContent":["import { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/abstractions.js\";\nimport type { IStoreValue } from \"~/features/DeleteModelTask/types.js\";\n\n/**\n * A single key per tenant holds the map of models currently being deleted (modelId -> record). The\n * api-core key-value store is get/set/delete only (no prefix scan), so we keep ONE map entry and\n * enumerate in memory rather than one entry per model. Tenant isolation comes from the store scope.\n */\nconst STORE_KEY = \"cmsModelsBeingDeleted\";\n\ntype StoreMap = Record<string, IStoreValue>;\n\nexport const createStoreValue = (params: IStoreValue): IStoreValue => {\n return {\n modelId: params.modelId,\n task: params.task,\n identity: params.identity,\n tenant: params.tenant\n };\n};\n\nexport interface IDeleteModelStore {\n list(): Promise<IStoreValue[]>;\n get(modelId: string): Promise<IStoreValue | null>;\n set(value: IStoreValue): Promise<void>;\n remove(modelId: string): Promise<void>;\n}\n\n/**\n * Delete-model tracking store, backed by the flavour-agnostic api-core key-value store (registered\n * by both the DynamoDB and SQL cores). Replaces the old `@webiny/db` `DbInstance.store`.\n */\nexport const createDeleteModelStore = (\n store: GlobalKeyValueStore.Interface,\n tenant: string\n): IDeleteModelStore => {\n const options = { scope: tenant };\n\n const readMap = async (): Promise<StoreMap> => {\n const result = await store.get<StoreMap>(STORE_KEY, options);\n // A missing key is a failed Result (KeyNotFound) — treat as an empty map.\n return result.isFail() ? {} : (result.value ?? {});\n };\n\n const writeMap = (map: StoreMap): Promise<void> => {\n return store.set(STORE_KEY, map, options).then(() => undefined);\n };\n\n return {\n async list() {\n return Object.values(await readMap());\n },\n async get(modelId) {\n const map = await readMap();\n return map[modelId] ?? null;\n },\n async set(value) {\n const map = await readMap();\n map[value.modelId] = value;\n await writeMap(map);\n },\n async remove(modelId) {\n const map = await readMap();\n if (!(modelId in map)) {\n return;\n }\n delete map[modelId];\n await writeMap(map);\n }\n };\n};\n"],"names":["STORE_KEY","createStoreValue","params","createDeleteModelStore","store","tenant","options","readMap","result","writeMap","map","undefined","Object","modelId","value"],"mappings":"AAQA,MAAMA,YAAY;AAIX,MAAMC,mBAAmB,CAACC,SACtB;QACH,SAASA,OAAO,OAAO;QACvB,MAAMA,OAAO,IAAI;QACjB,UAAUA,OAAO,QAAQ;QACzB,QAAQA,OAAO,MAAM;IACzB;AAcG,MAAMC,yBAAyB,CAClCC,OACAC;IAEA,MAAMC,UAAU;QAAE,OAAOD;IAAO;IAEhC,MAAME,UAAU;QACZ,MAAMC,SAAS,MAAMJ,MAAM,GAAG,CAAWJ,WAAWM;QAEpD,OAAOE,OAAO,MAAM,KAAK,CAAC,IAAKA,OAAO,KAAK,IAAI,CAAC;IACpD;IAEA,MAAMC,WAAW,CAACC,MACPN,MAAM,GAAG,CAACJ,WAAWU,KAAKJ,SAAS,IAAI,CAAC,IAAMK;IAGzD,OAAO;QACH,MAAM;YACF,OAAOC,OAAO,MAAM,CAAC,MAAML;QAC/B;QACA,MAAM,KAAIM,OAAO;YACb,MAAMH,MAAM,MAAMH;YAClB,OAAOG,GAAG,CAACG,QAAQ,IAAI;QAC3B;QACA,MAAM,KAAIC,KAAK;YACX,MAAMJ,MAAM,MAAMH;YAClBG,GAAG,CAACI,MAAM,OAAO,CAAC,GAAGA;YACrB,MAAML,SAASC;QACnB;QACA,MAAM,QAAOG,OAAO;YAChB,MAAMH,MAAM,MAAMH;YAClB,IAAI,CAAEM,CAAAA,WAAWH,GAAE,GACf;YAEJ,OAAOA,GAAG,CAACG,QAAQ;YACnB,MAAMJ,SAASC;QACnB;IACJ;AACJ"}
|
package/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare const createHcmsTasks: () => (import("@webiny/api").ContextPlugin<import("@webiny/api/types").Context> | (import("@webiny/api").ContextPlugin<import("@webiny/api/types").Context> | (import("@webiny/handler-aws/eventBridge").EventBridgeEventHandler<"WebinyEmptyTrashBin", Record<string, any>, any> | import("@webiny/handler/index").HandlerOnRequestPlugin<import("@webiny/handler/types").Context>)[] | import("@webiny/handler/index").BeforeHandlerPlugin<import("@webiny/api-headless-cms-bulk-actions/types").HcmsBulkActionsContext>)[])[];
|
|
1
|
+
export { HcmsTasksFeature } from "./HcmsTasksFeature.js";
|
package/index.js
CHANGED
|
@@ -1,22 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { createContextPlugin } from "@webiny/api";
|
|
3
|
-
import { DeleteModelTaskFeature } from "./features/DeleteModelTask/feature.js";
|
|
4
|
-
import { createDeleteModelCrud } from "./graphql/deleteModel/crud.js";
|
|
5
|
-
import { createDeleteModelGraphQl } from "./graphql/deleteModel/index.js";
|
|
6
|
-
const createDeleteModelTask = ()=>[
|
|
7
|
-
createDeleteModelCrud(),
|
|
8
|
-
createDeleteModelGraphQl(),
|
|
9
|
-
createContextPlugin((context)=>{
|
|
10
|
-
DeleteModelTaskFeature.register(context.container);
|
|
11
|
-
})
|
|
12
|
-
];
|
|
13
|
-
const createHcmsTasks = ()=>[
|
|
14
|
-
createHcmsBulkActions({
|
|
15
|
-
batchSize: 100
|
|
16
|
-
}),
|
|
17
|
-
createEmptyTrashBinsTask(),
|
|
18
|
-
createDeleteModelTask()
|
|
19
|
-
];
|
|
20
|
-
export { createDeleteModelTask, createHcmsTasks };
|
|
21
|
-
|
|
22
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export { HcmsTasksFeature } from "./HcmsTasksFeature.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/api-headless-cms-tasks",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -17,27 +17,27 @@
|
|
|
17
17
|
},
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@webiny/api": "6.
|
|
21
|
-
"@webiny/api-
|
|
22
|
-
"@webiny/api-headless-cms": "6.
|
|
23
|
-
"@webiny/api-headless-cms-bulk-actions": "6.
|
|
24
|
-
"@webiny/background-tasks": "6.
|
|
25
|
-
"@webiny/
|
|
26
|
-
"@webiny/
|
|
27
|
-
"@webiny/
|
|
28
|
-
"
|
|
29
|
-
"@webiny/utils": "6.4.5",
|
|
20
|
+
"@webiny/api-aco": "6.6.0-alpha.0",
|
|
21
|
+
"@webiny/api-graphql": "6.6.0-alpha.0",
|
|
22
|
+
"@webiny/api-headless-cms": "6.6.0-alpha.0",
|
|
23
|
+
"@webiny/api-headless-cms-bulk-actions": "6.6.0-alpha.0",
|
|
24
|
+
"@webiny/background-tasks": "6.6.0-alpha.0",
|
|
25
|
+
"@webiny/error": "6.6.0-alpha.0",
|
|
26
|
+
"@webiny/feature": "6.6.0-alpha.0",
|
|
27
|
+
"@webiny/utils": "6.6.0-alpha.0",
|
|
28
|
+
"graphql": "16.14.2",
|
|
30
29
|
"zod": "4.4.3"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
|
-
"@webiny/api-core": "6.
|
|
34
|
-
"@webiny/
|
|
35
|
-
"@webiny/
|
|
36
|
-
"@webiny/
|
|
37
|
-
"@webiny/
|
|
38
|
-
"@webiny/
|
|
39
|
-
"@webiny/
|
|
40
|
-
"
|
|
32
|
+
"@webiny/api-core": "6.6.0-alpha.0",
|
|
33
|
+
"@webiny/api-headless-cms-testing": "6.6.0-alpha.0",
|
|
34
|
+
"@webiny/api-opensearch": "6.6.0-alpha.0",
|
|
35
|
+
"@webiny/build-tools": "6.6.0-alpha.0",
|
|
36
|
+
"@webiny/event-handler-core": "6.6.0-alpha.0",
|
|
37
|
+
"@webiny/handler": "6.6.0-alpha.0",
|
|
38
|
+
"@webiny/plugins": "6.6.0-alpha.0",
|
|
39
|
+
"@webiny/project-utils": "6.6.0-alpha.0",
|
|
40
|
+
"typescript": "7.0.2",
|
|
41
41
|
"vitest": "4.1.10"
|
|
42
42
|
},
|
|
43
43
|
"publishConfig": {
|
package/types.d.ts
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
import type { HcmsBulkActionsContext } from "@webiny/api-headless-cms-bulk-actions/types.js";
|
|
2
2
|
import type { AcoContext } from "@webiny/api-aco/types.js";
|
|
3
|
-
import type { HeadlessCms } from "@webiny/api-headless-cms/types/index.js";
|
|
4
|
-
import type { IDeleteCmsModelTask, IStoreValue } from "./features/DeleteModelTask/types.js";
|
|
5
|
-
export interface HeadlessCmsFullyDeleteModel {
|
|
6
|
-
fullyDeleteModel: (modelId: string) => Promise<IDeleteCmsModelTask>;
|
|
7
|
-
cancelFullyDeleteModel: (modelId: string) => Promise<IDeleteCmsModelTask>;
|
|
8
|
-
getDeleteModelProgress: (modelId: string) => Promise<IDeleteCmsModelTask>;
|
|
9
|
-
isModelBeingDeleted: (modelId: string) => Promise<boolean>;
|
|
10
|
-
listModelsBeingDeleted: () => Promise<IStoreValue[]>;
|
|
11
|
-
}
|
|
12
3
|
export interface HcmsTasksContext extends HcmsBulkActionsContext, AcoContext {
|
|
13
|
-
cms: HeadlessCms & HeadlessCmsFullyDeleteModel;
|
|
14
4
|
}
|
package/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import {\n createEmptyTrashBinsTask,\n createHcmsBulkActions\n} from \"@webiny/api-headless-cms-bulk-actions\";\nimport { createContextPlugin } from \"@webiny/api\";\nimport { DeleteModelTaskFeature } from \"~/features/DeleteModelTask/feature.js\";\nimport { createDeleteModelCrud } from \"~/graphql/deleteModel/crud.js\";\nimport { createDeleteModelGraphQl } from \"~/graphql/deleteModel/index.js\";\n\nexport const createDeleteModelTask = () => {\n return [\n createDeleteModelCrud(),\n createDeleteModelGraphQl(),\n createContextPlugin(context => {\n DeleteModelTaskFeature.register(context.container);\n })\n ];\n};\n\nexport const createHcmsTasks = () => [\n createHcmsBulkActions({ batchSize: 100 }),\n createEmptyTrashBinsTask(),\n createDeleteModelTask()\n];\n"],"names":["createDeleteModelTask","createDeleteModelCrud","createDeleteModelGraphQl","createContextPlugin","context","DeleteModelTaskFeature","createHcmsTasks","createHcmsBulkActions","createEmptyTrashBinsTask"],"mappings":";;;;;AASO,MAAMA,wBAAwB,IAC1B;QACHC;QACAC;QACAC,oBAAoBC,CAAAA;YAChBC,uBAAuB,QAAQ,CAACD,QAAQ,SAAS;QACrD;KACH;AAGE,MAAME,kBAAkB,IAAM;QACjCC,sBAAsB;YAAE,WAAW;QAAI;QACvCC;QACAR;KACH"}
|