@mattisvensson/strapi-plugin-webatlas 0.10.1 → 0.11.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 (50) hide show
  1. package/README.md +16 -9
  2. package/dist/admin/{FullLoader-CrPED_dY.mjs → FullLoader-Btjb2W2p.mjs} +5 -1
  3. package/dist/admin/FullLoader-Btjb2W2p.mjs.map +1 -0
  4. package/dist/admin/{FullLoader-Cmsf8xS6.js → FullLoader-Da2n70bJ.js} +5 -1
  5. package/dist/admin/FullLoader-Da2n70bJ.js.map +1 -0
  6. package/dist/admin/{SettingTitle-uw1S5OmC.js → SettingTitle-B0quw3f8.js} +6 -2
  7. package/dist/admin/SettingTitle-B0quw3f8.js.map +1 -0
  8. package/dist/admin/{SettingTitle-DbsxB1V9.mjs → SettingTitle-HMfQOJnK.mjs} +6 -2
  9. package/dist/admin/SettingTitle-HMfQOJnK.mjs.map +1 -0
  10. package/dist/admin/de-B5pRvs13.mjs +1 -0
  11. package/dist/admin/de-B5pRvs13.mjs.map +1 -0
  12. package/dist/admin/de-CqU1FU8C.js +1 -0
  13. package/dist/admin/de-CqU1FU8C.js.map +1 -0
  14. package/dist/admin/en-BE-zzIv8.mjs +1 -0
  15. package/dist/admin/en-BE-zzIv8.mjs.map +1 -0
  16. package/dist/admin/en-C7I90FwV.js +1 -0
  17. package/dist/admin/en-C7I90FwV.js.map +1 -0
  18. package/dist/admin/{index-BKWY9Ta-.mjs → index-9_HhKDUC.mjs} +32 -58
  19. package/dist/admin/index-9_HhKDUC.mjs.map +1 -0
  20. package/dist/admin/{index-CIr8o1RP.mjs → index-B79ELMEC.mjs} +300 -282
  21. package/dist/admin/index-B79ELMEC.mjs.map +1 -0
  22. package/dist/admin/{index-DkqiqVx2.js → index-BEVoxEAm.js} +32 -58
  23. package/dist/admin/index-BEVoxEAm.js.map +1 -0
  24. package/dist/admin/index-Bmg-ERct.mjs +244 -0
  25. package/dist/admin/index-Bmg-ERct.mjs.map +1 -0
  26. package/dist/admin/{index-BXt-QjKo.js → index-C8YjuuOx.js} +497 -353
  27. package/dist/admin/index-C8YjuuOx.js.map +1 -0
  28. package/dist/admin/{index-DC5WwNdi.js → index-Cx_mktdk.js} +300 -282
  29. package/dist/admin/index-Cx_mktdk.js.map +1 -0
  30. package/dist/admin/{index-CUaBX_v-.mjs → index-Cz_k_jjp.mjs} +42 -30
  31. package/dist/admin/index-Cz_k_jjp.mjs.map +1 -0
  32. package/dist/admin/{index-BYlmJycd.js → index-D2hB1vTw.js} +42 -30
  33. package/dist/admin/index-D2hB1vTw.js.map +1 -0
  34. package/dist/admin/index-YdWxpvOH.js +244 -0
  35. package/dist/admin/index-YdWxpvOH.js.map +1 -0
  36. package/dist/admin/{index-tPrfjOIn.mjs → index-oEJT_mvw.mjs} +497 -353
  37. package/dist/admin/index-oEJT_mvw.mjs.map +1 -0
  38. package/dist/admin/index.js +2 -1
  39. package/dist/admin/index.js.map +1 -0
  40. package/dist/admin/index.mjs +2 -1
  41. package/dist/admin/index.mjs.map +1 -0
  42. package/dist/server/index.js +578 -394
  43. package/dist/server/index.js.map +1 -0
  44. package/dist/server/index.mjs +578 -394
  45. package/dist/server/index.mjs.map +1 -0
  46. package/package.json +108 -108
  47. package/dist/admin/index-B07KlG03.mjs +0 -218
  48. package/dist/admin/index-CGsC8P9P.js +0 -218
  49. package/dist/admin/src/index.d.ts +0 -12
  50. package/dist/server/src/index.d.ts +0 -301
@@ -1,17 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- function transformToUrl(input) {
3
+ function transformToUrl(input, replaceSlash = true) {
4
4
  const specialCharMap = {
5
- "ü": "ue",
6
- "ä": "ae",
7
- "ö": "oe"
5
+ ü: "ue",
6
+ ä: "ae",
7
+ ö: "oe",
8
+ ß: "ss"
8
9
  };
9
10
  if (!input || typeof input !== "string") return "";
10
11
  input = input.toLowerCase();
11
12
  input = input.replace(/\/+/g, "/");
12
13
  input = input.startsWith("/") ? input.slice(1) : input;
13
14
  input = input.endsWith("/") ? input.slice(0, -1) : input;
14
- input = input.replace(/\//g, "-");
15
+ if (replaceSlash) {
16
+ input = input.replace(/\//g, "-");
17
+ } else {
18
+ input = input.replace(/\/+/g, "/");
19
+ input = input.startsWith("/") ? input.slice(1) : input;
20
+ input = input.endsWith("/") ? input.slice(0, -1) : input;
21
+ }
15
22
  for (const char in specialCharMap) {
16
23
  const regex = new RegExp(char, "g");
17
24
  input = input.replace(regex, specialCharMap[char]);
@@ -30,36 +37,24 @@ const PLUGIN_ID = pluginPkg.strapi.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plug
30
37
  const waNavigation = `plugin::${PLUGIN_ID}.navigation`;
31
38
  const waNavItem = `plugin::${PLUGIN_ID}.navitem`;
32
39
  const waRoute = `plugin::${PLUGIN_ID}.route`;
33
- async function checkPathExists(path, targetRoutePath) {
34
- const entities = await strapi.documents(waRoute).findMany({
35
- filters: {
36
- $or: [
37
- { path },
38
- { slug: path },
39
- { uidPath: path },
40
- { canonicalPath: path }
41
- ]
42
- }
43
- });
44
- if (targetRoutePath && entities && entities[0]?.path === targetRoutePath)
45
- return false;
46
- return entities?.length > 0;
40
+ async function checkPathExists(path, excludeDocumentId) {
41
+ const filters = {
42
+ $or: [{ path }, { uidPath: path }, { canonicalPath: path }]
43
+ };
44
+ if (excludeDocumentId) {
45
+ filters.documentId = { $ne: excludeDocumentId };
46
+ }
47
+ const entity = await strapi.documents(waRoute).findFirst({ filters });
48
+ return !!entity;
47
49
  }
48
50
  async function duplicateCheck(initialPath, targetRouteDocumentId) {
49
51
  try {
50
52
  let uniquePath = initialPath;
51
- let targetRoutePath = null;
52
53
  let counter = 1;
53
- if (targetRouteDocumentId) {
54
- const route2 = await strapi.documents(waRoute).findOne({
55
- documentId: targetRouteDocumentId
56
- });
57
- if (route2) targetRoutePath = route2.path;
58
- }
59
- let exists = await checkPathExists(uniquePath, targetRoutePath);
54
+ let exists = await checkPathExists(uniquePath, targetRouteDocumentId);
60
55
  while (exists) {
61
56
  uniquePath = `${initialPath}-${counter}`;
62
- exists = await checkPathExists(uniquePath);
57
+ exists = await checkPathExists(uniquePath, targetRouteDocumentId);
63
58
  counter++;
64
59
  }
65
60
  return uniquePath;
@@ -107,10 +102,12 @@ async function deleteNavItem(documentId) {
107
102
  }
108
103
  }
109
104
  function getAdminService() {
110
- return strapi.plugin(PLUGIN_ID)?.service("admin");
105
+ var _a;
106
+ return (_a = strapi.plugin(PLUGIN_ID)) === null || _a === void 0 ? void 0 : _a.service("admin");
111
107
  }
112
108
  function getClientService() {
113
- return strapi.plugin(PLUGIN_ID)?.service("client");
109
+ var _a;
110
+ return (_a = strapi.plugin(PLUGIN_ID)) === null || _a === void 0 ? void 0 : _a.service("client");
114
111
  }
115
112
  function reduceDepthOfOrphanedItems(navigationItems, itemId) {
116
113
  const navigationItemsCopy = JSON.parse(JSON.stringify(navigationItems));
@@ -173,9 +170,11 @@ async function deleteRoute(documentId) {
173
170
  }
174
171
  }
175
172
  function buildStructuredNavigation(navigation2, variant = "nested") {
173
+ var _a;
176
174
  const itemsById = /* @__PURE__ */ new Map();
177
175
  const rootItems = [];
178
- if (!navigation2.items || navigation2.items?.length === 0) return navigation2;
176
+ if (!navigation2.items || ((_a = navigation2.items) === null || _a === void 0 ? void 0 : _a.length) === 0)
177
+ return navigation2;
179
178
  navigation2.items.forEach((item) => {
180
179
  itemsById.set(item.documentId, { ...item, items: [] });
181
180
  });
@@ -249,14 +248,17 @@ const sortItems = (items) => {
249
248
  };
250
249
  function extractRouteAndItems(items) {
251
250
  return items.map((item) => {
251
+ var _a;
252
252
  const route2 = { ...item.route };
253
253
  if (!route2) return null;
254
- if (item.depth) {
255
- route2.depth = item.depth;
254
+ let depth = null;
255
+ if (item.depth !== void 0) {
256
+ depth = item.depth;
256
257
  }
257
- if (item.items?.length > 0) {
258
+ let children = null;
259
+ if (((_a = item.items) === null || _a === void 0 ? void 0 : _a.length) > 0) {
258
260
  const items2 = extractRouteAndItems(item.items);
259
- if (items2.length > 0) route2.items = items2;
261
+ if (items2.length > 0) children = items2;
260
262
  }
261
263
  delete route2.relatedContentType;
262
264
  delete route2.relatedDocumentId;
@@ -267,7 +269,9 @@ function extractRouteAndItems(items) {
267
269
  return {
268
270
  __component: route2.type === "wrapper" ? `${PLUGIN_ID}.wrapper` : `${PLUGIN_ID}.route`,
269
271
  type: route2.type,
270
- ...route2
272
+ ...route2,
273
+ depth: depth !== null ? depth : void 0,
274
+ items: children !== null ? children : void 0
271
275
  };
272
276
  });
273
277
  }
@@ -4256,6 +4260,7 @@ const getModelPopulationAttributes = (model) => {
4256
4260
  return model.attributes;
4257
4261
  };
4258
4262
  function getFullPopulateObject(modelUid, maxDepth = 5, ignore = []) {
4263
+ var _a;
4259
4264
  if (maxDepth <= 1) {
4260
4265
  return true;
4261
4266
  }
@@ -4268,8 +4273,12 @@ function getFullPopulateObject(modelUid, maxDepth = 5, ignore = []) {
4268
4273
  const populate = {};
4269
4274
  const model = strapi.getModel(modelUid);
4270
4275
  const newIgnore = [...ignore, modelUid];
4276
+ if ((_a = model.options) === null || _a === void 0 ? void 0 : _a.populateCreatorFields) {
4277
+ populate.createdBy = true;
4278
+ populate.updatedBy = true;
4279
+ }
4271
4280
  for (const [key, value] of Object.entries(getModelPopulationAttributes(model))) {
4272
- if (ignore?.includes(key)) continue;
4281
+ if (ignore === null || ignore === void 0 ? void 0 : ignore.includes(key)) continue;
4273
4282
  if (value) {
4274
4283
  if (value.type === "component") {
4275
4284
  const componentPopulate = getFullPopulateObject(value.component, maxDepth - 1, newIgnore);
@@ -4315,9 +4324,7 @@ function cleanRootKeys(obj) {
4315
4324
  return obj;
4316
4325
  }
4317
4326
  function removeWaFields(obj) {
4318
- delete obj["webatlas_path"];
4319
- delete obj["webatlas_override"];
4320
- delete obj["webatlas_parent"];
4327
+ delete obj["webatlas"];
4321
4328
  return obj;
4322
4329
  }
4323
4330
  async function buildCanonicalPath(slug, parentDocumentId) {
@@ -4325,7 +4332,7 @@ async function buildCanonicalPath(slug, parentDocumentId) {
4325
4332
  const parentRoute = await strapi.documents(waRoute).findOne({
4326
4333
  documentId: parentDocumentId
4327
4334
  });
4328
- const parentCanonicalPath = parentRoute?.canonicalPath || "";
4335
+ const parentCanonicalPath = (parentRoute === null || parentRoute === void 0 ? void 0 : parentRoute.canonicalPath) || "";
4329
4336
  const canonicalPath = `${parentCanonicalPath ? parentCanonicalPath + "/" : ""}${slug}`;
4330
4337
  return canonicalPath;
4331
4338
  } catch (err) {
@@ -4333,26 +4340,55 @@ async function buildCanonicalPath(slug, parentDocumentId) {
4333
4340
  return slug;
4334
4341
  }
4335
4342
  }
4336
- async function cascadeCanonicalPathUpdates(parentRouteId, newParentCanonicalPath) {
4337
- const children = await strapi.db.query(waRoute).findMany({
4338
- where: {
4339
- parent: {
4340
- documentId: parentRouteId
4343
+ async function cascadePathUpdates({
4344
+ validatedParentPath,
4345
+ parentRouteDocumentId,
4346
+ canonicalPath,
4347
+ isOverride
4348
+ }) {
4349
+ try {
4350
+ const children = await strapi.db.query(waRoute).findMany({
4351
+ where: {
4352
+ parent: {
4353
+ documentId: parentRouteDocumentId
4354
+ }
4341
4355
  }
4342
- }
4343
- });
4344
- for (const child of children) {
4345
- const newCanonicalPath = `${newParentCanonicalPath}/${child.slug}`;
4346
- const updateData = {
4347
- canonicalPath: newCanonicalPath,
4348
- // Only update path if not manually overridden
4349
- ...child.isOverride ? {} : { path: newCanonicalPath }
4350
- };
4351
- await strapi.documents(waRoute).update({
4352
- documentId: child.documentId,
4353
- data: updateData
4354
4356
  });
4355
- await cascadeCanonicalPathUpdates(child.documentId, newCanonicalPath);
4357
+ for (const child of children) {
4358
+ const newCanonicalPath = `${canonicalPath}/${child.slug}`;
4359
+ const newPath = isOverride ? `${validatedParentPath}/${child.slug}` : newCanonicalPath;
4360
+ const validatedCanonicalPath = await duplicateCheck(newCanonicalPath, child.documentId);
4361
+ const validatedPath = isOverride ? await duplicateCheck(newPath, child.documentId) : validatedCanonicalPath;
4362
+ await strapi.db.query(waRoute).updateMany({
4363
+ where: { documentId: child.documentId },
4364
+ data: {
4365
+ canonicalPath: validatedCanonicalPath,
4366
+ path: validatedPath
4367
+ }
4368
+ });
4369
+ const existingEntry = await strapi.db.query(child.relatedContentType).findOne({
4370
+ where: { documentId: child.relatedDocumentId }
4371
+ });
4372
+ if (existingEntry) {
4373
+ await strapi.db.query(child.relatedContentType).updateMany({
4374
+ where: { documentId: child.relatedDocumentId },
4375
+ data: {
4376
+ webatlas: {
4377
+ ...existingEntry.webatlas,
4378
+ path: validatedPath
4379
+ }
4380
+ }
4381
+ });
4382
+ }
4383
+ await cascadePathUpdates({
4384
+ validatedParentPath: validatedPath,
4385
+ parentRouteDocumentId: child.documentId,
4386
+ canonicalPath: validatedCanonicalPath,
4387
+ isOverride
4388
+ });
4389
+ }
4390
+ } catch (err) {
4391
+ strapi.log.error(err);
4356
4392
  }
4357
4393
  }
4358
4394
  async function getRouteDescendants(routeId) {
@@ -4386,34 +4422,30 @@ async function getNonInternalRouteIds() {
4386
4422
  const routeIds = routes2.map((route2) => route2.documentId);
4387
4423
  return routeIds;
4388
4424
  }
4389
- async function validateRouteDependencies({
4390
- routeId,
4391
- newParentId
4392
- }) {
4425
+ async function validateRouteDependencies({ routeId, newParentId }) {
4393
4426
  if (!newParentId) return true;
4394
- const normalizedRouteId = routeId ?? void 0;
4427
+ const normalizedRouteId = routeId !== null && routeId !== void 0 ? routeId : void 0;
4395
4428
  const parentRoute = await strapi.documents(waRoute).findOne({
4396
4429
  documentId: newParentId
4397
4430
  });
4398
4431
  if (!parentRoute) {
4399
4432
  throw new Error(`Parent route not found: ${newParentId}`);
4400
4433
  }
4401
- if (parentRoute?.type === "external") {
4434
+ if ((parentRoute === null || parentRoute === void 0 ? void 0 : parentRoute.type) === "external") {
4402
4435
  throw new Error("External routes cannot have children");
4403
4436
  }
4404
4437
  if (!normalizedRouteId) return true;
4405
4438
  const descendants = await getRouteDescendants(normalizedRouteId);
4406
4439
  const nonInternalRouteIds = await getNonInternalRouteIds();
4407
4440
  if (normalizedRouteId === newParentId || descendants.includes(newParentId) || nonInternalRouteIds.includes(newParentId)) {
4408
- throw new Error(`Circular dependency detected: Cannot set route ${newParentId} as parent of ${normalizedRouteId}`);
4441
+ throw new Error(
4442
+ `Circular dependency detected: Cannot set route ${newParentId} as parent of ${normalizedRouteId}`
4443
+ );
4409
4444
  }
4410
4445
  return true;
4411
4446
  }
4412
- async function buildNavigationPath({
4413
- slug,
4414
- routeDocumentId,
4415
- calculatedParent
4416
- }) {
4447
+ async function buildNavigationPath({ slug, routeDocumentId, calculatedParent }) {
4448
+ var _a, _b, _c;
4417
4449
  let parentDocumentId = calculatedParent;
4418
4450
  let parent = null;
4419
4451
  if (parentDocumentId) {
@@ -4423,23 +4455,25 @@ async function buildNavigationPath({
4423
4455
  populate: ["route", "parent"]
4424
4456
  });
4425
4457
  parent = navItem;
4426
- parentDocumentId = navItem?.parent?.documentId || null;
4427
- if (parent?.route?.type === "internal") break;
4458
+ parentDocumentId = ((_a = navItem === null || navItem === void 0 ? void 0 : navItem.parent) === null || _a === void 0 ? void 0 : _a.documentId) || null;
4459
+ if (((_b = parent === null || parent === void 0 ? void 0 : parent.route) === null || _b === void 0 ? void 0 : _b.type) === "internal")
4460
+ break;
4428
4461
  } while (parentDocumentId);
4429
4462
  }
4430
- if (parent?.route?.type !== "internal")
4463
+ if (((_c = parent === null || parent === void 0 ? void 0 : parent.route) === null || _c === void 0 ? void 0 : _c.type) !== "internal")
4431
4464
  parent = null;
4432
4465
  if (slug.startsWith("/")) slug = slug.substring(1);
4433
- const newPath = parent?.route ? `${parent.route.path}/${slug}` : `${slug}`;
4466
+ const newPath = (parent === null || parent === void 0 ? void 0 : parent.route) ? `${parent.route.path}/${slug}` : `${slug}`;
4434
4467
  const validatedPath = await duplicateCheck(newPath, routeDocumentId);
4435
4468
  return validatedPath;
4436
4469
  }
4437
4470
  async function handleItemDeletion(navigationItems) {
4471
+ var _a;
4438
4472
  const errors = [];
4439
4473
  let items = [...navigationItems];
4440
4474
  for (let i = 0; i < items.length; i++) {
4441
4475
  const item = items[i];
4442
- if (item.clientModifications?.type === "delete") {
4476
+ if (((_a = item.clientModifications) === null || _a === void 0 ? void 0 : _a.type) === "delete") {
4443
4477
  try {
4444
4478
  if (item.documentId) {
4445
4479
  await deleteNavItem(item.documentId);
@@ -4487,9 +4521,10 @@ async function handleItemUpdate({
4487
4521
  navigationId,
4488
4522
  newNavItemsMap
4489
4523
  }) {
4524
+ var _a, _b, _c, _d;
4490
4525
  const errors = [];
4491
- const isCreate = item.clientModifications?.type === "create";
4492
- const isUpdate = item.clientModifications?.type === "update";
4526
+ const isCreate = ((_a = item.clientModifications) === null || _a === void 0 ? void 0 : _a.type) === "create";
4527
+ const isUpdate = ((_b = item.clientModifications) === null || _b === void 0 ? void 0 : _b.type) === "update";
4493
4528
  const isInternal = item.route.type === "internal";
4494
4529
  if (isCreate && !item.clientModifications.route) {
4495
4530
  try {
@@ -4517,7 +4552,8 @@ async function handleItemUpdate({
4517
4552
  const route2 = await strapi.documents(waRoute).findOne({
4518
4553
  documentId: item.clientModifications.route
4519
4554
  });
4520
- if (!route2) throw new Error(`Related route not found for new navigation item '${item.route.title}'`);
4555
+ if (!route2)
4556
+ throw new Error(`Related route not found for new navigation item '${item.route.title}'`);
4521
4557
  const path = await buildNavigationPath({
4522
4558
  slug: item.route.slug,
4523
4559
  routeDocumentId: route2.documentId,
@@ -4538,7 +4574,10 @@ async function handleItemUpdate({
4538
4574
  if (newNavItem) newNavItemsMap.set(item.documentId, newNavItem);
4539
4575
  } catch (err) {
4540
4576
  errors.push(err instanceof Error ? err.message : String(err));
4541
- strapi.log.error(`Error creating navigation item with existing route '${item.route.title}': `, err);
4577
+ strapi.log.error(
4578
+ `Error creating navigation item with existing route '${item.route.title}': `,
4579
+ err
4580
+ );
4542
4581
  }
4543
4582
  return { success: errors.length === 0, errors };
4544
4583
  }
@@ -4548,23 +4587,33 @@ async function handleItemUpdate({
4548
4587
  const route2 = await strapi.documents(waRoute).findOne({
4549
4588
  documentId: item.route.documentId
4550
4589
  });
4551
- if (!route2) throw new Error(`Related route not found for navigation item '${item.route.title}'`);
4552
- const slug = item.clientModifications?.slug || item.route.slug;
4553
- const path = isInternal ? await buildNavigationPath({ slug, routeDocumentId: route2.documentId, calculatedParent }) : slug;
4590
+ if (!route2)
4591
+ throw new Error(`Related route not found for navigation item '${item.route.title}'`);
4592
+ const slug = ((_c = item.clientModifications) === null || _c === void 0 ? void 0 : _c.slug) || item.route.slug;
4593
+ const path = isInternal ? await buildNavigationPath({
4594
+ slug,
4595
+ routeDocumentId: route2.documentId,
4596
+ calculatedParent
4597
+ }) : slug;
4598
+ const isOverride = path !== route2.canonicalPath;
4554
4599
  if (needsRouteUpdate) {
4555
4600
  await updateRoute(route2.documentId, {
4556
- title: item.clientModifications?.title || item.route.title,
4601
+ title: ((_d = item.clientModifications) === null || _d === void 0 ? void 0 : _d.title) || item.route.title,
4557
4602
  slug,
4558
4603
  path,
4559
- isOverride: path !== route2.canonicalPath
4604
+ isOverride
4560
4605
  });
4561
4606
  }
4562
4607
  if (isInternal) {
4563
- await strapi.entityService.update(item.route.relatedContentType, item.route.relatedDocumentId, {
4564
- data: {
4565
- webatlas_path: path,
4566
- webatlas_override: path !== route2.canonicalPath
4567
- }
4608
+ const webatlasObj = {
4609
+ path,
4610
+ isOverride,
4611
+ parentDocumentId: calculatedParent,
4612
+ slug
4613
+ };
4614
+ await strapi.db.query(item.route.relatedContentType).updateMany({
4615
+ where: { documentId: item.route.relatedDocumentId },
4616
+ data: { webatlas: webatlasObj }
4568
4617
  });
4569
4618
  }
4570
4619
  } catch (err) {
@@ -4589,6 +4638,7 @@ function calculateParentAndOrder({
4589
4638
  groupIndices,
4590
4639
  newNavItemsMap
4591
4640
  }) {
4641
+ var _a;
4592
4642
  if (item.depth === 0) {
4593
4643
  if (groupIndices[0] !== void 0) {
4594
4644
  groupIndices[0] = groupIndices[0] + 1;
@@ -4600,7 +4650,9 @@ function calculateParentAndOrder({
4600
4650
  const previousItem = navigationItems[index2 - 1];
4601
4651
  if (previousItem && typeof previousItem.depth === "number") {
4602
4652
  if (item.depth === previousItem.depth + 1) {
4603
- parentIds.push(previousItem.documentId.startsWith("temp-") ? newNavItemsMap.get(previousItem.documentId)?.documentId || previousItem.documentId : previousItem.documentId);
4653
+ parentIds.push(
4654
+ previousItem.documentId.startsWith("temp-") ? ((_a = newNavItemsMap.get(previousItem.documentId)) === null || _a === void 0 ? void 0 : _a.documentId) || previousItem.documentId : previousItem.documentId
4655
+ );
4604
4656
  groupIndices[item.depth] = 0;
4605
4657
  } else if (item.depth <= previousItem.depth) {
4606
4658
  const diff = previousItem.depth - item.depth;
@@ -4625,21 +4677,19 @@ const migration_001_canonical_path = {
4625
4677
  version: "001",
4626
4678
  description: "Migrate title field to canonicalPath using transformToUrl",
4627
4679
  async up(strapi2) {
4680
+ var _a;
4628
4681
  strapi2.log.info("[webatlas] Starting canonical path migration...");
4629
4682
  try {
4630
- const routes2 = await strapi2.db?.query(waRoute).findMany({
4683
+ const routes2 = await ((_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waRoute).findMany({
4631
4684
  where: {
4632
4685
  title: {
4633
4686
  $notNull: true,
4634
4687
  $ne: ""
4635
4688
  },
4636
- $or: [
4637
- { canonicalPath: { $null: true } },
4638
- { canonicalPath: "" }
4639
- ]
4689
+ $or: [{ canonicalPath: { $null: true } }, { canonicalPath: "" }]
4640
4690
  },
4641
4691
  populate: ["parent"]
4642
- });
4692
+ }));
4643
4693
  if (!routes2 || routes2.length === 0) {
4644
4694
  strapi2.log.info("[webatlas] No routes found that need canonical path migration");
4645
4695
  return;
@@ -4650,28 +4700,35 @@ const migration_001_canonical_path = {
4650
4700
  const chunkSize = 50;
4651
4701
  for (let i = 0; i < routes2.length; i += chunkSize) {
4652
4702
  const chunk = routes2.slice(i, i + chunkSize);
4653
- await Promise.all(chunk.map(async (route2) => {
4654
- try {
4655
- const transformedTitle = transformToUrl(route2.title);
4656
- const parentId = route2.parent?.id || null;
4657
- const canonicalPath = await buildCanonicalPath(transformedTitle, parentId);
4658
- await strapi2.db?.query(waRoute).update({
4659
- where: { id: route2.id },
4660
- data: { canonicalPath }
4661
- });
4662
- migratedCount++;
4663
- if (migratedCount % 25 === 0) {
4664
- strapi2.log.info(`[webatlas] Migrated ${migratedCount}/${routes2.length} routes`);
4703
+ await Promise.all(
4704
+ chunk.map(async (route2) => {
4705
+ var _a2, _b;
4706
+ try {
4707
+ const transformedTitle = transformToUrl(route2.title);
4708
+ const parentId = ((_a2 = route2.parent) === null || _a2 === void 0 ? void 0 : _a2.id) || null;
4709
+ const canonicalPath = await buildCanonicalPath(transformedTitle, parentId);
4710
+ await ((_b = strapi2.db) === null || _b === void 0 ? void 0 : _b.query(waRoute).update({
4711
+ where: { id: route2.id },
4712
+ data: { canonicalPath }
4713
+ }));
4714
+ migratedCount++;
4715
+ if (migratedCount % 25 === 0) {
4716
+ strapi2.log.info(`[webatlas] Migrated ${migratedCount}/${routes2.length} routes`);
4717
+ }
4718
+ } catch (error) {
4719
+ strapi2.log.error(`[webatlas] Failed to migrate route ${route2.id}:`, error);
4720
+ errorCount++;
4665
4721
  }
4666
- } catch (error) {
4667
- strapi2.log.error(`[webatlas] Failed to migrate route ${route2.id}:`, error);
4668
- errorCount++;
4669
- }
4670
- }));
4722
+ })
4723
+ );
4671
4724
  }
4672
- strapi2.log.info(`[webatlas] Canonical path migration completed. Migrated: ${migratedCount}, Errors: ${errorCount}`);
4725
+ strapi2.log.info(
4726
+ `[webatlas] Canonical path migration completed. Migrated: ${migratedCount}, Errors: ${errorCount}`
4727
+ );
4673
4728
  if (errorCount > 0) {
4674
- strapi2.log.warn(`[webatlas] ${errorCount} routes failed to migrate. Check logs for details.`);
4729
+ strapi2.log.warn(
4730
+ `[webatlas] ${errorCount} routes failed to migrate. Check logs for details.`
4731
+ );
4675
4732
  }
4676
4733
  } catch (error) {
4677
4734
  strapi2.log.error("[webatlas] Canonical path migration failed:", error);
@@ -4679,9 +4736,75 @@ const migration_001_canonical_path = {
4679
4736
  }
4680
4737
  }
4681
4738
  };
4682
- const migrations = [
4683
- migration_001_canonical_path
4684
- ];
4739
+ const migration_002_webatlas_json_field = {
4740
+ version: "002",
4741
+ description: "Migrate webatlas_path, webatlas_parent and webatlas_override text fields into the webatlas JSON field",
4742
+ async up(strapi2) {
4743
+ var _a, _b;
4744
+ const knex = strapi2.db.connection;
4745
+ const enabledContentTypes = Object.values(strapi2.contentTypes).filter((ct) => {
4746
+ var _a2, _b2;
4747
+ return ((_b2 = (_a2 = ct.pluginOptions) === null || _a2 === void 0 ? void 0 : _a2.webatlas) === null || _b2 === void 0 ? void 0 : _b2.enabled) === true;
4748
+ });
4749
+ for (const contentType of enabledContentTypes) {
4750
+ const tableName = (_b = (_a = strapi2.db.metadata.get(contentType.uid)) === null || _a === void 0 ? void 0 : _a.tableName) !== null && _b !== void 0 ? _b : contentType.collectionName;
4751
+ strapi2.log.info(`[webatlas] Processing table: ${tableName} (${contentType.uid})`);
4752
+ const [hasPathCol, hasOverrideCol, hasParentCol, hasWebatlasCol] = await Promise.all([
4753
+ knex.schema.hasColumn(tableName, "webatlas_path"),
4754
+ knex.schema.hasColumn(tableName, "webatlas_override"),
4755
+ knex.schema.hasColumn(tableName, "webatlas_parent"),
4756
+ knex.schema.hasColumn(tableName, "webatlas")
4757
+ ]);
4758
+ const hasAnyOldCol = hasPathCol || hasOverrideCol || hasParentCol;
4759
+ if (!hasAnyOldCol) {
4760
+ strapi2.log.info(`[webatlas] No old fields found in ${tableName}, skipping data migration`);
4761
+ } else if (!hasWebatlasCol) {
4762
+ strapi2.log.warn(
4763
+ `[webatlas] New "webatlas" column not found in ${tableName} — schema may not have synced yet. Skipping data migration, old columns will still be dropped.`
4764
+ );
4765
+ } else {
4766
+ const selectCols = ["id"];
4767
+ if (hasPathCol) selectCols.push("webatlas_path");
4768
+ if (hasOverrideCol) selectCols.push("webatlas_override");
4769
+ if (hasParentCol) selectCols.push("webatlas_parent");
4770
+ const rows = await knex(tableName).select(selectCols);
4771
+ let migratedCount = 0;
4772
+ for (const row of rows) {
4773
+ const path = row.webatlas_path || "";
4774
+ const isOverride = Boolean(row.webatlas_override);
4775
+ const parentDocumentId = row.webatlas_parent || null;
4776
+ if (!path && !isOverride && !parentDocumentId) continue;
4777
+ const slug = path ? path.split("/").pop() || "" : "";
4778
+ await knex(tableName).where({ id: row.id }).update({
4779
+ webatlas: JSON.stringify({
4780
+ path,
4781
+ slug,
4782
+ isOverride,
4783
+ parentDocumentId
4784
+ })
4785
+ });
4786
+ migratedCount++;
4787
+ }
4788
+ strapi2.log.info(
4789
+ `[webatlas] Migrated ${migratedCount} / ${rows.length} rows in ${tableName}`
4790
+ );
4791
+ }
4792
+ const colsToDrop = [
4793
+ hasPathCol && "webatlas_path",
4794
+ hasOverrideCol && "webatlas_override",
4795
+ hasParentCol && "webatlas_parent"
4796
+ ].filter(Boolean);
4797
+ if (colsToDrop.length > 0) {
4798
+ await knex.schema.table(tableName, (table) => {
4799
+ colsToDrop.forEach((col) => table.dropColumn(col));
4800
+ });
4801
+ strapi2.log.info(`[webatlas] Dropped columns [${colsToDrop.join(", ")}] from ${tableName}`);
4802
+ }
4803
+ }
4804
+ strapi2.log.info("[webatlas] webatlas JSON field migration completed");
4805
+ }
4806
+ };
4807
+ const migrations = [migration_001_canonical_path, migration_002_webatlas_json_field];
4685
4808
  const runMigrations = async (strapi2) => {
4686
4809
  const pluginStore = strapi2.store({ type: "plugin", name: PLUGIN_ID });
4687
4810
  let config2 = await pluginStore.get({ key: "config" });
@@ -4714,54 +4837,48 @@ const runMigrations = async (strapi2) => {
4714
4837
  }
4715
4838
  strapi2.log.info("[webatlas] All migrations completed successfully");
4716
4839
  };
4717
- const bootstrap = async ({ strapi: strapi2 }) => {
4718
- try {
4719
- await runMigrations(strapi2);
4720
- const actions = [
4721
- {
4722
- section: "plugins",
4723
- displayName: "Navigation page",
4724
- uid: "page.navigation",
4725
- subCategory: "Pages",
4726
- pluginName: PLUGIN_ID
4727
- },
4728
- {
4729
- section: "plugins",
4730
- displayName: "Routes page",
4731
- uid: "page.routes",
4732
- subCategory: "Pages",
4733
- pluginName: PLUGIN_ID
4734
- },
4735
- {
4736
- section: "plugins",
4737
- displayName: "General page",
4738
- uid: "settings.general",
4739
- subCategory: "Settings",
4740
- pluginName: PLUGIN_ID
4741
- },
4742
- {
4743
- section: "plugins",
4744
- displayName: "Navigation page",
4745
- uid: "settings.navigation",
4746
- subCategory: "Settings",
4747
- pluginName: PLUGIN_ID
4748
- },
4749
- {
4750
- section: "plugins",
4751
- displayName: "Aside panel",
4752
- uid: "cm.aside",
4753
- subCategory: "Content Manager",
4754
- pluginName: PLUGIN_ID
4755
- }
4756
- ];
4757
- strapi2.admin.services.permission.actionProvider.registerMany(actions);
4758
- } catch (error) {
4759
- strapi2.log.error(`Bootstrap failed. ${String(error)}`);
4760
- }
4761
- const contentTypes2 = strapi2.contentTypes;
4762
- const enabledContentTypes = Object.values(contentTypes2).filter(
4763
- (type) => type.pluginOptions?.webatlas?.enabled === true
4764
- );
4840
+ function registerPermissions(strapi2) {
4841
+ const actions = [
4842
+ {
4843
+ section: "plugins",
4844
+ displayName: "Navigation page",
4845
+ uid: "page.navigation",
4846
+ subCategory: "Pages",
4847
+ pluginName: PLUGIN_ID
4848
+ },
4849
+ {
4850
+ section: "plugins",
4851
+ displayName: "Routes page",
4852
+ uid: "page.routes",
4853
+ subCategory: "Pages",
4854
+ pluginName: PLUGIN_ID
4855
+ },
4856
+ {
4857
+ section: "plugins",
4858
+ displayName: "General page",
4859
+ uid: "settings.general",
4860
+ subCategory: "Settings",
4861
+ pluginName: PLUGIN_ID
4862
+ },
4863
+ {
4864
+ section: "plugins",
4865
+ displayName: "Navigation page",
4866
+ uid: "settings.navigation",
4867
+ subCategory: "Settings",
4868
+ pluginName: PLUGIN_ID
4869
+ },
4870
+ {
4871
+ section: "plugins",
4872
+ displayName: "Aside panel",
4873
+ uid: "cm.aside",
4874
+ subCategory: "Content Manager",
4875
+ pluginName: PLUGIN_ID
4876
+ }
4877
+ ];
4878
+ strapi2.admin.services.permission.actionProvider.registerMany(actions);
4879
+ }
4880
+ async function syncConfig(strapi2, enabledContentTypes) {
4881
+ var _a;
4765
4882
  const pluginStore = strapi2.store({ type: "plugin", name: PLUGIN_ID });
4766
4883
  const config2 = await pluginStore.get({
4767
4884
  key: "config"
@@ -4770,214 +4887,281 @@ const bootstrap = async ({ strapi: strapi2 }) => {
4770
4887
  ...config2,
4771
4888
  selectedContentTypes: [],
4772
4889
  navigation: {
4773
- maxDepth: config2?.navigation?.maxDepth || 1,
4774
- ...config2?.navigation
4890
+ maxDepth: ((_a = config2 === null || config2 === void 0 ? void 0 : config2.navigation) === null || _a === void 0 ? void 0 : _a.maxDepth) || 1,
4891
+ ...config2 === null || config2 === void 0 ? void 0 : config2.navigation
4775
4892
  },
4776
- migrationVersion: config2?.migrationVersion || "0"
4893
+ migrationVersion: (config2 === null || config2 === void 0 ? void 0 : config2.migrationVersion) || "0"
4777
4894
  };
4778
4895
  enabledContentTypes.forEach((type) => {
4779
- const existingConfig = config2?.selectedContentTypes?.find((ct) => ct.uid === type.uid);
4896
+ var _a2;
4897
+ const existingConfig = (_a2 = config2 === null || config2 === void 0 ? void 0 : config2.selectedContentTypes) === null || _a2 === void 0 ? void 0 : _a2.find((ct) => ct.uid === type.uid);
4780
4898
  newConfig.selectedContentTypes.push({
4781
4899
  uid: type.uid,
4782
4900
  label: type.info.displayName,
4783
- default: existingConfig?.default || null
4901
+ default: (existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.default) || null
4784
4902
  });
4785
4903
  });
4786
4904
  if (JSON.stringify(newConfig) !== JSON.stringify(config2)) {
4787
4905
  await pluginStore.set({ key: "config", value: newConfig });
4788
4906
  }
4789
- if (!enabledContentTypes.length) return;
4790
- strapi2.db?.lifecycles.subscribe({
4791
- models: [waNavItem],
4792
- // TODO: is beforeDelete needed?
4793
- async beforeDelete(event) {
4794
- const id = event.params.where["id"];
4795
- if (!id) return;
4796
- try {
4797
- const navItem = await strapi2.db?.query(waNavItem).findOne({
4798
- where: {
4799
- id
4800
- },
4801
- populate: ["route"]
4802
- });
4803
- if (!navItem || !navItem.route) return;
4804
- event.state = navItem.route.id && navItem.route.type === "external" ? { id: navItem.route.id } : null;
4805
- } catch (err) {
4806
- strapi2.log.error(err);
4807
- }
4808
- },
4809
- async afterDelete(event) {
4810
- const { id } = event.state;
4811
- if (!id) return;
4812
- try {
4813
- await strapi2.db?.query(waRoute).delete({
4814
- where: {
4815
- id
4816
- }
4817
- });
4818
- } catch (err) {
4819
- strapi2.log.error(err);
4820
- }
4907
+ return newConfig;
4908
+ }
4909
+ function documentMiddleware(strapi2, enabledContentTypes, config2) {
4910
+ const actions = ["create", "update", "delete"];
4911
+ strapi2.documents.use(async (context, next) => {
4912
+ var _a, _b, _c, _d, _e, _f;
4913
+ if (!enabledContentTypes.map((type) => type.uid).includes(context.uid) || !actions.includes(context.action)) {
4914
+ return next();
4821
4915
  }
4822
- });
4823
- strapi2.db?.lifecycles.subscribe({
4824
- models: enabledContentTypes.map((type) => type.uid),
4825
- async beforeCreate(event) {
4826
- if (!event.params.data.webatlas_path) return;
4827
- event.params.data.webatlas_path = transformToUrl(event.params.data.webatlas_path);
4828
- },
4829
- async afterCreate(event) {
4830
- const ctSettings = config2.selectedContentTypes.find((type) => type.uid === event.model.uid);
4831
- const {
4832
- webatlas_path,
4833
- webatlas_override,
4834
- webatlas_parent
4835
- } = event.params.data;
4836
- if (!webatlas_path) return;
4837
- const relatedRoute = await strapi2.db?.query(waRoute).findOne({
4838
- where: {
4839
- relatedDocumentId: event.result.documentId
4840
- }
4841
- });
4842
- if (relatedRoute) return;
4916
+ const ctSettings = config2.selectedContentTypes.find((ct) => ct.uid === context.uid);
4917
+ if (context.action === "create") {
4918
+ const data = context.params.data;
4919
+ const { webatlas } = data;
4920
+ const { slug, parentDocumentId, isOverride } = webatlas || {};
4921
+ const transformedSlug = slug ? transformToUrl(slug) : null;
4922
+ if (transformedSlug) {
4923
+ data.webatlas.slug = transformedSlug;
4924
+ }
4925
+ const result2 = await next();
4926
+ if (!transformedSlug) return result2;
4927
+ const existing = await ((_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waRoute).findOne({
4928
+ where: { relatedDocumentId: result2.documentId }
4929
+ }));
4930
+ if (existing) return result2;
4843
4931
  let parent = null;
4844
- if (webatlas_parent) {
4845
- try {
4846
- const isValid = await validateRouteDependencies({
4847
- newParentId: webatlas_parent
4932
+ let isValid = false;
4933
+ if (parentDocumentId) {
4934
+ isValid = await validateRouteDependencies({
4935
+ newParentId: parentDocumentId
4936
+ });
4937
+ if (isValid) {
4938
+ parent = await strapi2.documents(waRoute).findOne({
4939
+ documentId: parentDocumentId
4848
4940
  });
4849
- if (isValid) parent = webatlas_parent;
4850
- } catch (err) {
4851
- strapi2.log.error(`Route dependency validation failed: ${err.message}`);
4852
4941
  }
4853
4942
  }
4854
- const path = await duplicateCheck(transformToUrl(webatlas_path));
4855
- const canonicalPath = await buildCanonicalPath(path, parent);
4856
- const title = event.params.data[ctSettings?.default]?.trim() || path;
4943
+ let rawPath = transformedSlug;
4944
+ if (!isOverride) rawPath = parent ? `${parent.path}/${transformedSlug}` : transformedSlug;
4945
+ const validatedPath = await duplicateCheck(rawPath);
4946
+ if (!validatedPath)
4947
+ throw new Error(`Failed to generate a unique path for slug: ${transformedSlug}`);
4948
+ const singularName = context.contentType.info.singularName;
4949
+ const title = ((_b = context.params.data[ctSettings === null || ctSettings === void 0 ? void 0 : ctSettings.default]) === null || _b === void 0 ? void 0 : _b.trim()) || transformedSlug;
4950
+ const canonicalPath = await buildCanonicalPath(
4951
+ transformToUrl(title),
4952
+ isValid ? parent.documentId : null
4953
+ );
4857
4954
  await strapi2.documents(waRoute).create({
4858
4955
  data: {
4859
- relatedContentType: event.model.uid,
4860
- relatedId: event.result.id,
4861
- relatedDocumentId: event.result.documentId,
4862
- slug: path,
4863
- path,
4864
- uidPath: `${event.model.singularName}/${event.result.id}`,
4865
- isOverride: webatlas_override || false,
4956
+ relatedContentType: context.uid,
4957
+ relatedId: result2.id,
4958
+ relatedDocumentId: result2.documentId,
4959
+ slug: transformedSlug,
4960
+ path: validatedPath,
4961
+ uidPath: `${singularName}/${result2.id}`,
4962
+ isOverride: isOverride || false,
4866
4963
  title,
4867
- parent,
4964
+ parent: isValid ? parent === null || parent === void 0 ? void 0 : parent.documentId : null,
4868
4965
  canonicalPath
4869
4966
  }
4870
4967
  });
4871
- },
4872
- async afterUpdate(event) {
4873
- const ctSettings = config2.selectedContentTypes.find((type) => type.uid === event.model.uid);
4874
- const {
4875
- webatlas_path,
4876
- webatlas_override,
4877
- webatlas_parent,
4878
- documentId
4879
- } = event.params.data;
4880
- if (!webatlas_path) return;
4968
+ await ((_c = strapi2.db) === null || _c === void 0 ? void 0 : _c.query(context.uid).updateMany({
4969
+ where: { documentId: result2.documentId },
4970
+ data: {
4971
+ webatlas: {
4972
+ ...webatlas,
4973
+ slug: transformedSlug,
4974
+ path: validatedPath,
4975
+ parentDocumentId: isValid ? parent === null || parent === void 0 ? void 0 : parent.documentId : "null",
4976
+ isOverride: isOverride || false
4977
+ }
4978
+ }
4979
+ }));
4980
+ return result2;
4981
+ }
4982
+ if (context.action === "update") {
4983
+ const data = context.params.data;
4984
+ const { documentId } = context.params;
4985
+ const { webatlas } = data;
4986
+ const { slug, parentDocumentId, isOverride } = webatlas || {};
4987
+ if (!slug) return;
4881
4988
  const relatedRoute = await strapi2.documents(waRoute).findFirst({
4882
4989
  filters: {
4883
4990
  relatedDocumentId: documentId
4884
4991
  }
4885
4992
  });
4886
4993
  let parent = null;
4887
- if (webatlas_parent) {
4888
- try {
4889
- const isValid = await validateRouteDependencies({
4890
- routeId: relatedRoute ? relatedRoute.documentId : null,
4891
- newParentId: webatlas_parent
4994
+ let isValid = false;
4995
+ if (parentDocumentId) {
4996
+ isValid = await validateRouteDependencies({
4997
+ routeId: relatedRoute ? relatedRoute.documentId : null,
4998
+ newParentId: parentDocumentId
4999
+ });
5000
+ if (isValid) {
5001
+ parent = await strapi2.documents(waRoute).findOne({
5002
+ documentId: parentDocumentId
4892
5003
  });
4893
- if (isValid) {
4894
- parent = await strapi2.documents(waRoute).findOne({
4895
- documentId: webatlas_parent
4896
- });
4897
- }
4898
- } catch (err) {
4899
- strapi2.log.error(`Route dependency validation failed: ${err.message}`);
4900
5004
  }
4901
5005
  }
4902
- const transformedPath = transformToUrl(webatlas_path);
4903
- const rawPath = parent ? `${parent.path}/${transformedPath}` : transformedPath;
4904
- const path = await duplicateCheck(rawPath, relatedRoute ? relatedRoute.documentId : null);
4905
- const canonicalPath = await buildCanonicalPath(transformedPath, parent?.documentId);
4906
- const title = event.params.data[ctSettings?.default]?.trim() || path;
5006
+ const transformedSlug = transformToUrl(slug);
5007
+ let rawPath = transformedSlug;
5008
+ if (!isOverride) rawPath = parent ? `${parent.path}/${transformedSlug}` : transformedSlug;
5009
+ const validatedPath = await duplicateCheck(
5010
+ rawPath,
5011
+ (_d = relatedRoute === null || relatedRoute === void 0 ? void 0 : relatedRoute.documentId) !== null && _d !== void 0 ? _d : null
5012
+ );
5013
+ data.webatlas.path = validatedPath;
5014
+ data.webatlas.slug = transformedSlug;
5015
+ if (relatedRoute) data.relatedRoute = relatedRoute;
5016
+ if (!isValid && parentDocumentId) data.webatlas.parent = null;
5017
+ const result2 = await next();
5018
+ const title = ((_e = context.params.data[ctSettings === null || ctSettings === void 0 ? void 0 : ctSettings.default]) === null || _e === void 0 ? void 0 : _e.trim()) || slug;
5019
+ const canonicalPath = isOverride ? relatedRoute.path : await buildCanonicalPath(
5020
+ transformToUrl(title),
5021
+ parent === null || parent === void 0 ? void 0 : parent.documentId
5022
+ );
4907
5023
  const routeData = {
4908
5024
  title,
4909
- path,
4910
- slug: transformedPath,
4911
- isOverride: webatlas_override || false,
4912
- parent: parent?.documentId || null
5025
+ path: validatedPath,
5026
+ slug,
5027
+ isOverride: isOverride || false,
5028
+ parent: (parent === null || parent === void 0 ? void 0 : parent.documentId) || null,
5029
+ canonicalPath
4913
5030
  };
4914
- let routeDocumentId = relatedRoute?.documentId;
5031
+ let routeDocumentId = relatedRoute === null || relatedRoute === void 0 ? void 0 : relatedRoute.documentId;
4915
5032
  if (!relatedRoute) {
4916
5033
  const createdRoute = await strapi2.documents(waRoute).create({
4917
5034
  data: {
4918
- relatedContentType: event.model.uid,
4919
- relatedId: event.result.id,
4920
- relatedDocumentId: event.result.documentId,
4921
- uidPath: `${event.model.singularName}/${event.result.id}`,
4922
- canonicalPath,
5035
+ relatedContentType: context.uid,
5036
+ relatedId: result2.id,
5037
+ relatedDocumentId: result2.documentId,
5038
+ uidPath: `${context.contentType.info.singularName}/${result2.id}`,
4923
5039
  ...routeData
4924
5040
  }
4925
5041
  });
4926
- routeDocumentId = createdRoute?.documentId;
5042
+ routeDocumentId = createdRoute === null || createdRoute === void 0 ? void 0 : createdRoute.documentId;
4927
5043
  } else {
4928
5044
  await strapi2.documents(waRoute).update({
4929
5045
  documentId: relatedRoute.documentId,
4930
- data: {
4931
- ...routeData,
4932
- canonicalPath
4933
- }
5046
+ data: routeData
4934
5047
  });
4935
5048
  }
4936
5049
  if (routeDocumentId) {
4937
- await cascadeCanonicalPathUpdates(routeDocumentId, canonicalPath);
5050
+ await cascadePathUpdates({
5051
+ validatedParentPath: validatedPath,
5052
+ parentRouteDocumentId: routeDocumentId,
5053
+ canonicalPath,
5054
+ isOverride
5055
+ });
4938
5056
  }
4939
- },
4940
- async afterDelete(event) {
5057
+ }
5058
+ if (context.action === "delete") {
5059
+ const result2 = await next();
4941
5060
  try {
4942
- await findAndDeleteNavItem(event.result.id, event.model.uid);
5061
+ const relatedDocumentId = context.params.documentId;
5062
+ const deletedRoute = await strapi2.db.query(waRoute).delete({
5063
+ where: { relatedDocumentId },
5064
+ populate: ["navitem"]
5065
+ });
5066
+ if (!(deletedRoute === null || deletedRoute === void 0 ? void 0 : deletedRoute.documentId))
5067
+ return result2;
5068
+ const navItemDocumentIds = Array.from(
5069
+ (_f = deletedRoute.navitem) === null || _f === void 0 ? void 0 : _f.map((item) => item.documentId)
5070
+ );
5071
+ for (const navItemDocumentId of navItemDocumentIds) {
5072
+ await strapi2.documents(waNavItem).delete({ documentId: navItemDocumentId });
5073
+ }
4943
5074
  } catch (err) {
4944
5075
  strapi2.log.error(err);
4945
5076
  }
4946
- },
4947
- async afterDeleteMany(event) {
4948
- const deletedArr = event.params.where["$and"];
4949
- deletedArr.map((item) => {
4950
- const ids = item.id["$in"];
4951
- ids.map(async (id) => {
4952
- await findAndDeleteNavItem(id, event.model.uid);
4953
- });
4954
- });
5077
+ return result2;
4955
5078
  }
5079
+ const result = await next();
5080
+ return result;
4956
5081
  });
4957
- };
4958
- async function findAndDeleteNavItem(relatedId, relatedContentType) {
4959
- if (!relatedId || !relatedContentType) return;
4960
- try {
4961
- const route2 = await strapi.db?.query(waRoute).findOne({
4962
- where: {
4963
- relatedId,
4964
- relatedContentType
5082
+ }
5083
+ function webatlasMiddleware(strapi2) {
5084
+ strapi2.documents.use(async (context, next) => {
5085
+ var _a, _b;
5086
+ if (context.uid !== waNavItem) return next();
5087
+ if (context.action === "delete") {
5088
+ let externalRouteDocumentId = null;
5089
+ try {
5090
+ const navItem = await ((_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waNavItem).findOne({
5091
+ where: { documentId: context.params.documentId },
5092
+ populate: ["route"]
5093
+ }));
5094
+ if (((_b = navItem === null || navItem === void 0 ? void 0 : navItem.route) === null || _b === void 0 ? void 0 : _b.type) === "external") {
5095
+ externalRouteDocumentId = navItem.route.documentId;
5096
+ }
5097
+ } catch (err) {
5098
+ strapi2.log.error(err);
4965
5099
  }
4966
- });
4967
- if (!route2?.documentId) return;
4968
- const navItem = await strapi.db?.query(waNavItem).findOne({
4969
- where: {
4970
- route: {
4971
- documentId: route2.documentId
5100
+ const result = await next();
5101
+ if (externalRouteDocumentId) {
5102
+ try {
5103
+ await strapi2.documents(waRoute).delete({ documentId: externalRouteDocumentId });
5104
+ } catch (err) {
5105
+ strapi2.log.error(err);
4972
5106
  }
4973
5107
  }
5108
+ return result;
5109
+ }
5110
+ return next();
5111
+ });
5112
+ }
5113
+ const sanitizeWebatlas = (config2, { strapi: strapi2 }) => {
5114
+ return async (ctx, next) => {
5115
+ await next();
5116
+ if (!ctx.request.url.startsWith("/api/")) {
5117
+ return;
5118
+ }
5119
+ if (!ctx.body || ctx.status !== 200) {
5120
+ return;
5121
+ }
5122
+ const sanitizeWebatlasField = (data) => {
5123
+ if (!data || typeof data !== "object") return data;
5124
+ if (data.webatlas && typeof data.webatlas === "object") {
5125
+ data.webatlas = {
5126
+ path: data.webatlas.path || "",
5127
+ slug: data.webatlas.slug || ""
5128
+ };
5129
+ }
5130
+ return data;
5131
+ };
5132
+ if (ctx.body.data) {
5133
+ if (Array.isArray(ctx.body.data)) {
5134
+ ctx.body.data = ctx.body.data.map(sanitizeWebatlasField);
5135
+ } else {
5136
+ ctx.body.data = sanitizeWebatlasField(ctx.body.data);
5137
+ }
5138
+ } else if (Array.isArray(ctx.body)) {
5139
+ ctx.body = ctx.body.map(sanitizeWebatlasField);
5140
+ } else if (typeof ctx.body === "object") {
5141
+ ctx.body = sanitizeWebatlasField(ctx.body);
5142
+ }
5143
+ };
5144
+ };
5145
+ const middlewares = {
5146
+ sanitizeWebatlas
5147
+ };
5148
+ const bootstrap = async ({ strapi: strapi2 }) => {
5149
+ try {
5150
+ await runMigrations(strapi2);
5151
+ registerPermissions(strapi2);
5152
+ const enabledContentTypes = Object.values(strapi2.contentTypes).filter((type) => {
5153
+ var _a, _b;
5154
+ return ((_b = (_a = type.pluginOptions) === null || _a === void 0 ? void 0 : _a.webatlas) === null || _b === void 0 ? void 0 : _b.enabled) === true;
4974
5155
  });
4975
- await strapi.documents(waRoute).delete({ documentId: route2.documentId });
4976
- if (navItem?.documentId) await strapi.documents(waNavItem).delete({ documentId: navItem.documentId });
4977
- } catch (err) {
4978
- strapi.log.error(err);
5156
+ const config2 = await syncConfig(strapi2, enabledContentTypes);
5157
+ if (!enabledContentTypes.length) return;
5158
+ documentMiddleware(strapi2, enabledContentTypes, config2);
5159
+ webatlasMiddleware(strapi2);
5160
+ strapi2.server.use(middlewares.sanitizeWebatlas({}, { strapi: strapi2 }));
5161
+ } catch (error) {
5162
+ strapi2.log.error(`Bootstrap failed. ${String(error)}`);
4979
5163
  }
4980
- }
5164
+ };
4981
5165
  const destroy = ({ strapi: strapi2 }) => {
4982
5166
  };
4983
5167
  var _freeGlobal;
@@ -5884,7 +6068,9 @@ var setExports = requireSet();
5884
6068
  const set = /* @__PURE__ */ getDefaultExportFromCjs(setExports);
5885
6069
  const register = ({ strapi: strapi2 }) => {
5886
6070
  Object.values(strapi2.contentTypes).forEach((contentType) => {
5887
- if (!contentType.pluginOptions?.webatlas?.enabled) return;
6071
+ var _a, _b;
6072
+ if (!((_b = (_a = contentType.pluginOptions) === null || _a === void 0 ? void 0 : _a.webatlas) === null || _b === void 0 ? void 0 : _b.enabled))
6073
+ return;
5888
6074
  const { attributes } = contentType;
5889
6075
  const fieldSettings = {
5890
6076
  writable: true,
@@ -5893,21 +6079,11 @@ const register = ({ strapi: strapi2 }) => {
5893
6079
  visible: true,
5894
6080
  default: null
5895
6081
  };
5896
- set(attributes, "webatlas_path", {
6082
+ set(attributes, "webatlas", {
5897
6083
  ...fieldSettings,
5898
- type: "string",
6084
+ type: "json",
5899
6085
  private: false
5900
6086
  });
5901
- set(attributes, "webatlas_override", {
5902
- ...fieldSettings,
5903
- type: "boolean",
5904
- private: true
5905
- });
5906
- set(attributes, "webatlas_parent", {
5907
- ...fieldSettings,
5908
- type: "string",
5909
- private: true
5910
- });
5911
6087
  });
5912
6088
  };
5913
6089
  const config = {
@@ -6206,7 +6382,8 @@ const admin$2 = () => ({
6206
6382
  async updateNavigationItemStructure(ctx) {
6207
6383
  try {
6208
6384
  const { navigationId, navigationItems } = ctx.request.body;
6209
- if (!navigationId || !navigationItems) return ctx.throw(400, "NavigationId and Navigation items are required");
6385
+ if (!navigationId || !navigationItems)
6386
+ return ctx.throw(400, "NavigationId and Navigation items are required");
6210
6387
  return await getAdminService().updateNavigationItemStructure(navigationId, navigationItems);
6211
6388
  } catch (e) {
6212
6389
  return ctx.throw(500, e);
@@ -6237,7 +6414,13 @@ const client$2 = ({ strapi: strapi2 }) => ({
6237
6414
  try {
6238
6415
  const { slug, populate, populateDeepDepth, fields, status } = ctx.query;
6239
6416
  if (!slug) return ctx.throw(400, "Slug is required");
6240
- const entity = await getClientService().getEntityByPath(slug, populate, populateDeepDepth, fields, status);
6417
+ const entity = await getClientService().getEntityByPath(
6418
+ slug,
6419
+ populate,
6420
+ populateDeepDepth,
6421
+ fields,
6422
+ status
6423
+ );
6241
6424
  if (!entity) return ctx.throw(404, "Entity not found");
6242
6425
  return ctx.send(entity);
6243
6426
  } catch (e) {
@@ -6246,9 +6429,10 @@ const client$2 = ({ strapi: strapi2 }) => ({
6246
6429
  },
6247
6430
  async getNavigation(ctx) {
6248
6431
  try {
6249
- const { id, name, documentId, variant } = ctx.query;
6250
- if (!id && !name && !documentId) return ctx.throw(400, "Navigation id, name or documentId is required");
6251
- const navigation2 = await getClientService().getNavigation(id, name, documentId, variant);
6432
+ const { id, name, slug, documentId, variant } = ctx.query;
6433
+ if (!id && !name && !slug && !documentId)
6434
+ return ctx.throw(400, "Navigation id, name, slug or documentId is required");
6435
+ const navigation2 = await getClientService().getNavigation(id, name, slug, documentId, variant);
6252
6436
  if (!navigation2) return ctx.throw(404, "Navigation not found");
6253
6437
  return ctx.send(navigation2);
6254
6438
  } catch (e) {
@@ -6260,7 +6444,6 @@ const controllers = {
6260
6444
  admin: admin$2,
6261
6445
  client: client$2
6262
6446
  };
6263
- const middlewares = {};
6264
6447
  const hasPermissions = (policyContext, config2, { strapi: strapi2 }) => {
6265
6448
  const { userAbility, user } = policyContext.state;
6266
6449
  const { action, actions } = config2;
@@ -6337,10 +6520,7 @@ const admin$1 = {
6337
6520
  {
6338
6521
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6339
6522
  config: {
6340
- actions: [
6341
- `plugin::${PLUGIN_ID}.page.routes`,
6342
- `plugin::${PLUGIN_ID}.cm.aside`
6343
- ]
6523
+ actions: [`plugin::${PLUGIN_ID}.page.routes`, `plugin::${PLUGIN_ID}.cm.aside`]
6344
6524
  }
6345
6525
  }
6346
6526
  ]
@@ -6356,10 +6536,7 @@ const admin$1 = {
6356
6536
  {
6357
6537
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6358
6538
  config: {
6359
- actions: [
6360
- `plugin::${PLUGIN_ID}.cm.aside`,
6361
- `plugin::${PLUGIN_ID}.page.navigation`
6362
- ]
6539
+ actions: [`plugin::${PLUGIN_ID}.cm.aside`, `plugin::${PLUGIN_ID}.page.navigation`]
6363
6540
  }
6364
6541
  }
6365
6542
  ]
@@ -6375,9 +6552,7 @@ const admin$1 = {
6375
6552
  {
6376
6553
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6377
6554
  config: {
6378
- actions: [
6379
- `plugin::${PLUGIN_ID}.cm.aside`
6380
- ]
6555
+ actions: [`plugin::${PLUGIN_ID}.cm.aside`]
6381
6556
  }
6382
6557
  }
6383
6558
  ]
@@ -6393,9 +6568,7 @@ const admin$1 = {
6393
6568
  {
6394
6569
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6395
6570
  config: {
6396
- actions: [
6397
- `plugin::${PLUGIN_ID}.page.navigation`
6398
- ]
6571
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6399
6572
  }
6400
6573
  }
6401
6574
  ]
@@ -6412,9 +6585,7 @@ const admin$1 = {
6412
6585
  {
6413
6586
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6414
6587
  config: {
6415
- actions: [
6416
- `plugin::${PLUGIN_ID}.page.navigation`
6417
- ]
6588
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6418
6589
  }
6419
6590
  }
6420
6591
  ]
@@ -6430,9 +6601,7 @@ const admin$1 = {
6430
6601
  {
6431
6602
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6432
6603
  config: {
6433
- actions: [
6434
- `plugin::${PLUGIN_ID}.page.navigation`
6435
- ]
6604
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6436
6605
  }
6437
6606
  }
6438
6607
  ]
@@ -6448,9 +6617,7 @@ const admin$1 = {
6448
6617
  {
6449
6618
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6450
6619
  config: {
6451
- actions: [
6452
- `plugin::${PLUGIN_ID}.page.navigation`
6453
- ]
6620
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6454
6621
  }
6455
6622
  }
6456
6623
  ]
@@ -6466,9 +6633,7 @@ const admin$1 = {
6466
6633
  {
6467
6634
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6468
6635
  config: {
6469
- actions: [
6470
- `plugin::${PLUGIN_ID}.page.navigation`
6471
- ]
6636
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6472
6637
  }
6473
6638
  }
6474
6639
  ]
@@ -6484,9 +6649,7 @@ const admin$1 = {
6484
6649
  {
6485
6650
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6486
6651
  config: {
6487
- actions: [
6488
- `plugin::${PLUGIN_ID}.page.navigation`
6489
- ]
6652
+ actions: [`plugin::${PLUGIN_ID}.page.navigation`]
6490
6653
  }
6491
6654
  }
6492
6655
  ]
@@ -6503,10 +6666,7 @@ const admin$1 = {
6503
6666
  {
6504
6667
  name: `plugin::${PLUGIN_ID}.has-permissions`,
6505
6668
  config: {
6506
- actions: [
6507
- `plugin::${PLUGIN_ID}.cm.aside`,
6508
- `plugin::${PLUGIN_ID}.page.navigation`
6509
- ]
6669
+ actions: [`plugin::${PLUGIN_ID}.cm.aside`, `plugin::${PLUGIN_ID}.page.navigation`]
6510
6670
  }
6511
6671
  }
6512
6672
  ]
@@ -6544,7 +6704,10 @@ const admin = ({ strapi: strapi2 }) => ({
6544
6704
  if (!newConfig) return;
6545
6705
  let newConfigMerged;
6546
6706
  try {
6547
- const pluginStore = await strapi2.store({ type: "plugin", name: PLUGIN_ID });
6707
+ const pluginStore = await strapi2.store({
6708
+ type: "plugin",
6709
+ name: PLUGIN_ID
6710
+ });
6548
6711
  const config2 = await pluginStore.get({ key: "config" });
6549
6712
  newConfigMerged = { ...config2, ...newConfig };
6550
6713
  await pluginStore.set({ key: "config", value: newConfigMerged });
@@ -6565,7 +6728,7 @@ const admin = ({ strapi: strapi2 }) => ({
6565
6728
  ...config2,
6566
6729
  navigation: {
6567
6730
  ...defaultConfig.navigation,
6568
- ...config2?.navigation
6731
+ ...config2 === null || config2 === void 0 ? void 0 : config2.navigation
6569
6732
  }
6570
6733
  };
6571
6734
  return config2;
@@ -6588,13 +6751,14 @@ const admin = ({ strapi: strapi2 }) => ({
6588
6751
  }
6589
6752
  },
6590
6753
  async getRelatedRoute(documentId) {
6754
+ var _a;
6591
6755
  try {
6592
- return await strapi2.db?.query(waRoute).findOne({
6756
+ return await ((_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waRoute).findOne({
6593
6757
  where: {
6594
6758
  relatedDocumentId: documentId
6595
6759
  },
6596
6760
  populate: ["parent"]
6597
- });
6761
+ }));
6598
6762
  } catch (e) {
6599
6763
  strapi2.log.error(e);
6600
6764
  }
@@ -6607,10 +6771,10 @@ const admin = ({ strapi: strapi2 }) => ({
6607
6771
  documentId
6608
6772
  });
6609
6773
  }
6610
- const descendants = route2?.documentId ? await getRouteDescendants(route2.documentId) : [];
6774
+ const descendants = (route2 === null || route2 === void 0 ? void 0 : route2.documentId) ? await getRouteDescendants(route2.documentId) : [];
6611
6775
  const nonInternalRouteIds = await getNonInternalRouteIds();
6612
6776
  const prohibitedRouteIds = [...descendants, ...nonInternalRouteIds];
6613
- route2?.documentId && prohibitedRouteIds.push(route2.documentId);
6777
+ (route2 === null || route2 === void 0 ? void 0 : route2.documentId) && prohibitedRouteIds.push(route2.documentId);
6614
6778
  return prohibitedRouteIds;
6615
6779
  } catch (e) {
6616
6780
  strapi2.log.error(e);
@@ -6636,8 +6800,7 @@ const admin = ({ strapi: strapi2 }) => ({
6636
6800
  populate: ["items", "items.route", "items.parent"]
6637
6801
  });
6638
6802
  if (!navigation2) throw new Error("Navigation not found");
6639
- if (variant)
6640
- navigation2 = buildStructuredNavigation(navigation2, variant);
6803
+ if (variant) navigation2 = buildStructuredNavigation(navigation2, variant);
6641
6804
  } else {
6642
6805
  navigation2 = await strapi2.documents(waNavigation).findMany({
6643
6806
  populate: ["items", "items.route", "items.parent"]
@@ -6752,22 +6915,24 @@ const client = ({ strapi: strapi2 }) => ({
6752
6915
  try {
6753
6916
  const route2 = await strapi2.documents(waRoute).findFirst({
6754
6917
  filters: {
6755
- $or: [
6756
- { path: slug },
6757
- { canonicalPath: slug },
6758
- { uidPath: slug }
6759
- ]
6918
+ $or: [{ path: slug }, { canonicalPath: slug }, { uidPath: slug }]
6760
6919
  }
6761
6920
  });
6762
6921
  if (!route2) return null;
6763
6922
  let populateObject = populate;
6764
6923
  if (populate === "deep") {
6765
- const modelObject = getFullPopulateObject(route2.relatedContentType, Number(populateDeepDepth), []);
6924
+ const modelObject = getFullPopulateObject(
6925
+ route2.relatedContentType,
6926
+ Number(populateDeepDepth),
6927
+ []
6928
+ );
6766
6929
  if (typeof modelObject === "object" && "populate" in modelObject) {
6767
6930
  populateObject = modelObject.populate;
6768
6931
  }
6769
6932
  }
6770
- const contentTypeObject = Object.entries(strapi2.contentTypes).find(([key, value]) => key === route2.relatedContentType);
6933
+ const contentTypeObject = Object.entries(strapi2.contentTypes).find(
6934
+ ([key, value]) => key === route2.relatedContentType
6935
+ );
6771
6936
  if (!contentTypeObject) {
6772
6937
  return null;
6773
6938
  }
@@ -6799,32 +6964,50 @@ const client = ({ strapi: strapi2 }) => ({
6799
6964
  return e;
6800
6965
  }
6801
6966
  },
6802
- async getNavigation(id, name, documentId, variant = "nested") {
6967
+ async getNavigation(id, name, slug, documentId, variant = "nested") {
6803
6968
  try {
6804
6969
  let navigation2 = null;
6970
+ const populateObject = ["items", "items.parent", "items.route"];
6805
6971
  const lookupMethods = [
6806
6972
  {
6807
6973
  condition: documentId,
6808
6974
  lookup: () => strapi2.documents(waNavigation).findOne({
6809
6975
  documentId,
6810
- populate: ["items", "items.parent", "items.route"]
6976
+ populate: populateObject
6811
6977
  }),
6812
6978
  name: "documentId"
6813
6979
  },
6980
+ {
6981
+ condition: slug,
6982
+ lookup: () => {
6983
+ var _a;
6984
+ return (_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waNavigation).findOne({
6985
+ where: { slug },
6986
+ populate: populateObject
6987
+ });
6988
+ },
6989
+ name: "slug"
6990
+ },
6814
6991
  {
6815
6992
  condition: name,
6816
- lookup: () => strapi2.db?.query(waNavigation).findOne({
6817
- where: { name },
6818
- populate: ["items", "items.parent", "items.route"]
6819
- }),
6993
+ lookup: () => {
6994
+ var _a;
6995
+ return (_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waNavigation).findOne({
6996
+ where: { name },
6997
+ populate: populateObject
6998
+ });
6999
+ },
6820
7000
  name: "name"
6821
7001
  },
6822
7002
  {
6823
7003
  condition: id,
6824
- lookup: () => strapi2.db?.query(waNavigation).findOne({
6825
- where: { id },
6826
- populate: ["items", "items.parent", "items.route"]
6827
- }),
7004
+ lookup: () => {
7005
+ var _a;
7006
+ return (_a = strapi2.db) === null || _a === void 0 ? void 0 : _a.query(waNavigation).findOne({
7007
+ where: { id },
7008
+ populate: populateObject
7009
+ });
7010
+ },
6828
7011
  name: "id"
6829
7012
  }
6830
7013
  ];
@@ -6865,3 +7048,4 @@ const index = {
6865
7048
  middlewares
6866
7049
  };
6867
7050
  exports.default = index;
7051
+ //# sourceMappingURL=index.js.map