@localazy/strapi-plugin 1.0.11 → 1.1.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 (73) hide show
  1. package/dist/_chunks/{FetchIdentity-BB5V79aG.js → FetchIdentity-CevvxeEj.js} +73 -46
  2. package/dist/_chunks/{FetchIdentity-CkL7UYRt.mjs → FetchIdentity-DeThazz9.mjs} +43 -16
  3. package/dist/_chunks/{LanguagesSelector-DDjJ90sz.js → LanguagesSelector-BExpl4Vx.js} +15 -3
  4. package/dist/_chunks/{LanguagesSelector-BUSLrXE9.mjs → LanguagesSelector-D62gLZsM.mjs} +15 -3
  5. package/dist/_chunks/{LocalazyApp-H3kYTy7p.mjs → LocalazyApp-Czkb4s5J.mjs} +796 -69
  6. package/dist/_chunks/{LocalazyApp-BzcT9jmq.js → LocalazyApp-DIcO748C.js} +796 -67
  7. package/dist/_chunks/{LocalazyContentTransferSetup-rrXuAqRA.js → LocalazyContentTransferSetup-DAyZdwi9.js} +13 -10
  8. package/dist/_chunks/{LocalazyContentTransferSetup-BrLho135.mjs → LocalazyContentTransferSetup-Dx0Z6DXc.mjs} +13 -10
  9. package/dist/_chunks/{LocalazyGlobalSettings-NhjPAqfZ.mjs → LocalazyGlobalSettings-DWMBqlN4.mjs} +149 -12
  10. package/dist/_chunks/{LocalazyGlobalSettings-Dj93M25t.js → LocalazyGlobalSettings-DjrXGVxl.js} +148 -11
  11. package/dist/_chunks/{LocalazyPanel-DokDDR0T.mjs → LocalazyPanel-B-0HBTL_.mjs} +4 -4
  12. package/dist/_chunks/{LocalazyPanel-C1r8FU9w.js → LocalazyPanel-nBOpQo5B.js} +4 -4
  13. package/dist/_chunks/{LocalazyStatusColumn-CaAL-caH.mjs → LocalazyStatusColumn-CpO3yccG.mjs} +9 -7
  14. package/dist/_chunks/{LocalazyStatusColumn-D50ZkXY-.js → LocalazyStatusColumn-cGsUDMlX.js} +9 -7
  15. package/dist/_chunks/{RequireLocalazyAuth-C9qzj01C.js → RequireLocalazyAuth-56K8HUNR.js} +4 -4
  16. package/dist/_chunks/{RequireLocalazyAuth-c-nP7C0A.mjs → RequireLocalazyAuth-Dh-mAMcg.mjs} +4 -4
  17. package/dist/_chunks/{entry-exclusion-service-Db6jzNVM.mjs → entry-exclusion-service-Dm5_iP7I.mjs} +1 -1
  18. package/dist/_chunks/{entry-exclusion-service-0Ul5AWi-.js → entry-exclusion-service-Rf4Tr0zW.js} +1 -1
  19. package/dist/_chunks/{has-model-changed-VkgGfN-6.mjs → has-model-changed-6p1lR-Ho.mjs} +2 -2
  20. package/dist/_chunks/{has-model-changed-CmZh9bwD.js → has-model-changed-CGyDQARr.js} +2 -2
  21. package/dist/_chunks/{i18n-DaBjUC3Y.js → i18n-CAsbU4pi.js} +62 -4
  22. package/dist/_chunks/{i18n-Bga-GG_Z.mjs → i18n-QelOdIB2.mjs} +62 -4
  23. package/dist/_chunks/{index-BSNW1ypR.js → index-BK7lmZSN.js} +57 -19
  24. package/dist/_chunks/{index-C_svJuLd.mjs → index-Bpf1Mw2A.mjs} +8 -8
  25. package/dist/_chunks/{index-CaHacyle.js → index-BsQ_ie4C.js} +8 -8
  26. package/dist/_chunks/{index-BIHAiJnE.mjs → index-CHjIMO9T.mjs} +78 -40
  27. package/dist/_chunks/{strapi-api-base-BTpukPev.mjs → strapi-api-base-Bem_CGuz.mjs} +2 -2
  28. package/dist/_chunks/{strapi-api-base-DJi1gdZT.js → strapi-api-base-W_bUTSlY.js} +2 -2
  29. package/dist/admin/index.js +1 -1
  30. package/dist/admin/index.mjs +1 -1
  31. package/dist/admin/src/components/PluginErrorBoundary.d.ts +5 -0
  32. package/dist/admin/src/modules/@common/locale/en.d.ts +4 -0
  33. package/dist/admin/src/modules/@common/services/product-analytics-service.d.ts +1 -0
  34. package/dist/admin/src/modules/@common/services/project-service.d.ts +9 -0
  35. package/dist/admin/src/modules/@common/styles/heading-fix.d.ts +7 -0
  36. package/dist/admin/src/modules/@common/utils/export-json.d.ts +1 -0
  37. package/dist/admin/src/modules/@common/utils/redirect-to-plugin-route.d.ts +1 -0
  38. package/dist/admin/src/modules/activity-logs/components/HighlightMatch.d.ts +6 -0
  39. package/dist/admin/src/modules/activity-logs/components/SessionMetadata.d.ts +7 -0
  40. package/dist/admin/src/modules/activity-logs/components/SessionsTable.d.ts +17 -0
  41. package/dist/admin/src/modules/activity-logs/components/SortableHeader.d.ts +10 -0
  42. package/dist/admin/src/modules/activity-logs/components/StatusLabel.d.ts +6 -0
  43. package/dist/admin/src/modules/activity-logs/hooks/use-debounced-search.d.ts +6 -0
  44. package/dist/admin/src/modules/activity-logs/locale/en.d.ts +33 -0
  45. package/dist/admin/src/modules/activity-logs/models/activity-logs.d.ts +19 -0
  46. package/dist/admin/src/modules/activity-logs/services/activity-logs-service.d.ts +6 -0
  47. package/dist/admin/src/modules/activity-logs/utils/export-logs.d.ts +1 -0
  48. package/dist/admin/src/modules/activity-logs/utils/format-utils.d.ts +4 -0
  49. package/dist/admin/src/modules/plugin-settings/components/WebhookSetup.d.ts +2 -0
  50. package/dist/admin/src/modules/plugin-settings/locale/en.d.ts +21 -0
  51. package/dist/admin/src/pages/ActivityLogDetail.d.ts +7 -0
  52. package/dist/admin/src/pages/ActivityLogs.d.ts +7 -0
  53. package/dist/server/index.js +516 -61
  54. package/dist/server/index.mjs +516 -61
  55. package/dist/server/src/controllers/activity-logs-controller.d.ts +10 -0
  56. package/dist/server/src/controllers/index.d.ts +14 -3
  57. package/dist/server/src/controllers/localazy-auth-controller.d.ts +1 -1
  58. package/dist/server/src/controllers/localazy-project-controller.d.ts +3 -0
  59. package/dist/server/src/controllers/localazy-user-controller.d.ts +1 -1
  60. package/dist/server/src/controllers/plugin-settings-controller.d.ts +1 -1
  61. package/dist/server/src/core/index.d.ts +14 -0
  62. package/dist/server/src/db/model/activity-logs.d.ts +20 -0
  63. package/dist/server/src/db/model/plugin-settings.d.ts +14 -0
  64. package/dist/server/src/destroy.d.ts +1 -1
  65. package/dist/server/src/index.d.ts +31 -4
  66. package/dist/server/src/routes/activity-logs-routes.d.ts +9 -0
  67. package/dist/server/src/services/activity-logs-service.d.ts +17 -0
  68. package/dist/server/src/services/index.d.ts +16 -0
  69. package/dist/server/src/services/localazy-pubapi-service.d.ts +2 -0
  70. package/dist/server/src/services/strapi-service.d.ts +1 -0
  71. package/dist/server/src/utils/get-character-limits-metadata.d.ts +13 -0
  72. package/dist/server/src/utils/get-picked-flatten-keys-for-hook-entry.d.ts +3 -1
  73. package/package.json +5 -4
@@ -20532,7 +20532,7 @@ var distExports = dist$1.exports;
20532
20532
  const io = /* @__PURE__ */ getDefaultExportFromCjs(distExports);
20533
20533
  const { Server: Server2, Namespace, Socket: Socket3 } = io;
20534
20534
  const name = "@localazy/strapi-plugin";
20535
- const version = "1.0.11";
20535
+ const version = "1.1.1";
20536
20536
  const description = "The official Strapi Plugin by Localazy.";
20537
20537
  const keywords = [
20538
20538
  "strapi",
@@ -20593,11 +20593,12 @@ const scripts = {
20593
20593
  "test:server": "jest --config server/jest.config.ts",
20594
20594
  "test:server:coverage": "jest --config server/jest.config.ts --coverage",
20595
20595
  "test:server:watch": "jest --config server/jest.config.ts --watch",
20596
- "test:ts:back": "run -T tsc -p server/tsconfig.json",
20597
- "test:ts:front": "run -T tsc -p admin/tsconfig.json",
20596
+ "test:ts:back": "tsc -p server/tsconfig.json --noEmit",
20597
+ "test:ts:front": "tsc -p admin/tsconfig.json --noEmit",
20598
20598
  verify: "strapi-plugin verify",
20599
20599
  watch: "strapi-plugin watch",
20600
- "watch:link": "strapi-plugin watch:link"
20600
+ "watch:link": "strapi-plugin watch:link",
20601
+ prepare: "husky"
20601
20602
  };
20602
20603
  const dependencies = {
20603
20604
  shelljs: "^0.8.5",
@@ -20729,7 +20730,7 @@ const bootstrap = ({ strapi: strapi2 }) => {
20729
20730
  });
20730
20731
  }
20731
20732
  };
20732
- const destroy = ({ strapi: strapi2 }) => {
20733
+ const destroy = ({ strapi: _strapi }) => {
20733
20734
  };
20734
20735
  const isoStrapiToLocalazy = (isoStrapi) => {
20735
20736
  if (!isoStrapi) {
@@ -21887,6 +21888,100 @@ const pickEntries = (flatten, pickPaths) => {
21887
21888
  });
21888
21889
  return pickedEntries;
21889
21890
  };
21891
+ const getCharacterLimitsMetadata = (flattenedContent, modelUid) => {
21892
+ const metadata = {};
21893
+ const model = strapi.contentTypes[modelUid] || strapi.components[modelUid];
21894
+ if (!model) {
21895
+ return metadata;
21896
+ }
21897
+ for (const flatKey of Object.keys(flattenedContent)) {
21898
+ const maxLength = resolveMaxLength(flatKey, modelUid, model);
21899
+ if (maxLength != null) {
21900
+ metadata[`@meta:${flatKey}`] = { limit: maxLength };
21901
+ }
21902
+ }
21903
+ return metadata;
21904
+ };
21905
+ const resolveMaxLength = (flatKey, modelUid, model) => {
21906
+ if (!flatKey.startsWith(`${modelUid}[`)) {
21907
+ return void 0;
21908
+ }
21909
+ const afterUid = flatKey.substring(modelUid.length);
21910
+ const closingBracket = afterUid.indexOf("]");
21911
+ if (closingBracket === -1) {
21912
+ return void 0;
21913
+ }
21914
+ const withoutDocId = afterUid.substring(closingBracket + 2);
21915
+ if (!withoutDocId) {
21916
+ return void 0;
21917
+ }
21918
+ const allParts = withoutDocId.split(".");
21919
+ const fieldPath = parseFieldPath(allParts);
21920
+ if (fieldPath.length === 0) {
21921
+ return void 0;
21922
+ }
21923
+ return walkSchemaForMaxLength(fieldPath, model);
21924
+ };
21925
+ const parseFieldPath = (parts) => {
21926
+ const segments = [];
21927
+ let i2 = 0;
21928
+ while (i2 < parts.length) {
21929
+ const part = parts[i2];
21930
+ const dynamicZoneMatch = part.match(/^([^[]+)\[(\d+);(.+)$/);
21931
+ if (dynamicZoneMatch) {
21932
+ let componentName = dynamicZoneMatch[3];
21933
+ i2++;
21934
+ while (i2 < parts.length && !parts[i2].includes("]")) {
21935
+ componentName += "." + parts[i2];
21936
+ i2++;
21937
+ }
21938
+ if (i2 < parts.length && parts[i2].includes("]")) {
21939
+ componentName += "." + parts[i2].replace("]", "");
21940
+ i2++;
21941
+ }
21942
+ segments.push({ name: dynamicZoneMatch[1], dynamicZoneComponent: componentName });
21943
+ continue;
21944
+ }
21945
+ const bracketMatch = part.match(/^([^[]+)\[/);
21946
+ if (bracketMatch) {
21947
+ segments.push({ name: bracketMatch[1] });
21948
+ i2++;
21949
+ continue;
21950
+ }
21951
+ segments.push({ name: part });
21952
+ i2++;
21953
+ }
21954
+ return segments;
21955
+ };
21956
+ const walkSchemaForMaxLength = (fieldPath, model) => {
21957
+ let currentModel = model;
21958
+ for (let i2 = 0; i2 < fieldPath.length; i2++) {
21959
+ const segment = fieldPath[i2];
21960
+ const attribute = currentModel?.attributes?.[segment.name];
21961
+ if (!attribute) {
21962
+ return void 0;
21963
+ }
21964
+ if (i2 === fieldPath.length - 1) {
21965
+ return attribute.maxLength;
21966
+ }
21967
+ if (attribute.type === "component" && attribute.component) {
21968
+ currentModel = strapi.components[attribute.component];
21969
+ if (!currentModel) {
21970
+ return void 0;
21971
+ }
21972
+ continue;
21973
+ }
21974
+ if (attribute.type === "dynamiczone" && segment.dynamicZoneComponent) {
21975
+ currentModel = strapi.components[segment.dynamicZoneComponent];
21976
+ if (!currentModel) {
21977
+ return void 0;
21978
+ }
21979
+ continue;
21980
+ }
21981
+ return void 0;
21982
+ }
21983
+ return void 0;
21984
+ };
21890
21985
  const getMainKeysOfNestedArrayObjects = (array) => {
21891
21986
  return array.map((item) => Reflect.ownKeys(item)[0]);
21892
21987
  };
@@ -21981,6 +22076,9 @@ const getLocalazyUploadService = () => {
21981
22076
  const getEntryExclusionService = () => {
21982
22077
  return strapi.plugin(PLUGIN_NAME).service("EntryExclusionService");
21983
22078
  };
22079
+ const getActivityLogsService = () => {
22080
+ return strapi.plugin(PLUGIN_NAME).service("ActivityLogsService");
22081
+ };
21984
22082
  class PluginSettingsServiceHelper {
21985
22083
  constructor() {
21986
22084
  this.PluginSettingsService = getPluginSettingsService();
@@ -22159,8 +22257,13 @@ const getPickedFlattenKeysForHookEntry = async (params) => {
22159
22257
  };
22160
22258
  }
22161
22259
  const pickedFlatten = pickEntries(flatten, pickPathsWithUid);
22260
+ const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlatten, modelUid);
22261
+ const pickedFlattenWithMetadata = {
22262
+ ...pickedFlatten,
22263
+ ...characterLimitsMetadata
22264
+ };
22162
22265
  return {
22163
- pickedFlatten,
22266
+ pickedFlatten: pickedFlattenWithMetadata,
22164
22267
  eventEntryLocale,
22165
22268
  projectSourceLanguageCode
22166
22269
  };
@@ -23982,7 +24085,7 @@ const register = ({ strapi: strapi2 }) => {
23982
24085
  });
23983
24086
  };
23984
24087
  const contentTypes = {};
23985
- const LocalazyUserController = ({ strapi: strapi2 }) => ({
24088
+ const LocalazyUserController = ({ strapi: _strapi }) => ({
23986
24089
  async getUser(ctx) {
23987
24090
  ctx.body = await getLocalazyUserService().getUser();
23988
24091
  },
@@ -24080,7 +24183,7 @@ const LocalazyGenericConnectorClientFactory = async () => {
24080
24183
  });
24081
24184
  return api;
24082
24185
  };
24083
- const LocalazyAuthController = ({ strapi: strapi2 }) => ({
24186
+ const LocalazyAuthController = ({ strapi: _strapi }) => ({
24084
24187
  async generateKeys(ctx) {
24085
24188
  const GenericConnectorApi = await LocalazyGenericConnectorClientFactory();
24086
24189
  ctx.body = await GenericConnectorApi.public.keys();
@@ -24107,10 +24210,12 @@ const StrapiController = ({ strapi: strapi2 }) => ({
24107
24210
  },
24108
24211
  async getPluginVersion(ctx) {
24109
24212
  ctx.body = {
24110
- version: await getStrapiService().getPluginVersion()
24213
+ version: await getStrapiService().getPluginVersion(),
24214
+ versionStrapi: getStrapiService().getStrapiVersion()
24111
24215
  };
24112
24216
  }
24113
24217
  });
24218
+ const STRAPI_WEBHOOK_CUSTOM_ID = "strapi-plugin-localazy";
24114
24219
  const LocalazyProjectController = ({ strapi: strapi2 }) => ({
24115
24220
  async getConnectedProject(ctx) {
24116
24221
  const LocalazyUserService2 = getLocalazyUserService();
@@ -24118,9 +24223,69 @@ const LocalazyProjectController = ({ strapi: strapi2 }) => ({
24118
24223
  const user = await LocalazyUserService2.getUser();
24119
24224
  const project = await LocalazyPubAPIService2.getProject(user.project.id, true, true);
24120
24225
  ctx.body = project;
24226
+ },
24227
+ async getWebhookStatus(ctx) {
24228
+ const LocalazyUserService2 = getLocalazyUserService();
24229
+ const user = await LocalazyUserService2.getUser();
24230
+ const LocalazyPubApiService = getLocalazyPubAPIService();
24231
+ const webhooks = await LocalazyPubApiService.listWebhooks(user.project.id);
24232
+ const ours = webhooks.find((w2) => w2.customId === STRAPI_WEBHOOK_CUSTOM_ID);
24233
+ if (ours) {
24234
+ ctx.body = { status: "configured", url: ours.url, enabled: ours.enabled };
24235
+ return;
24236
+ }
24237
+ ctx.body = { status: "not_configured" };
24238
+ },
24239
+ async setupWebhook(ctx) {
24240
+ const { url: url2 } = ctx.request.body;
24241
+ if (!url2 || typeof url2 !== "string") {
24242
+ return ctx.badRequest("Webhook URL is required");
24243
+ }
24244
+ try {
24245
+ const parsed = new URL(url2);
24246
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
24247
+ return ctx.badRequest("Webhook URL must use http or https protocol");
24248
+ }
24249
+ } catch {
24250
+ return ctx.badRequest("Invalid webhook URL");
24251
+ }
24252
+ const LocalazyUserService2 = getLocalazyUserService();
24253
+ const user = await LocalazyUserService2.getUser();
24254
+ const LocalazyPubApiService = getLocalazyPubAPIService();
24255
+ const PluginSettingsService2 = getPluginSettingsService();
24256
+ const existing = await LocalazyPubApiService.listWebhooks(user.project.id);
24257
+ const filtered = existing.filter((w2) => w2.customId !== STRAPI_WEBHOOK_CUSTOM_ID);
24258
+ const items = [
24259
+ ...filtered,
24260
+ {
24261
+ enabled: true,
24262
+ customId: STRAPI_WEBHOOK_CUSTOM_ID,
24263
+ url: url2,
24264
+ events: ["project_published"],
24265
+ description: "Strapi Plugin - Download translations"
24266
+ }
24267
+ ];
24268
+ await LocalazyPubApiService.updateWebhooks(user.project.id, items);
24269
+ await PluginSettingsService2.updatePluginSettings({
24270
+ webhookConfig: { url: url2 }
24271
+ });
24272
+ ctx.body = { success: true };
24273
+ },
24274
+ async getStrapiUrl(ctx) {
24275
+ let url2 = strapi2.config.get("server.url");
24276
+ if (!url2) {
24277
+ const host = strapi2.config.get("server.host") || "0.0.0.0";
24278
+ const port = strapi2.config.get("server.port") || 1337;
24279
+ const displayHost = host === "0.0.0.0" || host === "::" ? "localhost" : host;
24280
+ url2 = `http://${displayHost}:${port}`;
24281
+ }
24282
+ const isLocal = /^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(
24283
+ url2
24284
+ );
24285
+ ctx.body = { url: url2, isLocal };
24121
24286
  }
24122
24287
  });
24123
- const PluginSettingsController = ({ strapi: strapi2 }) => ({
24288
+ const PluginSettingsController = ({ strapi: _strapi }) => ({
24124
24289
  async getContentTransferSetup(ctx) {
24125
24290
  ctx.body = await getPluginSettingsService().getContentTransferSetup();
24126
24291
  },
@@ -24315,6 +24480,27 @@ const EntryExclusionController = ({ strapi: strapi2 }) => ({
24315
24480
  }
24316
24481
  }
24317
24482
  });
24483
+ const ActivityLogsController = ({ strapi: _strapi }) => ({
24484
+ async getSessions(ctx) {
24485
+ const { type: type2 } = ctx.query;
24486
+ ctx.body = await getActivityLogsService().getSessions(type2);
24487
+ },
24488
+ async getSession(ctx) {
24489
+ const { sessionId } = ctx.params;
24490
+ const session = await getActivityLogsService().getSession(sessionId);
24491
+ if (!session) {
24492
+ return ctx.notFound("Session not found");
24493
+ }
24494
+ ctx.body = session;
24495
+ },
24496
+ async exportSessions(ctx) {
24497
+ ctx.body = await getActivityLogsService().getAllSessionsWithEntries();
24498
+ },
24499
+ async clearSessions(ctx) {
24500
+ await getActivityLogsService().clearSessions();
24501
+ ctx.body = { success: true };
24502
+ }
24503
+ });
24318
24504
  const controllers = {
24319
24505
  LocalazyUserController,
24320
24506
  LocalazyAuthController,
@@ -24322,7 +24508,8 @@ const controllers = {
24322
24508
  LocalazyProjectController,
24323
24509
  PluginSettingsController,
24324
24510
  LocalazyTransferController,
24325
- EntryExclusionController
24511
+ EntryExclusionController,
24512
+ ActivityLogsController
24326
24513
  };
24327
24514
  const verifyWebhook = (config2, { strapi: strapi2 }) => {
24328
24515
  return async (ctx, next) => {
@@ -24379,11 +24566,11 @@ const middlewares = {
24379
24566
  verifyWebhook
24380
24567
  };
24381
24568
  const policies = {};
24382
- const ROUTE_PREFIX$7 = "/user";
24569
+ const ROUTE_PREFIX$8 = "/user";
24383
24570
  const LocalazyUserRoutes = [
24384
24571
  {
24385
24572
  method: "GET",
24386
- path: `${ROUTE_PREFIX$7}`,
24573
+ path: `${ROUTE_PREFIX$8}`,
24387
24574
  handler: "LocalazyUserController.getUser",
24388
24575
  config: {
24389
24576
  policies: []
@@ -24391,7 +24578,7 @@ const LocalazyUserRoutes = [
24391
24578
  },
24392
24579
  {
24393
24580
  method: "PUT",
24394
- path: `${ROUTE_PREFIX$7}`,
24581
+ path: `${ROUTE_PREFIX$8}`,
24395
24582
  handler: "LocalazyUserController.updateUser",
24396
24583
  config: {
24397
24584
  policies: []
@@ -24399,18 +24586,18 @@ const LocalazyUserRoutes = [
24399
24586
  },
24400
24587
  {
24401
24588
  method: "DELETE",
24402
- path: `${ROUTE_PREFIX$7}`,
24589
+ path: `${ROUTE_PREFIX$8}`,
24403
24590
  handler: "LocalazyUserController.deleteUser",
24404
24591
  config: {
24405
24592
  policies: []
24406
24593
  }
24407
24594
  }
24408
24595
  ];
24409
- const ROUTE_PREFIX$6 = "/auth";
24596
+ const ROUTE_PREFIX$7 = "/auth";
24410
24597
  const LocalazyAuthRoutes = [
24411
24598
  {
24412
24599
  method: "GET",
24413
- path: `${ROUTE_PREFIX$6}/generate-keys`,
24600
+ path: `${ROUTE_PREFIX$7}/generate-keys`,
24414
24601
  handler: "LocalazyAuthController.generateKeys",
24415
24602
  config: {
24416
24603
  policies: []
@@ -24418,18 +24605,18 @@ const LocalazyAuthRoutes = [
24418
24605
  },
24419
24606
  {
24420
24607
  method: "GET",
24421
- path: `${ROUTE_PREFIX$6}/continuous-poll`,
24608
+ path: `${ROUTE_PREFIX$7}/continuous-poll`,
24422
24609
  handler: "LocalazyAuthController.continuousPoll",
24423
24610
  config: {
24424
24611
  policies: []
24425
24612
  }
24426
24613
  }
24427
24614
  ];
24428
- const ROUTE_PREFIX$5 = "/plugin-settings";
24615
+ const ROUTE_PREFIX$6 = "/plugin-settings";
24429
24616
  const PluginSettingsRoutes = [
24430
24617
  {
24431
24618
  method: "GET",
24432
- path: `${ROUTE_PREFIX$5}/content-transfer-setup`,
24619
+ path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
24433
24620
  handler: "PluginSettingsController.getContentTransferSetup",
24434
24621
  config: {
24435
24622
  policies: []
@@ -24437,7 +24624,7 @@ const PluginSettingsRoutes = [
24437
24624
  },
24438
24625
  {
24439
24626
  method: "PUT",
24440
- path: `${ROUTE_PREFIX$5}/content-transfer-setup`,
24627
+ path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
24441
24628
  handler: "PluginSettingsController.updateContentTransferSetup",
24442
24629
  config: {
24443
24630
  policies: []
@@ -24445,7 +24632,7 @@ const PluginSettingsRoutes = [
24445
24632
  },
24446
24633
  {
24447
24634
  method: "GET",
24448
- path: `${ROUTE_PREFIX$5}/plugin-settings`,
24635
+ path: `${ROUTE_PREFIX$6}/plugin-settings`,
24449
24636
  handler: "PluginSettingsController.getPluginSettings",
24450
24637
  config: {
24451
24638
  policies: []
@@ -24453,7 +24640,7 @@ const PluginSettingsRoutes = [
24453
24640
  },
24454
24641
  {
24455
24642
  method: "PUT",
24456
- path: `${ROUTE_PREFIX$5}/plugin-settings`,
24643
+ path: `${ROUTE_PREFIX$6}/plugin-settings`,
24457
24644
  handler: "PluginSettingsController.updatePluginSettings",
24458
24645
  config: {
24459
24646
  policies: []
@@ -24461,18 +24648,18 @@ const PluginSettingsRoutes = [
24461
24648
  },
24462
24649
  {
24463
24650
  method: "GET",
24464
- path: `${ROUTE_PREFIX$5}/sync-cursor`,
24651
+ path: `${ROUTE_PREFIX$6}/sync-cursor`,
24465
24652
  handler: "PluginSettingsController.getSyncCursor",
24466
24653
  config: {
24467
24654
  policies: []
24468
24655
  }
24469
24656
  }
24470
24657
  ];
24471
- const ROUTE_PREFIX$4 = "/strapi";
24658
+ const ROUTE_PREFIX$5 = "/strapi";
24472
24659
  const StrapiRoutes = [
24473
24660
  {
24474
24661
  method: "GET",
24475
- path: `${ROUTE_PREFIX$4}/models`,
24662
+ path: `${ROUTE_PREFIX$5}/models`,
24476
24663
  handler: "StrapiController.getModels",
24477
24664
  config: {
24478
24665
  policies: []
@@ -24480,7 +24667,7 @@ const StrapiRoutes = [
24480
24667
  },
24481
24668
  {
24482
24669
  method: "GET",
24483
- path: `${ROUTE_PREFIX$4}/localizable-models`,
24670
+ path: `${ROUTE_PREFIX$5}/localizable-models`,
24484
24671
  handler: "StrapiController.getLocalizableModels",
24485
24672
  config: {
24486
24673
  policies: []
@@ -24488,7 +24675,7 @@ const StrapiRoutes = [
24488
24675
  },
24489
24676
  {
24490
24677
  method: "POST",
24491
- path: `${ROUTE_PREFIX$4}/lifecycle/localazy-webhooks`,
24678
+ path: `${ROUTE_PREFIX$5}/lifecycle/localazy-webhooks`,
24492
24679
  handler: "StrapiController.postLifecycleLocalazyWebhooks",
24493
24680
  config: {
24494
24681
  policies: []
@@ -24496,18 +24683,18 @@ const StrapiRoutes = [
24496
24683
  },
24497
24684
  {
24498
24685
  method: "GET",
24499
- path: `${ROUTE_PREFIX$4}/version`,
24686
+ path: `${ROUTE_PREFIX$5}/version`,
24500
24687
  handler: "StrapiController.getPluginVersion",
24501
24688
  config: {
24502
24689
  policies: []
24503
24690
  }
24504
24691
  }
24505
24692
  ];
24506
- const ROUTE_PREFIX$3 = "/transfer";
24693
+ const ROUTE_PREFIX$4 = "/transfer";
24507
24694
  const LocalazyTransferRoutes = [
24508
24695
  {
24509
24696
  method: "POST",
24510
- path: `${ROUTE_PREFIX$3}/upload`,
24697
+ path: `${ROUTE_PREFIX$4}/upload`,
24511
24698
  handler: "LocalazyTransferController.upload",
24512
24699
  config: {
24513
24700
  policies: []
@@ -24515,29 +24702,53 @@ const LocalazyTransferRoutes = [
24515
24702
  },
24516
24703
  {
24517
24704
  method: "POST",
24518
- path: `${ROUTE_PREFIX$3}/download`,
24705
+ path: `${ROUTE_PREFIX$4}/download`,
24519
24706
  handler: "LocalazyTransferController.download",
24520
24707
  config: {
24521
24708
  policies: []
24522
24709
  }
24523
24710
  }
24524
24711
  ];
24525
- const ROUTE_PREFIX$2 = "/project";
24712
+ const ROUTE_PREFIX$3 = "/project";
24526
24713
  const LocalazyProjectRoutes = [
24527
24714
  {
24528
24715
  method: "GET",
24529
- path: `${ROUTE_PREFIX$2}`,
24716
+ path: `${ROUTE_PREFIX$3}`,
24530
24717
  handler: "LocalazyProjectController.getConnectedProject",
24531
24718
  config: {
24532
24719
  policies: []
24533
24720
  }
24721
+ },
24722
+ {
24723
+ method: "GET",
24724
+ path: `${ROUTE_PREFIX$3}/webhooks`,
24725
+ handler: "LocalazyProjectController.getWebhookStatus",
24726
+ config: {
24727
+ policies: []
24728
+ }
24729
+ },
24730
+ {
24731
+ method: "POST",
24732
+ path: `${ROUTE_PREFIX$3}/webhooks/setup`,
24733
+ handler: "LocalazyProjectController.setupWebhook",
24734
+ config: {
24735
+ policies: []
24736
+ }
24737
+ },
24738
+ {
24739
+ method: "GET",
24740
+ path: `${ROUTE_PREFIX$3}/strapi-url`,
24741
+ handler: "LocalazyProjectController.getStrapiUrl",
24742
+ config: {
24743
+ policies: []
24744
+ }
24534
24745
  }
24535
24746
  ];
24536
- const ROUTE_PREFIX$1 = "/public/transfer";
24747
+ const ROUTE_PREFIX$2 = "/public/transfer";
24537
24748
  const LocalazyPublicTransferRoutes = [
24538
24749
  {
24539
24750
  method: "POST",
24540
- path: `${ROUTE_PREFIX$1}/download`,
24751
+ path: `${ROUTE_PREFIX$2}/download`,
24541
24752
  handler: "LocalazyTransferController.download",
24542
24753
  config: {
24543
24754
  policies: [],
@@ -24547,11 +24758,11 @@ const LocalazyPublicTransferRoutes = [
24547
24758
  }
24548
24759
  }
24549
24760
  ];
24550
- const ROUTE_PREFIX = "/entry-exclusion";
24761
+ const ROUTE_PREFIX$1 = "/entry-exclusion";
24551
24762
  const EntryExclusionRoutes = [
24552
24763
  {
24553
24764
  method: "GET",
24554
- path: `${ROUTE_PREFIX}/:contentType/:documentId`,
24765
+ path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
24555
24766
  handler: "EntryExclusionController.getEntryExclusion",
24556
24767
  config: {
24557
24768
  policies: []
@@ -24559,7 +24770,7 @@ const EntryExclusionRoutes = [
24559
24770
  },
24560
24771
  {
24561
24772
  method: "PUT",
24562
- path: `${ROUTE_PREFIX}/:contentType/:documentId`,
24773
+ path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
24563
24774
  handler: "EntryExclusionController.setEntryExclusion",
24564
24775
  config: {
24565
24776
  policies: []
@@ -24567,13 +24778,48 @@ const EntryExclusionRoutes = [
24567
24778
  },
24568
24779
  {
24569
24780
  method: "GET",
24570
- path: `${ROUTE_PREFIX}/:contentType`,
24781
+ path: `${ROUTE_PREFIX$1}/:contentType`,
24571
24782
  handler: "EntryExclusionController.getContentTypeExclusions",
24572
24783
  config: {
24573
24784
  policies: []
24574
24785
  }
24575
24786
  }
24576
24787
  ];
24788
+ const ROUTE_PREFIX = "/activity-logs";
24789
+ const ActivityLogsRoutes = [
24790
+ {
24791
+ method: "GET",
24792
+ path: `${ROUTE_PREFIX}`,
24793
+ handler: "ActivityLogsController.getSessions",
24794
+ config: {
24795
+ policies: []
24796
+ }
24797
+ },
24798
+ {
24799
+ method: "GET",
24800
+ path: `${ROUTE_PREFIX}/export`,
24801
+ handler: "ActivityLogsController.exportSessions",
24802
+ config: {
24803
+ policies: []
24804
+ }
24805
+ },
24806
+ {
24807
+ method: "GET",
24808
+ path: `${ROUTE_PREFIX}/:sessionId`,
24809
+ handler: "ActivityLogsController.getSession",
24810
+ config: {
24811
+ policies: []
24812
+ }
24813
+ },
24814
+ {
24815
+ method: "DELETE",
24816
+ path: `${ROUTE_PREFIX}`,
24817
+ handler: "ActivityLogsController.clearSessions",
24818
+ config: {
24819
+ policies: []
24820
+ }
24821
+ }
24822
+ ];
24577
24823
  const routes = {
24578
24824
  "content-api": {
24579
24825
  routes: [...StrapiRoutes]
@@ -24587,14 +24833,15 @@ const routes = {
24587
24833
  ...StrapiRoutes,
24588
24834
  ...LocalazyTransferRoutes,
24589
24835
  ...LocalazyProjectRoutes,
24590
- ...EntryExclusionRoutes
24836
+ ...EntryExclusionRoutes,
24837
+ ...ActivityLogsRoutes
24591
24838
  ]
24592
24839
  },
24593
24840
  LocalazyPublicTransferRoutes: {
24594
24841
  routes: [...LocalazyPublicTransferRoutes]
24595
24842
  }
24596
24843
  };
24597
- const KEY$3 = "identity";
24844
+ const KEY$4 = "identity";
24598
24845
  const emptyIdentity = {
24599
24846
  accessToken: "",
24600
24847
  project: {
@@ -24618,13 +24865,13 @@ const getStrapiStore = (strapi2) => strapi2.store({
24618
24865
  const LocalazyUserService = ({ strapi: strapi2 }) => ({
24619
24866
  async getUser() {
24620
24867
  const pluginStore = getStrapiStore(strapi2);
24621
- const user = await pluginStore.get({ key: KEY$3 });
24868
+ const user = await pluginStore.get({ key: KEY$4 });
24622
24869
  return user || emptyIdentity;
24623
24870
  },
24624
24871
  async updateUser(identity2) {
24625
24872
  const pluginStore = getStrapiStore(strapi2);
24626
24873
  await pluginStore.set({
24627
- key: KEY$3,
24874
+ key: KEY$4,
24628
24875
  value: identity2
24629
24876
  });
24630
24877
  return identity2;
@@ -24698,6 +24945,9 @@ const StrapiService = ({ strapi: strapi2 }) => ({
24698
24945
  },
24699
24946
  async getPluginVersion() {
24700
24947
  return await Promise.resolve().then(() => _package$1).then((module2) => module2.version);
24948
+ },
24949
+ getStrapiVersion() {
24950
+ return strapi2.config.get("info.strapi");
24701
24951
  }
24702
24952
  });
24703
24953
  const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
@@ -24740,6 +24990,25 @@ const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
24740
24990
  return null;
24741
24991
  }
24742
24992
  },
24993
+ async listWebhooks(projectId) {
24994
+ try {
24995
+ const LocalazyApi = await LocalazyApiClientFactory();
24996
+ const result = await LocalazyApi.webhooks.list({ project: projectId });
24997
+ return result;
24998
+ } catch (e2) {
24999
+ strapi2.log.error(e2);
25000
+ return [];
25001
+ }
25002
+ },
25003
+ async updateWebhooks(projectId, items) {
25004
+ try {
25005
+ const LocalazyApi = await LocalazyApiClientFactory();
25006
+ await LocalazyApi.webhooks.update({ project: projectId, items });
25007
+ } catch (e2) {
25008
+ strapi2.log.error(e2);
25009
+ throw e2;
25010
+ }
25011
+ },
24743
25012
  async getWebhooksSecret(projectId) {
24744
25013
  try {
24745
25014
  const LocalazyApi = await LocalazyApiClientFactory();
@@ -24751,23 +25020,23 @@ const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
24751
25020
  }
24752
25021
  }
24753
25022
  });
24754
- const KEY$2 = "content-transfer-setup";
25023
+ const KEY$3 = "content-transfer-setup";
24755
25024
  const emptyContentTransferSetup = {
24756
25025
  has_setup: false,
24757
25026
  setup: []
24758
25027
  };
24759
- const KEY$1 = "plugin-settings";
25028
+ const KEY$2 = "plugin-settings";
24760
25029
  const emptyPluginSettings = {
24761
25030
  defaultRoute: null
24762
25031
  };
24763
- const KEY = "sync-cursor";
25032
+ const KEY$1 = "sync-cursor";
24764
25033
  const emptySyncCursor = {
24765
25034
  processedKeys: {}
24766
25035
  };
24767
25036
  const PluginSettingsService = ({ strapi: strapi2 }) => ({
24768
25037
  async getContentTransferSetup() {
24769
25038
  const pluginStore = getStrapiStore(strapi2);
24770
- const setup2 = await pluginStore.get({ key: KEY$2 });
25039
+ const setup2 = await pluginStore.get({ key: KEY$3 });
24771
25040
  return setup2 || emptyContentTransferSetup;
24772
25041
  },
24773
25042
  async updateContentTransferSetup(setup2) {
@@ -24777,14 +25046,14 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
24777
25046
  };
24778
25047
  const pluginStore = getStrapiStore(strapi2);
24779
25048
  await pluginStore.set({
24780
- key: KEY$2,
25049
+ key: KEY$3,
24781
25050
  value: newSetup
24782
25051
  });
24783
25052
  return newSetup;
24784
25053
  },
24785
25054
  async getPluginSettings() {
24786
25055
  const pluginStore = getStrapiStore(strapi2);
24787
- const settings = await pluginStore.get({ key: KEY$1 });
25056
+ const settings = await pluginStore.get({ key: KEY$2 });
24788
25057
  return settings || emptyPluginSettings;
24789
25058
  },
24790
25059
  async updatePluginSettings(settings) {
@@ -24795,20 +25064,20 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
24795
25064
  };
24796
25065
  const pluginStore = getStrapiStore(strapi2);
24797
25066
  await pluginStore.set({
24798
- key: KEY$1,
25067
+ key: KEY$2,
24799
25068
  value: newSettings
24800
25069
  });
24801
25070
  return newSettings;
24802
25071
  },
24803
25072
  async getSyncCursor() {
24804
25073
  const pluginStore = getStrapiStore(strapi2);
24805
- const cursor = await pluginStore.get({ key: KEY });
25074
+ const cursor = await pluginStore.get({ key: KEY$1 });
24806
25075
  return cursor || emptySyncCursor;
24807
25076
  },
24808
25077
  async updateSyncCursor(cursor) {
24809
25078
  const pluginStore = getStrapiStore(strapi2);
24810
25079
  await pluginStore.set({
24811
- key: KEY,
25080
+ key: KEY$1,
24812
25081
  value: cursor
24813
25082
  });
24814
25083
  return cursor;
@@ -24820,6 +25089,9 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24820
25089
  await notificationService.emit(EventType.UPLOAD, {
24821
25090
  message: "Upload started"
24822
25091
  });
25092
+ const activityLogsService = getActivityLogsService();
25093
+ const sessionId = await activityLogsService.startSession("upload", "Strapi User");
25094
+ await activityLogsService.addEntry(sessionId, "Upload started");
24823
25095
  let success = true;
24824
25096
  const StrapiService2 = getStrapiService();
24825
25097
  const StrapiI18nService2 = getStrapiI18nService();
@@ -24833,6 +25105,8 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24833
25105
  success,
24834
25106
  message
24835
25107
  });
25108
+ await activityLogsService.addEntry(sessionId, message);
25109
+ await activityLogsService.finishSession(sessionId, "failed", message);
24836
25110
  strapi2.log.info(message);
24837
25111
  return;
24838
25112
  }
@@ -24853,6 +25127,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24853
25127
  await notificationService.emit(EventType.UPLOAD, {
24854
25128
  message: message2
24855
25129
  });
25130
+ await activityLogsService.addEntry(sessionId, message2);
24856
25131
  strapi2.log.info(message2);
24857
25132
  continue;
24858
25133
  }
@@ -24863,6 +25138,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24863
25138
  await notificationService.emit(EventType.UPLOAD, {
24864
25139
  message: message2
24865
25140
  });
25141
+ await activityLogsService.addEntry(sessionId, message2);
24866
25142
  strapi2.log.warn(message2);
24867
25143
  continue;
24868
25144
  }
@@ -24889,6 +25165,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24889
25165
  await notificationService.emit(EventType.UPLOAD, {
24890
25166
  message: message2
24891
25167
  });
25168
+ await activityLogsService.addEntry(sessionId, message2);
24892
25169
  strapi2.log.info(message2);
24893
25170
  continue;
24894
25171
  }
@@ -24896,6 +25173,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24896
25173
  await notificationService.emit(EventType.UPLOAD, {
24897
25174
  message
24898
25175
  });
25176
+ await activityLogsService.addEntry(sessionId, message);
24899
25177
  strapi2.log.info(message);
24900
25178
  entries = omitDeep(entries, ["locale", "createdAt", "updatedAt", "publishedAt"]);
24901
25179
  entries.forEach((entry) => {
@@ -24908,6 +25186,11 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24908
25186
  ...pickedFlatten
24909
25187
  };
24910
25188
  });
25189
+ const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlattenStrapiContent, modelUid);
25190
+ pickedFlattenStrapiContent = {
25191
+ ...pickedFlattenStrapiContent,
25192
+ ...characterLimitsMetadata
25193
+ };
24911
25194
  }
24912
25195
  const strapiDefaultLocaleCode = await StrapiI18nService2.getDefaultLocaleCode();
24913
25196
  const localazyLocaleCode = strapiDefaultLocaleCode ? isoStrapiToLocalazy(strapiDefaultLocaleCode) : config.default.LOCALAZY_DEFAULT_LOCALE;
@@ -24928,12 +25211,33 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24928
25211
  await notificationService.emit(EventType.UPLOAD, {
24929
25212
  message: "Uploading collections to Localazy..."
24930
25213
  });
24931
- await LocalazyUploadService2.upload(importFile, uploadConfig);
25214
+ await activityLogsService.addEntry(sessionId, "Uploading collections to Localazy...");
25215
+ try {
25216
+ await LocalazyUploadService2.upload(importFile, uploadConfig);
25217
+ } catch (error) {
25218
+ success = false;
25219
+ const errorMessage = `Upload to Localazy failed: ${error instanceof Error ? error.message : String(error)}`;
25220
+ strapi2.log.error(errorMessage);
25221
+ await notificationService.emit(EventType.UPLOAD_FINISHED, {
25222
+ success,
25223
+ message: errorMessage
25224
+ });
25225
+ await activityLogsService.addEntry(sessionId, errorMessage);
25226
+ await activityLogsService.finishSession(sessionId, "failed", errorMessage);
25227
+ console.timeEnd("upload");
25228
+ return;
25229
+ }
24932
25230
  strapi2.log.info("Upload finished in");
24933
25231
  await notificationService.emit(EventType.UPLOAD_FINISHED, {
24934
25232
  success,
24935
25233
  message: "Upload finished"
24936
25234
  });
25235
+ await activityLogsService.addEntry(sessionId, "Upload finished");
25236
+ await activityLogsService.finishSession(
25237
+ sessionId,
25238
+ success ? "completed" : "failed",
25239
+ success ? "Upload completed successfully" : "Upload finished with errors"
25240
+ );
24937
25241
  console.timeEnd("upload");
24938
25242
  }
24939
25243
  });
@@ -25352,6 +25656,12 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25352
25656
  await notificationService.emit(EventType.DOWNLOAD, {
25353
25657
  message: `Download started (${syncMode})`
25354
25658
  });
25659
+ const activityLogsService = getActivityLogsService();
25660
+ const requestInitiatorHelper = new RequestInitiatorHelper(strapi2);
25661
+ const isWebhook = requestInitiatorHelper.isInitiatedByLocalazyWebhook();
25662
+ const initiatedBy = isWebhook ? "Webhook" : "Strapi User";
25663
+ const sessionId = await activityLogsService.startSession(isWebhook ? "webhook" : "download", initiatedBy);
25664
+ await activityLogsService.addEntry(sessionId, `Download started (${syncMode})`);
25355
25665
  let success = true;
25356
25666
  const StrapiService2 = getStrapiService();
25357
25667
  const StrapiI18nService2 = getStrapiI18nService();
@@ -25370,6 +25680,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25370
25680
  success,
25371
25681
  message
25372
25682
  });
25683
+ await activityLogsService.addEntry(sessionId, message);
25684
+ await activityLogsService.finishSession(sessionId, "failed", message);
25373
25685
  return;
25374
25686
  }
25375
25687
  const project = await LocalazyPubAPIService2.getProject(user.project.id, false, true);
@@ -25381,6 +25693,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25381
25693
  success,
25382
25694
  message
25383
25695
  });
25696
+ await activityLogsService.addEntry(sessionId, message);
25697
+ await activityLogsService.finishSession(sessionId, "failed", message);
25384
25698
  return;
25385
25699
  }
25386
25700
  const projectLanguages = project.languages;
@@ -25394,6 +25708,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25394
25708
  success,
25395
25709
  message
25396
25710
  });
25711
+ await activityLogsService.addEntry(sessionId, message);
25712
+ await activityLogsService.finishSession(sessionId, "failed", message);
25397
25713
  return;
25398
25714
  }
25399
25715
  const projectSourceLanguageCode = sourceLanguage.code;
@@ -25407,6 +25723,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25407
25723
  success,
25408
25724
  message
25409
25725
  });
25726
+ await activityLogsService.addEntry(sessionId, message);
25727
+ await activityLogsService.finishSession(sessionId, "completed", message);
25410
25728
  return;
25411
25729
  }
25412
25730
  let languagesCodes = projectLanguagesWithoutSourceLanguage.map((language3) => language3.code);
@@ -25425,6 +25743,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25425
25743
  await notificationService.emit(EventType.DOWNLOAD, {
25426
25744
  message: `Created locale ${newLocale.code}`
25427
25745
  });
25746
+ await activityLogsService.addEntry(sessionId, `Created locale ${newLocale.code}`);
25428
25747
  } catch (e2) {
25429
25748
  strapi2.log.error(e2.message);
25430
25749
  if (e2.name === "ValidationError") {
@@ -25432,10 +25751,12 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25432
25751
  await notificationService.emit(EventType.DOWNLOAD, {
25433
25752
  message: `Language ${isoLocalazy} is not supported by Strapi`
25434
25753
  });
25754
+ await activityLogsService.addEntry(sessionId, `Language ${isoLocalazy} is not supported by Strapi`);
25435
25755
  } else {
25436
25756
  await notificationService.emit(EventType.DOWNLOAD, {
25437
25757
  message: e2.message
25438
25758
  });
25759
+ await activityLogsService.addEntry(sessionId, e2.message);
25439
25760
  }
25440
25761
  }
25441
25762
  }
@@ -25460,6 +25781,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25460
25781
  await notificationService.emit(EventType.DOWNLOAD, {
25461
25782
  message: `No keys found for language ${isoLocalazy}`
25462
25783
  });
25784
+ await activityLogsService.addEntry(sessionId, `No keys found for language ${isoLocalazy}`);
25463
25785
  } else {
25464
25786
  const newKeys = langKeys.filter((k2) => {
25465
25787
  const storedEvent = langProcessedKeys[k2.id];
@@ -25468,6 +25790,10 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25468
25790
  await notificationService.emit(EventType.DOWNLOAD, {
25469
25791
  message: `${syncMode}: ${newKeys.length} changed / ${langKeys.length} total keys for language ${isoLocalazy}`
25470
25792
  });
25793
+ await activityLogsService.addEntry(
25794
+ sessionId,
25795
+ `${syncMode}: ${newKeys.length} changed / ${langKeys.length} total keys for language ${isoLocalazy}`
25796
+ );
25471
25797
  }
25472
25798
  localazyContent[isoLocalazy] = langKeys;
25473
25799
  }
@@ -25596,9 +25922,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25596
25922
  locDownloadPLevel: 6
25597
25923
  });
25598
25924
  if (isEmpty(baseEntry)) {
25599
- strapi2.log.info(
25600
- `Source language entry ${uid}[${documentId}] does not exist anymore, skipping...`
25601
- );
25925
+ strapi2.log.info(`Source language entry ${uid}[${documentId}] does not exist anymore, skipping...`);
25602
25926
  await markKeysProcessed(sourceKeys);
25603
25927
  continue;
25604
25928
  }
@@ -25610,7 +25934,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25610
25934
  const localazySearchUrl = `${user.project.url}/source-language?search=${uid}[${documentId}]`;
25611
25935
  if (isEmpty(currentLanguageLocalizedEntry)) {
25612
25936
  try {
25613
- const createdEntry = await StrapiLocalazyI18nService2.createEntry(
25937
+ await StrapiLocalazyI18nService2.createEntry(
25614
25938
  uid,
25615
25939
  strapiContentTypesModels,
25616
25940
  translatedModel,
@@ -25622,6 +25946,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25622
25946
  await notificationService.emit(EventType.DOWNLOAD, {
25623
25947
  message
25624
25948
  });
25949
+ await activityLogsService.addEntry(sessionId, message);
25625
25950
  await markKeysProcessed(sourceKeys);
25626
25951
  } catch (e2) {
25627
25952
  success = false;
@@ -25634,11 +25959,15 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25634
25959
  localazy: localazySearchUrl
25635
25960
  }
25636
25961
  });
25962
+ await activityLogsService.addEntry(
25963
+ sessionId,
25964
+ `Failed to create ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25965
+ );
25637
25966
  }
25638
25967
  } else {
25639
25968
  try {
25640
25969
  const localizedDocumentId = currentLanguageLocalizedEntry.documentId;
25641
- const updatedEntry = await StrapiLocalazyI18nService2.updateEntry(
25970
+ await StrapiLocalazyI18nService2.updateEntry(
25642
25971
  uid,
25643
25972
  localizedDocumentId,
25644
25973
  strapiContentTypesModels,
@@ -25651,6 +25980,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25651
25980
  await notificationService.emit(EventType.DOWNLOAD, {
25652
25981
  message
25653
25982
  });
25983
+ await activityLogsService.addEntry(sessionId, message);
25654
25984
  await markKeysProcessed(sourceKeys);
25655
25985
  } catch (e2) {
25656
25986
  success = false;
@@ -25663,6 +25993,10 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25663
25993
  localazy: localazySearchUrl
25664
25994
  }
25665
25995
  });
25996
+ await activityLogsService.addEntry(
25997
+ sessionId,
25998
+ `Failed to update ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25999
+ );
25666
26000
  }
25667
26001
  }
25668
26002
  } catch (e2) {
@@ -25671,11 +26005,18 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25671
26005
  await notificationService.emit(EventType.DOWNLOAD, {
25672
26006
  message: `Error processing ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25673
26007
  });
26008
+ await activityLogsService.addEntry(
26009
+ sessionId,
26010
+ `Error processing ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
26011
+ );
25674
26012
  }
25675
26013
  }
25676
26014
  }
25677
26015
  }
25678
- const totalProcessedKeys = Object.values(processedKeys).reduce((sum, langKeys) => sum + Object.keys(langKeys).length, 0);
26016
+ const totalProcessedKeys = Object.values(processedKeys).reduce(
26017
+ (sum, langKeys) => sum + Object.keys(langKeys).length,
26018
+ 0
26019
+ );
25679
26020
  strapi2.log.info(
25680
26021
  `Download finished. Tracked ${totalProcessedKeys} processed keys across ${Object.keys(processedKeys).length} languages.`
25681
26022
  );
@@ -25683,6 +26024,13 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25683
26024
  success,
25684
26025
  message: "Download finished"
25685
26026
  });
26027
+ const finishMessage = `Download finished. Tracked ${totalProcessedKeys} processed keys across ${Object.keys(processedKeys).length} languages.`;
26028
+ await activityLogsService.addEntry(sessionId, finishMessage);
26029
+ await activityLogsService.finishSession(
26030
+ sessionId,
26031
+ success ? "completed" : "failed",
26032
+ success ? "Download completed successfully" : "Download finished with errors"
26033
+ );
25686
26034
  console.timeEnd("download");
25687
26035
  }
25688
26036
  });
@@ -26406,6 +26754,112 @@ const EntryExclusionService = ({ strapi: strapi2 }) => ({
26406
26754
  return Object.values(exclusions).filter((exclusion) => exclusion.contentType === contentType && exclusion.excludeFromTranslation).map((exclusion) => exclusion.documentId);
26407
26755
  }
26408
26756
  });
26757
+ const KEY = "activity-logs";
26758
+ const emptyActivityLogs = {
26759
+ sessions: []
26760
+ };
26761
+ const ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1e3;
26762
+ let writeLock = Promise.resolve();
26763
+ const withLock = async (fn) => {
26764
+ let release;
26765
+ const next = new Promise((resolve) => {
26766
+ release = resolve;
26767
+ });
26768
+ const prev2 = writeLock;
26769
+ writeLock = next;
26770
+ await prev2;
26771
+ try {
26772
+ return await fn();
26773
+ } finally {
26774
+ release();
26775
+ }
26776
+ };
26777
+ const ActivityLogsService = ({ strapi: strapi2 }) => ({
26778
+ async getActivityLogs() {
26779
+ const pluginStore = getStrapiStore(strapi2);
26780
+ const logs = await pluginStore.get({ key: KEY });
26781
+ return logs || { sessions: [] };
26782
+ },
26783
+ async saveActivityLogs(logs) {
26784
+ const pluginStore = getStrapiStore(strapi2);
26785
+ await pluginStore.set({
26786
+ key: KEY,
26787
+ value: logs
26788
+ });
26789
+ },
26790
+ async startSession(eventType, initiatedBy) {
26791
+ return withLock(async () => {
26792
+ const logs = await this.getActivityLogs();
26793
+ const sessionId = generateRandomId();
26794
+ const session = {
26795
+ id: sessionId,
26796
+ eventType,
26797
+ status: "in-progress",
26798
+ startedAt: Date.now(),
26799
+ initiatedBy,
26800
+ summary: "",
26801
+ entries: []
26802
+ };
26803
+ logs.sessions.unshift(session);
26804
+ const cutoff = Date.now() - ONE_YEAR_MS;
26805
+ logs.sessions = logs.sessions.filter((s2) => s2.startedAt >= cutoff);
26806
+ await this.saveActivityLogs(logs);
26807
+ return sessionId;
26808
+ });
26809
+ },
26810
+ async addEntry(sessionId, message, data) {
26811
+ return withLock(async () => {
26812
+ const logs = await this.getActivityLogs();
26813
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26814
+ if (!session) {
26815
+ return;
26816
+ }
26817
+ const entry = {
26818
+ message,
26819
+ timestamp: Date.now(),
26820
+ data
26821
+ };
26822
+ session.entries.push(entry);
26823
+ await this.saveActivityLogs(logs);
26824
+ });
26825
+ },
26826
+ async finishSession(sessionId, status, summary) {
26827
+ return withLock(async () => {
26828
+ const logs = await this.getActivityLogs();
26829
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26830
+ if (!session) {
26831
+ return;
26832
+ }
26833
+ session.status = status;
26834
+ session.finishedAt = Date.now();
26835
+ session.summary = summary;
26836
+ await this.saveActivityLogs(logs);
26837
+ });
26838
+ },
26839
+ async getSessions(eventType) {
26840
+ const logs = await this.getActivityLogs();
26841
+ let { sessions } = logs;
26842
+ if (eventType) {
26843
+ sessions = sessions.filter((s2) => s2.eventType === eventType);
26844
+ }
26845
+ return sessions.map((s2) => ({
26846
+ ...s2,
26847
+ entries: []
26848
+ }));
26849
+ },
26850
+ async getAllSessionsWithEntries() {
26851
+ const logs = await this.getActivityLogs();
26852
+ return logs.sessions;
26853
+ },
26854
+ async getSession(sessionId) {
26855
+ const logs = await this.getActivityLogs();
26856
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26857
+ return session || null;
26858
+ },
26859
+ async clearSessions() {
26860
+ await this.saveActivityLogs(emptyActivityLogs);
26861
+ }
26862
+ });
26409
26863
  const services = {
26410
26864
  LocalazyUserService,
26411
26865
  StrapiService,
@@ -26416,7 +26870,8 @@ const services = {
26416
26870
  StrapiI18nService,
26417
26871
  LocalazyUploadService,
26418
26872
  StrapiLocalazyI18nService,
26419
- EntryExclusionService
26873
+ EntryExclusionService,
26874
+ ActivityLogsService
26420
26875
  };
26421
26876
  const index = {
26422
26877
  register,