@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
@@ -20519,7 +20519,7 @@ var distExports = dist$1.exports;
20519
20519
  const io = /* @__PURE__ */ getDefaultExportFromCjs(distExports);
20520
20520
  const { Server: Server2, Namespace, Socket: Socket3 } = io;
20521
20521
  const name = "@localazy/strapi-plugin";
20522
- const version = "1.0.11";
20522
+ const version = "1.1.1";
20523
20523
  const description = "The official Strapi Plugin by Localazy.";
20524
20524
  const keywords = [
20525
20525
  "strapi",
@@ -20580,11 +20580,12 @@ const scripts = {
20580
20580
  "test:server": "jest --config server/jest.config.ts",
20581
20581
  "test:server:coverage": "jest --config server/jest.config.ts --coverage",
20582
20582
  "test:server:watch": "jest --config server/jest.config.ts --watch",
20583
- "test:ts:back": "run -T tsc -p server/tsconfig.json",
20584
- "test:ts:front": "run -T tsc -p admin/tsconfig.json",
20583
+ "test:ts:back": "tsc -p server/tsconfig.json --noEmit",
20584
+ "test:ts:front": "tsc -p admin/tsconfig.json --noEmit",
20585
20585
  verify: "strapi-plugin verify",
20586
20586
  watch: "strapi-plugin watch",
20587
- "watch:link": "strapi-plugin watch:link"
20587
+ "watch:link": "strapi-plugin watch:link",
20588
+ prepare: "husky"
20588
20589
  };
20589
20590
  const dependencies = {
20590
20591
  shelljs: "^0.8.5",
@@ -20716,7 +20717,7 @@ const bootstrap = ({ strapi: strapi2 }) => {
20716
20717
  });
20717
20718
  }
20718
20719
  };
20719
- const destroy = ({ strapi: strapi2 }) => {
20720
+ const destroy = ({ strapi: _strapi }) => {
20720
20721
  };
20721
20722
  const isoStrapiToLocalazy = (isoStrapi) => {
20722
20723
  if (!isoStrapi) {
@@ -21874,6 +21875,100 @@ const pickEntries = (flatten, pickPaths) => {
21874
21875
  });
21875
21876
  return pickedEntries;
21876
21877
  };
21878
+ const getCharacterLimitsMetadata = (flattenedContent, modelUid) => {
21879
+ const metadata = {};
21880
+ const model = strapi.contentTypes[modelUid] || strapi.components[modelUid];
21881
+ if (!model) {
21882
+ return metadata;
21883
+ }
21884
+ for (const flatKey of Object.keys(flattenedContent)) {
21885
+ const maxLength = resolveMaxLength(flatKey, modelUid, model);
21886
+ if (maxLength != null) {
21887
+ metadata[`@meta:${flatKey}`] = { limit: maxLength };
21888
+ }
21889
+ }
21890
+ return metadata;
21891
+ };
21892
+ const resolveMaxLength = (flatKey, modelUid, model) => {
21893
+ if (!flatKey.startsWith(`${modelUid}[`)) {
21894
+ return void 0;
21895
+ }
21896
+ const afterUid = flatKey.substring(modelUid.length);
21897
+ const closingBracket = afterUid.indexOf("]");
21898
+ if (closingBracket === -1) {
21899
+ return void 0;
21900
+ }
21901
+ const withoutDocId = afterUid.substring(closingBracket + 2);
21902
+ if (!withoutDocId) {
21903
+ return void 0;
21904
+ }
21905
+ const allParts = withoutDocId.split(".");
21906
+ const fieldPath = parseFieldPath(allParts);
21907
+ if (fieldPath.length === 0) {
21908
+ return void 0;
21909
+ }
21910
+ return walkSchemaForMaxLength(fieldPath, model);
21911
+ };
21912
+ const parseFieldPath = (parts) => {
21913
+ const segments = [];
21914
+ let i2 = 0;
21915
+ while (i2 < parts.length) {
21916
+ const part = parts[i2];
21917
+ const dynamicZoneMatch = part.match(/^([^[]+)\[(\d+);(.+)$/);
21918
+ if (dynamicZoneMatch) {
21919
+ let componentName = dynamicZoneMatch[3];
21920
+ i2++;
21921
+ while (i2 < parts.length && !parts[i2].includes("]")) {
21922
+ componentName += "." + parts[i2];
21923
+ i2++;
21924
+ }
21925
+ if (i2 < parts.length && parts[i2].includes("]")) {
21926
+ componentName += "." + parts[i2].replace("]", "");
21927
+ i2++;
21928
+ }
21929
+ segments.push({ name: dynamicZoneMatch[1], dynamicZoneComponent: componentName });
21930
+ continue;
21931
+ }
21932
+ const bracketMatch = part.match(/^([^[]+)\[/);
21933
+ if (bracketMatch) {
21934
+ segments.push({ name: bracketMatch[1] });
21935
+ i2++;
21936
+ continue;
21937
+ }
21938
+ segments.push({ name: part });
21939
+ i2++;
21940
+ }
21941
+ return segments;
21942
+ };
21943
+ const walkSchemaForMaxLength = (fieldPath, model) => {
21944
+ let currentModel = model;
21945
+ for (let i2 = 0; i2 < fieldPath.length; i2++) {
21946
+ const segment = fieldPath[i2];
21947
+ const attribute = currentModel?.attributes?.[segment.name];
21948
+ if (!attribute) {
21949
+ return void 0;
21950
+ }
21951
+ if (i2 === fieldPath.length - 1) {
21952
+ return attribute.maxLength;
21953
+ }
21954
+ if (attribute.type === "component" && attribute.component) {
21955
+ currentModel = strapi.components[attribute.component];
21956
+ if (!currentModel) {
21957
+ return void 0;
21958
+ }
21959
+ continue;
21960
+ }
21961
+ if (attribute.type === "dynamiczone" && segment.dynamicZoneComponent) {
21962
+ currentModel = strapi.components[segment.dynamicZoneComponent];
21963
+ if (!currentModel) {
21964
+ return void 0;
21965
+ }
21966
+ continue;
21967
+ }
21968
+ return void 0;
21969
+ }
21970
+ return void 0;
21971
+ };
21877
21972
  const getMainKeysOfNestedArrayObjects = (array) => {
21878
21973
  return array.map((item) => Reflect.ownKeys(item)[0]);
21879
21974
  };
@@ -21968,6 +22063,9 @@ const getLocalazyUploadService = () => {
21968
22063
  const getEntryExclusionService = () => {
21969
22064
  return strapi.plugin(PLUGIN_NAME).service("EntryExclusionService");
21970
22065
  };
22066
+ const getActivityLogsService = () => {
22067
+ return strapi.plugin(PLUGIN_NAME).service("ActivityLogsService");
22068
+ };
21971
22069
  class PluginSettingsServiceHelper {
21972
22070
  constructor() {
21973
22071
  this.PluginSettingsService = getPluginSettingsService();
@@ -22146,8 +22244,13 @@ const getPickedFlattenKeysForHookEntry = async (params) => {
22146
22244
  };
22147
22245
  }
22148
22246
  const pickedFlatten = pickEntries(flatten, pickPathsWithUid);
22247
+ const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlatten, modelUid);
22248
+ const pickedFlattenWithMetadata = {
22249
+ ...pickedFlatten,
22250
+ ...characterLimitsMetadata
22251
+ };
22149
22252
  return {
22150
- pickedFlatten,
22253
+ pickedFlatten: pickedFlattenWithMetadata,
22151
22254
  eventEntryLocale,
22152
22255
  projectSourceLanguageCode
22153
22256
  };
@@ -23969,7 +24072,7 @@ const register = ({ strapi: strapi2 }) => {
23969
24072
  });
23970
24073
  };
23971
24074
  const contentTypes = {};
23972
- const LocalazyUserController = ({ strapi: strapi2 }) => ({
24075
+ const LocalazyUserController = ({ strapi: _strapi }) => ({
23973
24076
  async getUser(ctx) {
23974
24077
  ctx.body = await getLocalazyUserService().getUser();
23975
24078
  },
@@ -24067,7 +24170,7 @@ const LocalazyGenericConnectorClientFactory = async () => {
24067
24170
  });
24068
24171
  return api;
24069
24172
  };
24070
- const LocalazyAuthController = ({ strapi: strapi2 }) => ({
24173
+ const LocalazyAuthController = ({ strapi: _strapi }) => ({
24071
24174
  async generateKeys(ctx) {
24072
24175
  const GenericConnectorApi = await LocalazyGenericConnectorClientFactory();
24073
24176
  ctx.body = await GenericConnectorApi.public.keys();
@@ -24094,10 +24197,12 @@ const StrapiController = ({ strapi: strapi2 }) => ({
24094
24197
  },
24095
24198
  async getPluginVersion(ctx) {
24096
24199
  ctx.body = {
24097
- version: await getStrapiService().getPluginVersion()
24200
+ version: await getStrapiService().getPluginVersion(),
24201
+ versionStrapi: getStrapiService().getStrapiVersion()
24098
24202
  };
24099
24203
  }
24100
24204
  });
24205
+ const STRAPI_WEBHOOK_CUSTOM_ID = "strapi-plugin-localazy";
24101
24206
  const LocalazyProjectController = ({ strapi: strapi2 }) => ({
24102
24207
  async getConnectedProject(ctx) {
24103
24208
  const LocalazyUserService2 = getLocalazyUserService();
@@ -24105,9 +24210,69 @@ const LocalazyProjectController = ({ strapi: strapi2 }) => ({
24105
24210
  const user = await LocalazyUserService2.getUser();
24106
24211
  const project = await LocalazyPubAPIService2.getProject(user.project.id, true, true);
24107
24212
  ctx.body = project;
24213
+ },
24214
+ async getWebhookStatus(ctx) {
24215
+ const LocalazyUserService2 = getLocalazyUserService();
24216
+ const user = await LocalazyUserService2.getUser();
24217
+ const LocalazyPubApiService = getLocalazyPubAPIService();
24218
+ const webhooks = await LocalazyPubApiService.listWebhooks(user.project.id);
24219
+ const ours = webhooks.find((w2) => w2.customId === STRAPI_WEBHOOK_CUSTOM_ID);
24220
+ if (ours) {
24221
+ ctx.body = { status: "configured", url: ours.url, enabled: ours.enabled };
24222
+ return;
24223
+ }
24224
+ ctx.body = { status: "not_configured" };
24225
+ },
24226
+ async setupWebhook(ctx) {
24227
+ const { url: url2 } = ctx.request.body;
24228
+ if (!url2 || typeof url2 !== "string") {
24229
+ return ctx.badRequest("Webhook URL is required");
24230
+ }
24231
+ try {
24232
+ const parsed = new URL(url2);
24233
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
24234
+ return ctx.badRequest("Webhook URL must use http or https protocol");
24235
+ }
24236
+ } catch {
24237
+ return ctx.badRequest("Invalid webhook URL");
24238
+ }
24239
+ const LocalazyUserService2 = getLocalazyUserService();
24240
+ const user = await LocalazyUserService2.getUser();
24241
+ const LocalazyPubApiService = getLocalazyPubAPIService();
24242
+ const PluginSettingsService2 = getPluginSettingsService();
24243
+ const existing = await LocalazyPubApiService.listWebhooks(user.project.id);
24244
+ const filtered = existing.filter((w2) => w2.customId !== STRAPI_WEBHOOK_CUSTOM_ID);
24245
+ const items = [
24246
+ ...filtered,
24247
+ {
24248
+ enabled: true,
24249
+ customId: STRAPI_WEBHOOK_CUSTOM_ID,
24250
+ url: url2,
24251
+ events: ["project_published"],
24252
+ description: "Strapi Plugin - Download translations"
24253
+ }
24254
+ ];
24255
+ await LocalazyPubApiService.updateWebhooks(user.project.id, items);
24256
+ await PluginSettingsService2.updatePluginSettings({
24257
+ webhookConfig: { url: url2 }
24258
+ });
24259
+ ctx.body = { success: true };
24260
+ },
24261
+ async getStrapiUrl(ctx) {
24262
+ let url2 = strapi2.config.get("server.url");
24263
+ if (!url2) {
24264
+ const host = strapi2.config.get("server.host") || "0.0.0.0";
24265
+ const port = strapi2.config.get("server.port") || 1337;
24266
+ const displayHost = host === "0.0.0.0" || host === "::" ? "localhost" : host;
24267
+ url2 = `http://${displayHost}:${port}`;
24268
+ }
24269
+ const isLocal = /^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(
24270
+ url2
24271
+ );
24272
+ ctx.body = { url: url2, isLocal };
24108
24273
  }
24109
24274
  });
24110
- const PluginSettingsController = ({ strapi: strapi2 }) => ({
24275
+ const PluginSettingsController = ({ strapi: _strapi }) => ({
24111
24276
  async getContentTransferSetup(ctx) {
24112
24277
  ctx.body = await getPluginSettingsService().getContentTransferSetup();
24113
24278
  },
@@ -24302,6 +24467,27 @@ const EntryExclusionController = ({ strapi: strapi2 }) => ({
24302
24467
  }
24303
24468
  }
24304
24469
  });
24470
+ const ActivityLogsController = ({ strapi: _strapi }) => ({
24471
+ async getSessions(ctx) {
24472
+ const { type: type2 } = ctx.query;
24473
+ ctx.body = await getActivityLogsService().getSessions(type2);
24474
+ },
24475
+ async getSession(ctx) {
24476
+ const { sessionId } = ctx.params;
24477
+ const session = await getActivityLogsService().getSession(sessionId);
24478
+ if (!session) {
24479
+ return ctx.notFound("Session not found");
24480
+ }
24481
+ ctx.body = session;
24482
+ },
24483
+ async exportSessions(ctx) {
24484
+ ctx.body = await getActivityLogsService().getAllSessionsWithEntries();
24485
+ },
24486
+ async clearSessions(ctx) {
24487
+ await getActivityLogsService().clearSessions();
24488
+ ctx.body = { success: true };
24489
+ }
24490
+ });
24305
24491
  const controllers = {
24306
24492
  LocalazyUserController,
24307
24493
  LocalazyAuthController,
@@ -24309,7 +24495,8 @@ const controllers = {
24309
24495
  LocalazyProjectController,
24310
24496
  PluginSettingsController,
24311
24497
  LocalazyTransferController,
24312
- EntryExclusionController
24498
+ EntryExclusionController,
24499
+ ActivityLogsController
24313
24500
  };
24314
24501
  const verifyWebhook = (config2, { strapi: strapi2 }) => {
24315
24502
  return async (ctx, next) => {
@@ -24366,11 +24553,11 @@ const middlewares = {
24366
24553
  verifyWebhook
24367
24554
  };
24368
24555
  const policies = {};
24369
- const ROUTE_PREFIX$7 = "/user";
24556
+ const ROUTE_PREFIX$8 = "/user";
24370
24557
  const LocalazyUserRoutes = [
24371
24558
  {
24372
24559
  method: "GET",
24373
- path: `${ROUTE_PREFIX$7}`,
24560
+ path: `${ROUTE_PREFIX$8}`,
24374
24561
  handler: "LocalazyUserController.getUser",
24375
24562
  config: {
24376
24563
  policies: []
@@ -24378,7 +24565,7 @@ const LocalazyUserRoutes = [
24378
24565
  },
24379
24566
  {
24380
24567
  method: "PUT",
24381
- path: `${ROUTE_PREFIX$7}`,
24568
+ path: `${ROUTE_PREFIX$8}`,
24382
24569
  handler: "LocalazyUserController.updateUser",
24383
24570
  config: {
24384
24571
  policies: []
@@ -24386,18 +24573,18 @@ const LocalazyUserRoutes = [
24386
24573
  },
24387
24574
  {
24388
24575
  method: "DELETE",
24389
- path: `${ROUTE_PREFIX$7}`,
24576
+ path: `${ROUTE_PREFIX$8}`,
24390
24577
  handler: "LocalazyUserController.deleteUser",
24391
24578
  config: {
24392
24579
  policies: []
24393
24580
  }
24394
24581
  }
24395
24582
  ];
24396
- const ROUTE_PREFIX$6 = "/auth";
24583
+ const ROUTE_PREFIX$7 = "/auth";
24397
24584
  const LocalazyAuthRoutes = [
24398
24585
  {
24399
24586
  method: "GET",
24400
- path: `${ROUTE_PREFIX$6}/generate-keys`,
24587
+ path: `${ROUTE_PREFIX$7}/generate-keys`,
24401
24588
  handler: "LocalazyAuthController.generateKeys",
24402
24589
  config: {
24403
24590
  policies: []
@@ -24405,18 +24592,18 @@ const LocalazyAuthRoutes = [
24405
24592
  },
24406
24593
  {
24407
24594
  method: "GET",
24408
- path: `${ROUTE_PREFIX$6}/continuous-poll`,
24595
+ path: `${ROUTE_PREFIX$7}/continuous-poll`,
24409
24596
  handler: "LocalazyAuthController.continuousPoll",
24410
24597
  config: {
24411
24598
  policies: []
24412
24599
  }
24413
24600
  }
24414
24601
  ];
24415
- const ROUTE_PREFIX$5 = "/plugin-settings";
24602
+ const ROUTE_PREFIX$6 = "/plugin-settings";
24416
24603
  const PluginSettingsRoutes = [
24417
24604
  {
24418
24605
  method: "GET",
24419
- path: `${ROUTE_PREFIX$5}/content-transfer-setup`,
24606
+ path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
24420
24607
  handler: "PluginSettingsController.getContentTransferSetup",
24421
24608
  config: {
24422
24609
  policies: []
@@ -24424,7 +24611,7 @@ const PluginSettingsRoutes = [
24424
24611
  },
24425
24612
  {
24426
24613
  method: "PUT",
24427
- path: `${ROUTE_PREFIX$5}/content-transfer-setup`,
24614
+ path: `${ROUTE_PREFIX$6}/content-transfer-setup`,
24428
24615
  handler: "PluginSettingsController.updateContentTransferSetup",
24429
24616
  config: {
24430
24617
  policies: []
@@ -24432,7 +24619,7 @@ const PluginSettingsRoutes = [
24432
24619
  },
24433
24620
  {
24434
24621
  method: "GET",
24435
- path: `${ROUTE_PREFIX$5}/plugin-settings`,
24622
+ path: `${ROUTE_PREFIX$6}/plugin-settings`,
24436
24623
  handler: "PluginSettingsController.getPluginSettings",
24437
24624
  config: {
24438
24625
  policies: []
@@ -24440,7 +24627,7 @@ const PluginSettingsRoutes = [
24440
24627
  },
24441
24628
  {
24442
24629
  method: "PUT",
24443
- path: `${ROUTE_PREFIX$5}/plugin-settings`,
24630
+ path: `${ROUTE_PREFIX$6}/plugin-settings`,
24444
24631
  handler: "PluginSettingsController.updatePluginSettings",
24445
24632
  config: {
24446
24633
  policies: []
@@ -24448,18 +24635,18 @@ const PluginSettingsRoutes = [
24448
24635
  },
24449
24636
  {
24450
24637
  method: "GET",
24451
- path: `${ROUTE_PREFIX$5}/sync-cursor`,
24638
+ path: `${ROUTE_PREFIX$6}/sync-cursor`,
24452
24639
  handler: "PluginSettingsController.getSyncCursor",
24453
24640
  config: {
24454
24641
  policies: []
24455
24642
  }
24456
24643
  }
24457
24644
  ];
24458
- const ROUTE_PREFIX$4 = "/strapi";
24645
+ const ROUTE_PREFIX$5 = "/strapi";
24459
24646
  const StrapiRoutes = [
24460
24647
  {
24461
24648
  method: "GET",
24462
- path: `${ROUTE_PREFIX$4}/models`,
24649
+ path: `${ROUTE_PREFIX$5}/models`,
24463
24650
  handler: "StrapiController.getModels",
24464
24651
  config: {
24465
24652
  policies: []
@@ -24467,7 +24654,7 @@ const StrapiRoutes = [
24467
24654
  },
24468
24655
  {
24469
24656
  method: "GET",
24470
- path: `${ROUTE_PREFIX$4}/localizable-models`,
24657
+ path: `${ROUTE_PREFIX$5}/localizable-models`,
24471
24658
  handler: "StrapiController.getLocalizableModels",
24472
24659
  config: {
24473
24660
  policies: []
@@ -24475,7 +24662,7 @@ const StrapiRoutes = [
24475
24662
  },
24476
24663
  {
24477
24664
  method: "POST",
24478
- path: `${ROUTE_PREFIX$4}/lifecycle/localazy-webhooks`,
24665
+ path: `${ROUTE_PREFIX$5}/lifecycle/localazy-webhooks`,
24479
24666
  handler: "StrapiController.postLifecycleLocalazyWebhooks",
24480
24667
  config: {
24481
24668
  policies: []
@@ -24483,18 +24670,18 @@ const StrapiRoutes = [
24483
24670
  },
24484
24671
  {
24485
24672
  method: "GET",
24486
- path: `${ROUTE_PREFIX$4}/version`,
24673
+ path: `${ROUTE_PREFIX$5}/version`,
24487
24674
  handler: "StrapiController.getPluginVersion",
24488
24675
  config: {
24489
24676
  policies: []
24490
24677
  }
24491
24678
  }
24492
24679
  ];
24493
- const ROUTE_PREFIX$3 = "/transfer";
24680
+ const ROUTE_PREFIX$4 = "/transfer";
24494
24681
  const LocalazyTransferRoutes = [
24495
24682
  {
24496
24683
  method: "POST",
24497
- path: `${ROUTE_PREFIX$3}/upload`,
24684
+ path: `${ROUTE_PREFIX$4}/upload`,
24498
24685
  handler: "LocalazyTransferController.upload",
24499
24686
  config: {
24500
24687
  policies: []
@@ -24502,29 +24689,53 @@ const LocalazyTransferRoutes = [
24502
24689
  },
24503
24690
  {
24504
24691
  method: "POST",
24505
- path: `${ROUTE_PREFIX$3}/download`,
24692
+ path: `${ROUTE_PREFIX$4}/download`,
24506
24693
  handler: "LocalazyTransferController.download",
24507
24694
  config: {
24508
24695
  policies: []
24509
24696
  }
24510
24697
  }
24511
24698
  ];
24512
- const ROUTE_PREFIX$2 = "/project";
24699
+ const ROUTE_PREFIX$3 = "/project";
24513
24700
  const LocalazyProjectRoutes = [
24514
24701
  {
24515
24702
  method: "GET",
24516
- path: `${ROUTE_PREFIX$2}`,
24703
+ path: `${ROUTE_PREFIX$3}`,
24517
24704
  handler: "LocalazyProjectController.getConnectedProject",
24518
24705
  config: {
24519
24706
  policies: []
24520
24707
  }
24708
+ },
24709
+ {
24710
+ method: "GET",
24711
+ path: `${ROUTE_PREFIX$3}/webhooks`,
24712
+ handler: "LocalazyProjectController.getWebhookStatus",
24713
+ config: {
24714
+ policies: []
24715
+ }
24716
+ },
24717
+ {
24718
+ method: "POST",
24719
+ path: `${ROUTE_PREFIX$3}/webhooks/setup`,
24720
+ handler: "LocalazyProjectController.setupWebhook",
24721
+ config: {
24722
+ policies: []
24723
+ }
24724
+ },
24725
+ {
24726
+ method: "GET",
24727
+ path: `${ROUTE_PREFIX$3}/strapi-url`,
24728
+ handler: "LocalazyProjectController.getStrapiUrl",
24729
+ config: {
24730
+ policies: []
24731
+ }
24521
24732
  }
24522
24733
  ];
24523
- const ROUTE_PREFIX$1 = "/public/transfer";
24734
+ const ROUTE_PREFIX$2 = "/public/transfer";
24524
24735
  const LocalazyPublicTransferRoutes = [
24525
24736
  {
24526
24737
  method: "POST",
24527
- path: `${ROUTE_PREFIX$1}/download`,
24738
+ path: `${ROUTE_PREFIX$2}/download`,
24528
24739
  handler: "LocalazyTransferController.download",
24529
24740
  config: {
24530
24741
  policies: [],
@@ -24534,11 +24745,11 @@ const LocalazyPublicTransferRoutes = [
24534
24745
  }
24535
24746
  }
24536
24747
  ];
24537
- const ROUTE_PREFIX = "/entry-exclusion";
24748
+ const ROUTE_PREFIX$1 = "/entry-exclusion";
24538
24749
  const EntryExclusionRoutes = [
24539
24750
  {
24540
24751
  method: "GET",
24541
- path: `${ROUTE_PREFIX}/:contentType/:documentId`,
24752
+ path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
24542
24753
  handler: "EntryExclusionController.getEntryExclusion",
24543
24754
  config: {
24544
24755
  policies: []
@@ -24546,7 +24757,7 @@ const EntryExclusionRoutes = [
24546
24757
  },
24547
24758
  {
24548
24759
  method: "PUT",
24549
- path: `${ROUTE_PREFIX}/:contentType/:documentId`,
24760
+ path: `${ROUTE_PREFIX$1}/:contentType/:documentId`,
24550
24761
  handler: "EntryExclusionController.setEntryExclusion",
24551
24762
  config: {
24552
24763
  policies: []
@@ -24554,13 +24765,48 @@ const EntryExclusionRoutes = [
24554
24765
  },
24555
24766
  {
24556
24767
  method: "GET",
24557
- path: `${ROUTE_PREFIX}/:contentType`,
24768
+ path: `${ROUTE_PREFIX$1}/:contentType`,
24558
24769
  handler: "EntryExclusionController.getContentTypeExclusions",
24559
24770
  config: {
24560
24771
  policies: []
24561
24772
  }
24562
24773
  }
24563
24774
  ];
24775
+ const ROUTE_PREFIX = "/activity-logs";
24776
+ const ActivityLogsRoutes = [
24777
+ {
24778
+ method: "GET",
24779
+ path: `${ROUTE_PREFIX}`,
24780
+ handler: "ActivityLogsController.getSessions",
24781
+ config: {
24782
+ policies: []
24783
+ }
24784
+ },
24785
+ {
24786
+ method: "GET",
24787
+ path: `${ROUTE_PREFIX}/export`,
24788
+ handler: "ActivityLogsController.exportSessions",
24789
+ config: {
24790
+ policies: []
24791
+ }
24792
+ },
24793
+ {
24794
+ method: "GET",
24795
+ path: `${ROUTE_PREFIX}/:sessionId`,
24796
+ handler: "ActivityLogsController.getSession",
24797
+ config: {
24798
+ policies: []
24799
+ }
24800
+ },
24801
+ {
24802
+ method: "DELETE",
24803
+ path: `${ROUTE_PREFIX}`,
24804
+ handler: "ActivityLogsController.clearSessions",
24805
+ config: {
24806
+ policies: []
24807
+ }
24808
+ }
24809
+ ];
24564
24810
  const routes = {
24565
24811
  "content-api": {
24566
24812
  routes: [...StrapiRoutes]
@@ -24574,14 +24820,15 @@ const routes = {
24574
24820
  ...StrapiRoutes,
24575
24821
  ...LocalazyTransferRoutes,
24576
24822
  ...LocalazyProjectRoutes,
24577
- ...EntryExclusionRoutes
24823
+ ...EntryExclusionRoutes,
24824
+ ...ActivityLogsRoutes
24578
24825
  ]
24579
24826
  },
24580
24827
  LocalazyPublicTransferRoutes: {
24581
24828
  routes: [...LocalazyPublicTransferRoutes]
24582
24829
  }
24583
24830
  };
24584
- const KEY$3 = "identity";
24831
+ const KEY$4 = "identity";
24585
24832
  const emptyIdentity = {
24586
24833
  accessToken: "",
24587
24834
  project: {
@@ -24605,13 +24852,13 @@ const getStrapiStore = (strapi2) => strapi2.store({
24605
24852
  const LocalazyUserService = ({ strapi: strapi2 }) => ({
24606
24853
  async getUser() {
24607
24854
  const pluginStore = getStrapiStore(strapi2);
24608
- const user = await pluginStore.get({ key: KEY$3 });
24855
+ const user = await pluginStore.get({ key: KEY$4 });
24609
24856
  return user || emptyIdentity;
24610
24857
  },
24611
24858
  async updateUser(identity2) {
24612
24859
  const pluginStore = getStrapiStore(strapi2);
24613
24860
  await pluginStore.set({
24614
- key: KEY$3,
24861
+ key: KEY$4,
24615
24862
  value: identity2
24616
24863
  });
24617
24864
  return identity2;
@@ -24685,6 +24932,9 @@ const StrapiService = ({ strapi: strapi2 }) => ({
24685
24932
  },
24686
24933
  async getPluginVersion() {
24687
24934
  return await Promise.resolve().then(() => _package$1).then((module2) => module2.version);
24935
+ },
24936
+ getStrapiVersion() {
24937
+ return strapi2.config.get("info.strapi");
24688
24938
  }
24689
24939
  });
24690
24940
  const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
@@ -24727,6 +24977,25 @@ const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
24727
24977
  return null;
24728
24978
  }
24729
24979
  },
24980
+ async listWebhooks(projectId) {
24981
+ try {
24982
+ const LocalazyApi = await LocalazyApiClientFactory();
24983
+ const result = await LocalazyApi.webhooks.list({ project: projectId });
24984
+ return result;
24985
+ } catch (e2) {
24986
+ strapi2.log.error(e2);
24987
+ return [];
24988
+ }
24989
+ },
24990
+ async updateWebhooks(projectId, items) {
24991
+ try {
24992
+ const LocalazyApi = await LocalazyApiClientFactory();
24993
+ await LocalazyApi.webhooks.update({ project: projectId, items });
24994
+ } catch (e2) {
24995
+ strapi2.log.error(e2);
24996
+ throw e2;
24997
+ }
24998
+ },
24730
24999
  async getWebhooksSecret(projectId) {
24731
25000
  try {
24732
25001
  const LocalazyApi = await LocalazyApiClientFactory();
@@ -24738,23 +25007,23 @@ const LocalazyPubAPIService = ({ strapi: strapi2 }) => ({
24738
25007
  }
24739
25008
  }
24740
25009
  });
24741
- const KEY$2 = "content-transfer-setup";
25010
+ const KEY$3 = "content-transfer-setup";
24742
25011
  const emptyContentTransferSetup = {
24743
25012
  has_setup: false,
24744
25013
  setup: []
24745
25014
  };
24746
- const KEY$1 = "plugin-settings";
25015
+ const KEY$2 = "plugin-settings";
24747
25016
  const emptyPluginSettings = {
24748
25017
  defaultRoute: null
24749
25018
  };
24750
- const KEY = "sync-cursor";
25019
+ const KEY$1 = "sync-cursor";
24751
25020
  const emptySyncCursor = {
24752
25021
  processedKeys: {}
24753
25022
  };
24754
25023
  const PluginSettingsService = ({ strapi: strapi2 }) => ({
24755
25024
  async getContentTransferSetup() {
24756
25025
  const pluginStore = getStrapiStore(strapi2);
24757
- const setup2 = await pluginStore.get({ key: KEY$2 });
25026
+ const setup2 = await pluginStore.get({ key: KEY$3 });
24758
25027
  return setup2 || emptyContentTransferSetup;
24759
25028
  },
24760
25029
  async updateContentTransferSetup(setup2) {
@@ -24764,14 +25033,14 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
24764
25033
  };
24765
25034
  const pluginStore = getStrapiStore(strapi2);
24766
25035
  await pluginStore.set({
24767
- key: KEY$2,
25036
+ key: KEY$3,
24768
25037
  value: newSetup
24769
25038
  });
24770
25039
  return newSetup;
24771
25040
  },
24772
25041
  async getPluginSettings() {
24773
25042
  const pluginStore = getStrapiStore(strapi2);
24774
- const settings = await pluginStore.get({ key: KEY$1 });
25043
+ const settings = await pluginStore.get({ key: KEY$2 });
24775
25044
  return settings || emptyPluginSettings;
24776
25045
  },
24777
25046
  async updatePluginSettings(settings) {
@@ -24782,20 +25051,20 @@ const PluginSettingsService = ({ strapi: strapi2 }) => ({
24782
25051
  };
24783
25052
  const pluginStore = getStrapiStore(strapi2);
24784
25053
  await pluginStore.set({
24785
- key: KEY$1,
25054
+ key: KEY$2,
24786
25055
  value: newSettings
24787
25056
  });
24788
25057
  return newSettings;
24789
25058
  },
24790
25059
  async getSyncCursor() {
24791
25060
  const pluginStore = getStrapiStore(strapi2);
24792
- const cursor = await pluginStore.get({ key: KEY });
25061
+ const cursor = await pluginStore.get({ key: KEY$1 });
24793
25062
  return cursor || emptySyncCursor;
24794
25063
  },
24795
25064
  async updateSyncCursor(cursor) {
24796
25065
  const pluginStore = getStrapiStore(strapi2);
24797
25066
  await pluginStore.set({
24798
- key: KEY,
25067
+ key: KEY$1,
24799
25068
  value: cursor
24800
25069
  });
24801
25070
  return cursor;
@@ -24807,6 +25076,9 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24807
25076
  await notificationService.emit(EventType.UPLOAD, {
24808
25077
  message: "Upload started"
24809
25078
  });
25079
+ const activityLogsService = getActivityLogsService();
25080
+ const sessionId = await activityLogsService.startSession("upload", "Strapi User");
25081
+ await activityLogsService.addEntry(sessionId, "Upload started");
24810
25082
  let success = true;
24811
25083
  const StrapiService2 = getStrapiService();
24812
25084
  const StrapiI18nService2 = getStrapiI18nService();
@@ -24820,6 +25092,8 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24820
25092
  success,
24821
25093
  message
24822
25094
  });
25095
+ await activityLogsService.addEntry(sessionId, message);
25096
+ await activityLogsService.finishSession(sessionId, "failed", message);
24823
25097
  strapi2.log.info(message);
24824
25098
  return;
24825
25099
  }
@@ -24840,6 +25114,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24840
25114
  await notificationService.emit(EventType.UPLOAD, {
24841
25115
  message: message2
24842
25116
  });
25117
+ await activityLogsService.addEntry(sessionId, message2);
24843
25118
  strapi2.log.info(message2);
24844
25119
  continue;
24845
25120
  }
@@ -24850,6 +25125,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24850
25125
  await notificationService.emit(EventType.UPLOAD, {
24851
25126
  message: message2
24852
25127
  });
25128
+ await activityLogsService.addEntry(sessionId, message2);
24853
25129
  strapi2.log.warn(message2);
24854
25130
  continue;
24855
25131
  }
@@ -24876,6 +25152,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24876
25152
  await notificationService.emit(EventType.UPLOAD, {
24877
25153
  message: message2
24878
25154
  });
25155
+ await activityLogsService.addEntry(sessionId, message2);
24879
25156
  strapi2.log.info(message2);
24880
25157
  continue;
24881
25158
  }
@@ -24883,6 +25160,7 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24883
25160
  await notificationService.emit(EventType.UPLOAD, {
24884
25161
  message
24885
25162
  });
25163
+ await activityLogsService.addEntry(sessionId, message);
24886
25164
  strapi2.log.info(message);
24887
25165
  entries = omitDeep(entries, ["locale", "createdAt", "updatedAt", "publishedAt"]);
24888
25166
  entries.forEach((entry) => {
@@ -24895,6 +25173,11 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24895
25173
  ...pickedFlatten
24896
25174
  };
24897
25175
  });
25176
+ const characterLimitsMetadata = getCharacterLimitsMetadata(pickedFlattenStrapiContent, modelUid);
25177
+ pickedFlattenStrapiContent = {
25178
+ ...pickedFlattenStrapiContent,
25179
+ ...characterLimitsMetadata
25180
+ };
24898
25181
  }
24899
25182
  const strapiDefaultLocaleCode = await StrapiI18nService2.getDefaultLocaleCode();
24900
25183
  const localazyLocaleCode = strapiDefaultLocaleCode ? isoStrapiToLocalazy(strapiDefaultLocaleCode) : config.default.LOCALAZY_DEFAULT_LOCALE;
@@ -24915,12 +25198,33 @@ const LocalazyTransferUploadService = ({ strapi: strapi2 }) => ({
24915
25198
  await notificationService.emit(EventType.UPLOAD, {
24916
25199
  message: "Uploading collections to Localazy..."
24917
25200
  });
24918
- await LocalazyUploadService2.upload(importFile, uploadConfig);
25201
+ await activityLogsService.addEntry(sessionId, "Uploading collections to Localazy...");
25202
+ try {
25203
+ await LocalazyUploadService2.upload(importFile, uploadConfig);
25204
+ } catch (error) {
25205
+ success = false;
25206
+ const errorMessage = `Upload to Localazy failed: ${error instanceof Error ? error.message : String(error)}`;
25207
+ strapi2.log.error(errorMessage);
25208
+ await notificationService.emit(EventType.UPLOAD_FINISHED, {
25209
+ success,
25210
+ message: errorMessage
25211
+ });
25212
+ await activityLogsService.addEntry(sessionId, errorMessage);
25213
+ await activityLogsService.finishSession(sessionId, "failed", errorMessage);
25214
+ console.timeEnd("upload");
25215
+ return;
25216
+ }
24919
25217
  strapi2.log.info("Upload finished in");
24920
25218
  await notificationService.emit(EventType.UPLOAD_FINISHED, {
24921
25219
  success,
24922
25220
  message: "Upload finished"
24923
25221
  });
25222
+ await activityLogsService.addEntry(sessionId, "Upload finished");
25223
+ await activityLogsService.finishSession(
25224
+ sessionId,
25225
+ success ? "completed" : "failed",
25226
+ success ? "Upload completed successfully" : "Upload finished with errors"
25227
+ );
24924
25228
  console.timeEnd("upload");
24925
25229
  }
24926
25230
  });
@@ -25339,6 +25643,12 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25339
25643
  await notificationService.emit(EventType.DOWNLOAD, {
25340
25644
  message: `Download started (${syncMode})`
25341
25645
  });
25646
+ const activityLogsService = getActivityLogsService();
25647
+ const requestInitiatorHelper = new RequestInitiatorHelper(strapi2);
25648
+ const isWebhook = requestInitiatorHelper.isInitiatedByLocalazyWebhook();
25649
+ const initiatedBy = isWebhook ? "Webhook" : "Strapi User";
25650
+ const sessionId = await activityLogsService.startSession(isWebhook ? "webhook" : "download", initiatedBy);
25651
+ await activityLogsService.addEntry(sessionId, `Download started (${syncMode})`);
25342
25652
  let success = true;
25343
25653
  const StrapiService2 = getStrapiService();
25344
25654
  const StrapiI18nService2 = getStrapiI18nService();
@@ -25357,6 +25667,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25357
25667
  success,
25358
25668
  message
25359
25669
  });
25670
+ await activityLogsService.addEntry(sessionId, message);
25671
+ await activityLogsService.finishSession(sessionId, "failed", message);
25360
25672
  return;
25361
25673
  }
25362
25674
  const project = await LocalazyPubAPIService2.getProject(user.project.id, false, true);
@@ -25368,6 +25680,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25368
25680
  success,
25369
25681
  message
25370
25682
  });
25683
+ await activityLogsService.addEntry(sessionId, message);
25684
+ await activityLogsService.finishSession(sessionId, "failed", message);
25371
25685
  return;
25372
25686
  }
25373
25687
  const projectLanguages = project.languages;
@@ -25381,6 +25695,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25381
25695
  success,
25382
25696
  message
25383
25697
  });
25698
+ await activityLogsService.addEntry(sessionId, message);
25699
+ await activityLogsService.finishSession(sessionId, "failed", message);
25384
25700
  return;
25385
25701
  }
25386
25702
  const projectSourceLanguageCode = sourceLanguage.code;
@@ -25394,6 +25710,8 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25394
25710
  success,
25395
25711
  message
25396
25712
  });
25713
+ await activityLogsService.addEntry(sessionId, message);
25714
+ await activityLogsService.finishSession(sessionId, "completed", message);
25397
25715
  return;
25398
25716
  }
25399
25717
  let languagesCodes = projectLanguagesWithoutSourceLanguage.map((language3) => language3.code);
@@ -25412,6 +25730,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25412
25730
  await notificationService.emit(EventType.DOWNLOAD, {
25413
25731
  message: `Created locale ${newLocale.code}`
25414
25732
  });
25733
+ await activityLogsService.addEntry(sessionId, `Created locale ${newLocale.code}`);
25415
25734
  } catch (e2) {
25416
25735
  strapi2.log.error(e2.message);
25417
25736
  if (e2.name === "ValidationError") {
@@ -25419,10 +25738,12 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25419
25738
  await notificationService.emit(EventType.DOWNLOAD, {
25420
25739
  message: `Language ${isoLocalazy} is not supported by Strapi`
25421
25740
  });
25741
+ await activityLogsService.addEntry(sessionId, `Language ${isoLocalazy} is not supported by Strapi`);
25422
25742
  } else {
25423
25743
  await notificationService.emit(EventType.DOWNLOAD, {
25424
25744
  message: e2.message
25425
25745
  });
25746
+ await activityLogsService.addEntry(sessionId, e2.message);
25426
25747
  }
25427
25748
  }
25428
25749
  }
@@ -25447,6 +25768,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25447
25768
  await notificationService.emit(EventType.DOWNLOAD, {
25448
25769
  message: `No keys found for language ${isoLocalazy}`
25449
25770
  });
25771
+ await activityLogsService.addEntry(sessionId, `No keys found for language ${isoLocalazy}`);
25450
25772
  } else {
25451
25773
  const newKeys = langKeys.filter((k2) => {
25452
25774
  const storedEvent = langProcessedKeys[k2.id];
@@ -25455,6 +25777,10 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25455
25777
  await notificationService.emit(EventType.DOWNLOAD, {
25456
25778
  message: `${syncMode}: ${newKeys.length} changed / ${langKeys.length} total keys for language ${isoLocalazy}`
25457
25779
  });
25780
+ await activityLogsService.addEntry(
25781
+ sessionId,
25782
+ `${syncMode}: ${newKeys.length} changed / ${langKeys.length} total keys for language ${isoLocalazy}`
25783
+ );
25458
25784
  }
25459
25785
  localazyContent[isoLocalazy] = langKeys;
25460
25786
  }
@@ -25583,9 +25909,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25583
25909
  locDownloadPLevel: 6
25584
25910
  });
25585
25911
  if (isEmpty(baseEntry)) {
25586
- strapi2.log.info(
25587
- `Source language entry ${uid}[${documentId}] does not exist anymore, skipping...`
25588
- );
25912
+ strapi2.log.info(`Source language entry ${uid}[${documentId}] does not exist anymore, skipping...`);
25589
25913
  await markKeysProcessed(sourceKeys);
25590
25914
  continue;
25591
25915
  }
@@ -25597,7 +25921,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25597
25921
  const localazySearchUrl = `${user.project.url}/source-language?search=${uid}[${documentId}]`;
25598
25922
  if (isEmpty(currentLanguageLocalizedEntry)) {
25599
25923
  try {
25600
- const createdEntry = await StrapiLocalazyI18nService2.createEntry(
25924
+ await StrapiLocalazyI18nService2.createEntry(
25601
25925
  uid,
25602
25926
  strapiContentTypesModels,
25603
25927
  translatedModel,
@@ -25609,6 +25933,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25609
25933
  await notificationService.emit(EventType.DOWNLOAD, {
25610
25934
  message
25611
25935
  });
25936
+ await activityLogsService.addEntry(sessionId, message);
25612
25937
  await markKeysProcessed(sourceKeys);
25613
25938
  } catch (e2) {
25614
25939
  success = false;
@@ -25621,11 +25946,15 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25621
25946
  localazy: localazySearchUrl
25622
25947
  }
25623
25948
  });
25949
+ await activityLogsService.addEntry(
25950
+ sessionId,
25951
+ `Failed to create ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25952
+ );
25624
25953
  }
25625
25954
  } else {
25626
25955
  try {
25627
25956
  const localizedDocumentId = currentLanguageLocalizedEntry.documentId;
25628
- const updatedEntry = await StrapiLocalazyI18nService2.updateEntry(
25957
+ await StrapiLocalazyI18nService2.updateEntry(
25629
25958
  uid,
25630
25959
  localizedDocumentId,
25631
25960
  strapiContentTypesModels,
@@ -25638,6 +25967,7 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25638
25967
  await notificationService.emit(EventType.DOWNLOAD, {
25639
25968
  message
25640
25969
  });
25970
+ await activityLogsService.addEntry(sessionId, message);
25641
25971
  await markKeysProcessed(sourceKeys);
25642
25972
  } catch (e2) {
25643
25973
  success = false;
@@ -25650,6 +25980,10 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25650
25980
  localazy: localazySearchUrl
25651
25981
  }
25652
25982
  });
25983
+ await activityLogsService.addEntry(
25984
+ sessionId,
25985
+ `Failed to update ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25986
+ );
25653
25987
  }
25654
25988
  }
25655
25989
  } catch (e2) {
@@ -25658,11 +25992,18 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25658
25992
  await notificationService.emit(EventType.DOWNLOAD, {
25659
25993
  message: `Error processing ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25660
25994
  });
25995
+ await activityLogsService.addEntry(
25996
+ sessionId,
25997
+ `Error processing ${uid} [${documentId}] in ${isoStrapi}: ${e2.message}`
25998
+ );
25661
25999
  }
25662
26000
  }
25663
26001
  }
25664
26002
  }
25665
- const totalProcessedKeys = Object.values(processedKeys).reduce((sum, langKeys) => sum + Object.keys(langKeys).length, 0);
26003
+ const totalProcessedKeys = Object.values(processedKeys).reduce(
26004
+ (sum, langKeys) => sum + Object.keys(langKeys).length,
26005
+ 0
26006
+ );
25666
26007
  strapi2.log.info(
25667
26008
  `Download finished. Tracked ${totalProcessedKeys} processed keys across ${Object.keys(processedKeys).length} languages.`
25668
26009
  );
@@ -25670,6 +26011,13 @@ const LocalazyTransferDownloadService = ({ strapi: strapi2 }) => ({
25670
26011
  success,
25671
26012
  message: "Download finished"
25672
26013
  });
26014
+ const finishMessage = `Download finished. Tracked ${totalProcessedKeys} processed keys across ${Object.keys(processedKeys).length} languages.`;
26015
+ await activityLogsService.addEntry(sessionId, finishMessage);
26016
+ await activityLogsService.finishSession(
26017
+ sessionId,
26018
+ success ? "completed" : "failed",
26019
+ success ? "Download completed successfully" : "Download finished with errors"
26020
+ );
25673
26021
  console.timeEnd("download");
25674
26022
  }
25675
26023
  });
@@ -26393,6 +26741,112 @@ const EntryExclusionService = ({ strapi: strapi2 }) => ({
26393
26741
  return Object.values(exclusions).filter((exclusion) => exclusion.contentType === contentType && exclusion.excludeFromTranslation).map((exclusion) => exclusion.documentId);
26394
26742
  }
26395
26743
  });
26744
+ const KEY = "activity-logs";
26745
+ const emptyActivityLogs = {
26746
+ sessions: []
26747
+ };
26748
+ const ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1e3;
26749
+ let writeLock = Promise.resolve();
26750
+ const withLock = async (fn) => {
26751
+ let release;
26752
+ const next = new Promise((resolve) => {
26753
+ release = resolve;
26754
+ });
26755
+ const prev2 = writeLock;
26756
+ writeLock = next;
26757
+ await prev2;
26758
+ try {
26759
+ return await fn();
26760
+ } finally {
26761
+ release();
26762
+ }
26763
+ };
26764
+ const ActivityLogsService = ({ strapi: strapi2 }) => ({
26765
+ async getActivityLogs() {
26766
+ const pluginStore = getStrapiStore(strapi2);
26767
+ const logs = await pluginStore.get({ key: KEY });
26768
+ return logs || { sessions: [] };
26769
+ },
26770
+ async saveActivityLogs(logs) {
26771
+ const pluginStore = getStrapiStore(strapi2);
26772
+ await pluginStore.set({
26773
+ key: KEY,
26774
+ value: logs
26775
+ });
26776
+ },
26777
+ async startSession(eventType, initiatedBy) {
26778
+ return withLock(async () => {
26779
+ const logs = await this.getActivityLogs();
26780
+ const sessionId = generateRandomId();
26781
+ const session = {
26782
+ id: sessionId,
26783
+ eventType,
26784
+ status: "in-progress",
26785
+ startedAt: Date.now(),
26786
+ initiatedBy,
26787
+ summary: "",
26788
+ entries: []
26789
+ };
26790
+ logs.sessions.unshift(session);
26791
+ const cutoff = Date.now() - ONE_YEAR_MS;
26792
+ logs.sessions = logs.sessions.filter((s2) => s2.startedAt >= cutoff);
26793
+ await this.saveActivityLogs(logs);
26794
+ return sessionId;
26795
+ });
26796
+ },
26797
+ async addEntry(sessionId, message, data) {
26798
+ return withLock(async () => {
26799
+ const logs = await this.getActivityLogs();
26800
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26801
+ if (!session) {
26802
+ return;
26803
+ }
26804
+ const entry = {
26805
+ message,
26806
+ timestamp: Date.now(),
26807
+ data
26808
+ };
26809
+ session.entries.push(entry);
26810
+ await this.saveActivityLogs(logs);
26811
+ });
26812
+ },
26813
+ async finishSession(sessionId, status, summary) {
26814
+ return withLock(async () => {
26815
+ const logs = await this.getActivityLogs();
26816
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26817
+ if (!session) {
26818
+ return;
26819
+ }
26820
+ session.status = status;
26821
+ session.finishedAt = Date.now();
26822
+ session.summary = summary;
26823
+ await this.saveActivityLogs(logs);
26824
+ });
26825
+ },
26826
+ async getSessions(eventType) {
26827
+ const logs = await this.getActivityLogs();
26828
+ let { sessions } = logs;
26829
+ if (eventType) {
26830
+ sessions = sessions.filter((s2) => s2.eventType === eventType);
26831
+ }
26832
+ return sessions.map((s2) => ({
26833
+ ...s2,
26834
+ entries: []
26835
+ }));
26836
+ },
26837
+ async getAllSessionsWithEntries() {
26838
+ const logs = await this.getActivityLogs();
26839
+ return logs.sessions;
26840
+ },
26841
+ async getSession(sessionId) {
26842
+ const logs = await this.getActivityLogs();
26843
+ const session = logs.sessions.find((s2) => s2.id === sessionId);
26844
+ return session || null;
26845
+ },
26846
+ async clearSessions() {
26847
+ await this.saveActivityLogs(emptyActivityLogs);
26848
+ }
26849
+ });
26396
26850
  const services = {
26397
26851
  LocalazyUserService,
26398
26852
  StrapiService,
@@ -26403,7 +26857,8 @@ const services = {
26403
26857
  StrapiI18nService,
26404
26858
  LocalazyUploadService,
26405
26859
  StrapiLocalazyI18nService,
26406
- EntryExclusionService
26860
+ EntryExclusionService,
26861
+ ActivityLogsService
26407
26862
  };
26408
26863
  const index = {
26409
26864
  register,