@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.js
CHANGED
|
@@ -28,6 +28,7 @@ __export(index_exports, {
|
|
|
28
28
|
HttpClient: () => HttpClient,
|
|
29
29
|
InsForgeClient: () => InsForgeClient,
|
|
30
30
|
InsForgeError: () => InsForgeError,
|
|
31
|
+
Logger: () => Logger,
|
|
31
32
|
Realtime: () => Realtime,
|
|
32
33
|
Storage: () => Storage,
|
|
33
34
|
StorageBucket: () => StorageBucket,
|
|
@@ -56,9 +57,191 @@ var InsForgeError = class _InsForgeError extends Error {
|
|
|
56
57
|
}
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
// src/lib/logger.ts
|
|
61
|
+
var SENSITIVE_HEADERS = ["authorization", "x-api-key", "cookie", "set-cookie"];
|
|
62
|
+
var SENSITIVE_BODY_KEYS = [
|
|
63
|
+
"password",
|
|
64
|
+
"token",
|
|
65
|
+
"accesstoken",
|
|
66
|
+
"refreshtoken",
|
|
67
|
+
"authorization",
|
|
68
|
+
"secret",
|
|
69
|
+
"apikey",
|
|
70
|
+
"api_key",
|
|
71
|
+
"email",
|
|
72
|
+
"ssn",
|
|
73
|
+
"creditcard",
|
|
74
|
+
"credit_card"
|
|
75
|
+
];
|
|
76
|
+
function redactHeaders(headers) {
|
|
77
|
+
const redacted = {};
|
|
78
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
79
|
+
if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {
|
|
80
|
+
redacted[key] = "***REDACTED***";
|
|
81
|
+
} else {
|
|
82
|
+
redacted[key] = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return redacted;
|
|
86
|
+
}
|
|
87
|
+
function sanitizeBody(body) {
|
|
88
|
+
if (body === null || body === void 0) return body;
|
|
89
|
+
if (typeof body === "string") {
|
|
90
|
+
try {
|
|
91
|
+
const parsed = JSON.parse(body);
|
|
92
|
+
return sanitizeBody(parsed);
|
|
93
|
+
} catch {
|
|
94
|
+
return body;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (Array.isArray(body)) return body.map(sanitizeBody);
|
|
98
|
+
if (typeof body === "object") {
|
|
99
|
+
const sanitized = {};
|
|
100
|
+
for (const [key, value] of Object.entries(body)) {
|
|
101
|
+
if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ""))) {
|
|
102
|
+
sanitized[key] = "***REDACTED***";
|
|
103
|
+
} else {
|
|
104
|
+
sanitized[key] = sanitizeBody(value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return sanitized;
|
|
108
|
+
}
|
|
109
|
+
return body;
|
|
110
|
+
}
|
|
111
|
+
function formatBody(body) {
|
|
112
|
+
if (body === void 0 || body === null) return "";
|
|
113
|
+
if (typeof body === "string") {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
116
|
+
} catch {
|
|
117
|
+
return body;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
121
|
+
return "[FormData]";
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
return JSON.stringify(body, null, 2);
|
|
125
|
+
} catch {
|
|
126
|
+
return "[Unserializable body]";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
var Logger = class {
|
|
130
|
+
/**
|
|
131
|
+
* Creates a new Logger instance.
|
|
132
|
+
* @param debug - Set to true to enable console logging, or pass a custom log function
|
|
133
|
+
*/
|
|
134
|
+
constructor(debug) {
|
|
135
|
+
if (typeof debug === "function") {
|
|
136
|
+
this.enabled = true;
|
|
137
|
+
this.customLog = debug;
|
|
138
|
+
} else {
|
|
139
|
+
this.enabled = !!debug;
|
|
140
|
+
this.customLog = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Logs a debug message at the info level.
|
|
145
|
+
* @param message - The message to log
|
|
146
|
+
* @param args - Additional arguments to pass to the log function
|
|
147
|
+
*/
|
|
148
|
+
log(message, ...args) {
|
|
149
|
+
if (!this.enabled) return;
|
|
150
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
151
|
+
if (this.customLog) {
|
|
152
|
+
this.customLog(formatted, ...args);
|
|
153
|
+
} else {
|
|
154
|
+
console.log(formatted, ...args);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Logs a debug message at the warning level.
|
|
159
|
+
* @param message - The message to log
|
|
160
|
+
* @param args - Additional arguments to pass to the log function
|
|
161
|
+
*/
|
|
162
|
+
warn(message, ...args) {
|
|
163
|
+
if (!this.enabled) return;
|
|
164
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
165
|
+
if (this.customLog) {
|
|
166
|
+
this.customLog(formatted, ...args);
|
|
167
|
+
} else {
|
|
168
|
+
console.warn(formatted, ...args);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Logs a debug message at the error level.
|
|
173
|
+
* @param message - The message to log
|
|
174
|
+
* @param args - Additional arguments to pass to the log function
|
|
175
|
+
*/
|
|
176
|
+
error(message, ...args) {
|
|
177
|
+
if (!this.enabled) return;
|
|
178
|
+
const formatted = `[InsForge Debug] ${message}`;
|
|
179
|
+
if (this.customLog) {
|
|
180
|
+
this.customLog(formatted, ...args);
|
|
181
|
+
} else {
|
|
182
|
+
console.error(formatted, ...args);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Logs an outgoing HTTP request with method, URL, headers, and body.
|
|
187
|
+
* Sensitive headers and body fields are automatically redacted.
|
|
188
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
189
|
+
* @param url - The full request URL
|
|
190
|
+
* @param headers - Request headers (sensitive values will be redacted)
|
|
191
|
+
* @param body - Request body (sensitive fields will be masked)
|
|
192
|
+
*/
|
|
193
|
+
logRequest(method, url, headers, body) {
|
|
194
|
+
if (!this.enabled) return;
|
|
195
|
+
const parts = [
|
|
196
|
+
`\u2192 ${method} ${url}`
|
|
197
|
+
];
|
|
198
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
199
|
+
parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);
|
|
200
|
+
}
|
|
201
|
+
const formattedBody = formatBody(sanitizeBody(body));
|
|
202
|
+
if (formattedBody) {
|
|
203
|
+
const truncated = formattedBody.length > 1e3 ? formattedBody.slice(0, 1e3) + "... [truncated]" : formattedBody;
|
|
204
|
+
parts.push(` Body: ${truncated}`);
|
|
205
|
+
}
|
|
206
|
+
this.log(parts.join("\n"));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Logs an incoming HTTP response with method, URL, status, duration, and body.
|
|
210
|
+
* Error responses (4xx/5xx) are logged at the error level.
|
|
211
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
212
|
+
* @param url - The full request URL
|
|
213
|
+
* @param status - HTTP response status code
|
|
214
|
+
* @param durationMs - Request duration in milliseconds
|
|
215
|
+
* @param body - Response body (sensitive fields will be masked, large bodies truncated)
|
|
216
|
+
*/
|
|
217
|
+
logResponse(method, url, status, durationMs, body) {
|
|
218
|
+
if (!this.enabled) return;
|
|
219
|
+
const parts = [
|
|
220
|
+
`\u2190 ${method} ${url} ${status} (${durationMs}ms)`
|
|
221
|
+
];
|
|
222
|
+
const formattedBody = formatBody(sanitizeBody(body));
|
|
223
|
+
if (formattedBody) {
|
|
224
|
+
const truncated = formattedBody.length > 1e3 ? formattedBody.slice(0, 1e3) + "... [truncated]" : formattedBody;
|
|
225
|
+
parts.push(` Body: ${truncated}`);
|
|
226
|
+
}
|
|
227
|
+
if (status >= 400) {
|
|
228
|
+
this.error(parts.join("\n"));
|
|
229
|
+
} else {
|
|
230
|
+
this.log(parts.join("\n"));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
59
235
|
// src/lib/http-client.ts
|
|
236
|
+
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
237
|
+
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
60
238
|
var HttpClient = class {
|
|
61
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Creates a new HttpClient instance.
|
|
241
|
+
* @param config - SDK configuration including baseUrl, timeout, retry settings, and fetch implementation.
|
|
242
|
+
* @param logger - Optional logger instance for request/response debugging.
|
|
243
|
+
*/
|
|
244
|
+
constructor(config, logger) {
|
|
62
245
|
this.userToken = null;
|
|
63
246
|
this.baseUrl = config.baseUrl || "http://localhost:7130";
|
|
64
247
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
@@ -66,12 +249,20 @@ var HttpClient = class {
|
|
|
66
249
|
this.defaultHeaders = {
|
|
67
250
|
...config.headers
|
|
68
251
|
};
|
|
252
|
+
this.logger = logger || new Logger(false);
|
|
253
|
+
this.timeout = config.timeout ?? 3e4;
|
|
254
|
+
this.retryCount = config.retryCount ?? 3;
|
|
255
|
+
this.retryDelay = config.retryDelay ?? 500;
|
|
69
256
|
if (!this.fetch) {
|
|
70
257
|
throw new Error(
|
|
71
258
|
"Fetch is not available. Please provide a fetch implementation in the config."
|
|
72
259
|
);
|
|
73
260
|
}
|
|
74
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Builds a full URL from a path and optional query parameters.
|
|
264
|
+
* Normalizes PostgREST select parameters for proper syntax.
|
|
265
|
+
*/
|
|
75
266
|
buildUrl(path, params) {
|
|
76
267
|
const url = new URL(path, this.baseUrl);
|
|
77
268
|
if (params) {
|
|
@@ -87,9 +278,36 @@ var HttpClient = class {
|
|
|
87
278
|
}
|
|
88
279
|
return url.toString();
|
|
89
280
|
}
|
|
281
|
+
/** Checks if an HTTP status code is eligible for retry (5xx server errors). */
|
|
282
|
+
isRetryableStatus(status) {
|
|
283
|
+
return RETRYABLE_STATUS_CODES.has(status);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Computes the delay before the next retry using exponential backoff with jitter.
|
|
287
|
+
* @param attempt - The current retry attempt number (1-based).
|
|
288
|
+
* @returns Delay in milliseconds.
|
|
289
|
+
*/
|
|
290
|
+
computeRetryDelay(attempt) {
|
|
291
|
+
const base = this.retryDelay * Math.pow(2, attempt - 1);
|
|
292
|
+
const jitter = base * (0.85 + Math.random() * 0.3);
|
|
293
|
+
return Math.round(jitter);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Performs an HTTP request with automatic retry and timeout handling.
|
|
297
|
+
* Retries on network errors and 5xx server errors with exponential backoff.
|
|
298
|
+
* Client errors (4xx) and timeouts are thrown immediately without retry.
|
|
299
|
+
* @param method - HTTP method (GET, POST, PUT, PATCH, DELETE).
|
|
300
|
+
* @param path - API path relative to the base URL.
|
|
301
|
+
* @param options - Optional request configuration including headers, body, and query params.
|
|
302
|
+
* @returns Parsed response data.
|
|
303
|
+
* @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
|
|
304
|
+
*/
|
|
90
305
|
async request(method, path, options = {}) {
|
|
91
|
-
const { params, headers = {}, body, ...fetchOptions } = options;
|
|
306
|
+
const { params, headers = {}, body, signal: callerSignal, ...fetchOptions } = options;
|
|
92
307
|
const url = this.buildUrl(path, params);
|
|
308
|
+
const startTime = Date.now();
|
|
309
|
+
const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
|
|
310
|
+
const maxAttempts = canRetry ? this.retryCount : 0;
|
|
93
311
|
const requestHeaders = {
|
|
94
312
|
...this.defaultHeaders
|
|
95
313
|
};
|
|
@@ -108,62 +326,175 @@ var HttpClient = class {
|
|
|
108
326
|
processedBody = JSON.stringify(body);
|
|
109
327
|
}
|
|
110
328
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return void 0;
|
|
120
|
-
}
|
|
121
|
-
let data;
|
|
122
|
-
const contentType = response.headers.get("content-type");
|
|
123
|
-
if (contentType?.includes("json")) {
|
|
124
|
-
data = await response.json();
|
|
329
|
+
if (headers instanceof Headers) {
|
|
330
|
+
headers.forEach((value, key) => {
|
|
331
|
+
requestHeaders[key] = value;
|
|
332
|
+
});
|
|
333
|
+
} else if (Array.isArray(headers)) {
|
|
334
|
+
headers.forEach(([key, value]) => {
|
|
335
|
+
requestHeaders[key] = value;
|
|
336
|
+
});
|
|
125
337
|
} else {
|
|
126
|
-
|
|
338
|
+
Object.assign(requestHeaders, headers);
|
|
127
339
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
340
|
+
this.logger.logRequest(method, url, requestHeaders, processedBody);
|
|
341
|
+
let lastError;
|
|
342
|
+
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
343
|
+
if (attempt > 0) {
|
|
344
|
+
const delay = this.computeRetryDelay(attempt);
|
|
345
|
+
this.logger.warn(`Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`);
|
|
346
|
+
if (callerSignal?.aborted) throw callerSignal.reason;
|
|
347
|
+
await new Promise((resolve, reject) => {
|
|
348
|
+
const onAbort = () => {
|
|
349
|
+
clearTimeout(timer2);
|
|
350
|
+
reject(callerSignal.reason);
|
|
351
|
+
};
|
|
352
|
+
const timer2 = setTimeout(() => {
|
|
353
|
+
if (callerSignal) callerSignal.removeEventListener("abort", onAbort);
|
|
354
|
+
resolve();
|
|
355
|
+
}, delay);
|
|
356
|
+
if (callerSignal) {
|
|
357
|
+
callerSignal.addEventListener("abort", onAbort, { once: true });
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
let controller;
|
|
362
|
+
let timer;
|
|
363
|
+
if (this.timeout > 0 || callerSignal) {
|
|
364
|
+
controller = new AbortController();
|
|
365
|
+
if (this.timeout > 0) {
|
|
366
|
+
timer = setTimeout(() => controller.abort(), this.timeout);
|
|
132
367
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
368
|
+
if (callerSignal) {
|
|
369
|
+
if (callerSignal.aborted) {
|
|
370
|
+
controller.abort(callerSignal.reason);
|
|
371
|
+
} else {
|
|
372
|
+
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
373
|
+
callerSignal.addEventListener("abort", onCallerAbort, { once: true });
|
|
374
|
+
controller.signal.addEventListener("abort", () => {
|
|
375
|
+
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
376
|
+
}, { once: true });
|
|
137
377
|
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
const response = await this.fetch(url, {
|
|
382
|
+
method,
|
|
383
|
+
headers: requestHeaders,
|
|
384
|
+
body: processedBody,
|
|
385
|
+
...fetchOptions,
|
|
386
|
+
...controller ? { signal: controller.signal } : {}
|
|
138
387
|
});
|
|
139
|
-
|
|
388
|
+
if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {
|
|
389
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
390
|
+
await response.body?.cancel();
|
|
391
|
+
lastError = new InsForgeError(
|
|
392
|
+
`Server error: ${response.status} ${response.statusText}`,
|
|
393
|
+
response.status,
|
|
394
|
+
"SERVER_ERROR"
|
|
395
|
+
);
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (response.status === 204) {
|
|
399
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
let data;
|
|
403
|
+
const contentType = response.headers.get("content-type");
|
|
404
|
+
try {
|
|
405
|
+
if (contentType?.includes("json")) {
|
|
406
|
+
data = await response.json();
|
|
407
|
+
} else {
|
|
408
|
+
data = await response.text();
|
|
409
|
+
}
|
|
410
|
+
} catch (parseErr) {
|
|
411
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
412
|
+
throw new InsForgeError(
|
|
413
|
+
`Failed to parse response body: ${parseErr?.message || "Unknown error"}`,
|
|
414
|
+
response.status,
|
|
415
|
+
response.ok ? "PARSE_ERROR" : "REQUEST_FAILED"
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
419
|
+
if (!response.ok) {
|
|
420
|
+
this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
|
|
421
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
422
|
+
if (!data.statusCode && !data.status) {
|
|
423
|
+
data.statusCode = response.status;
|
|
424
|
+
}
|
|
425
|
+
const error = InsForgeError.fromApiError(data);
|
|
426
|
+
Object.keys(data).forEach((key) => {
|
|
427
|
+
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
428
|
+
error[key] = data[key];
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
throw error;
|
|
432
|
+
}
|
|
433
|
+
throw new InsForgeError(
|
|
434
|
+
`Request failed: ${response.statusText}`,
|
|
435
|
+
response.status,
|
|
436
|
+
"REQUEST_FAILED"
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
|
|
440
|
+
return data;
|
|
441
|
+
} catch (err) {
|
|
442
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
443
|
+
if (err?.name === "AbortError") {
|
|
444
|
+
if (controller && controller.signal.aborted && this.timeout > 0 && !callerSignal?.aborted) {
|
|
445
|
+
throw new InsForgeError(
|
|
446
|
+
`Request timed out after ${this.timeout}ms`,
|
|
447
|
+
408,
|
|
448
|
+
"REQUEST_TIMEOUT"
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
throw err;
|
|
452
|
+
}
|
|
453
|
+
if (err instanceof InsForgeError) {
|
|
454
|
+
throw err;
|
|
455
|
+
}
|
|
456
|
+
if (attempt < maxAttempts) {
|
|
457
|
+
lastError = err;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
throw new InsForgeError(
|
|
461
|
+
`Network request failed: ${err?.message || "Unknown error"}`,
|
|
462
|
+
0,
|
|
463
|
+
"NETWORK_ERROR"
|
|
464
|
+
);
|
|
140
465
|
}
|
|
141
|
-
throw new InsForgeError(
|
|
142
|
-
`Request failed: ${response.statusText}`,
|
|
143
|
-
response.status,
|
|
144
|
-
"REQUEST_FAILED"
|
|
145
|
-
);
|
|
146
466
|
}
|
|
147
|
-
|
|
467
|
+
throw lastError || new InsForgeError(
|
|
468
|
+
"Request failed after all retry attempts",
|
|
469
|
+
0,
|
|
470
|
+
"NETWORK_ERROR"
|
|
471
|
+
);
|
|
148
472
|
}
|
|
473
|
+
/** Performs a GET request. */
|
|
149
474
|
get(path, options) {
|
|
150
475
|
return this.request("GET", path, options);
|
|
151
476
|
}
|
|
477
|
+
/** Performs a POST request with an optional JSON body. */
|
|
152
478
|
post(path, body, options) {
|
|
153
479
|
return this.request("POST", path, { ...options, body });
|
|
154
480
|
}
|
|
481
|
+
/** Performs a PUT request with an optional JSON body. */
|
|
155
482
|
put(path, body, options) {
|
|
156
483
|
return this.request("PUT", path, { ...options, body });
|
|
157
484
|
}
|
|
485
|
+
/** Performs a PATCH request with an optional JSON body. */
|
|
158
486
|
patch(path, body, options) {
|
|
159
487
|
return this.request("PATCH", path, { ...options, body });
|
|
160
488
|
}
|
|
489
|
+
/** Performs a DELETE request. */
|
|
161
490
|
delete(path, options) {
|
|
162
491
|
return this.request("DELETE", path, options);
|
|
163
492
|
}
|
|
493
|
+
/** Sets or clears the user authentication token for subsequent requests. */
|
|
164
494
|
setAuthToken(token) {
|
|
165
495
|
this.userToken = token;
|
|
166
496
|
}
|
|
497
|
+
/** Returns the current default headers including the authorization header if set. */
|
|
167
498
|
getHeaders() {
|
|
168
499
|
const headers = { ...this.defaultHeaders };
|
|
169
500
|
const authToken = this.userToken || this.anonKey;
|
|
@@ -318,6 +649,7 @@ function cleanUrlParams(...params) {
|
|
|
318
649
|
}
|
|
319
650
|
|
|
320
651
|
// src/modules/auth/auth.ts
|
|
652
|
+
var import_shared_schemas = require("@insforge/shared-schemas");
|
|
321
653
|
var Auth = class {
|
|
322
654
|
constructor(http, tokenManager, options = {}) {
|
|
323
655
|
this.http = http;
|
|
@@ -464,18 +796,23 @@ var Auth = class {
|
|
|
464
796
|
async signInWithOAuth(options) {
|
|
465
797
|
try {
|
|
466
798
|
const { provider, redirectTo, skipBrowserRedirect } = options;
|
|
799
|
+
const providerKey = encodeURIComponent(provider.toLowerCase());
|
|
467
800
|
const codeVerifier = generateCodeVerifier();
|
|
468
801
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
469
802
|
storePkceVerifier(codeVerifier);
|
|
470
803
|
const params = { code_challenge: codeChallenge };
|
|
471
804
|
if (redirectTo) params.redirect_uri = redirectTo;
|
|
472
|
-
const
|
|
805
|
+
const isBuiltInProvider = import_shared_schemas.oAuthProvidersSchema.options.includes(
|
|
806
|
+
providerKey
|
|
807
|
+
);
|
|
808
|
+
const oauthPath = isBuiltInProvider ? `/api/auth/oauth/${providerKey}` : `/api/auth/oauth/custom/${providerKey}`;
|
|
809
|
+
const response = await this.http.get(oauthPath, { params });
|
|
473
810
|
if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
|
|
474
811
|
window.location.href = response.authUrl;
|
|
475
812
|
return { data: {}, error: null };
|
|
476
813
|
}
|
|
477
814
|
return {
|
|
478
|
-
data: { url: response.authUrl, provider, codeVerifier },
|
|
815
|
+
data: { url: response.authUrl, provider: providerKey, codeVerifier },
|
|
479
816
|
error: null
|
|
480
817
|
};
|
|
481
818
|
} catch (error) {
|
|
@@ -1778,7 +2115,8 @@ var Emails = class {
|
|
|
1778
2115
|
// src/client.ts
|
|
1779
2116
|
var InsForgeClient = class {
|
|
1780
2117
|
constructor(config = {}) {
|
|
1781
|
-
|
|
2118
|
+
const logger = new Logger(config.debug);
|
|
2119
|
+
this.http = new HttpClient(config, logger);
|
|
1782
2120
|
this.tokenManager = new TokenManager();
|
|
1783
2121
|
if (config.edgeFunctionToken) {
|
|
1784
2122
|
this.http.setAuthToken(config.edgeFunctionToken);
|
|
@@ -1831,6 +2169,7 @@ var index_default = InsForgeClient;
|
|
|
1831
2169
|
HttpClient,
|
|
1832
2170
|
InsForgeClient,
|
|
1833
2171
|
InsForgeError,
|
|
2172
|
+
Logger,
|
|
1834
2173
|
Realtime,
|
|
1835
2174
|
Storage,
|
|
1836
2175
|
StorageBucket,
|