@operstack/audit 0.19.2 → 0.19.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/package.json +1 -1
- package/src/test-blocked.mjs +16 -0
- package/src/visibility.mjs +8 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operstack/audit",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.3",
|
|
4
4
|
"description": "SEO, AEO and GEO audit generator: collect public signals from a site into audit.json, let an analyst or an agent fill the narrative, render the OperStack report as HTML and PDF.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/test-blocked.mjs
CHANGED
|
@@ -80,5 +80,21 @@ const CLOSED = 'User-agent: GPTBot\nDisallow: /\n\nUser-agent: ClaudeBot\nDisall
|
|
|
80
80
|
ok('в английском нет кириллицы', !/[А-Яа-яЁё]/.test(blockedNote({ status: 403, challenged: true, robotsText: OPEN, lang: 'en' }).text));
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// ---- несуществующий адрес: человек чаще всего просто опечатался
|
|
84
|
+
//
|
|
85
|
+
// Стояло «Сайт ответил ничем на https://…»: и коряво, и бесполезно. Человек, который ошибся в
|
|
86
|
+
// букве, должен узнать об этом первым делом, а не гадать, что с его сайтом.
|
|
87
|
+
{
|
|
88
|
+
const { checkVisibility } = await import('./visibility.mjs');
|
|
89
|
+
for (const lang of ['ru', 'en']) {
|
|
90
|
+
const v = await checkVisibility('https://takogo-domena-tochno-net-4f7a2b9c.ru/', { budgetMs: 8500, samplePages: 3, lang });
|
|
91
|
+
ok(`${lang}: балла у несуществующего адреса нет`, v.ok === false);
|
|
92
|
+
ok(`${lang}: названа вероятная причина, опечатка`, lang === 'ru' ? /опечатка в адресе/.test(v.error) : /typo in the address/.test(v.error));
|
|
93
|
+
ok(`${lang}: сказано, что делать`, lang === 'ru' ? /проверьте написание/.test(v.error) : /check the spelling/.test(v.error));
|
|
94
|
+
ok(`${lang}: нет старого «ответил ничем»`, lang === 'ru' ? !/ответил ничем/.test(v.error) : !/answered nothing/.test(v.error));
|
|
95
|
+
ok(`${lang}: чужого языка нет`, lang === 'ru' ? !/[A-Za-z]{5}/.test(v.error.replace(/https?:\/\/[^\s]+/g, '')) : !/[А-Яа-яЁё]/.test(v.error));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
if (bad) { console.error(`\n${bad} тест(ов) упало`); process.exit(1); }
|
|
84
100
|
console.log('\nпро чужой сайт говорим только измеренное');
|
package/src/visibility.mjs
CHANGED
|
@@ -48,7 +48,9 @@ export const MESSAGES = {
|
|
|
48
48
|
en: {
|
|
49
49
|
badInput: 'Enter a public site address, for example example.com',
|
|
50
50
|
tooSlow: 'The site took too long to answer',
|
|
51
|
-
badAnswer: (status, url) => `The site answered ${status
|
|
51
|
+
badAnswer: (status, url) => `The site answered ${status} for ${url}`,
|
|
52
|
+
// Чаще всего это опечатка в адресе, и сказать об этом надо первым делом, а не после разбора.
|
|
53
|
+
unreachable: (url) => `Nothing answered at ${url}. Most often that is a typo in the address: check the spelling, and if the site really is there, it may be down right now.`,
|
|
52
54
|
botWall: (status) => `The site refuses unknown clients (HTTP ${status}), so this check could not read a single page.`,
|
|
53
55
|
botChallenge: (status) => `The site sits behind a browser challenge (Cloudflare, HTTP ${status}), so this check could not read a single page.`,
|
|
54
56
|
// Что мы знаем про роботов ИИ, когда нас самих развернули: ровно то, что написано в правилах
|
|
@@ -98,7 +100,8 @@ export const MESSAGES = {
|
|
|
98
100
|
ru: {
|
|
99
101
|
badInput: 'Введите адрес публичного сайта, например example.ru',
|
|
100
102
|
tooSlow: 'Сайт слишком долго не отвечал',
|
|
101
|
-
badAnswer: (status, url) => `Сайт ответил
|
|
103
|
+
badAnswer: (status, url) => `Сайт ответил кодом ${status} на ${url}`,
|
|
104
|
+
unreachable: (url) => `По адресу ${url} никто не ответил. Чаще всего это опечатка в адресе: проверьте написание. Если сайт там действительно есть, значит он сейчас недоступен.`,
|
|
102
105
|
botWall: (status) => `Сайт отказывает незнакомым клиентам (код ${status}), поэтому прочитать хотя бы одну страницу проверка не смогла.`,
|
|
103
106
|
botChallenge: (status) => `Сайт закрыт проверкой браузера (Cloudflare, код ${status}), поэтому прочитать хотя бы одну страницу проверка не смогла.`,
|
|
104
107
|
rulesAllowBots: (list) => ` Правила самого сайта роботов ИИ при этом пускают (${list}), а защита такого типа проверенных роботов нередко пропускает. Пустят ли их на деле, решает защита, а не эта проверка, поэтому в плюс или в минус сайту это не зачтено.`,
|
|
@@ -403,8 +406,9 @@ export async function checkVisibility(input, { budgetMs = 8500, lang = 'en', sam
|
|
|
403
406
|
*/
|
|
404
407
|
const note = blockedNote({ status: home.status, challenged, blocked, robotsText: robotsRes.ok ? robotsRes.text : null, lang });
|
|
405
408
|
const error = home.error === 'timeout' ? T.tooSlow
|
|
406
|
-
:
|
|
407
|
-
:
|
|
409
|
+
: home.error === 'unreachable' || !home.status ? T.unreachable(url)
|
|
410
|
+
: blocked ? note.text
|
|
411
|
+
: T.badAnswer(home.status, url);
|
|
408
412
|
// `botsBlocked` говорит только про написанные правила, а не про поведение защиты: по нему
|
|
409
413
|
// нельзя утверждать, что робота не пустили, можно лишь, что ему не разрешали.
|
|
410
414
|
return { ok: false, blocked, challenged, status: home.status, error, botsBlocked: note.botsBlocked };
|