@seo-partner/adapters 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/dist/astro-adapter.d.ts +13 -0
- package/dist/astro-adapter.d.ts.map +1 -0
- package/dist/astro-adapter.js +95 -0
- package/dist/astro-adapter.js.map +1 -0
- package/dist/contract.d.ts +21 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +2 -0
- package/dist/contract.js.map +1 -0
- package/dist/detector.d.ts +15 -0
- package/dist/detector.d.ts.map +1 -0
- package/dist/detector.js +40 -0
- package/dist/detector.js.map +1 -0
- package/dist/django-adapter.d.ts +13 -0
- package/dist/django-adapter.d.ts.map +1 -0
- package/dist/django-adapter.js +133 -0
- package/dist/django-adapter.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/nextjs-adapter.d.ts +15 -0
- package/dist/nextjs-adapter.d.ts.map +1 -0
- package/dist/nextjs-adapter.js +83 -0
- package/dist/nextjs-adapter.js.map +1 -0
- package/dist/nuxt-adapter.d.ts +13 -0
- package/dist/nuxt-adapter.d.ts.map +1 -0
- package/dist/nuxt-adapter.js +88 -0
- package/dist/nuxt-adapter.js.map +1 -0
- package/dist/parsers/astro-parser.d.ts +8 -0
- package/dist/parsers/astro-parser.d.ts.map +1 -0
- package/dist/parsers/astro-parser.js +218 -0
- package/dist/parsers/astro-parser.js.map +1 -0
- package/dist/parsers/dtl-parser.d.ts +7 -0
- package/dist/parsers/dtl-parser.d.ts.map +1 -0
- package/dist/parsers/dtl-parser.js +143 -0
- package/dist/parsers/dtl-parser.js.map +1 -0
- package/dist/parsers/html-parser.d.ts +3 -0
- package/dist/parsers/html-parser.d.ts.map +1 -0
- package/dist/parsers/html-parser.js +195 -0
- package/dist/parsers/html-parser.js.map +1 -0
- package/dist/parsers/layout-resolver.d.ts +44 -0
- package/dist/parsers/layout-resolver.d.ts.map +1 -0
- package/dist/parsers/layout-resolver.js +85 -0
- package/dist/parsers/layout-resolver.js.map +1 -0
- package/dist/parsers/php-route-parser.d.ts +11 -0
- package/dist/parsers/php-route-parser.d.ts.map +1 -0
- package/dist/parsers/php-route-parser.js +194 -0
- package/dist/parsers/php-route-parser.js.map +1 -0
- package/dist/parsers/php-template-parser.d.ts +3 -0
- package/dist/parsers/php-template-parser.d.ts.map +1 -0
- package/dist/parsers/php-template-parser.js +230 -0
- package/dist/parsers/php-template-parser.js.map +1 -0
- package/dist/parsers/python-url-parser.d.ts +19 -0
- package/dist/parsers/python-url-parser.d.ts.map +1 -0
- package/dist/parsers/python-url-parser.js +69 -0
- package/dist/parsers/python-url-parser.js.map +1 -0
- package/dist/parsers/remix-parser.d.ts +3 -0
- package/dist/parsers/remix-parser.d.ts.map +1 -0
- package/dist/parsers/remix-parser.js +139 -0
- package/dist/parsers/remix-parser.js.map +1 -0
- package/dist/parsers/robots-sitemap-parser.d.ts +15 -0
- package/dist/parsers/robots-sitemap-parser.d.ts.map +1 -0
- package/dist/parsers/robots-sitemap-parser.js +100 -0
- package/dist/parsers/robots-sitemap-parser.js.map +1 -0
- package/dist/parsers/route-normalizer.d.ts +11 -0
- package/dist/parsers/route-normalizer.d.ts.map +1 -0
- package/dist/parsers/route-normalizer.js +59 -0
- package/dist/parsers/route-normalizer.js.map +1 -0
- package/dist/parsers/svelte-parser.d.ts +3 -0
- package/dist/parsers/svelte-parser.d.ts.map +1 -0
- package/dist/parsers/svelte-parser.js +148 -0
- package/dist/parsers/svelte-parser.js.map +1 -0
- package/dist/parsers/tsx-ast-parser.d.ts +4 -0
- package/dist/parsers/tsx-ast-parser.d.ts.map +1 -0
- package/dist/parsers/tsx-ast-parser.js +380 -0
- package/dist/parsers/tsx-ast-parser.js.map +1 -0
- package/dist/parsers/vue-sfc-parser.d.ts +3 -0
- package/dist/parsers/vue-sfc-parser.d.ts.map +1 -0
- package/dist/parsers/vue-sfc-parser.js +183 -0
- package/dist/parsers/vue-sfc-parser.js.map +1 -0
- package/dist/php-adapter.d.ts +12 -0
- package/dist/php-adapter.d.ts.map +1 -0
- package/dist/php-adapter.js +42 -0
- package/dist/php-adapter.js.map +1 -0
- package/dist/remix-adapter.d.ts +13 -0
- package/dist/remix-adapter.d.ts.map +1 -0
- package/dist/remix-adapter.js +91 -0
- package/dist/remix-adapter.js.map +1 -0
- package/dist/static-adapter.d.ts +12 -0
- package/dist/static-adapter.d.ts.map +1 -0
- package/dist/static-adapter.js +44 -0
- package/dist/static-adapter.js.map +1 -0
- package/dist/sveltekit-adapter.d.ts +13 -0
- package/dist/sveltekit-adapter.d.ts.map +1 -0
- package/dist/sveltekit-adapter.js +89 -0
- package/dist/sveltekit-adapter.js.map +1 -0
- package/package.json +23 -3
- package/src/astro-adapter.ts +126 -0
- package/src/contract.ts +40 -0
- package/src/detector.ts +46 -0
- package/src/django-adapter.ts +173 -0
- package/src/index.ts +23 -0
- package/src/nextjs-adapter.ts +116 -0
- package/src/nuxt-adapter.ts +118 -0
- package/src/parsers/astro-parser.ts +249 -0
- package/src/parsers/dtl-parser.ts +166 -0
- package/src/parsers/html-parser.ts +214 -0
- package/src/parsers/layout-resolver.ts +112 -0
- package/src/parsers/php-route-parser.ts +254 -0
- package/src/parsers/php-template-parser.ts +303 -0
- package/src/parsers/python-url-parser.ts +92 -0
- package/src/parsers/remix-parser.ts +161 -0
- package/src/parsers/robots-sitemap-parser.ts +128 -0
- package/src/parsers/route-normalizer.ts +70 -0
- package/src/parsers/svelte-parser.ts +167 -0
- package/src/parsers/tsx-ast-parser.ts +404 -0
- package/src/parsers/vue-sfc-parser.ts +207 -0
- package/src/php-adapter.ts +68 -0
- package/src/remix-adapter.ts +123 -0
- package/src/static-adapter.ts +62 -0
- package/src/sveltekit-adapter.ts +119 -0
- package/tsconfig.json +9 -0
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-sfc-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/vue-sfc-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAKnB,MAAM,mBAAmB,CAAC;AAgB3B,wBAAgB,WAAW,CACzB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,kBAAkB,CAmLpB"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
function lineNumberAtOffset(content, offset) {
|
|
2
|
+
let line = 1;
|
|
3
|
+
for (let i = 0; i < offset && i < content.length; i += 1) {
|
|
4
|
+
if (content.charCodeAt(i) === 10)
|
|
5
|
+
line += 1;
|
|
6
|
+
}
|
|
7
|
+
return line;
|
|
8
|
+
}
|
|
9
|
+
function getAttr(attrsRaw, attrName) {
|
|
10
|
+
const re = new RegExp(`\\b${attrName}\\s*=\\s*["']([^"']*)["']`, 'i');
|
|
11
|
+
const m = re.exec(attrsRaw);
|
|
12
|
+
return m ? (m[1] ?? null) : null;
|
|
13
|
+
}
|
|
14
|
+
export function parseVueSfc(route, fileContent) {
|
|
15
|
+
let title = null;
|
|
16
|
+
let description = null;
|
|
17
|
+
let canonical = null;
|
|
18
|
+
let robots = null;
|
|
19
|
+
let htmlLang = undefined;
|
|
20
|
+
let isDynamic = false;
|
|
21
|
+
const openGraph = {};
|
|
22
|
+
const hreflang = [];
|
|
23
|
+
const headings = [];
|
|
24
|
+
const images = [];
|
|
25
|
+
const links = [];
|
|
26
|
+
const jsonLdItems = [];
|
|
27
|
+
// 1. Scan script block: <script setup> or <script>
|
|
28
|
+
const scriptMatch = /<script\b[^>]*>([\s\S]*?)<\/script>/i.exec(fileContent);
|
|
29
|
+
if (scriptMatch && scriptMatch[1]) {
|
|
30
|
+
const scriptContent = scriptMatch[1];
|
|
31
|
+
const scriptOffset = scriptMatch.index;
|
|
32
|
+
// useSeoMeta({ ... })
|
|
33
|
+
const useSeoMetaMatch = /useSeoMeta\s*\(\s*\{([\s\S]*?)\}\s*\)/i.exec(scriptContent);
|
|
34
|
+
if (useSeoMetaMatch && useSeoMetaMatch[1]) {
|
|
35
|
+
const metaBody = useSeoMetaMatch[1];
|
|
36
|
+
const callLine = lineNumberAtOffset(fileContent, scriptOffset + useSeoMetaMatch.index);
|
|
37
|
+
// title: '...' or title: "..."
|
|
38
|
+
const titleProp = /title\s*:\s*["']([^"']+)["']/i.exec(metaBody);
|
|
39
|
+
if (titleProp && !title) {
|
|
40
|
+
title = { value: titleProp[1] ?? '', line: callLine };
|
|
41
|
+
}
|
|
42
|
+
else if (/title\s*:\s*[`()]/i.test(metaBody) && !title) {
|
|
43
|
+
title = { value: '[Valeur dynamique]', line: callLine };
|
|
44
|
+
isDynamic = true;
|
|
45
|
+
}
|
|
46
|
+
// description: '...'
|
|
47
|
+
const descProp = /description\s*:\s*["']([^"']+)["']/i.exec(metaBody);
|
|
48
|
+
if (descProp && !description) {
|
|
49
|
+
description = { value: descProp[1] ?? '', line: callLine };
|
|
50
|
+
}
|
|
51
|
+
// robots: '...'
|
|
52
|
+
const robotsProp = /robots\s*:\s*["']([^"']+)["']/i.exec(metaBody);
|
|
53
|
+
if (robotsProp && !robots) {
|
|
54
|
+
robots = { value: robotsProp[1] ?? '', line: callLine };
|
|
55
|
+
}
|
|
56
|
+
// ogTitle, ogDescription
|
|
57
|
+
const ogTitleProp = /ogTitle\s*:\s*["']([^"']+)["']/i.exec(metaBody);
|
|
58
|
+
if (ogTitleProp)
|
|
59
|
+
openGraph['title'] = ogTitleProp[1] ?? '';
|
|
60
|
+
const ogDescProp = /ogDescription\s*:\s*["']([^"']+)["']/i.exec(metaBody);
|
|
61
|
+
if (ogDescProp)
|
|
62
|
+
openGraph['description'] = ogDescProp[1] ?? '';
|
|
63
|
+
}
|
|
64
|
+
// useHead({ ... })
|
|
65
|
+
const useHeadMatch = /useHead\s*\(\s*\{([\s\S]*?)\}\s*\)/i.exec(scriptContent);
|
|
66
|
+
if (useHeadMatch && useHeadMatch[1]) {
|
|
67
|
+
const headBody = useHeadMatch[1];
|
|
68
|
+
const callLine = lineNumberAtOffset(fileContent, scriptOffset + useHeadMatch.index);
|
|
69
|
+
const titleProp = /title\s*:\s*["']([^"']+)["']/i.exec(headBody);
|
|
70
|
+
if (titleProp && !title) {
|
|
71
|
+
title = { value: titleProp[1] ?? '', line: callLine };
|
|
72
|
+
}
|
|
73
|
+
else if (/title\s*:\s*[`()]/i.test(headBody) && !title) {
|
|
74
|
+
title = { value: '[Valeur dynamique]', line: callLine };
|
|
75
|
+
isDynamic = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 2. Scan template block for components: <Title>, <Meta>, <NuxtLink>, <html lang>
|
|
80
|
+
const templateMatch = /<template\b[^>]*>([\s\S]*?)<\/template>/i.exec(fileContent);
|
|
81
|
+
const templateContent = templateMatch && templateMatch[1] ? templateMatch[1] : fileContent;
|
|
82
|
+
const templateOffset = templateMatch ? templateMatch.index : 0;
|
|
83
|
+
// <html lang="...">
|
|
84
|
+
const htmlTagMatch = /<html\b([^>]*?)>/i.exec(templateContent);
|
|
85
|
+
if (htmlTagMatch) {
|
|
86
|
+
const langVal = getAttr(htmlTagMatch[1] ?? '', 'lang');
|
|
87
|
+
if (langVal) {
|
|
88
|
+
htmlLang = {
|
|
89
|
+
value: langVal.trim(),
|
|
90
|
+
line: lineNumberAtOffset(fileContent, templateOffset + htmlTagMatch.index),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// <Title>...</Title> or <title>...</title>
|
|
95
|
+
const titleTagMatch = /<[Tt]itle[^>]*>([\s\S]*?)<\/[Tt]itle>/i.exec(templateContent);
|
|
96
|
+
if (titleTagMatch && !title) {
|
|
97
|
+
const rawVal = (titleTagMatch[1] ?? '').trim();
|
|
98
|
+
const line = lineNumberAtOffset(fileContent, templateOffset + titleTagMatch.index);
|
|
99
|
+
if (/\{\{[^}]+\}\}/.test(rawVal)) {
|
|
100
|
+
title = { value: '[Valeur dynamique]', line };
|
|
101
|
+
isDynamic = true;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
title = { value: rawVal.replace(/\s+/g, ' '), line };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// <Meta name="..." content="..." /> or <meta ...>
|
|
108
|
+
const metaRegex = /<[Mm]eta\b([^>]*?)\/?>/gi;
|
|
109
|
+
let mMatch;
|
|
110
|
+
while ((mMatch = metaRegex.exec(templateContent)) !== null) {
|
|
111
|
+
const attrs = mMatch[1] ?? '';
|
|
112
|
+
const line = lineNumberAtOffset(fileContent, templateOffset + mMatch.index);
|
|
113
|
+
const nameVal = getAttr(attrs, 'name')?.toLowerCase();
|
|
114
|
+
const contentVal = getAttr(attrs, 'content');
|
|
115
|
+
if (nameVal === 'description' && contentVal !== null && !description) {
|
|
116
|
+
description = { value: contentVal, line };
|
|
117
|
+
}
|
|
118
|
+
else if (nameVal === 'robots' && contentVal !== null && !robots) {
|
|
119
|
+
robots = { value: contentVal, line };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Headings: <h1> to <h6>
|
|
123
|
+
const headingRegex = /<h([1-6])\b[^>]*>([\s\S]*?)<\/h\1>/gi;
|
|
124
|
+
let hMatch;
|
|
125
|
+
while ((hMatch = headingRegex.exec(templateContent)) !== null) {
|
|
126
|
+
const level = Number(hMatch[1]);
|
|
127
|
+
const text = (hMatch[2] ?? '').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();
|
|
128
|
+
headings.push({
|
|
129
|
+
level,
|
|
130
|
+
text,
|
|
131
|
+
line: lineNumberAtOffset(fileContent, templateOffset + hMatch.index),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Links: <NuxtLink to="..."> or <a href="...">
|
|
135
|
+
const nuxtLinkRegex = /<NuxtLink\b([^>]*?)>([\s\S]*?)<\/NuxtLink>/gi;
|
|
136
|
+
let nlMatch;
|
|
137
|
+
while ((nlMatch = nuxtLinkRegex.exec(templateContent)) !== null) {
|
|
138
|
+
const attrs = nlMatch[1] ?? '';
|
|
139
|
+
const to = getAttr(attrs, 'to') || getAttr(attrs, ':to') || getAttr(attrs, 'href');
|
|
140
|
+
if (to) {
|
|
141
|
+
const anchorText = (nlMatch[2] ?? '').replace(/<[^>]+>/g, '').trim();
|
|
142
|
+
links.push({
|
|
143
|
+
toUrl: to,
|
|
144
|
+
anchorText,
|
|
145
|
+
kind: to.startsWith('http://') || to.startsWith('https://') ? 'external' : 'internal',
|
|
146
|
+
rel: getAttr(attrs, 'rel'),
|
|
147
|
+
line: lineNumberAtOffset(fileContent, templateOffset + nlMatch.index),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const aRegex = /<a\b([^>]*?)>([\s\S]*?)<\/a>/gi;
|
|
152
|
+
let aMatch;
|
|
153
|
+
while ((aMatch = aRegex.exec(templateContent)) !== null) {
|
|
154
|
+
const attrs = aMatch[1] ?? '';
|
|
155
|
+
const href = getAttr(attrs, 'href');
|
|
156
|
+
if (href) {
|
|
157
|
+
const anchorText = (aMatch[2] ?? '').replace(/<[^>]+>/g, '').trim();
|
|
158
|
+
links.push({
|
|
159
|
+
toUrl: href,
|
|
160
|
+
anchorText,
|
|
161
|
+
kind: href.startsWith('http://') || href.startsWith('https://') ? 'external' : 'internal',
|
|
162
|
+
rel: getAttr(attrs, 'rel'),
|
|
163
|
+
line: lineNumberAtOffset(fileContent, templateOffset + aMatch.index),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
route,
|
|
169
|
+
title,
|
|
170
|
+
description,
|
|
171
|
+
canonical,
|
|
172
|
+
robots,
|
|
173
|
+
htmlLang,
|
|
174
|
+
headings,
|
|
175
|
+
openGraph,
|
|
176
|
+
hreflang,
|
|
177
|
+
images,
|
|
178
|
+
links,
|
|
179
|
+
jsonLdItems,
|
|
180
|
+
isDynamic,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=vue-sfc-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-sfc-parser.js","sourceRoot":"","sources":["../../src/parsers/vue-sfc-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare class PhpAdapter implements FrameworkAdapter {
|
|
4
|
+
readonly id = "php";
|
|
5
|
+
readonly name = "PHP Ecosystem (Laravel / Blade, Symfony / Twig, Native PHP / Laragon)";
|
|
6
|
+
readonly version: "1.0";
|
|
7
|
+
readonly capabilities: AdapterCapabilities;
|
|
8
|
+
detect(_projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>): Promise<boolean>;
|
|
9
|
+
discoverRoutes(_projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>, sitemapPaths: ReadonlySet<string>): Promise<ReadonlyArray<DiscoveredRoute>>;
|
|
10
|
+
extractRoute(projectRoot: string, route: DiscoveredRoute, fileContent: string): Promise<ExtractedRouteData>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=php-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"php-adapter.d.ts","sourceRoot":"","sources":["../src/php-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAU3E,qBAAa,UAAW,YAAW,gBAAgB;IACjD,SAAgB,EAAE,SAAS;IAC3B,SAAgB,IAAI,2EAA2E;IAC/F,SAAgB,OAAO,EAAG,KAAK,CAAU;IACzC,SAAgB,YAAY,EAAE,mBAAmB,CAQ/C;IAEW,MAAM,CACjB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1C,OAAO,CAAC,OAAO,CAAC;IAIN,cAAc,CACzB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAqB7B,YAAY,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAG/B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isPrivateRoutePattern } from './nextjs-adapter.js';
|
|
2
|
+
import { detectPhpFlavor, discoverNativePhpRoutes, parseLaravelRoutes, parseSymfonyRoutes, } from './parsers/php-route-parser.js';
|
|
3
|
+
import { parsePhpOrTemplateFile } from './parsers/php-template-parser.js';
|
|
4
|
+
export class PhpAdapter {
|
|
5
|
+
id = 'php';
|
|
6
|
+
name = 'PHP Ecosystem (Laravel / Blade, Symfony / Twig, Native PHP / Laragon)';
|
|
7
|
+
version = '1.0';
|
|
8
|
+
capabilities = {
|
|
9
|
+
routes: true,
|
|
10
|
+
metadata: true,
|
|
11
|
+
headings: true,
|
|
12
|
+
internalLinks: true,
|
|
13
|
+
jsonLd: true,
|
|
14
|
+
images: true,
|
|
15
|
+
robotsAndSitemap: true,
|
|
16
|
+
};
|
|
17
|
+
async detect(_projectRoot, filePaths, contentsByPath) {
|
|
18
|
+
return detectPhpFlavor(filePaths, contentsByPath) !== null;
|
|
19
|
+
}
|
|
20
|
+
async discoverRoutes(_projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
21
|
+
const flavor = detectPhpFlavor(filePaths, contentsByPath);
|
|
22
|
+
if (!flavor)
|
|
23
|
+
return [];
|
|
24
|
+
const entries = flavor === 'laravel'
|
|
25
|
+
? parseLaravelRoutes(filePaths, contentsByPath)
|
|
26
|
+
: flavor === 'symfony'
|
|
27
|
+
? parseSymfonyRoutes(filePaths, contentsByPath)
|
|
28
|
+
: discoverNativePhpRoutes(filePaths);
|
|
29
|
+
return entries.map((entry) => ({
|
|
30
|
+
pattern: entry.pattern,
|
|
31
|
+
filePath: entry.filePath,
|
|
32
|
+
routerKind: entry.flavor,
|
|
33
|
+
renderingMode: 'ssr-ssg',
|
|
34
|
+
isPrivate: isPrivateRoutePattern(entry.pattern),
|
|
35
|
+
inSitemap: sitemapPaths.has(entry.pattern),
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
async extractRoute(projectRoot, route, fileContent) {
|
|
39
|
+
return parsePhpOrTemplateFile(projectRoot, route, fileContent);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=php-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"php-adapter.js","sourceRoot":"","sources":["../src/php-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAE1E,MAAM,OAAO,UAAU;IACL,EAAE,GAAG,KAAK,CAAC;IACX,IAAI,GAAG,uEAAuE,CAAC;IAC/E,OAAO,GAAG,KAAc,CAAC;IACzB,YAAY,GAAwB;QAClD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,IAAI;KACvB,CAAC;IAEK,KAAK,CAAC,MAAM,CACjB,YAAoB,EACpB,SAAgC,EAChC,cAA2C;QAE3C,OAAO,eAAe,CAAC,SAAS,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IAC7D,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,YAAoB,EACpB,SAAgC,EAChC,cAA2C,EAC3C,YAAiC;QAEjC,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,MAAM,OAAO,GACX,MAAM,KAAK,SAAS;YAClB,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,cAAc,CAAC;YAC/C,CAAC,CAAC,MAAM,KAAK,SAAS;gBACpB,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,cAAc,CAAC;gBAC/C,CAAC,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAE3C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,aAAa,EAAE,SAAS;YACxB,SAAS,EAAE,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC;YAC/C,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;SAC3C,CAAC,CAAC,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,YAAY,CACvB,WAAmB,EACnB,KAAsB,EACtB,WAAmB;QAEnB,OAAO,sBAAsB,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, AdapterVersion, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare class RemixAdapter implements FrameworkAdapter {
|
|
4
|
+
readonly id = "remix";
|
|
5
|
+
readonly name = "Remix / React Router v7";
|
|
6
|
+
readonly version: AdapterVersion;
|
|
7
|
+
readonly capabilities: AdapterCapabilities;
|
|
8
|
+
private readonly layoutResolver;
|
|
9
|
+
detect(projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>): Promise<boolean>;
|
|
10
|
+
discoverRoutes(projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>, sitemapPaths: ReadonlySet<string>): Promise<ReadonlyArray<DiscoveredRoute>>;
|
|
11
|
+
extractRoute(projectRoot: string, route: DiscoveredRoute, fileContent: string): Promise<ExtractedRouteData>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=remix-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remix-adapter.d.ts","sourceRoot":"","sources":["../src/remix-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAK3F,qBAAa,YAAa,YAAW,gBAAgB;IACnD,SAAgB,EAAE,WAAW;IAC7B,SAAgB,IAAI,6BAA6B;IACjD,SAAgB,OAAO,EAAE,cAAc,CAAS;IAChD,SAAgB,YAAY,EAAE,mBAAmB,CAQ/C;IAEF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IAE1C,MAAM,CACjB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1C,OAAO,CAAC,OAAO,CAAC;IAyBN,cAAc,CACzB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAoD7B,YAAY,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAS/B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { parseRemixRoute } from './parsers/remix-parser.js';
|
|
2
|
+
import { normalizeRoutePattern } from './parsers/route-normalizer.js';
|
|
3
|
+
import { LayoutResolver } from './parsers/layout-resolver.js';
|
|
4
|
+
export class RemixAdapter {
|
|
5
|
+
id = 'remix';
|
|
6
|
+
name = 'Remix / React Router v7';
|
|
7
|
+
version = '1.0';
|
|
8
|
+
capabilities = {
|
|
9
|
+
routes: true,
|
|
10
|
+
metadata: true,
|
|
11
|
+
headings: true,
|
|
12
|
+
internalLinks: true,
|
|
13
|
+
jsonLd: true,
|
|
14
|
+
images: true,
|
|
15
|
+
robotsAndSitemap: true,
|
|
16
|
+
};
|
|
17
|
+
layoutResolver = new LayoutResolver();
|
|
18
|
+
async detect(projectRoot, filePaths, contentsByPath) {
|
|
19
|
+
for (const filePath of filePaths) {
|
|
20
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
21
|
+
if (normalized === 'remix.config.js' ||
|
|
22
|
+
normalized === 'remix.config.ts' ||
|
|
23
|
+
normalized === 'remix.config.mjs' ||
|
|
24
|
+
normalized === 'react-router.config.ts' ||
|
|
25
|
+
normalized === 'react-router.config.js') {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (normalized === 'package.json') {
|
|
29
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
30
|
+
if (content.includes('"@remix-run/') ||
|
|
31
|
+
content.includes('"react-router"')) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
async discoverRoutes(projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
39
|
+
const routes = [];
|
|
40
|
+
// Pre-cache root layout from app/root.tsx
|
|
41
|
+
for (const filePath of filePaths) {
|
|
42
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
43
|
+
if (normalized === 'app/root.tsx' || normalized === 'app/root.jsx') {
|
|
44
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
45
|
+
const parsed = parseRemixRoute({
|
|
46
|
+
pattern: '',
|
|
47
|
+
filePath,
|
|
48
|
+
routerKind: 'remix',
|
|
49
|
+
renderingMode: 'ssr-ssg',
|
|
50
|
+
isPrivate: false,
|
|
51
|
+
inSitemap: false,
|
|
52
|
+
}, content);
|
|
53
|
+
this.layoutResolver.registerLayout({
|
|
54
|
+
filePath,
|
|
55
|
+
htmlLang: parsed.htmlLang,
|
|
56
|
+
title: parsed.title,
|
|
57
|
+
description: parsed.description,
|
|
58
|
+
canonical: parsed.canonical,
|
|
59
|
+
robots: parsed.robots,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
for (const filePath of filePaths) {
|
|
64
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
65
|
+
if (!normalized.startsWith('app/routes/'))
|
|
66
|
+
continue;
|
|
67
|
+
if (!/\.(tsx|jsx|ts|js)$/i.test(normalized))
|
|
68
|
+
continue;
|
|
69
|
+
const relativeInsideRoutes = normalized.slice('app/routes/'.length);
|
|
70
|
+
const pattern = normalizeRoutePattern(relativeInsideRoutes, 'remix');
|
|
71
|
+
const inSitemap = sitemapPaths.has(pattern);
|
|
72
|
+
routes.push({
|
|
73
|
+
pattern,
|
|
74
|
+
filePath,
|
|
75
|
+
routerKind: 'remix',
|
|
76
|
+
renderingMode: 'ssr-ssg',
|
|
77
|
+
isPrivate: false,
|
|
78
|
+
inSitemap,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return routes;
|
|
82
|
+
}
|
|
83
|
+
async extractRoute(projectRoot, route, fileContent) {
|
|
84
|
+
let extracted = parseRemixRoute(route, fileContent);
|
|
85
|
+
// Apply root layout inheritance
|
|
86
|
+
const layoutCandidates = ['app/root.tsx', 'app/root.jsx'];
|
|
87
|
+
extracted = this.layoutResolver.applyInheritance(extracted, layoutCandidates);
|
|
88
|
+
return extracted;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=remix-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remix-adapter.js","sourceRoot":"","sources":["../src/remix-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare class StaticAdapter implements FrameworkAdapter {
|
|
4
|
+
readonly id = "static-html";
|
|
5
|
+
readonly name = "Static HTML & Markdown";
|
|
6
|
+
readonly version: "1.0";
|
|
7
|
+
readonly capabilities: AdapterCapabilities;
|
|
8
|
+
detect(_projectRoot: string, filePaths: ReadonlyArray<string>): Promise<boolean>;
|
|
9
|
+
discoverRoutes(_projectRoot: string, filePaths: ReadonlyArray<string>, _contentsByPath: ReadonlyMap<string, string>, sitemapPaths: ReadonlySet<string>): Promise<ReadonlyArray<DiscoveredRoute>>;
|
|
10
|
+
extractRoute(_projectRoot: string, route: DiscoveredRoute, fileContent: string): Promise<ExtractedRouteData>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=static-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-adapter.d.ts","sourceRoot":"","sources":["../src/static-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAI3E,qBAAa,aAAc,YAAW,gBAAgB;IACpD,SAAgB,EAAE,iBAAiB;IACnC,SAAgB,IAAI,4BAA4B;IAChD,SAAgB,OAAO,EAAG,KAAK,CAAU;IACzC,SAAgB,YAAY,EAAE,mBAAmB,CAQ/C;IAEW,MAAM,CACjB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC;IAIN,cAAc,CACzB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAsB7B,YAAY,CACvB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAG/B"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { isPrivateRoutePattern } from './nextjs-adapter.js';
|
|
2
|
+
import { parseStaticHtmlOrMarkdown } from './parsers/html-parser.js';
|
|
3
|
+
export class StaticAdapter {
|
|
4
|
+
id = 'static-html';
|
|
5
|
+
name = 'Static HTML & Markdown';
|
|
6
|
+
version = '1.0';
|
|
7
|
+
capabilities = {
|
|
8
|
+
routes: true,
|
|
9
|
+
metadata: true,
|
|
10
|
+
headings: true,
|
|
11
|
+
internalLinks: true,
|
|
12
|
+
jsonLd: true,
|
|
13
|
+
images: true,
|
|
14
|
+
robotsAndSitemap: true,
|
|
15
|
+
};
|
|
16
|
+
async detect(_projectRoot, filePaths) {
|
|
17
|
+
return filePaths.some((p) => p.endsWith('.html'));
|
|
18
|
+
}
|
|
19
|
+
async discoverRoutes(_projectRoot, filePaths, _contentsByPath, sitemapPaths) {
|
|
20
|
+
const routes = [];
|
|
21
|
+
for (const filePath of filePaths) {
|
|
22
|
+
if (filePath.endsWith('.html')) {
|
|
23
|
+
const clean = filePath
|
|
24
|
+
.replace(/^public\//, '')
|
|
25
|
+
.replace(/index\.html$/, '')
|
|
26
|
+
.replace(/\.html$/, '');
|
|
27
|
+
const pattern = clean.startsWith('/') ? clean : `/${clean}`;
|
|
28
|
+
routes.push({
|
|
29
|
+
pattern: pattern === '' ? '/' : pattern,
|
|
30
|
+
filePath,
|
|
31
|
+
routerKind: 'static-html',
|
|
32
|
+
renderingMode: 'static',
|
|
33
|
+
isPrivate: isPrivateRoutePattern(pattern),
|
|
34
|
+
inSitemap: sitemapPaths.has(pattern),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return routes;
|
|
39
|
+
}
|
|
40
|
+
async extractRoute(_projectRoot, route, fileContent) {
|
|
41
|
+
return parseStaticHtmlOrMarkdown(route, fileContent);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=static-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-adapter.js","sourceRoot":"","sources":["../src/static-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAErE,MAAM,OAAO,aAAa;IACR,EAAE,GAAG,aAAa,CAAC;IACnB,IAAI,GAAG,wBAAwB,CAAC;IAChC,OAAO,GAAG,KAAc,CAAC;IACzB,YAAY,GAAwB;QAClD,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,IAAI;KACvB,CAAC;IAEK,KAAK,CAAC,MAAM,CACjB,YAAoB,EACpB,SAAgC;QAEhC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,YAAoB,EACpB,SAAgC,EAChC,eAA4C,EAC5C,YAAiC;QAEjC,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,QAAQ;qBACnB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;qBACxB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;qBAC3B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;gBAC5D,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO;oBACvC,QAAQ;oBACR,UAAU,EAAE,aAAa;oBACzB,aAAa,EAAE,QAAQ;oBACvB,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC;oBACzC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,YAAY,CACvB,YAAoB,EACpB,KAAsB,EACtB,WAAmB;QAEnB,OAAO,yBAAyB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, AdapterVersion, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare class SvelteKitAdapter implements FrameworkAdapter {
|
|
4
|
+
readonly id = "sveltekit";
|
|
5
|
+
readonly name = "SvelteKit";
|
|
6
|
+
readonly version: AdapterVersion;
|
|
7
|
+
readonly capabilities: AdapterCapabilities;
|
|
8
|
+
private readonly layoutResolver;
|
|
9
|
+
detect(projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>): Promise<boolean>;
|
|
10
|
+
discoverRoutes(projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>, sitemapPaths: ReadonlySet<string>): Promise<ReadonlyArray<DiscoveredRoute>>;
|
|
11
|
+
extractRoute(projectRoot: string, route: DiscoveredRoute, fileContent: string): Promise<ExtractedRouteData>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=sveltekit-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sveltekit-adapter.d.ts","sourceRoot":"","sources":["../src/sveltekit-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAK3F,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,SAAgB,EAAE,eAAe;IACjC,SAAgB,IAAI,eAAe;IACnC,SAAgB,OAAO,EAAE,cAAc,CAAS;IAChD,SAAgB,YAAY,EAAE,mBAAmB,CAQ/C;IAEF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IAE1C,MAAM,CACjB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1C,OAAO,CAAC,OAAO,CAAC;IAqBN,cAAc,CACzB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,EAChC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAoD7B,YAAY,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAS/B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { parseSvelteComponent } from './parsers/svelte-parser.js';
|
|
2
|
+
import { normalizeRoutePattern } from './parsers/route-normalizer.js';
|
|
3
|
+
import { LayoutResolver } from './parsers/layout-resolver.js';
|
|
4
|
+
export class SvelteKitAdapter {
|
|
5
|
+
id = 'sveltekit';
|
|
6
|
+
name = 'SvelteKit';
|
|
7
|
+
version = '1.0';
|
|
8
|
+
capabilities = {
|
|
9
|
+
routes: true,
|
|
10
|
+
metadata: true,
|
|
11
|
+
headings: true,
|
|
12
|
+
internalLinks: true,
|
|
13
|
+
jsonLd: true,
|
|
14
|
+
images: true,
|
|
15
|
+
robotsAndSitemap: true,
|
|
16
|
+
};
|
|
17
|
+
layoutResolver = new LayoutResolver();
|
|
18
|
+
async detect(projectRoot, filePaths, contentsByPath) {
|
|
19
|
+
for (const filePath of filePaths) {
|
|
20
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
21
|
+
if (normalized === 'svelte.config.js' ||
|
|
22
|
+
normalized === 'svelte.config.ts' ||
|
|
23
|
+
normalized === 'svelte.config.mjs' ||
|
|
24
|
+
normalized === 'svelte.config.cjs') {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
if (normalized === 'package.json') {
|
|
28
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
29
|
+
if (content.includes('"@sveltejs/kit"')) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
async discoverRoutes(projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
37
|
+
const routes = [];
|
|
38
|
+
// Pre-cache layouts from src/routes/**/+layout.svelte
|
|
39
|
+
for (const filePath of filePaths) {
|
|
40
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
41
|
+
if (normalized.startsWith('src/routes/') && normalized.endsWith('+layout.svelte')) {
|
|
42
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
43
|
+
const parsed = parseSvelteComponent({
|
|
44
|
+
pattern: '',
|
|
45
|
+
filePath,
|
|
46
|
+
routerKind: 'sveltekit',
|
|
47
|
+
renderingMode: 'ssr-ssg',
|
|
48
|
+
isPrivate: false,
|
|
49
|
+
inSitemap: false,
|
|
50
|
+
}, content);
|
|
51
|
+
this.layoutResolver.registerLayout({
|
|
52
|
+
filePath,
|
|
53
|
+
htmlLang: parsed.htmlLang,
|
|
54
|
+
title: parsed.title,
|
|
55
|
+
description: parsed.description,
|
|
56
|
+
canonical: parsed.canonical,
|
|
57
|
+
robots: parsed.robots,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const filePath of filePaths) {
|
|
62
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
63
|
+
if (!normalized.startsWith('src/routes/'))
|
|
64
|
+
continue;
|
|
65
|
+
if (!normalized.endsWith('+page.svelte'))
|
|
66
|
+
continue;
|
|
67
|
+
const relativeInsideRoutes = normalized.slice('src/routes/'.length);
|
|
68
|
+
const pattern = normalizeRoutePattern(relativeInsideRoutes, 'sveltekit');
|
|
69
|
+
const inSitemap = sitemapPaths.has(pattern);
|
|
70
|
+
routes.push({
|
|
71
|
+
pattern,
|
|
72
|
+
filePath,
|
|
73
|
+
routerKind: 'sveltekit',
|
|
74
|
+
renderingMode: 'ssr-ssg',
|
|
75
|
+
isPrivate: false,
|
|
76
|
+
inSitemap,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return routes;
|
|
80
|
+
}
|
|
81
|
+
async extractRoute(projectRoot, route, fileContent) {
|
|
82
|
+
let extracted = parseSvelteComponent(route, fileContent);
|
|
83
|
+
// Apply hierarchical layout inheritance from leaf up to root
|
|
84
|
+
const parentLayouts = this.layoutResolver.findSvelteKitLayoutPaths(route.filePath);
|
|
85
|
+
extracted = this.layoutResolver.applyInheritance(extracted, parentLayouts);
|
|
86
|
+
return extracted;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=sveltekit-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sveltekit-adapter.js","sourceRoot":"","sources":["../src/sveltekit-adapter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seo-partner/adapters",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"typescript": "^5.7.2",
|
|
15
|
+
"@seo-partner/core": "1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Firinze Gbènito Dossou",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
25
|
+
}
|
|
6
26
|
}
|