@webiny/api-headless-cms-bulk-actions 6.4.11 → 6.6.0-alpha.1

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.
Files changed (77) hide show
  1. package/HcmsBulkActionsFeature.d.ts +7 -0
  2. package/HcmsBulkActionsFeature.js +32 -0
  3. package/HcmsBulkActionsFeature.js.map +1 -0
  4. package/exports/api/cms/entry.d.ts +1 -0
  5. package/exports/api/cms/entry.js +1 -0
  6. package/features/DeleteEntriesBulkAction/DeleteEntriesBulkAction.d.ts +1 -1
  7. package/features/DeleteEntriesBulkAction/DeleteEntriesBulkAction.js +0 -1
  8. package/features/DeleteEntriesBulkAction/DeleteEntriesBulkAction.js.map +1 -1
  9. package/features/EntriesBulkAction/abstractions.d.ts +7 -7
  10. package/features/EntriesBulkAction/abstractions.js.map +1 -1
  11. package/features/EntriesBulkAction/createBulkActionTasks.d.ts +47 -4
  12. package/features/EntriesBulkAction/createBulkActionTasks.js +132 -117
  13. package/features/EntriesBulkAction/createBulkActionTasks.js.map +1 -1
  14. package/features/EntriesBulkAction/internals/ChildTasksCleanup.d.ts +2 -2
  15. package/features/EntriesBulkAction/internals/ChildTasksCleanup.js +8 -8
  16. package/features/EntriesBulkAction/internals/ChildTasksCleanup.js.map +1 -1
  17. package/features/EntriesBulkAction/internals/CreateTasksByModel.d.ts +4 -4
  18. package/features/EntriesBulkAction/internals/CreateTasksByModel.js +7 -6
  19. package/features/EntriesBulkAction/internals/CreateTasksByModel.js.map +1 -1
  20. package/features/EntriesBulkAction/internals/ProcessTask.d.ts +1 -1
  21. package/features/EntriesBulkAction/internals/ProcessTasksByModel.d.ts +3 -3
  22. package/features/EntriesBulkAction/internals/ProcessTasksByModel.js +3 -3
  23. package/features/EntriesBulkAction/internals/ProcessTasksByModel.js.map +1 -1
  24. package/features/EntriesBulkAction/internals/TaskCache.d.ts +4 -4
  25. package/features/EntriesBulkAction/internals/TaskCache.js +2 -2
  26. package/features/EntriesBulkAction/internals/TaskCache.js.map +1 -1
  27. package/features/MoveToFolderBulkAction/MoveToFolderBulkAction.d.ts +1 -1
  28. package/features/MoveToFolderBulkAction/MoveToFolderBulkAction.js +3 -2
  29. package/features/MoveToFolderBulkAction/MoveToFolderBulkAction.js.map +1 -1
  30. package/features/MoveToTrashBulkAction/MoveToTrashBulkAction.d.ts +1 -1
  31. package/features/MoveToTrashBulkAction/MoveToTrashBulkAction.js +0 -1
  32. package/features/MoveToTrashBulkAction/MoveToTrashBulkAction.js.map +1 -1
  33. package/features/PublishEntriesBulkAction/PublishEntriesBulkAction.d.ts +1 -1
  34. package/features/PublishEntriesBulkAction/PublishEntriesBulkAction.js +3 -2
  35. package/features/PublishEntriesBulkAction/PublishEntriesBulkAction.js.map +1 -1
  36. package/features/RestoreEntriesBulkAction/RestoreEntriesBulkAction.d.ts +1 -1
  37. package/features/RestoreEntriesBulkAction/RestoreEntriesBulkAction.js +0 -1
  38. package/features/RestoreEntriesBulkAction/RestoreEntriesBulkAction.js.map +1 -1
  39. package/features/UnpublishEntriesBulkAction/UnpublishEntriesBulkAction.d.ts +1 -1
  40. package/features/UnpublishEntriesBulkAction/UnpublishEntriesBulkAction.js +3 -2
  41. package/features/UnpublishEntriesBulkAction/UnpublishEntriesBulkAction.js.map +1 -1
  42. package/graphql/BulkActionsGraphQLSchema.d.ts +12 -0
  43. package/graphql/BulkActionsGraphQLSchema.js +106 -0
  44. package/graphql/BulkActionsGraphQLSchema.js.map +1 -0
  45. package/graphql/createBulkActionGraphQL.js +21 -18
  46. package/graphql/createBulkActionGraphQL.js.map +1 -1
  47. package/graphql/createDefaultGraphQL.d.ts +7 -2
  48. package/graphql/createDefaultGraphQL.js +41 -39
  49. package/graphql/createDefaultGraphQL.js.map +1 -1
  50. package/index.d.ts +2 -7
  51. package/index.js +1 -46
  52. package/package.json +18 -16
  53. package/tasks/EmptyTrashBinTaskDefinition.d.ts +1 -1
  54. package/tasks/EmptyTrashBinTaskDefinition.js +0 -6
  55. package/tasks/EmptyTrashBinTaskDefinition.js.map +1 -1
  56. package/types.d.ts +2 -0
  57. package/types.js.map +1 -1
  58. package/features/BulkActionContext/abstractions.d.ts +0 -5
  59. package/features/BulkActionContext/abstractions.js +0 -5
  60. package/features/BulkActionContext/abstractions.js.map +0 -1
  61. package/features/BulkActionContext/index.d.ts +0 -1
  62. package/features/BulkActionContext/index.js +0 -1
  63. package/handlers/eventBridgeEventHandler.d.ts +0 -1
  64. package/handlers/eventBridgeEventHandler.js +0 -28
  65. package/handlers/eventBridgeEventHandler.js.map +0 -1
  66. package/handlers/index.d.ts +0 -1
  67. package/handlers/index.js +0 -9
  68. package/handlers/index.js.map +0 -1
  69. package/handlers/setupEventsTenant.d.ts +0 -1
  70. package/handlers/setupEventsTenant.js +0 -10
  71. package/handlers/setupEventsTenant.js.map +0 -1
  72. package/index.js.map +0 -1
  73. package/tasks/createEmptyTrashBinsTask.d.ts +0 -1
  74. package/tasks/createEmptyTrashBinsTask.js +0 -8
  75. package/tasks/createEmptyTrashBinsTask.js.map +0 -1
  76. package/tasks/index.d.ts +0 -1
  77. package/tasks/index.js +0 -1
@@ -1,19 +1,22 @@
1
- import { CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from "@webiny/api-headless-cms";
2
- import { Response } from "@webiny/handler-graphql";
1
+ import { CmsGraphQLSchemaFactory, CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from "@webiny/api-headless-cms";
2
+ import { ListModelsUseCase } from "@webiny/api-headless-cms/features/contentModel/ListModels/index.js";
3
+ import { Response } from "@webiny/api-graphql";
3
4
  import { CMS_MODEL_SINGLETON_TAG } from "@webiny/api-headless-cms/constants.js";
4
5
  import { BulkActionName } from "../domain/BulkActionName.js";
6
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
7
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
8
+ import { TriggerTaskUseCase } from "@webiny/background-tasks/api";
5
9
  const createBulkActionGraphQL = async (context, bulkAction)=>{
6
- const tenant = context.tenancy.getCurrentTenant();
10
+ const tenant = context.container.resolve(TenantContext).getTenant();
7
11
  if (!await isHeadlessCmsReady(context)) return;
8
- const models = await context.security.withoutAuthorization(async ()=>{
9
- const allModels = await context.cms.listModels();
10
- return allModels.filter((model)=>{
11
- if (model.isPrivate) return false;
12
- const tags = Array.isArray(model.tags) ? model.tags : [];
13
- if (tags.includes(CMS_MODEL_SINGLETON_TAG)) return false;
14
- if (bulkAction.modelIds?.length) return bulkAction.modelIds.includes(model.modelId);
15
- return true;
16
- });
12
+ const modelsResult = await context.container.resolve(IdentityContext).withoutAuthorization(async ()=>context.container.resolve(ListModelsUseCase).execute());
13
+ if (modelsResult.isFail()) return;
14
+ const models = modelsResult.value.filter((model)=>{
15
+ if (model.isPrivate) return false;
16
+ const tags = Array.isArray(model.tags) ? model.tags : [];
17
+ if (tags.includes(CMS_MODEL_SINGLETON_TAG)) return false;
18
+ if (bulkAction.modelIds?.length) return bulkAction.modelIds.includes(model.modelId);
19
+ return true;
17
20
  });
18
21
  const plugins = [];
19
22
  models.forEach((model)=>{
@@ -26,8 +29,8 @@ const createBulkActionGraphQL = async (context, bulkAction)=>{
26
29
  resolvers: {
27
30
  Mutation: {
28
31
  [`bulkAction${model.singularApiName}`]: async (_, args, context)=>{
29
- const identity = context.security.getIdentity();
30
- const response = await context.tasks.trigger({
32
+ const identity = context.container.resolve(IdentityContext).getIdentity();
33
+ const response = await context.container.resolve(TriggerTaskUseCase).execute({
31
34
  definition: `hcmsBulkList${args.action}Entries`,
32
35
  input: {
33
36
  modelId: model.modelId,
@@ -43,14 +46,14 @@ const createBulkActionGraphQL = async (context, bulkAction)=>{
43
46
  }
44
47
  }
45
48
  },
46
- isApplicable: (context)=>context.tenancy.getCurrentTenant().id === tenant.id
49
+ isApplicable: (context)=>context.container.resolve(TenantContext).getTenant().id === tenant.id
47
50
  });
48
51
  plugin.name = `headless-cms.graphql.schema.bulkAction.${model.modelId}.${bulkAction.name}`;
49
52
  plugins.push(plugin);
50
53
  });
51
- context.plugins.register([
52
- ...plugins
53
- ]);
54
+ context.container.registerInstance(CmsGraphQLSchemaFactory, {
55
+ execute: ()=>plugins
56
+ });
54
57
  };
55
58
  export { createBulkActionGraphQL };
56
59
 
@@ -1 +1 @@
1
- {"version":3,"file":"graphql/createBulkActionGraphQL.js","sources":["../../src/graphql/createBulkActionGraphQL.ts"],"sourcesContent":["import type { HcmsBulkActionsContext } from \"~/types.js\";\nimport { CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from \"@webiny/api-headless-cms\";\nimport { Response } from \"@webiny/handler-graphql\";\nimport { CMS_MODEL_SINGLETON_TAG } from \"@webiny/api-headless-cms/constants.js\";\nimport { EntriesBulkAction } from \"~/features/EntriesBulkAction/abstractions.js\";\nimport { BulkActionName } from \"~/domain/BulkActionName.js\";\n\nexport const createBulkActionGraphQL = async (\n context: HcmsBulkActionsContext,\n bulkAction: EntriesBulkAction.Interface\n) => {\n const tenant = context.tenancy.getCurrentTenant();\n\n // TODO: once we have GraphSchema plugin via an abstraction, we'll be able to remove this.\n if (!(await isHeadlessCmsReady(context))) {\n return;\n }\n\n const models = await context.security.withoutAuthorization(async () => {\n const allModels = await context.cms.listModels();\n return allModels.filter(model => {\n if (model.isPrivate) {\n return false;\n }\n const tags = Array.isArray(model.tags) ? model.tags : [];\n if (tags.includes(CMS_MODEL_SINGLETON_TAG)) {\n return false;\n }\n if (bulkAction.modelIds?.length) {\n return bulkAction.modelIds.includes(model.modelId);\n }\n return true;\n });\n });\n\n const plugins: CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>[] = [];\n\n models.forEach(model => {\n const plugin = new CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>({\n typeDefs: /* GraphQL */ `\n extend enum BulkAction${model.singularApiName}Name {\n ${BulkActionName.from(bulkAction.name)}\n }\n `,\n resolvers: {\n Mutation: {\n [`bulkAction${model.singularApiName}`]: async (_, args, context) => {\n const identity = context.security.getIdentity();\n\n const response = await context.tasks.trigger({\n definition: `hcmsBulkList${args.action}Entries`,\n input: {\n modelId: model.modelId,\n where: args.where,\n search: args.search,\n data: args.data,\n identity\n }\n });\n\n return new Response({\n id: response.value.id\n });\n }\n }\n },\n isApplicable: context => context.tenancy.getCurrentTenant().id === tenant.id\n });\n\n plugin.name = `headless-cms.graphql.schema.bulkAction.${model.modelId}.${bulkAction.name}`;\n plugins.push(plugin);\n });\n\n context.plugins.register([...plugins]);\n};\n"],"names":["createBulkActionGraphQL","context","bulkAction","tenant","isHeadlessCmsReady","models","allModels","model","tags","Array","CMS_MODEL_SINGLETON_TAG","plugins","plugin","CmsGraphQLSchemaPlugin","BulkActionName","_","args","identity","response","Response"],"mappings":";;;;AAOO,MAAMA,0BAA0B,OACnCC,SACAC;IAEA,MAAMC,SAASF,QAAQ,OAAO,CAAC,gBAAgB;IAG/C,IAAI,CAAE,MAAMG,mBAAmBH,UAC3B;IAGJ,MAAMI,SAAS,MAAMJ,QAAQ,QAAQ,CAAC,oBAAoB,CAAC;QACvD,MAAMK,YAAY,MAAML,QAAQ,GAAG,CAAC,UAAU;QAC9C,OAAOK,UAAU,MAAM,CAACC,CAAAA;YACpB,IAAIA,MAAM,SAAS,EACf,OAAO;YAEX,MAAMC,OAAOC,MAAM,OAAO,CAACF,MAAM,IAAI,IAAIA,MAAM,IAAI,GAAG,EAAE;YACxD,IAAIC,KAAK,QAAQ,CAACE,0BACd,OAAO;YAEX,IAAIR,WAAW,QAAQ,EAAE,QACrB,OAAOA,WAAW,QAAQ,CAAC,QAAQ,CAACK,MAAM,OAAO;YAErD,OAAO;QACX;IACJ;IAEA,MAAMI,UAA4D,EAAE;IAEpEN,OAAO,OAAO,CAACE,CAAAA;QACX,MAAMK,SAAS,IAAIC,uBAA+C;YAC9D,UAAwB,CAAC;2CACM,EAAEN,MAAM,eAAe,CAAC;wBAC3C,EAAEO,eAAe,IAAI,CAACZ,WAAW,IAAI,EAAE;;gBAE/C,CAAC;YACL,WAAW;gBACP,UAAU;oBACN,CAAC,CAAC,UAAU,EAAEK,MAAM,eAAe,EAAE,CAAC,EAAE,OAAOQ,GAAGC,MAAMf;wBACpD,MAAMgB,WAAWhB,QAAQ,QAAQ,CAAC,WAAW;wBAE7C,MAAMiB,WAAW,MAAMjB,QAAQ,KAAK,CAAC,OAAO,CAAC;4BACzC,YAAY,CAAC,YAAY,EAAEe,KAAK,MAAM,CAAC,OAAO,CAAC;4BAC/C,OAAO;gCACH,SAAST,MAAM,OAAO;gCACtB,OAAOS,KAAK,KAAK;gCACjB,QAAQA,KAAK,MAAM;gCACnB,MAAMA,KAAK,IAAI;gCACfC;4BACJ;wBACJ;wBAEA,OAAO,IAAIE,SAAS;4BAChB,IAAID,SAAS,KAAK,CAAC,EAAE;wBACzB;oBACJ;gBACJ;YACJ;YACA,cAAcjB,CAAAA,UAAWA,QAAQ,OAAO,CAAC,gBAAgB,GAAG,EAAE,KAAKE,OAAO,EAAE;QAChF;QAEAS,OAAO,IAAI,GAAG,CAAC,uCAAuC,EAAEL,MAAM,OAAO,CAAC,CAAC,EAAEL,WAAW,IAAI,EAAE;QAC1FS,QAAQ,IAAI,CAACC;IACjB;IAEAX,QAAQ,OAAO,CAAC,QAAQ,CAAC;WAAIU;KAAQ;AACzC"}
1
+ {"version":3,"file":"graphql/createBulkActionGraphQL.js","sources":["../../src/graphql/createBulkActionGraphQL.ts"],"sourcesContent":["import type { HcmsBulkActionsContext } from \"~/types.js\";\nimport {\n CmsGraphQLSchemaPlugin,\n CmsGraphQLSchemaFactory,\n isHeadlessCmsReady\n} from \"@webiny/api-headless-cms\";\nimport { ListModelsUseCase } from \"@webiny/api-headless-cms/features/contentModel/ListModels/index.js\";\nimport { Response } from \"@webiny/api-graphql\";\nimport { CMS_MODEL_SINGLETON_TAG } from \"@webiny/api-headless-cms/constants.js\";\nimport { EntriesBulkAction } from \"~/features/EntriesBulkAction/abstractions.js\";\nimport { BulkActionName } from \"~/domain/BulkActionName.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport { TriggerTaskUseCase } from \"@webiny/background-tasks/api\";\n\nexport const createBulkActionGraphQL = async (\n context: HcmsBulkActionsContext,\n bulkAction: EntriesBulkAction.Interface\n) => {\n const tenant = context.container.resolve(TenantContext).getTenant();\n\n if (!(await isHeadlessCmsReady(context))) {\n return;\n }\n\n const modelsResult = await context.container\n .resolve(IdentityContext)\n .withoutAuthorization(async () => {\n return context.container.resolve(ListModelsUseCase).execute();\n });\n if (modelsResult.isFail()) {\n return;\n }\n const models = modelsResult.value.filter(model => {\n if (model.isPrivate) {\n return false;\n }\n const tags = Array.isArray(model.tags) ? model.tags : [];\n if (tags.includes(CMS_MODEL_SINGLETON_TAG)) {\n return false;\n }\n if (bulkAction.modelIds?.length) {\n return bulkAction.modelIds.includes(model.modelId);\n }\n return true;\n });\n\n const plugins: CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>[] = [];\n\n models.forEach(model => {\n const plugin = new CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>({\n typeDefs: /* GraphQL */ `\n extend enum BulkAction${model.singularApiName}Name {\n ${BulkActionName.from(bulkAction.name)}\n }\n `,\n resolvers: {\n Mutation: {\n [`bulkAction${model.singularApiName}`]: async (_, args, context) => {\n const identity = context.container.resolve(IdentityContext).getIdentity();\n\n const response = await context.container\n .resolve(TriggerTaskUseCase)\n .execute({\n definition: `hcmsBulkList${args.action}Entries`,\n input: {\n modelId: model.modelId,\n where: args.where,\n search: args.search,\n data: args.data,\n identity\n }\n });\n\n return new Response({\n id: response.value.id\n });\n }\n }\n },\n isApplicable: context =>\n context.container.resolve(TenantContext).getTenant().id === tenant.id\n });\n\n plugin.name = `headless-cms.graphql.schema.bulkAction.${model.modelId}.${bulkAction.name}`;\n plugins.push(plugin);\n });\n\n context.container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => plugins\n });\n};\n"],"names":["createBulkActionGraphQL","context","bulkAction","tenant","TenantContext","isHeadlessCmsReady","modelsResult","IdentityContext","ListModelsUseCase","models","model","tags","Array","CMS_MODEL_SINGLETON_TAG","plugins","plugin","CmsGraphQLSchemaPlugin","BulkActionName","_","args","identity","response","TriggerTaskUseCase","Response","CmsGraphQLSchemaFactory"],"mappings":";;;;;;;;AAeO,MAAMA,0BAA0B,OACnCC,SACAC;IAEA,MAAMC,SAASF,QAAQ,SAAS,CAAC,OAAO,CAACG,eAAe,SAAS;IAEjE,IAAI,CAAE,MAAMC,mBAAmBJ,UAC3B;IAGJ,MAAMK,eAAe,MAAML,QAAQ,SAAS,CACvC,OAAO,CAACM,iBACR,oBAAoB,CAAC,UACXN,QAAQ,SAAS,CAAC,OAAO,CAACO,mBAAmB,OAAO;IAEnE,IAAIF,aAAa,MAAM,IACnB;IAEJ,MAAMG,SAASH,aAAa,KAAK,CAAC,MAAM,CAACI,CAAAA;QACrC,IAAIA,MAAM,SAAS,EACf,OAAO;QAEX,MAAMC,OAAOC,MAAM,OAAO,CAACF,MAAM,IAAI,IAAIA,MAAM,IAAI,GAAG,EAAE;QACxD,IAAIC,KAAK,QAAQ,CAACE,0BACd,OAAO;QAEX,IAAIX,WAAW,QAAQ,EAAE,QACrB,OAAOA,WAAW,QAAQ,CAAC,QAAQ,CAACQ,MAAM,OAAO;QAErD,OAAO;IACX;IAEA,MAAMI,UAA4D,EAAE;IAEpEL,OAAO,OAAO,CAACC,CAAAA;QACX,MAAMK,SAAS,IAAIC,uBAA+C;YAC9D,UAAwB,CAAC;2CACM,EAAEN,MAAM,eAAe,CAAC;wBAC3C,EAAEO,eAAe,IAAI,CAACf,WAAW,IAAI,EAAE;;gBAE/C,CAAC;YACL,WAAW;gBACP,UAAU;oBACN,CAAC,CAAC,UAAU,EAAEQ,MAAM,eAAe,EAAE,CAAC,EAAE,OAAOQ,GAAGC,MAAMlB;wBACpD,MAAMmB,WAAWnB,QAAQ,SAAS,CAAC,OAAO,CAACM,iBAAiB,WAAW;wBAEvE,MAAMc,WAAW,MAAMpB,QAAQ,SAAS,CACnC,OAAO,CAACqB,oBACR,OAAO,CAAC;4BACL,YAAY,CAAC,YAAY,EAAEH,KAAK,MAAM,CAAC,OAAO,CAAC;4BAC/C,OAAO;gCACH,SAAST,MAAM,OAAO;gCACtB,OAAOS,KAAK,KAAK;gCACjB,QAAQA,KAAK,MAAM;gCACnB,MAAMA,KAAK,IAAI;gCACfC;4BACJ;wBACJ;wBAEJ,OAAO,IAAIG,SAAS;4BAChB,IAAIF,SAAS,KAAK,CAAC,EAAE;wBACzB;oBACJ;gBACJ;YACJ;YACA,cAAcpB,CAAAA,UACVA,QAAQ,SAAS,CAAC,OAAO,CAACG,eAAe,SAAS,GAAG,EAAE,KAAKD,OAAO,EAAE;QAC7E;QAEAY,OAAO,IAAI,GAAG,CAAC,uCAAuC,EAAEL,MAAM,OAAO,CAAC,CAAC,EAAER,WAAW,IAAI,EAAE;QAC1FY,QAAQ,IAAI,CAACC;IACjB;IAEAd,QAAQ,SAAS,CAAC,gBAAgB,CAACuB,yBAAyB;QACxD,SAAS,IAAMV;IACnB;AACJ"}
@@ -1,3 +1,8 @@
1
1
  import type { HcmsBulkActionsContext } from "../types.js";
2
- import { BeforeHandlerPlugin } from "@webiny/handler/plugins/BeforeHandlerPlugin.js";
3
- export declare const createDefaultGraphQL: () => BeforeHandlerPlugin<HcmsBulkActionsContext>;
2
+ /**
3
+ * Registers the "default" bulk-action GraphQL for every public model: the shared response types plus,
4
+ * per model, an empty `BulkAction<Model>Name` enum + `bulkAction<Model>` mutation skeleton (each
5
+ * action extends the enum via createBulkActionGraphQL). Run per request, since models are only
6
+ * known at request time.
7
+ */
8
+ export declare const registerDefaultBulkActionGraphQL: (context: HcmsBulkActionsContext) => Promise<void>;
@@ -1,35 +1,35 @@
1
- import { CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from "@webiny/api-headless-cms";
1
+ import { CmsGraphQLSchemaFactory, CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from "@webiny/api-headless-cms";
2
+ import { ListModelsUseCase } from "@webiny/api-headless-cms/features/contentModel/ListModels/index.js";
2
3
  import { CMS_MODEL_SINGLETON_TAG } from "@webiny/api-headless-cms/constants.js";
3
- import { BeforeHandlerPlugin } from "@webiny/handler/plugins/BeforeHandlerPlugin.js";
4
- const createDefaultGraphQL = ()=>new BeforeHandlerPlugin(async (context)=>{
5
- const tenant = context.tenancy.getCurrentTenant();
6
- if (!await isHeadlessCmsReady(context)) return;
7
- const defaultPlugin = new CmsGraphQLSchemaPlugin({
8
- typeDefs: `
9
- type BulkActionResponseData {
10
- id: String
11
- }
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
6
+ const registerDefaultBulkActionGraphQL = async (context)=>{
7
+ const tenant = context.container.resolve(TenantContext).getTenant();
8
+ if (!await isHeadlessCmsReady(context)) return;
9
+ const defaultPlugin = new CmsGraphQLSchemaPlugin({
10
+ typeDefs: `
11
+ type BulkActionResponseData {
12
+ id: String
13
+ }
12
14
 
13
- type BulkActionResponse {
14
- data: BulkActionResponseData
15
- error: CmsError
16
- }
17
- `
18
- });
19
- defaultPlugin.name = "headless-cms.graphql.schema.bulkAction.default";
20
- const models = await context.security.withoutAuthorization(async ()=>{
21
- const allModels = await context.cms.listModels();
22
- return allModels.filter((model)=>{
23
- if (model.isPrivate) return false;
24
- const tags = Array.isArray(model.tags) ? model.tags : [];
25
- if (tags.includes(CMS_MODEL_SINGLETON_TAG)) return false;
26
- return true;
27
- });
28
- });
29
- const modelPlugins = [];
30
- models.forEach((model)=>{
31
- const plugin = new CmsGraphQLSchemaPlugin({
32
- typeDefs: `
15
+ type BulkActionResponse {
16
+ data: BulkActionResponseData
17
+ error: CmsError
18
+ }
19
+ `
20
+ });
21
+ defaultPlugin.name = "headless-cms.graphql.schema.bulkAction.default";
22
+ const modelsResult = await context.container.resolve(IdentityContext).withoutAuthorization(async ()=>context.container.resolve(ListModelsUseCase).execute());
23
+ if (modelsResult.isFail()) return;
24
+ const models = modelsResult.value.filter((model)=>{
25
+ if (model.isPrivate) return false;
26
+ const tags = Array.isArray(model.tags) ? model.tags : [];
27
+ return !tags.includes(CMS_MODEL_SINGLETON_TAG);
28
+ });
29
+ const modelPlugins = [];
30
+ models.forEach((model)=>{
31
+ const plugin = new CmsGraphQLSchemaPlugin({
32
+ typeDefs: `
33
33
  enum BulkAction${model.singularApiName}Name {
34
34
  _empty
35
35
  }
@@ -43,16 +43,18 @@ const createDefaultGraphQL = ()=>new BeforeHandlerPlugin(async (context)=>{
43
43
  ): BulkActionResponse
44
44
  }
45
45
  `,
46
- isApplicable: (context)=>context.tenancy.getCurrentTenant().id === tenant.id
47
- });
48
- plugin.name = `headless-cms.graphql.schema.bulkAction.default.${model.modelId}`;
49
- modelPlugins.push(plugin);
46
+ isApplicable: (context)=>context.container.resolve(TenantContext).getTenant().id === tenant.id
50
47
  });
51
- context.plugins.register([
52
- defaultPlugin,
53
- ...modelPlugins
54
- ]);
48
+ plugin.name = `headless-cms.graphql.schema.bulkAction.default.${model.modelId}`;
49
+ modelPlugins.push(plugin);
50
+ });
51
+ context.container.registerInstance(CmsGraphQLSchemaFactory, {
52
+ execute: ()=>[
53
+ defaultPlugin,
54
+ ...modelPlugins
55
+ ]
55
56
  });
56
- export { createDefaultGraphQL };
57
+ };
58
+ export { registerDefaultBulkActionGraphQL };
57
59
 
58
60
  //# sourceMappingURL=createDefaultGraphQL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphql/createDefaultGraphQL.js","sources":["../../src/graphql/createDefaultGraphQL.ts"],"sourcesContent":["import type { HcmsBulkActionsContext } from \"~/types.js\";\nimport { CmsGraphQLSchemaPlugin, isHeadlessCmsReady } from \"@webiny/api-headless-cms\";\nimport { CMS_MODEL_SINGLETON_TAG } from \"@webiny/api-headless-cms/constants.js\";\nimport { BeforeHandlerPlugin } from \"@webiny/handler/plugins/BeforeHandlerPlugin.js\";\n\nexport const createDefaultGraphQL = () => {\n return new BeforeHandlerPlugin<HcmsBulkActionsContext>(async context => {\n const tenant = context.tenancy.getCurrentTenant();\n\n if (!(await isHeadlessCmsReady(context))) {\n return;\n }\n\n const defaultPlugin = new CmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n type BulkActionResponseData {\n id: String\n }\n\n type BulkActionResponse {\n data: BulkActionResponseData\n error: CmsError\n }\n `\n });\n defaultPlugin.name = `headless-cms.graphql.schema.bulkAction.default`;\n\n const models = await context.security.withoutAuthorization(async () => {\n const allModels = await context.cms.listModels();\n return allModels.filter(model => {\n if (model.isPrivate) {\n return false;\n }\n const tags = Array.isArray(model.tags) ? model.tags : [];\n if (tags.includes(CMS_MODEL_SINGLETON_TAG)) {\n return false;\n }\n return true;\n });\n });\n\n const modelPlugins: CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>[] = [];\n\n models.forEach(model => {\n const plugin = new CmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n enum BulkAction${model.singularApiName}Name {\n _empty\n }\n \n extend type Mutation {\n bulkAction${model.singularApiName}(\n action: BulkAction${model.singularApiName}Name!\n where: ${model.singularApiName}ListWhereInput\n search: String\n data: JSON\n ): BulkActionResponse\n }\n `,\n isApplicable: context => context.tenancy.getCurrentTenant().id === tenant.id\n });\n\n plugin.name = `headless-cms.graphql.schema.bulkAction.default.${model.modelId}`;\n modelPlugins.push(plugin);\n });\n\n context.plugins.register([defaultPlugin, ...modelPlugins]);\n });\n};\n"],"names":["createDefaultGraphQL","BeforeHandlerPlugin","context","tenant","isHeadlessCmsReady","defaultPlugin","CmsGraphQLSchemaPlugin","models","allModels","model","tags","Array","CMS_MODEL_SINGLETON_TAG","modelPlugins","plugin"],"mappings":";;;AAKO,MAAMA,uBAAuB,IACzB,IAAIC,oBAA4C,OAAMC;QACzD,MAAMC,SAASD,QAAQ,OAAO,CAAC,gBAAgB;QAE/C,IAAI,CAAE,MAAME,mBAAmBF,UAC3B;QAGJ,MAAMG,gBAAgB,IAAIC,uBAAuB;YAC7C,UAAwB,CAAC;;;;;;;;;YASzB,CAAC;QACL;QACAD,cAAc,IAAI,GAAG;QAErB,MAAME,SAAS,MAAML,QAAQ,QAAQ,CAAC,oBAAoB,CAAC;YACvD,MAAMM,YAAY,MAAMN,QAAQ,GAAG,CAAC,UAAU;YAC9C,OAAOM,UAAU,MAAM,CAACC,CAAAA;gBACpB,IAAIA,MAAM,SAAS,EACf,OAAO;gBAEX,MAAMC,OAAOC,MAAM,OAAO,CAACF,MAAM,IAAI,IAAIA,MAAM,IAAI,GAAG,EAAE;gBACxD,IAAIC,KAAK,QAAQ,CAACE,0BACd,OAAO;gBAEX,OAAO;YACX;QACJ;QAEA,MAAMC,eAAiE,EAAE;QAEzEN,OAAO,OAAO,CAACE,CAAAA;YACX,MAAMK,SAAS,IAAIR,uBAAuB;gBACtC,UAAwB,CAAC;mCACN,EAAEG,MAAM,eAAe,CAAC;;;;;kCAKzB,EAAEA,MAAM,eAAe,CAAC;8CACZ,EAAEA,MAAM,eAAe,CAAC;mCACnC,EAAEA,MAAM,eAAe,CAAC;;;;;gBAK3C,CAAC;gBACD,cAAcP,CAAAA,UAAWA,QAAQ,OAAO,CAAC,gBAAgB,GAAG,EAAE,KAAKC,OAAO,EAAE;YAChF;YAEAW,OAAO,IAAI,GAAG,CAAC,+CAA+C,EAAEL,MAAM,OAAO,EAAE;YAC/EI,aAAa,IAAI,CAACC;QACtB;QAEAZ,QAAQ,OAAO,CAAC,QAAQ,CAAC;YAACG;eAAkBQ;SAAa;IAC7D"}
1
+ {"version":3,"file":"graphql/createDefaultGraphQL.js","sources":["../../src/graphql/createDefaultGraphQL.ts"],"sourcesContent":["import type { HcmsBulkActionsContext } from \"~/types.js\";\nimport {\n CmsGraphQLSchemaPlugin,\n CmsGraphQLSchemaFactory,\n isHeadlessCmsReady\n} from \"@webiny/api-headless-cms\";\nimport { ListModelsUseCase } from \"@webiny/api-headless-cms/features/contentModel/ListModels/index.js\";\nimport { CMS_MODEL_SINGLETON_TAG } from \"@webiny/api-headless-cms/constants.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\n\n/**\n * Registers the \"default\" bulk-action GraphQL for every public model: the shared response types plus,\n * per model, an empty `BulkAction<Model>Name` enum + `bulkAction<Model>` mutation skeleton (each\n * action extends the enum via createBulkActionGraphQL). Run per request, since models are only\n * known at request time.\n */\nexport const registerDefaultBulkActionGraphQL = async (context: HcmsBulkActionsContext) => {\n const tenant = context.container.resolve(TenantContext).getTenant();\n\n if (!(await isHeadlessCmsReady(context))) {\n return;\n }\n\n const defaultPlugin = new CmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n type BulkActionResponseData {\n id: String\n }\n\n type BulkActionResponse {\n data: BulkActionResponseData\n error: CmsError\n }\n `\n });\n defaultPlugin.name = `headless-cms.graphql.schema.bulkAction.default`;\n\n const modelsResult = await context.container\n .resolve(IdentityContext)\n .withoutAuthorization(async () => {\n return context.container.resolve(ListModelsUseCase).execute();\n });\n if (modelsResult.isFail()) {\n return;\n }\n const models = modelsResult.value.filter(model => {\n if (model.isPrivate) {\n return false;\n }\n const tags = Array.isArray(model.tags) ? model.tags : [];\n return !tags.includes(CMS_MODEL_SINGLETON_TAG);\n });\n\n const modelPlugins: CmsGraphQLSchemaPlugin<HcmsBulkActionsContext>[] = [];\n\n models.forEach(model => {\n const plugin = new CmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n enum BulkAction${model.singularApiName}Name {\n _empty\n }\n \n extend type Mutation {\n bulkAction${model.singularApiName}(\n action: BulkAction${model.singularApiName}Name!\n where: ${model.singularApiName}ListWhereInput\n search: String\n data: JSON\n ): BulkActionResponse\n }\n `,\n isApplicable: context =>\n context.container.resolve(TenantContext).getTenant().id === tenant.id\n });\n\n plugin.name = `headless-cms.graphql.schema.bulkAction.default.${model.modelId}`;\n modelPlugins.push(plugin);\n });\n\n context.container.registerInstance(CmsGraphQLSchemaFactory, {\n execute: () => [defaultPlugin, ...modelPlugins]\n });\n};\n"],"names":["registerDefaultBulkActionGraphQL","context","tenant","TenantContext","isHeadlessCmsReady","defaultPlugin","CmsGraphQLSchemaPlugin","modelsResult","IdentityContext","ListModelsUseCase","models","model","tags","Array","CMS_MODEL_SINGLETON_TAG","modelPlugins","plugin","CmsGraphQLSchemaFactory"],"mappings":";;;;;AAiBO,MAAMA,mCAAmC,OAAOC;IACnD,MAAMC,SAASD,QAAQ,SAAS,CAAC,OAAO,CAACE,eAAe,SAAS;IAEjE,IAAI,CAAE,MAAMC,mBAAmBH,UAC3B;IAGJ,MAAMI,gBAAgB,IAAIC,uBAAuB;QAC7C,UAAwB,CAAC;;;;;;;;;QASzB,CAAC;IACL;IACAD,cAAc,IAAI,GAAG;IAErB,MAAME,eAAe,MAAMN,QAAQ,SAAS,CACvC,OAAO,CAACO,iBACR,oBAAoB,CAAC,UACXP,QAAQ,SAAS,CAAC,OAAO,CAACQ,mBAAmB,OAAO;IAEnE,IAAIF,aAAa,MAAM,IACnB;IAEJ,MAAMG,SAASH,aAAa,KAAK,CAAC,MAAM,CAACI,CAAAA;QACrC,IAAIA,MAAM,SAAS,EACf,OAAO;QAEX,MAAMC,OAAOC,MAAM,OAAO,CAACF,MAAM,IAAI,IAAIA,MAAM,IAAI,GAAG,EAAE;QACxD,OAAO,CAACC,KAAK,QAAQ,CAACE;IAC1B;IAEA,MAAMC,eAAiE,EAAE;IAEzEL,OAAO,OAAO,CAACC,CAAAA;QACX,MAAMK,SAAS,IAAIV,uBAAuB;YACtC,UAAwB,CAAC;mCACF,EAAEK,MAAM,eAAe,CAAC;;;;;kCAKzB,EAAEA,MAAM,eAAe,CAAC;8CACZ,EAAEA,MAAM,eAAe,CAAC;mCACnC,EAAEA,MAAM,eAAe,CAAC;;;;;gBAK3C,CAAC;YACL,cAAcV,CAAAA,UACVA,QAAQ,SAAS,CAAC,OAAO,CAACE,eAAe,SAAS,GAAG,EAAE,KAAKD,OAAO,EAAE;QAC7E;QAEAc,OAAO,IAAI,GAAG,CAAC,+CAA+C,EAAEL,MAAM,OAAO,EAAE;QAC/EI,aAAa,IAAI,CAACC;IACtB;IAEAf,QAAQ,SAAS,CAAC,gBAAgB,CAACgB,yBAAyB;QACxD,SAAS,IAAM;gBAACZ;mBAAkBU;aAAa;IACnD;AACJ"}
package/index.d.ts CHANGED
@@ -1,8 +1,3 @@
1
- import type { HcmsBulkActionsContext } from "./types.js";
2
1
  export type * from "./abstractions/index.js";
3
- export { createHandlers } from "./handlers/index.js";
4
- export { createEmptyTrashBinsTask } from "./tasks/index.js";
5
- interface BulkActionsConfig {
6
- batchSize?: number;
7
- }
8
- export declare const createHcmsBulkActions: (config?: BulkActionsConfig) => ((import("@webiny/handler-aws/index.js").EventBridgeEventHandler<"WebinyEmptyTrashBin", Record<string, any>, any> | import("@webiny/handler/index.js").HandlerOnRequestPlugin<import("@webiny/handler/types.js").Context>)[] | import("@webiny/handler/index.js").BeforeHandlerPlugin<HcmsBulkActionsContext> | import("@webiny/api").ContextPlugin<import("@webiny/api/types.js").Context>)[];
2
+ export { HcmsBulkActionsFeature } from "./HcmsBulkActionsFeature.js";
3
+ export type { HcmsBulkActionsFeatureConfig } from "./HcmsBulkActionsFeature.js";
package/index.js CHANGED
@@ -1,46 +1 @@
1
- import { createHandlers } from "./handlers/index.js";
2
- import { createBeforeHandlerPlugin } from "@webiny/handler/plugins/BeforeHandlerPlugin.js";
3
- import { EntriesBulkAction, EntriesBulkActionConfig } from "./features/EntriesBulkAction/abstractions.js";
4
- import { BulkActionContext } from "./features/BulkActionContext/index.js";
5
- import { createBulkActionTasks } from "./features/EntriesBulkAction/createBulkActionTasks.js";
6
- import { createDefaultGraphQL } from "./graphql/createDefaultGraphQL.js";
7
- import { createBulkActionGraphQL } from "./graphql/createBulkActionGraphQL.js";
8
- import { createContextPlugin } from "@webiny/api";
9
- import { DeleteEntriesBulkActionFeature } from "./features/DeleteEntriesBulkAction/feature.js";
10
- import { MoveToFolderBulkActionFeature } from "./features/MoveToFolderBulkAction/feature.js";
11
- import { MoveToTrashBulkActionFeature } from "./features/MoveToTrashBulkAction/feature.js";
12
- import { PublishEntriesBulkActionFeature } from "./features/PublishEntriesBulkAction/feature.js";
13
- import { UnpublishEntriesBulkActionFeature } from "./features/UnpublishEntriesBulkAction/feature.js";
14
- import { RestoreEntriesBulkActionFeature } from "./features/RestoreEntriesBulkAction/feature.js";
15
- const createHcmsBulkActions = (config)=>{
16
- const batchSize = config?.batchSize ?? 100;
17
- return [
18
- createHandlers(),
19
- createDefaultGraphQL(),
20
- createContextPlugin((context)=>{
21
- context.container.registerInstance(EntriesBulkActionConfig, {
22
- batchSize
23
- });
24
- DeleteEntriesBulkActionFeature.register(context.container);
25
- MoveToFolderBulkActionFeature.register(context.container);
26
- MoveToTrashBulkActionFeature.register(context.container);
27
- PublishEntriesBulkActionFeature.register(context.container);
28
- UnpublishEntriesBulkActionFeature.register(context.container);
29
- RestoreEntriesBulkActionFeature.register(context.container);
30
- }),
31
- createBeforeHandlerPlugin(async (context)=>{
32
- context.container.registerInstance(BulkActionContext, context);
33
- const bulkActions = context.container.resolveAll(EntriesBulkAction);
34
- const bulkActionsConfig = context.container.resolve(EntriesBulkActionConfig);
35
- for (const bulkAction of bulkActions){
36
- const feature = createBulkActionTasks(bulkAction, bulkActionsConfig);
37
- feature.register(context.container);
38
- await createBulkActionGraphQL(context, bulkAction);
39
- }
40
- })
41
- ];
42
- };
43
- export { createEmptyTrashBinsTask } from "./tasks/index.js";
44
- export { createHandlers, createHcmsBulkActions };
45
-
46
- //# sourceMappingURL=index.js.map
1
+ export { HcmsBulkActionsFeature } from "./HcmsBulkActionsFeature.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-headless-cms-bulk-actions",
3
- "version": "6.4.11",
3
+ "version": "6.6.0-alpha.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -17,24 +17,26 @@
17
17
  },
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@webiny/api-headless-cms": "6.4.11",
21
- "@webiny/background-tasks": "6.4.11",
22
- "@webiny/feature": "6.4.11",
23
- "@webiny/handler": "6.4.11",
24
- "@webiny/handler-aws": "6.4.11",
25
- "@webiny/utils": "6.4.11"
20
+ "@webiny/api-graphql": "6.6.0-alpha.1",
21
+ "@webiny/api-headless-cms": "6.6.0-alpha.1",
22
+ "@webiny/background-tasks": "6.6.0-alpha.1",
23
+ "@webiny/event-handler-core": "6.6.0-alpha.1",
24
+ "@webiny/feature": "6.6.0-alpha.1",
25
+ "@webiny/handler": "6.6.0-alpha.1",
26
+ "@webiny/utils": "6.6.0-alpha.1"
26
27
  },
27
28
  "devDependencies": {
28
- "@webiny/api": "6.4.11",
29
- "@webiny/api-core": "6.4.11",
30
- "@webiny/build-tools": "6.4.11",
31
- "@webiny/handler-graphql": "6.4.11",
32
- "@webiny/plugins": "6.4.11",
33
- "@webiny/project-utils": "6.4.11",
34
- "@webiny/wcp": "6.4.11",
29
+ "@webiny/api": "6.6.0-alpha.1",
30
+ "@webiny/api-core": "6.6.0-alpha.1",
31
+ "@webiny/api-graphql": "6.6.0-alpha.1",
32
+ "@webiny/api-headless-cms-testing": "6.6.0-alpha.1",
33
+ "@webiny/build-tools": "6.6.0-alpha.1",
34
+ "@webiny/di": "1.1.0",
35
+ "@webiny/plugins": "6.6.0-alpha.1",
36
+ "@webiny/wcp": "6.6.0-alpha.1",
35
37
  "graphql": "16.14.2",
36
- "typescript": "6.0.3",
37
- "vitest": "4.1.10"
38
+ "typescript": "7.0.2",
39
+ "vitest": "4.1.11"
38
40
  },
39
41
  "publishConfig": {
40
42
  "access": "public"
@@ -17,7 +17,7 @@ declare class EmptyTrashBinTask implements TaskDefinition.Interface<IEmptyTrashB
17
17
  readonly description = "Delete all entries in the trash bin for each model in the system.";
18
18
  readonly maxIterations = 120;
19
19
  readonly databaseLogs = false;
20
- readonly selfCleanup: ("onSuccess" | "onAbort")[];
20
+ readonly selfCleanup: ("onAbort" | "onSuccess")[];
21
21
  constructor(tenantContext: TenantContext.Interface, listTenants: ListTenantsUseCase.Interface, listModels: ListModelsUseCase.Interface, listDeletedEntries: ListDeletedEntriesUseCase.Interface, deleteEntry: DeleteEntryUseCase.Interface);
22
22
  run(params: TaskDefinition.RunParams<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>): Promise<TaskDefinition.Result<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>>;
23
23
  }
@@ -33,7 +33,6 @@ class EmptyTrashBinTask {
33
33
  const { input, controller } = params;
34
34
  if (controller.runtime.isAborted()) return controller.response.aborted();
35
35
  const tenantsResult = await this.listTenants.execute();
36
- if (tenantsResult.isFail()) return controller.response.error(tenantsResult.error);
37
36
  const baseTenants = tenantsResult.value;
38
37
  const executedTenantIds = input.executedTenantIds || [];
39
38
  const tenants = baseTenants.filter((tenant)=>!executedTenantIds.includes(tenant.id));
@@ -50,7 +49,6 @@ class EmptyTrashBinTask {
50
49
  const modelsResult = await this.listModels.execute({
51
50
  includePrivate: false
52
51
  });
53
- if (modelsResult.isFail()) return void controller.logger.error(modelsResult.error);
54
52
  const models = modelsResult.value;
55
53
  for (const model of models){
56
54
  const listEntriesParams = {
@@ -61,10 +59,6 @@ class EmptyTrashBinTask {
61
59
  };
62
60
  while(true){
63
61
  const listResult = await this.listDeletedEntries.execute(model, listEntriesParams);
64
- if (listResult.isFail()) {
65
- controller.logger.error(listResult.error);
66
- break;
67
- }
68
62
  const { entries, meta } = listResult.value;
69
63
  if (0 === meta.totalCount) break;
70
64
  if (controller.runtime.isCloseToTimeout()) {
@@ -1 +1 @@
1
- {"version":3,"file":"tasks/EmptyTrashBinTaskDefinition.js","sources":["../../src/tasks/EmptyTrashBinTaskDefinition.ts"],"sourcesContent":["import type { IEmptyTrashBinsInput, IEmptyTrashBinsOutput } from \"~/types.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { ListTenantsUseCase } from \"@webiny/api-core/features/tenancy/ListTenants/index.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { ListModelsUseCase } from \"@webiny/api-headless-cms/features/contentModel/ListModels/index.js\";\nimport { DeleteEntryUseCase } from \"@webiny/api-headless-cms/features/contentEntry/DeleteEntry/index.js\";\nimport { ListDeletedEntriesUseCase } from \"@webiny/api-headless-cms/features/contentEntry/ListEntries/index.js\";\n\nconst calculateDateTimeString = () => {\n // Retrieve the retention period from the environment variable WEBINY_TRASH_BIN_RETENTION_PERIOD_DAYS,\n // or default to 90 days if not set or set to 0.\n const retentionPeriodFromEnv = process.env[\"WEBINY_TRASH_BIN_RETENTION_PERIOD_DAYS\"];\n const retentionPeriod =\n retentionPeriodFromEnv && Number(retentionPeriodFromEnv) !== 0\n ? Number(retentionPeriodFromEnv)\n : 90;\n\n // Calculate the date-time by subtracting the retention period (in days) from the current date.\n const currentDate = new Date();\n currentDate.setDate(currentDate.getDate() - retentionPeriod);\n\n // Return the calculated date-time string in ISO 8601 format.\n return currentDate.toISOString();\n};\n\nclass EmptyTrashBinTask implements TaskDefinition.Interface<\n IEmptyTrashBinsInput,\n IEmptyTrashBinsOutput\n> {\n public readonly isPrivate = true;\n public readonly id = \"hcmsEntriesEmptyTrashBins\";\n public readonly title = \"Headless CMS - Empty all trash bins\";\n public readonly description =\n \"Delete all entries in the trash bin for each model in the system.\";\n public readonly maxIterations = 120;\n public readonly databaseLogs = false;\n\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private tenantContext: TenantContext.Interface,\n private listTenants: ListTenantsUseCase.Interface,\n private listModels: ListModelsUseCase.Interface,\n private listDeletedEntries: ListDeletedEntriesUseCase.Interface,\n private deleteEntry: DeleteEntryUseCase.Interface\n ) {}\n\n async run(\n params: TaskDefinition.RunParams<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>\n ): Promise<TaskDefinition.Result<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>> {\n const { input, controller } = params;\n\n // Abort the task if needed.\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Fetch all tenants, excluding those already processed.\n const tenantsResult = await this.listTenants.execute();\n if (tenantsResult.isFail()) {\n return controller.response.error(tenantsResult.error);\n }\n const baseTenants = tenantsResult.value;\n const executedTenantIds = input.executedTenantIds || [];\n const tenants = baseTenants.filter(tenant => !executedTenantIds.includes(tenant.id));\n\n let shouldTaskContinue = false;\n\n // Iterate over each tenant.\n await this.tenantContext.withEachTenant(tenants, async tenant => {\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n return;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n return;\n }\n\n // List all non-private models.\n const modelsResult = await this.listModels.execute({ includePrivate: false });\n if (modelsResult.isFail()) {\n controller.logger.error(modelsResult.error);\n return;\n }\n const models = modelsResult.value;\n\n // Process each model to delete trashed entries.\n for (const model of models) {\n // Query parameters for fetching deleted entries older than a minute ago.\n const listEntriesParams = {\n where: {\n deletedOn_lt: calculateDateTimeString()\n },\n limit: 50\n };\n\n // Continue deleting entries while there are entries left to delete.\n while (true) {\n const listResult = await this.listDeletedEntries.execute(\n model,\n listEntriesParams\n );\n if (listResult.isFail()) {\n controller.logger.error(listResult.error);\n break;\n }\n const { entries, meta } = listResult.value;\n\n if (meta.totalCount === 0) {\n break;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n break;\n }\n for (const entry of entries) {\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n break;\n }\n // Delete each entry individually.\n await this.deleteEntry.execute(model, entry.id, { permanently: true });\n }\n }\n }\n\n // If the task isn't continuing, add the tenant to the executed list.\n if (!shouldTaskContinue) {\n executedTenantIds.push(tenant.id);\n }\n });\n\n // Continue the task or mark it as done based on the `shouldContinue` flag.\n return shouldTaskContinue\n ? controller.response.continue({ ...input, executedTenantIds })\n : controller.response.done(\n \"Task done: emptied the trash bin for all registered models.\"\n );\n }\n}\n\nexport const EmptyTrashBinTaskDefinition = TaskDefinition.createImplementation({\n implementation: EmptyTrashBinTask,\n dependencies: [\n TenantContext,\n ListTenantsUseCase,\n ListModelsUseCase,\n ListDeletedEntriesUseCase,\n DeleteEntryUseCase\n ]\n});\n"],"names":["calculateDateTimeString","retentionPeriodFromEnv","process","retentionPeriod","Number","currentDate","Date","EmptyTrashBinTask","tenantContext","listTenants","listModels","listDeletedEntries","deleteEntry","params","input","controller","tenantsResult","baseTenants","executedTenantIds","tenants","tenant","shouldTaskContinue","modelsResult","models","model","listEntriesParams","listResult","entries","meta","entry","EmptyTrashBinTaskDefinition","TaskDefinition","TenantContext","ListTenantsUseCase","ListModelsUseCase","ListDeletedEntriesUseCase","DeleteEntryUseCase"],"mappings":";;;;;;AAQA,MAAMA,0BAA0B;IAG5B,MAAMC,yBAAyBC,QAAQ,GAAG,CAAC,yCAAyC;IACpF,MAAMC,kBACFF,0BAA0BG,AAAmC,MAAnCA,OAAOH,0BAC3BG,OAAOH,0BACP;IAGV,MAAMI,cAAc,IAAIC;IACxBD,YAAY,OAAO,CAACA,YAAY,OAAO,KAAKF;IAG5C,OAAOE,YAAY,WAAW;AAClC;AAEA,MAAME;IAcF,YACYC,aAAsC,EACtCC,WAAyC,EACzCC,UAAuC,EACvCC,kBAAuD,EACvDC,WAAyC,CACnD;aALUJ,aAAa,GAAbA;aACAC,WAAW,GAAXA;aACAC,UAAU,GAAVA;aACAC,kBAAkB,GAAlBA;aACAC,WAAW,GAAXA;aAfI,SAAS,GAAG;aACZ,EAAE,GAAG;aACL,KAAK,GAAG;aACR,WAAW,GACvB;aACY,aAAa,GAAG;aAChB,YAAY,GAAG;aAEf,WAAW,GAAG;YAAC;YAAsB;SAAmB;IAQrE;IAEH,MAAM,IACFC,MAA6E,EACF;QAC3E,MAAM,EAAEC,KAAK,EAAEC,UAAU,EAAE,GAAGF;QAG9B,IAAIE,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAItC,MAAMC,gBAAgB,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO;QACpD,IAAIA,cAAc,MAAM,IACpB,OAAOD,WAAW,QAAQ,CAAC,KAAK,CAACC,cAAc,KAAK;QAExD,MAAMC,cAAcD,cAAc,KAAK;QACvC,MAAME,oBAAoBJ,MAAM,iBAAiB,IAAI,EAAE;QACvD,MAAMK,UAAUF,YAAY,MAAM,CAACG,CAAAA,SAAU,CAACF,kBAAkB,QAAQ,CAACE,OAAO,EAAE;QAElF,IAAIC,qBAAqB;QAGzB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAACF,SAAS,OAAMC;YACnD,IAAIL,WAAW,OAAO,CAAC,gBAAgB,IAAI;gBACvCM,qBAAqB;gBACrB;YACJ;YAEA,IAAIN,WAAW,OAAO,CAAC,gBAAgB,IAAI;gBACvCM,qBAAqB;gBACrB;YACJ;YAGA,MAAMC,eAAe,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,gBAAgB;YAAM;YAC3E,IAAIA,aAAa,MAAM,IAAI,YACvBP,WAAW,MAAM,CAAC,KAAK,CAACO,aAAa,KAAK;YAG9C,MAAMC,SAASD,aAAa,KAAK;YAGjC,KAAK,MAAME,SAASD,OAAQ;gBAExB,MAAME,oBAAoB;oBACtB,OAAO;wBACH,cAAczB;oBAClB;oBACA,OAAO;gBACX;gBAGA,MAAO,KAAM;oBACT,MAAM0B,aAAa,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CACpDF,OACAC;oBAEJ,IAAIC,WAAW,MAAM,IAAI;wBACrBX,WAAW,MAAM,CAAC,KAAK,CAACW,WAAW,KAAK;wBACxC;oBACJ;oBACA,MAAM,EAAEC,OAAO,EAAEC,IAAI,EAAE,GAAGF,WAAW,KAAK;oBAE1C,IAAIE,AAAoB,MAApBA,KAAK,UAAU,EACf;oBAGJ,IAAIb,WAAW,OAAO,CAAC,gBAAgB,IAAI;wBACvCM,qBAAqB;wBACrB;oBACJ;oBACA,KAAK,MAAMQ,SAASF,QAAS;wBACzB,IAAIZ,WAAW,OAAO,CAAC,gBAAgB,IAAI;4BACvCM,qBAAqB;4BACrB;wBACJ;wBAEA,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAACG,OAAOK,MAAM,EAAE,EAAE;4BAAE,aAAa;wBAAK;oBACxE;gBACJ;YACJ;YAGA,IAAI,CAACR,oBACDH,kBAAkB,IAAI,CAACE,OAAO,EAAE;QAExC;QAGA,OAAOC,qBACDN,WAAW,QAAQ,CAAC,QAAQ,CAAC;YAAE,GAAGD,KAAK;YAAEI;QAAkB,KAC3DH,WAAW,QAAQ,CAAC,IAAI,CACpB;IAEd;AACJ;AAEO,MAAMe,8BAA8BC,eAAe,oBAAoB,CAAC;IAC3E,gBAAgBxB;IAChB,cAAc;QACVyB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
1
+ {"version":3,"file":"tasks/EmptyTrashBinTaskDefinition.js","sources":["../../src/tasks/EmptyTrashBinTaskDefinition.ts"],"sourcesContent":["import type { IEmptyTrashBinsInput, IEmptyTrashBinsOutput } from \"~/types.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { ListTenantsUseCase } from \"@webiny/api-core/features/tenancy/ListTenants/index.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { ListModelsUseCase } from \"@webiny/api-headless-cms/features/contentModel/ListModels/index.js\";\nimport { DeleteEntryUseCase } from \"@webiny/api-headless-cms/features/contentEntry/DeleteEntry/index.js\";\nimport { ListDeletedEntriesUseCase } from \"@webiny/api-headless-cms/features/contentEntry/ListEntries/index.js\";\n\nconst calculateDateTimeString = () => {\n // Retrieve the retention period from the environment variable WEBINY_TRASH_BIN_RETENTION_PERIOD_DAYS,\n // or default to 90 days if not set or set to 0.\n const retentionPeriodFromEnv = process.env[\"WEBINY_TRASH_BIN_RETENTION_PERIOD_DAYS\"];\n const retentionPeriod =\n retentionPeriodFromEnv && Number(retentionPeriodFromEnv) !== 0\n ? Number(retentionPeriodFromEnv)\n : 90;\n\n // Calculate the date-time by subtracting the retention period (in days) from the current date.\n const currentDate = new Date();\n currentDate.setDate(currentDate.getDate() - retentionPeriod);\n\n // Return the calculated date-time string in ISO 8601 format.\n return currentDate.toISOString();\n};\n\nclass EmptyTrashBinTask implements TaskDefinition.Interface<\n IEmptyTrashBinsInput,\n IEmptyTrashBinsOutput\n> {\n public readonly isPrivate = true;\n public readonly id = \"hcmsEntriesEmptyTrashBins\";\n public readonly title = \"Headless CMS - Empty all trash bins\";\n public readonly description =\n \"Delete all entries in the trash bin for each model in the system.\";\n public readonly maxIterations = 120;\n public readonly databaseLogs = false;\n\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private tenantContext: TenantContext.Interface,\n private listTenants: ListTenantsUseCase.Interface,\n private listModels: ListModelsUseCase.Interface,\n private listDeletedEntries: ListDeletedEntriesUseCase.Interface,\n private deleteEntry: DeleteEntryUseCase.Interface\n ) {}\n\n async run(\n params: TaskDefinition.RunParams<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>\n ): Promise<TaskDefinition.Result<IEmptyTrashBinsInput, IEmptyTrashBinsOutput>> {\n const { input, controller } = params;\n\n // Abort the task if needed.\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Fetch all tenants, excluding those already processed.\n const tenantsResult = await this.listTenants.execute();\n const baseTenants = tenantsResult.value;\n const executedTenantIds = input.executedTenantIds || [];\n const tenants = baseTenants.filter(tenant => !executedTenantIds.includes(tenant.id));\n\n let shouldTaskContinue = false;\n\n // Iterate over each tenant.\n await this.tenantContext.withEachTenant(tenants, async tenant => {\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n return;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n return;\n }\n\n // List all non-private models.\n const modelsResult = await this.listModels.execute({ includePrivate: false });\n const models = modelsResult.value;\n\n // Process each model to delete trashed entries.\n for (const model of models) {\n // Query parameters for fetching deleted entries older than a minute ago.\n const listEntriesParams = {\n where: {\n deletedOn_lt: calculateDateTimeString()\n },\n limit: 50\n };\n\n // Continue deleting entries while there are entries left to delete.\n while (true) {\n const listResult = await this.listDeletedEntries.execute(\n model,\n listEntriesParams\n );\n const { entries, meta } = listResult.value;\n\n if (meta.totalCount === 0) {\n break;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n break;\n }\n for (const entry of entries) {\n if (controller.runtime.isCloseToTimeout()) {\n shouldTaskContinue = true;\n break;\n }\n // Delete each entry individually.\n await this.deleteEntry.execute(model, entry.id, { permanently: true });\n }\n }\n }\n\n // If the task isn't continuing, add the tenant to the executed list.\n if (!shouldTaskContinue) {\n executedTenantIds.push(tenant.id);\n }\n });\n\n // Continue the task or mark it as done based on the `shouldContinue` flag.\n return shouldTaskContinue\n ? controller.response.continue({ ...input, executedTenantIds })\n : controller.response.done(\n \"Task done: emptied the trash bin for all registered models.\"\n );\n }\n}\n\nexport const EmptyTrashBinTaskDefinition = TaskDefinition.createImplementation({\n implementation: EmptyTrashBinTask,\n dependencies: [\n TenantContext,\n ListTenantsUseCase,\n ListModelsUseCase,\n ListDeletedEntriesUseCase,\n DeleteEntryUseCase\n ]\n});\n"],"names":["calculateDateTimeString","retentionPeriodFromEnv","process","retentionPeriod","Number","currentDate","Date","EmptyTrashBinTask","tenantContext","listTenants","listModels","listDeletedEntries","deleteEntry","params","input","controller","tenantsResult","baseTenants","executedTenantIds","tenants","tenant","shouldTaskContinue","modelsResult","models","model","listEntriesParams","listResult","entries","meta","entry","EmptyTrashBinTaskDefinition","TaskDefinition","TenantContext","ListTenantsUseCase","ListModelsUseCase","ListDeletedEntriesUseCase","DeleteEntryUseCase"],"mappings":";;;;;;AAQA,MAAMA,0BAA0B;IAG5B,MAAMC,yBAAyBC,QAAQ,GAAG,CAAC,yCAAyC;IACpF,MAAMC,kBACFF,0BAA0BG,AAAmC,MAAnCA,OAAOH,0BAC3BG,OAAOH,0BACP;IAGV,MAAMI,cAAc,IAAIC;IACxBD,YAAY,OAAO,CAACA,YAAY,OAAO,KAAKF;IAG5C,OAAOE,YAAY,WAAW;AAClC;AAEA,MAAME;IAcF,YACYC,aAAsC,EACtCC,WAAyC,EACzCC,UAAuC,EACvCC,kBAAuD,EACvDC,WAAyC,CACnD;aALUJ,aAAa,GAAbA;aACAC,WAAW,GAAXA;aACAC,UAAU,GAAVA;aACAC,kBAAkB,GAAlBA;aACAC,WAAW,GAAXA;aAfI,SAAS,GAAG;aACZ,EAAE,GAAG;aACL,KAAK,GAAG;aACR,WAAW,GACvB;aACY,aAAa,GAAG;aAChB,YAAY,GAAG;aAEf,WAAW,GAAG;YAAC;YAAsB;SAAmB;IAQrE;IAEH,MAAM,IACFC,MAA6E,EACF;QAC3E,MAAM,EAAEC,KAAK,EAAEC,UAAU,EAAE,GAAGF;QAG9B,IAAIE,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAItC,MAAMC,gBAAgB,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO;QACpD,MAAMC,cAAcD,cAAc,KAAK;QACvC,MAAME,oBAAoBJ,MAAM,iBAAiB,IAAI,EAAE;QACvD,MAAMK,UAAUF,YAAY,MAAM,CAACG,CAAAA,SAAU,CAACF,kBAAkB,QAAQ,CAACE,OAAO,EAAE;QAElF,IAAIC,qBAAqB;QAGzB,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAACF,SAAS,OAAMC;YACnD,IAAIL,WAAW,OAAO,CAAC,gBAAgB,IAAI;gBACvCM,qBAAqB;gBACrB;YACJ;YAEA,IAAIN,WAAW,OAAO,CAAC,gBAAgB,IAAI;gBACvCM,qBAAqB;gBACrB;YACJ;YAGA,MAAMC,eAAe,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,gBAAgB;YAAM;YAC3E,MAAMC,SAASD,aAAa,KAAK;YAGjC,KAAK,MAAME,SAASD,OAAQ;gBAExB,MAAME,oBAAoB;oBACtB,OAAO;wBACH,cAAczB;oBAClB;oBACA,OAAO;gBACX;gBAGA,MAAO,KAAM;oBACT,MAAM0B,aAAa,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CACpDF,OACAC;oBAEJ,MAAM,EAAEE,OAAO,EAAEC,IAAI,EAAE,GAAGF,WAAW,KAAK;oBAE1C,IAAIE,AAAoB,MAApBA,KAAK,UAAU,EACf;oBAGJ,IAAIb,WAAW,OAAO,CAAC,gBAAgB,IAAI;wBACvCM,qBAAqB;wBACrB;oBACJ;oBACA,KAAK,MAAMQ,SAASF,QAAS;wBACzB,IAAIZ,WAAW,OAAO,CAAC,gBAAgB,IAAI;4BACvCM,qBAAqB;4BACrB;wBACJ;wBAEA,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAACG,OAAOK,MAAM,EAAE,EAAE;4BAAE,aAAa;wBAAK;oBACxE;gBACJ;YACJ;YAGA,IAAI,CAACR,oBACDH,kBAAkB,IAAI,CAACE,OAAO,EAAE;QAExC;QAGA,OAAOC,qBACDN,WAAW,QAAQ,CAAC,QAAQ,CAAC;YAAE,GAAGD,KAAK;YAAEI;QAAkB,KAC3DH,WAAW,QAAQ,CAAC,IAAI,CACpB;IAEd;AACJ;AAEO,MAAMe,8BAA8BC,eAAe,oBAAoB,CAAC;IAC3E,gBAAgBxB;IAChB,cAAc;QACVyB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
package/types.d.ts CHANGED
@@ -8,6 +8,7 @@ export interface HcmsBulkActionsContext extends BaseContext, CmsContext, TasksCo
8
8
  * Bulk Action Operation
9
9
  */
10
10
  export interface IBulkActionOperationInput {
11
+ actionName: string;
11
12
  modelId: string;
12
13
  ids: string[];
13
14
  data?: Record<string, any>;
@@ -30,6 +31,7 @@ export declare enum BulkActionOperationByModelAction {
30
31
  END_TASK = "END_TASK"
31
32
  }
32
33
  export interface IBulkActionOperationByModelInput {
34
+ actionName: string;
33
35
  modelId: string;
34
36
  identity?: ITaskIdentity;
35
37
  where?: Record<string, any>;
package/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../src/types.ts"],"sourcesContent":["import type { CmsContext } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { Context as BaseContext } from \"@webiny/handler/types.js\";\nimport type { Context as TasksContext, ITaskIdentity } from \"@webiny/background-tasks/api/types.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface HcmsBulkActionsContext extends BaseContext, CmsContext, TasksContext {}\n\n/**\n * Bulk Action Operation\n */\n\nexport interface IBulkActionOperationInput {\n modelId: string;\n ids: string[];\n data?: Record<string, any>;\n identity: ITaskIdentity;\n done?: string[];\n failed?: string[];\n}\n\nexport interface IBulkActionOperationOutput {\n done: string[];\n failed: string[];\n}\n\nexport type IBulkActionOperationTaskParams = TaskDefinition.RunParams<\n IBulkActionOperationInput,\n IBulkActionOperationOutput\n>;\n\n/**\n * Bulk Action Operation By Model\n */\n\nexport enum BulkActionOperationByModelAction {\n CREATE_SUBTASKS = \"CREATE_SUBTASKS\",\n CHECK_MORE_SUBTASKS = \"CHECK_MORE_SUBTASKS\",\n PROCESS_SUBTASKS = \"PROCESS_SUBTASKS\",\n END_TASK = \"END_TASK\"\n}\n\nexport interface IBulkActionOperationByModelInput {\n modelId: string;\n identity?: ITaskIdentity;\n where?: Record<string, any>;\n search?: string;\n after?: string | null;\n data?: Record<string, any>;\n action?: BulkActionOperationByModelAction;\n}\n\nexport interface IBulkActionOperationByModelOutput {\n done: string[];\n failed: string[];\n}\n\nexport type IBulkActionOperationByModelTaskParams = TaskDefinition.RunParams<\n IBulkActionOperationByModelInput,\n IBulkActionOperationByModelOutput\n>;\n\n/**\n * Empty Trash Bin\n */\n\nexport interface IEmptyTrashBinsInput {\n executedTenantIds?: string[] | null;\n}\n\nexport type IEmptyTrashBinsOutput = TaskDefinition.ResultDone;\n\nexport type IEmptyTrashBinsTaskParams = TaskDefinition.RunParams<\n IEmptyTrashBinsInput,\n IEmptyTrashBinsOutput\n>;\n"],"names":["BulkActionOperationByModelAction"],"mappings":"AAkCO,IAAKA,yCAAgCA,WAAAA,GAAAA,SAAhCA,gCAAgC;;;;;WAAhCA"}
1
+ {"version":3,"file":"types.js","sources":["../src/types.ts"],"sourcesContent":["import type { CmsContext } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { Context as BaseContext } from \"@webiny/handler/types.js\";\nimport type { Context as TasksContext, ITaskIdentity } from \"@webiny/background-tasks/api/types.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface HcmsBulkActionsContext extends BaseContext, CmsContext, TasksContext {}\n\n/**\n * Bulk Action Operation\n */\n\nexport interface IBulkActionOperationInput {\n actionName: string;\n modelId: string;\n ids: string[];\n data?: Record<string, any>;\n identity: ITaskIdentity;\n done?: string[];\n failed?: string[];\n}\n\nexport interface IBulkActionOperationOutput {\n done: string[];\n failed: string[];\n}\n\nexport type IBulkActionOperationTaskParams = TaskDefinition.RunParams<\n IBulkActionOperationInput,\n IBulkActionOperationOutput\n>;\n\n/**\n * Bulk Action Operation By Model\n */\n\nexport enum BulkActionOperationByModelAction {\n CREATE_SUBTASKS = \"CREATE_SUBTASKS\",\n CHECK_MORE_SUBTASKS = \"CHECK_MORE_SUBTASKS\",\n PROCESS_SUBTASKS = \"PROCESS_SUBTASKS\",\n END_TASK = \"END_TASK\"\n}\n\nexport interface IBulkActionOperationByModelInput {\n actionName: string;\n modelId: string;\n identity?: ITaskIdentity;\n where?: Record<string, any>;\n search?: string;\n after?: string | null;\n data?: Record<string, any>;\n action?: BulkActionOperationByModelAction;\n}\n\nexport interface IBulkActionOperationByModelOutput {\n done: string[];\n failed: string[];\n}\n\nexport type IBulkActionOperationByModelTaskParams = TaskDefinition.RunParams<\n IBulkActionOperationByModelInput,\n IBulkActionOperationByModelOutput\n>;\n\n/**\n * Empty Trash Bin\n */\n\nexport interface IEmptyTrashBinsInput {\n executedTenantIds?: string[] | null;\n}\n\nexport type IEmptyTrashBinsOutput = TaskDefinition.ResultDone;\n\nexport type IEmptyTrashBinsTaskParams = TaskDefinition.RunParams<\n IEmptyTrashBinsInput,\n IEmptyTrashBinsOutput\n>;\n"],"names":["BulkActionOperationByModelAction"],"mappings":"AAmCO,IAAKA,yCAAgCA,WAAAA,GAAAA,SAAhCA,gCAAgC;;;;;WAAhCA"}
@@ -1,5 +0,0 @@
1
- import type { HcmsBulkActionsContext } from "../../types.js";
2
- export declare const BulkActionContext: import("@webiny/di").Abstraction<HcmsBulkActionsContext>;
3
- export declare namespace BulkActionContext {
4
- type Interface = HcmsBulkActionsContext;
5
- }
@@ -1,5 +0,0 @@
1
- import { createAbstraction } from "@webiny/feature/api";
2
- const BulkActionContext = createAbstraction("BulkActionContext");
3
- export { BulkActionContext };
4
-
5
- //# sourceMappingURL=abstractions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features/BulkActionContext/abstractions.js","sources":["../../../src/features/BulkActionContext/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { HcmsBulkActionsContext } from \"~/types.js\";\n\n// TODO: this is a bridge for legacy context; needs review and refactor of code that uses it.\n\nexport const BulkActionContext = createAbstraction<HcmsBulkActionsContext>(\"BulkActionContext\");\n\nexport namespace BulkActionContext {\n export type Interface = HcmsBulkActionsContext;\n}\n"],"names":["BulkActionContext","createAbstraction"],"mappings":";AAKO,MAAMA,oBAAoBC,kBAA0C"}
@@ -1 +0,0 @@
1
- export * from "./abstractions.js";
@@ -1 +0,0 @@
1
- export * from "./abstractions.js";
@@ -1 +0,0 @@
1
- export declare const createEventBridgeHandler: () => import("@webiny/handler-aws").EventBridgeEventHandler<"WebinyEmptyTrashBin", Record<string, any>, any>;
@@ -1,28 +0,0 @@
1
- import { createEventBridgeEventHandler } from "@webiny/handler-aws";
2
- const DETAIL_TYPE = "WebinyEmptyTrashBin";
3
- const createEventBridgeHandler = ()=>{
4
- const handler = createEventBridgeEventHandler(async ({ context: ctx, payload, next })=>{
5
- try {
6
- if (payload["detail-type"] !== DETAIL_TYPE) return next();
7
- const context = ctx;
8
- if (!context.tasks || !context.tenancy) return void console.error("Missing tasks or tenancy definition on context.");
9
- await context.tenancy.withRootTenant(async ()=>{
10
- await context.tasks.trigger({
11
- definition: "hcmsEntriesEmptyTrashBins"
12
- });
13
- });
14
- return;
15
- } catch (ex) {
16
- console.error("[EVENT_BRIDGE_HANDLER_EMPTY_TRASH_BIN] => ", JSON.stringify({
17
- message: ex.message,
18
- code: ex.code,
19
- data: ex.data
20
- }));
21
- }
22
- });
23
- handler.name = handler.type + ".cmsBulkActions";
24
- return handler;
25
- };
26
- export { createEventBridgeHandler };
27
-
28
- //# sourceMappingURL=eventBridgeEventHandler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handlers/eventBridgeEventHandler.js","sources":["../../src/handlers/eventBridgeEventHandler.ts"],"sourcesContent":["import { createEventBridgeEventHandler } from \"@webiny/handler-aws\";\nimport type { HcmsBulkActionsContext } from \"~/types.js\";\n\nconst DETAIL_TYPE = \"WebinyEmptyTrashBin\";\n\nexport const createEventBridgeHandler = () => {\n const handler = createEventBridgeEventHandler<typeof DETAIL_TYPE, Record<string, any>>(\n async ({ context: ctx, payload, next }) => {\n try {\n /**\n * If we receive an event that is not \"WebinyEmptyTrashBin\", we should exit.\n */\n if (payload[\"detail-type\"] !== DETAIL_TYPE) {\n return next();\n }\n\n const context = ctx as unknown as HcmsBulkActionsContext;\n\n if (!context.tasks || !context.tenancy) {\n console.error(\"Missing tasks or tenancy definition on context.\");\n return;\n }\n\n /**\n * Since the event is at the infrastructure level, it has no knowledge about tenancy.\n * We trigger the `hcmsEntriesEmptyTrashBins` using root tenant.\n */\n await context.tenancy.withRootTenant(async () => {\n await context.tasks.trigger({\n definition: \"hcmsEntriesEmptyTrashBins\"\n });\n });\n\n return;\n } catch (ex) {\n console.error(\n \"[EVENT_BRIDGE_HANDLER_EMPTY_TRASH_BIN] => \",\n JSON.stringify({\n message: ex.message,\n code: ex.code,\n data: ex.data\n })\n );\n }\n }\n );\n\n // Assign a human-readable name for easier debugging.\n handler.name = handler.type + \".cmsBulkActions\";\n\n return handler;\n};\n"],"names":["DETAIL_TYPE","createEventBridgeHandler","handler","createEventBridgeEventHandler","ctx","payload","next","context","console","ex","JSON"],"mappings":";AAGA,MAAMA,cAAc;AAEb,MAAMC,2BAA2B;IACpC,MAAMC,UAAUC,8BACZ,OAAO,EAAE,SAASC,GAAG,EAAEC,OAAO,EAAEC,IAAI,EAAE;QAClC,IAAI;YAIA,IAAID,OAAO,CAAC,cAAc,KAAKL,aAC3B,OAAOM;YAGX,MAAMC,UAAUH;YAEhB,IAAI,CAACG,QAAQ,KAAK,IAAI,CAACA,QAAQ,OAAO,EAAE,YACpCC,QAAQ,KAAK,CAAC;YAQlB,MAAMD,QAAQ,OAAO,CAAC,cAAc,CAAC;gBACjC,MAAMA,QAAQ,KAAK,CAAC,OAAO,CAAC;oBACxB,YAAY;gBAChB;YACJ;YAEA;QACJ,EAAE,OAAOE,IAAI;YACTD,QAAQ,KAAK,CACT,8CACAE,KAAK,SAAS,CAAC;gBACX,SAASD,GAAG,OAAO;gBACnB,MAAMA,GAAG,IAAI;gBACb,MAAMA,GAAG,IAAI;YACjB;QAER;IACJ;IAIJP,QAAQ,IAAI,GAAGA,QAAQ,IAAI,GAAG;IAE9B,OAAOA;AACX"}
@@ -1 +0,0 @@
1
- export declare const createHandlers: () => (import("@webiny/handler-aws/index.js").EventBridgeEventHandler<"WebinyEmptyTrashBin", Record<string, any>, any> | import("@webiny/handler/index.js").HandlerOnRequestPlugin<import("@webiny/handler/types.js").Context>)[];
package/handlers/index.js DELETED
@@ -1,9 +0,0 @@
1
- import { createEventBridgeHandler } from "./eventBridgeEventHandler.js";
2
- import { setupEventsTenant } from "./setupEventsTenant.js";
3
- const createHandlers = ()=>[
4
- setupEventsTenant(),
5
- createEventBridgeHandler()
6
- ];
7
- export { createHandlers };
8
-
9
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handlers/index.js","sources":["../../src/handlers/index.ts"],"sourcesContent":["import { createEventBridgeHandler } from \"./eventBridgeEventHandler.js\";\nimport { setupEventsTenant } from \"./setupEventsTenant.js\";\n\nexport const createHandlers = () => {\n return [setupEventsTenant(), createEventBridgeHandler()];\n};\n"],"names":["createHandlers","setupEventsTenant","createEventBridgeHandler"],"mappings":";;AAGO,MAAMA,iBAAiB,IACnB;QAACC;QAAqBC;KAA2B"}
@@ -1 +0,0 @@
1
- export declare const setupEventsTenant: () => import("@webiny/handler").HandlerOnRequestPlugin<import("@webiny/handler/types").Context>;
@@ -1,10 +0,0 @@
1
- import { createHandlerOnRequest } from "@webiny/handler";
2
- const setupEventsTenant = ()=>createHandlerOnRequest(async (request)=>{
3
- request.headers = {
4
- ...request.headers,
5
- "x-tenant": request.headers["x-tenant"] || "root"
6
- };
7
- });
8
- export { setupEventsTenant };
9
-
10
- //# sourceMappingURL=setupEventsTenant.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handlers/setupEventsTenant.js","sources":["../../src/handlers/setupEventsTenant.ts"],"sourcesContent":["import { createHandlerOnRequest } from \"@webiny/handler\";\n\nexport const setupEventsTenant = () => {\n return createHandlerOnRequest(async request => {\n request.headers = {\n ...request.headers,\n \"x-tenant\": request.headers[\"x-tenant\"] || \"root\"\n };\n\n return;\n });\n};\n"],"names":["setupEventsTenant","createHandlerOnRequest","request"],"mappings":";AAEO,MAAMA,oBAAoB,IACtBC,uBAAuB,OAAMC;QAChCA,QAAQ,OAAO,GAAG;YACd,GAAGA,QAAQ,OAAO;YAClB,YAAYA,QAAQ,OAAO,CAAC,WAAW,IAAI;QAC/C;IAGJ"}
package/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { createHandlers } from \"~/handlers/index.js\";\nimport { createBeforeHandlerPlugin } from \"@webiny/handler/plugins/BeforeHandlerPlugin.js\";\nimport {\n EntriesBulkAction,\n EntriesBulkActionConfig\n} from \"~/features/EntriesBulkAction/abstractions.js\";\nimport { BulkActionContext } from \"~/features/BulkActionContext/index.js\";\nimport { createBulkActionTasks } from \"~/features/EntriesBulkAction/createBulkActionTasks.js\";\nimport { createDefaultGraphQL } from \"~/graphql/createDefaultGraphQL.js\";\nimport { createBulkActionGraphQL } from \"~/graphql/createBulkActionGraphQL.js\";\nimport { createContextPlugin } from \"@webiny/api\";\nimport { DeleteEntriesBulkActionFeature } from \"~/features/DeleteEntriesBulkAction/feature.js\";\nimport { MoveToFolderBulkActionFeature } from \"~/features/MoveToFolderBulkAction/feature.js\";\nimport { MoveToTrashBulkActionFeature } from \"~/features/MoveToTrashBulkAction/feature.js\";\nimport { PublishEntriesBulkActionFeature } from \"~/features/PublishEntriesBulkAction/feature.js\";\nimport { UnpublishEntriesBulkActionFeature } from \"~/features/UnpublishEntriesBulkAction/feature.js\";\nimport { RestoreEntriesBulkActionFeature } from \"~/features/RestoreEntriesBulkAction/feature.js\";\nimport type { HcmsBulkActionsContext } from \"~/types.js\";\n\nexport type * from \"./abstractions/index.js\";\nexport { createHandlers } from \"./handlers/index.js\";\nexport { createEmptyTrashBinsTask } from \"./tasks/index.js\";\n\ninterface BulkActionsConfig {\n batchSize?: number;\n}\n\nexport const createHcmsBulkActions = (config?: BulkActionsConfig) => {\n const batchSize = config?.batchSize ?? 100;\n\n return [\n createHandlers(),\n createDefaultGraphQL(),\n // Register bulk action features\n createContextPlugin(context => {\n // Bulk action config is shared among all bulk actions.\n context.container.registerInstance(EntriesBulkActionConfig, { batchSize });\n\n DeleteEntriesBulkActionFeature.register(context.container);\n MoveToFolderBulkActionFeature.register(context.container);\n MoveToTrashBulkActionFeature.register(context.container);\n PublishEntriesBulkActionFeature.register(context.container);\n UnpublishEntriesBulkActionFeature.register(context.container);\n RestoreEntriesBulkActionFeature.register(context.container);\n }),\n // Set up bulk actions after the context is bootstrapped, but before actual handler processing\n createBeforeHandlerPlugin<HcmsBulkActionsContext>(async context => {\n context.container.registerInstance(BulkActionContext, context);\n\n const bulkActions = context.container.resolveAll(EntriesBulkAction);\n const bulkActionsConfig = context.container.resolve(EntriesBulkActionConfig);\n\n // 2. For each EntriesBulkAction, create and register tasks + GraphQL schema\n for (const bulkAction of bulkActions) {\n // Register tasks implementation\n const feature = createBulkActionTasks(bulkAction, bulkActionsConfig);\n feature.register(context.container);\n // Register GraphQL schema\n await createBulkActionGraphQL(context, bulkAction);\n }\n })\n ];\n};\n"],"names":["createHcmsBulkActions","config","batchSize","createHandlers","createDefaultGraphQL","createContextPlugin","context","EntriesBulkActionConfig","DeleteEntriesBulkActionFeature","MoveToFolderBulkActionFeature","MoveToTrashBulkActionFeature","PublishEntriesBulkActionFeature","UnpublishEntriesBulkActionFeature","RestoreEntriesBulkActionFeature","createBeforeHandlerPlugin","BulkActionContext","bulkActions","EntriesBulkAction","bulkActionsConfig","bulkAction","feature","createBulkActionTasks","createBulkActionGraphQL"],"mappings":";;;;;;;;;;;;;;AA2BO,MAAMA,wBAAwB,CAACC;IAClC,MAAMC,YAAYD,QAAQ,aAAa;IAEvC,OAAO;QACHE;QACAC;QAEAC,oBAAoBC,CAAAA;YAEhBA,QAAQ,SAAS,CAAC,gBAAgB,CAACC,yBAAyB;gBAAEL;YAAU;YAExEM,+BAA+B,QAAQ,CAACF,QAAQ,SAAS;YACzDG,8BAA8B,QAAQ,CAACH,QAAQ,SAAS;YACxDI,6BAA6B,QAAQ,CAACJ,QAAQ,SAAS;YACvDK,gCAAgC,QAAQ,CAACL,QAAQ,SAAS;YAC1DM,kCAAkC,QAAQ,CAACN,QAAQ,SAAS;YAC5DO,gCAAgC,QAAQ,CAACP,QAAQ,SAAS;QAC9D;QAEAQ,0BAAkD,OAAMR;YACpDA,QAAQ,SAAS,CAAC,gBAAgB,CAACS,mBAAmBT;YAEtD,MAAMU,cAAcV,QAAQ,SAAS,CAAC,UAAU,CAACW;YACjD,MAAMC,oBAAoBZ,QAAQ,SAAS,CAAC,OAAO,CAACC;YAGpD,KAAK,MAAMY,cAAcH,YAAa;gBAElC,MAAMI,UAAUC,sBAAsBF,YAAYD;gBAClDE,QAAQ,QAAQ,CAACd,QAAQ,SAAS;gBAElC,MAAMgB,wBAAwBhB,SAASa;YAC3C;QACJ;KACH;AACL"}
@@ -1 +0,0 @@
1
- export declare const createEmptyTrashBinsTask: () => import("@webiny/api").ContextPlugin<import("@webiny/api/types.js").Context>;
@@ -1,8 +0,0 @@
1
- import { createContextPlugin } from "@webiny/api";
2
- import { EmptyTrashBinTaskDefinition } from "./EmptyTrashBinTaskDefinition.js";
3
- const createEmptyTrashBinsTask = ()=>createContextPlugin((context)=>{
4
- context.container.register(EmptyTrashBinTaskDefinition);
5
- });
6
- export { createEmptyTrashBinsTask };
7
-
8
- //# sourceMappingURL=createEmptyTrashBinsTask.js.map