@basictech/react 0.7.0-beta.1 → 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 +12 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +362 -363
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +360 -351
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/AuthContext.tsx +242 -404
- package/src/index.ts +11 -32
- package/src/sync/index.ts +1 -1
- package/src/updater/updateMigrations.ts +22 -0
- package/src/updater/versionUpdater.ts +160 -0
- package/src/utils/network.ts +82 -0
- package/src/utils/schema.ts +120 -0
- package/src/utils/storage.ts +63 -0
- package/src/schema.ts +0 -159
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -165,116 +155,8 @@ var syncProtocol = function() {
|
|
|
165
155
|
});
|
|
166
156
|
};
|
|
167
157
|
|
|
168
|
-
// src/schema.ts
|
|
169
|
-
var import_ajv = __toESM(require("ajv"));
|
|
170
|
-
var basicJsonSchema = {
|
|
171
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
172
|
-
"type": "object",
|
|
173
|
-
"properties": {
|
|
174
|
-
"project_id": {
|
|
175
|
-
"type": "string"
|
|
176
|
-
},
|
|
177
|
-
"namespace": {
|
|
178
|
-
"type": "string"
|
|
179
|
-
},
|
|
180
|
-
"version": {
|
|
181
|
-
"type": "integer",
|
|
182
|
-
"minimum": 0
|
|
183
|
-
},
|
|
184
|
-
"tables": {
|
|
185
|
-
"type": "object",
|
|
186
|
-
"patternProperties": {
|
|
187
|
-
"^[a-zA-Z0-9_]+$": {
|
|
188
|
-
"type": "object",
|
|
189
|
-
"properties": {
|
|
190
|
-
"name": {
|
|
191
|
-
"type": "string"
|
|
192
|
-
},
|
|
193
|
-
"type": {
|
|
194
|
-
"type": "string",
|
|
195
|
-
"enum": ["collection"]
|
|
196
|
-
},
|
|
197
|
-
"fields": {
|
|
198
|
-
"type": "object",
|
|
199
|
-
"patternProperties": {
|
|
200
|
-
"^[a-zA-Z0-9_]+$": {
|
|
201
|
-
"type": "object",
|
|
202
|
-
"properties": {
|
|
203
|
-
"type": {
|
|
204
|
-
"type": "string",
|
|
205
|
-
"enum": ["string", "boolean", "number", "json"]
|
|
206
|
-
},
|
|
207
|
-
"indexed": {
|
|
208
|
-
"type": "boolean"
|
|
209
|
-
},
|
|
210
|
-
"required": {
|
|
211
|
-
"type": "boolean"
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
"required": ["type"]
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
"additionalProperties": true
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
"required": ["fields"]
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
"additionalProperties": true
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
|
-
"required": ["project_id", "version", "tables"]
|
|
227
|
-
};
|
|
228
|
-
var ajv = new import_ajv.default();
|
|
229
|
-
var validator = ajv.compile(basicJsonSchema);
|
|
230
|
-
function validateSchema(schema) {
|
|
231
|
-
const v = validator(schema);
|
|
232
|
-
return {
|
|
233
|
-
valid: v,
|
|
234
|
-
errors: validator.errors || []
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
function validateData(schema, table, data, checkRequired = true) {
|
|
238
|
-
const valid = validateSchema(schema);
|
|
239
|
-
if (!valid.valid) {
|
|
240
|
-
return { valid: false, errors: valid.errors, message: "Schema is invalid" };
|
|
241
|
-
}
|
|
242
|
-
const tableSchema = schema.tables[table];
|
|
243
|
-
if (!tableSchema) {
|
|
244
|
-
return { valid: false, errors: [{ message: `Table ${table} not found in schema` }], message: "Table not found" };
|
|
245
|
-
}
|
|
246
|
-
for (const [fieldName, fieldValue] of Object.entries(data)) {
|
|
247
|
-
const fieldSchema = tableSchema.fields[fieldName];
|
|
248
|
-
if (!fieldSchema) {
|
|
249
|
-
return {
|
|
250
|
-
valid: false,
|
|
251
|
-
errors: [{ message: `Field ${fieldName} not found in schema` }],
|
|
252
|
-
message: "Invalid field"
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
const schemaType = fieldSchema.type;
|
|
256
|
-
const valueType = typeof fieldValue;
|
|
257
|
-
if (schemaType === "string" && valueType !== "string" || schemaType === "number" && valueType !== "number" || schemaType === "boolean" && valueType !== "boolean" || schemaType === "json" && valueType !== "object") {
|
|
258
|
-
return {
|
|
259
|
-
valid: false,
|
|
260
|
-
errors: [{
|
|
261
|
-
message: `Field ${fieldName} should be type ${schemaType}, got ${valueType}`
|
|
262
|
-
}],
|
|
263
|
-
message: "invalid type"
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (checkRequired) {
|
|
268
|
-
for (const [fieldName, fieldSchema] of Object.entries(tableSchema.fields)) {
|
|
269
|
-
if (fieldSchema.required && !data[fieldName]) {
|
|
270
|
-
return { valid: false, errors: [{ message: `Field ${fieldName} is required` }], message: "Required field missing" };
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return { valid: true, errors: [] };
|
|
275
|
-
}
|
|
276
|
-
|
|
277
158
|
// src/sync/index.ts
|
|
159
|
+
var import_schema = require("@basictech/schema");
|
|
278
160
|
syncProtocol();
|
|
279
161
|
var BasicSync = class extends import_dexie2.Dexie {
|
|
280
162
|
basic_schema;
|
|
@@ -349,7 +231,7 @@ var BasicSync = class extends import_dexie2.Dexie {
|
|
|
349
231
|
ref: this.table(name),
|
|
350
232
|
// --- WRITE ---- //
|
|
351
233
|
add: (data) => {
|
|
352
|
-
const valid = validateData(this.basic_schema, name, data);
|
|
234
|
+
const valid = (0, import_schema.validateData)(this.basic_schema, name, data);
|
|
353
235
|
if (!valid.valid) {
|
|
354
236
|
log("Invalid data", valid);
|
|
355
237
|
return Promise.reject({ ...valid });
|
|
@@ -360,7 +242,7 @@ var BasicSync = class extends import_dexie2.Dexie {
|
|
|
360
242
|
});
|
|
361
243
|
},
|
|
362
244
|
put: (data) => {
|
|
363
|
-
const valid = validateData(this.basic_schema, name, data);
|
|
245
|
+
const valid = (0, import_schema.validateData)(this.basic_schema, name, data);
|
|
364
246
|
if (!valid.valid) {
|
|
365
247
|
log("Invalid data", valid);
|
|
366
248
|
return Promise.reject({ ...valid });
|
|
@@ -371,7 +253,7 @@ var BasicSync = class extends import_dexie2.Dexie {
|
|
|
371
253
|
});
|
|
372
254
|
},
|
|
373
255
|
update: (id, data) => {
|
|
374
|
-
const valid = validateData(this.basic_schema, name, data, false);
|
|
256
|
+
const valid = (0, import_schema.validateData)(this.basic_schema, name, data, false);
|
|
375
257
|
if (!valid.valid) {
|
|
376
258
|
log("Invalid data", valid);
|
|
377
259
|
return Promise.reject({ ...valid });
|
|
@@ -396,60 +278,135 @@ var BasicSync = class extends import_dexie2.Dexie {
|
|
|
396
278
|
}
|
|
397
279
|
};
|
|
398
280
|
|
|
399
|
-
//
|
|
400
|
-
var
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
281
|
+
// package.json
|
|
282
|
+
var version = "0.7.0-beta.2";
|
|
283
|
+
|
|
284
|
+
// src/updater/versionUpdater.ts
|
|
285
|
+
var VersionUpdater = class {
|
|
286
|
+
storage;
|
|
287
|
+
currentVersion;
|
|
288
|
+
migrations;
|
|
289
|
+
versionKey = "basic_app_version";
|
|
290
|
+
constructor(storage, currentVersion, migrations = []) {
|
|
291
|
+
this.storage = storage;
|
|
292
|
+
this.currentVersion = currentVersion;
|
|
293
|
+
this.migrations = migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion));
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Check current stored version and run migrations if needed
|
|
297
|
+
* Only compares major.minor versions, ignoring beta/prerelease parts
|
|
298
|
+
* Example: "0.7.0-beta.1" and "0.7.0" are treated as the same version
|
|
299
|
+
*/
|
|
300
|
+
async checkAndUpdate() {
|
|
301
|
+
const storedVersion = await this.getStoredVersion();
|
|
302
|
+
if (!storedVersion) {
|
|
303
|
+
await this.setStoredVersion(this.currentVersion);
|
|
304
|
+
return { updated: false, toVersion: this.currentVersion };
|
|
406
305
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
async function add({ projectId, accountId, tableName, value, token }) {
|
|
411
|
-
const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;
|
|
412
|
-
const response = await fetch(url, {
|
|
413
|
-
method: "POST",
|
|
414
|
-
headers: {
|
|
415
|
-
"Content-Type": "application/json",
|
|
416
|
-
"Authorization": `Bearer ${token}`
|
|
417
|
-
},
|
|
418
|
-
body: JSON.stringify({ "value": value })
|
|
419
|
-
});
|
|
420
|
-
return response.json();
|
|
421
|
-
}
|
|
422
|
-
async function update({ projectId, accountId, tableName, id, value, token }) {
|
|
423
|
-
const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;
|
|
424
|
-
const response = await fetch(url, {
|
|
425
|
-
method: "PATCH",
|
|
426
|
-
headers: {
|
|
427
|
-
"Content-Type": "application/json",
|
|
428
|
-
"Authorization": `Bearer ${token}`
|
|
429
|
-
},
|
|
430
|
-
body: JSON.stringify({ id, value })
|
|
431
|
-
});
|
|
432
|
-
return response.json();
|
|
433
|
-
}
|
|
434
|
-
async function deleteRecord({ projectId, accountId, tableName, id, token }) {
|
|
435
|
-
const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;
|
|
436
|
-
const response = await fetch(url, {
|
|
437
|
-
method: "DELETE",
|
|
438
|
-
headers: {
|
|
439
|
-
"Authorization": `Bearer ${token}`
|
|
306
|
+
if (storedVersion === this.currentVersion) {
|
|
307
|
+
return { updated: false, toVersion: this.currentVersion };
|
|
440
308
|
}
|
|
441
|
-
|
|
442
|
-
|
|
309
|
+
const migrationsToRun = this.getMigrationsToRun(storedVersion, this.currentVersion);
|
|
310
|
+
if (migrationsToRun.length === 0) {
|
|
311
|
+
await this.setStoredVersion(this.currentVersion);
|
|
312
|
+
return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion };
|
|
313
|
+
}
|
|
314
|
+
for (const migration of migrationsToRun) {
|
|
315
|
+
try {
|
|
316
|
+
console.log(`Running migration from ${migration.fromVersion} to ${migration.toVersion}`);
|
|
317
|
+
await migration.migrate(this.storage);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.error(`Migration failed from ${migration.fromVersion} to ${migration.toVersion}:`, error);
|
|
320
|
+
throw new Error(`Migration failed: ${error}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
await this.setStoredVersion(this.currentVersion);
|
|
324
|
+
return { updated: true, fromVersion: storedVersion, toVersion: this.currentVersion };
|
|
325
|
+
}
|
|
326
|
+
async getStoredVersion() {
|
|
327
|
+
try {
|
|
328
|
+
const versionData = await this.storage.get(this.versionKey);
|
|
329
|
+
if (!versionData)
|
|
330
|
+
return null;
|
|
331
|
+
const versionInfo = JSON.parse(versionData);
|
|
332
|
+
return versionInfo.version;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.warn("Failed to get stored version:", error);
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async setStoredVersion(version2) {
|
|
339
|
+
const versionInfo = {
|
|
340
|
+
version: version2,
|
|
341
|
+
lastUpdated: Date.now()
|
|
342
|
+
};
|
|
343
|
+
await this.storage.set(this.versionKey, JSON.stringify(versionInfo));
|
|
344
|
+
}
|
|
345
|
+
getMigrationsToRun(fromVersion, toVersion) {
|
|
346
|
+
return this.migrations.filter((migration) => {
|
|
347
|
+
const storedLessThanMigrationTo = this.compareVersions(fromVersion, migration.toVersion) < 0;
|
|
348
|
+
const currentGreaterThanOrEqualMigrationTo = this.compareVersions(toVersion, migration.toVersion) >= 0;
|
|
349
|
+
console.log(`Checking migration ${migration.fromVersion} \u2192 ${migration.toVersion}:`);
|
|
350
|
+
console.log(` stored ${fromVersion} < migration.to ${migration.toVersion}: ${storedLessThanMigrationTo}`);
|
|
351
|
+
console.log(` current ${toVersion} >= migration.to ${migration.toVersion}: ${currentGreaterThanOrEqualMigrationTo}`);
|
|
352
|
+
const shouldRun = storedLessThanMigrationTo && currentGreaterThanOrEqualMigrationTo;
|
|
353
|
+
console.log(` Should run: ${shouldRun}`);
|
|
354
|
+
return shouldRun;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Simple semantic version comparison (major.minor only, ignoring beta/prerelease)
|
|
359
|
+
* Returns: -1 if a < b, 0 if a === b, 1 if a > b
|
|
360
|
+
*/
|
|
361
|
+
compareVersions(a, b) {
|
|
362
|
+
const aMajorMinor = this.extractMajorMinor(a);
|
|
363
|
+
const bMajorMinor = this.extractMajorMinor(b);
|
|
364
|
+
if (aMajorMinor.major !== bMajorMinor.major) {
|
|
365
|
+
return aMajorMinor.major - bMajorMinor.major;
|
|
366
|
+
}
|
|
367
|
+
return aMajorMinor.minor - bMajorMinor.minor;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Extract major.minor from version string, ignoring beta/prerelease
|
|
371
|
+
* Examples: "0.7.0-beta.1" -> {major: 0, minor: 7}
|
|
372
|
+
* "1.2.3" -> {major: 1, minor: 2}
|
|
373
|
+
*/
|
|
374
|
+
extractMajorMinor(version2) {
|
|
375
|
+
const cleanVersion = version2.split("-")[0]?.split("+")[0] || version2;
|
|
376
|
+
const parts = cleanVersion.split(".").map(Number);
|
|
377
|
+
return {
|
|
378
|
+
major: parts[0] || 0,
|
|
379
|
+
minor: parts[1] || 0
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Add a migration to the updater
|
|
384
|
+
*/
|
|
385
|
+
addMigration(migration) {
|
|
386
|
+
this.migrations.push(migration);
|
|
387
|
+
this.migrations.sort((a, b) => this.compareVersions(a.fromVersion, b.fromVersion));
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
function createVersionUpdater(storage, currentVersion, migrations = []) {
|
|
391
|
+
return new VersionUpdater(storage, currentVersion, migrations);
|
|
443
392
|
}
|
|
444
393
|
|
|
445
|
-
// src/
|
|
446
|
-
var
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
394
|
+
// src/updater/updateMigrations.ts
|
|
395
|
+
var addMigrationTimestamp = {
|
|
396
|
+
fromVersion: "0.6.0",
|
|
397
|
+
toVersion: "0.7.0",
|
|
398
|
+
async migrate(storage) {
|
|
399
|
+
console.log("Running test migration");
|
|
400
|
+
storage.set("test_migration", "true");
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
function getMigrations() {
|
|
404
|
+
return [
|
|
405
|
+
addMigrationTimestamp
|
|
406
|
+
];
|
|
407
|
+
}
|
|
450
408
|
|
|
451
|
-
// src/
|
|
452
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
409
|
+
// src/utils/storage.ts
|
|
453
410
|
var LocalStorageAdapter = class {
|
|
454
411
|
async get(key) {
|
|
455
412
|
return localStorage.getItem(key);
|
|
@@ -461,24 +418,112 @@ var LocalStorageAdapter = class {
|
|
|
461
418
|
localStorage.removeItem(key);
|
|
462
419
|
}
|
|
463
420
|
};
|
|
464
|
-
var
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
421
|
+
var STORAGE_KEYS = {
|
|
422
|
+
REFRESH_TOKEN: "basic_refresh_token",
|
|
423
|
+
USER_INFO: "basic_user_info",
|
|
424
|
+
AUTH_STATE: "basic_auth_state",
|
|
425
|
+
DEBUG: "basic_debug"
|
|
426
|
+
};
|
|
427
|
+
function getCookie(name) {
|
|
428
|
+
let cookieValue = "";
|
|
429
|
+
if (document.cookie && document.cookie !== "") {
|
|
430
|
+
const cookies = document.cookie.split(";");
|
|
431
|
+
for (let i = 0; i < cookies.length; i++) {
|
|
432
|
+
const cookie = cookies[i]?.trim();
|
|
433
|
+
if (cookie && cookie.substring(0, name.length + 1) === name + "=") {
|
|
434
|
+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return cookieValue;
|
|
440
|
+
}
|
|
441
|
+
function setCookie(name, value, options) {
|
|
442
|
+
const opts = {
|
|
443
|
+
secure: true,
|
|
444
|
+
sameSite: "Strict",
|
|
445
|
+
httpOnly: false,
|
|
446
|
+
...options
|
|
447
|
+
};
|
|
448
|
+
let cookieString = `${name}=${value}`;
|
|
449
|
+
if (opts.secure)
|
|
450
|
+
cookieString += "; Secure";
|
|
451
|
+
if (opts.sameSite)
|
|
452
|
+
cookieString += `; SameSite=${opts.sameSite}`;
|
|
453
|
+
if (opts.httpOnly)
|
|
454
|
+
cookieString += "; HttpOnly";
|
|
455
|
+
document.cookie = cookieString;
|
|
456
|
+
}
|
|
457
|
+
function clearCookie(name) {
|
|
458
|
+
document.cookie = `${name}=; Secure; SameSite=Strict`;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/utils/network.ts
|
|
462
|
+
function isDevelopment(debug) {
|
|
463
|
+
return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.includes("localhost") || window.location.hostname.includes("127.0.0.1") || window.location.hostname.includes(".local") || process.env.NODE_ENV === "development" || debug === true;
|
|
464
|
+
}
|
|
465
|
+
async function checkForNewVersion() {
|
|
466
|
+
try {
|
|
467
|
+
const isBeta = version.includes("beta");
|
|
468
|
+
const response = await fetch(`https://registry.npmjs.org/@basictech/react/${isBeta ? "beta" : "latest"}`);
|
|
469
|
+
if (!response.ok) {
|
|
470
|
+
throw new Error("Failed to fetch version from npm");
|
|
471
|
+
}
|
|
472
|
+
const data = await response.json();
|
|
473
|
+
const latestVersion = data.version;
|
|
474
|
+
if (latestVersion !== version) {
|
|
475
|
+
console.warn("[basic] New version available:", latestVersion, `
|
|
476
|
+
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
477
|
+
}
|
|
478
|
+
if (isBeta) {
|
|
479
|
+
log("thank you for being on basictech/react beta :)");
|
|
480
|
+
}
|
|
481
|
+
return {
|
|
482
|
+
hasNewVersion: version !== latestVersion,
|
|
483
|
+
latestVersion,
|
|
484
|
+
currentVersion: version
|
|
485
|
+
};
|
|
486
|
+
} catch (error) {
|
|
487
|
+
log("Error checking for new version:", error);
|
|
488
|
+
return {
|
|
489
|
+
hasNewVersion: false,
|
|
490
|
+
latestVersion: null,
|
|
491
|
+
currentVersion: null
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function cleanOAuthParamsFromUrl() {
|
|
496
|
+
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
497
|
+
const url = new URL(window.location.href);
|
|
498
|
+
url.searchParams.delete("code");
|
|
499
|
+
url.searchParams.delete("state");
|
|
500
|
+
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
501
|
+
log("Cleaned OAuth parameters from URL");
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function getSyncStatus(statusCode) {
|
|
505
|
+
switch (statusCode) {
|
|
506
|
+
case -1:
|
|
507
|
+
return "ERROR";
|
|
508
|
+
case 0:
|
|
509
|
+
return "OFFLINE";
|
|
510
|
+
case 1:
|
|
511
|
+
return "CONNECTING";
|
|
512
|
+
case 2:
|
|
513
|
+
return "ONLINE";
|
|
514
|
+
case 3:
|
|
515
|
+
return "SYNCING";
|
|
516
|
+
case 4:
|
|
517
|
+
return "ERROR_WILL_RETRY";
|
|
518
|
+
default:
|
|
519
|
+
return "UNKNOWN";
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/utils/schema.ts
|
|
524
|
+
var import_schema2 = require("@basictech/schema");
|
|
479
525
|
async function getSchemaStatus(schema) {
|
|
480
526
|
const projectId = schema.project_id;
|
|
481
|
-
let status = "";
|
|
482
527
|
const valid = (0, import_schema2.validateSchema)(schema);
|
|
483
528
|
if (!valid.valid) {
|
|
484
529
|
console.warn("BasicDB Error: your local schema is invalid. Please fix errors and try again - sync is disabled");
|
|
@@ -541,54 +586,54 @@ async function getSchemaStatus(schema) {
|
|
|
541
586
|
};
|
|
542
587
|
}
|
|
543
588
|
}
|
|
544
|
-
function
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
case 4:
|
|
557
|
-
return "ERROR_WILL_RETRY";
|
|
558
|
-
default:
|
|
559
|
-
return "UNKNOWN";
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
async function checkForNewVersion() {
|
|
563
|
-
try {
|
|
564
|
-
const isBeta = version.includes("beta");
|
|
565
|
-
const response = await fetch(`https://registry.npmjs.org/@basictech/react/${isBeta ? "beta" : "latest"}`);
|
|
566
|
-
if (!response.ok) {
|
|
567
|
-
throw new Error("Failed to fetch version from npm");
|
|
568
|
-
}
|
|
569
|
-
const data = await response.json();
|
|
570
|
-
const latestVersion = data.version;
|
|
571
|
-
if (latestVersion !== version) {
|
|
572
|
-
console.warn("[basic] New version available:", latestVersion, `
|
|
573
|
-
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
574
|
-
}
|
|
575
|
-
if (isBeta) {
|
|
576
|
-
log("thank you for being on basictech/react beta :)");
|
|
577
|
-
}
|
|
578
|
-
return {
|
|
579
|
-
hasNewVersion: version !== latestVersion,
|
|
580
|
-
latestVersion,
|
|
581
|
-
currentVersion: version
|
|
582
|
-
};
|
|
583
|
-
} catch (error) {
|
|
584
|
-
log("Error checking for new version:", error);
|
|
589
|
+
async function validateAndCheckSchema(schema) {
|
|
590
|
+
const valid = (0, import_schema2.validateSchema)(schema);
|
|
591
|
+
if (!valid.valid) {
|
|
592
|
+
log("Basic Schema is invalid!", valid.errors);
|
|
593
|
+
console.group("Schema Errors");
|
|
594
|
+
let errorMessage = "";
|
|
595
|
+
valid.errors.forEach((error, index) => {
|
|
596
|
+
log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`);
|
|
597
|
+
errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}
|
|
598
|
+
`;
|
|
599
|
+
});
|
|
600
|
+
console.groupEnd();
|
|
585
601
|
return {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
602
|
+
isValid: false,
|
|
603
|
+
schemaStatus: { valid: false },
|
|
604
|
+
errors: valid.errors
|
|
589
605
|
};
|
|
590
606
|
}
|
|
607
|
+
let schemaStatus = { valid: false };
|
|
608
|
+
if (schema.version !== 0) {
|
|
609
|
+
schemaStatus = await getSchemaStatus(schema);
|
|
610
|
+
log("schemaStatus", schemaStatus);
|
|
611
|
+
} else {
|
|
612
|
+
log("schema not published - at version 0");
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
isValid: true,
|
|
616
|
+
schemaStatus
|
|
617
|
+
};
|
|
591
618
|
}
|
|
619
|
+
|
|
620
|
+
// src/AuthContext.tsx
|
|
621
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
622
|
+
var BasicContext = (0, import_react.createContext)({
|
|
623
|
+
unicorn: "\u{1F984}",
|
|
624
|
+
isAuthReady: false,
|
|
625
|
+
isSignedIn: false,
|
|
626
|
+
user: null,
|
|
627
|
+
signout: () => Promise.resolve(),
|
|
628
|
+
signin: () => Promise.resolve(),
|
|
629
|
+
signinWithCode: () => new Promise(() => {
|
|
630
|
+
}),
|
|
631
|
+
getToken: () => new Promise(() => {
|
|
632
|
+
}),
|
|
633
|
+
getSignInLink: () => Promise.resolve(""),
|
|
634
|
+
db: {},
|
|
635
|
+
dbStatus: "LOADING" /* LOADING */
|
|
636
|
+
});
|
|
592
637
|
function BasicProvider({
|
|
593
638
|
children,
|
|
594
639
|
project_id,
|
|
@@ -608,24 +653,8 @@ function BasicProvider({
|
|
|
608
653
|
const [pendingRefresh, setPendingRefresh] = (0, import_react.useState)(false);
|
|
609
654
|
const syncRef = (0, import_react.useRef)(null);
|
|
610
655
|
const storageAdapter = storage || new LocalStorageAdapter();
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
USER_INFO: "basic_user_info",
|
|
614
|
-
AUTH_STATE: "basic_auth_state",
|
|
615
|
-
DEBUG: "basic_debug"
|
|
616
|
-
};
|
|
617
|
-
const isDevelopment = () => {
|
|
618
|
-
return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.includes("localhost") || window.location.hostname.includes("127.0.0.1") || window.location.hostname.includes(".local") || process.env.NODE_ENV === "development" || debug === true;
|
|
619
|
-
};
|
|
620
|
-
const cleanOAuthParamsFromUrl = () => {
|
|
621
|
-
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
622
|
-
const url = new URL(window.location.href);
|
|
623
|
-
url.searchParams.delete("code");
|
|
624
|
-
url.searchParams.delete("state");
|
|
625
|
-
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
626
|
-
log("Cleaned OAuth parameters from URL");
|
|
627
|
-
}
|
|
628
|
-
};
|
|
656
|
+
const isDevMode = () => isDevelopment(debug);
|
|
657
|
+
const cleanOAuthParams = () => cleanOAuthParamsFromUrl();
|
|
629
658
|
(0, import_react.useEffect)(() => {
|
|
630
659
|
const handleOnline = () => {
|
|
631
660
|
log("Network came back online");
|
|
@@ -636,7 +665,7 @@ function BasicProvider({
|
|
|
636
665
|
if (token) {
|
|
637
666
|
const refreshToken = token.refresh_token || localStorage.getItem("basic_refresh_token");
|
|
638
667
|
if (refreshToken) {
|
|
639
|
-
fetchToken(refreshToken).catch((error2) => {
|
|
668
|
+
fetchToken(refreshToken, true).catch((error2) => {
|
|
640
669
|
log("Retry refresh failed:", error2);
|
|
641
670
|
});
|
|
642
671
|
}
|
|
@@ -662,9 +691,6 @@ function BasicProvider({
|
|
|
662
691
|
syncRef.current.syncable.on("statusChanged", (status, url) => {
|
|
663
692
|
setDbStatus(getSyncStatus(status));
|
|
664
693
|
});
|
|
665
|
-
syncRef.current.syncable.getStatus().then((status) => {
|
|
666
|
-
setDbStatus(getSyncStatus(status));
|
|
667
|
-
});
|
|
668
694
|
if (options.shouldConnect) {
|
|
669
695
|
setShouldConnect(true);
|
|
670
696
|
} else {
|
|
@@ -674,17 +700,15 @@ function BasicProvider({
|
|
|
674
700
|
}
|
|
675
701
|
}
|
|
676
702
|
async function checkSchema() {
|
|
677
|
-
const
|
|
678
|
-
if (!
|
|
679
|
-
log("Basic Schema is invalid!", valid.errors);
|
|
680
|
-
console.group("Schema Errors");
|
|
703
|
+
const result = await validateAndCheckSchema(schema);
|
|
704
|
+
if (!result.isValid) {
|
|
681
705
|
let errorMessage = "";
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
706
|
+
if (result.errors) {
|
|
707
|
+
result.errors.forEach((error2, index) => {
|
|
708
|
+
errorMessage += `${index + 1}: ${error2.message} - at ${error2.instancePath}
|
|
685
709
|
`;
|
|
686
|
-
|
|
687
|
-
|
|
710
|
+
});
|
|
711
|
+
}
|
|
688
712
|
setError({
|
|
689
713
|
code: "schema_invalid",
|
|
690
714
|
title: "Basic Schema is invalid!",
|
|
@@ -693,17 +717,10 @@ function BasicProvider({
|
|
|
693
717
|
setIsReady(true);
|
|
694
718
|
return null;
|
|
695
719
|
}
|
|
696
|
-
|
|
697
|
-
if (schema.version !== 0) {
|
|
698
|
-
schemaStatus = await getSchemaStatus(schema);
|
|
699
|
-
log("schemaStatus", schemaStatus);
|
|
700
|
-
} else {
|
|
701
|
-
log("schema not published - at version 0");
|
|
702
|
-
}
|
|
703
|
-
if (schemaStatus.valid) {
|
|
720
|
+
if (result.schemaStatus.valid) {
|
|
704
721
|
initDb({ shouldConnect: true });
|
|
705
722
|
} else {
|
|
706
|
-
log("Schema is invalid!", schemaStatus);
|
|
723
|
+
log("Schema is invalid!", result.schemaStatus);
|
|
707
724
|
initDb({ shouldConnect: false });
|
|
708
725
|
}
|
|
709
726
|
checkForNewVersion();
|
|
@@ -715,43 +732,61 @@ function BasicProvider({
|
|
|
715
732
|
}
|
|
716
733
|
}, []);
|
|
717
734
|
(0, import_react.useEffect)(() => {
|
|
718
|
-
|
|
719
|
-
|
|
735
|
+
async function connectToDb() {
|
|
736
|
+
if (token && syncRef.current && isSignedIn && shouldConnect) {
|
|
737
|
+
const tok = await getToken();
|
|
738
|
+
if (!tok) {
|
|
739
|
+
log("no token found");
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
log("connecting to db...");
|
|
743
|
+
syncRef.current?.connect({ access_token: tok }).catch((e) => {
|
|
744
|
+
log("error connecting to db", e);
|
|
745
|
+
});
|
|
746
|
+
}
|
|
720
747
|
}
|
|
748
|
+
connectToDb();
|
|
721
749
|
}, [isSignedIn, shouldConnect]);
|
|
722
|
-
const connectToDb = async () => {
|
|
723
|
-
const tok = await getToken();
|
|
724
|
-
if (!tok) {
|
|
725
|
-
log("no token found");
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
log("connecting to db...");
|
|
729
|
-
syncRef.current.connect({ access_token: tok }).catch((e) => {
|
|
730
|
-
log("error connecting to db", e);
|
|
731
|
-
});
|
|
732
|
-
};
|
|
733
750
|
(0, import_react.useEffect)(() => {
|
|
734
751
|
const initializeAuth = async () => {
|
|
735
752
|
await storageAdapter.set(STORAGE_KEYS.DEBUG, debug ? "true" : "false");
|
|
753
|
+
try {
|
|
754
|
+
const versionUpdater = createVersionUpdater(storageAdapter, version, getMigrations());
|
|
755
|
+
const updateResult = await versionUpdater.checkAndUpdate();
|
|
756
|
+
if (updateResult.updated) {
|
|
757
|
+
log(`App updated from ${updateResult.fromVersion} to ${updateResult.toVersion}`);
|
|
758
|
+
} else {
|
|
759
|
+
log(`App version ${updateResult.toVersion} is current`);
|
|
760
|
+
}
|
|
761
|
+
} catch (error2) {
|
|
762
|
+
log("Version update failed:", error2);
|
|
763
|
+
}
|
|
736
764
|
try {
|
|
737
765
|
if (window.location.search.includes("code")) {
|
|
738
|
-
let code = window.location?.search?.split("code=")[1]
|
|
766
|
+
let code = window.location?.search?.split("code=")[1]?.split("&")[0];
|
|
767
|
+
if (!code)
|
|
768
|
+
return;
|
|
739
769
|
const state = await storageAdapter.get(STORAGE_KEYS.AUTH_STATE);
|
|
740
|
-
|
|
770
|
+
const urlState = window.location.search.split("state=")[1]?.split("&")[0];
|
|
771
|
+
if (!state || state !== urlState) {
|
|
741
772
|
log("error: auth state does not match");
|
|
742
773
|
setIsAuthReady(true);
|
|
743
774
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
744
|
-
|
|
775
|
+
cleanOAuthParams();
|
|
745
776
|
return;
|
|
746
777
|
}
|
|
747
778
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
748
|
-
|
|
749
|
-
fetchToken(code)
|
|
779
|
+
cleanOAuthParams();
|
|
780
|
+
fetchToken(code, false).catch((error2) => {
|
|
781
|
+
log("Error fetching token:", error2);
|
|
782
|
+
});
|
|
750
783
|
} else {
|
|
751
784
|
const refreshToken = await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
752
785
|
if (refreshToken) {
|
|
753
786
|
log("Found refresh token in storage, attempting to refresh access token");
|
|
754
|
-
fetchToken(refreshToken)
|
|
787
|
+
fetchToken(refreshToken, true).catch((error2) => {
|
|
788
|
+
log("Error fetching refresh token:", error2);
|
|
789
|
+
});
|
|
755
790
|
} else {
|
|
756
791
|
let cookie_token = getCookie("basic_token");
|
|
757
792
|
if (cookie_token !== "") {
|
|
@@ -800,8 +835,8 @@ function BasicProvider({
|
|
|
800
835
|
}
|
|
801
836
|
await storageAdapter.set(STORAGE_KEYS.USER_INFO, JSON.stringify(user2));
|
|
802
837
|
log("Cached user info in storage");
|
|
803
|
-
|
|
804
|
-
|
|
838
|
+
setCookie("basic_access_token", token?.access_token || "", { httpOnly: false });
|
|
839
|
+
setCookie("basic_token", JSON.stringify(token));
|
|
805
840
|
setUser(user2);
|
|
806
841
|
setIsSignedIn(true);
|
|
807
842
|
setIsAuthReady(true);
|
|
@@ -818,19 +853,19 @@ function BasicProvider({
|
|
|
818
853
|
if (isExpired) {
|
|
819
854
|
log("token is expired - refreshing ...");
|
|
820
855
|
try {
|
|
821
|
-
const newToken = await fetchToken(token?.refresh_token);
|
|
822
|
-
fetchUser(newToken
|
|
856
|
+
const newToken = await fetchToken(token?.refresh_token || "", true);
|
|
857
|
+
fetchUser(newToken?.access_token || "");
|
|
823
858
|
} catch (error2) {
|
|
824
859
|
log("Failed to refresh token in checkToken:", error2);
|
|
825
860
|
if (error2.message.includes("offline") || error2.message.includes("Network")) {
|
|
826
861
|
log("Network issue - continuing with expired token until online");
|
|
827
|
-
fetchUser(token
|
|
862
|
+
fetchUser(token?.access_token || "");
|
|
828
863
|
} else {
|
|
829
864
|
setIsAuthReady(true);
|
|
830
865
|
}
|
|
831
866
|
}
|
|
832
867
|
} else {
|
|
833
|
-
fetchUser(token
|
|
868
|
+
fetchUser(token?.access_token || "");
|
|
834
869
|
}
|
|
835
870
|
}
|
|
836
871
|
if (token) {
|
|
@@ -849,14 +884,14 @@ function BasicProvider({
|
|
|
849
884
|
if (!redirectUrl || !redirectUrl.startsWith("http://") && !redirectUrl.startsWith("https://")) {
|
|
850
885
|
throw new Error("Invalid redirect URI provided");
|
|
851
886
|
}
|
|
852
|
-
let
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
887
|
+
let baseUrl = "https://api.basic.tech/auth/authorize";
|
|
888
|
+
baseUrl += `?client_id=${project_id}`;
|
|
889
|
+
baseUrl += `&redirect_uri=${encodeURIComponent(redirectUrl)}`;
|
|
890
|
+
baseUrl += `&response_type=code`;
|
|
891
|
+
baseUrl += `&scope=profile`;
|
|
892
|
+
baseUrl += `&state=${randomState}`;
|
|
858
893
|
log("Generated sign-in link successfully");
|
|
859
|
-
return
|
|
894
|
+
return baseUrl;
|
|
860
895
|
} catch (error2) {
|
|
861
896
|
log("Error generating sign-in link:", error2);
|
|
862
897
|
throw error2;
|
|
@@ -878,7 +913,7 @@ function BasicProvider({
|
|
|
878
913
|
window.location.href = signInLink;
|
|
879
914
|
} catch (error2) {
|
|
880
915
|
log("Error during sign-in:", error2);
|
|
881
|
-
if (
|
|
916
|
+
if (isDevMode()) {
|
|
882
917
|
setError({
|
|
883
918
|
code: "signin_error",
|
|
884
919
|
title: "Sign-in Failed",
|
|
@@ -902,8 +937,8 @@ function BasicProvider({
|
|
|
902
937
|
}
|
|
903
938
|
}
|
|
904
939
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
905
|
-
|
|
906
|
-
const token2 = await fetchToken(code);
|
|
940
|
+
cleanOAuthParams();
|
|
941
|
+
const token2 = await fetchToken(code, false);
|
|
907
942
|
if (token2) {
|
|
908
943
|
log("signinWithCode successful");
|
|
909
944
|
return { success: true };
|
|
@@ -923,16 +958,16 @@ function BasicProvider({
|
|
|
923
958
|
setUser({});
|
|
924
959
|
setIsSignedIn(false);
|
|
925
960
|
setToken(null);
|
|
926
|
-
|
|
927
|
-
|
|
961
|
+
clearCookie("basic_token");
|
|
962
|
+
clearCookie("basic_access_token");
|
|
928
963
|
await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
|
|
929
964
|
await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
|
|
930
965
|
await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
|
|
931
966
|
if (syncRef.current) {
|
|
932
967
|
(async () => {
|
|
933
968
|
try {
|
|
934
|
-
await syncRef.current
|
|
935
|
-
await syncRef.current
|
|
969
|
+
await syncRef.current?.close();
|
|
970
|
+
await syncRef.current?.delete({ disableAutoOpen: false });
|
|
936
971
|
syncRef.current = null;
|
|
937
972
|
window?.location?.reload();
|
|
938
973
|
} catch (error2) {
|
|
@@ -948,7 +983,7 @@ function BasicProvider({
|
|
|
948
983
|
if (refreshToken) {
|
|
949
984
|
log("No token in memory, attempting to refresh from storage");
|
|
950
985
|
try {
|
|
951
|
-
const newToken = await fetchToken(refreshToken);
|
|
986
|
+
const newToken = await fetchToken(refreshToken, true);
|
|
952
987
|
if (newToken?.access_token) {
|
|
953
988
|
return newToken.access_token;
|
|
954
989
|
}
|
|
@@ -975,7 +1010,7 @@ function BasicProvider({
|
|
|
975
1010
|
const refreshToken = token?.refresh_token || await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
976
1011
|
if (refreshToken) {
|
|
977
1012
|
try {
|
|
978
|
-
const newToken = await fetchToken(refreshToken);
|
|
1013
|
+
const newToken = await fetchToken(refreshToken, true);
|
|
979
1014
|
return newToken?.access_token || "";
|
|
980
1015
|
} catch (error2) {
|
|
981
1016
|
log("Failed to refresh expired token:", error2);
|
|
@@ -991,33 +1026,26 @@ function BasicProvider({
|
|
|
991
1026
|
}
|
|
992
1027
|
return token?.access_token || "";
|
|
993
1028
|
};
|
|
994
|
-
|
|
995
|
-
let cookieValue = "";
|
|
996
|
-
if (document.cookie && document.cookie !== "") {
|
|
997
|
-
const cookies = document.cookie.split(";");
|
|
998
|
-
for (let i = 0; i < cookies.length; i++) {
|
|
999
|
-
const cookie = cookies[i].trim();
|
|
1000
|
-
if (cookie.substring(0, name.length + 1) === name + "=") {
|
|
1001
|
-
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
1002
|
-
break;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
return cookieValue;
|
|
1007
|
-
}
|
|
1008
|
-
const fetchToken = async (code) => {
|
|
1029
|
+
const fetchToken = async (codeOrRefreshToken, isRefreshToken = false) => {
|
|
1009
1030
|
try {
|
|
1010
1031
|
if (!isOnline) {
|
|
1011
1032
|
log("Network is offline, marking refresh as pending");
|
|
1012
1033
|
setPendingRefresh(true);
|
|
1013
1034
|
throw new Error("Network offline - refresh will be retried when online");
|
|
1014
1035
|
}
|
|
1036
|
+
const requestBody = isRefreshToken ? {
|
|
1037
|
+
grant_type: "refresh_token",
|
|
1038
|
+
refresh_token: codeOrRefreshToken
|
|
1039
|
+
} : {
|
|
1040
|
+
grant_type: "authorization_code",
|
|
1041
|
+
code: codeOrRefreshToken
|
|
1042
|
+
};
|
|
1015
1043
|
const token2 = await fetch("https://api.basic.tech/auth/token", {
|
|
1016
1044
|
method: "POST",
|
|
1017
1045
|
headers: {
|
|
1018
1046
|
"Content-Type": "application/json"
|
|
1019
1047
|
},
|
|
1020
|
-
body: JSON.stringify(
|
|
1048
|
+
body: JSON.stringify(requestBody)
|
|
1021
1049
|
}).then((response) => response.json()).catch((error2) => {
|
|
1022
1050
|
log("Network error fetching token:", error2);
|
|
1023
1051
|
if (!isOnline) {
|
|
@@ -1034,8 +1062,8 @@ function BasicProvider({
|
|
|
1034
1062
|
}
|
|
1035
1063
|
await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
|
|
1036
1064
|
await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
|
|
1037
|
-
|
|
1038
|
-
|
|
1065
|
+
clearCookie("basic_token");
|
|
1066
|
+
clearCookie("basic_access_token");
|
|
1039
1067
|
setUser({});
|
|
1040
1068
|
setIsSignedIn(false);
|
|
1041
1069
|
setToken(null);
|
|
@@ -1048,7 +1076,7 @@ function BasicProvider({
|
|
|
1048
1076
|
await storageAdapter.set(STORAGE_KEYS.REFRESH_TOKEN, token2.refresh_token);
|
|
1049
1077
|
log("Updated refresh token in storage");
|
|
1050
1078
|
}
|
|
1051
|
-
|
|
1079
|
+
setCookie("basic_access_token", token2.access_token, { httpOnly: false });
|
|
1052
1080
|
log("Updated access token in cookie");
|
|
1053
1081
|
}
|
|
1054
1082
|
return token2;
|
|
@@ -1057,8 +1085,8 @@ function BasicProvider({
|
|
|
1057
1085
|
if (!error2.message.includes("offline") && !error2.message.includes("Network")) {
|
|
1058
1086
|
await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
|
|
1059
1087
|
await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
|
|
1060
|
-
|
|
1061
|
-
|
|
1088
|
+
clearCookie("basic_token");
|
|
1089
|
+
clearCookie("basic_access_token");
|
|
1062
1090
|
setUser({});
|
|
1063
1091
|
setIsSignedIn(false);
|
|
1064
1092
|
setToken(null);
|
|
@@ -1067,35 +1095,6 @@ function BasicProvider({
|
|
|
1067
1095
|
throw error2;
|
|
1068
1096
|
}
|
|
1069
1097
|
};
|
|
1070
|
-
const db_ = (tableName) => {
|
|
1071
|
-
const checkSignIn = () => {
|
|
1072
|
-
if (!isSignedIn) {
|
|
1073
|
-
throw new Error("cannot use db. user not logged in.");
|
|
1074
|
-
}
|
|
1075
|
-
};
|
|
1076
|
-
return {
|
|
1077
|
-
get: async () => {
|
|
1078
|
-
checkSignIn();
|
|
1079
|
-
const tok = await getToken();
|
|
1080
|
-
return get({ projectId: project_id, accountId: user.id, tableName, token: tok });
|
|
1081
|
-
},
|
|
1082
|
-
add: async (value) => {
|
|
1083
|
-
checkSignIn();
|
|
1084
|
-
const tok = await getToken();
|
|
1085
|
-
return add({ projectId: project_id, accountId: user.id, tableName, value, token: tok });
|
|
1086
|
-
},
|
|
1087
|
-
update: async (id, value) => {
|
|
1088
|
-
checkSignIn();
|
|
1089
|
-
const tok = await getToken();
|
|
1090
|
-
return update({ projectId: project_id, accountId: user.id, tableName, id, value, token: tok });
|
|
1091
|
-
},
|
|
1092
|
-
delete: async (id) => {
|
|
1093
|
-
checkSignIn();
|
|
1094
|
-
const tok = await getToken();
|
|
1095
|
-
return deleteRecord({ projectId: project_id, accountId: user.id, tableName, id, token: tok });
|
|
1096
|
-
}
|
|
1097
|
-
};
|
|
1098
|
-
};
|
|
1099
1098
|
const noDb = {
|
|
1100
1099
|
collection: () => {
|
|
1101
1100
|
throw new Error("no basicdb found - initialization failed. double check your schema.");
|
|
@@ -1114,7 +1113,7 @@ function BasicProvider({
|
|
|
1114
1113
|
db: syncRef.current ? syncRef.current : noDb,
|
|
1115
1114
|
dbStatus
|
|
1116
1115
|
}, children: [
|
|
1117
|
-
error &&
|
|
1116
|
+
error && isDevMode() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorDisplay, { error }),
|
|
1118
1117
|
isReady && children
|
|
1119
1118
|
] });
|
|
1120
1119
|
}
|