@djangocfg/seo 2.1.205 → 2.1.207
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/dist/cli.mjs +30 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +30 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/content/link-checker.ts +14 -16
- package/src/content/link-fixer.ts +31 -7
package/dist/cli.mjs
CHANGED
|
@@ -3181,12 +3181,12 @@ var LINK_PATTERNS = [
|
|
|
3181
3181
|
{ regex: /\]\(\/docs\/([^)#\s"]+)/g, type: "absolute" },
|
|
3182
3182
|
{ regex: /href="\/docs\/([^"#]+)"/g, type: "absolute" },
|
|
3183
3183
|
{ regex: /to="\/docs\/([^"#]+)"/g, type: "absolute" },
|
|
3184
|
-
// Dot-slash relative: [text](./path)
|
|
3184
|
+
// Dot-slash relative: [text](./path) — captures without ./
|
|
3185
3185
|
{ regex: /\]\(\.\/([^)#\s"]+)(?:#[^)]*)?\)/g, type: "dotslash" },
|
|
3186
3186
|
{ regex: /href="\.\/([^"#]+)"/g, type: "dotslash" },
|
|
3187
|
-
// Parent relative: [text](../path)
|
|
3188
|
-
{ regex: /\]\(\.\.\/
|
|
3189
|
-
{ regex: /href="\.\.\/
|
|
3187
|
+
// Parent relative: [text](../path) — captures FULL href including leading ../
|
|
3188
|
+
{ regex: /\]\((\.\.\/[^)#\s"]+)(?:#[^)]*)?\)/g, type: "parent" },
|
|
3189
|
+
{ regex: /href="(\.\.\/[^"#]+)"/g, type: "parent" },
|
|
3190
3190
|
// Simple relative (no prefix): [text](path)
|
|
3191
3191
|
{ regex: /\]\((?!\/|http|#|\.|\[)([a-zA-Z][^)#\s"]*)(?:#[^)]*)?\)/g, type: "simple" },
|
|
3192
3192
|
{ regex: /href="(?!\/|http|#|\.)([a-zA-Z][^"#]*)"/g, type: "simple" }
|
|
@@ -3198,24 +3198,21 @@ function resolveLink(fromFilePath, linkPath, linkType, contentDir) {
|
|
|
3198
3198
|
if (linkType === "absolute") {
|
|
3199
3199
|
return linkPath;
|
|
3200
3200
|
}
|
|
3201
|
-
const {
|
|
3201
|
+
const { folder: sourceFolder} = getFileInfo(fromFilePath, contentDir);
|
|
3202
3202
|
sourceFolder ? sourceFolder.split("/") : [];
|
|
3203
3203
|
if (linkType === "dotslash" || linkType === "simple") {
|
|
3204
|
-
|
|
3205
|
-
return sourceFolder ? `${sourceFolder}/${linkPath}` : linkPath;
|
|
3206
|
-
} else {
|
|
3207
|
-
return sourceFolder ? `${sourceFolder}/${fileName}/${linkPath}` : `${fileName}/${linkPath}`;
|
|
3208
|
-
}
|
|
3204
|
+
return sourceFolder ? `${sourceFolder}/${linkPath}` : linkPath;
|
|
3209
3205
|
}
|
|
3210
3206
|
if (linkType === "parent") {
|
|
3211
3207
|
const base = sourceFolder ? `/${sourceFolder}` : "/";
|
|
3212
|
-
const resolved = path.posix.resolve(base,
|
|
3208
|
+
const resolved = path.posix.resolve(base, linkPath);
|
|
3213
3209
|
return resolved.replace(/^\//, "");
|
|
3214
3210
|
}
|
|
3215
3211
|
return linkPath;
|
|
3216
3212
|
}
|
|
3217
3213
|
function extractLinks(filePath, contentDir, assetExtensions) {
|
|
3218
|
-
const
|
|
3214
|
+
const raw = fs4.readFileSync(filePath, "utf-8");
|
|
3215
|
+
const content = raw.replace(/```[\s\S]*?```/g, (match) => " ".repeat(match.length));
|
|
3219
3216
|
const links = [];
|
|
3220
3217
|
for (const { regex, type } of LINK_PATTERNS) {
|
|
3221
3218
|
regex.lastIndex = 0;
|
|
@@ -3333,11 +3330,12 @@ function calculateRelativePath(sourceFile, targetDocsPath, contentDir) {
|
|
|
3333
3330
|
function processFile(filePath, contentDir, assetExtensions) {
|
|
3334
3331
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
3335
3332
|
const fixes = [];
|
|
3336
|
-
const
|
|
3333
|
+
const { isIndex, folder: sourceFolder } = getFileInfo(filePath, contentDir);
|
|
3334
|
+
const absolutePatterns = [
|
|
3337
3335
|
{ regex: /(\]\()\/docs\/([^)#\s"]+)(\))/g },
|
|
3338
3336
|
{ regex: /(href=")\/docs\/([^"#]+)(")/g }
|
|
3339
3337
|
];
|
|
3340
|
-
for (const { regex } of
|
|
3338
|
+
for (const { regex } of absolutePatterns) {
|
|
3341
3339
|
regex.lastIndex = 0;
|
|
3342
3340
|
let match;
|
|
3343
3341
|
while ((match = regex.exec(content)) !== null) {
|
|
@@ -3355,6 +3353,24 @@ function processFile(filePath, contentDir, assetExtensions) {
|
|
|
3355
3353
|
}
|
|
3356
3354
|
}
|
|
3357
3355
|
}
|
|
3356
|
+
if (!isIndex && sourceFolder) {
|
|
3357
|
+
const parentRelPattern = /\]\(\.\.\/([^./][^)#\s"]*?)(#[^)]*?)?\)/g;
|
|
3358
|
+
parentRelPattern.lastIndex = 0;
|
|
3359
|
+
let match;
|
|
3360
|
+
while ((match = parentRelPattern.exec(content)) !== null) {
|
|
3361
|
+
const slug = match[1];
|
|
3362
|
+
const anchor = match[2] || "";
|
|
3363
|
+
if (!slug || slug.includes("/")) continue;
|
|
3364
|
+
if (isAssetLink2(slug, assetExtensions)) continue;
|
|
3365
|
+
const siblingPath = sourceFolder ? `${sourceFolder}/${slug}` : slug;
|
|
3366
|
+
if (!pathExists(siblingPath, contentDir)) continue;
|
|
3367
|
+
fixes.push({
|
|
3368
|
+
from: `](../${slug}${anchor})`,
|
|
3369
|
+
to: `](./${slug}${anchor})`,
|
|
3370
|
+
line: content.substring(0, match.index).split("\n").length
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3358
3374
|
return fixes;
|
|
3359
3375
|
}
|
|
3360
3376
|
function applyFixes(filePath, fixes) {
|