@lynxflow/seo-engine 1.8.30 → 2.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.
Files changed (96) hide show
  1. package/README.md +47 -93
  2. package/dist/ai-copilot-client.d.ts +2 -0
  3. package/dist/built-in-locations.d.ts +18 -0
  4. package/dist/content-ai-arsenal.d.ts +28 -0
  5. package/dist/existing-media-harvester.d.ts +33 -0
  6. package/dist/extended-schemas.d.ts +84 -0
  7. package/dist/features-knowledge-harvester.d.ts +56 -0
  8. package/dist/geo-citation-scorer.d.ts +34 -0
  9. package/dist/i18n-detector.d.ts +1 -1
  10. package/dist/index.d.ts +32 -7
  11. package/dist/index.js +538 -82
  12. package/dist/index.mjs +2028 -163
  13. package/dist/internal-pagerank-graph.d.ts +59 -0
  14. package/dist/knowledge-bank-builder.d.ts +91 -0
  15. package/dist/marketing-skills-engine.d.ts +74 -0
  16. package/dist/matrix-engine.d.ts +26 -0
  17. package/dist/power-words-psychology.d.ts +27 -15
  18. package/dist/public-manifest-engine.d.ts +58 -0
  19. package/dist/rag-knowledge-engine.d.ts +50 -0
  20. package/dist/rate-limited-translator.d.ts +19 -0
  21. package/dist/token-quota-manager.d.ts +4 -0
  22. package/package.json +11 -3
  23. package/TUTORIEL_INTEGRATION_SITE.md +0 -283
  24. package/connectors/cloudflare-worker/worker.js +0 -106
  25. package/connectors/laravel/LynxSeoController.php +0 -37
  26. package/connectors/wordpress/lynxseo-admin-app.js +0 -2611
  27. package/connectors/wordpress/lynxseo-connector.php +0 -1712
  28. package/connectors/wordpress/lynxseo-connector.zip +0 -0
  29. package/lynxflow-seo-engine-1.2.0.tgz +0 -0
  30. package/src/ad-intelligence-cro.ts +0 -140
  31. package/src/ai-bots-log-analyzer.ts +0 -127
  32. package/src/ai-copilot-client.ts +0 -99
  33. package/src/analytics-client.ts +0 -315
  34. package/src/auth-key.ts +0 -262
  35. package/src/backlinks-client.ts +0 -85
  36. package/src/brand-dna-calendar.ts +0 -120
  37. package/src/brand-icons.ts +0 -138
  38. package/src/built-in-locations.ts +0 -170
  39. package/src/content-ai-arsenal.ts +0 -268
  40. package/src/copy-frameworks-master.ts +0 -89
  41. package/src/cro-copywriting-engine.ts +0 -105
  42. package/src/crosslink-scorer.ts +0 -101
  43. package/src/embeddable-seo-widget.ts +0 -57
  44. package/src/engine.test.ts +0 -386
  45. package/src/engine.ts +0 -813
  46. package/src/existing-media-harvester.ts +0 -98
  47. package/src/extended-schemas.ts +0 -589
  48. package/src/features-knowledge-harvester.ts +0 -190
  49. package/src/free-public-tools.ts +0 -224
  50. package/src/geo-mesh-linking.ts +0 -93
  51. package/src/google-business-profile.ts +0 -280
  52. package/src/i18n-detector.ts +0 -98
  53. package/src/i18n-dictionary.ts +0 -422
  54. package/src/index.ts +0 -164
  55. package/src/indexnow-client.ts +0 -94
  56. package/src/instant-matrix-search.ts +0 -48
  57. package/src/isr-cache-manager.ts +0 -78
  58. package/src/keyword-permutator.ts +0 -118
  59. package/src/knowledge-bank-builder.ts +0 -299
  60. package/src/knowledge-graph-linker.ts +0 -81
  61. package/src/lago-token-meter.ts +0 -120
  62. package/src/legal-disclaimers.ts +0 -407
  63. package/src/llm-content-cleaner.ts +0 -64
  64. package/src/llm-prompt.ts +0 -323
  65. package/src/master-marketing-engine.ts +0 -314
  66. package/src/matrix-engine.ts +0 -1204
  67. package/src/mcp-seo-server.ts +0 -108
  68. package/src/ngram-density-analyzer.ts +0 -108
  69. package/src/og-image-generator.ts +0 -109
  70. package/src/power-words-psychology.ts +0 -369
  71. package/src/public-manifest-engine.ts +0 -109
  72. package/src/rag-knowledge-engine.ts +0 -163
  73. package/src/rank-math-parity.ts +0 -235
  74. package/src/rate-limited-translator.ts +0 -110
  75. package/src/real-reviews-sync.ts +0 -207
  76. package/src/rss-syndication-feed.ts +0 -56
  77. package/src/schema-builder.ts +0 -134
  78. package/src/seo-opportunities-decay.ts +0 -154
  79. package/src/serp-client.ts +0 -89
  80. package/src/serp-history-alerts.ts +0 -75
  81. package/src/site-auditor.ts +0 -83
  82. package/src/site-crawler.ts +0 -406
  83. package/src/slug-engine.ts +0 -183
  84. package/src/social-ads-seo.ts +0 -211
  85. package/src/social-growth-suite.ts +0 -310
  86. package/src/social-trend-seo.ts +0 -103
  87. package/src/social-video-seo.ts +0 -100
  88. package/src/team-rbac.ts +0 -61
  89. package/src/technical-rules-auditor.ts +0 -171
  90. package/src/token-quota-manager.ts +0 -91
  91. package/src/types.ts +0 -143
  92. package/src/ui-icons.ts +0 -134
  93. package/src/urlytics-engine.ts +0 -97
  94. package/src/video-youtube-analyzer.ts +0 -81
  95. package/src/yoast-parity.ts +0 -161
  96. package/tsconfig.json +0 -15
@@ -1,280 +0,0 @@
1
- export interface GoogleBusinessProfileConfig {
2
- placeId?: string;
3
- businessName: string;
4
- category: string;
5
- streetAddress: string;
6
- addressLocality: string;
7
- postalCode: string;
8
- addressCountry: string;
9
- telephone: string;
10
- priceRange?: string;
11
- latitude?: number;
12
- longitude?: number;
13
- openingHours?: string[]; // e.g. ["Mo-Fr 09:00-18:00", "Sa 10:00-16:00"]
14
- ratingValue?: number;
15
- reviewCount?: number;
16
- googleMapsUrl?: string;
17
- }
18
-
19
- export interface GbpAuditResult {
20
- score: number;
21
- grade: "A+" | "A" | "B" | "C" | "D";
22
- passedChecks: number;
23
- totalChecks: number;
24
- checks: Array<{
25
- name: string;
26
- status: "pass" | "warn" | "fail";
27
- points: number;
28
- description: string;
29
- recommendation?: string;
30
- }>;
31
- summary: string;
32
- localPackEligibility: "Excellente" | "Moyenne" | "Faible";
33
- }
34
-
35
- export class GoogleBusinessProfileEngine {
36
- /**
37
- * Generates Schema.org LocalBusiness JSON-LD structure matching Google specifications
38
- */
39
- static generateLocalBusinessSchema(config: GoogleBusinessProfileConfig) {
40
- const schema: Record<string, any> = {
41
- "@context": "https://schema.org",
42
- "@type": config.category || "LocalBusiness",
43
- "name": config.businessName,
44
- "address": {
45
- "@type": "PostalAddress",
46
- "streetAddress": config.streetAddress,
47
- "addressLocality": config.addressLocality,
48
- "postalCode": config.postalCode,
49
- "addressCountry": config.addressCountry || "FR"
50
- },
51
- "telephone": config.telephone,
52
- "priceRange": config.priceRange || "€€"
53
- };
54
-
55
- if (config.latitude && config.longitude) {
56
- schema.geo = {
57
- "@type": "GeoCoordinates",
58
- "latitude": config.latitude,
59
- "longitude": config.longitude
60
- };
61
- }
62
-
63
- if (config.openingHours && config.openingHours.length > 0) {
64
- schema.openingHours = config.openingHours;
65
- }
66
-
67
- if (config.ratingValue && config.reviewCount) {
68
- schema.aggregateRating = {
69
- "@type": "AggregateRating",
70
- "ratingValue": config.ratingValue.toString(),
71
- "reviewCount": config.reviewCount.toString(),
72
- "bestRating": "5",
73
- "worstRating": "1"
74
- };
75
- }
76
-
77
- if (config.googleMapsUrl || config.placeId) {
78
- schema.hasMap = config.googleMapsUrl || `https://www.google.com/maps/place/?q=place_id:${config.placeId}`;
79
- }
80
-
81
- return schema;
82
- }
83
-
84
- /**
85
- * Generates interactive HTML Badge with Google Review stars and direct Maps link
86
- */
87
- static generateGbpBadgeHtml(config: GoogleBusinessProfileConfig): string {
88
- const stars = "★".repeat(Math.round(config.ratingValue || 5)) + "☆".repeat(5 - Math.round(config.ratingValue || 5));
89
- const mapsUrl = config.googleMapsUrl || (config.placeId ? `https://www.google.com/maps/place/?q=place_id:${config.placeId}` : "#");
90
-
91
- return `
92
- <div style="background:#ffffff;border:1px solid #e2e8f0;border-radius:12px;padding:16px 20px;max-width:420px;box-shadow:0 2px 4px rgba(0,0,0,0.04);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
93
- <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
94
- <div style="display:flex;align-items:center;gap:8px;">
95
- <svg width="20" height="20" viewBox="0 0 24 24" fill="#4285F4"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></svg>
96
- <strong style="font-size:15px;color:#0f172a;">${config.businessName}</strong>
97
- </div>
98
- <span style="font-size:11px;font-weight:700;color:#166534;background:#dcfce7;padding:2px 8px;border-radius:999px;">Vérifié Google</span>
99
- </div>
100
- <div style="font-size:13px;color:#475569;margin-bottom:8px;">
101
- ${config.streetAddress}, ${config.postalCode} ${config.addressLocality}
102
- </div>
103
- <div style="display:flex;align-items:center;justify-content:space-between;border-top:1px solid #f1f5f9;padding-top:10px;">
104
- <div style="display:flex;align-items:center;gap:6px;">
105
- <span style="color:#f59e0b;letter-spacing:1px;font-size:14px;">${stars}</span>
106
- <strong style="font-size:13px;color:#0f172a;">${config.ratingValue || "4.9"}/5</strong>
107
- <span style="font-size:12px;color:#64748b;">(${config.reviewCount || "128"} avis)</span>
108
- </div>
109
- <a href="${mapsUrl}" target="_blank" rel="noopener noreferrer" style="font-size:12px;color:#2563eb;font-weight:600;text-decoration:none;">Voir sur Google Maps &rarr;</a>
110
- </div>
111
- </div>
112
- `.trim();
113
- }
114
-
115
- /**
116
- * Complete Diagnostic & Audit of a Google Business Profile / Local SEO setup
117
- */
118
- static auditProfile(config: GoogleBusinessProfileConfig): GbpAuditResult {
119
- const checks: GbpAuditResult["checks"] = [];
120
- let score = 0;
121
-
122
- // 1. Nom d'établissement
123
- if (config.businessName && config.businessName.length >= 3) {
124
- checks.push({
125
- name: "Nom de l'établissement (NAP)",
126
- status: "pass",
127
- points: 15,
128
- description: `Nom correctement configuré : "${config.businessName}".`
129
- });
130
- score += 15;
131
- } else {
132
- checks.push({
133
- name: "Nom de l'établissement (NAP)",
134
- status: "fail",
135
- points: 15,
136
- description: "Nom d'établissement manquant ou trop court.",
137
- recommendation: "Renseignez le nom exact de votre entreprise tel qu'affiché sur Google Maps."
138
- });
139
- }
140
-
141
- // 2. Adresse & Code Postal
142
- if (config.streetAddress && config.postalCode && config.addressLocality) {
143
- checks.push({
144
- name: "Adresse physique complète",
145
- status: "pass",
146
- points: 20,
147
- description: `Adresse géolocalisée : ${config.streetAddress}, ${config.postalCode} ${config.addressLocality}.`
148
- });
149
- score += 20;
150
- } else {
151
- checks.push({
152
- name: "Adresse physique complète",
153
- status: "fail",
154
- points: 20,
155
- description: "Adresse ou code postal incomplet.",
156
- recommendation: "Renseignez la rue, le code postal et la ville pour le ciblage Google Maps Local Pack."
157
- });
158
- }
159
-
160
- // 3. Téléphone
161
- if (config.telephone && config.telephone.length >= 8) {
162
- checks.push({
163
- name: "Téléphone direct vérifié",
164
- status: "pass",
165
- points: 10,
166
- description: `Numéro de contact : ${config.telephone}.`
167
- });
168
- score += 10;
169
- } else {
170
- checks.push({
171
- name: "Téléphone direct vérifié",
172
- status: "warn",
173
- points: 10,
174
- description: "Numéro de téléphone absent.",
175
- recommendation: "Ajoutez un numéro de téléphone fixe ou mobile local pour permettre les appels directs depuis les SERP."
176
- });
177
- }
178
-
179
- // 4. Coordonnées GPS
180
- if (config.latitude && config.longitude && !isNaN(config.latitude) && !isNaN(config.longitude)) {
181
- checks.push({
182
- name: "Coordonnées GPS (Lat / Long)",
183
- status: "pass",
184
- points: 15,
185
- description: `Positionnement précis : ${config.latitude}, ${config.longitude}.`
186
- });
187
- score += 15;
188
- } else {
189
- checks.push({
190
- name: "Coordonnées GPS (Lat / Long)",
191
- status: "fail",
192
- points: 15,
193
- description: "Coordonnées GPS manquantes dans le schéma.",
194
- recommendation: "Ajoutez les coordonnées de latitude/longitude exactes pour optimiser l'affichage dans le Google 3-Pack."
195
- });
196
- }
197
-
198
- // 5. Horaires d'ouverture
199
- if (config.openingHours && config.openingHours.length > 0) {
200
- checks.push({
201
- name: "Horaires d'ouverture",
202
- status: "pass",
203
- points: 10,
204
- description: `${config.openingHours.length} créneau(x) d'ouverture configuré(s).`
205
- });
206
- score += 10;
207
- } else {
208
- checks.push({
209
- name: "Horaires d'ouverture",
210
- status: "warn",
211
- points: 10,
212
- description: "Horaires d'ouverture non spécifiés.",
213
- recommendation: "Indiquez vos horaires (ex: Mo-Fr 09:00-18:00) pour rassurer les clients et éviter le statut 'Fermé'."
214
- });
215
- }
216
-
217
- // 6. Note Google & Volume d'Avis
218
- const rating = config.ratingValue || 0;
219
- const reviews = config.reviewCount || 0;
220
- if (rating >= 4.5 && reviews >= 20) {
221
- checks.push({
222
- name: "Réputation & Preuve Sociale",
223
- status: "pass",
224
- points: 20,
225
- description: `Excellente réputation : ${rating}/5 étoiles sur ${reviews} avis.`
226
- });
227
- score += 20;
228
- } else if (rating >= 4.0 && reviews > 0) {
229
- checks.push({
230
- name: "Réputation & Preuve Sociale",
231
- status: "warn",
232
- points: 10,
233
- description: `Note de ${rating}/5 avec ${reviews} avis.`,
234
- recommendation: "Augmentez le volume d'avis certifiés au-delà de 20 avis pour maximiser le taux de conversion."
235
- });
236
- score += 10;
237
- } else {
238
- checks.push({
239
- name: "Réputation & Preuve Sociale",
240
- status: "fail",
241
- points: 20,
242
- description: "Avis clients absents ou note inférieure à 4.0.",
243
- recommendation: "Activez la collecte d'avis clients réels pour afficher les étoiles dorées dans Google."
244
- });
245
- }
246
-
247
- // 7. Lien Google Maps ou Place ID
248
- if (config.placeId || config.googleMapsUrl) {
249
- checks.push({
250
- name: "Lien Google Place ID officiel",
251
- status: "pass",
252
- points: 10,
253
- description: "Lien direct vers la fiche Maps configuré."
254
- });
255
- score += 10;
256
- } else {
257
- checks.push({
258
- name: "Lien Google Place ID officiel",
259
- status: "warn",
260
- points: 10,
261
- description: "Place ID Google non renseigné.",
262
- recommendation: "Associez votre Place ID Google pour faciliter l'indexation par Google Maps."
263
- });
264
- }
265
-
266
- const passedChecks = checks.filter(c => c.status === "pass").length;
267
- const grade: GbpAuditResult["grade"] = score >= 90 ? "A+" : score >= 75 ? "A" : score >= 60 ? "B" : score >= 40 ? "C" : "D";
268
- const eligibility: GbpAuditResult["localPackEligibility"] = score >= 80 ? "Excellente" : score >= 50 ? "Moyenne" : "Faible";
269
-
270
- return {
271
- score,
272
- grade,
273
- passedChecks,
274
- totalChecks: checks.length,
275
- checks,
276
- summary: `Score Local SEO de ${score}/100 (Grade ${grade}) — Éligibilité Google Local 3-Pack : ${eligibility}.`,
277
- localPackEligibility: eligibility
278
- };
279
- }
280
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * 🌐 Dynamic i18n & Locale Auto-Detector
3
- * Automatically detects and synchronizes website locales without requiring hardcoded lists.
4
- * Compatible with next-intl, next-i18next, i18next, Paraglide, and Astro i18n.
5
- */
6
-
7
- export const SUPPORTED_CANONICAL_LOCALES = [
8
- "en",
9
- "fr",
10
- "es",
11
- "de",
12
- "it",
13
- "pt",
14
- "nl",
15
- "ru",
16
- "tr",
17
- "zh",
18
- "ja",
19
- "ko",
20
- "hi",
21
- "id",
22
- "ar",
23
- "pl",
24
- "sv",
25
- "no",
26
- "da",
27
- "fi",
28
- "cs",
29
- "el",
30
- "ro",
31
- "hu",
32
- "uk",
33
- "vi",
34
- "th",
35
- "ms",
36
- "bg",
37
- "hr",
38
- "sk",
39
- "sl",
40
- "et",
41
- "lv",
42
- "lt",
43
- "fa",
44
- "bn",
45
- "ta",
46
- "sw",
47
- "af",
48
- "tl",
49
- ] as const;
50
-
51
- export type SupportedLocale = (typeof SUPPORTED_CANONICAL_LOCALES)[number];
52
-
53
- export class I18nDetector {
54
- /**
55
- * Resolves a clean 2-letter ISO language code from any locale string (e.g. "fr-FR" -> "fr").
56
- */
57
- static normalizeLocale(localeInput?: string): string {
58
- if (!localeInput || typeof localeInput !== "string") return "en";
59
- const clean = localeInput.toLowerCase().split(/[-_]/)[0].trim();
60
- return clean || "en";
61
- }
62
-
63
- /**
64
- * Auto-detects and extracts active locales from common environment variables or array inputs.
65
- */
66
- static resolveActiveLocales(explicitLocales?: string[] | string): string[] {
67
- if (explicitLocales) {
68
- const list = Array.isArray(explicitLocales) ? explicitLocales : [explicitLocales];
69
- const normalized = list.map((l) => this.normalizeLocale(l)).filter(Boolean);
70
- return Array.from(new Set(normalized));
71
- }
72
-
73
- // Default fallback
74
- return ["en", "fr"];
75
- }
76
-
77
- /**
78
- * Matches whether a given path segment is a language prefix (e.g. "/fr/autopost-facebook/paris").
79
- */
80
- static extractLocaleFromPath(pathname: string, activeLocales: string[]): { locale: string; remainingPath: string } {
81
- const cleanPath = pathname.startsWith("/") ? pathname : `/${pathname}`;
82
- const segments = cleanPath.split("/").filter(Boolean);
83
-
84
- if (segments.length > 0 && activeLocales.includes(segments[0].toLowerCase())) {
85
- const locale = segments[0].toLowerCase();
86
- const remainingSegments = segments.slice(1);
87
- return {
88
- locale,
89
- remainingPath: `/${remainingSegments.join("/")}`,
90
- };
91
- }
92
-
93
- return {
94
- locale: activeLocales[0] || "en",
95
- remainingPath: cleanPath,
96
- };
97
- }
98
- }