newtqnia-node 1.0.0 → 1.1.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 CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/newtqnia/newtqnia-node/actions/workflows/ci.yml/badge.svg)](https://github.com/newtqnia/newtqnia-node/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/newtqnia-node)](https://www.npmjs.com/package/newtqnia-node)
5
+ [![JSR](https://jsr.io/badges/@newtqnia/newtqnia-node)](https://jsr.io/@newtqnia/newtqnia-node)
5
6
  [![Node](https://img.shields.io/node/v/newtqnia-node)](package.json)
6
7
  [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
8
 
@@ -17,8 +18,16 @@ The official, TypeScript-first SDK for the [NewTqnia technology news API](https:
17
18
  npm install newtqnia-node
18
19
  ```
19
20
 
21
+ For Deno, install the package from JSR:
22
+
23
+ ```bash
24
+ deno add jsr:@newtqnia/newtqnia-node
25
+ ```
26
+
20
27
  ## Quick start
21
28
 
29
+ Node.js:
30
+
22
31
  ```ts
23
32
  import { NewTqniaClient } from "newtqnia-node";
24
33
 
@@ -32,6 +41,27 @@ for (const article of digest.articles) {
32
41
  }
33
42
  ```
34
43
 
44
+ Deno:
45
+
46
+ ```ts
47
+ import { NewTqniaClient } from "@newtqnia/newtqnia-node";
48
+
49
+ const client = new NewTqniaClient({
50
+ apiKey: Deno.env.get("NEWTQNIA_API_KEY"),
51
+ });
52
+
53
+ const digest = await client.news.latest({ locale: "en", limit: 5 });
54
+ for (const article of digest.articles) {
55
+ console.log(article.title, article.url);
56
+ }
57
+ ```
58
+
59
+ Run the Deno example with environment access enabled:
60
+
61
+ ```bash
62
+ deno run --allow-env --allow-net example.ts
63
+ ```
64
+
35
65
  The public API currently exposes the two endpoints in NewTqnia's [OpenAPI document](https://newtqnia.com/openapi.yaml):
36
66
 
37
67
  ```ts
@@ -43,18 +73,21 @@ The API contract does not currently define free-text search, individual article
43
73
 
44
74
  ## Authentication
45
75
 
46
- The public digest can be used without a key. When `apiKey` is provided, the SDK sends it as a Bearer token. Keep keys in environment variables and never ship them to browsers.
76
+ The public digest can be used without a key. When `apiKey` is provided, the SDK sends it as `X-API-Key`. Optional keys can be created and managed in your [NewTqnia profile](https://newtqnia.com/en/account). Keep keys in environment variables and never ship them to browsers.
47
77
 
48
78
  ## Configuration
49
79
 
50
80
  ```ts
51
81
  const client = new NewTqniaClient({
52
82
  apiKey: process.env.NEWTQNIA_API_KEY,
53
- baseUrl: "https://newtqnia.com",
83
+ rapidApiKey: process.env.RAPIDAPI_KEY,
84
+ application: "my-service",
85
+ website: "https://example.com",
86
+ baseUrl: "https://api.newtqnia.com",
54
87
  timeout: 15_000,
55
88
  retry: { maxRetries: 3, initialDelayMs: 500, maxDelayMs: 8_000 },
56
89
  userAgent: "my-service/2.0",
57
- defaultHeaders: { "X-Application": "my-service" },
90
+ defaultHeaders: { "X-Trace-Source": "my-service" },
58
91
  fetch: customFetch,
59
92
  signal: applicationShutdownSignal,
60
93
  });
package/dist/index.cjs CHANGED
@@ -117,7 +117,10 @@ var Transport = class {
117
117
  const headers = new Headers(this.options.headers);
118
118
  headers.set("Accept", "application/json");
119
119
  headers.set("User-Agent", this.options.userAgent);
120
- if (this.options.apiKey) headers.set("Authorization", `Bearer ${this.options.apiKey}`);
120
+ if (this.options.apiKey) headers.set("X-API-Key", this.options.apiKey);
121
+ if (this.options.rapidApiKey) headers.set("X-RapidAPI-Key", this.options.rapidApiKey);
122
+ if (this.options.application) headers.set("X-NewTqnia-Application", this.options.application);
123
+ if (this.options.website) headers.set("X-NewTqnia-Website", this.options.website);
121
124
  return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });
122
125
  }
123
126
  async decode(response) {
@@ -205,10 +208,13 @@ var NewTqniaClient = class {
205
208
  /** Localized news endpoints. */
206
209
  news;
207
210
  constructor(options = {}) {
208
- const baseUrl = (options.baseUrl ?? "https://newtqnia.com").replace(/\/+$/, "");
211
+ const baseUrl = (options.baseUrl ?? "https://api.newtqnia.com").replace(/\/+$/, "");
209
212
  this.validate(baseUrl, options.timeout);
210
213
  const transport = new Transport({
211
214
  ...options.apiKey ? { apiKey: options.apiKey } : {},
215
+ ...options.rapidApiKey ? { rapidApiKey: options.rapidApiKey } : {},
216
+ ...options.application ? { application: options.application } : {},
217
+ ...options.website ? { website: options.website } : {},
212
218
  baseUrl,
213
219
  timeout: options.timeout ?? 3e4,
214
220
  fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
@@ -217,7 +223,7 @@ var NewTqniaClient = class {
217
223
  initialDelayMs: options.retry?.initialDelayMs ?? 500,
218
224
  maxDelayMs: options.retry?.maxDelayMs ?? 8e3
219
225
  },
220
- userAgent: options.userAgent ?? "newtqnia-node/1.0.0",
226
+ userAgent: options.userAgent ?? "newtqnia-node/1.1.0",
221
227
  headers: options.defaultHeaders ?? {},
222
228
  ...options.signal ? { signal: options.signal } : {}
223
229
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/index.ts","../src/resources/news.ts","../src/utils/query.ts","../src/transport/transport.ts","../src/client/client.ts"],"names":["signal"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface ErrorOptions {\n status?: number | undefined;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n code?: string | undefined;\n cause?: unknown | undefined;\n}\n\n/** Base class for all SDK errors. */\nexport class NewTqniaError extends Error {\n readonly status: number | undefined;\n readonly requestId: string | undefined;\n readonly retryAfter: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, options: ErrorOptions = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = new.target.name;\n this.status = options.status;\n this.requestId = options.requestId;\n this.retryAfter = options.retryAfter;\n this.code = options.code;\n }\n}\nexport class AuthenticationError extends NewTqniaError {}\nexport class AuthorizationError extends NewTqniaError {}\nexport class ValidationError extends NewTqniaError {}\nexport class NotFoundError extends NewTqniaError {}\nexport class ConflictError extends NewTqniaError {}\nexport class RateLimitError extends NewTqniaError {}\nexport class ServerError extends NewTqniaError {}\nexport class TimeoutError extends NewTqniaError {}\nexport class NetworkError extends NewTqniaError {}\n","import { ValidationError } from \"../errors/index.js\";\nimport type { Digest, NewsListParams } from \"../models/index.js\";\nimport type { Transport } from \"../transport/transport.js\";\n\n/** Access localized NewTqnia news collections. */\nexport class NewsResource {\n /** @internal */\n constructor(private readonly transport: Transport) {}\n\n /** Get articles published today using the Asia/Dubai day boundary. */\n today(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"today\", params);\n }\n\n /** Get the latest published articles. */\n latest(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"latest\", params);\n }\n\n private get(collection: \"today\" | \"latest\", params: NewsListParams): Promise<Digest> {\n if (params.locale !== undefined && params.locale !== \"en\" && params.locale !== \"ar\") {\n throw new ValidationError('locale must be \"en\" or \"ar\".');\n }\n if (params.limit !== undefined && (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 10)) {\n throw new ValidationError(\"limit must be an integer between 1 and 10.\");\n }\n if (params.category !== undefined && params.category.trim() === \"\") {\n throw new ValidationError(\"category cannot be empty.\");\n }\n return this.transport.request<Digest>({\n method: \"GET\",\n path: `/v1/news/${collection}`,\n query: { locale: params.locale, limit: params.limit, category: params.category },\n ...(params.signal ? { signal: params.signal } : {}),\n });\n }\n}\n","export function serializeQuery(values: Record<string, string | number | boolean | undefined>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined) search.append(key, String(value));\n }\n return search.toString();\n}\n","import {\n AuthenticationError, AuthorizationError, ConflictError, NetworkError, NewTqniaError,\n NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError,\n} from \"../errors/index.js\";\nimport { serializeQuery } from \"../utils/query.js\";\nimport type { Fetch, RequestOptions, RetryOptions } from \"./types.js\";\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport interface TransportOptions {\n apiKey?: string;\n baseUrl: string;\n timeout: number;\n fetch: Fetch;\n retry: Required<RetryOptions>;\n userAgent: string;\n headers: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport class Transport {\n constructor(private readonly options: TransportOptions) {}\n\n async request<T>(request: RequestOptions): Promise<T> {\n const query = request.query ? serializeQuery(request.query) : \"\";\n const url = `${this.options.baseUrl}${request.path}${query ? `?${query}` : \"\"}`;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.options.retry.maxRetries; attempt += 1) {\n try {\n const response = await this.fetchOnce(url, request);\n if (response.ok) return await this.decode<T>(response);\n if (RETRYABLE.has(response.status) && attempt < this.options.retry.maxRetries) {\n await this.pause(this.retryDelay(response, attempt), request.signal);\n continue;\n }\n throw await this.apiError(response);\n } catch (error) {\n if (error instanceof NewTqniaError) throw error;\n if (this.wasCancelled(request.signal)) throw error;\n if (this.isTimeout(error)) throw new TimeoutError(`Request timed out after ${this.options.timeout}ms`, { cause: error });\n lastError = error;\n if (attempt < this.options.retry.maxRetries) {\n await this.pause(this.backoff(attempt), request.signal);\n continue;\n }\n }\n }\n throw new NetworkError(\"Unable to reach the NewTqnia API.\", { cause: lastError });\n }\n\n private async fetchOnce(url: string, request: RequestOptions): Promise<Response> {\n const timeout = AbortSignal.timeout(this.options.timeout);\n const signals = [timeout, this.options.signal, request.signal].filter((signal): signal is AbortSignal => signal !== undefined);\n const signal = this.combineSignals(signals);\n const headers = new Headers(this.options.headers);\n headers.set(\"Accept\", \"application/json\");\n headers.set(\"User-Agent\", this.options.userAgent);\n if (this.options.apiKey) headers.set(\"Authorization\", `Bearer ${this.options.apiKey}`);\n return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });\n }\n\n private async decode<T>(response: Response): Promise<T> {\n try {\n return await response.json() as T;\n } catch (cause) {\n throw new NewTqniaError(\"The API returned invalid JSON.\", {\n status: response.status, requestId: this.requestId(response), cause,\n });\n }\n }\n\n private async apiError(response: Response): Promise<NewTqniaError> {\n const data = await response.json().catch(() => ({})) as Record<string, unknown>;\n const message = typeof data.message === \"string\" ? data.message : `NewTqnia API request failed with status ${response.status}.`;\n const retryAfter = this.parseRetryAfter(response.headers.get(\"retry-after\"));\n const options = {\n status: response.status,\n requestId: this.requestId(response),\n retryAfter,\n code: typeof data.code === \"string\" ? data.code : undefined,\n };\n if (response.status === 401) return new AuthenticationError(message, options);\n if (response.status === 403) return new AuthorizationError(message, options);\n if (response.status === 404) return new NotFoundError(message, options);\n if (response.status === 409) return new ConflictError(message, options);\n if (response.status === 422 || response.status === 400) return new ValidationError(message, options);\n if (response.status === 429) return new RateLimitError(message, options);\n if (response.status >= 500) return new ServerError(message, options);\n return new NewTqniaError(message, options);\n }\n\n private retryDelay(response: Response, attempt: number): number {\n return this.parseRetryAfter(response.headers.get(\"retry-after\")) ?? this.backoff(attempt);\n }\n private parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n }\n private backoff(attempt: number): number {\n const raw = this.options.retry.initialDelayMs * (2 ** attempt);\n return Math.min(raw, this.options.retry.maxDelayMs);\n }\n private async pause(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); reject(signal.reason); }, { once: true });\n });\n }\n private requestId(response: Response): string | undefined {\n return response.headers.get(\"x-request-id\") ?? undefined;\n }\n private combineSignals(signals: AbortSignal[]): AbortSignal | undefined {\n if (signals.length === 0) return undefined;\n if (signals.length === 1) return signals[0];\n const controller = new AbortController();\n const abort = (signal: AbortSignal) => {\n if (!controller.signal.aborted) controller.abort(signal.reason);\n };\n for (const signal of signals) {\n if (signal.aborted) {\n abort(signal);\n break;\n }\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n }\n return controller.signal;\n }\n private wasCancelled(signal?: AbortSignal): boolean {\n return Boolean(signal?.aborted || this.options.signal?.aborted);\n }\n private isTimeout(error: unknown): boolean {\n return error instanceof DOMException && (error.name === \"TimeoutError\" || error.name === \"AbortError\")\n && !this.options.signal?.aborted;\n }\n}\n","import { ValidationError } from \"../errors/index.js\";\nimport { NewsResource } from \"../resources/news.js\";\nimport { Transport } from \"../transport/transport.js\";\nimport type { Fetch, RetryOptions } from \"../transport/types.js\";\n\nexport interface NewTqniaClientOptions {\n /** Optional bearer API key. */\n apiKey?: string;\n /** API origin. @default \"https://newtqnia.com\" */\n baseUrl?: string;\n /** Request timeout in milliseconds. @default 30000 */\n timeout?: number;\n /** Cancels every request made by this client. */\n signal?: AbortSignal;\n /** Custom Fetch-compatible implementation. */\n fetch?: Fetch;\n /** Retry behavior for rate limits, server errors, and temporary network failures. */\n retry?: RetryOptions;\n /** User-Agent header. @default \"newtqnia-node/1.0.0\" */\n userAgent?: string;\n /** Headers included with every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Official NewTqnia API client. */\nexport class NewTqniaClient {\n /** Localized news endpoints. */\n readonly news: NewsResource;\n\n constructor(options: NewTqniaClientOptions = {}) {\n const baseUrl = (options.baseUrl ?? \"https://newtqnia.com\").replace(/\\/+$/, \"\");\n this.validate(baseUrl, options.timeout);\n const transport = new Transport({\n ...(options.apiKey ? { apiKey: options.apiKey } : {}),\n baseUrl,\n timeout: options.timeout ?? 30_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n retry: {\n maxRetries: options.retry?.maxRetries ?? 2,\n initialDelayMs: options.retry?.initialDelayMs ?? 500,\n maxDelayMs: options.retry?.maxDelayMs ?? 8_000,\n },\n userAgent: options.userAgent ?? \"newtqnia-node/1.0.0\",\n headers: options.defaultHeaders ?? {},\n ...(options.signal ? { signal: options.signal } : {}),\n });\n this.news = new NewsResource(transport);\n }\n\n private validate(baseUrl: string, timeout?: number): void {\n let url: URL;\n try { url = new URL(baseUrl); } catch { throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\"); }\n if (![\"http:\", \"https:\"].includes(url.protocol)) throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\");\n const local = [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname);\n if (url.protocol !== \"https:\" && !local) throw new ValidationError(\"baseUrl must use HTTPS except for local development.\");\n if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) throw new ValidationError(\"timeout must be a positive number.\");\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/resources/news.ts","../src/utils/query.ts","../src/transport/transport.ts","../src/client/client.ts"],"names":["signal"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface ErrorOptions {\n status?: number | undefined;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n code?: string | undefined;\n cause?: unknown | undefined;\n}\n\n/** Base class for all SDK errors. */\nexport class NewTqniaError extends Error {\n readonly status: number | undefined;\n readonly requestId: string | undefined;\n readonly retryAfter: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, options: ErrorOptions = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = new.target.name;\n this.status = options.status;\n this.requestId = options.requestId;\n this.retryAfter = options.retryAfter;\n this.code = options.code;\n }\n}\nexport class AuthenticationError extends NewTqniaError {}\nexport class AuthorizationError extends NewTqniaError {}\nexport class ValidationError extends NewTqniaError {}\nexport class NotFoundError extends NewTqniaError {}\nexport class ConflictError extends NewTqniaError {}\nexport class RateLimitError extends NewTqniaError {}\nexport class ServerError extends NewTqniaError {}\nexport class TimeoutError extends NewTqniaError {}\nexport class NetworkError extends NewTqniaError {}\n","import { ValidationError } from \"../errors/index.js\";\nimport type { Digest, NewsListParams } from \"../models/index.js\";\nimport type { Transport } from \"../transport/transport.js\";\n\n/** Access localized NewTqnia news collections. */\nexport class NewsResource {\n /** @internal */\n constructor(private readonly transport: Transport) {}\n\n /** Get articles published today using the Asia/Dubai day boundary. */\n today(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"today\", params);\n }\n\n /** Get the latest published articles. */\n latest(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"latest\", params);\n }\n\n private get(collection: \"today\" | \"latest\", params: NewsListParams): Promise<Digest> {\n if (params.locale !== undefined && params.locale !== \"en\" && params.locale !== \"ar\") {\n throw new ValidationError('locale must be \"en\" or \"ar\".');\n }\n if (params.limit !== undefined && (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 10)) {\n throw new ValidationError(\"limit must be an integer between 1 and 10.\");\n }\n if (params.category !== undefined && params.category.trim() === \"\") {\n throw new ValidationError(\"category cannot be empty.\");\n }\n return this.transport.request<Digest>({\n method: \"GET\",\n path: `/v1/news/${collection}`,\n query: { locale: params.locale, limit: params.limit, category: params.category },\n ...(params.signal ? { signal: params.signal } : {}),\n });\n }\n}\n","export function serializeQuery(values: Record<string, string | number | boolean | undefined>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined) search.append(key, String(value));\n }\n return search.toString();\n}\n","import {\n AuthenticationError, AuthorizationError, ConflictError, NetworkError, NewTqniaError,\n NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError,\n} from \"../errors/index.js\";\nimport { serializeQuery } from \"../utils/query.js\";\nimport type { Fetch, RequestOptions, RetryOptions } from \"./types.js\";\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport interface TransportOptions {\n apiKey?: string;\n rapidApiKey?: string;\n application?: string;\n website?: string;\n baseUrl: string;\n timeout: number;\n fetch: Fetch;\n retry: Required<RetryOptions>;\n userAgent: string;\n headers: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport class Transport {\n constructor(private readonly options: TransportOptions) {}\n\n async request<T>(request: RequestOptions): Promise<T> {\n const query = request.query ? serializeQuery(request.query) : \"\";\n const url = `${this.options.baseUrl}${request.path}${query ? `?${query}` : \"\"}`;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.options.retry.maxRetries; attempt += 1) {\n try {\n const response = await this.fetchOnce(url, request);\n if (response.ok) return await this.decode<T>(response);\n if (RETRYABLE.has(response.status) && attempt < this.options.retry.maxRetries) {\n await this.pause(this.retryDelay(response, attempt), request.signal);\n continue;\n }\n throw await this.apiError(response);\n } catch (error) {\n if (error instanceof NewTqniaError) throw error;\n if (this.wasCancelled(request.signal)) throw error;\n if (this.isTimeout(error)) throw new TimeoutError(`Request timed out after ${this.options.timeout}ms`, { cause: error });\n lastError = error;\n if (attempt < this.options.retry.maxRetries) {\n await this.pause(this.backoff(attempt), request.signal);\n continue;\n }\n }\n }\n throw new NetworkError(\"Unable to reach the NewTqnia API.\", { cause: lastError });\n }\n\n private async fetchOnce(url: string, request: RequestOptions): Promise<Response> {\n const timeout = AbortSignal.timeout(this.options.timeout);\n const signals = [timeout, this.options.signal, request.signal].filter((signal): signal is AbortSignal => signal !== undefined);\n const signal = this.combineSignals(signals);\n const headers = new Headers(this.options.headers);\n headers.set(\"Accept\", \"application/json\");\n headers.set(\"User-Agent\", this.options.userAgent);\n if (this.options.apiKey) headers.set(\"X-API-Key\", this.options.apiKey);\n if (this.options.rapidApiKey) headers.set(\"X-RapidAPI-Key\", this.options.rapidApiKey);\n if (this.options.application) headers.set(\"X-NewTqnia-Application\", this.options.application);\n if (this.options.website) headers.set(\"X-NewTqnia-Website\", this.options.website);\n return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });\n }\n\n private async decode<T>(response: Response): Promise<T> {\n try {\n return await response.json() as T;\n } catch (cause) {\n throw new NewTqniaError(\"The API returned invalid JSON.\", {\n status: response.status, requestId: this.requestId(response), cause,\n });\n }\n }\n\n private async apiError(response: Response): Promise<NewTqniaError> {\n const data = await response.json().catch(() => ({})) as Record<string, unknown>;\n const message = typeof data.message === \"string\" ? data.message : `NewTqnia API request failed with status ${response.status}.`;\n const retryAfter = this.parseRetryAfter(response.headers.get(\"retry-after\"));\n const options = {\n status: response.status,\n requestId: this.requestId(response),\n retryAfter,\n code: typeof data.code === \"string\" ? data.code : undefined,\n };\n if (response.status === 401) return new AuthenticationError(message, options);\n if (response.status === 403) return new AuthorizationError(message, options);\n if (response.status === 404) return new NotFoundError(message, options);\n if (response.status === 409) return new ConflictError(message, options);\n if (response.status === 422 || response.status === 400) return new ValidationError(message, options);\n if (response.status === 429) return new RateLimitError(message, options);\n if (response.status >= 500) return new ServerError(message, options);\n return new NewTqniaError(message, options);\n }\n\n private retryDelay(response: Response, attempt: number): number {\n return this.parseRetryAfter(response.headers.get(\"retry-after\")) ?? this.backoff(attempt);\n }\n private parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n }\n private backoff(attempt: number): number {\n const raw = this.options.retry.initialDelayMs * (2 ** attempt);\n return Math.min(raw, this.options.retry.maxDelayMs);\n }\n private async pause(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); reject(signal.reason); }, { once: true });\n });\n }\n private requestId(response: Response): string | undefined {\n return response.headers.get(\"x-request-id\") ?? undefined;\n }\n private combineSignals(signals: AbortSignal[]): AbortSignal | undefined {\n if (signals.length === 0) return undefined;\n if (signals.length === 1) return signals[0];\n const controller = new AbortController();\n const abort = (signal: AbortSignal) => {\n if (!controller.signal.aborted) controller.abort(signal.reason);\n };\n for (const signal of signals) {\n if (signal.aborted) {\n abort(signal);\n break;\n }\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n }\n return controller.signal;\n }\n private wasCancelled(signal?: AbortSignal): boolean {\n return Boolean(signal?.aborted || this.options.signal?.aborted);\n }\n private isTimeout(error: unknown): boolean {\n return error instanceof DOMException && (error.name === \"TimeoutError\" || error.name === \"AbortError\")\n && !this.options.signal?.aborted;\n }\n}\n","import { ValidationError } from \"../errors/index.js\";\nimport { NewsResource } from \"../resources/news.js\";\nimport { Transport } from \"../transport/transport.js\";\nimport type { Fetch, RetryOptions } from \"../transport/types.js\";\n\nexport interface NewTqniaClientOptions {\n /** Optional NewTqnia API key sent as X-API-Key. */\n apiKey?: string;\n /** Optional RapidAPI key sent as X-RapidAPI-Key. */\n rapidApiKey?: string;\n /** Optional caller application name. */\n application?: string;\n /** Optional caller website origin. */\n website?: string;\n /** API origin. @default \"https://api.newtqnia.com\" */\n baseUrl?: string;\n /** Request timeout in milliseconds. @default 30000 */\n timeout?: number;\n /** Cancels every request made by this client. */\n signal?: AbortSignal;\n /** Custom Fetch-compatible implementation. */\n fetch?: Fetch;\n /** Retry behavior for rate limits, server errors, and temporary network failures. */\n retry?: RetryOptions;\n /** User-Agent header. @default \"newtqnia-node/1.1.0\" */\n userAgent?: string;\n /** Headers included with every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Official NewTqnia API client. */\nexport class NewTqniaClient {\n /** Localized news endpoints. */\n readonly news: NewsResource;\n\n constructor(options: NewTqniaClientOptions = {}) {\n const baseUrl = (options.baseUrl ?? \"https://api.newtqnia.com\").replace(/\\/+$/, \"\");\n this.validate(baseUrl, options.timeout);\n const transport = new Transport({\n ...(options.apiKey ? { apiKey: options.apiKey } : {}),\n ...(options.rapidApiKey ? { rapidApiKey: options.rapidApiKey } : {}),\n ...(options.application ? { application: options.application } : {}),\n ...(options.website ? { website: options.website } : {}),\n baseUrl,\n timeout: options.timeout ?? 30_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n retry: {\n maxRetries: options.retry?.maxRetries ?? 2,\n initialDelayMs: options.retry?.initialDelayMs ?? 500,\n maxDelayMs: options.retry?.maxDelayMs ?? 8_000,\n },\n userAgent: options.userAgent ?? \"newtqnia-node/1.1.0\",\n headers: options.defaultHeaders ?? {},\n ...(options.signal ? { signal: options.signal } : {}),\n });\n this.news = new NewsResource(transport);\n }\n\n private validate(baseUrl: string, timeout?: number): void {\n let url: URL;\n try { url = new URL(baseUrl); } catch { throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\"); }\n if (![\"http:\", \"https:\"].includes(url.protocol)) throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\");\n const local = [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname);\n if (url.protocol !== \"https:\" && !local) throw new ValidationError(\"baseUrl must use HTTPS except for local development.\");\n if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) throw new ValidationError(\"timeout must be a positive number.\");\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -104,6 +104,9 @@ interface RequestOptions {
104
104
 
105
105
  interface TransportOptions {
106
106
  apiKey?: string;
107
+ rapidApiKey?: string;
108
+ application?: string;
109
+ website?: string;
107
110
  baseUrl: string;
108
111
  timeout: number;
109
112
  fetch: Fetch;
@@ -142,9 +145,15 @@ declare class NewsResource {
142
145
  }
143
146
 
144
147
  interface NewTqniaClientOptions {
145
- /** Optional bearer API key. */
148
+ /** Optional NewTqnia API key sent as X-API-Key. */
146
149
  apiKey?: string;
147
- /** API origin. @default "https://newtqnia.com" */
150
+ /** Optional RapidAPI key sent as X-RapidAPI-Key. */
151
+ rapidApiKey?: string;
152
+ /** Optional caller application name. */
153
+ application?: string;
154
+ /** Optional caller website origin. */
155
+ website?: string;
156
+ /** API origin. @default "https://api.newtqnia.com" */
148
157
  baseUrl?: string;
149
158
  /** Request timeout in milliseconds. @default 30000 */
150
159
  timeout?: number;
@@ -154,7 +163,7 @@ interface NewTqniaClientOptions {
154
163
  fetch?: Fetch;
155
164
  /** Retry behavior for rate limits, server errors, and temporary network failures. */
156
165
  retry?: RetryOptions;
157
- /** User-Agent header. @default "newtqnia-node/1.0.0" */
166
+ /** User-Agent header. @default "newtqnia-node/1.1.0" */
158
167
  userAgent?: string;
159
168
  /** Headers included with every request. */
160
169
  defaultHeaders?: Record<string, string>;
package/dist/index.d.ts CHANGED
@@ -104,6 +104,9 @@ interface RequestOptions {
104
104
 
105
105
  interface TransportOptions {
106
106
  apiKey?: string;
107
+ rapidApiKey?: string;
108
+ application?: string;
109
+ website?: string;
107
110
  baseUrl: string;
108
111
  timeout: number;
109
112
  fetch: Fetch;
@@ -142,9 +145,15 @@ declare class NewsResource {
142
145
  }
143
146
 
144
147
  interface NewTqniaClientOptions {
145
- /** Optional bearer API key. */
148
+ /** Optional NewTqnia API key sent as X-API-Key. */
146
149
  apiKey?: string;
147
- /** API origin. @default "https://newtqnia.com" */
150
+ /** Optional RapidAPI key sent as X-RapidAPI-Key. */
151
+ rapidApiKey?: string;
152
+ /** Optional caller application name. */
153
+ application?: string;
154
+ /** Optional caller website origin. */
155
+ website?: string;
156
+ /** API origin. @default "https://api.newtqnia.com" */
148
157
  baseUrl?: string;
149
158
  /** Request timeout in milliseconds. @default 30000 */
150
159
  timeout?: number;
@@ -154,7 +163,7 @@ interface NewTqniaClientOptions {
154
163
  fetch?: Fetch;
155
164
  /** Retry behavior for rate limits, server errors, and temporary network failures. */
156
165
  retry?: RetryOptions;
157
- /** User-Agent header. @default "newtqnia-node/1.0.0" */
166
+ /** User-Agent header. @default "newtqnia-node/1.1.0" */
158
167
  userAgent?: string;
159
168
  /** Headers included with every request. */
160
169
  defaultHeaders?: Record<string, string>;
package/dist/index.js CHANGED
@@ -115,7 +115,10 @@ var Transport = class {
115
115
  const headers = new Headers(this.options.headers);
116
116
  headers.set("Accept", "application/json");
117
117
  headers.set("User-Agent", this.options.userAgent);
118
- if (this.options.apiKey) headers.set("Authorization", `Bearer ${this.options.apiKey}`);
118
+ if (this.options.apiKey) headers.set("X-API-Key", this.options.apiKey);
119
+ if (this.options.rapidApiKey) headers.set("X-RapidAPI-Key", this.options.rapidApiKey);
120
+ if (this.options.application) headers.set("X-NewTqnia-Application", this.options.application);
121
+ if (this.options.website) headers.set("X-NewTqnia-Website", this.options.website);
119
122
  return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });
120
123
  }
121
124
  async decode(response) {
@@ -203,10 +206,13 @@ var NewTqniaClient = class {
203
206
  /** Localized news endpoints. */
204
207
  news;
205
208
  constructor(options = {}) {
206
- const baseUrl = (options.baseUrl ?? "https://newtqnia.com").replace(/\/+$/, "");
209
+ const baseUrl = (options.baseUrl ?? "https://api.newtqnia.com").replace(/\/+$/, "");
207
210
  this.validate(baseUrl, options.timeout);
208
211
  const transport = new Transport({
209
212
  ...options.apiKey ? { apiKey: options.apiKey } : {},
213
+ ...options.rapidApiKey ? { rapidApiKey: options.rapidApiKey } : {},
214
+ ...options.application ? { application: options.application } : {},
215
+ ...options.website ? { website: options.website } : {},
210
216
  baseUrl,
211
217
  timeout: options.timeout ?? 3e4,
212
218
  fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
@@ -215,7 +221,7 @@ var NewTqniaClient = class {
215
221
  initialDelayMs: options.retry?.initialDelayMs ?? 500,
216
222
  maxDelayMs: options.retry?.maxDelayMs ?? 8e3
217
223
  },
218
- userAgent: options.userAgent ?? "newtqnia-node/1.0.0",
224
+ userAgent: options.userAgent ?? "newtqnia-node/1.1.0",
219
225
  headers: options.defaultHeaders ?? {},
220
226
  ...options.signal ? { signal: options.signal } : {}
221
227
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/index.ts","../src/resources/news.ts","../src/utils/query.ts","../src/transport/transport.ts","../src/client/client.ts"],"names":["signal"],"mappings":";AASO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAC9B,MAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAA;AAAA,EAET,WAAA,CAAY,OAAA,EAAiB,OAAA,GAAwB,EAAC,EAAG;AACvD,IAAA,KAAA,CAAM,OAAA,EAAS,QAAQ,KAAA,KAAU,MAAA,GAAY,SAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,CAAA;AACjF,IAAA,IAAA,CAAK,OAAO,GAAA,CAAA,MAAA,CAAW,IAAA;AACvB,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AACzB,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA;AAAA,EACtB;AACF;AACO,IAAM,mBAAA,GAAN,cAAkC,aAAA,CAAc;AAAC;AACjD,IAAM,kBAAA,GAAN,cAAiC,aAAA,CAAc;AAAC;AAChD,IAAM,eAAA,GAAN,cAA8B,aAAA,CAAc;AAAC;AAC7C,IAAM,aAAA,GAAN,cAA4B,aAAA,CAAc;AAAC;AAC3C,IAAM,aAAA,GAAN,cAA4B,aAAA,CAAc;AAAC;AAC3C,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAC;AAC5C,IAAM,WAAA,GAAN,cAA0B,aAAA,CAAc;AAAC;AACzC,IAAM,YAAA,GAAN,cAA2B,aAAA,CAAc;AAAC;AAC1C,IAAM,YAAA,GAAN,cAA2B,aAAA,CAAc;AAAC;;;AC3B1C,IAAM,eAAN,MAAmB;AAAA;AAAA,EAExB,YAA6B,SAAA,EAAsB;AAAtB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAAuB;AAAA,EAAvB,SAAA;AAAA;AAAA,EAG7B,KAAA,CAAM,MAAA,GAAyB,EAAC,EAAoB;AAClD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA,EAGA,MAAA,CAAO,MAAA,GAAyB,EAAC,EAAoB;AACnD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AAAA,EAClC;AAAA,EAEQ,GAAA,CAAI,YAAgC,MAAA,EAAyC;AACnF,IAAA,IAAI,MAAA,CAAO,WAAW,MAAA,IAAa,MAAA,CAAO,WAAW,IAAA,IAAQ,MAAA,CAAO,WAAW,IAAA,EAAM;AACnF,MAAA,MAAM,IAAI,gBAAgB,8BAA8B,CAAA;AAAA,IAC1D;AACA,IAAA,IAAI,MAAA,CAAO,KAAA,KAAU,MAAA,KAAc,CAAC,OAAO,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA,IAAK,MAAA,CAAO,KAAA,GAAQ,CAAA,IAAK,MAAA,CAAO,QAAQ,EAAA,CAAA,EAAK;AAC5G,MAAA,MAAM,IAAI,gBAAgB,4CAA4C,CAAA;AAAA,IACxE;AACA,IAAA,IAAI,OAAO,QAAA,KAAa,MAAA,IAAa,OAAO,QAAA,CAAS,IAAA,OAAW,EAAA,EAAI;AAClE,MAAA,MAAM,IAAI,gBAAgB,2BAA2B,CAAA;AAAA,IACvD;AACA,IAAA,OAAO,IAAA,CAAK,UAAU,OAAA,CAAgB;AAAA,MACpC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,YAAY,UAAU,CAAA,CAAA;AAAA,MAC5B,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,OAAO,MAAA,CAAO,KAAA,EAAO,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAAA,MAC/E,GAAI,OAAO,MAAA,GAAS,EAAE,QAAQ,MAAA,CAAO,MAAA,KAAW;AAAC,KAClD,CAAA;AAAA,EACH;AACF,CAAA;;;ACpCO,SAAS,eAAe,MAAA,EAAuE;AACpG,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,IAAA,IAAI,UAAU,MAAA,EAAW,MAAA,CAAO,OAAO,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC3D;AACA,EAAA,OAAO,OAAO,QAAA,EAAS;AACzB;;;ACCA,IAAM,SAAA,uBAAgB,GAAA,CAAI,CAAC,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAa5C,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,OAAA,EAA2B;AAA3B,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAA4B;AAAA,EAA5B,OAAA;AAAA,EAE7B,MAAM,QAAW,OAAA,EAAqC;AACpD,IAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,GAAQ,cAAA,CAAe,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAA;AAC9D,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAA,EAAG,KAAA,GAAQ,CAAA,CAAA,EAAI,KAAK,KAAK,EAAE,CAAA,CAAA;AAC7E,IAAA,IAAI,SAAA;AAEJ,IAAA,KAAA,IAAS,OAAA,GAAU,GAAG,OAAA,IAAW,IAAA,CAAK,QAAQ,KAAA,CAAM,UAAA,EAAY,WAAW,CAAA,EAAG;AAC5E,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAClD,QAAA,IAAI,SAAS,EAAA,EAAI,OAAO,MAAM,IAAA,CAAK,OAAU,QAAQ,CAAA;AACrD,QAAA,IAAI,SAAA,CAAU,IAAI,QAAA,CAAS,MAAM,KAAK,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,UAAA,EAAY;AAC7E,UAAA,MAAM,IAAA,CAAK,MAAM,IAAA,CAAK,UAAA,CAAW,UAAU,OAAO,CAAA,EAAG,QAAQ,MAAM,CAAA;AACnE,UAAA;AAAA,QACF;AACA,QAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AAAA,MACpC,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,KAAA,YAAiB,eAAe,MAAM,KAAA;AAC1C,QAAA,IAAI,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,MAAM,GAAG,MAAM,KAAA;AAC7C,QAAA,IAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,QAAS,IAAI,YAAA,CAAa,CAAA,wBAAA,EAA2B,IAAA,CAAK,QAAQ,OAAO,CAAA,EAAA,CAAA,EAAM,EAAE,KAAA,EAAO,OAAO,CAAA;AACvH,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,IAAI,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,UAAA,EAAY;AAC3C,UAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,QAAQ,OAAO,CAAA,EAAG,QAAQ,MAAM,CAAA;AACtD,UAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,IAAI,YAAA,CAAa,mCAAA,EAAqC,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,EAClF;AAAA,EAEA,MAAc,SAAA,CAAU,GAAA,EAAa,OAAA,EAA4C;AAC/E,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,QAAQ,OAAO,CAAA;AACxD,IAAA,MAAM,OAAA,GAAU,CAAC,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAA,CAAO,CAACA,OAAAA,KAAkCA,YAAW,MAAS,CAAA;AAC7H,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AAC1C,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAQ,OAAO,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAI,UAAU,kBAAkB,CAAA;AACxC,IAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA;AAChD,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,iBAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,CAAE,CAAA;AACrF,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,GAAA,EAAK,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,MAAA,IAAU,IAAA,EAAM,CAAA;AAAA,EAC5F;AAAA,EAEA,MAAc,OAAU,QAAA,EAAgC;AACtD,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,cAAc,gCAAA,EAAkC;AAAA,QACxD,QAAQ,QAAA,CAAS,MAAA;AAAA,QAAQ,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,QAAG;AAAA,OAC/D,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,SAAS,QAAA,EAA4C;AACjE,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACnD,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,OAAA,KAAY,WAAW,IAAA,CAAK,OAAA,GAAU,CAAA,wCAAA,EAA2C,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA;AAC5H,IAAA,MAAM,aAAa,IAAA,CAAK,eAAA,CAAgB,SAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAC,CAAA;AAC3E,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,MAClC,UAAA;AAAA,MACA,MAAM,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,KAAK,IAAA,GAAO;AAAA,KACpD;AACA,IAAA,IAAI,SAAS,MAAA,KAAW,GAAA,SAAY,IAAI,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAC5E,IAAA,IAAI,SAAS,MAAA,KAAW,GAAA,SAAY,IAAI,kBAAA,CAAmB,SAAS,OAAO,CAAA;AAC3E,IAAA,IAAI,SAAS,MAAA,KAAW,GAAA,SAAY,IAAI,aAAA,CAAc,SAAS,OAAO,CAAA;AACtE,IAAA,IAAI,SAAS,MAAA,KAAW,GAAA,SAAY,IAAI,aAAA,CAAc,SAAS,OAAO,CAAA;AACtE,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,IAAO,QAAA,CAAS,MAAA,KAAW,KAAK,OAAO,IAAI,eAAA,CAAgB,OAAA,EAAS,OAAO,CAAA;AACnG,IAAA,IAAI,SAAS,MAAA,KAAW,GAAA,SAAY,IAAI,cAAA,CAAe,SAAS,OAAO,CAAA;AACvE,IAAA,IAAI,SAAS,MAAA,IAAU,GAAA,SAAY,IAAI,WAAA,CAAY,SAAS,OAAO,CAAA;AACnE,IAAA,OAAO,IAAI,aAAA,CAAc,OAAA,EAAS,OAAO,CAAA;AAAA,EAC3C;AAAA,EAEQ,UAAA,CAAW,UAAoB,OAAA,EAAyB;AAC9D,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAC,CAAA,IAAK,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAA;AAAA,EAC1F;AAAA,EACQ,gBAAgB,KAAA,EAA0C;AAChE,IAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,IAAA,MAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC5B,IAAA,IAAI,MAAA,CAAO,SAAS,OAAO,CAAA,SAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,GAAU,GAAI,CAAA;AAC/D,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAC7B,IAAA,OAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,MAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAAA,EACvE;AAAA,EACQ,QAAQ,OAAA,EAAyB;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,iBAAkB,CAAA,IAAK,OAAA;AACtD,IAAA,OAAO,KAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,MAAM,UAAU,CAAA;AAAA,EACpD;AAAA,EACA,MAAc,KAAA,CAAM,EAAA,EAAY,MAAA,EAAqC;AACnE,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,EAAS,EAAE,CAAA;AACpC,MAAA,MAAA,EAAQ,gBAAA,CAAiB,SAAS,MAAM;AAAE,QAAA,YAAA,CAAa,KAAK,CAAA;AAAG,QAAA,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,MAAG,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IACzG,CAAC,CAAA;AAAA,EACH;AAAA,EACQ,UAAU,QAAA,EAAwC;AACxD,IAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA;AAAA,EACjD;AAAA,EACQ,eAAe,OAAA,EAAiD;AACtE,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AACjC,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,QAAQ,CAAC,CAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,KAAwB;AACrC,MAAA,IAAI,CAAC,UAAA,CAAW,MAAA,CAAO,SAAS,UAAA,CAAW,KAAA,CAAM,OAAO,MAAM,CAAA;AAAA,IAChE,CAAA;AACA,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,KAAA,CAAM,MAAM,CAAA;AACZ,QAAA;AAAA,MACF;AACA,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM,KAAA,CAAM,MAAM,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,IACtE;AACA,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,EACpB;AAAA,EACQ,aAAa,MAAA,EAA+B;AAClD,IAAA,OAAO,QAAQ,MAAA,EAAQ,OAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAAA,EAChE;AAAA,EACQ,UAAU,KAAA,EAAyB;AACzC,IAAA,OAAO,KAAA,YAAiB,YAAA,KAAiB,KAAA,CAAM,IAAA,KAAS,cAAA,IAAkB,KAAA,CAAM,IAAA,KAAS,YAAA,CAAA,IACpF,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,OAAA;AAAA,EAC7B;AACF,CAAA;;;ACjHO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAEjB,IAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,MAAM,WAAW,OAAA,CAAQ,OAAA,IAAW,sBAAA,EAAwB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC9E,IAAA,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA;AACtC,IAAA,MAAM,SAAA,GAAY,IAAI,SAAA,CAAU;AAAA,MAC9B,GAAI,QAAQ,MAAA,GAAS,EAAE,QAAQ,OAAA,CAAQ,MAAA,KAAW,EAAC;AAAA,MACnD,OAAA;AAAA,MACA,OAAA,EAAS,QAAQ,OAAA,IAAW,GAAA;AAAA,MAC5B,OAAO,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AAAA,MACxD,KAAA,EAAO;AAAA,QACL,UAAA,EAAY,OAAA,CAAQ,KAAA,EAAO,UAAA,IAAc,CAAA;AAAA,QACzC,cAAA,EAAgB,OAAA,CAAQ,KAAA,EAAO,cAAA,IAAkB,GAAA;AAAA,QACjD,UAAA,EAAY,OAAA,CAAQ,KAAA,EAAO,UAAA,IAAc;AAAA,OAC3C;AAAA,MACA,SAAA,EAAW,QAAQ,SAAA,IAAa,qBAAA;AAAA,MAChC,OAAA,EAAS,OAAA,CAAQ,cAAA,IAAkB,EAAC;AAAA,MACpC,GAAI,QAAQ,MAAA,GAAS,EAAE,QAAQ,OAAA,CAAQ,MAAA,KAAW;AAAC,KACpD,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,SAAS,CAAA;AAAA,EACxC;AAAA,EAEQ,QAAA,CAAS,SAAiB,OAAA,EAAwB;AACxD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AAAE,MAAA,GAAA,GAAM,IAAI,IAAI,OAAO,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAE,MAAA,MAAM,IAAI,gBAAgB,0CAA0C,CAAA;AAAA,IAAG;AAC/G,IAAA,IAAI,CAAC,CAAC,OAAA,EAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,eAAA,CAAgB,0CAA0C,CAAA;AACrH,IAAA,MAAM,KAAA,GAAQ,CAAC,WAAA,EAAa,WAAA,EAAa,OAAO,CAAA,CAAE,QAAA,CAAS,IAAI,QAAQ,CAAA;AACvE,IAAA,IAAI,GAAA,CAAI,aAAa,QAAA,IAAY,CAAC,OAAO,MAAM,IAAI,gBAAgB,sDAAsD,CAAA;AACzH,IAAA,IAAI,OAAA,KAAY,MAAA,KAAc,CAAC,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,IAAK,OAAA,IAAW,CAAA,CAAA,EAAI,MAAM,IAAI,eAAA,CAAgB,oCAAoC,CAAA;AAAA,EAC1I;AACF","file":"index.js","sourcesContent":["export interface ErrorOptions {\n status?: number | undefined;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n code?: string | undefined;\n cause?: unknown | undefined;\n}\n\n/** Base class for all SDK errors. */\nexport class NewTqniaError extends Error {\n readonly status: number | undefined;\n readonly requestId: string | undefined;\n readonly retryAfter: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, options: ErrorOptions = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = new.target.name;\n this.status = options.status;\n this.requestId = options.requestId;\n this.retryAfter = options.retryAfter;\n this.code = options.code;\n }\n}\nexport class AuthenticationError extends NewTqniaError {}\nexport class AuthorizationError extends NewTqniaError {}\nexport class ValidationError extends NewTqniaError {}\nexport class NotFoundError extends NewTqniaError {}\nexport class ConflictError extends NewTqniaError {}\nexport class RateLimitError extends NewTqniaError {}\nexport class ServerError extends NewTqniaError {}\nexport class TimeoutError extends NewTqniaError {}\nexport class NetworkError extends NewTqniaError {}\n","import { ValidationError } from \"../errors/index.js\";\nimport type { Digest, NewsListParams } from \"../models/index.js\";\nimport type { Transport } from \"../transport/transport.js\";\n\n/** Access localized NewTqnia news collections. */\nexport class NewsResource {\n /** @internal */\n constructor(private readonly transport: Transport) {}\n\n /** Get articles published today using the Asia/Dubai day boundary. */\n today(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"today\", params);\n }\n\n /** Get the latest published articles. */\n latest(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"latest\", params);\n }\n\n private get(collection: \"today\" | \"latest\", params: NewsListParams): Promise<Digest> {\n if (params.locale !== undefined && params.locale !== \"en\" && params.locale !== \"ar\") {\n throw new ValidationError('locale must be \"en\" or \"ar\".');\n }\n if (params.limit !== undefined && (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 10)) {\n throw new ValidationError(\"limit must be an integer between 1 and 10.\");\n }\n if (params.category !== undefined && params.category.trim() === \"\") {\n throw new ValidationError(\"category cannot be empty.\");\n }\n return this.transport.request<Digest>({\n method: \"GET\",\n path: `/v1/news/${collection}`,\n query: { locale: params.locale, limit: params.limit, category: params.category },\n ...(params.signal ? { signal: params.signal } : {}),\n });\n }\n}\n","export function serializeQuery(values: Record<string, string | number | boolean | undefined>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined) search.append(key, String(value));\n }\n return search.toString();\n}\n","import {\n AuthenticationError, AuthorizationError, ConflictError, NetworkError, NewTqniaError,\n NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError,\n} from \"../errors/index.js\";\nimport { serializeQuery } from \"../utils/query.js\";\nimport type { Fetch, RequestOptions, RetryOptions } from \"./types.js\";\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport interface TransportOptions {\n apiKey?: string;\n baseUrl: string;\n timeout: number;\n fetch: Fetch;\n retry: Required<RetryOptions>;\n userAgent: string;\n headers: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport class Transport {\n constructor(private readonly options: TransportOptions) {}\n\n async request<T>(request: RequestOptions): Promise<T> {\n const query = request.query ? serializeQuery(request.query) : \"\";\n const url = `${this.options.baseUrl}${request.path}${query ? `?${query}` : \"\"}`;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.options.retry.maxRetries; attempt += 1) {\n try {\n const response = await this.fetchOnce(url, request);\n if (response.ok) return await this.decode<T>(response);\n if (RETRYABLE.has(response.status) && attempt < this.options.retry.maxRetries) {\n await this.pause(this.retryDelay(response, attempt), request.signal);\n continue;\n }\n throw await this.apiError(response);\n } catch (error) {\n if (error instanceof NewTqniaError) throw error;\n if (this.wasCancelled(request.signal)) throw error;\n if (this.isTimeout(error)) throw new TimeoutError(`Request timed out after ${this.options.timeout}ms`, { cause: error });\n lastError = error;\n if (attempt < this.options.retry.maxRetries) {\n await this.pause(this.backoff(attempt), request.signal);\n continue;\n }\n }\n }\n throw new NetworkError(\"Unable to reach the NewTqnia API.\", { cause: lastError });\n }\n\n private async fetchOnce(url: string, request: RequestOptions): Promise<Response> {\n const timeout = AbortSignal.timeout(this.options.timeout);\n const signals = [timeout, this.options.signal, request.signal].filter((signal): signal is AbortSignal => signal !== undefined);\n const signal = this.combineSignals(signals);\n const headers = new Headers(this.options.headers);\n headers.set(\"Accept\", \"application/json\");\n headers.set(\"User-Agent\", this.options.userAgent);\n if (this.options.apiKey) headers.set(\"Authorization\", `Bearer ${this.options.apiKey}`);\n return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });\n }\n\n private async decode<T>(response: Response): Promise<T> {\n try {\n return await response.json() as T;\n } catch (cause) {\n throw new NewTqniaError(\"The API returned invalid JSON.\", {\n status: response.status, requestId: this.requestId(response), cause,\n });\n }\n }\n\n private async apiError(response: Response): Promise<NewTqniaError> {\n const data = await response.json().catch(() => ({})) as Record<string, unknown>;\n const message = typeof data.message === \"string\" ? data.message : `NewTqnia API request failed with status ${response.status}.`;\n const retryAfter = this.parseRetryAfter(response.headers.get(\"retry-after\"));\n const options = {\n status: response.status,\n requestId: this.requestId(response),\n retryAfter,\n code: typeof data.code === \"string\" ? data.code : undefined,\n };\n if (response.status === 401) return new AuthenticationError(message, options);\n if (response.status === 403) return new AuthorizationError(message, options);\n if (response.status === 404) return new NotFoundError(message, options);\n if (response.status === 409) return new ConflictError(message, options);\n if (response.status === 422 || response.status === 400) return new ValidationError(message, options);\n if (response.status === 429) return new RateLimitError(message, options);\n if (response.status >= 500) return new ServerError(message, options);\n return new NewTqniaError(message, options);\n }\n\n private retryDelay(response: Response, attempt: number): number {\n return this.parseRetryAfter(response.headers.get(\"retry-after\")) ?? this.backoff(attempt);\n }\n private parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n }\n private backoff(attempt: number): number {\n const raw = this.options.retry.initialDelayMs * (2 ** attempt);\n return Math.min(raw, this.options.retry.maxDelayMs);\n }\n private async pause(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); reject(signal.reason); }, { once: true });\n });\n }\n private requestId(response: Response): string | undefined {\n return response.headers.get(\"x-request-id\") ?? undefined;\n }\n private combineSignals(signals: AbortSignal[]): AbortSignal | undefined {\n if (signals.length === 0) return undefined;\n if (signals.length === 1) return signals[0];\n const controller = new AbortController();\n const abort = (signal: AbortSignal) => {\n if (!controller.signal.aborted) controller.abort(signal.reason);\n };\n for (const signal of signals) {\n if (signal.aborted) {\n abort(signal);\n break;\n }\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n }\n return controller.signal;\n }\n private wasCancelled(signal?: AbortSignal): boolean {\n return Boolean(signal?.aborted || this.options.signal?.aborted);\n }\n private isTimeout(error: unknown): boolean {\n return error instanceof DOMException && (error.name === \"TimeoutError\" || error.name === \"AbortError\")\n && !this.options.signal?.aborted;\n }\n}\n","import { ValidationError } from \"../errors/index.js\";\nimport { NewsResource } from \"../resources/news.js\";\nimport { Transport } from \"../transport/transport.js\";\nimport type { Fetch, RetryOptions } from \"../transport/types.js\";\n\nexport interface NewTqniaClientOptions {\n /** Optional bearer API key. */\n apiKey?: string;\n /** API origin. @default \"https://newtqnia.com\" */\n baseUrl?: string;\n /** Request timeout in milliseconds. @default 30000 */\n timeout?: number;\n /** Cancels every request made by this client. */\n signal?: AbortSignal;\n /** Custom Fetch-compatible implementation. */\n fetch?: Fetch;\n /** Retry behavior for rate limits, server errors, and temporary network failures. */\n retry?: RetryOptions;\n /** User-Agent header. @default \"newtqnia-node/1.0.0\" */\n userAgent?: string;\n /** Headers included with every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Official NewTqnia API client. */\nexport class NewTqniaClient {\n /** Localized news endpoints. */\n readonly news: NewsResource;\n\n constructor(options: NewTqniaClientOptions = {}) {\n const baseUrl = (options.baseUrl ?? \"https://newtqnia.com\").replace(/\\/+$/, \"\");\n this.validate(baseUrl, options.timeout);\n const transport = new Transport({\n ...(options.apiKey ? { apiKey: options.apiKey } : {}),\n baseUrl,\n timeout: options.timeout ?? 30_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n retry: {\n maxRetries: options.retry?.maxRetries ?? 2,\n initialDelayMs: options.retry?.initialDelayMs ?? 500,\n maxDelayMs: options.retry?.maxDelayMs ?? 8_000,\n },\n userAgent: options.userAgent ?? \"newtqnia-node/1.0.0\",\n headers: options.defaultHeaders ?? {},\n ...(options.signal ? { signal: options.signal } : {}),\n });\n this.news = new NewsResource(transport);\n }\n\n private validate(baseUrl: string, timeout?: number): void {\n let url: URL;\n try { url = new URL(baseUrl); } catch { throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\"); }\n if (![\"http:\", \"https:\"].includes(url.protocol)) throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\");\n const local = [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname);\n if (url.protocol !== \"https:\" && !local) throw new ValidationError(\"baseUrl must use HTTPS except for local development.\");\n if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) throw new ValidationError(\"timeout must be a positive number.\");\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/resources/news.ts","../src/utils/query.ts","../src/transport/transport.ts","../src/client/client.ts"],"names":["signal"],"mappings":"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","file":"index.js","sourcesContent":["export interface ErrorOptions {\n status?: number | undefined;\n requestId?: string | undefined;\n retryAfter?: number | undefined;\n code?: string | undefined;\n cause?: unknown | undefined;\n}\n\n/** Base class for all SDK errors. */\nexport class NewTqniaError extends Error {\n readonly status: number | undefined;\n readonly requestId: string | undefined;\n readonly retryAfter: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, options: ErrorOptions = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = new.target.name;\n this.status = options.status;\n this.requestId = options.requestId;\n this.retryAfter = options.retryAfter;\n this.code = options.code;\n }\n}\nexport class AuthenticationError extends NewTqniaError {}\nexport class AuthorizationError extends NewTqniaError {}\nexport class ValidationError extends NewTqniaError {}\nexport class NotFoundError extends NewTqniaError {}\nexport class ConflictError extends NewTqniaError {}\nexport class RateLimitError extends NewTqniaError {}\nexport class ServerError extends NewTqniaError {}\nexport class TimeoutError extends NewTqniaError {}\nexport class NetworkError extends NewTqniaError {}\n","import { ValidationError } from \"../errors/index.js\";\nimport type { Digest, NewsListParams } from \"../models/index.js\";\nimport type { Transport } from \"../transport/transport.js\";\n\n/** Access localized NewTqnia news collections. */\nexport class NewsResource {\n /** @internal */\n constructor(private readonly transport: Transport) {}\n\n /** Get articles published today using the Asia/Dubai day boundary. */\n today(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"today\", params);\n }\n\n /** Get the latest published articles. */\n latest(params: NewsListParams = {}): Promise<Digest> {\n return this.get(\"latest\", params);\n }\n\n private get(collection: \"today\" | \"latest\", params: NewsListParams): Promise<Digest> {\n if (params.locale !== undefined && params.locale !== \"en\" && params.locale !== \"ar\") {\n throw new ValidationError('locale must be \"en\" or \"ar\".');\n }\n if (params.limit !== undefined && (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 10)) {\n throw new ValidationError(\"limit must be an integer between 1 and 10.\");\n }\n if (params.category !== undefined && params.category.trim() === \"\") {\n throw new ValidationError(\"category cannot be empty.\");\n }\n return this.transport.request<Digest>({\n method: \"GET\",\n path: `/v1/news/${collection}`,\n query: { locale: params.locale, limit: params.limit, category: params.category },\n ...(params.signal ? { signal: params.signal } : {}),\n });\n }\n}\n","export function serializeQuery(values: Record<string, string | number | boolean | undefined>): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined) search.append(key, String(value));\n }\n return search.toString();\n}\n","import {\n AuthenticationError, AuthorizationError, ConflictError, NetworkError, NewTqniaError,\n NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError,\n} from \"../errors/index.js\";\nimport { serializeQuery } from \"../utils/query.js\";\nimport type { Fetch, RequestOptions, RetryOptions } from \"./types.js\";\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport interface TransportOptions {\n apiKey?: string;\n rapidApiKey?: string;\n application?: string;\n website?: string;\n baseUrl: string;\n timeout: number;\n fetch: Fetch;\n retry: Required<RetryOptions>;\n userAgent: string;\n headers: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport class Transport {\n constructor(private readonly options: TransportOptions) {}\n\n async request<T>(request: RequestOptions): Promise<T> {\n const query = request.query ? serializeQuery(request.query) : \"\";\n const url = `${this.options.baseUrl}${request.path}${query ? `?${query}` : \"\"}`;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.options.retry.maxRetries; attempt += 1) {\n try {\n const response = await this.fetchOnce(url, request);\n if (response.ok) return await this.decode<T>(response);\n if (RETRYABLE.has(response.status) && attempt < this.options.retry.maxRetries) {\n await this.pause(this.retryDelay(response, attempt), request.signal);\n continue;\n }\n throw await this.apiError(response);\n } catch (error) {\n if (error instanceof NewTqniaError) throw error;\n if (this.wasCancelled(request.signal)) throw error;\n if (this.isTimeout(error)) throw new TimeoutError(`Request timed out after ${this.options.timeout}ms`, { cause: error });\n lastError = error;\n if (attempt < this.options.retry.maxRetries) {\n await this.pause(this.backoff(attempt), request.signal);\n continue;\n }\n }\n }\n throw new NetworkError(\"Unable to reach the NewTqnia API.\", { cause: lastError });\n }\n\n private async fetchOnce(url: string, request: RequestOptions): Promise<Response> {\n const timeout = AbortSignal.timeout(this.options.timeout);\n const signals = [timeout, this.options.signal, request.signal].filter((signal): signal is AbortSignal => signal !== undefined);\n const signal = this.combineSignals(signals);\n const headers = new Headers(this.options.headers);\n headers.set(\"Accept\", \"application/json\");\n headers.set(\"User-Agent\", this.options.userAgent);\n if (this.options.apiKey) headers.set(\"X-API-Key\", this.options.apiKey);\n if (this.options.rapidApiKey) headers.set(\"X-RapidAPI-Key\", this.options.rapidApiKey);\n if (this.options.application) headers.set(\"X-NewTqnia-Application\", this.options.application);\n if (this.options.website) headers.set(\"X-NewTqnia-Website\", this.options.website);\n return this.options.fetch(url, { method: request.method, headers, signal: signal ?? null });\n }\n\n private async decode<T>(response: Response): Promise<T> {\n try {\n return await response.json() as T;\n } catch (cause) {\n throw new NewTqniaError(\"The API returned invalid JSON.\", {\n status: response.status, requestId: this.requestId(response), cause,\n });\n }\n }\n\n private async apiError(response: Response): Promise<NewTqniaError> {\n const data = await response.json().catch(() => ({})) as Record<string, unknown>;\n const message = typeof data.message === \"string\" ? data.message : `NewTqnia API request failed with status ${response.status}.`;\n const retryAfter = this.parseRetryAfter(response.headers.get(\"retry-after\"));\n const options = {\n status: response.status,\n requestId: this.requestId(response),\n retryAfter,\n code: typeof data.code === \"string\" ? data.code : undefined,\n };\n if (response.status === 401) return new AuthenticationError(message, options);\n if (response.status === 403) return new AuthorizationError(message, options);\n if (response.status === 404) return new NotFoundError(message, options);\n if (response.status === 409) return new ConflictError(message, options);\n if (response.status === 422 || response.status === 400) return new ValidationError(message, options);\n if (response.status === 429) return new RateLimitError(message, options);\n if (response.status >= 500) return new ServerError(message, options);\n return new NewTqniaError(message, options);\n }\n\n private retryDelay(response: Response, attempt: number): number {\n return this.parseRetryAfter(response.headers.get(\"retry-after\")) ?? this.backoff(attempt);\n }\n private parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n }\n private backoff(attempt: number): number {\n const raw = this.options.retry.initialDelayMs * (2 ** attempt);\n return Math.min(raw, this.options.retry.maxDelayMs);\n }\n private async pause(ms: number, signal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); reject(signal.reason); }, { once: true });\n });\n }\n private requestId(response: Response): string | undefined {\n return response.headers.get(\"x-request-id\") ?? undefined;\n }\n private combineSignals(signals: AbortSignal[]): AbortSignal | undefined {\n if (signals.length === 0) return undefined;\n if (signals.length === 1) return signals[0];\n const controller = new AbortController();\n const abort = (signal: AbortSignal) => {\n if (!controller.signal.aborted) controller.abort(signal.reason);\n };\n for (const signal of signals) {\n if (signal.aborted) {\n abort(signal);\n break;\n }\n signal.addEventListener(\"abort\", () => abort(signal), { once: true });\n }\n return controller.signal;\n }\n private wasCancelled(signal?: AbortSignal): boolean {\n return Boolean(signal?.aborted || this.options.signal?.aborted);\n }\n private isTimeout(error: unknown): boolean {\n return error instanceof DOMException && (error.name === \"TimeoutError\" || error.name === \"AbortError\")\n && !this.options.signal?.aborted;\n }\n}\n","import { ValidationError } from \"../errors/index.js\";\nimport { NewsResource } from \"../resources/news.js\";\nimport { Transport } from \"../transport/transport.js\";\nimport type { Fetch, RetryOptions } from \"../transport/types.js\";\n\nexport interface NewTqniaClientOptions {\n /** Optional NewTqnia API key sent as X-API-Key. */\n apiKey?: string;\n /** Optional RapidAPI key sent as X-RapidAPI-Key. */\n rapidApiKey?: string;\n /** Optional caller application name. */\n application?: string;\n /** Optional caller website origin. */\n website?: string;\n /** API origin. @default \"https://api.newtqnia.com\" */\n baseUrl?: string;\n /** Request timeout in milliseconds. @default 30000 */\n timeout?: number;\n /** Cancels every request made by this client. */\n signal?: AbortSignal;\n /** Custom Fetch-compatible implementation. */\n fetch?: Fetch;\n /** Retry behavior for rate limits, server errors, and temporary network failures. */\n retry?: RetryOptions;\n /** User-Agent header. @default \"newtqnia-node/1.1.0\" */\n userAgent?: string;\n /** Headers included with every request. */\n defaultHeaders?: Record<string, string>;\n}\n\n/** Official NewTqnia API client. */\nexport class NewTqniaClient {\n /** Localized news endpoints. */\n readonly news: NewsResource;\n\n constructor(options: NewTqniaClientOptions = {}) {\n const baseUrl = (options.baseUrl ?? \"https://api.newtqnia.com\").replace(/\\/+$/, \"\");\n this.validate(baseUrl, options.timeout);\n const transport = new Transport({\n ...(options.apiKey ? { apiKey: options.apiKey } : {}),\n ...(options.rapidApiKey ? { rapidApiKey: options.rapidApiKey } : {}),\n ...(options.application ? { application: options.application } : {}),\n ...(options.website ? { website: options.website } : {}),\n baseUrl,\n timeout: options.timeout ?? 30_000,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n retry: {\n maxRetries: options.retry?.maxRetries ?? 2,\n initialDelayMs: options.retry?.initialDelayMs ?? 500,\n maxDelayMs: options.retry?.maxDelayMs ?? 8_000,\n },\n userAgent: options.userAgent ?? \"newtqnia-node/1.1.0\",\n headers: options.defaultHeaders ?? {},\n ...(options.signal ? { signal: options.signal } : {}),\n });\n this.news = new NewsResource(transport);\n }\n\n private validate(baseUrl: string, timeout?: number): void {\n let url: URL;\n try { url = new URL(baseUrl); } catch { throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\"); }\n if (![\"http:\", \"https:\"].includes(url.protocol)) throw new ValidationError(\"baseUrl must be an absolute HTTP(S) URL.\");\n const local = [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname);\n if (url.protocol !== \"https:\" && !local) throw new ValidationError(\"baseUrl must use HTTPS except for local development.\");\n if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) throw new ValidationError(\"timeout must be a positive number.\");\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newtqnia-node",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Official Node.js and TypeScript SDK for the NewTqnia technology news API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",