@greatapps/common 1.1.127 → 1.1.128
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/infra/api/client.mjs +23 -11
- package/dist/infra/api/client.mjs.map +1 -1
- package/package.json +1 -1
- package/src/infra/api/client.ts +37 -12
|
@@ -4,11 +4,15 @@ class ApiClient {
|
|
|
4
4
|
baseUrl;
|
|
5
5
|
apiVersion = "v1";
|
|
6
6
|
apiLocale = "pt-br";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
omitApiVersion;
|
|
8
|
+
constructor(baseUrl, options) {
|
|
9
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
10
|
+
this.omitApiVersion = options?.omitApiVersion ?? false;
|
|
9
11
|
}
|
|
10
12
|
async buildUrl(endpoint, whiteLabelId) {
|
|
11
|
-
const
|
|
13
|
+
const wlPath = this.omitApiVersion ? `/${this.apiLocale}/${whiteLabelId}` : `/${this.apiVersion}/${this.apiLocale}/${whiteLabelId}`;
|
|
14
|
+
const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
|
|
15
|
+
const url = `${this.baseUrl}${wlPath}${path}`;
|
|
12
16
|
console.log("[ApiClient] buildUrl", {
|
|
13
17
|
baseURL: this.baseUrl,
|
|
14
18
|
whiteLabelId,
|
|
@@ -31,7 +35,7 @@ class ApiClient {
|
|
|
31
35
|
}
|
|
32
36
|
async request(endpoint, config = {}) {
|
|
33
37
|
console.log("[ApiClient] request called", { endpoint, method: config.method });
|
|
34
|
-
const { timeout = 3e4, ...fetchConfig } = config;
|
|
38
|
+
const { timeout = 3e4, responseType = "json", ...fetchConfig } = config;
|
|
35
39
|
const controller = new AbortController();
|
|
36
40
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
37
41
|
try {
|
|
@@ -56,13 +60,21 @@ class ApiClient {
|
|
|
56
60
|
});
|
|
57
61
|
console.log("[ApiClient] Response received", { status: response.status, ok: response.ok });
|
|
58
62
|
if (!response.ok) {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
errorData
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const errBody = await response.text();
|
|
64
|
+
let message = `HTTP error ${response.status}`;
|
|
65
|
+
let code = "HTTP_ERROR";
|
|
66
|
+
try {
|
|
67
|
+
const errorData = JSON.parse(errBody);
|
|
68
|
+
if (typeof errorData.message === "string") message = errorData.message;
|
|
69
|
+
if (typeof errorData.code === "string") code = errorData.code;
|
|
70
|
+
} catch {
|
|
71
|
+
if (errBody.trim()) message = errBody.trim();
|
|
72
|
+
}
|
|
73
|
+
console.error("[ApiClient] Request failed", { status: response.status, message });
|
|
74
|
+
throw new ApiError(message, code, response.status);
|
|
75
|
+
}
|
|
76
|
+
if (responseType === "text") {
|
|
77
|
+
return await response.text();
|
|
66
78
|
}
|
|
67
79
|
const data = await response.json();
|
|
68
80
|
console.log("[ApiClient] Request successful", { hasData: !!data });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/infra/api/client.ts"],"sourcesContent":["import { ApiError } from './types';\r\nimport { findWhitelabel } from '../../modules/whitelabel/actions/find-whitelabel.action';\r\n\r\
|
|
1
|
+
{"version":3,"sources":["../../../src/infra/api/client.ts"],"sourcesContent":["import { ApiError } from './types';\r\nimport { findWhitelabel } from '../../modules/whitelabel/actions/find-whitelabel.action';\r\n\r\nexport interface ApiClientOptions {\r\n /**\r\n * Quando true, monta `{base}/{locale}/{wlId}{endpoint}` (ex.: r2-clone).\r\n * Padrão false: `{base}/v1/{locale}/{wlId}{endpoint}`.\r\n */\r\n omitApiVersion?: boolean;\r\n}\r\n\r\nexport interface RequestConfig extends RequestInit {\r\n timeout?: number;\r\n /** Padrão `json`. Use `text` quando a API devolve corpo não-JSON. */\r\n responseType?: 'json' | 'text';\r\n}\r\n\r\nclass ApiClient {\r\n private readonly baseUrl: string;\r\n private readonly apiVersion = 'v1';\r\n private readonly apiLocale = 'pt-br';\r\n private readonly omitApiVersion: boolean;\r\n\r\n constructor(baseUrl: string, options?: ApiClientOptions) {\r\n this.baseUrl = baseUrl.replace(/\\/$/, '');\r\n this.omitApiVersion = options?.omitApiVersion ?? false;\r\n }\r\n\r\n private async buildUrl(endpoint: string, whiteLabelId: number): Promise<string> {\r\n const wlPath = this.omitApiVersion\r\n ? `/${this.apiLocale}/${whiteLabelId}`\r\n : `/${this.apiVersion}/${this.apiLocale}/${whiteLabelId}`;\r\n const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;\r\n const url = `${this.baseUrl}${wlPath}${path}`;\r\n console.log('[ApiClient] buildUrl', {\r\n baseURL: this.baseUrl,\r\n whiteLabelId,\r\n endpoint,\r\n fullUrl: url,\r\n });\r\n return url;\r\n }\r\n\r\n private async getDefaultHeaders(token: string, isFormData = false): Promise<HeadersInit> {\r\n console.log('[ApiClient] getDefaultHeaders', {\r\n token: token.substring(0, 20) + '...',\r\n });\r\n\r\n const headers: HeadersInit = {\r\n authorization: token,\r\n };\r\n\r\n if (!isFormData) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n async request<T>(endpoint: string, config: RequestConfig = {}): Promise<T> {\r\n console.log('[ApiClient] request called', { endpoint, method: config.method });\r\n\r\n const { timeout = 30000, responseType = 'json', ...fetchConfig } = config;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n\r\n try {\r\n console.log('[ApiClient] Building URL and headers...');\r\n\r\n const { id, token } = await findWhitelabel();\r\n\r\n const [url, defaultHeaders] = await Promise.all([\r\n this.buildUrl(endpoint, id),\r\n this.getDefaultHeaders(token, fetchConfig.body instanceof FormData),\r\n ]);\r\n\r\n console.log('[ApiClient] Fetching', {\r\n url,\r\n method: fetchConfig.method,\r\n headers: defaultHeaders,\r\n });\r\n\r\n const response = await fetch(url, {\r\n ...fetchConfig,\r\n headers: {\r\n ...defaultHeaders,\r\n ...fetchConfig.headers,\r\n },\r\n signal: controller.signal,\r\n });\r\n\r\n console.log('[ApiClient] Response received', { status: response.status, ok: response.ok });\r\n\r\n if (!response.ok) {\r\n const errBody = await response.text();\r\n let message = `HTTP error ${response.status}`;\r\n let code = 'HTTP_ERROR';\r\n try {\r\n const errorData = JSON.parse(errBody) as Record<string, unknown>;\r\n if (typeof errorData.message === 'string') message = errorData.message;\r\n if (typeof errorData.code === 'string') code = errorData.code;\r\n } catch {\r\n if (errBody.trim()) message = errBody.trim();\r\n }\r\n console.error('[ApiClient] Request failed', { status: response.status, message });\r\n throw new ApiError(message, code, response.status);\r\n }\r\n\r\n if (responseType === 'text') {\r\n return (await response.text()) as T;\r\n }\r\n\r\n const data = (await response.json()) as T;\r\n console.log('[ApiClient] Request successful', { hasData: !!data });\r\n return data;\r\n } catch (error) {\r\n console.error('[ApiClient] Request error', { error });\r\n\r\n if (error instanceof ApiError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error) {\r\n if (error.name === 'AbortError') {\r\n throw new ApiError('Tempo de requisição excedido', 'TIMEOUT', 408);\r\n }\r\n throw new ApiError(error.message, 'NETWORK_ERROR', 0);\r\n }\r\n\r\n throw new ApiError('Erro desconhecido', 'UNKNOWN_ERROR', 500);\r\n } finally {\r\n clearTimeout(timeoutId);\r\n }\r\n }\r\n\r\n async get<T>(endpoint: string, config?: RequestConfig): Promise<T> {\r\n return this.request<T>(endpoint, { ...config, method: 'GET' });\r\n }\r\n\r\n async post<T>(endpoint: string, data?: unknown, config?: RequestConfig): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n ...config,\r\n method: 'POST',\r\n body: data instanceof FormData ? data : data ? JSON.stringify(data) : undefined,\r\n });\r\n }\r\n\r\n async put<T>(endpoint: string, data?: unknown, config?: RequestConfig): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n ...config,\r\n method: 'PUT',\r\n body: data instanceof FormData ? data : data ? JSON.stringify(data) : undefined,\r\n });\r\n }\r\n\r\n async patch<T>(endpoint: string, data?: unknown, config?: RequestConfig): Promise<T> {\r\n return this.request<T>(endpoint, {\r\n ...config,\r\n method: 'PATCH',\r\n body: data instanceof FormData ? data : data ? JSON.stringify(data) : undefined,\r\n });\r\n }\r\n\r\n async delete<T>(endpoint: string, config?: RequestConfig): Promise<T> {\r\n return this.request<T>(endpoint, { ...config, method: 'DELETE' });\r\n }\r\n}\r\n\r\nconst api = {\r\n apps: new ApiClient(process.env.GAPPS_R3_API_URL || 'https://r3-api.greatapps.dev.br'),\r\n pages: new ApiClient(process.env.GPAGES_R3_API_URL || 'https://r3-api.greatpages.dev.br'),\r\n}\r\n\r\n/** @deprecated use api.apps */\r\nexport const apiClient = api.apps;\r\n\r\nexport { api, ApiClient };\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
package/src/infra/api/client.ts
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { ApiError } from './types';
|
|
2
2
|
import { findWhitelabel } from '../../modules/whitelabel/actions/find-whitelabel.action';
|
|
3
3
|
|
|
4
|
-
interface
|
|
4
|
+
export interface ApiClientOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Quando true, monta `{base}/{locale}/{wlId}{endpoint}` (ex.: r2-clone).
|
|
7
|
+
* Padrão false: `{base}/v1/{locale}/{wlId}{endpoint}`.
|
|
8
|
+
*/
|
|
9
|
+
omitApiVersion?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface RequestConfig extends RequestInit {
|
|
5
13
|
timeout?: number;
|
|
14
|
+
/** Padrão `json`. Use `text` quando a API devolve corpo não-JSON. */
|
|
15
|
+
responseType?: 'json' | 'text';
|
|
6
16
|
}
|
|
7
17
|
|
|
8
18
|
class ApiClient {
|
|
9
19
|
private readonly baseUrl: string;
|
|
10
20
|
private readonly apiVersion = 'v1';
|
|
11
21
|
private readonly apiLocale = 'pt-br';
|
|
22
|
+
private readonly omitApiVersion: boolean;
|
|
12
23
|
|
|
13
|
-
constructor(baseUrl: string) {
|
|
14
|
-
this.baseUrl = baseUrl;
|
|
24
|
+
constructor(baseUrl: string, options?: ApiClientOptions) {
|
|
25
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
26
|
+
this.omitApiVersion = options?.omitApiVersion ?? false;
|
|
15
27
|
}
|
|
16
28
|
|
|
17
29
|
private async buildUrl(endpoint: string, whiteLabelId: number): Promise<string> {
|
|
18
|
-
const
|
|
30
|
+
const wlPath = this.omitApiVersion
|
|
31
|
+
? `/${this.apiLocale}/${whiteLabelId}`
|
|
32
|
+
: `/${this.apiVersion}/${this.apiLocale}/${whiteLabelId}`;
|
|
33
|
+
const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
|
|
34
|
+
const url = `${this.baseUrl}${wlPath}${path}`;
|
|
19
35
|
console.log('[ApiClient] buildUrl', {
|
|
20
36
|
baseURL: this.baseUrl,
|
|
21
37
|
whiteLabelId,
|
|
@@ -44,7 +60,7 @@ class ApiClient {
|
|
|
44
60
|
async request<T>(endpoint: string, config: RequestConfig = {}): Promise<T> {
|
|
45
61
|
console.log('[ApiClient] request called', { endpoint, method: config.method });
|
|
46
62
|
|
|
47
|
-
const { timeout = 30000, ...fetchConfig } = config;
|
|
63
|
+
const { timeout = 30000, responseType = 'json', ...fetchConfig } = config;
|
|
48
64
|
|
|
49
65
|
const controller = new AbortController();
|
|
50
66
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
@@ -77,13 +93,22 @@ class ApiClient {
|
|
|
77
93
|
console.log('[ApiClient] Response received', { status: response.status, ok: response.ok });
|
|
78
94
|
|
|
79
95
|
if (!response.ok) {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
const errBody = await response.text();
|
|
97
|
+
let message = `HTTP error ${response.status}`;
|
|
98
|
+
let code = 'HTTP_ERROR';
|
|
99
|
+
try {
|
|
100
|
+
const errorData = JSON.parse(errBody) as Record<string, unknown>;
|
|
101
|
+
if (typeof errorData.message === 'string') message = errorData.message;
|
|
102
|
+
if (typeof errorData.code === 'string') code = errorData.code;
|
|
103
|
+
} catch {
|
|
104
|
+
if (errBody.trim()) message = errBody.trim();
|
|
105
|
+
}
|
|
106
|
+
console.error('[ApiClient] Request failed', { status: response.status, message });
|
|
107
|
+
throw new ApiError(message, code, response.status);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (responseType === 'text') {
|
|
111
|
+
return (await response.text()) as T;
|
|
87
112
|
}
|
|
88
113
|
|
|
89
114
|
const data = (await response.json()) as T;
|