@mattisvensson/strapi-plugin-webatlas 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/admin/FullLoader-Cmsf8xS6.js +1 -0
- package/dist/admin/FullLoader-Cmsf8xS6.js.map +1 -0
- package/dist/admin/FullLoader-CrPED_dY.mjs +1 -0
- package/dist/admin/FullLoader-CrPED_dY.mjs.map +1 -0
- package/dist/admin/{SettingTitle-DbsxB1V9.mjs → SettingTitle-B1IaU3qs.mjs} +2 -1
- package/dist/admin/SettingTitle-B1IaU3qs.mjs.map +1 -0
- package/dist/admin/{SettingTitle-uw1S5OmC.js → SettingTitle-BjE_2u6R.js} +2 -1
- package/dist/admin/SettingTitle-BjE_2u6R.js.map +1 -0
- package/dist/admin/de-B5pRvs13.mjs +1 -0
- package/dist/admin/de-B5pRvs13.mjs.map +1 -0
- package/dist/admin/de-CqU1FU8C.js +1 -0
- package/dist/admin/de-CqU1FU8C.js.map +1 -0
- package/dist/admin/en-BE-zzIv8.mjs +1 -0
- package/dist/admin/en-BE-zzIv8.mjs.map +1 -0
- package/dist/admin/en-C7I90FwV.js +1 -0
- package/dist/admin/en-C7I90FwV.js.map +1 -0
- package/dist/admin/{index-BXt-QjKo.js → index-AVI3QJ0R.js} +2 -1
- package/dist/admin/index-AVI3QJ0R.js.map +1 -0
- package/dist/admin/{index-CGsC8P9P.js → index-B90eSO4a.js} +3 -2
- package/dist/admin/index-B90eSO4a.js.map +1 -0
- package/dist/admin/{index-tPrfjOIn.mjs → index-BIEUXWe7.mjs} +2 -1
- package/dist/admin/index-BIEUXWe7.mjs.map +1 -0
- package/dist/admin/{index-CUaBX_v-.mjs → index-BbnlyBrZ.mjs} +3 -2
- package/dist/admin/index-BbnlyBrZ.mjs.map +1 -0
- package/dist/admin/{index-BKWY9Ta-.mjs → index-Cf9j0bn2.mjs} +2 -1
- package/dist/admin/index-Cf9j0bn2.mjs.map +1 -0
- package/dist/admin/{index-BYlmJycd.js → index-D8bG0YFB.js} +3 -2
- package/dist/admin/index-D8bG0YFB.js.map +1 -0
- package/dist/admin/{index-CIr8o1RP.mjs → index-DCYCtKrj.mjs} +118 -106
- package/dist/admin/index-DCYCtKrj.mjs.map +1 -0
- package/dist/admin/{index-DkqiqVx2.js → index-JLpXBQVL.js} +2 -1
- package/dist/admin/index-JLpXBQVL.js.map +1 -0
- package/dist/admin/{index-B07KlG03.mjs → index-Y_PYIiRA.mjs} +3 -2
- package/dist/admin/index-Y_PYIiRA.mjs.map +1 -0
- package/dist/admin/{index-DC5WwNdi.js → index-Yq-QR8t0.js} +118 -106
- package/dist/admin/index-Yq-QR8t0.js.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +2 -1
- package/dist/admin/index.mjs.map +1 -0
- package/dist/server/index.js +384 -259
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +384 -259
- package/dist/server/index.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/admin/src/index.d.ts +0 -12
- package/dist/server/src/index.d.ts +0 -301
package/dist/server/index.js
CHANGED
|
@@ -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
5
|
"ü": "ue",
|
|
6
6
|
"ä": "ae",
|
|
7
|
-
"ö": "oe"
|
|
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
|
-
|
|
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,28 @@ 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,
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return entities?.length > 0;
|
|
40
|
+
async function checkPathExists(path, excludeDocumentId) {
|
|
41
|
+
const filters = {
|
|
42
|
+
$or: [
|
|
43
|
+
{ path },
|
|
44
|
+
{ uidPath: path },
|
|
45
|
+
{ canonicalPath: path }
|
|
46
|
+
]
|
|
47
|
+
};
|
|
48
|
+
if (excludeDocumentId) {
|
|
49
|
+
filters.documentId = { $ne: excludeDocumentId };
|
|
50
|
+
}
|
|
51
|
+
const entity = await strapi.documents(waRoute).findFirst({ filters });
|
|
52
|
+
return !!entity;
|
|
47
53
|
}
|
|
48
54
|
async function duplicateCheck(initialPath, targetRouteDocumentId) {
|
|
49
55
|
try {
|
|
50
56
|
let uniquePath = initialPath;
|
|
51
|
-
let targetRoutePath = null;
|
|
52
57
|
let counter = 1;
|
|
53
|
-
|
|
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);
|
|
58
|
+
let exists = await checkPathExists(uniquePath, targetRouteDocumentId);
|
|
60
59
|
while (exists) {
|
|
61
60
|
uniquePath = `${initialPath}-${counter}`;
|
|
62
|
-
exists = await checkPathExists(uniquePath);
|
|
61
|
+
exists = await checkPathExists(uniquePath, targetRouteDocumentId);
|
|
63
62
|
counter++;
|
|
64
63
|
}
|
|
65
64
|
return uniquePath;
|
|
@@ -251,12 +250,14 @@ function extractRouteAndItems(items) {
|
|
|
251
250
|
return items.map((item) => {
|
|
252
251
|
const route2 = { ...item.route };
|
|
253
252
|
if (!route2) return null;
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
let depth = null;
|
|
254
|
+
if (item.depth !== void 0) {
|
|
255
|
+
depth = item.depth;
|
|
256
256
|
}
|
|
257
|
+
let children = null;
|
|
257
258
|
if (item.items?.length > 0) {
|
|
258
259
|
const items2 = extractRouteAndItems(item.items);
|
|
259
|
-
if (items2.length > 0)
|
|
260
|
+
if (items2.length > 0) children = items2;
|
|
260
261
|
}
|
|
261
262
|
delete route2.relatedContentType;
|
|
262
263
|
delete route2.relatedDocumentId;
|
|
@@ -267,7 +268,9 @@ function extractRouteAndItems(items) {
|
|
|
267
268
|
return {
|
|
268
269
|
__component: route2.type === "wrapper" ? `${PLUGIN_ID}.wrapper` : `${PLUGIN_ID}.route`,
|
|
269
270
|
type: route2.type,
|
|
270
|
-
...route2
|
|
271
|
+
...route2,
|
|
272
|
+
depth: depth !== null ? depth : void 0,
|
|
273
|
+
items: children !== null ? children : void 0
|
|
271
274
|
};
|
|
272
275
|
});
|
|
273
276
|
}
|
|
@@ -4318,6 +4321,7 @@ function removeWaFields(obj) {
|
|
|
4318
4321
|
delete obj["webatlas_path"];
|
|
4319
4322
|
delete obj["webatlas_override"];
|
|
4320
4323
|
delete obj["webatlas_parent"];
|
|
4324
|
+
delete obj["webatlas"];
|
|
4321
4325
|
return obj;
|
|
4322
4326
|
}
|
|
4323
4327
|
async function buildCanonicalPath(slug, parentDocumentId) {
|
|
@@ -4333,26 +4337,55 @@ async function buildCanonicalPath(slug, parentDocumentId) {
|
|
|
4333
4337
|
return slug;
|
|
4334
4338
|
}
|
|
4335
4339
|
}
|
|
4336
|
-
async function
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4340
|
+
async function cascadePathUpdates({
|
|
4341
|
+
validatedParentPath,
|
|
4342
|
+
parentRouteDocumentId,
|
|
4343
|
+
canonicalPath,
|
|
4344
|
+
isOverride
|
|
4345
|
+
}) {
|
|
4346
|
+
try {
|
|
4347
|
+
const children = await strapi.db.query(waRoute).findMany({
|
|
4348
|
+
where: {
|
|
4349
|
+
parent: {
|
|
4350
|
+
documentId: parentRouteDocumentId
|
|
4351
|
+
}
|
|
4341
4352
|
}
|
|
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
4353
|
});
|
|
4355
|
-
|
|
4354
|
+
for (const child of children) {
|
|
4355
|
+
const newCanonicalPath = `${canonicalPath}/${child.slug}`;
|
|
4356
|
+
const newPath = isOverride ? `${validatedParentPath}/${child.slug}` : newCanonicalPath;
|
|
4357
|
+
const validatedCanonicalPath = await duplicateCheck(newCanonicalPath, child.documentId);
|
|
4358
|
+
const validatedPath = isOverride ? await duplicateCheck(newPath, child.documentId) : validatedCanonicalPath;
|
|
4359
|
+
await strapi.db.query(waRoute).updateMany({
|
|
4360
|
+
where: { documentId: child.documentId },
|
|
4361
|
+
data: {
|
|
4362
|
+
canonicalPath: validatedCanonicalPath,
|
|
4363
|
+
path: validatedPath
|
|
4364
|
+
}
|
|
4365
|
+
});
|
|
4366
|
+
const existingEntry = await strapi.db.query(child.relatedContentType).findOne({
|
|
4367
|
+
where: { documentId: child.relatedDocumentId }
|
|
4368
|
+
});
|
|
4369
|
+
if (existingEntry) {
|
|
4370
|
+
await strapi.db.query(child.relatedContentType).updateMany({
|
|
4371
|
+
where: { documentId: child.relatedDocumentId },
|
|
4372
|
+
data: {
|
|
4373
|
+
webatlas: {
|
|
4374
|
+
...existingEntry.webatlas,
|
|
4375
|
+
path: validatedPath
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
4380
|
+
await cascadePathUpdates({
|
|
4381
|
+
validatedParentPath: validatedPath,
|
|
4382
|
+
parentRouteDocumentId: child.documentId,
|
|
4383
|
+
canonicalPath: validatedCanonicalPath,
|
|
4384
|
+
isOverride
|
|
4385
|
+
});
|
|
4386
|
+
}
|
|
4387
|
+
} catch (err) {
|
|
4388
|
+
strapi.log.error(err);
|
|
4356
4389
|
}
|
|
4357
4390
|
}
|
|
4358
4391
|
async function getRouteDescendants(routeId) {
|
|
@@ -4679,8 +4712,66 @@ const migration_001_canonical_path = {
|
|
|
4679
4712
|
}
|
|
4680
4713
|
}
|
|
4681
4714
|
};
|
|
4715
|
+
const migration_002_webatlas_json_field = {
|
|
4716
|
+
version: "002",
|
|
4717
|
+
description: "Migrate webatlas_path, webatlas_parent and webatlas_override text fields into the webatlas JSON field",
|
|
4718
|
+
async up(strapi2) {
|
|
4719
|
+
const knex = strapi2.db.connection;
|
|
4720
|
+
const enabledContentTypes = Object.values(strapi2.contentTypes).filter(
|
|
4721
|
+
(ct) => ct.pluginOptions?.webatlas?.enabled === true
|
|
4722
|
+
);
|
|
4723
|
+
for (const contentType of enabledContentTypes) {
|
|
4724
|
+
const tableName = strapi2.db.metadata.get(contentType.uid)?.tableName ?? contentType.collectionName;
|
|
4725
|
+
strapi2.log.info(`[webatlas] Processing table: ${tableName} (${contentType.uid})`);
|
|
4726
|
+
const [hasPathCol, hasOverrideCol, hasParentCol, hasWebatlasCol] = await Promise.all([
|
|
4727
|
+
knex.schema.hasColumn(tableName, "webatlas_path"),
|
|
4728
|
+
knex.schema.hasColumn(tableName, "webatlas_override"),
|
|
4729
|
+
knex.schema.hasColumn(tableName, "webatlas_parent"),
|
|
4730
|
+
knex.schema.hasColumn(tableName, "webatlas")
|
|
4731
|
+
]);
|
|
4732
|
+
const hasAnyOldCol = hasPathCol || hasOverrideCol || hasParentCol;
|
|
4733
|
+
if (!hasAnyOldCol) {
|
|
4734
|
+
strapi2.log.info(`[webatlas] No old fields found in ${tableName}, skipping data migration`);
|
|
4735
|
+
} else if (!hasWebatlasCol) {
|
|
4736
|
+
strapi2.log.warn(`[webatlas] New "webatlas" column not found in ${tableName} — schema may not have synced yet. Skipping data migration, old columns will still be dropped.`);
|
|
4737
|
+
} else {
|
|
4738
|
+
const selectCols = ["id"];
|
|
4739
|
+
if (hasPathCol) selectCols.push("webatlas_path");
|
|
4740
|
+
if (hasOverrideCol) selectCols.push("webatlas_override");
|
|
4741
|
+
if (hasParentCol) selectCols.push("webatlas_parent");
|
|
4742
|
+
const rows = await knex(tableName).select(selectCols);
|
|
4743
|
+
let migratedCount = 0;
|
|
4744
|
+
for (const row of rows) {
|
|
4745
|
+
const path = row.webatlas_path || "";
|
|
4746
|
+
const isOverride = Boolean(row.webatlas_override);
|
|
4747
|
+
const parentDocumentId = row.webatlas_parent || null;
|
|
4748
|
+
if (!path && !isOverride && !parentDocumentId) continue;
|
|
4749
|
+
const slug = path ? path.split("/").pop() || "" : "";
|
|
4750
|
+
await knex(tableName).where({ id: row.id }).update({
|
|
4751
|
+
webatlas: JSON.stringify({ path, slug, isOverride, parentDocumentId })
|
|
4752
|
+
});
|
|
4753
|
+
migratedCount++;
|
|
4754
|
+
}
|
|
4755
|
+
strapi2.log.info(`[webatlas] Migrated ${migratedCount} / ${rows.length} rows in ${tableName}`);
|
|
4756
|
+
}
|
|
4757
|
+
const colsToDrop = [
|
|
4758
|
+
hasPathCol && "webatlas_path",
|
|
4759
|
+
hasOverrideCol && "webatlas_override",
|
|
4760
|
+
hasParentCol && "webatlas_parent"
|
|
4761
|
+
].filter(Boolean);
|
|
4762
|
+
if (colsToDrop.length > 0) {
|
|
4763
|
+
await knex.schema.table(tableName, (table) => {
|
|
4764
|
+
colsToDrop.forEach((col) => table.dropColumn(col));
|
|
4765
|
+
});
|
|
4766
|
+
strapi2.log.info(`[webatlas] Dropped columns [${colsToDrop.join(", ")}] from ${tableName}`);
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
strapi2.log.info("[webatlas] webatlas JSON field migration completed");
|
|
4770
|
+
}
|
|
4771
|
+
};
|
|
4682
4772
|
const migrations = [
|
|
4683
|
-
migration_001_canonical_path
|
|
4773
|
+
migration_001_canonical_path,
|
|
4774
|
+
migration_002_webatlas_json_field
|
|
4684
4775
|
];
|
|
4685
4776
|
const runMigrations = async (strapi2) => {
|
|
4686
4777
|
const pluginStore = strapi2.store({ type: "plugin", name: PLUGIN_ID });
|
|
@@ -4714,54 +4805,47 @@ const runMigrations = async (strapi2) => {
|
|
|
4714
4805
|
}
|
|
4715
4806
|
strapi2.log.info("[webatlas] All migrations completed successfully");
|
|
4716
4807
|
};
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
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
|
-
);
|
|
4808
|
+
function registerPermissions(strapi2) {
|
|
4809
|
+
const actions = [
|
|
4810
|
+
{
|
|
4811
|
+
section: "plugins",
|
|
4812
|
+
displayName: "Navigation page",
|
|
4813
|
+
uid: "page.navigation",
|
|
4814
|
+
subCategory: "Pages",
|
|
4815
|
+
pluginName: PLUGIN_ID
|
|
4816
|
+
},
|
|
4817
|
+
{
|
|
4818
|
+
section: "plugins",
|
|
4819
|
+
displayName: "Routes page",
|
|
4820
|
+
uid: "page.routes",
|
|
4821
|
+
subCategory: "Pages",
|
|
4822
|
+
pluginName: PLUGIN_ID
|
|
4823
|
+
},
|
|
4824
|
+
{
|
|
4825
|
+
section: "plugins",
|
|
4826
|
+
displayName: "General page",
|
|
4827
|
+
uid: "settings.general",
|
|
4828
|
+
subCategory: "Settings",
|
|
4829
|
+
pluginName: PLUGIN_ID
|
|
4830
|
+
},
|
|
4831
|
+
{
|
|
4832
|
+
section: "plugins",
|
|
4833
|
+
displayName: "Navigation page",
|
|
4834
|
+
uid: "settings.navigation",
|
|
4835
|
+
subCategory: "Settings",
|
|
4836
|
+
pluginName: PLUGIN_ID
|
|
4837
|
+
},
|
|
4838
|
+
{
|
|
4839
|
+
section: "plugins",
|
|
4840
|
+
displayName: "Aside panel",
|
|
4841
|
+
uid: "cm.aside",
|
|
4842
|
+
subCategory: "Content Manager",
|
|
4843
|
+
pluginName: PLUGIN_ID
|
|
4844
|
+
}
|
|
4845
|
+
];
|
|
4846
|
+
strapi2.admin.services.permission.actionProvider.registerMany(actions);
|
|
4847
|
+
}
|
|
4848
|
+
async function syncConfig(strapi2, enabledContentTypes) {
|
|
4765
4849
|
const pluginStore = strapi2.store({ type: "plugin", name: PLUGIN_ID });
|
|
4766
4850
|
const config2 = await pluginStore.get({
|
|
4767
4851
|
key: "config"
|
|
@@ -4786,140 +4870,117 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
4786
4870
|
if (JSON.stringify(newConfig) !== JSON.stringify(config2)) {
|
|
4787
4871
|
await pluginStore.set({ key: "config", value: newConfig });
|
|
4788
4872
|
}
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
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
|
-
}
|
|
4873
|
+
return newConfig;
|
|
4874
|
+
}
|
|
4875
|
+
function documentMiddleware(strapi2, enabledContentTypes, config2) {
|
|
4876
|
+
const actions = ["create", "update", "delete"];
|
|
4877
|
+
strapi2.documents.use(async (context, next) => {
|
|
4878
|
+
if (!enabledContentTypes.map((type) => type.uid).includes(context.uid) || !actions.includes(context.action)) {
|
|
4879
|
+
return next();
|
|
4821
4880
|
}
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
const
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
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
|
-
}
|
|
4881
|
+
const ctSettings = config2.selectedContentTypes.find((ct) => ct.uid === context.uid);
|
|
4882
|
+
if (context.action === "create") {
|
|
4883
|
+
const data = context.params.data;
|
|
4884
|
+
const { webatlas } = data;
|
|
4885
|
+
const { slug, parentDocumentId, isOverride } = webatlas || {};
|
|
4886
|
+
const transformedSlug = slug ? transformToUrl(slug) : null;
|
|
4887
|
+
if (transformedSlug) {
|
|
4888
|
+
data.webatlas.slug = transformedSlug;
|
|
4889
|
+
}
|
|
4890
|
+
const result2 = await next();
|
|
4891
|
+
if (!transformedSlug) return result2;
|
|
4892
|
+
const existing = await strapi2.db?.query(waRoute).findOne({
|
|
4893
|
+
where: { relatedDocumentId: result2.documentId }
|
|
4841
4894
|
});
|
|
4842
|
-
if (
|
|
4895
|
+
if (existing) return result2;
|
|
4843
4896
|
let parent = null;
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4897
|
+
let isValid = false;
|
|
4898
|
+
if (parentDocumentId) {
|
|
4899
|
+
isValid = await validateRouteDependencies({ newParentId: parentDocumentId });
|
|
4900
|
+
if (isValid) {
|
|
4901
|
+
parent = await strapi2.documents(waRoute).findOne({
|
|
4902
|
+
documentId: parentDocumentId
|
|
4848
4903
|
});
|
|
4849
|
-
if (isValid) parent = webatlas_parent;
|
|
4850
|
-
} catch (err) {
|
|
4851
|
-
strapi2.log.error(`Route dependency validation failed: ${err.message}`);
|
|
4852
4904
|
}
|
|
4853
4905
|
}
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
const
|
|
4906
|
+
let rawPath = transformedSlug;
|
|
4907
|
+
if (!isOverride) rawPath = parent ? `${parent.path}/${transformedSlug}` : transformedSlug;
|
|
4908
|
+
const validatedPath = await duplicateCheck(rawPath);
|
|
4909
|
+
if (!validatedPath) throw new Error(`Failed to generate a unique path for slug: ${transformedSlug}`);
|
|
4910
|
+
const singularName = context.contentType.info.singularName;
|
|
4911
|
+
const title = context.params.data[ctSettings?.default]?.trim() || transformedSlug;
|
|
4912
|
+
const canonicalPath = await buildCanonicalPath(transformToUrl(title), isValid ? parent.documentId : null);
|
|
4857
4913
|
await strapi2.documents(waRoute).create({
|
|
4858
4914
|
data: {
|
|
4859
|
-
relatedContentType:
|
|
4860
|
-
relatedId:
|
|
4861
|
-
relatedDocumentId:
|
|
4862
|
-
slug:
|
|
4863
|
-
path,
|
|
4864
|
-
uidPath: `${
|
|
4865
|
-
isOverride:
|
|
4915
|
+
relatedContentType: context.uid,
|
|
4916
|
+
relatedId: result2.id,
|
|
4917
|
+
relatedDocumentId: result2.documentId,
|
|
4918
|
+
slug: transformedSlug,
|
|
4919
|
+
path: validatedPath,
|
|
4920
|
+
uidPath: `${singularName}/${result2.id}`,
|
|
4921
|
+
isOverride: isOverride || false,
|
|
4866
4922
|
title,
|
|
4867
|
-
parent,
|
|
4923
|
+
parent: isValid ? parent?.documentId : null,
|
|
4868
4924
|
canonicalPath
|
|
4869
4925
|
}
|
|
4870
4926
|
});
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
} =
|
|
4880
|
-
|
|
4927
|
+
await strapi2.db?.query(context.uid).updateMany({
|
|
4928
|
+
where: { documentId: result2.documentId },
|
|
4929
|
+
data: { webatlas: { ...webatlas, slug: transformedSlug, path: validatedPath, parentDocumentId: isValid ? parent?.documentId : null } }
|
|
4930
|
+
});
|
|
4931
|
+
return result2;
|
|
4932
|
+
}
|
|
4933
|
+
if (context.action === "update") {
|
|
4934
|
+
const data = context.params.data;
|
|
4935
|
+
const { documentId } = context.params;
|
|
4936
|
+
const { webatlas } = data;
|
|
4937
|
+
const { slug, parentDocumentId, isOverride } = webatlas || {};
|
|
4938
|
+
if (!slug) return;
|
|
4881
4939
|
const relatedRoute = await strapi2.documents(waRoute).findFirst({
|
|
4882
4940
|
filters: {
|
|
4883
4941
|
relatedDocumentId: documentId
|
|
4884
4942
|
}
|
|
4885
4943
|
});
|
|
4886
4944
|
let parent = null;
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4945
|
+
let isValid = false;
|
|
4946
|
+
if (parentDocumentId) {
|
|
4947
|
+
isValid = await validateRouteDependencies({
|
|
4948
|
+
routeId: relatedRoute ? relatedRoute.documentId : null,
|
|
4949
|
+
newParentId: parentDocumentId
|
|
4950
|
+
});
|
|
4951
|
+
if (isValid) {
|
|
4952
|
+
parent = await strapi2.documents(waRoute).findOne({
|
|
4953
|
+
documentId: parentDocumentId
|
|
4892
4954
|
});
|
|
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
4955
|
}
|
|
4901
4956
|
}
|
|
4902
|
-
const
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
const
|
|
4906
|
-
|
|
4957
|
+
const transformedSlug = transformToUrl(slug);
|
|
4958
|
+
let rawPath = transformedSlug;
|
|
4959
|
+
if (!isOverride) rawPath = parent ? `${parent.path}/${transformedSlug}` : transformedSlug;
|
|
4960
|
+
const validatedPath = await duplicateCheck(rawPath, relatedRoute?.documentId ?? null);
|
|
4961
|
+
data.webatlas.path = validatedPath;
|
|
4962
|
+
data.webatlas.slug = transformedSlug;
|
|
4963
|
+
if (relatedRoute) data.relatedRoute = relatedRoute;
|
|
4964
|
+
if (!isValid && parentDocumentId) data.webatlas.parent = null;
|
|
4965
|
+
const result2 = await next();
|
|
4966
|
+
const title = context.params.data[ctSettings?.default]?.trim() || slug;
|
|
4967
|
+
const canonicalPath = isOverride ? relatedRoute.path : await buildCanonicalPath(transformToUrl(title), parent?.documentId);
|
|
4907
4968
|
const routeData = {
|
|
4908
4969
|
title,
|
|
4909
|
-
path,
|
|
4910
|
-
slug
|
|
4911
|
-
isOverride:
|
|
4912
|
-
parent: parent?.documentId || null
|
|
4970
|
+
path: validatedPath,
|
|
4971
|
+
slug,
|
|
4972
|
+
isOverride: isOverride || false,
|
|
4973
|
+
parent: parent?.documentId || null,
|
|
4974
|
+
canonicalPath
|
|
4913
4975
|
};
|
|
4914
4976
|
let routeDocumentId = relatedRoute?.documentId;
|
|
4915
4977
|
if (!relatedRoute) {
|
|
4916
4978
|
const createdRoute = await strapi2.documents(waRoute).create({
|
|
4917
4979
|
data: {
|
|
4918
|
-
relatedContentType:
|
|
4919
|
-
relatedId:
|
|
4920
|
-
relatedDocumentId:
|
|
4921
|
-
uidPath: `${
|
|
4922
|
-
canonicalPath,
|
|
4980
|
+
relatedContentType: context.uid,
|
|
4981
|
+
relatedId: result2.id,
|
|
4982
|
+
relatedDocumentId: result2.documentId,
|
|
4983
|
+
uidPath: `${context.contentType.info.singularName}/${result2.id}`,
|
|
4923
4984
|
...routeData
|
|
4924
4985
|
}
|
|
4925
4986
|
});
|
|
@@ -4927,57 +4988,121 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
4927
4988
|
} else {
|
|
4928
4989
|
await strapi2.documents(waRoute).update({
|
|
4929
4990
|
documentId: relatedRoute.documentId,
|
|
4930
|
-
data:
|
|
4931
|
-
...routeData,
|
|
4932
|
-
canonicalPath
|
|
4933
|
-
}
|
|
4991
|
+
data: routeData
|
|
4934
4992
|
});
|
|
4935
4993
|
}
|
|
4936
4994
|
if (routeDocumentId) {
|
|
4937
|
-
await
|
|
4995
|
+
await cascadePathUpdates({
|
|
4996
|
+
validatedParentPath: validatedPath,
|
|
4997
|
+
parentRouteDocumentId: routeDocumentId,
|
|
4998
|
+
canonicalPath,
|
|
4999
|
+
isOverride
|
|
5000
|
+
});
|
|
4938
5001
|
}
|
|
4939
|
-
}
|
|
4940
|
-
|
|
5002
|
+
}
|
|
5003
|
+
if (context.action === "delete") {
|
|
5004
|
+
const result2 = await next();
|
|
4941
5005
|
try {
|
|
4942
|
-
|
|
5006
|
+
const relatedDocumentId = context.params.documentId;
|
|
5007
|
+
const deletedRoute = await strapi2.db.query(waRoute).delete({
|
|
5008
|
+
where: { relatedDocumentId },
|
|
5009
|
+
populate: ["navitem"]
|
|
5010
|
+
});
|
|
5011
|
+
if (!deletedRoute?.documentId) return result2;
|
|
5012
|
+
const navItemDocumentIds = Array.from(deletedRoute.navitem?.map((item) => item.documentId));
|
|
5013
|
+
for (const navItemDocumentId of navItemDocumentIds) {
|
|
5014
|
+
await strapi2.documents(waNavItem).delete({ documentId: navItemDocumentId });
|
|
5015
|
+
}
|
|
4943
5016
|
} catch (err) {
|
|
4944
5017
|
strapi2.log.error(err);
|
|
4945
5018
|
}
|
|
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
|
-
});
|
|
5019
|
+
return result2;
|
|
4955
5020
|
}
|
|
5021
|
+
const result = await next();
|
|
5022
|
+
return result;
|
|
4956
5023
|
});
|
|
4957
|
-
}
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
5024
|
+
}
|
|
5025
|
+
function webatlasMiddleware(strapi2) {
|
|
5026
|
+
strapi2.documents.use(async (context, next) => {
|
|
5027
|
+
if (context.uid !== waNavItem) return next();
|
|
5028
|
+
if (context.action === "delete") {
|
|
5029
|
+
let externalRouteDocumentId = null;
|
|
5030
|
+
try {
|
|
5031
|
+
const navItem = await strapi2.db?.query(waNavItem).findOne({
|
|
5032
|
+
where: { documentId: context.params.documentId },
|
|
5033
|
+
populate: ["route"]
|
|
5034
|
+
});
|
|
5035
|
+
if (navItem?.route?.type === "external") {
|
|
5036
|
+
externalRouteDocumentId = navItem.route.documentId;
|
|
5037
|
+
}
|
|
5038
|
+
} catch (err) {
|
|
5039
|
+
strapi2.log.error(err);
|
|
4965
5040
|
}
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
5041
|
+
const result = await next();
|
|
5042
|
+
if (externalRouteDocumentId) {
|
|
5043
|
+
try {
|
|
5044
|
+
await strapi2.documents(waRoute).delete({ documentId: externalRouteDocumentId });
|
|
5045
|
+
} catch (err) {
|
|
5046
|
+
strapi2.log.error(err);
|
|
4972
5047
|
}
|
|
4973
5048
|
}
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
}
|
|
4978
|
-
|
|
4979
|
-
|
|
5049
|
+
return result;
|
|
5050
|
+
}
|
|
5051
|
+
return next();
|
|
5052
|
+
});
|
|
5053
|
+
}
|
|
5054
|
+
function contentTypeMiddleware(strapi2) {
|
|
5055
|
+
strapi2.documents.use(async (context, next) => {
|
|
5056
|
+
const pluginOptions = context.contentType?.pluginOptions;
|
|
5057
|
+
if (!pluginOptions?.webatlas?.enabled) {
|
|
5058
|
+
return next();
|
|
5059
|
+
}
|
|
5060
|
+
if (!["findOne", "findMany"].includes(context.action)) {
|
|
5061
|
+
return next();
|
|
5062
|
+
}
|
|
5063
|
+
const result = await next();
|
|
5064
|
+
if (context.action === "findOne") {
|
|
5065
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) return result;
|
|
5066
|
+
const entry = result;
|
|
5067
|
+
const webatlasObj = entry.webatlas || {};
|
|
5068
|
+
const newWebatlasObj = {
|
|
5069
|
+
path: webatlasObj.path || "",
|
|
5070
|
+
slug: webatlasObj.slug || ""
|
|
5071
|
+
};
|
|
5072
|
+
return { ...entry, webatlas: newWebatlasObj };
|
|
5073
|
+
}
|
|
5074
|
+
if (context.action === "findMany") {
|
|
5075
|
+
if (!Array.isArray(result)) return result;
|
|
5076
|
+
return result.map(
|
|
5077
|
+
(entry) => {
|
|
5078
|
+
const webatlasObj = entry.webatlas || {};
|
|
5079
|
+
const newWebatlasObj = {
|
|
5080
|
+
path: webatlasObj.path || "",
|
|
5081
|
+
slug: webatlasObj.slug || ""
|
|
5082
|
+
};
|
|
5083
|
+
return { ...entry, webatlas: newWebatlasObj };
|
|
5084
|
+
}
|
|
5085
|
+
);
|
|
5086
|
+
}
|
|
5087
|
+
return result;
|
|
5088
|
+
});
|
|
4980
5089
|
}
|
|
5090
|
+
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
5091
|
+
try {
|
|
5092
|
+
await runMigrations(strapi2);
|
|
5093
|
+
registerPermissions(strapi2);
|
|
5094
|
+
const enabledContentTypes = Object.values(strapi2.contentTypes).filter(
|
|
5095
|
+
(type) => type.pluginOptions?.webatlas?.enabled === true
|
|
5096
|
+
);
|
|
5097
|
+
const config2 = await syncConfig(strapi2, enabledContentTypes);
|
|
5098
|
+
if (!enabledContentTypes.length) return;
|
|
5099
|
+
documentMiddleware(strapi2, enabledContentTypes, config2);
|
|
5100
|
+
webatlasMiddleware(strapi2);
|
|
5101
|
+
contentTypeMiddleware(strapi2);
|
|
5102
|
+
} catch (error) {
|
|
5103
|
+
strapi2.log.error(`Bootstrap failed. ${String(error)}`);
|
|
5104
|
+
}
|
|
5105
|
+
};
|
|
4981
5106
|
const destroy = ({ strapi: strapi2 }) => {
|
|
4982
5107
|
};
|
|
4983
5108
|
var _freeGlobal;
|
|
@@ -5893,21 +6018,11 @@ const register = ({ strapi: strapi2 }) => {
|
|
|
5893
6018
|
visible: true,
|
|
5894
6019
|
default: null
|
|
5895
6020
|
};
|
|
5896
|
-
set(attributes, "
|
|
6021
|
+
set(attributes, "webatlas", {
|
|
5897
6022
|
...fieldSettings,
|
|
5898
|
-
type: "
|
|
6023
|
+
type: "json",
|
|
5899
6024
|
private: false
|
|
5900
6025
|
});
|
|
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
6026
|
});
|
|
5912
6027
|
};
|
|
5913
6028
|
const config = {
|
|
@@ -6246,9 +6361,9 @@ const client$2 = ({ strapi: strapi2 }) => ({
|
|
|
6246
6361
|
},
|
|
6247
6362
|
async getNavigation(ctx) {
|
|
6248
6363
|
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);
|
|
6364
|
+
const { id, name, slug, documentId, variant } = ctx.query;
|
|
6365
|
+
if (!id && !name && !slug && !documentId) return ctx.throw(400, "Navigation id, name, slug or documentId is required");
|
|
6366
|
+
const navigation2 = await getClientService().getNavigation(id, name, slug, documentId, variant);
|
|
6252
6367
|
if (!navigation2) return ctx.throw(404, "Navigation not found");
|
|
6253
6368
|
return ctx.send(navigation2);
|
|
6254
6369
|
} catch (e) {
|
|
@@ -6799,23 +6914,32 @@ const client = ({ strapi: strapi2 }) => ({
|
|
|
6799
6914
|
return e;
|
|
6800
6915
|
}
|
|
6801
6916
|
},
|
|
6802
|
-
async getNavigation(id, name, documentId, variant = "nested") {
|
|
6917
|
+
async getNavigation(id, name, slug, documentId, variant = "nested") {
|
|
6803
6918
|
try {
|
|
6804
6919
|
let navigation2 = null;
|
|
6920
|
+
const populateObject = ["items", "items.parent", "items.route"];
|
|
6805
6921
|
const lookupMethods = [
|
|
6806
6922
|
{
|
|
6807
6923
|
condition: documentId,
|
|
6808
6924
|
lookup: () => strapi2.documents(waNavigation).findOne({
|
|
6809
6925
|
documentId,
|
|
6810
|
-
populate:
|
|
6926
|
+
populate: populateObject
|
|
6811
6927
|
}),
|
|
6812
6928
|
name: "documentId"
|
|
6813
6929
|
},
|
|
6930
|
+
{
|
|
6931
|
+
condition: slug,
|
|
6932
|
+
lookup: () => strapi2.db?.query(waNavigation).findOne({
|
|
6933
|
+
where: { slug },
|
|
6934
|
+
populate: populateObject
|
|
6935
|
+
}),
|
|
6936
|
+
name: "slug"
|
|
6937
|
+
},
|
|
6814
6938
|
{
|
|
6815
6939
|
condition: name,
|
|
6816
6940
|
lookup: () => strapi2.db?.query(waNavigation).findOne({
|
|
6817
6941
|
where: { name },
|
|
6818
|
-
populate:
|
|
6942
|
+
populate: populateObject
|
|
6819
6943
|
}),
|
|
6820
6944
|
name: "name"
|
|
6821
6945
|
},
|
|
@@ -6823,7 +6947,7 @@ const client = ({ strapi: strapi2 }) => ({
|
|
|
6823
6947
|
condition: id,
|
|
6824
6948
|
lookup: () => strapi2.db?.query(waNavigation).findOne({
|
|
6825
6949
|
where: { id },
|
|
6826
|
-
populate:
|
|
6950
|
+
populate: populateObject
|
|
6827
6951
|
}),
|
|
6828
6952
|
name: "id"
|
|
6829
6953
|
}
|
|
@@ -6865,3 +6989,4 @@ const index = {
|
|
|
6865
6989
|
middlewares
|
|
6866
6990
|
};
|
|
6867
6991
|
exports.default = index;
|
|
6992
|
+
//# sourceMappingURL=index.js.map
|