jsonseo 1.0.0 → 1.0.1
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 +2 -2
- package/dist/cjs/client.d.ts +1 -1
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/http.js +12 -3
- package/dist/esm/client.d.ts +1 -1
- package/dist/esm/client.js +1 -1
- package/dist/esm/http.js +12 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ bun add jsonseo
|
|
|
23
23
|
```ts
|
|
24
24
|
import { JsonSeoClient } from 'jsonseo';
|
|
25
25
|
|
|
26
|
-
const client = new JsonSeoClient('
|
|
26
|
+
const client = new JsonSeoClient('YOUR_KEY');
|
|
27
27
|
|
|
28
28
|
const serp = await client.yandex({
|
|
29
29
|
text: 'купить ноутбук',
|
|
@@ -462,7 +462,7 @@ try {
|
|
|
462
462
|
|
|
463
463
|
```ts
|
|
464
464
|
const client = new JsonSeoClient({
|
|
465
|
-
apiKey: '
|
|
465
|
+
apiKey: 'YOUR_KEY',
|
|
466
466
|
baseUrl: 'https://jsonseo.ru/api', // адрес API
|
|
467
467
|
timeoutMs: 300_000, // сколько ждать ответа на одну попытку
|
|
468
468
|
attempts: 3, // всего попыток, вместе с первой
|
package/dist/cjs/client.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { BalanceResponse, DirectResponse, GeoipResponse, GoogleRegionsRespo
|
|
|
6
6
|
* Клиент JSON SEO API.
|
|
7
7
|
*
|
|
8
8
|
* ```ts
|
|
9
|
-
* const client = new JsonSeoClient('
|
|
9
|
+
* const client = new JsonSeoClient('YOUR_KEY');
|
|
10
10
|
* const serp = await client.yandex({ text: 'купить ноутбук', region: 213 });
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
package/dist/cjs/client.js
CHANGED
|
@@ -7,7 +7,7 @@ const http_js_1 = require("./http.js");
|
|
|
7
7
|
* Клиент JSON SEO API.
|
|
8
8
|
*
|
|
9
9
|
* ```ts
|
|
10
|
-
* const client = new JsonSeoClient('
|
|
10
|
+
* const client = new JsonSeoClient('YOUR_KEY');
|
|
11
11
|
* const serp = await client.yandex({ text: 'купить ноутбук', region: 213 });
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
package/dist/cjs/http.js
CHANGED
|
@@ -20,7 +20,7 @@ const KNOWN_OPTIONS = {
|
|
|
20
20
|
fetch: true,
|
|
21
21
|
};
|
|
22
22
|
const KNOWN_OPTION_NAMES = Object.keys(KNOWN_OPTIONS);
|
|
23
|
-
const VERSION = '1.0.
|
|
23
|
+
const VERSION = '1.0.1';
|
|
24
24
|
/**
|
|
25
25
|
* Транспорт: собирает запрос, разбирает ответ и решает, повторять ли отказ.
|
|
26
26
|
*
|
|
@@ -28,9 +28,18 @@ const VERSION = '1.0.0';
|
|
|
28
28
|
*/
|
|
29
29
|
class HttpClient {
|
|
30
30
|
constructor(options) {
|
|
31
|
-
|
|
31
|
+
// Обрезаем ровно тот же набор, что и остальные SDK: родной trim в
|
|
32
|
+
// каждом языке свой, и один ключ принимался бы по-разному.
|
|
33
|
+
const apiKey = typeof options.apiKey === 'string' ? options.apiKey.replace(/^[ \t\n\r]+|[ \t\n\r]+$/g, '') : '';
|
|
34
|
+
if (apiKey === '') {
|
|
32
35
|
throw new errors_js_1.InvalidArgumentError('Нужен API-ключ: возьмите его в личном кабинете на https://jsonseo.ru.');
|
|
33
36
|
}
|
|
37
|
+
// Заголовок Authorization не переносит не-ASCII и управляющие символы:
|
|
38
|
+
// с таким ключом он не соберётся, и сервис ответит «токен не
|
|
39
|
+
// предоставлен» вместо внятной ошибки.
|
|
40
|
+
if (/[^\x20-\x7E]/.test(apiKey)) {
|
|
41
|
+
throw new errors_js_1.InvalidArgumentError('API-ключ содержит символы вне ASCII: проверьте, что он скопирован целиком и без лишних знаков.');
|
|
42
|
+
}
|
|
34
43
|
// undefined из спреда частичного конфига — не настройка, а её отсутствие.
|
|
35
44
|
const unknown = Object.keys(options).filter((name) => !KNOWN_OPTION_NAMES.includes(name) && options[name] !== undefined);
|
|
36
45
|
if (unknown.length > 0) {
|
|
@@ -48,7 +57,7 @@ class HttpClient {
|
|
|
48
57
|
if (!fetchImpl) {
|
|
49
58
|
throw new errors_js_1.InvalidArgumentError('В этой среде нет глобального fetch. Нужен Node 18+, Bun или Deno — либо передайте свою реализацию настройкой fetch.');
|
|
50
59
|
}
|
|
51
|
-
this.apiKey =
|
|
60
|
+
this.apiKey = apiKey;
|
|
52
61
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
53
62
|
this.timeoutMs = options.timeoutMs ?? 300000;
|
|
54
63
|
this.attempts = options.attempts ?? 3;
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { BalanceResponse, DirectResponse, GeoipResponse, GoogleRegionsRespo
|
|
|
6
6
|
* Клиент JSON SEO API.
|
|
7
7
|
*
|
|
8
8
|
* ```ts
|
|
9
|
-
* const client = new JsonSeoClient('
|
|
9
|
+
* const client = new JsonSeoClient('YOUR_KEY');
|
|
10
10
|
* const serp = await client.yandex({ text: 'купить ноутбук', region: 213 });
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
package/dist/esm/client.js
CHANGED
|
@@ -4,7 +4,7 @@ import { HttpClient } from './http.js';
|
|
|
4
4
|
* Клиент JSON SEO API.
|
|
5
5
|
*
|
|
6
6
|
* ```ts
|
|
7
|
-
* const client = new JsonSeoClient('
|
|
7
|
+
* const client = new JsonSeoClient('YOUR_KEY');
|
|
8
8
|
* const serp = await client.yandex({ text: 'купить ноутбук', region: 213 });
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
package/dist/esm/http.js
CHANGED
|
@@ -16,7 +16,7 @@ const KNOWN_OPTIONS = {
|
|
|
16
16
|
fetch: true,
|
|
17
17
|
};
|
|
18
18
|
const KNOWN_OPTION_NAMES = Object.keys(KNOWN_OPTIONS);
|
|
19
|
-
const VERSION = '1.0.
|
|
19
|
+
const VERSION = '1.0.1';
|
|
20
20
|
/**
|
|
21
21
|
* Транспорт: собирает запрос, разбирает ответ и решает, повторять ли отказ.
|
|
22
22
|
*
|
|
@@ -24,9 +24,18 @@ const VERSION = '1.0.0';
|
|
|
24
24
|
*/
|
|
25
25
|
export class HttpClient {
|
|
26
26
|
constructor(options) {
|
|
27
|
-
|
|
27
|
+
// Обрезаем ровно тот же набор, что и остальные SDK: родной trim в
|
|
28
|
+
// каждом языке свой, и один ключ принимался бы по-разному.
|
|
29
|
+
const apiKey = typeof options.apiKey === 'string' ? options.apiKey.replace(/^[ \t\n\r]+|[ \t\n\r]+$/g, '') : '';
|
|
30
|
+
if (apiKey === '') {
|
|
28
31
|
throw new InvalidArgumentError('Нужен API-ключ: возьмите его в личном кабинете на https://jsonseo.ru.');
|
|
29
32
|
}
|
|
33
|
+
// Заголовок Authorization не переносит не-ASCII и управляющие символы:
|
|
34
|
+
// с таким ключом он не соберётся, и сервис ответит «токен не
|
|
35
|
+
// предоставлен» вместо внятной ошибки.
|
|
36
|
+
if (/[^\x20-\x7E]/.test(apiKey)) {
|
|
37
|
+
throw new InvalidArgumentError('API-ключ содержит символы вне ASCII: проверьте, что он скопирован целиком и без лишних знаков.');
|
|
38
|
+
}
|
|
30
39
|
// undefined из спреда частичного конфига — не настройка, а её отсутствие.
|
|
31
40
|
const unknown = Object.keys(options).filter((name) => !KNOWN_OPTION_NAMES.includes(name) && options[name] !== undefined);
|
|
32
41
|
if (unknown.length > 0) {
|
|
@@ -44,7 +53,7 @@ export class HttpClient {
|
|
|
44
53
|
if (!fetchImpl) {
|
|
45
54
|
throw new InvalidArgumentError('В этой среде нет глобального fetch. Нужен Node 18+, Bun или Deno — либо передайте свою реализацию настройкой fetch.');
|
|
46
55
|
}
|
|
47
|
-
this.apiKey =
|
|
56
|
+
this.apiKey = apiKey;
|
|
48
57
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
49
58
|
this.timeoutMs = options.timeoutMs ?? 300000;
|
|
50
59
|
this.attempts = options.attempts ?? 3;
|
package/package.json
CHANGED