@basictech/react 0.7.0-beta.2 → 0.7.0-beta.3
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/AUTH_IMPLEMENTATION_GUIDE.md +2009 -0
- package/changelog.md +6 -0
- package/dist/index.d.mts +1 -106
- package/dist/index.d.ts +1 -106
- package/dist/index.js +17 -381
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -380
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/AuthContext.tsx +74 -12
- package/src/index.ts +5 -1
- package/src/utils/storage.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
BasicDBSDK: () => BasicDBSDK,
|
|
24
23
|
BasicProvider: () => BasicProvider,
|
|
25
24
|
useBasic: () => useBasic,
|
|
26
25
|
useQuery: () => import_dexie_react_hooks.useLiveQuery
|
|
@@ -279,363 +278,8 @@ var BasicSync = class extends import_dexie2.Dexie {
|
|
|
279
278
|
}
|
|
280
279
|
};
|
|
281
280
|
|
|
282
|
-
// src/db_ts.ts
|
|
283
|
-
var DBError = class extends Error {
|
|
284
|
-
constructor(message, status, response, originalError) {
|
|
285
|
-
super(message);
|
|
286
|
-
this.status = status;
|
|
287
|
-
this.response = response;
|
|
288
|
-
this.originalError = originalError;
|
|
289
|
-
this.name = "DBError";
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
var QueryBuilder = class {
|
|
293
|
-
constructor(tableClient, tableSchema) {
|
|
294
|
-
this.tableClient = tableClient;
|
|
295
|
-
this.tableSchema = tableSchema;
|
|
296
|
-
}
|
|
297
|
-
params = {};
|
|
298
|
-
// Reserved fields that are always allowed
|
|
299
|
-
reservedFields = ["created_at", "updated_at", "id"];
|
|
300
|
-
// Validate field existence in schema
|
|
301
|
-
validateField(field) {
|
|
302
|
-
if (this.tableSchema && !this.reservedFields.includes(field)) {
|
|
303
|
-
if (!this.tableSchema.fields || !(field in this.tableSchema.fields)) {
|
|
304
|
-
throw new Error(`Invalid field: "${field}". Field does not exist in table schema.`);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
// Validate operator based on field type
|
|
309
|
-
validateOperator(field, operator, value) {
|
|
310
|
-
if (!this.tableSchema || this.reservedFields.includes(field)) {
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
const fieldInfo = this.tableSchema.fields[field];
|
|
314
|
-
if (!fieldInfo)
|
|
315
|
-
return;
|
|
316
|
-
switch (operator) {
|
|
317
|
-
case "gt":
|
|
318
|
-
case "gte":
|
|
319
|
-
case "lt":
|
|
320
|
-
case "lte":
|
|
321
|
-
if (fieldInfo.type !== "number" && fieldInfo.type !== "string") {
|
|
322
|
-
throw new Error(`Operator "${operator}" can only be used with number or string fields. Field "${field}" is type "${fieldInfo.type}".`);
|
|
323
|
-
}
|
|
324
|
-
break;
|
|
325
|
-
case "like":
|
|
326
|
-
case "ilike":
|
|
327
|
-
if (fieldInfo.type !== "string") {
|
|
328
|
-
throw new Error(`Operator "${operator}" can only be used with string fields. Field "${field}" is type "${fieldInfo.type}".`);
|
|
329
|
-
}
|
|
330
|
-
if (typeof value !== "string") {
|
|
331
|
-
throw new Error(`Operator "${operator}" requires a string value. Received: ${typeof value}`);
|
|
332
|
-
}
|
|
333
|
-
break;
|
|
334
|
-
case "in":
|
|
335
|
-
if (!Array.isArray(value)) {
|
|
336
|
-
throw new Error(`Operator "in" requires an array value. Received: ${typeof value}`);
|
|
337
|
-
}
|
|
338
|
-
break;
|
|
339
|
-
case "is":
|
|
340
|
-
if (value !== null && typeof value !== "boolean") {
|
|
341
|
-
throw new Error(`Operator "is" requires null or boolean. Received: ${typeof value}`);
|
|
342
|
-
}
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Add ordering to query with schema validation
|
|
347
|
-
order(field, direction = "asc") {
|
|
348
|
-
this.validateField(field);
|
|
349
|
-
this.params.order = `${field}.${direction}`;
|
|
350
|
-
return this;
|
|
351
|
-
}
|
|
352
|
-
// Add filtering to query
|
|
353
|
-
filter(conditions) {
|
|
354
|
-
if (!this.params.filters) {
|
|
355
|
-
this.params.filters = {};
|
|
356
|
-
}
|
|
357
|
-
for (const [field, condition] of Object.entries(conditions)) {
|
|
358
|
-
this.validateField(field);
|
|
359
|
-
if (condition === null || typeof condition !== "object") {
|
|
360
|
-
this.params.filters[field] = condition;
|
|
361
|
-
} else {
|
|
362
|
-
this.params.filters[field] = condition;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return this;
|
|
366
|
-
}
|
|
367
|
-
// Add limit to query
|
|
368
|
-
limit(count) {
|
|
369
|
-
this.params.limit = count;
|
|
370
|
-
return this;
|
|
371
|
-
}
|
|
372
|
-
// Add offset to query for pagination
|
|
373
|
-
offset(count) {
|
|
374
|
-
this.params.offset = count;
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
// Auto-execute when awaited
|
|
378
|
-
then(onfulfilled, onrejected) {
|
|
379
|
-
return this.tableClient.executeQuery(this.params).then(onfulfilled, onrejected);
|
|
380
|
-
}
|
|
381
|
-
// Auto-execute when awaited with catch
|
|
382
|
-
catch(onrejected) {
|
|
383
|
-
return this.tableClient.executeQuery(this.params).catch(onrejected);
|
|
384
|
-
}
|
|
385
|
-
// Auto-execute when awaited with finally
|
|
386
|
-
finally(onfinally) {
|
|
387
|
-
return this.tableClient.executeQuery(this.params).finally(onfinally);
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
var TableClient = class {
|
|
391
|
-
constructor(baseUrl, projectId, token, table, getToken, schema) {
|
|
392
|
-
this.baseUrl = baseUrl;
|
|
393
|
-
this.projectId = projectId;
|
|
394
|
-
this.token = token;
|
|
395
|
-
this.table = table;
|
|
396
|
-
this.getToken = getToken;
|
|
397
|
-
this.schema = schema;
|
|
398
|
-
if (schema && schema.tables && schema.tables[table]) {
|
|
399
|
-
this.tableSchema = schema.tables[table];
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
tableSchema;
|
|
403
|
-
async headers() {
|
|
404
|
-
const token = await this.getToken();
|
|
405
|
-
return {
|
|
406
|
-
Authorization: `Bearer ${token}`,
|
|
407
|
-
"Content-Type": "application/json"
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
async handleRequest(request) {
|
|
411
|
-
try {
|
|
412
|
-
const res = await request;
|
|
413
|
-
if (!res.ok) {
|
|
414
|
-
let errorMessage = `Request failed with status ${res.status}`;
|
|
415
|
-
let errorData;
|
|
416
|
-
try {
|
|
417
|
-
const json2 = await res.json();
|
|
418
|
-
errorData = json2;
|
|
419
|
-
if (json2.error || json2.message) {
|
|
420
|
-
const errorDetails = typeof json2.error === "object" ? JSON.stringify(json2.error) : json2.error;
|
|
421
|
-
const messageDetails = typeof json2.message === "object" ? JSON.stringify(json2.message) : json2.message;
|
|
422
|
-
errorMessage = `${res.status} ${res.statusText}: ${messageDetails || errorDetails || "Unknown error"}`;
|
|
423
|
-
}
|
|
424
|
-
} catch (e) {
|
|
425
|
-
console.log("Failed to parse error response:", e);
|
|
426
|
-
errorMessage = `${res.status} ${res.statusText}`;
|
|
427
|
-
}
|
|
428
|
-
throw new DBError(
|
|
429
|
-
errorMessage,
|
|
430
|
-
res.status,
|
|
431
|
-
errorData
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
const json = await res.json();
|
|
435
|
-
return json.data;
|
|
436
|
-
} catch (error) {
|
|
437
|
-
console.log("Caught error:", error);
|
|
438
|
-
if (error instanceof Error) {
|
|
439
|
-
console.log("Error type:", error.constructor.name);
|
|
440
|
-
console.log("Error stack:", error.stack);
|
|
441
|
-
}
|
|
442
|
-
if (error instanceof DBError) {
|
|
443
|
-
throw error;
|
|
444
|
-
}
|
|
445
|
-
if (error instanceof TypeError && error.message === "Network request failed") {
|
|
446
|
-
throw new DBError(
|
|
447
|
-
"Network request failed. Please check your internet connection and try again.",
|
|
448
|
-
void 0,
|
|
449
|
-
void 0,
|
|
450
|
-
error
|
|
451
|
-
);
|
|
452
|
-
}
|
|
453
|
-
throw new DBError(
|
|
454
|
-
`Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
455
|
-
void 0,
|
|
456
|
-
void 0,
|
|
457
|
-
error instanceof Error ? error : void 0
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
// Build query string from query options
|
|
462
|
-
buildQueryParams(query) {
|
|
463
|
-
if (!query)
|
|
464
|
-
return "";
|
|
465
|
-
const params = [];
|
|
466
|
-
if (query.id) {
|
|
467
|
-
params.push(`id=${query.id}`);
|
|
468
|
-
}
|
|
469
|
-
if (query.filters) {
|
|
470
|
-
for (const [field, condition] of Object.entries(query.filters)) {
|
|
471
|
-
this.addFilterParam(params, field, condition);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
if (query.order) {
|
|
475
|
-
params.push(`order=${query.order}`);
|
|
476
|
-
}
|
|
477
|
-
if (query.limit !== void 0 && query.limit >= 0) {
|
|
478
|
-
params.push(`limit=${query.limit}`);
|
|
479
|
-
}
|
|
480
|
-
if (query.offset !== void 0 && query.offset >= 0) {
|
|
481
|
-
params.push(`offset=${query.offset}`);
|
|
482
|
-
}
|
|
483
|
-
return params.length > 0 ? `?${params.join("&")}` : "";
|
|
484
|
-
}
|
|
485
|
-
// Helper method to build filter parameters
|
|
486
|
-
addFilterParam(params, field, condition, negate = false) {
|
|
487
|
-
if (condition === null || typeof condition !== "object") {
|
|
488
|
-
if (condition === null) {
|
|
489
|
-
params.push(`${field}=${negate ? "not." : ""}is.null`);
|
|
490
|
-
} else if (typeof condition === "boolean") {
|
|
491
|
-
params.push(`${field}=${negate ? "not." : ""}is.${condition}`);
|
|
492
|
-
} else if (typeof condition === "number") {
|
|
493
|
-
params.push(`${field}=${negate ? "not." : ""}eq.${condition}`);
|
|
494
|
-
} else {
|
|
495
|
-
params.push(`${field}=${negate ? "not." : ""}eq.${encodeURIComponent(String(condition))}`);
|
|
496
|
-
}
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
const operatorObj = condition;
|
|
500
|
-
if (operatorObj.not) {
|
|
501
|
-
this.addFilterParam(params, field, operatorObj.not, true);
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
for (const [op, value] of Object.entries(operatorObj)) {
|
|
505
|
-
if (op === "not")
|
|
506
|
-
continue;
|
|
507
|
-
const operator = op;
|
|
508
|
-
if (value === null) {
|
|
509
|
-
params.push(`${field}=${negate ? "not." : ""}is.null`);
|
|
510
|
-
} else if (operator === "in" && Array.isArray(value)) {
|
|
511
|
-
params.push(`${field}=${negate ? "not." : ""}in.${value.join(",")}`);
|
|
512
|
-
} else if (operator === "is") {
|
|
513
|
-
if (typeof value === "boolean") {
|
|
514
|
-
params.push(`${field}=${negate ? "not." : ""}is.${value}`);
|
|
515
|
-
} else {
|
|
516
|
-
params.push(`${field}=${negate ? "not." : ""}is.null`);
|
|
517
|
-
}
|
|
518
|
-
} else {
|
|
519
|
-
const paramValue = typeof value === "string" ? encodeURIComponent(value) : String(value);
|
|
520
|
-
params.push(`${field}=${negate ? "not." : ""}${operator}.${paramValue}`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
// Internal method to execute a query with options
|
|
525
|
-
async executeQuery(options) {
|
|
526
|
-
const params = this.buildQueryParams(options);
|
|
527
|
-
const headers = await this.headers();
|
|
528
|
-
return this.handleRequest(
|
|
529
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}${params}`, {
|
|
530
|
-
headers
|
|
531
|
-
})
|
|
532
|
-
);
|
|
533
|
-
}
|
|
534
|
-
// Public method to start building a query
|
|
535
|
-
getAll() {
|
|
536
|
-
return new QueryBuilder(this, this.tableSchema);
|
|
537
|
-
}
|
|
538
|
-
// Get a specific item by ID
|
|
539
|
-
async get(id) {
|
|
540
|
-
const headers = await this.headers();
|
|
541
|
-
return this.handleRequest(
|
|
542
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
|
|
543
|
-
headers
|
|
544
|
-
})
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
async create(value) {
|
|
548
|
-
const headers = await this.headers();
|
|
549
|
-
return this.handleRequest(
|
|
550
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}`, {
|
|
551
|
-
method: "POST",
|
|
552
|
-
headers,
|
|
553
|
-
body: JSON.stringify({ value })
|
|
554
|
-
})
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
async update(id, value) {
|
|
558
|
-
const headers = await this.headers();
|
|
559
|
-
return this.handleRequest(
|
|
560
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
|
|
561
|
-
method: "PATCH",
|
|
562
|
-
headers,
|
|
563
|
-
body: JSON.stringify({ value })
|
|
564
|
-
})
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
async replace(id, value) {
|
|
568
|
-
const headers = await this.headers();
|
|
569
|
-
return this.handleRequest(
|
|
570
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
|
|
571
|
-
method: "PUT",
|
|
572
|
-
headers,
|
|
573
|
-
body: JSON.stringify({ value })
|
|
574
|
-
})
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
async delete(id) {
|
|
578
|
-
const token = await this.getToken();
|
|
579
|
-
const headers = {
|
|
580
|
-
Authorization: `Bearer ${token}`
|
|
581
|
-
};
|
|
582
|
-
return this.handleRequest(
|
|
583
|
-
fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
|
|
584
|
-
method: "DELETE",
|
|
585
|
-
headers
|
|
586
|
-
})
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
var BasicDBSDK = class {
|
|
591
|
-
projectId;
|
|
592
|
-
getToken;
|
|
593
|
-
baseUrl;
|
|
594
|
-
schema;
|
|
595
|
-
tableNames;
|
|
596
|
-
constructor(config) {
|
|
597
|
-
this.projectId = config.project_id;
|
|
598
|
-
if (config.getToken) {
|
|
599
|
-
this.getToken = config.getToken;
|
|
600
|
-
} else if (config.token) {
|
|
601
|
-
this.getToken = async () => config.token;
|
|
602
|
-
} else {
|
|
603
|
-
throw new Error("Either token or getToken must be provided");
|
|
604
|
-
}
|
|
605
|
-
this.baseUrl = config.baseUrl || "https://api.basic.tech";
|
|
606
|
-
this.schema = config.schema;
|
|
607
|
-
this.tableNames = Object.keys(this.schema.tables);
|
|
608
|
-
}
|
|
609
|
-
// Primary method - table access
|
|
610
|
-
table(name) {
|
|
611
|
-
if (!this.tableNames.includes(name)) {
|
|
612
|
-
throw new Error(`Table '${name}' not found in schema. Available tables: ${this.tableNames.join(", ")}`);
|
|
613
|
-
}
|
|
614
|
-
return new TableClient(
|
|
615
|
-
this.baseUrl,
|
|
616
|
-
this.projectId,
|
|
617
|
-
"",
|
|
618
|
-
// Empty placeholder, will be replaced in headers() method
|
|
619
|
-
name,
|
|
620
|
-
this.getToken,
|
|
621
|
-
this.schema
|
|
622
|
-
// Pass the entire schema to the TableClient
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
get tables() {
|
|
626
|
-
return {};
|
|
627
|
-
}
|
|
628
|
-
fields(table) {
|
|
629
|
-
const tableSchema = this.schema.tables[table];
|
|
630
|
-
if (!tableSchema) {
|
|
631
|
-
throw new Error(`Table '${table}' not found in schema`);
|
|
632
|
-
}
|
|
633
|
-
return Object.keys(tableSchema.fields);
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
|
|
637
281
|
// package.json
|
|
638
|
-
var version = "0.7.0-beta.
|
|
282
|
+
var version = "0.7.0-beta.2";
|
|
639
283
|
|
|
640
284
|
// src/updater/versionUpdater.ts
|
|
641
285
|
var VersionUpdater = class {
|
|
@@ -988,7 +632,6 @@ var BasicContext = (0, import_react.createContext)({
|
|
|
988
632
|
}),
|
|
989
633
|
getSignInLink: () => Promise.resolve(""),
|
|
990
634
|
db: {},
|
|
991
|
-
remoteDb: {},
|
|
992
635
|
dbStatus: "LOADING" /* LOADING */
|
|
993
636
|
});
|
|
994
637
|
function BasicProvider({
|
|
@@ -1009,7 +652,6 @@ function BasicProvider({
|
|
|
1009
652
|
const [isOnline, setIsOnline] = (0, import_react.useState)(navigator.onLine);
|
|
1010
653
|
const [pendingRefresh, setPendingRefresh] = (0, import_react.useState)(false);
|
|
1011
654
|
const syncRef = (0, import_react.useRef)(null);
|
|
1012
|
-
const remoteDbRef = (0, import_react.useRef)(null);
|
|
1013
655
|
const storageAdapter = storage || new LocalStorageAdapter();
|
|
1014
656
|
const isDevMode = () => isDevelopment(debug);
|
|
1015
657
|
const cleanOAuthParams = () => cleanOAuthParamsFromUrl();
|
|
@@ -1023,7 +665,7 @@ function BasicProvider({
|
|
|
1023
665
|
if (token) {
|
|
1024
666
|
const refreshToken = token.refresh_token || localStorage.getItem("basic_refresh_token");
|
|
1025
667
|
if (refreshToken) {
|
|
1026
|
-
fetchToken(refreshToken).catch((error2) => {
|
|
668
|
+
fetchToken(refreshToken, true).catch((error2) => {
|
|
1027
669
|
log("Retry refresh failed:", error2);
|
|
1028
670
|
});
|
|
1029
671
|
}
|
|
@@ -1105,17 +747,6 @@ function BasicProvider({
|
|
|
1105
747
|
}
|
|
1106
748
|
connectToDb();
|
|
1107
749
|
}, [isSignedIn, shouldConnect]);
|
|
1108
|
-
(0, import_react.useEffect)(() => {
|
|
1109
|
-
if (project_id && schema && token?.access_token && !remoteDbRef.current) {
|
|
1110
|
-
log("Initializing Remote DB SDK");
|
|
1111
|
-
remoteDbRef.current = new BasicDBSDK({
|
|
1112
|
-
project_id,
|
|
1113
|
-
schema,
|
|
1114
|
-
getToken: () => getToken(),
|
|
1115
|
-
baseUrl: "https://api.basic.tech"
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
}, [token, project_id, schema]);
|
|
1119
750
|
(0, import_react.useEffect)(() => {
|
|
1120
751
|
const initializeAuth = async () => {
|
|
1121
752
|
await storageAdapter.set(STORAGE_KEYS.DEBUG, debug ? "true" : "false");
|
|
@@ -1146,14 +777,14 @@ function BasicProvider({
|
|
|
1146
777
|
}
|
|
1147
778
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
1148
779
|
cleanOAuthParams();
|
|
1149
|
-
fetchToken(code).catch((error2) => {
|
|
780
|
+
fetchToken(code, false).catch((error2) => {
|
|
1150
781
|
log("Error fetching token:", error2);
|
|
1151
782
|
});
|
|
1152
783
|
} else {
|
|
1153
784
|
const refreshToken = await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
1154
785
|
if (refreshToken) {
|
|
1155
786
|
log("Found refresh token in storage, attempting to refresh access token");
|
|
1156
|
-
fetchToken(refreshToken).catch((error2) => {
|
|
787
|
+
fetchToken(refreshToken, true).catch((error2) => {
|
|
1157
788
|
log("Error fetching refresh token:", error2);
|
|
1158
789
|
});
|
|
1159
790
|
} else {
|
|
@@ -1222,7 +853,7 @@ function BasicProvider({
|
|
|
1222
853
|
if (isExpired) {
|
|
1223
854
|
log("token is expired - refreshing ...");
|
|
1224
855
|
try {
|
|
1225
|
-
const newToken = await fetchToken(token?.refresh_token || "");
|
|
856
|
+
const newToken = await fetchToken(token?.refresh_token || "", true);
|
|
1226
857
|
fetchUser(newToken?.access_token || "");
|
|
1227
858
|
} catch (error2) {
|
|
1228
859
|
log("Failed to refresh token in checkToken:", error2);
|
|
@@ -1307,7 +938,7 @@ function BasicProvider({
|
|
|
1307
938
|
}
|
|
1308
939
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
1309
940
|
cleanOAuthParams();
|
|
1310
|
-
const token2 = await fetchToken(code);
|
|
941
|
+
const token2 = await fetchToken(code, false);
|
|
1311
942
|
if (token2) {
|
|
1312
943
|
log("signinWithCode successful");
|
|
1313
944
|
return { success: true };
|
|
@@ -1352,7 +983,7 @@ function BasicProvider({
|
|
|
1352
983
|
if (refreshToken) {
|
|
1353
984
|
log("No token in memory, attempting to refresh from storage");
|
|
1354
985
|
try {
|
|
1355
|
-
const newToken = await fetchToken(refreshToken);
|
|
986
|
+
const newToken = await fetchToken(refreshToken, true);
|
|
1356
987
|
if (newToken?.access_token) {
|
|
1357
988
|
return newToken.access_token;
|
|
1358
989
|
}
|
|
@@ -1379,7 +1010,7 @@ function BasicProvider({
|
|
|
1379
1010
|
const refreshToken = token?.refresh_token || await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
1380
1011
|
if (refreshToken) {
|
|
1381
1012
|
try {
|
|
1382
|
-
const newToken = await fetchToken(refreshToken);
|
|
1013
|
+
const newToken = await fetchToken(refreshToken, true);
|
|
1383
1014
|
return newToken?.access_token || "";
|
|
1384
1015
|
} catch (error2) {
|
|
1385
1016
|
log("Failed to refresh expired token:", error2);
|
|
@@ -1395,19 +1026,26 @@ function BasicProvider({
|
|
|
1395
1026
|
}
|
|
1396
1027
|
return token?.access_token || "";
|
|
1397
1028
|
};
|
|
1398
|
-
const fetchToken = async (
|
|
1029
|
+
const fetchToken = async (codeOrRefreshToken, isRefreshToken = false) => {
|
|
1399
1030
|
try {
|
|
1400
1031
|
if (!isOnline) {
|
|
1401
1032
|
log("Network is offline, marking refresh as pending");
|
|
1402
1033
|
setPendingRefresh(true);
|
|
1403
1034
|
throw new Error("Network offline - refresh will be retried when online");
|
|
1404
1035
|
}
|
|
1036
|
+
const requestBody = isRefreshToken ? {
|
|
1037
|
+
grant_type: "refresh_token",
|
|
1038
|
+
refresh_token: codeOrRefreshToken
|
|
1039
|
+
} : {
|
|
1040
|
+
grant_type: "authorization_code",
|
|
1041
|
+
code: codeOrRefreshToken
|
|
1042
|
+
};
|
|
1405
1043
|
const token2 = await fetch("https://api.basic.tech/auth/token", {
|
|
1406
1044
|
method: "POST",
|
|
1407
1045
|
headers: {
|
|
1408
1046
|
"Content-Type": "application/json"
|
|
1409
1047
|
},
|
|
1410
|
-
body: JSON.stringify(
|
|
1048
|
+
body: JSON.stringify(requestBody)
|
|
1411
1049
|
}).then((response) => response.json()).catch((error2) => {
|
|
1412
1050
|
log("Network error fetching token:", error2);
|
|
1413
1051
|
if (!isOnline) {
|
|
@@ -1473,7 +1111,6 @@ function BasicProvider({
|
|
|
1473
1111
|
getToken,
|
|
1474
1112
|
getSignInLink,
|
|
1475
1113
|
db: syncRef.current ? syncRef.current : noDb,
|
|
1476
|
-
remoteDb: remoteDbRef.current ? remoteDbRef.current : noDb,
|
|
1477
1114
|
dbStatus
|
|
1478
1115
|
}, children: [
|
|
1479
1116
|
error && isDevMode() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorDisplay, { error }),
|
|
@@ -1511,7 +1148,6 @@ function useBasic() {
|
|
|
1511
1148
|
var import_dexie_react_hooks = require("dexie-react-hooks");
|
|
1512
1149
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1513
1150
|
0 && (module.exports = {
|
|
1514
|
-
BasicDBSDK,
|
|
1515
1151
|
BasicProvider,
|
|
1516
1152
|
useBasic,
|
|
1517
1153
|
useQuery
|