@seo-partner/adapters 0.0.0-stage → 1.0.3
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/ast-merger.d.ts +24 -0
- package/dist/ast-merger.d.ts.map +1 -0
- package/dist/ast-merger.js +85 -0
- package/dist/ast-merger.js.map +1 -0
- package/dist/astro-adapter.d.ts +19 -0
- package/dist/astro-adapter.d.ts.map +1 -0
- package/dist/astro-adapter.js +114 -0
- package/dist/astro-adapter.js.map +1 -0
- package/dist/blog-scaffold-generator.d.ts +8 -0
- package/dist/blog-scaffold-generator.d.ts.map +1 -0
- package/dist/blog-scaffold-generator.js +138 -0
- package/dist/blog-scaffold-generator.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 +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/laravel-adapter.d.ts +7 -0
- package/dist/laravel-adapter.d.ts.map +1 -0
- package/dist/laravel-adapter.js +35 -0
- package/dist/laravel-adapter.js.map +1 -0
- package/dist/layout-title-resolver.d.ts +8 -0
- package/dist/layout-title-resolver.d.ts.map +1 -0
- package/dist/layout-title-resolver.js +28 -0
- package/dist/layout-title-resolver.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 +19 -0
- package/dist/nuxt-adapter.d.ts.map +1 -0
- package/dist/nuxt-adapter.js +108 -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/php-native-adapter.d.ts +7 -0
- package/dist/php-native-adapter.d.ts.map +1 -0
- package/dist/php-native-adapter.js +31 -0
- package/dist/php-native-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/sitemap-builder.d.ts +10 -0
- package/dist/sitemap-builder.d.ts.map +1 -0
- package/dist/sitemap-builder.js +37 -0
- package/dist/sitemap-builder.js.map +1 -0
- package/dist/skeleton-detector.d.ts +14 -0
- package/dist/skeleton-detector.d.ts.map +1 -0
- package/dist/skeleton-detector.js +33 -0
- package/dist/skeleton-detector.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 +19 -0
- package/dist/sveltekit-adapter.d.ts.map +1 -0
- package/dist/sveltekit-adapter.js +115 -0
- package/dist/sveltekit-adapter.js.map +1 -0
- package/dist/symfony-adapter.d.ts +7 -0
- package/dist/symfony-adapter.d.ts.map +1 -0
- package/dist/symfony-adapter.js +23 -0
- package/dist/symfony-adapter.js.map +1 -0
- package/package.json +23 -3
- package/src/ast-merger.ts +123 -0
- package/src/astro-adapter.ts +155 -0
- package/src/blog-scaffold-generator.ts +153 -0
- package/src/contract.ts +40 -0
- package/src/detector.ts +46 -0
- package/src/django-adapter.ts +173 -0
- package/src/index.ts +31 -0
- package/src/laravel-adapter.ts +45 -0
- package/src/layout-title-resolver.ts +37 -0
- package/src/nextjs-adapter.ts +116 -0
- package/src/nuxt-adapter.ts +148 -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/php-native-adapter.ts +46 -0
- package/src/remix-adapter.ts +123 -0
- package/src/sitemap-builder.ts +57 -0
- package/src/skeleton-detector.ts +56 -0
- package/src/static-adapter.ts +62 -0
- package/src/sveltekit-adapter.ts +160 -0
- package/src/symfony-adapter.ts +33 -0
- package/tsconfig.json +9 -0
- package/README.md +0 -3
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { parseDjangoUrls, parseDjangoViews } from './parsers/python-url-parser.js';
|
|
2
|
+
import { parseDjangoTemplate } from './parsers/dtl-parser.js';
|
|
3
|
+
import { LayoutResolver } from './parsers/layout-resolver.js';
|
|
4
|
+
export class DjangoAdapter {
|
|
5
|
+
id = 'django';
|
|
6
|
+
name = 'Django';
|
|
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 === 'manage.py' ||
|
|
22
|
+
normalized.endsWith('/manage.py') ||
|
|
23
|
+
normalized === 'wsgi.py' ||
|
|
24
|
+
normalized.endsWith('/wsgi.py') ||
|
|
25
|
+
normalized === 'asgi.py' ||
|
|
26
|
+
normalized.endsWith('/asgi.py') ||
|
|
27
|
+
normalized.endsWith('settings.py')) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
async discoverRoutes(projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
34
|
+
const routes = [];
|
|
35
|
+
// 1. Pre-cache all base templates (e.g. templates/base.html, templates/*/base.html)
|
|
36
|
+
for (const filePath of filePaths) {
|
|
37
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
38
|
+
if (normalized.endsWith('.html')) {
|
|
39
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
40
|
+
if (normalized.endsWith('base.html') ||
|
|
41
|
+
content.includes('<!DOCTYPE html>') ||
|
|
42
|
+
content.includes('<html')) {
|
|
43
|
+
const parsed = parseDjangoTemplate({
|
|
44
|
+
pattern: '',
|
|
45
|
+
filePath,
|
|
46
|
+
routerKind: 'django',
|
|
47
|
+
renderingMode: 'dynamic',
|
|
48
|
+
isPrivate: false,
|
|
49
|
+
inSitemap: false,
|
|
50
|
+
}, content);
|
|
51
|
+
this.layoutResolver.registerLayout({
|
|
52
|
+
filePath,
|
|
53
|
+
htmlLang: parsed.routeData.htmlLang,
|
|
54
|
+
title: parsed.routeData.title,
|
|
55
|
+
description: parsed.routeData.description,
|
|
56
|
+
canonical: parsed.routeData.canonical,
|
|
57
|
+
robots: parsed.routeData.robots,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 2. Parse all views.py to build viewName -> templateName mapping
|
|
63
|
+
const viewToTemplate = new Map();
|
|
64
|
+
for (const filePath of filePaths) {
|
|
65
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
66
|
+
if (normalized.endsWith('views.py')) {
|
|
67
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
68
|
+
const mappings = parseDjangoViews(content);
|
|
69
|
+
for (const m of mappings) {
|
|
70
|
+
viewToTemplate.set(m.viewName, m.templateName);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// 3. Parse all urls.py to discover routes
|
|
75
|
+
for (const filePath of filePaths) {
|
|
76
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
77
|
+
if (!normalized.endsWith('urls.py'))
|
|
78
|
+
continue;
|
|
79
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
80
|
+
const patterns = parseDjangoUrls(content);
|
|
81
|
+
for (const p of patterns) {
|
|
82
|
+
const targetTemplateName = viewToTemplate.get(p.viewName);
|
|
83
|
+
let resolvedFilePath = filePath;
|
|
84
|
+
if (targetTemplateName) {
|
|
85
|
+
// Find matching template in filePaths
|
|
86
|
+
const found = filePaths.find((fp) => {
|
|
87
|
+
const norm = fp.replace(/\\/g, '/');
|
|
88
|
+
return norm.endsWith(`/${targetTemplateName}`) || norm === targetTemplateName;
|
|
89
|
+
});
|
|
90
|
+
if (found) {
|
|
91
|
+
resolvedFilePath = found;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Conventional fallback: check for templates/<viewName>.html
|
|
96
|
+
const fallback = filePaths.find((fp) => {
|
|
97
|
+
const norm = fp.replace(/\\/g, '/');
|
|
98
|
+
return (norm.endsWith(`/${p.viewName}.html`) ||
|
|
99
|
+
norm.endsWith(`templates/${p.viewName}.html`));
|
|
100
|
+
});
|
|
101
|
+
if (fallback) {
|
|
102
|
+
resolvedFilePath = fallback;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const inSitemap = sitemapPaths.has(p.pattern) || sitemapPaths.has(`${p.pattern}/`);
|
|
106
|
+
routes.push({
|
|
107
|
+
pattern: p.pattern,
|
|
108
|
+
filePath: resolvedFilePath,
|
|
109
|
+
routerKind: 'django',
|
|
110
|
+
renderingMode: 'dynamic',
|
|
111
|
+
isPrivate: false,
|
|
112
|
+
inSitemap,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return routes;
|
|
117
|
+
}
|
|
118
|
+
async extractRoute(projectRoot, route, fileContent) {
|
|
119
|
+
const parsed = parseDjangoTemplate(route, fileContent);
|
|
120
|
+
let extracted = parsed.routeData;
|
|
121
|
+
// Resolve base template inheritance
|
|
122
|
+
const candidates = [];
|
|
123
|
+
if (parsed.extendsTemplate) {
|
|
124
|
+
candidates.push(parsed.extendsTemplate);
|
|
125
|
+
candidates.push(`templates/${parsed.extendsTemplate}`);
|
|
126
|
+
}
|
|
127
|
+
candidates.push('templates/base.html');
|
|
128
|
+
candidates.push('base.html');
|
|
129
|
+
extracted = this.layoutResolver.applyInheritance(extracted, candidates);
|
|
130
|
+
return extracted;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=django-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"django-adapter.js","sourceRoot":"","sources":["../src/django-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export * from './contract.js';
|
|
2
|
+
export * from './detector.js';
|
|
3
|
+
export * from './nextjs-adapter.js';
|
|
4
|
+
export * from './astro-adapter.js';
|
|
5
|
+
export * from './nuxt-adapter.js';
|
|
6
|
+
export * from './sveltekit-adapter.js';
|
|
7
|
+
export * from './remix-adapter.js';
|
|
8
|
+
export * from './django-adapter.js';
|
|
9
|
+
export * from './php-adapter.js';
|
|
10
|
+
export * from './laravel-adapter.js';
|
|
11
|
+
export * from './symfony-adapter.js';
|
|
12
|
+
export * from './php-native-adapter.js';
|
|
13
|
+
export * from './static-adapter.js';
|
|
14
|
+
export * from './parsers/tsx-ast-parser.js';
|
|
15
|
+
export * from './parsers/html-parser.js';
|
|
16
|
+
export * from './parsers/astro-parser.js';
|
|
17
|
+
export * from './parsers/vue-sfc-parser.js';
|
|
18
|
+
export * from './parsers/svelte-parser.js';
|
|
19
|
+
export * from './parsers/remix-parser.js';
|
|
20
|
+
export * from './parsers/python-url-parser.js';
|
|
21
|
+
export * from './parsers/dtl-parser.js';
|
|
22
|
+
export * from './parsers/php-route-parser.js';
|
|
23
|
+
export * from './parsers/php-template-parser.js';
|
|
24
|
+
export * from './parsers/robots-sitemap-parser.js';
|
|
25
|
+
export * from './parsers/route-normalizer.js';
|
|
26
|
+
export * from './parsers/layout-resolver.js';
|
|
27
|
+
export * from './sitemap-builder.js';
|
|
28
|
+
export * from './skeleton-detector.js';
|
|
29
|
+
export * from './ast-merger.js';
|
|
30
|
+
export * from './layout-title-resolver.js';
|
|
31
|
+
export * from './blog-scaffold-generator.js';
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export * from './contract.js';
|
|
2
|
+
export * from './detector.js';
|
|
3
|
+
export * from './nextjs-adapter.js';
|
|
4
|
+
export * from './astro-adapter.js';
|
|
5
|
+
export * from './nuxt-adapter.js';
|
|
6
|
+
export * from './sveltekit-adapter.js';
|
|
7
|
+
export * from './remix-adapter.js';
|
|
8
|
+
export * from './django-adapter.js';
|
|
9
|
+
export * from './php-adapter.js';
|
|
10
|
+
export * from './laravel-adapter.js';
|
|
11
|
+
export * from './symfony-adapter.js';
|
|
12
|
+
export * from './php-native-adapter.js';
|
|
13
|
+
export * from './static-adapter.js';
|
|
14
|
+
export * from './parsers/tsx-ast-parser.js';
|
|
15
|
+
export * from './parsers/html-parser.js';
|
|
16
|
+
export * from './parsers/astro-parser.js';
|
|
17
|
+
export * from './parsers/vue-sfc-parser.js';
|
|
18
|
+
export * from './parsers/svelte-parser.js';
|
|
19
|
+
export * from './parsers/remix-parser.js';
|
|
20
|
+
export * from './parsers/python-url-parser.js';
|
|
21
|
+
export * from './parsers/dtl-parser.js';
|
|
22
|
+
export * from './parsers/php-route-parser.js';
|
|
23
|
+
export * from './parsers/php-template-parser.js';
|
|
24
|
+
export * from './parsers/robots-sitemap-parser.js';
|
|
25
|
+
export * from './parsers/route-normalizer.js';
|
|
26
|
+
export * from './parsers/layout-resolver.js';
|
|
27
|
+
export * from './sitemap-builder.js';
|
|
28
|
+
export * from './skeleton-detector.js';
|
|
29
|
+
export * from './ast-merger.js';
|
|
30
|
+
export * from './layout-title-resolver.js';
|
|
31
|
+
export * from './blog-scaffold-generator.js';
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"laravel-adapter.d.ts","sourceRoot":"","sources":["../src/laravel-adapter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAkCR"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function patchLaravelBladeTemplate(sourceCode, meta) {
|
|
2
|
+
let result = sourceCode;
|
|
3
|
+
// Title section
|
|
4
|
+
if (meta.title && !/@section\(\s*['"]title['"]/i.test(result)) {
|
|
5
|
+
const sectionTitle = `@section('title', '${meta.title.replace(/'/g, "\\'")}')\n`;
|
|
6
|
+
if (/@extends\([^)]+\)/i.test(result)) {
|
|
7
|
+
result = result.replace(/(@extends\([^)]+\)\s*\n)/i, `$1${sectionTitle}`);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
result = sectionTitle + result;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// Meta push
|
|
14
|
+
if ((meta.description || meta.canonical) && !/@push\(\s*['"]meta['"]/i.test(result)) {
|
|
15
|
+
const metaTags = ["@push('meta')"];
|
|
16
|
+
if (meta.description) {
|
|
17
|
+
metaTags.push(` <meta name="description" content="${meta.description.replace(/"/g, '"')}">`);
|
|
18
|
+
}
|
|
19
|
+
if (meta.canonical) {
|
|
20
|
+
metaTags.push(` <link rel="canonical" href="${meta.canonical}">`);
|
|
21
|
+
}
|
|
22
|
+
metaTags.push('@endpush\n');
|
|
23
|
+
if (/@section\(\s*['"]title['"][^)]*\)/i.test(result)) {
|
|
24
|
+
result = result.replace(/(@section\(\s*['"]title['"][^)]*\)\s*\n)/i, `$1${metaTags.join('\n')}`);
|
|
25
|
+
}
|
|
26
|
+
else if (/@extends\([^)]+\)/i.test(result)) {
|
|
27
|
+
result = result.replace(/(@extends\([^)]+\)\s*\n)/i, `$1${metaTags.join('\n')}`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
result = metaTags.join('\n') + result;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=laravel-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"laravel-adapter.js","sourceRoot":"","sources":["../src/laravel-adapter.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,yBAAyB,CACvC,UAAkB,EAClB,IAAuB;IAEvB,IAAI,MAAM,GAAG,UAAU,CAAC;IAExB,gBAAgB;IAChB,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,MAAM,YAAY,GAAG,sBAAsB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;QACjF,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,2BAA2B,EAAE,KAAK,YAAY,EAAE,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;QACjC,CAAC;IACH,CAAC;IAED,YAAY;IACZ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpF,MAAM,QAAQ,GAAa,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,uCAAuC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrG,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,iCAAiC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACrE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5B,IAAI,oCAAoC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,2CAA2C,EAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;aAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,2BAA2B,EAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface LayoutTitleTemplate {
|
|
2
|
+
template?: string;
|
|
3
|
+
defaultTitle?: string;
|
|
4
|
+
brandName?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function extractLayoutTitleTemplate(layoutCode: string): LayoutTitleTemplate | null;
|
|
7
|
+
export declare function sanitizePageTitleForLayout(pageTitle: string, layoutTemplate: LayoutTitleTemplate | null): string;
|
|
8
|
+
//# sourceMappingURL=layout-title-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-title-resolver.d.ts","sourceRoot":"","sources":["../src/layout-title-resolver.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAqBzF;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,mBAAmB,GAAG,IAAI,GAAG,MAAM,CAOhH"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function extractLayoutTitleTemplate(layoutCode) {
|
|
2
|
+
const match = /title\s*:\s*\{([^}]+)\}/m.exec(layoutCode);
|
|
3
|
+
if (!match || !match[1])
|
|
4
|
+
return null;
|
|
5
|
+
const body = match[1];
|
|
6
|
+
const templateMatch = /template\s*:\s*['"`]([^'"`]+)['"`]/.exec(body);
|
|
7
|
+
const defaultMatch = /default\s*:\s*['"`]([^'"`]+)['"`]/.exec(body);
|
|
8
|
+
const template = templateMatch?.[1];
|
|
9
|
+
const defaultTitle = defaultMatch?.[1];
|
|
10
|
+
let brandName;
|
|
11
|
+
if (template && template.includes('%s')) {
|
|
12
|
+
brandName = template.replace('%s', '').replace(/^[| -]+|[| -]+$/g, '').trim();
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
template,
|
|
16
|
+
defaultTitle,
|
|
17
|
+
brandName,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function sanitizePageTitleForLayout(pageTitle, layoutTemplate) {
|
|
21
|
+
if (!layoutTemplate?.brandName) {
|
|
22
|
+
return pageTitle;
|
|
23
|
+
}
|
|
24
|
+
const brand = layoutTemplate.brandName;
|
|
25
|
+
const regex = new RegExp(`(\\s*[|\\-]\\s*${brand.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')})+$`, 'i');
|
|
26
|
+
return pageTitle.replace(regex, '').trim();
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=layout-title-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-title-resolver.js","sourceRoot":"","sources":["../src/layout-title-resolver.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,MAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,aAAa,GAAG,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpE,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,MAAM,YAAY,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,IAAI,SAA6B,CAAC;IAClC,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChF,CAAC;IAED,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,SAAiB,EAAE,cAA0C;IACtG,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,kBAAkB,KAAK,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrG,OAAO,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare function isPrivateRoutePattern(pattern: string): boolean;
|
|
4
|
+
export declare function appRouterPathToPattern(relPath: string): string;
|
|
5
|
+
export declare function pagesRouterPathToPattern(relPath: string): string;
|
|
6
|
+
export declare class NextJsAdapter implements FrameworkAdapter {
|
|
7
|
+
readonly id = "nextjs";
|
|
8
|
+
readonly name = "Next.js (App Router & Pages Router)";
|
|
9
|
+
readonly version: "1.0";
|
|
10
|
+
readonly capabilities: AdapterCapabilities;
|
|
11
|
+
detect(_projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>): Promise<boolean>;
|
|
12
|
+
discoverRoutes(_projectRoot: string, filePaths: ReadonlyArray<string>, contentsByPath: ReadonlyMap<string, string>, sitemapPaths: ReadonlySet<string>): Promise<ReadonlyArray<DiscoveredRoute>>;
|
|
13
|
+
extractRoute(_projectRoot: string, route: DiscoveredRoute, fileContent: string): Promise<ExtractedRouteData>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=nextjs-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-adapter.d.ts","sourceRoot":"","sources":["../src/nextjs-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;AAQ3E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,qBAAa,aAAc,YAAW,gBAAgB;IACpD,SAAgB,EAAE,YAAY;IAC9B,SAAgB,IAAI,yCAAyC;IAC7D,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;IAaN,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;IAsC7B,YAAY,CACvB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAG/B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { detectRenderingModeFromTsx, parseTsxRouteFile, } from './parsers/tsx-ast-parser.js';
|
|
2
|
+
const PRIVATE_ROUTE_PREFIXES = ['/admin', '/dashboard', '/login', '/auth', '/api', '/account'];
|
|
3
|
+
export function isPrivateRoutePattern(pattern) {
|
|
4
|
+
const lower = pattern.toLowerCase();
|
|
5
|
+
return PRIVATE_ROUTE_PREFIXES.some((prefix) => lower === prefix || lower.startsWith(`${prefix}/`));
|
|
6
|
+
}
|
|
7
|
+
export function appRouterPathToPattern(relPath) {
|
|
8
|
+
const withoutPrefix = relPath.replace(/^(src\/)?app\//, '');
|
|
9
|
+
const withoutPage = withoutPrefix.replace(/\/?page\.(tsx|ts|jsx|js|mdx)$/, '');
|
|
10
|
+
const segments = withoutPage
|
|
11
|
+
.split('/')
|
|
12
|
+
.filter((s) => s.length > 0 && !(s.startsWith('(') && s.endsWith(')')));
|
|
13
|
+
return segments.length === 0 ? '/' : `/${segments.join('/')}`;
|
|
14
|
+
}
|
|
15
|
+
export function pagesRouterPathToPattern(relPath) {
|
|
16
|
+
const withoutPrefix = relPath.replace(/^(src\/)?pages\//, '');
|
|
17
|
+
const withoutExt = withoutPrefix.replace(/\.(tsx|ts|jsx|js)$/, '');
|
|
18
|
+
if (withoutExt === 'index')
|
|
19
|
+
return '/';
|
|
20
|
+
const cleaned = withoutExt.replace(/\/index$/, '');
|
|
21
|
+
return `/${cleaned}`;
|
|
22
|
+
}
|
|
23
|
+
export class NextJsAdapter {
|
|
24
|
+
id = 'nextjs';
|
|
25
|
+
name = 'Next.js (App Router & Pages Router)';
|
|
26
|
+
version = '1.0';
|
|
27
|
+
capabilities = {
|
|
28
|
+
routes: true,
|
|
29
|
+
metadata: true,
|
|
30
|
+
headings: true,
|
|
31
|
+
internalLinks: true,
|
|
32
|
+
jsonLd: true,
|
|
33
|
+
images: true,
|
|
34
|
+
robotsAndSitemap: true,
|
|
35
|
+
};
|
|
36
|
+
async detect(_projectRoot, filePaths, contentsByPath) {
|
|
37
|
+
const pkgJson = contentsByPath.get('package.json');
|
|
38
|
+
if (pkgJson && /"next"\s*:/.test(pkgJson)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return filePaths.some((p) => /^next\.config\.(js|mjs|ts|cjs)$/.test(p) ||
|
|
42
|
+
/^(src\/)?app\/.*page\.(tsx|ts|jsx|js)$/.test(p) ||
|
|
43
|
+
/^(src\/)?pages\/.*\.(tsx|ts|jsx|js)$/.test(p));
|
|
44
|
+
}
|
|
45
|
+
async discoverRoutes(_projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
46
|
+
const routes = [];
|
|
47
|
+
for (const filePath of filePaths) {
|
|
48
|
+
if (/^(src\/)?app\/(.*\/)?page\.(tsx|ts|jsx|js)$/.test(filePath)) {
|
|
49
|
+
const pattern = appRouterPathToPattern(filePath);
|
|
50
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
51
|
+
routes.push({
|
|
52
|
+
pattern,
|
|
53
|
+
filePath,
|
|
54
|
+
routerKind: 'nextjs-app',
|
|
55
|
+
renderingMode: detectRenderingModeFromTsx(content),
|
|
56
|
+
isPrivate: isPrivateRoutePattern(pattern),
|
|
57
|
+
inSitemap: sitemapPaths.has(pattern),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else if (/^(src\/)?pages\/.*\.(tsx|ts|jsx|js)$/.test(filePath) &&
|
|
61
|
+
!/\/_app\./.test(filePath) &&
|
|
62
|
+
!/\/_document\./.test(filePath) &&
|
|
63
|
+
!/\/_error\./.test(filePath) &&
|
|
64
|
+
!/^(src\/)?pages\/api\//.test(filePath)) {
|
|
65
|
+
const pattern = pagesRouterPathToPattern(filePath);
|
|
66
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
67
|
+
routes.push({
|
|
68
|
+
pattern,
|
|
69
|
+
filePath,
|
|
70
|
+
routerKind: 'nextjs-pages',
|
|
71
|
+
renderingMode: detectRenderingModeFromTsx(content),
|
|
72
|
+
isPrivate: isPrivateRoutePattern(pattern),
|
|
73
|
+
inSitemap: sitemapPaths.has(pattern),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return routes;
|
|
78
|
+
}
|
|
79
|
+
async extractRoute(_projectRoot, route, fileContent) {
|
|
80
|
+
return parseTsxRouteFile(route, fileContent);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=nextjs-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-adapter.js","sourceRoot":"","sources":["../src/nextjs-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAErC,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/F,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,sBAAsB,CAAC,IAAI,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,WAAW;SACzB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IACnE,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,OAAO,aAAa;IACR,EAAE,GAAG,QAAQ,CAAC;IACd,IAAI,GAAG,qCAAqC,CAAC;IAC7C,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,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,EAAE,CACJ,iCAAiC,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,sCAAsC,CAAC,IAAI,CAAC,CAAC,CAAC,CACjD,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,cAAc,CACzB,YAAoB,EACpB,SAAgC,EAChC,cAA2C,EAC3C,YAAiC;QAEjC,MAAM,MAAM,GAAsB,EAAE,CAAC;QAErC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,6CAA6C,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjE,MAAM,OAAO,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;gBACjD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnD,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO;oBACP,QAAQ;oBACR,UAAU,EAAE,YAAY;oBACxB,aAAa,EAAE,0BAA0B,CAAC,OAAO,CAAC;oBAClD,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC;oBACzC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;iBAAM,IACL,sCAAsC,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACrD,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC1B,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC/B,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC5B,CAAC,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,EACvC,CAAC;gBACD,MAAM,OAAO,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;gBACnD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnD,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO;oBACP,QAAQ;oBACR,UAAU,EAAE,cAAc;oBAC1B,aAAa,EAAE,0BAA0B,CAAC,OAAO,CAAC;oBAClD,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC;oBACzC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,YAAY,CACvB,YAAoB,EACpB,KAAsB,EACtB,WAAmB;QAEnB,OAAO,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
import type { AdapterCapabilities, AdapterVersion, FrameworkAdapter } from './contract.js';
|
|
3
|
+
export declare class NuxtAdapter implements FrameworkAdapter {
|
|
4
|
+
readonly id = "nuxt";
|
|
5
|
+
readonly name = "Nuxt 3";
|
|
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
|
+
export interface NuxtMetaFields {
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
canonical?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function patchNuxtTemplate(sourceCode: string, meta: NuxtMetaFields): string;
|
|
19
|
+
//# sourceMappingURL=nuxt-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt-adapter.d.ts","sourceRoot":"","sources":["../src/nuxt-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,WAAY,YAAW,gBAAgB;IAClD,SAAgB,EAAE,UAAU;IAC5B,SAAgB,IAAI,YAAY;IAChC,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;IAoBN,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;AAGD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,GACnB,MAAM,CAmBR"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { parseVueSfc } from './parsers/vue-sfc-parser.js';
|
|
2
|
+
import { normalizeRoutePattern } from './parsers/route-normalizer.js';
|
|
3
|
+
import { LayoutResolver } from './parsers/layout-resolver.js';
|
|
4
|
+
export class NuxtAdapter {
|
|
5
|
+
id = 'nuxt';
|
|
6
|
+
name = 'Nuxt 3';
|
|
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 === 'nuxt.config.ts' ||
|
|
22
|
+
normalized === 'nuxt.config.js' ||
|
|
23
|
+
normalized === 'nuxt.config.mjs') {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (normalized === 'package.json') {
|
|
27
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
28
|
+
if (content.includes('"nuxt"') || content.includes('"@nuxt/')) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
async discoverRoutes(projectRoot, filePaths, contentsByPath, sitemapPaths) {
|
|
36
|
+
const routes = [];
|
|
37
|
+
// Pre-cache layouts from layouts/**
|
|
38
|
+
for (const filePath of filePaths) {
|
|
39
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
40
|
+
if (normalized.startsWith('layouts/') && normalized.endsWith('.vue')) {
|
|
41
|
+
const content = contentsByPath.get(filePath) ?? '';
|
|
42
|
+
const parsed = parseVueSfc({
|
|
43
|
+
pattern: '',
|
|
44
|
+
filePath,
|
|
45
|
+
routerKind: 'nuxt',
|
|
46
|
+
renderingMode: 'ssr-ssg',
|
|
47
|
+
isPrivate: false,
|
|
48
|
+
inSitemap: false,
|
|
49
|
+
}, content);
|
|
50
|
+
this.layoutResolver.registerLayout({
|
|
51
|
+
filePath,
|
|
52
|
+
htmlLang: parsed.htmlLang,
|
|
53
|
+
title: parsed.title,
|
|
54
|
+
description: parsed.description,
|
|
55
|
+
canonical: parsed.canonical,
|
|
56
|
+
robots: parsed.robots,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const filePath of filePaths) {
|
|
61
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
62
|
+
if (!normalized.startsWith('pages/'))
|
|
63
|
+
continue;
|
|
64
|
+
if (!normalized.endsWith('.vue'))
|
|
65
|
+
continue;
|
|
66
|
+
const relativeInsidePages = normalized.slice('pages/'.length);
|
|
67
|
+
const pattern = normalizeRoutePattern(relativeInsidePages, 'nuxt');
|
|
68
|
+
const inSitemap = sitemapPaths.has(pattern);
|
|
69
|
+
routes.push({
|
|
70
|
+
pattern,
|
|
71
|
+
filePath,
|
|
72
|
+
routerKind: 'nuxt',
|
|
73
|
+
renderingMode: 'ssr-ssg',
|
|
74
|
+
isPrivate: false,
|
|
75
|
+
inSitemap,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return routes;
|
|
79
|
+
}
|
|
80
|
+
async extractRoute(projectRoot, route, fileContent) {
|
|
81
|
+
let extracted = parseVueSfc(route, fileContent);
|
|
82
|
+
// Inherit from default layout if present
|
|
83
|
+
const layoutCandidates = ['layouts/default.vue', 'layouts/main.vue'];
|
|
84
|
+
extracted = this.layoutResolver.applyInheritance(extracted, layoutCandidates);
|
|
85
|
+
return extracted;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function patchNuxtTemplate(sourceCode, meta) {
|
|
89
|
+
let result = sourceCode;
|
|
90
|
+
const entries = [];
|
|
91
|
+
if (meta.title)
|
|
92
|
+
entries.push(` title: '${meta.title.replace(/'/g, "\\'")}',`);
|
|
93
|
+
if (meta.description)
|
|
94
|
+
entries.push(` description: '${meta.description.replace(/'/g, "\\'")}',`);
|
|
95
|
+
if (meta.canonical)
|
|
96
|
+
entries.push(` canonical: '${meta.canonical}',`);
|
|
97
|
+
const seoMetaCall = `useSeoMeta({\n${entries.join('\n')}\n});\n`;
|
|
98
|
+
if (/<script\s+setup[^>]*>/i.test(result)) {
|
|
99
|
+
if (!/useSeoMeta\s*\(/i.test(result)) {
|
|
100
|
+
result = result.replace(/(<script\s+setup[^>]*>\s*\n)/i, `$1${seoMetaCall}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
result = `<script setup lang="ts">\n${seoMetaCall}</script>\n\n` + result;
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=nuxt-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt-adapter.js","sourceRoot":"","sources":["../src/nuxt-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DiscoveredRoute, ExtractedRouteData } from '@seo-partner/core';
|
|
2
|
+
export interface AstroParseResult {
|
|
3
|
+
readonly routeData: ExtractedRouteData;
|
|
4
|
+
readonly layoutReference?: string;
|
|
5
|
+
readonly layoutProps?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseAstroOrMarkdown(route: DiscoveredRoute, fileContent: string): AstroParseResult;
|
|
8
|
+
//# sourceMappingURL=astro-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astro-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/astro-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAKnB,MAAM,mBAAmB,CAAC;AAgB3B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,gBAAgB,CAuNlB"}
|