@koolbase/core 10.0.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 +19 -0
- package/dist/cjs/analytics.d.ts +24 -0
- package/dist/cjs/analytics.js +110 -0
- package/dist/cjs/auth-errors.d.ts +117 -0
- package/dist/cjs/auth-errors.js +250 -0
- package/dist/cjs/auth.d.ts +213 -0
- package/dist/cjs/auth.js +813 -0
- package/dist/cjs/cache-store.d.ts +50 -0
- package/dist/cjs/cache-store.js +194 -0
- package/dist/cjs/conflict.d.ts +80 -0
- package/dist/cjs/conflict.js +84 -0
- package/dist/cjs/database-errors.d.ts +101 -0
- package/dist/cjs/database-errors.js +200 -0
- package/dist/cjs/database.d.ts +298 -0
- package/dist/cjs/database.js +852 -0
- package/dist/cjs/device-id.d.ts +1 -0
- package/dist/cjs/device-id.js +57 -0
- package/dist/cjs/device-metadata.d.ts +36 -0
- package/dist/cjs/device-metadata.js +94 -0
- package/dist/cjs/errors.d.ts +64 -0
- package/dist/cjs/errors.js +85 -0
- package/dist/cjs/flags.d.ts +15 -0
- package/dist/cjs/flags.js +76 -0
- package/dist/cjs/function-errors.d.ts +51 -0
- package/dist/cjs/function-errors.js +103 -0
- package/dist/cjs/functions.d.ts +15 -0
- package/dist/cjs/functions.js +83 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.js +56 -0
- package/dist/cjs/messaging.d.ts +13 -0
- package/dist/cjs/messaging.js +36 -0
- package/dist/cjs/offline-state.d.ts +97 -0
- package/dist/cjs/offline-state.js +198 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/pending-write.d.ts +47 -0
- package/dist/cjs/pending-write.js +22 -0
- package/dist/cjs/platform.d.ts +51 -0
- package/dist/cjs/platform.js +41 -0
- package/dist/cjs/realtime.d.ts +44 -0
- package/dist/cjs/realtime.js +195 -0
- package/dist/cjs/record.d.ts +2 -0
- package/dist/cjs/record.js +23 -0
- package/dist/cjs/shared.d.ts +9 -0
- package/dist/cjs/shared.js +43 -0
- package/dist/cjs/storage-errors.d.ts +163 -0
- package/dist/cjs/storage-errors.js +253 -0
- package/dist/cjs/storage.d.ts +198 -0
- package/dist/cjs/storage.js +451 -0
- package/dist/cjs/sync-engine.d.ts +30 -0
- package/dist/cjs/sync-engine.js +286 -0
- package/dist/cjs/types.d.ts +487 -0
- package/dist/cjs/types.js +40 -0
- package/dist/esm/analytics.d.ts +24 -0
- package/dist/esm/analytics.js +106 -0
- package/dist/esm/auth-errors.d.ts +117 -0
- package/dist/esm/auth-errors.js +222 -0
- package/dist/esm/auth.d.ts +213 -0
- package/dist/esm/auth.js +809 -0
- package/dist/esm/cache-store.d.ts +50 -0
- package/dist/esm/cache-store.js +179 -0
- package/dist/esm/conflict.d.ts +80 -0
- package/dist/esm/conflict.js +80 -0
- package/dist/esm/database-errors.d.ts +101 -0
- package/dist/esm/database-errors.js +189 -0
- package/dist/esm/database.d.ts +298 -0
- package/dist/esm/database.js +848 -0
- package/dist/esm/device-id.d.ts +1 -0
- package/dist/esm/device-id.js +54 -0
- package/dist/esm/device-metadata.d.ts +36 -0
- package/dist/esm/device-metadata.js +90 -0
- package/dist/esm/errors.d.ts +64 -0
- package/dist/esm/errors.js +79 -0
- package/dist/esm/flags.d.ts +15 -0
- package/dist/esm/flags.js +72 -0
- package/dist/esm/function-errors.d.ts +51 -0
- package/dist/esm/function-errors.js +93 -0
- package/dist/esm/functions.d.ts +15 -0
- package/dist/esm/functions.js +79 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.js +25 -0
- package/dist/esm/messaging.d.ts +13 -0
- package/dist/esm/messaging.js +32 -0
- package/dist/esm/offline-state.d.ts +97 -0
- package/dist/esm/offline-state.js +189 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/pending-write.d.ts +47 -0
- package/dist/esm/pending-write.js +19 -0
- package/dist/esm/platform.d.ts +51 -0
- package/dist/esm/platform.js +36 -0
- package/dist/esm/realtime.d.ts +44 -0
- package/dist/esm/realtime.js +191 -0
- package/dist/esm/record.d.ts +2 -0
- package/dist/esm/record.js +20 -0
- package/dist/esm/shared.d.ts +9 -0
- package/dist/esm/shared.js +39 -0
- package/dist/esm/storage-errors.d.ts +163 -0
- package/dist/esm/storage-errors.js +239 -0
- package/dist/esm/storage.d.ts +198 -0
- package/dist/esm/storage.js +447 -0
- package/dist/esm/sync-engine.d.ts +30 -0
- package/dist/esm/sync-engine.js +282 -0
- package/dist/esm/types.d.ts +487 -0
- package/dist/esm/types.js +37 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @koolbase/core
|
|
2
|
+
|
|
3
|
+
The shared behaviour behind Koolbase's client SDKs. **Install a platform package,
|
|
4
|
+
not this one:**
|
|
5
|
+
|
|
6
|
+
- Browser — [`@koolbase/js`](https://www.npmjs.com/package/@koolbase/js)
|
|
7
|
+
- React Native — [`@koolbase/react-native`](https://www.npmjs.com/package/@koolbase/react-native)
|
|
8
|
+
|
|
9
|
+
Each of those depends on this package and composes it with a platform adapter
|
|
10
|
+
for its host: storage, connectivity, lifecycle, and session persistence. The
|
|
11
|
+
auth logic, database client, offline write queue, conflict resolution,
|
|
12
|
+
realtime, storage and functions clients all live here, once, and are proven by
|
|
13
|
+
one test suite run against every adapter.
|
|
14
|
+
|
|
15
|
+
This package has no runtime dependencies and makes no assumptions about its
|
|
16
|
+
host. If you are building a Koolbase SDK for a new platform, the
|
|
17
|
+
`PlatformAdapter` interface in `src/platform.ts` is the contract.
|
|
18
|
+
|
|
19
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { KoolbaseConfig } from './types.js';
|
|
2
|
+
export declare class KoolbaseAnalytics {
|
|
3
|
+
private config;
|
|
4
|
+
private queue;
|
|
5
|
+
private deviceId;
|
|
6
|
+
private userId?;
|
|
7
|
+
private environmentId?;
|
|
8
|
+
private userProperties;
|
|
9
|
+
private sessionId;
|
|
10
|
+
private appVersion;
|
|
11
|
+
private flushTimer?;
|
|
12
|
+
private initialized;
|
|
13
|
+
constructor(config: KoolbaseConfig);
|
|
14
|
+
init(appVersion?: string): Promise<void>;
|
|
15
|
+
track(eventName: string, properties?: Record<string, unknown>): void;
|
|
16
|
+
screenView(screenName: string, properties?: Record<string, unknown>): void;
|
|
17
|
+
identify(userId: string): void;
|
|
18
|
+
setUserProperty(key: string, value: unknown): void;
|
|
19
|
+
setUserProperties(properties: Record<string, unknown>): void;
|
|
20
|
+
setEnvironment(environmentId: string): void;
|
|
21
|
+
reset(): void;
|
|
22
|
+
flush(): Promise<void>;
|
|
23
|
+
dispose(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KoolbaseAnalytics = void 0;
|
|
4
|
+
const platform_js_1 = require("./platform.js");
|
|
5
|
+
const device_id_js_1 = require("./device-id.js");
|
|
6
|
+
// ─── KoolbaseAnalytics ───────────────────────────────────────────────────────
|
|
7
|
+
const SDK_VERSION = '1.3.0';
|
|
8
|
+
const DEVICE_ID_KEY = 'koolbase:device_id';
|
|
9
|
+
const FLUSH_INTERVAL_MS = 30000;
|
|
10
|
+
const MAX_BATCH_SIZE = 20;
|
|
11
|
+
class KoolbaseAnalytics {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.queue = [];
|
|
14
|
+
this.deviceId = '';
|
|
15
|
+
this.userProperties = {};
|
|
16
|
+
this.sessionId = '';
|
|
17
|
+
this.appVersion = '1.0.0';
|
|
18
|
+
this.initialized = false;
|
|
19
|
+
this.config = config;
|
|
20
|
+
}
|
|
21
|
+
// ─── Init ─────────────────────────────────────────────────────────────────
|
|
22
|
+
async init(appVersion) {
|
|
23
|
+
if (this.initialized)
|
|
24
|
+
return;
|
|
25
|
+
this.deviceId = await (0, device_id_js_1.getOrCreateDeviceId)();
|
|
26
|
+
this.sessionId = `${this.deviceId}-${Date.now()}`;
|
|
27
|
+
this.appVersion = appVersion ?? '1.0.0';
|
|
28
|
+
// Auto flush on app background
|
|
29
|
+
(0, platform_js_1.getPlatform)().lifecycle.onBackground(() => { this.flush(); });
|
|
30
|
+
// Periodic flush
|
|
31
|
+
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
32
|
+
// Auto track app_open
|
|
33
|
+
this.track('app_open');
|
|
34
|
+
this.initialized = true;
|
|
35
|
+
}
|
|
36
|
+
// ─── Public API ───────────────────────────────────────────────────────────
|
|
37
|
+
track(eventName, properties) {
|
|
38
|
+
const event = {
|
|
39
|
+
device_id: this.deviceId,
|
|
40
|
+
user_id: this.userId,
|
|
41
|
+
environment_id: this.environmentId,
|
|
42
|
+
event_name: eventName,
|
|
43
|
+
properties: properties ?? {},
|
|
44
|
+
user_properties: { ...this.userProperties },
|
|
45
|
+
platform: (0, platform_js_1.getPlatform)().info.os,
|
|
46
|
+
app_version: this.appVersion,
|
|
47
|
+
sdk_version: SDK_VERSION,
|
|
48
|
+
session_id: this.sessionId,
|
|
49
|
+
occurred_at: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
this.queue.push(event);
|
|
52
|
+
if (this.queue.length >= MAX_BATCH_SIZE) {
|
|
53
|
+
this.flush();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
screenView(screenName, properties) {
|
|
57
|
+
this.track('screen_view', {
|
|
58
|
+
screen_name: screenName,
|
|
59
|
+
...properties,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
identify(userId) {
|
|
63
|
+
this.userId = userId;
|
|
64
|
+
}
|
|
65
|
+
setUserProperty(key, value) {
|
|
66
|
+
this.userProperties[key] = value;
|
|
67
|
+
}
|
|
68
|
+
setUserProperties(properties) {
|
|
69
|
+
Object.assign(this.userProperties, properties);
|
|
70
|
+
}
|
|
71
|
+
setEnvironment(environmentId) {
|
|
72
|
+
this.environmentId = environmentId;
|
|
73
|
+
}
|
|
74
|
+
reset() {
|
|
75
|
+
this.userId = undefined;
|
|
76
|
+
this.userProperties = {};
|
|
77
|
+
}
|
|
78
|
+
// ─── Flush ────────────────────────────────────────────────────────────────
|
|
79
|
+
async flush() {
|
|
80
|
+
if (this.queue.length === 0)
|
|
81
|
+
return;
|
|
82
|
+
const batch = [...this.queue];
|
|
83
|
+
this.queue = [];
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch(`${this.config.baseUrl}/v1/analytics/events`, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
'x-api-key': this.config.publicKey,
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({ events: batch }),
|
|
92
|
+
});
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
// Re-queue on failure
|
|
95
|
+
this.queue.unshift(...batch.slice(0, MAX_BATCH_SIZE - this.queue.length));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Re-queue on network error
|
|
100
|
+
this.queue.unshift(...batch.slice(0, MAX_BATCH_SIZE - this.queue.length));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async dispose() {
|
|
104
|
+
if (this.flushTimer)
|
|
105
|
+
clearInterval(this.flushTimer);
|
|
106
|
+
this.track('session_end');
|
|
107
|
+
await this.flush();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.KoolbaseAnalytics = KoolbaseAnalytics;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { KoolbaseError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base error type for all Koolbase auth errors. Catchable via
|
|
4
|
+
* `instanceof KoolbaseAuthError` to handle any auth-related failure
|
|
5
|
+
* generically; subclasses let you handle specific cases.
|
|
6
|
+
*/
|
|
7
|
+
export declare class KoolbaseAuthError extends KoolbaseError {
|
|
8
|
+
constructor(message: string, code?: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class InvalidCredentialsError extends KoolbaseAuthError {
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
13
|
+
export declare class EmailAlreadyInUseError extends KoolbaseAuthError {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
export declare class UserDisabledError extends KoolbaseAuthError {
|
|
17
|
+
constructor();
|
|
18
|
+
}
|
|
19
|
+
export declare class WeakPasswordError extends KoolbaseAuthError {
|
|
20
|
+
constructor();
|
|
21
|
+
}
|
|
22
|
+
export declare class SessionExpiredError extends KoolbaseAuthError {
|
|
23
|
+
constructor();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Thrown when the access token references a session that has been revoked
|
|
27
|
+
* centrally — either by the user (sessions endpoint) or an administrator.
|
|
28
|
+
* Distinct from {@link SessionExpiredError} which indicates the access
|
|
29
|
+
* token TTL elapsed without a successful refresh.
|
|
30
|
+
*
|
|
31
|
+
* Forward-compatible: matches multiple server message patterns so it stays
|
|
32
|
+
* accurate as the server's revocation signaling evolves.
|
|
33
|
+
*/
|
|
34
|
+
export declare class TokenRevokedError extends KoolbaseAuthError {
|
|
35
|
+
constructor();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thrown when the account is temporarily locked due to too many failed
|
|
39
|
+
* login attempts. The server uses progressive 5/10/20-attempt lockouts;
|
|
40
|
+
* if an unlock email was issued (level 2+), the user can clear the lock
|
|
41
|
+
* by passing that token to {@link KoolbaseAuth.unlock}.
|
|
42
|
+
*
|
|
43
|
+
* [lockedUntil] is currently null — the server returns a generic 429 but
|
|
44
|
+
* does not yet include the unlock timestamp in the response body. Field
|
|
45
|
+
* is forward-compatible for when the server adds it.
|
|
46
|
+
*/
|
|
47
|
+
export declare class AccountLockedError extends KoolbaseAuthError {
|
|
48
|
+
lockedUntil?: Date;
|
|
49
|
+
constructor(lockedUntil?: Date);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Thrown when the unlock token from a brute-force unlock email is
|
|
53
|
+
* invalid, expired, or already consumed. Unlock tokens are one-shot.
|
|
54
|
+
*/
|
|
55
|
+
export declare class UnlockTokenInvalidError extends KoolbaseAuthError {
|
|
56
|
+
constructor();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Thrown when the server rate-limits a non-phone authentication endpoint
|
|
60
|
+
* (HTTP 429 without the "account temporarily locked" marker). Phone OTP
|
|
61
|
+
* endpoints throw {@link OtpRateLimitError} instead — they hit a
|
|
62
|
+
* separate server-side rate-limiter.
|
|
63
|
+
*/
|
|
64
|
+
export declare class RateLimitError extends KoolbaseAuthError {
|
|
65
|
+
constructor(message?: string);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generic network error. The SDK does NOT throw this directly — fetch
|
|
69
|
+
* failures (DNS, no connection, timeout) propagate as native TypeErrors.
|
|
70
|
+
* This class exists for consumer code that wants to construct or
|
|
71
|
+
* `instanceof`-check a typed network error from their own retry logic.
|
|
72
|
+
*/
|
|
73
|
+
export declare class NetworkError extends KoolbaseAuthError {
|
|
74
|
+
constructor();
|
|
75
|
+
}
|
|
76
|
+
export declare class InvalidPhoneNumberError extends KoolbaseAuthError {
|
|
77
|
+
constructor();
|
|
78
|
+
}
|
|
79
|
+
export declare class OtpExpiredError extends KoolbaseAuthError {
|
|
80
|
+
constructor();
|
|
81
|
+
}
|
|
82
|
+
export declare class OtpInvalidError extends KoolbaseAuthError {
|
|
83
|
+
constructor();
|
|
84
|
+
}
|
|
85
|
+
export declare class OtpMaxAttemptsError extends KoolbaseAuthError {
|
|
86
|
+
constructor();
|
|
87
|
+
}
|
|
88
|
+
export declare class OtpRateLimitError extends KoolbaseAuthError {
|
|
89
|
+
constructor();
|
|
90
|
+
}
|
|
91
|
+
export declare class PhoneAlreadyLinkedError extends KoolbaseAuthError {
|
|
92
|
+
constructor();
|
|
93
|
+
}
|
|
94
|
+
export declare class SmsConfigMissingError extends KoolbaseAuthError {
|
|
95
|
+
constructor();
|
|
96
|
+
}
|
|
97
|
+
export declare class AppleSignInNotConfiguredError extends KoolbaseAuthError {
|
|
98
|
+
constructor();
|
|
99
|
+
}
|
|
100
|
+
export declare class InvalidAppleTokenError extends KoolbaseAuthError {
|
|
101
|
+
constructor();
|
|
102
|
+
}
|
|
103
|
+
export declare class AppleEmailRequiredError extends KoolbaseAuthError {
|
|
104
|
+
constructor();
|
|
105
|
+
}
|
|
106
|
+
export declare class OAuthEmailConflictError extends KoolbaseAuthError {
|
|
107
|
+
constructor();
|
|
108
|
+
}
|
|
109
|
+
export declare class GoogleSignInNotConfiguredError extends KoolbaseAuthError {
|
|
110
|
+
constructor();
|
|
111
|
+
}
|
|
112
|
+
export declare class InvalidGoogleTokenError extends KoolbaseAuthError {
|
|
113
|
+
constructor();
|
|
114
|
+
}
|
|
115
|
+
export declare class GoogleEmailRequiredError extends KoolbaseAuthError {
|
|
116
|
+
constructor();
|
|
117
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoogleEmailRequiredError = exports.InvalidGoogleTokenError = exports.GoogleSignInNotConfiguredError = exports.OAuthEmailConflictError = exports.AppleEmailRequiredError = exports.InvalidAppleTokenError = exports.AppleSignInNotConfiguredError = exports.SmsConfigMissingError = exports.PhoneAlreadyLinkedError = exports.OtpRateLimitError = exports.OtpMaxAttemptsError = exports.OtpInvalidError = exports.OtpExpiredError = exports.InvalidPhoneNumberError = exports.NetworkError = exports.RateLimitError = exports.UnlockTokenInvalidError = exports.AccountLockedError = exports.TokenRevokedError = exports.SessionExpiredError = exports.WeakPasswordError = exports.UserDisabledError = exports.EmailAlreadyInUseError = exports.InvalidCredentialsError = exports.KoolbaseAuthError = void 0;
|
|
4
|
+
const errors_js_1 = require("./errors.js");
|
|
5
|
+
/**
|
|
6
|
+
* Base error type for all Koolbase auth errors. Catchable via
|
|
7
|
+
* `instanceof KoolbaseAuthError` to handle any auth-related failure
|
|
8
|
+
* generically; subclasses let you handle specific cases.
|
|
9
|
+
*/
|
|
10
|
+
class KoolbaseAuthError extends errors_js_1.KoolbaseError {
|
|
11
|
+
constructor(message, code) {
|
|
12
|
+
super(message, code);
|
|
13
|
+
this.name = 'KoolbaseAuthError';
|
|
14
|
+
Object.setPrototypeOf(this, KoolbaseAuthError.prototype);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.KoolbaseAuthError = KoolbaseAuthError;
|
|
18
|
+
// ─── Credentials / Registration ────────────────────────────────────────────
|
|
19
|
+
class InvalidCredentialsError extends KoolbaseAuthError {
|
|
20
|
+
constructor() {
|
|
21
|
+
super('Invalid email or password', 'invalid_credentials');
|
|
22
|
+
this.name = 'InvalidCredentialsError';
|
|
23
|
+
Object.setPrototypeOf(this, InvalidCredentialsError.prototype);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.InvalidCredentialsError = InvalidCredentialsError;
|
|
27
|
+
class EmailAlreadyInUseError extends KoolbaseAuthError {
|
|
28
|
+
constructor() {
|
|
29
|
+
super('Email is already in use', 'email_taken');
|
|
30
|
+
this.name = 'EmailAlreadyInUseError';
|
|
31
|
+
Object.setPrototypeOf(this, EmailAlreadyInUseError.prototype);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.EmailAlreadyInUseError = EmailAlreadyInUseError;
|
|
35
|
+
class UserDisabledError extends KoolbaseAuthError {
|
|
36
|
+
constructor() {
|
|
37
|
+
super('This account has been disabled', 'user_disabled');
|
|
38
|
+
this.name = 'UserDisabledError';
|
|
39
|
+
Object.setPrototypeOf(this, UserDisabledError.prototype);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.UserDisabledError = UserDisabledError;
|
|
43
|
+
class WeakPasswordError extends KoolbaseAuthError {
|
|
44
|
+
constructor() {
|
|
45
|
+
super('Password must be at least 8 characters', 'weak_password');
|
|
46
|
+
this.name = 'WeakPasswordError';
|
|
47
|
+
Object.setPrototypeOf(this, WeakPasswordError.prototype);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.WeakPasswordError = WeakPasswordError;
|
|
51
|
+
// ─── Session lifecycle ─────────────────────────────────────────────────────
|
|
52
|
+
class SessionExpiredError extends KoolbaseAuthError {
|
|
53
|
+
constructor() {
|
|
54
|
+
super('Session expired, please log in again', 'session_expired');
|
|
55
|
+
this.name = 'SessionExpiredError';
|
|
56
|
+
Object.setPrototypeOf(this, SessionExpiredError.prototype);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.SessionExpiredError = SessionExpiredError;
|
|
60
|
+
/**
|
|
61
|
+
* Thrown when the access token references a session that has been revoked
|
|
62
|
+
* centrally — either by the user (sessions endpoint) or an administrator.
|
|
63
|
+
* Distinct from {@link SessionExpiredError} which indicates the access
|
|
64
|
+
* token TTL elapsed without a successful refresh.
|
|
65
|
+
*
|
|
66
|
+
* Forward-compatible: matches multiple server message patterns so it stays
|
|
67
|
+
* accurate as the server's revocation signaling evolves.
|
|
68
|
+
*/
|
|
69
|
+
class TokenRevokedError extends KoolbaseAuthError {
|
|
70
|
+
constructor() {
|
|
71
|
+
super('Session has been revoked, please log in again', 'token_revoked');
|
|
72
|
+
this.name = 'TokenRevokedError';
|
|
73
|
+
Object.setPrototypeOf(this, TokenRevokedError.prototype);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.TokenRevokedError = TokenRevokedError;
|
|
77
|
+
// ─── Brute-force protection ────────────────────────────────────────────────
|
|
78
|
+
/**
|
|
79
|
+
* Thrown when the account is temporarily locked due to too many failed
|
|
80
|
+
* login attempts. The server uses progressive 5/10/20-attempt lockouts;
|
|
81
|
+
* if an unlock email was issued (level 2+), the user can clear the lock
|
|
82
|
+
* by passing that token to {@link KoolbaseAuth.unlock}.
|
|
83
|
+
*
|
|
84
|
+
* [lockedUntil] is currently null — the server returns a generic 429 but
|
|
85
|
+
* does not yet include the unlock timestamp in the response body. Field
|
|
86
|
+
* is forward-compatible for when the server adds it.
|
|
87
|
+
*/
|
|
88
|
+
class AccountLockedError extends KoolbaseAuthError {
|
|
89
|
+
constructor(lockedUntil) {
|
|
90
|
+
super('Account temporarily locked due to too many failed attempts', 'account_locked');
|
|
91
|
+
this.lockedUntil = lockedUntil;
|
|
92
|
+
this.name = 'AccountLockedError';
|
|
93
|
+
Object.setPrototypeOf(this, AccountLockedError.prototype);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.AccountLockedError = AccountLockedError;
|
|
97
|
+
/**
|
|
98
|
+
* Thrown when the unlock token from a brute-force unlock email is
|
|
99
|
+
* invalid, expired, or already consumed. Unlock tokens are one-shot.
|
|
100
|
+
*/
|
|
101
|
+
class UnlockTokenInvalidError extends KoolbaseAuthError {
|
|
102
|
+
constructor() {
|
|
103
|
+
super('Unlock link is invalid or has expired', 'unlock_token_invalid');
|
|
104
|
+
this.name = 'UnlockTokenInvalidError';
|
|
105
|
+
Object.setPrototypeOf(this, UnlockTokenInvalidError.prototype);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.UnlockTokenInvalidError = UnlockTokenInvalidError;
|
|
109
|
+
/**
|
|
110
|
+
* Thrown when the server rate-limits a non-phone authentication endpoint
|
|
111
|
+
* (HTTP 429 without the "account temporarily locked" marker). Phone OTP
|
|
112
|
+
* endpoints throw {@link OtpRateLimitError} instead — they hit a
|
|
113
|
+
* separate server-side rate-limiter.
|
|
114
|
+
*/
|
|
115
|
+
class RateLimitError extends KoolbaseAuthError {
|
|
116
|
+
constructor(message) {
|
|
117
|
+
super(message ?? 'Too many requests, please wait before trying again', 'rate_limit');
|
|
118
|
+
this.name = 'RateLimitError';
|
|
119
|
+
Object.setPrototypeOf(this, RateLimitError.prototype);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.RateLimitError = RateLimitError;
|
|
123
|
+
// ─── Network ───────────────────────────────────────────────────────────────
|
|
124
|
+
/**
|
|
125
|
+
* Generic network error. The SDK does NOT throw this directly — fetch
|
|
126
|
+
* failures (DNS, no connection, timeout) propagate as native TypeErrors.
|
|
127
|
+
* This class exists for consumer code that wants to construct or
|
|
128
|
+
* `instanceof`-check a typed network error from their own retry logic.
|
|
129
|
+
*/
|
|
130
|
+
class NetworkError extends KoolbaseAuthError {
|
|
131
|
+
constructor() {
|
|
132
|
+
super('Network error, please check your connection', 'network_error');
|
|
133
|
+
this.name = 'NetworkError';
|
|
134
|
+
Object.setPrototypeOf(this, NetworkError.prototype);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.NetworkError = NetworkError;
|
|
138
|
+
// ─── Phone OTP (unchanged from earlier releases) ───────────────────────────
|
|
139
|
+
class InvalidPhoneNumberError extends KoolbaseAuthError {
|
|
140
|
+
constructor() {
|
|
141
|
+
super('Phone number must be in E.164 format (e.g. +233XXXXXXXXX)', 'invalid_phone');
|
|
142
|
+
this.name = 'InvalidPhoneNumberError';
|
|
143
|
+
Object.setPrototypeOf(this, InvalidPhoneNumberError.prototype);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.InvalidPhoneNumberError = InvalidPhoneNumberError;
|
|
147
|
+
class OtpExpiredError extends KoolbaseAuthError {
|
|
148
|
+
constructor() {
|
|
149
|
+
super('OTP has expired, please request a new code', 'otp_expired');
|
|
150
|
+
this.name = 'OtpExpiredError';
|
|
151
|
+
Object.setPrototypeOf(this, OtpExpiredError.prototype);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.OtpExpiredError = OtpExpiredError;
|
|
155
|
+
class OtpInvalidError extends KoolbaseAuthError {
|
|
156
|
+
constructor() {
|
|
157
|
+
super('Invalid OTP code', 'otp_invalid');
|
|
158
|
+
this.name = 'OtpInvalidError';
|
|
159
|
+
Object.setPrototypeOf(this, OtpInvalidError.prototype);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.OtpInvalidError = OtpInvalidError;
|
|
163
|
+
class OtpMaxAttemptsError extends KoolbaseAuthError {
|
|
164
|
+
constructor() {
|
|
165
|
+
super('Too many incorrect attempts, please request a new code', 'otp_max_attempts');
|
|
166
|
+
this.name = 'OtpMaxAttemptsError';
|
|
167
|
+
Object.setPrototypeOf(this, OtpMaxAttemptsError.prototype);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.OtpMaxAttemptsError = OtpMaxAttemptsError;
|
|
171
|
+
class OtpRateLimitError extends KoolbaseAuthError {
|
|
172
|
+
constructor() {
|
|
173
|
+
super('Too many OTP requests, please wait before trying again', 'otp_rate_limit');
|
|
174
|
+
this.name = 'OtpRateLimitError';
|
|
175
|
+
Object.setPrototypeOf(this, OtpRateLimitError.prototype);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.OtpRateLimitError = OtpRateLimitError;
|
|
179
|
+
class PhoneAlreadyLinkedError extends KoolbaseAuthError {
|
|
180
|
+
constructor() {
|
|
181
|
+
super('Phone number is already associated with another account', 'phone_taken');
|
|
182
|
+
this.name = 'PhoneAlreadyLinkedError';
|
|
183
|
+
Object.setPrototypeOf(this, PhoneAlreadyLinkedError.prototype);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.PhoneAlreadyLinkedError = PhoneAlreadyLinkedError;
|
|
187
|
+
class SmsConfigMissingError extends KoolbaseAuthError {
|
|
188
|
+
constructor() {
|
|
189
|
+
super('SMS provider not configured for this project', 'sms_config_missing');
|
|
190
|
+
this.name = 'SmsConfigMissingError';
|
|
191
|
+
Object.setPrototypeOf(this, SmsConfigMissingError.prototype);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.SmsConfigMissingError = SmsConfigMissingError;
|
|
195
|
+
class AppleSignInNotConfiguredError extends KoolbaseAuthError {
|
|
196
|
+
constructor() {
|
|
197
|
+
super('Apple Sign-In is not configured for this environment', 'apple_not_configured');
|
|
198
|
+
this.name = 'AppleSignInNotConfiguredError';
|
|
199
|
+
Object.setPrototypeOf(this, AppleSignInNotConfiguredError.prototype);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.AppleSignInNotConfiguredError = AppleSignInNotConfiguredError;
|
|
203
|
+
class InvalidAppleTokenError extends KoolbaseAuthError {
|
|
204
|
+
constructor() {
|
|
205
|
+
super('Invalid Apple identity token', 'invalid_apple_token');
|
|
206
|
+
this.name = 'InvalidAppleTokenError';
|
|
207
|
+
Object.setPrototypeOf(this, InvalidAppleTokenError.prototype);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.InvalidAppleTokenError = InvalidAppleTokenError;
|
|
211
|
+
class AppleEmailRequiredError extends KoolbaseAuthError {
|
|
212
|
+
constructor() {
|
|
213
|
+
super('Apple did not return email for this sign-in. Revoke this app in iOS Settings → Apple ID and retry.', 'apple_email_required');
|
|
214
|
+
this.name = 'AppleEmailRequiredError';
|
|
215
|
+
Object.setPrototypeOf(this, AppleEmailRequiredError.prototype);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.AppleEmailRequiredError = AppleEmailRequiredError;
|
|
219
|
+
class OAuthEmailConflictError extends KoolbaseAuthError {
|
|
220
|
+
constructor() {
|
|
221
|
+
super('Email is already in use by another account. Sign in with your existing method and link Apple from settings.', 'oauth_email_conflict');
|
|
222
|
+
this.name = 'OAuthEmailConflictError';
|
|
223
|
+
Object.setPrototypeOf(this, OAuthEmailConflictError.prototype);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
exports.OAuthEmailConflictError = OAuthEmailConflictError;
|
|
227
|
+
class GoogleSignInNotConfiguredError extends KoolbaseAuthError {
|
|
228
|
+
constructor() {
|
|
229
|
+
super('Google Sign-In is not configured for this environment', 'google_not_configured');
|
|
230
|
+
this.name = 'GoogleSignInNotConfiguredError';
|
|
231
|
+
Object.setPrototypeOf(this, GoogleSignInNotConfiguredError.prototype);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
exports.GoogleSignInNotConfiguredError = GoogleSignInNotConfiguredError;
|
|
235
|
+
class InvalidGoogleTokenError extends KoolbaseAuthError {
|
|
236
|
+
constructor() {
|
|
237
|
+
super('Invalid Google identity token', 'invalid_google_token');
|
|
238
|
+
this.name = 'InvalidGoogleTokenError';
|
|
239
|
+
Object.setPrototypeOf(this, InvalidGoogleTokenError.prototype);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
exports.InvalidGoogleTokenError = InvalidGoogleTokenError;
|
|
243
|
+
class GoogleEmailRequiredError extends KoolbaseAuthError {
|
|
244
|
+
constructor() {
|
|
245
|
+
super('Google did not return email for this sign-in. Ensure the email scope is requested in the native flow.', 'google_email_required');
|
|
246
|
+
this.name = 'GoogleEmailRequiredError';
|
|
247
|
+
Object.setPrototypeOf(this, GoogleEmailRequiredError.prototype);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.GoogleEmailRequiredError = GoogleEmailRequiredError;
|