@insforge/sdk 1.2.0-dev.2 → 1.2.1-dev.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 +2 -2
- package/dist/index.d.mts +146 -3
- package/dist/index.d.ts +146 -3
- package/dist/index.js +374 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +373 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -17,9 +17,191 @@ var InsForgeError = class _InsForgeError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
// src/lib/logger.ts
|
|
21
|
+
var SENSITIVE_HEADERS = ["authorization", "x-api-key", "cookie", "set-cookie"];
|
|
22
|
+
var SENSITIVE_BODY_KEYS = [
|
|
23
|
+
"password",
|
|
24
|
+
"token",
|
|
25
|
+
"accesstoken",
|
|
26
|
+
"refreshtoken",
|
|
27
|
+
"authorization",
|
|
28
|
+
"secret",
|
|
29
|
+
"apikey",
|
|
30
|
+
"api_key",
|
|
31
|
+
"email",
|
|
32
|
+
"ssn",
|
|
33
|
+
"creditcard",
|
|
34
|
+
"credit_card"
|
|
35
|
+
];
|
|
36
|
+
function redactHeaders(headers) {
|
|
37
|
+
const redacted = {};
|
|
38
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
39
|
+
if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {
|
|
40
|
+
redacted[key] = "***REDACTED***";
|
|
41
|
+
} else {
|
|
42
|
+
redacted[key] = value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return redacted;
|
|
46
|
+
}
|
|
47
|
+
function sanitizeBody(body) {
|
|
48
|
+
if (body === null || body === void 0) return body;
|
|
49
|
+
if (typeof body === "string") {
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(body);
|
|
52
|
+
return sanitizeBody(parsed);
|
|
53
|
+
} catch {
|
|
54
|
+
return body;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(body)) return body.map(sanitizeBody);
|
|
58
|
+
if (typeof body === "object") {
|
|
59
|
+
const sanitized = {};
|
|
60
|
+
for (const [key, value] of Object.entries(body)) {
|
|
61
|
+
if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ""))) {
|
|
62
|
+
sanitized[key] = "***REDACTED***";
|
|
63
|
+
} else {
|
|
64
|
+
sanitized[key] = sanitizeBody(value);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return sanitized;
|
|
68
|
+
}
|
|
69
|
+
return body;
|
|
70
|
+
}
|
|
71
|
+
function formatBody(body) {
|
|
72
|
+
if (body === void 0 || body === null) return "";
|
|
73
|
+
if (typeof body === "string") {
|
|
74
|
+
try {
|
|
75
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
76
|
+
} catch {
|
|
77
|
+
return body;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
81
|
+
return "[FormData]";
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return JSON.stringify(body, null, 2);
|
|
85
|
+
} catch {
|
|
86
|
+
return "[Unserializable body]";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var Logger = class {
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new Logger instance.
|
|
92
|
+
* @param debug - Set to true to enable console logging, or pass a custom log function
|
|
93
|
+
*/
|
|
94
|
+
constructor(debug) {
|
|
95
|
+
if (typeof debug === "function") {
|
|
96
|
+
this.enabled = true;
|
|
97
|
+
this.customLog = debug;
|
|
98
|
+
} else {
|
|
99
|
+
this.enabled = !!debug;
|
|
100
|
+
this.customLog = null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Logs a debug message at the info level.
|
|
105
|
+
* @param message - The message to log
|
|
106
|
+
* @param args - Additional arguments to pass to the log function
|
|
107
|
+
*/
|
|
108
|
+
log(message, ...args) {
|
|
109
|
+
if (!this.enabled) return;
|
|
110
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
111
|
+
if (this.customLog) {
|
|
112
|
+
this.customLog(formatted, ...args);
|
|
113
|
+
} else {
|
|
114
|
+
console.log(formatted, ...args);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Logs a debug message at the warning level.
|
|
119
|
+
* @param message - The message to log
|
|
120
|
+
* @param args - Additional arguments to pass to the log function
|
|
121
|
+
*/
|
|
122
|
+
warn(message, ...args) {
|
|
123
|
+
if (!this.enabled) return;
|
|
124
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
125
|
+
if (this.customLog) {
|
|
126
|
+
this.customLog(formatted, ...args);
|
|
127
|
+
} else {
|
|
128
|
+
console.warn(formatted, ...args);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Logs a debug message at the error level.
|
|
133
|
+
* @param message - The message to log
|
|
134
|
+
* @param args - Additional arguments to pass to the log function
|
|
135
|
+
*/
|
|
136
|
+
error(message, ...args) {
|
|
137
|
+
if (!this.enabled) return;
|
|
138
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
139
|
+
if (this.customLog) {
|
|
140
|
+
this.customLog(formatted, ...args);
|
|
141
|
+
} else {
|
|
142
|
+
console.error(formatted, ...args);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Logs an outgoing HTTP request with method, URL, headers, and body.
|
|
147
|
+
* Sensitive headers and body fields are automatically redacted.
|
|
148
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
149
|
+
* @param url - The full request URL
|
|
150
|
+
* @param headers - Request headers (sensitive values will be redacted)
|
|
151
|
+
* @param body - Request body (sensitive fields will be masked)
|
|
152
|
+
*/
|
|
153
|
+
logRequest(method, url, headers, body) {
|
|
154
|
+
if (!this.enabled) return;
|
|
155
|
+
const parts = [
|
|
156
|
+
`\u2192 ${method} ${url}`
|
|
157
|
+
];
|
|
158
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
159
|
+
parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);
|
|
160
|
+
}
|
|
161
|
+
const formattedBody = formatBody(sanitizeBody(body));
|
|
162
|
+
if (formattedBody) {
|
|
163
|
+
const truncated = formattedBody.length > 1e3 ? formattedBody.slice(0, 1e3) + "... [truncated]" : formattedBody;
|
|
164
|
+
parts.push(` Body: ${truncated}`);
|
|
165
|
+
}
|
|
166
|
+
this.log(parts.join("\n"));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Logs an incoming HTTP response with method, URL, status, duration, and body.
|
|
170
|
+
* Error responses (4xx/5xx) are logged at the error level.
|
|
171
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
172
|
+
* @param url - The full request URL
|
|
173
|
+
* @param status - HTTP response status code
|
|
174
|
+
* @param durationMs - Request duration in milliseconds
|
|
175
|
+
* @param body - Response body (sensitive fields will be masked, large bodies truncated)
|
|
176
|
+
*/
|
|
177
|
+
logResponse(method, url, status, durationMs, body) {
|
|
178
|
+
if (!this.enabled) return;
|
|
179
|
+
const parts = [
|
|
180
|
+
`\u2190 ${method} ${url} ${status} (${durationMs}ms)`
|
|
181
|
+
];
|
|
182
|
+
const formattedBody = formatBody(sanitizeBody(body));
|
|
183
|
+
if (formattedBody) {
|
|
184
|
+
const truncated = formattedBody.length > 1e3 ? formattedBody.slice(0, 1e3) + "... [truncated]" : formattedBody;
|
|
185
|
+
parts.push(` Body: ${truncated}`);
|
|
186
|
+
}
|
|
187
|
+
if (status >= 400) {
|
|
188
|
+
this.error(parts.join("\n"));
|
|
189
|
+
} else {
|
|
190
|
+
this.log(parts.join("\n"));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
20
195
|
// src/lib/http-client.ts
|
|
196
|
+
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
197
|
+
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
21
198
|
var HttpClient = class {
|
|
22
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Creates a new HttpClient instance.
|
|
201
|
+
* @param config - SDK configuration including baseUrl, timeout, retry settings, and fetch implementation.
|
|
202
|
+
* @param logger - Optional logger instance for request/response debugging.
|
|
203
|
+
*/
|
|
204
|
+
constructor(config, logger) {
|
|
23
205
|
this.userToken = null;
|
|
24
206
|
this.baseUrl = config.baseUrl || "http://localhost:7130";
|
|
25
207
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
@@ -27,12 +209,20 @@ var HttpClient = class {
|
|
|
27
209
|
this.defaultHeaders = {
|
|
28
210
|
...config.headers
|
|
29
211
|
};
|
|
212
|
+
this.logger = logger || new Logger(false);
|
|
213
|
+
this.timeout = config.timeout ?? 3e4;
|
|
214
|
+
this.retryCount = config.retryCount ?? 3;
|
|
215
|
+
this.retryDelay = config.retryDelay ?? 500;
|
|
30
216
|
if (!this.fetch) {
|
|
31
217
|
throw new Error(
|
|
32
218
|
"Fetch is not available. Please provide a fetch implementation in the config."
|
|
33
219
|
);
|
|
34
220
|
}
|
|
35
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Builds a full URL from a path and optional query parameters.
|
|
224
|
+
* Normalizes PostgREST select parameters for proper syntax.
|
|
225
|
+
*/
|
|
36
226
|
buildUrl(path, params) {
|
|
37
227
|
const url = new URL(path, this.baseUrl);
|
|
38
228
|
if (params) {
|
|
@@ -48,9 +238,36 @@ var HttpClient = class {
|
|
|
48
238
|
}
|
|
49
239
|
return url.toString();
|
|
50
240
|
}
|
|
241
|
+
/** Checks if an HTTP status code is eligible for retry (5xx server errors). */
|
|
242
|
+
isRetryableStatus(status) {
|
|
243
|
+
return RETRYABLE_STATUS_CODES.has(status);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Computes the delay before the next retry using exponential backoff with jitter.
|
|
247
|
+
* @param attempt - The current retry attempt number (1-based).
|
|
248
|
+
* @returns Delay in milliseconds.
|
|
249
|
+
*/
|
|
250
|
+
computeRetryDelay(attempt) {
|
|
251
|
+
const base = this.retryDelay * Math.pow(2, attempt - 1);
|
|
252
|
+
const jitter = base * (0.85 + Math.random() * 0.3);
|
|
253
|
+
return Math.round(jitter);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Performs an HTTP request with automatic retry and timeout handling.
|
|
257
|
+
* Retries on network errors and 5xx server errors with exponential backoff.
|
|
258
|
+
* Client errors (4xx) and timeouts are thrown immediately without retry.
|
|
259
|
+
* @param method - HTTP method (GET, POST, PUT, PATCH, DELETE).
|
|
260
|
+
* @param path - API path relative to the base URL.
|
|
261
|
+
* @param options - Optional request configuration including headers, body, and query params.
|
|
262
|
+
* @returns Parsed response data.
|
|
263
|
+
* @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
|
|
264
|
+
*/
|
|
51
265
|
async request(method, path, options = {}) {
|
|
52
|
-
const { params, headers = {}, body, ...fetchOptions } = options;
|
|
266
|
+
const { params, headers = {}, body, signal: callerSignal, ...fetchOptions } = options;
|
|
53
267
|
const url = this.buildUrl(path, params);
|
|
268
|
+
const startTime = Date.now();
|
|
269
|
+
const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
|
|
270
|
+
const maxAttempts = canRetry ? this.retryCount : 0;
|
|
54
271
|
const requestHeaders = {
|
|
55
272
|
...this.defaultHeaders
|
|
56
273
|
};
|
|
@@ -69,62 +286,175 @@ var HttpClient = class {
|
|
|
69
286
|
processedBody = JSON.stringify(body);
|
|
70
287
|
}
|
|
71
288
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return void 0;
|
|
81
|
-
}
|
|
82
|
-
let data;
|
|
83
|
-
const contentType = response.headers.get("content-type");
|
|
84
|
-
if (contentType?.includes("json")) {
|
|
85
|
-
data = await response.json();
|
|
289
|
+
if (headers instanceof Headers) {
|
|
290
|
+
headers.forEach((value, key) => {
|
|
291
|
+
requestHeaders[key] = value;
|
|
292
|
+
});
|
|
293
|
+
} else if (Array.isArray(headers)) {
|
|
294
|
+
headers.forEach(([key, value]) => {
|
|
295
|
+
requestHeaders[key] = value;
|
|
296
|
+
});
|
|
86
297
|
} else {
|
|
87
|
-
|
|
298
|
+
Object.assign(requestHeaders, headers);
|
|
88
299
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
300
|
+
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
301
|
+
let lastError;
|
|
302
|
+
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
303
|
+
if (attempt > 0) {
|
|
304
|
+
const delay = this.computeRetryDelay(attempt);
|
|
305
|
+
this.logger.warn(`Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`);
|
|
306
|
+
if (callerSignal?.aborted) throw callerSignal.reason;
|
|
307
|
+
await new Promise((resolve, reject) => {
|
|
308
|
+
const onAbort = () => {
|
|
309
|
+
clearTimeout(timer2);
|
|
310
|
+
reject(callerSignal.reason);
|
|
311
|
+
};
|
|
312
|
+
const timer2 = setTimeout(() => {
|
|
313
|
+
if (callerSignal) callerSignal.removeEventListener("abort", onAbort);
|
|
314
|
+
resolve();
|
|
315
|
+
}, delay);
|
|
316
|
+
if (callerSignal) {
|
|
317
|
+
callerSignal.addEventListener("abort", onAbort, { once: true });
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
let controller;
|
|
322
|
+
let timer;
|
|
323
|
+
if (this.timeout > 0 || callerSignal) {
|
|
324
|
+
controller = new AbortController();
|
|
325
|
+
if (this.timeout > 0) {
|
|
326
|
+
timer = setTimeout(() => controller.abort(), this.timeout);
|
|
93
327
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
328
|
+
if (callerSignal) {
|
|
329
|
+
if (callerSignal.aborted) {
|
|
330
|
+
controller.abort(callerSignal.reason);
|
|
331
|
+
} else {
|
|
332
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
333
|
+
callerSignal.addEventListener("abort", onCallerAbort, { once: true });
|
|
334
|
+
controller.signal.addEventListener("abort", () => {
|
|
335
|
+
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
336
|
+
}, { once: true });
|
|
98
337
|
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
const response = await this.fetch(url, {
|
|
342
|
+
method,
|
|
343
|
+
headers: requestHeaders,
|
|
344
|
+
body: processedBody,
|
|
345
|
+
...fetchOptions,
|
|
346
|
+
...controller ? { signal: controller.signal } : {}
|
|
99
347
|
});
|
|
100
|
-
|
|
348
|
+
if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {
|
|
349
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
350
|
+
await response.body?.cancel();
|
|
351
|
+
lastError = new InsForgeError(
|
|
352
|
+
`Server error: ${response.status} ${response.statusText}`,
|
|
353
|
+
response.status,
|
|
354
|
+
"SERVER_ERROR"
|
|
355
|
+
);
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (response.status === 204) {
|
|
359
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
360
|
+
return void 0;
|
|
361
|
+
}
|
|
362
|
+
let data;
|
|
363
|
+
const contentType = response.headers.get("content-type");
|
|
364
|
+
try {
|
|
365
|
+
if (contentType?.includes("json")) {
|
|
366
|
+
data = await response.json();
|
|
367
|
+
} else {
|
|
368
|
+
data = await response.text();
|
|
369
|
+
}
|
|
370
|
+
} catch (parseErr) {
|
|
371
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
372
|
+
throw new InsForgeError(
|
|
373
|
+
`Failed to parse response body: ${parseErr?.message || "Unknown error"}`,
|
|
374
|
+
response.status,
|
|
375
|
+
response.ok ? "PARSE_ERROR" : "REQUEST_FAILED"
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
379
|
+
if (!response.ok) {
|
|
380
|
+
this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
|
|
381
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
382
|
+
if (!data.statusCode && !data.status) {
|
|
383
|
+
data.statusCode = response.status;
|
|
384
|
+
}
|
|
385
|
+
const error = InsForgeError.fromApiError(data);
|
|
386
|
+
Object.keys(data).forEach((key) => {
|
|
387
|
+
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
388
|
+
error[key] = data[key];
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
393
|
+
throw new InsForgeError(
|
|
394
|
+
`Request failed: ${response.statusText}`,
|
|
395
|
+
response.status,
|
|
396
|
+
"REQUEST_FAILED"
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
|
|
400
|
+
return data;
|
|
401
|
+
} catch (err) {
|
|
402
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
403
|
+
if (err?.name === "AbortError") {
|
|
404
|
+
if (controller && controller.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
405
|
+
throw new InsForgeError(
|
|
406
|
+
`Request timed out after ${this.timeout}ms`,
|
|
407
|
+
408,
|
|
408
|
+
"REQUEST_TIMEOUT"
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
throw err;
|
|
412
|
+
}
|
|
413
|
+
if (err instanceof InsForgeError) {
|
|
414
|
+
throw err;
|
|
415
|
+
}
|
|
416
|
+
if (attempt < maxAttempts) {
|
|
417
|
+
lastError = err;
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
throw new InsForgeError(
|
|
421
|
+
`Network request failed: ${err?.message || "Unknown error"}`,
|
|
422
|
+
0,
|
|
423
|
+
"NETWORK_ERROR"
|
|
424
|
+
);
|
|
101
425
|
}
|
|
102
|
-
throw new InsForgeError(
|
|
103
|
-
`Request failed: ${response.statusText}`,
|
|
104
|
-
response.status,
|
|
105
|
-
"REQUEST_FAILED"
|
|
106
|
-
);
|
|
107
426
|
}
|
|
108
|
-
|
|
427
|
+
throw lastError || new InsForgeError(
|
|
428
|
+
"Request failed after all retry attempts",
|
|
429
|
+
0,
|
|
430
|
+
"NETWORK_ERROR"
|
|
431
|
+
);
|
|
109
432
|
}
|
|
433
|
+
/** Performs a GET request. */
|
|
110
434
|
get(path, options) {
|
|
111
435
|
return this.request("GET", path, options);
|
|
112
436
|
}
|
|
437
|
+
/** Performs a POST request with an optional JSON body. */
|
|
113
438
|
post(path, body, options) {
|
|
114
439
|
return this.request("POST", path, { ...options, body });
|
|
115
440
|
}
|
|
441
|
+
/** Performs a PUT request with an optional JSON body. */
|
|
116
442
|
put(path, body, options) {
|
|
117
443
|
return this.request("PUT", path, { ...options, body });
|
|
118
444
|
}
|
|
445
|
+
/** Performs a PATCH request with an optional JSON body. */
|
|
119
446
|
patch(path, body, options) {
|
|
120
447
|
return this.request("PATCH", path, { ...options, body });
|
|
121
448
|
}
|
|
449
|
+
/** Performs a DELETE request. */
|
|
122
450
|
delete(path, options) {
|
|
123
451
|
return this.request("DELETE", path, options);
|
|
124
452
|
}
|
|
453
|
+
/** Sets or clears the user authentication token for subsequent requests. */
|
|
125
454
|
setAuthToken(token) {
|
|
126
455
|
this.userToken = token;
|
|
127
456
|
}
|
|
457
|
+
/** Returns the current default headers including the authorization header if set. */
|
|
128
458
|
getHeaders() {
|
|
129
459
|
const headers = { ...this.defaultHeaders };
|
|
130
460
|
const authToken = this.userToken || this.anonKey;
|
|
@@ -279,6 +609,7 @@ function cleanUrlParams(...params) {
|
|
|
279
609
|
}
|
|
280
610
|
|
|
281
611
|
// src/modules/auth/auth.ts
|
|
612
|
+
import { oAuthProvidersSchema } from "@insforge/shared-schemas";
|
|
282
613
|
var Auth = class {
|
|
283
614
|
constructor(http, tokenManager, options = {}) {
|
|
284
615
|
this.http = http;
|
|
@@ -425,18 +756,23 @@ var Auth = class {
|
|
|
425
756
|
async signInWithOAuth(options) {
|
|
426
757
|
try {
|
|
427
758
|
const { provider, redirectTo, skipBrowserRedirect } = options;
|
|
759
|
+
const providerKey = encodeURIComponent(provider.toLowerCase());
|
|
428
760
|
const codeVerifier = generateCodeVerifier();
|
|
429
761
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
430
762
|
storePkceVerifier(codeVerifier);
|
|
431
763
|
const params = { code_challenge: codeChallenge };
|
|
432
764
|
if (redirectTo) params.redirect_uri = redirectTo;
|
|
433
|
-
const
|
|
765
|
+
const isBuiltInProvider = oAuthProvidersSchema.options.includes(
|
|
766
|
+
providerKey
|
|
767
|
+
);
|
|
768
|
+
const oauthPath = isBuiltInProvider ? `/api/auth/oauth/${providerKey}` : `/api/auth/oauth/custom/${providerKey}`;
|
|
769
|
+
const response = await this.http.get(oauthPath, { params });
|
|
434
770
|
if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
|
|
435
771
|
window.location.href = response.authUrl;
|
|
436
772
|
return { data: {}, error: null };
|
|
437
773
|
}
|
|
438
774
|
return {
|
|
439
|
-
data: { url: response.authUrl, provider, codeVerifier },
|
|
775
|
+
data: { url: response.authUrl, provider: providerKey, codeVerifier },
|
|
440
776
|
error: null
|
|
441
777
|
};
|
|
442
778
|
} catch (error) {
|
|
@@ -1739,7 +2075,8 @@ var Emails = class {
|
|
|
1739
2075
|
// src/client.ts
|
|
1740
2076
|
var InsForgeClient = class {
|
|
1741
2077
|
constructor(config = {}) {
|
|
1742
|
-
|
|
2078
|
+
const logger = new Logger(config.debug);
|
|
2079
|
+
this.http = new HttpClient(config, logger);
|
|
1743
2080
|
this.tokenManager = new TokenManager();
|
|
1744
2081
|
if (config.edgeFunctionToken) {
|
|
1745
2082
|
this.http.setAuthToken(config.edgeFunctionToken);
|
|
@@ -1791,6 +2128,7 @@ export {
|
|
|
1791
2128
|
HttpClient,
|
|
1792
2129
|
InsForgeClient,
|
|
1793
2130
|
InsForgeError,
|
|
2131
|
+
Logger,
|
|
1794
2132
|
Realtime,
|
|
1795
2133
|
Storage,
|
|
1796
2134
|
StorageBucket,
|