seo 0.2.19 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +82 -82
- package/dist/cli.js.map +1 -1
- package/dist/{dist-B0a6PpwF.js → dist-CtDv7OFQ.js} +129 -129
- package/dist/dist-CtDv7OFQ.js.map +1 -0
- package/dist/{dist-orqZyOnQ.js → dist-DXAAiZSX.js} +1 -1
- package/dist/{package-Dl66IhTH.js → esm-DvJj2-vq.js} +5 -5
- package/dist/esm-DvJj2-vq.js.map +1 -0
- package/dist/index.d.ts +14 -12
- package/dist/index.js +139 -89
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +97 -81
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-B0a6PpwF.js.map +0 -1
- package/dist/package-Dl66IhTH.js.map +0 -1
package/dist/mcp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __seoCreateRequire } from 'node:module'; const require = __seoCreateRequire(import.meta.url);
|
|
2
|
-
import { n as
|
|
2
|
+
import { n as version, t as load } from "./esm-DvJj2-vq.js";
|
|
3
3
|
import { Headers, fetch as fetch$1 } from "undici";
|
|
4
4
|
import { chmodSync, createReadStream, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { arch, homedir, platform, totalmem } from "node:os";
|
|
@@ -115,6 +115,86 @@ function seoErrorEnvelope(error) {
|
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
//#endregion
|
|
118
|
+
//#region packages/core/dist/version.js
|
|
119
|
+
const SEO_VERSION = version;
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region packages/core/dist/fetch/crawler-identity.js
|
|
122
|
+
const SEO_CRAWLER_TOKEN = "SEO-Skill";
|
|
123
|
+
const SEO_CRAWLER_USER_AGENT = `${SEO_CRAWLER_TOKEN}/${SEO_VERSION} (+https://seoskill.dev)`;
|
|
124
|
+
const SEO_CRAWLER_IDENTITY = {
|
|
125
|
+
name: "SEO Skill",
|
|
126
|
+
robotsToken: SEO_CRAWLER_TOKEN,
|
|
127
|
+
version: SEO_VERSION,
|
|
128
|
+
userAgent: SEO_CRAWLER_USER_AGENT,
|
|
129
|
+
documentationUrl: "https://seoskill.dev/docs/crawler/"
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region packages/core/dist/fetch/http-client.js
|
|
133
|
+
var ResponseSizeLimitError = class extends Error {
|
|
134
|
+
maxBytes;
|
|
135
|
+
constructor(maxBytes, label = "Response") {
|
|
136
|
+
super(`${label} exceeds the ${maxBytes}-byte response limit.`);
|
|
137
|
+
this.maxBytes = maxBytes;
|
|
138
|
+
this.name = "ResponseSizeLimitError";
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
function requestHeaders(profile) {
|
|
142
|
+
if (profile === "bot") return new Headers({
|
|
143
|
+
accept: "text/plain,*/*;q=0.8",
|
|
144
|
+
"accept-language": "en-US,en;q=0.9",
|
|
145
|
+
connection: "close",
|
|
146
|
+
"user-agent": SEO_CRAWLER_USER_AGENT
|
|
147
|
+
});
|
|
148
|
+
return new Headers({
|
|
149
|
+
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
150
|
+
"accept-language": "en-US,en;q=0.9",
|
|
151
|
+
connection: "close",
|
|
152
|
+
"sec-ch-ua-mobile": "?0",
|
|
153
|
+
"sec-ch-ua-platform": "\"macOS\"",
|
|
154
|
+
"upgrade-insecure-requests": "1",
|
|
155
|
+
"user-agent": SEO_CRAWLER_USER_AGENT
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function publicHttpFetch(url, input = {}) {
|
|
159
|
+
const { profile = "browser", headers, ...init } = input;
|
|
160
|
+
const base = requestHeaders(profile);
|
|
161
|
+
if (headers instanceof Headers) for (const [key, value] of headers.entries()) base.set(key, value);
|
|
162
|
+
else if (Array.isArray(headers)) for (const [key, value] of headers) base.set(key, value);
|
|
163
|
+
else if (headers) {
|
|
164
|
+
for (const [key, value] of Object.entries(headers)) if (value !== void 0) base.set(key, value);
|
|
165
|
+
}
|
|
166
|
+
return fetch$1(url, {
|
|
167
|
+
...init,
|
|
168
|
+
headers: base
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async function readBoundedResponseText(response, maxBytes, label = "Response") {
|
|
172
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
173
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
174
|
+
await response.body?.cancel().catch(() => void 0);
|
|
175
|
+
throw new ResponseSizeLimitError(maxBytes, label);
|
|
176
|
+
}
|
|
177
|
+
const reader = response.body?.getReader();
|
|
178
|
+
if (!reader) return "";
|
|
179
|
+
const chunks = [];
|
|
180
|
+
let total = 0;
|
|
181
|
+
try {
|
|
182
|
+
while (true) {
|
|
183
|
+
const { done, value } = await reader.read();
|
|
184
|
+
if (done) break;
|
|
185
|
+
total += value.byteLength;
|
|
186
|
+
if (total > maxBytes) {
|
|
187
|
+
await reader.cancel().catch(() => void 0);
|
|
188
|
+
throw new ResponseSizeLimitError(maxBytes, label);
|
|
189
|
+
}
|
|
190
|
+
chunks.push(value);
|
|
191
|
+
}
|
|
192
|
+
} finally {
|
|
193
|
+
reader.releaseLock();
|
|
194
|
+
}
|
|
195
|
+
return Buffer.concat(chunks, total).toString("utf8");
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
118
198
|
//#region packages/core/dist/paths.js
|
|
119
199
|
let memoizedPaths;
|
|
120
200
|
function defaultConfigDir(input) {
|
|
@@ -1558,6 +1638,22 @@ function hashKey(parts) {
|
|
|
1558
1638
|
return Buffer.from(json).toString("base64url");
|
|
1559
1639
|
}
|
|
1560
1640
|
//#endregion
|
|
1641
|
+
//#region packages/core/dist/ga4/account-summaries.js
|
|
1642
|
+
const propertySummarySchema = z.object({
|
|
1643
|
+
property: z.string().trim().min(1),
|
|
1644
|
+
displayName: z.string().optional(),
|
|
1645
|
+
propertyType: z.string().optional(),
|
|
1646
|
+
parent: z.string().optional()
|
|
1647
|
+
}).strip();
|
|
1648
|
+
z.object({
|
|
1649
|
+
accountSummaries: z.array(z.object({
|
|
1650
|
+
account: z.string().trim().min(1),
|
|
1651
|
+
displayName: z.string().optional(),
|
|
1652
|
+
propertySummaries: z.array(propertySummarySchema).optional()
|
|
1653
|
+
}).strip()).max(200).optional(),
|
|
1654
|
+
nextPageToken: z.string().optional()
|
|
1655
|
+
}).strip();
|
|
1656
|
+
//#endregion
|
|
1561
1657
|
//#region packages/core/dist/ga4/client.js
|
|
1562
1658
|
function ga4RequestCanUseCache(body) {
|
|
1563
1659
|
return body.dateRanges.every((range) => /^\d{4}-\d{2}-\d{2}$/.test(range.startDate) && /^\d{4}-\d{2}-\d{2}$/.test(range.endDate));
|
|
@@ -3410,20 +3506,6 @@ async function extractPage(fetchResult, extractor = "defuddle", dependencies = {
|
|
|
3410
3506
|
};
|
|
3411
3507
|
}
|
|
3412
3508
|
//#endregion
|
|
3413
|
-
//#region packages/core/dist/version.js
|
|
3414
|
-
const SEO_VERSION = version;
|
|
3415
|
-
//#endregion
|
|
3416
|
-
//#region packages/core/dist/fetch/crawler-identity.js
|
|
3417
|
-
const SEO_CRAWLER_TOKEN = "SEO-Skill";
|
|
3418
|
-
const SEO_CRAWLER_USER_AGENT = `${SEO_CRAWLER_TOKEN}/${SEO_VERSION} (+https://seoskill.dev)`;
|
|
3419
|
-
const SEO_CRAWLER_IDENTITY = {
|
|
3420
|
-
name: "SEO Skill",
|
|
3421
|
-
robotsToken: SEO_CRAWLER_TOKEN,
|
|
3422
|
-
version: SEO_VERSION,
|
|
3423
|
-
userAgent: SEO_CRAWLER_USER_AGENT,
|
|
3424
|
-
documentationUrl: "https://seoskill.dev/docs/crawler/"
|
|
3425
|
-
};
|
|
3426
|
-
//#endregion
|
|
3427
3509
|
//#region packages/core/dist/fetch/access-block.js
|
|
3428
3510
|
const CLOUDFLARE_SKIP_DOCS = "https://developers.cloudflare.com/waf/custom-rules/skip/";
|
|
3429
3511
|
function isHeadersLike(headers) {
|
|
@@ -3495,72 +3577,6 @@ function detectAccessBlock(input) {
|
|
|
3495
3577
|
};
|
|
3496
3578
|
}
|
|
3497
3579
|
//#endregion
|
|
3498
|
-
//#region packages/core/dist/fetch/http-client.js
|
|
3499
|
-
var ResponseSizeLimitError = class extends Error {
|
|
3500
|
-
maxBytes;
|
|
3501
|
-
constructor(maxBytes, label = "Response") {
|
|
3502
|
-
super(`${label} exceeds the ${maxBytes}-byte response limit.`);
|
|
3503
|
-
this.maxBytes = maxBytes;
|
|
3504
|
-
this.name = "ResponseSizeLimitError";
|
|
3505
|
-
}
|
|
3506
|
-
};
|
|
3507
|
-
function requestHeaders(profile) {
|
|
3508
|
-
if (profile === "bot") return new Headers({
|
|
3509
|
-
accept: "text/plain,*/*;q=0.8",
|
|
3510
|
-
"accept-language": "en-US,en;q=0.9",
|
|
3511
|
-
connection: "close",
|
|
3512
|
-
"user-agent": SEO_CRAWLER_USER_AGENT
|
|
3513
|
-
});
|
|
3514
|
-
return new Headers({
|
|
3515
|
-
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
3516
|
-
"accept-language": "en-US,en;q=0.9",
|
|
3517
|
-
connection: "close",
|
|
3518
|
-
"sec-ch-ua-mobile": "?0",
|
|
3519
|
-
"sec-ch-ua-platform": "\"macOS\"",
|
|
3520
|
-
"upgrade-insecure-requests": "1",
|
|
3521
|
-
"user-agent": SEO_CRAWLER_USER_AGENT
|
|
3522
|
-
});
|
|
3523
|
-
}
|
|
3524
|
-
function publicHttpFetch(url, input = {}) {
|
|
3525
|
-
const { profile = "browser", headers, ...init } = input;
|
|
3526
|
-
const base = requestHeaders(profile);
|
|
3527
|
-
if (headers instanceof Headers) for (const [key, value] of headers.entries()) base.set(key, value);
|
|
3528
|
-
else if (Array.isArray(headers)) for (const [key, value] of headers) base.set(key, value);
|
|
3529
|
-
else if (headers) {
|
|
3530
|
-
for (const [key, value] of Object.entries(headers)) if (value !== void 0) base.set(key, value);
|
|
3531
|
-
}
|
|
3532
|
-
return fetch$1(url, {
|
|
3533
|
-
...init,
|
|
3534
|
-
headers: base
|
|
3535
|
-
});
|
|
3536
|
-
}
|
|
3537
|
-
async function readBoundedResponseText(response, maxBytes, label = "Response") {
|
|
3538
|
-
const declaredLength = Number(response.headers.get("content-length"));
|
|
3539
|
-
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
3540
|
-
await response.body?.cancel().catch(() => void 0);
|
|
3541
|
-
throw new ResponseSizeLimitError(maxBytes, label);
|
|
3542
|
-
}
|
|
3543
|
-
const reader = response.body?.getReader();
|
|
3544
|
-
if (!reader) return "";
|
|
3545
|
-
const chunks = [];
|
|
3546
|
-
let total = 0;
|
|
3547
|
-
try {
|
|
3548
|
-
while (true) {
|
|
3549
|
-
const { done, value } = await reader.read();
|
|
3550
|
-
if (done) break;
|
|
3551
|
-
total += value.byteLength;
|
|
3552
|
-
if (total > maxBytes) {
|
|
3553
|
-
await reader.cancel().catch(() => void 0);
|
|
3554
|
-
throw new ResponseSizeLimitError(maxBytes, label);
|
|
3555
|
-
}
|
|
3556
|
-
chunks.push(value);
|
|
3557
|
-
}
|
|
3558
|
-
} finally {
|
|
3559
|
-
reader.releaseLock();
|
|
3560
|
-
}
|
|
3561
|
-
return Buffer.concat(chunks, total).toString("utf8");
|
|
3562
|
-
}
|
|
3563
|
-
//#endregion
|
|
3564
3580
|
//#region packages/core/dist/fetch/page-fetcher/rate-controls.js
|
|
3565
3581
|
const HOST_QUEUES = /* @__PURE__ */ new Map();
|
|
3566
3582
|
const HOST_HEALTH = /* @__PURE__ */ new Map();
|