@lynxflow/seo-engine 1.0.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -82
- package/connectors/cloudflare-worker/worker.js +54 -26
- package/connectors/laravel/LynxSeoController.php +8 -8
- package/connectors/wordpress/lynxseo-connector.php +296 -53
- package/dist/ai-copilot-client.d.ts +36 -0
- package/dist/analytics-client.d.ts +53 -0
- package/dist/auth-key.d.ts +57 -0
- package/dist/backlinks-client.d.ts +31 -0
- package/dist/engine.d.ts +79 -0
- package/dist/i18n-dictionary.d.ts +30 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +1561 -169
- package/dist/index.mjs +1759 -0
- package/dist/indexnow-client.d.ts +25 -0
- package/dist/lago-token-meter.d.ts +36 -0
- package/dist/schema-builder.d.ts +27 -0
- package/dist/serp-client.d.ts +42 -0
- package/dist/site-auditor.d.ts +29 -0
- package/dist/site-crawler.d.ts +76 -0
- package/dist/src/ai-copilot-client.d.ts +36 -0
- package/dist/src/analytics-client.d.ts +53 -0
- package/dist/src/auth-key.d.ts +57 -0
- package/dist/src/backlinks-client.d.ts +31 -0
- package/dist/src/engine.d.ts +72 -0
- package/dist/src/i18n-dictionary.d.ts +30 -0
- package/dist/src/index.d.ts +42 -0
- package/dist/src/indexnow-client.d.ts +25 -0
- package/dist/src/lago-token-meter.d.ts +36 -0
- package/dist/src/schema-builder.d.ts +27 -0
- package/dist/src/serp-client.d.ts +42 -0
- package/dist/src/site-auditor.d.ts +29 -0
- package/dist/src/token-quota-manager.d.ts +37 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/token-quota-manager.d.ts +37 -0
- package/dist/types.d.ts +162 -0
- package/lynxflow-seo-engine-1.2.0.tgz +0 -0
- package/package.json +1 -1
- package/src/ai-copilot-client.ts +84 -0
- package/src/analytics-client.ts +141 -0
- package/src/auth-key.ts +203 -0
- package/src/backlinks-client.ts +85 -0
- package/src/engine.ts +508 -85
- package/src/i18n-dictionary.ts +362 -0
- package/src/index.ts +22 -4
- package/src/indexnow-client.ts +94 -0
- package/src/lago-token-meter.ts +7 -2
- package/src/schema-builder.ts +87 -0
- package/src/serp-client.ts +89 -0
- package/src/site-auditor.ts +83 -0
- package/src/site-crawler.ts +406 -0
- package/src/types.ts +148 -28
- package/tsconfig.json +14 -0
- package/lynxflow-seo-engine-1.0.0.tgz +0 -0
- package/src/licensing.ts +0 -138
package/src/types.ts
CHANGED
|
@@ -1,48 +1,168 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 🌟 Types & Interfaces for @lynxflow/seo-engine SDK
|
|
2
|
+
* 🌟 Types & Interfaces for @lynxflow/seo-engine Universal SDK
|
|
3
|
+
*
|
|
4
|
+
* Full Institutional pSEO Type System matching LynxFlow's 8 Programmatic Matrices:
|
|
5
|
+
* 1. 📍 Local & GEO : [Pillar/Service] × [City/Country]
|
|
6
|
+
* 2. 🥊 VS & Comparatifs : [Brand/Service] vs [Competitor]
|
|
7
|
+
* 3. 🔄 Alternatives : [Competitor] ➔ [Brand/Service]
|
|
8
|
+
* 4. 🏢 Secteurs & Métiers : [Service] × [Industry Vertical] (with localized ROI)
|
|
9
|
+
* 5. 🔌 Intégrations : [Service] × [Third-party Software]
|
|
10
|
+
* 6. 👤 Personas & Décideurs : [Service] × [Decision Maker Role]
|
|
11
|
+
* 7. 🎯 Cas d'Usage : [Problem Statement] ➔ [AI Workflow Solution]
|
|
12
|
+
* 8. 🧮 Simulateurs & Outils : Interactive ROI & Time-Savings Calculators
|
|
3
13
|
*/
|
|
4
14
|
|
|
15
|
+
export interface LynxServiceDefinition {
|
|
16
|
+
slug: string;
|
|
17
|
+
name: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
pricePerMonth: number;
|
|
20
|
+
category?: string;
|
|
21
|
+
features?: string[];
|
|
22
|
+
faqs?: { question: string; answer: string }[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface PseoIndustry {
|
|
26
|
+
slug: string;
|
|
27
|
+
name: string;
|
|
28
|
+
singular: string;
|
|
29
|
+
category: string;
|
|
30
|
+
badge?: string;
|
|
31
|
+
painPoints?: string[];
|
|
32
|
+
targetSolutions?: string[];
|
|
33
|
+
roiMonthlySavings?: number;
|
|
34
|
+
hoursSavedWeekly?: number;
|
|
35
|
+
conversionBoost?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PseoCompetitor {
|
|
39
|
+
slug: string;
|
|
40
|
+
name: string;
|
|
41
|
+
badge?: string;
|
|
42
|
+
category: string;
|
|
43
|
+
priceRange?: string;
|
|
44
|
+
strengths?: string[];
|
|
45
|
+
weaknesses?: string[];
|
|
46
|
+
whySwitchToUs?: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface PseoIntegration {
|
|
50
|
+
slug: string;
|
|
51
|
+
name: string;
|
|
52
|
+
category: string;
|
|
53
|
+
badge?: string;
|
|
54
|
+
syncFeatures?: string[];
|
|
55
|
+
setupTimeMinutes?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface PseoUseCase {
|
|
59
|
+
slug: string;
|
|
60
|
+
title: string;
|
|
61
|
+
problem: string;
|
|
62
|
+
aiSolution: string;
|
|
63
|
+
measurableOutcome?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface PseoPersona {
|
|
67
|
+
slug: string;
|
|
68
|
+
role: string;
|
|
69
|
+
department: string;
|
|
70
|
+
topResponsibilities?: string[];
|
|
71
|
+
timeWastersAutomated?: string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface PseoCity {
|
|
75
|
+
slug: string;
|
|
76
|
+
name: string;
|
|
77
|
+
region: string;
|
|
78
|
+
country: string;
|
|
79
|
+
department?: string;
|
|
80
|
+
densityTier?: "major" | "secondary" | "regional";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface PseoCountry {
|
|
84
|
+
code: string;
|
|
85
|
+
name: string;
|
|
86
|
+
currency: string;
|
|
87
|
+
currencySymbol: string;
|
|
88
|
+
locale: string;
|
|
89
|
+
economicMultiplier: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
5
92
|
export interface LynxSeoConfig {
|
|
6
|
-
|
|
93
|
+
apiKey?: string;
|
|
94
|
+
licenseKey?: string; // Deprecated: use apiKey
|
|
7
95
|
domain: string;
|
|
8
96
|
brandName: string;
|
|
9
97
|
category?: string;
|
|
98
|
+
defaultLocale?: string;
|
|
99
|
+
supportedLocales?: string[];
|
|
10
100
|
currency?: string;
|
|
11
101
|
currencySymbol?: string;
|
|
12
|
-
services:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
slug: string;
|
|
20
|
-
name: string;
|
|
21
|
-
}[];
|
|
102
|
+
services: LynxServiceDefinition[];
|
|
103
|
+
industries?: PseoIndustry[];
|
|
104
|
+
competitors?: PseoCompetitor[];
|
|
105
|
+
integrations?: PseoIntegration[];
|
|
106
|
+
personas?: PseoPersona[];
|
|
107
|
+
useCases?: PseoUseCase[];
|
|
108
|
+
cities?: PseoCity[];
|
|
22
109
|
}
|
|
23
110
|
|
|
24
111
|
export interface LynxResolvedPage {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
112
|
+
url: string;
|
|
113
|
+
title: string;
|
|
114
|
+
description: string;
|
|
115
|
+
h1: string;
|
|
116
|
+
directAnswer: string;
|
|
117
|
+
locale?: string;
|
|
118
|
+
hreflangs?: { lang: string; url: string }[];
|
|
119
|
+
faqs: { question: string; answer: string }[];
|
|
120
|
+
jsonLd: Record<string, unknown>;
|
|
121
|
+
htmlBody: string;
|
|
122
|
+
markdownBody: string;
|
|
123
|
+
executionTimeMs: number;
|
|
124
|
+
|
|
125
|
+
// Localized ROI data (when applicable)
|
|
126
|
+
localizedRoi?: {
|
|
127
|
+
monthlySavingsFormatted: string;
|
|
128
|
+
hoursSavedWeekly: number;
|
|
129
|
+
annualSavingsFormatted: string;
|
|
130
|
+
currencySymbol: string;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Structured component data
|
|
134
|
+
service?: LynxServiceDefinition;
|
|
135
|
+
industry?: PseoIndustry;
|
|
136
|
+
competitor?: PseoCompetitor;
|
|
137
|
+
integration?: PseoIntegration;
|
|
138
|
+
|
|
139
|
+
meta?: {
|
|
28
140
|
title: string;
|
|
29
141
|
description: string;
|
|
30
142
|
h1: string;
|
|
31
143
|
canonical: string;
|
|
32
|
-
openGraphImageUrl
|
|
144
|
+
openGraphImageUrl?: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Backward compatibility convenience fields
|
|
148
|
+
fullUrl?: string;
|
|
149
|
+
schemaJsonLd?: Record<string, unknown>;
|
|
150
|
+
content?: {
|
|
151
|
+
directAnswerGeoHtml?: string;
|
|
152
|
+
heroHeadline?: string;
|
|
153
|
+
heroSubheadline?: string;
|
|
154
|
+
markdownBody?: string;
|
|
155
|
+
faqList?: { question: string; answer: string }[];
|
|
33
156
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
heroSubheadline: string;
|
|
39
|
-
markdownBody: string;
|
|
40
|
-
faqList: { question: string; answer: string }[];
|
|
41
|
-
neighboringLinks: { name: string; url: string }[];
|
|
157
|
+
pricing?: {
|
|
158
|
+
priceNumber?: number;
|
|
159
|
+
priceFormatted?: string;
|
|
160
|
+
currency?: string;
|
|
42
161
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
162
|
+
|
|
163
|
+
debug?: {
|
|
164
|
+
licenseStatus?: "active" | "trial" | "expired" | "offline_mode";
|
|
165
|
+
generationMs?: number;
|
|
166
|
+
matrixType?: string;
|
|
46
167
|
};
|
|
47
|
-
executionTimeMs: number;
|
|
48
168
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"emitDeclarationOnly": true,
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"skipLibCheck": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"]
|
|
14
|
+
}
|
|
Binary file
|
package/src/licensing.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🔒 LynxFlow License Key Guardian & Cryptographic Issuer
|
|
3
|
-
*
|
|
4
|
-
* Manages enterprise cryptographic license keys, HMAC signatures,
|
|
5
|
-
* tenant quota boundaries, and subscription status synchronization with Lago & Hyperswitch.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { TokenQuotaManager } from "./token-quota-manager";
|
|
9
|
-
|
|
10
|
-
export interface LicenseValidationResult {
|
|
11
|
-
isValid: boolean;
|
|
12
|
-
tier: "starter" | "growth" | "enterprise";
|
|
13
|
-
tenantId?: string;
|
|
14
|
-
maxPages: number;
|
|
15
|
-
monthlyCreditBudget: number;
|
|
16
|
-
tokenManager: TokenQuotaManager;
|
|
17
|
-
subscriptionStatus: "active" | "trialing" | "past_due" | "canceled";
|
|
18
|
-
expiresAt?: string;
|
|
19
|
-
errorMessage?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class LicenseGuardian {
|
|
23
|
-
/**
|
|
24
|
-
* Generates a cryptographically signed license key for a tenant.
|
|
25
|
-
* Format: lynx_<tier>_<tenantId>_<shortChecksum>
|
|
26
|
-
*/
|
|
27
|
-
static generateKey(tenantId: string, tier: "starter" | "growth" | "enterprise" = "growth", secret = "lynxflow_secret_key"): string {
|
|
28
|
-
const raw = `${tenantId}:${tier}:${secret}`;
|
|
29
|
-
let hash = 0;
|
|
30
|
-
for (let i = 0; i < raw.length; i++) {
|
|
31
|
-
hash = ((hash << 5) - hash) + raw.charCodeAt(i);
|
|
32
|
-
hash |= 0;
|
|
33
|
-
}
|
|
34
|
-
const checksum = Math.abs(hash).toString(36).substring(0, 6);
|
|
35
|
-
return `lynx_${tier}_${tenantId}_${checksum}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Fast offline/online license validator with HMAC parsing.
|
|
40
|
-
*/
|
|
41
|
-
static validateKey(licenseKey?: string, secret = "lynxflow_secret_key"): LicenseValidationResult {
|
|
42
|
-
if (!licenseKey || typeof licenseKey !== "string") {
|
|
43
|
-
return {
|
|
44
|
-
isValid: false,
|
|
45
|
-
tier: "starter",
|
|
46
|
-
maxPages: 100,
|
|
47
|
-
monthlyCreditBudget: 500,
|
|
48
|
-
subscriptionStatus: "canceled",
|
|
49
|
-
tokenManager: new TokenQuotaManager("starter"),
|
|
50
|
-
errorMessage: "Missing or invalid LynxFlow license key. Please set LYNXFLOW_LICENSE_KEY or pass licenseKey in config.",
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const cleanKey = licenseKey.trim();
|
|
55
|
-
const parts = cleanKey.split("_");
|
|
56
|
-
// Extract tenantId preserving internal underscores: lynx_<tier>_<tenantId>_<checksum>
|
|
57
|
-
const tenantId = parts.length >= 4 ? parts.slice(2, -1).join("_") : (parts.length >= 3 ? parts[2] : "default_tenant");
|
|
58
|
-
|
|
59
|
-
// 1. Enterprise / Internal master keys
|
|
60
|
-
if (cleanKey.startsWith("lynx_enterprise_") || cleanKey.startsWith("lynx_live_") || cleanKey.startsWith("lynx_ent_")) {
|
|
61
|
-
return {
|
|
62
|
-
isValid: true,
|
|
63
|
-
tier: "enterprise",
|
|
64
|
-
tenantId,
|
|
65
|
-
maxPages: 5_000_000,
|
|
66
|
-
monthlyCreditBudget: 50_000,
|
|
67
|
-
subscriptionStatus: "active",
|
|
68
|
-
tokenManager: new TokenQuotaManager("enterprise"),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 2. Growth Tier keys
|
|
73
|
-
if (cleanKey.startsWith("lynx_growth_")) {
|
|
74
|
-
return {
|
|
75
|
-
isValid: true,
|
|
76
|
-
tier: "growth",
|
|
77
|
-
tenantId,
|
|
78
|
-
maxPages: 500_000,
|
|
79
|
-
monthlyCreditBudget: 5_000,
|
|
80
|
-
subscriptionStatus: "active",
|
|
81
|
-
tokenManager: new TokenQuotaManager("growth"),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// 3. Starter / Trial keys
|
|
86
|
-
if (cleanKey.startsWith("lynx_starter_") || cleanKey.startsWith("lynx_test_")) {
|
|
87
|
-
return {
|
|
88
|
-
isValid: true,
|
|
89
|
-
tier: "starter",
|
|
90
|
-
tenantId,
|
|
91
|
-
maxPages: 10_000,
|
|
92
|
-
monthlyCreditBudget: 500,
|
|
93
|
-
subscriptionStatus: "trialing",
|
|
94
|
-
tokenManager: new TokenQuotaManager("starter"),
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
isValid: false,
|
|
100
|
-
tier: "starter",
|
|
101
|
-
maxPages: 0,
|
|
102
|
-
monthlyCreditBudget: 0,
|
|
103
|
-
subscriptionStatus: "canceled",
|
|
104
|
-
tokenManager: new TokenQuotaManager("starter"),
|
|
105
|
-
errorMessage: "Unrecognized or corrupted LynxFlow license key signature.",
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Online real-time verification against LynxFlow's central API (optional).
|
|
111
|
-
*/
|
|
112
|
-
static async verifyOnline(licenseKey: string, apiEndpoint = "https://api.lynxintel.io/api/license/verify"): Promise<LicenseValidationResult> {
|
|
113
|
-
const offlineResult = this.validateKey(licenseKey);
|
|
114
|
-
if (!offlineResult.isValid) return offlineResult;
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const res = await fetch(apiEndpoint, {
|
|
118
|
-
method: "POST",
|
|
119
|
-
headers: { "Content-Type": "application/json" },
|
|
120
|
-
body: JSON.stringify({ licenseKey }),
|
|
121
|
-
signal: AbortSignal.timeout(3000),
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
if (res.ok) {
|
|
125
|
-
const data = await res.json();
|
|
126
|
-
return {
|
|
127
|
-
...offlineResult,
|
|
128
|
-
isValid: data.isValid ?? true,
|
|
129
|
-
subscriptionStatus: data.status ?? "active",
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
} catch {
|
|
133
|
-
// Graceful offline fallback: keep valid offline result if network is temporarily unreachable
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return offlineResult;
|
|
137
|
-
}
|
|
138
|
-
}
|