@aurabase/core 0.5.2 → 0.5.4
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/dist/index.cjs +124 -25
- package/dist/index.d.cts +257 -12
- package/dist/index.d.ts +257 -12
- package/dist/index.js +124 -25
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5,15 +5,60 @@ var AuraError = class _AuraError extends Error {
|
|
|
5
5
|
status;
|
|
6
6
|
code;
|
|
7
7
|
details;
|
|
8
|
+
retryAfter;
|
|
8
9
|
/** Marqueur runtime pour `isAuraError` (détection cross-realm/cross-bundle). */
|
|
9
10
|
__isAuraError = true;
|
|
10
|
-
constructor(status, body) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
constructor(status, body, headers) {
|
|
12
|
+
let rawMessage = body?.error?.message ?? body?.message ?? (status === 429 ? "Trop de requ\xEAtes, veuillez patienter avant de r\xE9essayer." : `HTTP ${status}`);
|
|
13
|
+
let retryAfterSec;
|
|
14
|
+
if (headers) {
|
|
15
|
+
const getHeader = (name) => {
|
|
16
|
+
if (typeof headers.get === "function") {
|
|
17
|
+
return headers.get(name);
|
|
18
|
+
}
|
|
19
|
+
const record = headers;
|
|
20
|
+
return record[name] ?? record[name.toLowerCase()];
|
|
21
|
+
};
|
|
22
|
+
const ra = getHeader("retry-after") ?? getHeader("x-ratelimit-after");
|
|
23
|
+
if (ra) {
|
|
24
|
+
const sec = parseInt(ra, 10);
|
|
25
|
+
if (!isNaN(sec)) {
|
|
26
|
+
retryAfterSec = sec;
|
|
27
|
+
if (status === 429) {
|
|
28
|
+
rawMessage = `Trop de requ\xEAtes, veuillez patienter ${sec} seconde${sec > 1 ? "s" : ""} avant de r\xE9essayer.`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
super(rawMessage);
|
|
13
34
|
this.name = "AuraError";
|
|
14
35
|
this.status = status;
|
|
15
|
-
this.code = body?.error?.code ?? `http_${status}`;
|
|
16
36
|
this.details = body;
|
|
37
|
+
if (retryAfterSec !== void 0) {
|
|
38
|
+
this.retryAfter = retryAfterSec;
|
|
39
|
+
}
|
|
40
|
+
const rawCode = body?.error?.code;
|
|
41
|
+
const lowerMsg = rawMessage.toLowerCase();
|
|
42
|
+
const isGenericHttpCode = typeof rawCode !== "string" || rawCode === "UNAUTHORIZED" || rawCode === "BAD_REQUEST" || rawCode === "CONFLICT" || rawCode === "RATE_LIMITED" || rawCode.startsWith("http_");
|
|
43
|
+
if (!isGenericHttpCode) {
|
|
44
|
+
this.code = rawCode;
|
|
45
|
+
} else if (status === 429 || rawCode === "RATE_LIMITED" || rawCode === "http_429") {
|
|
46
|
+
this.code = "rate_limit_exceeded";
|
|
47
|
+
} else if (status === 401 && (lowerMsg.includes("identifiants") || lowerMsg.includes("credentials") || lowerMsg.includes("mot de passe incorrect"))) {
|
|
48
|
+
this.code = "invalid_credentials";
|
|
49
|
+
} else if (status === 401 && lowerMsg.includes("r\xE9voqu\xE9e")) {
|
|
50
|
+
this.code = "session_revoked";
|
|
51
|
+
} else if (status === 401 && lowerMsg.includes("expir\xE9")) {
|
|
52
|
+
this.code = "session_expired";
|
|
53
|
+
} else if (status === 400 && (lowerMsg.includes("mot de passe") || lowerMsg.includes("password"))) {
|
|
54
|
+
this.code = "weak_password";
|
|
55
|
+
} else if (status === 409 && (lowerMsg.includes("d\xE9j\xE0 utilis\xE9") || lowerMsg.includes("already exists") || lowerMsg.includes("already in use") || lowerMsg.includes("email"))) {
|
|
56
|
+
this.code = "email_already_in_use";
|
|
57
|
+
} else if (status === 404 && lowerMsg.includes("utilisateur")) {
|
|
58
|
+
this.code = "user_not_found";
|
|
59
|
+
} else {
|
|
60
|
+
this.code = rawCode ?? `http_${status}`;
|
|
61
|
+
}
|
|
17
62
|
Object.setPrototypeOf(this, _AuraError.prototype);
|
|
18
63
|
}
|
|
19
64
|
get isNotFound() {
|
|
@@ -300,6 +345,15 @@ function unwrapEnvelope(body) {
|
|
|
300
345
|
}
|
|
301
346
|
return body;
|
|
302
347
|
}
|
|
348
|
+
function parseContentRangeTotal(headerVal) {
|
|
349
|
+
if (!headerVal) return void 0;
|
|
350
|
+
const parts = headerVal.split("/");
|
|
351
|
+
if (parts.length === 2 && parts[1] !== "*") {
|
|
352
|
+
const n = parseInt(parts[1], 10);
|
|
353
|
+
if (!Number.isNaN(n)) return n;
|
|
354
|
+
}
|
|
355
|
+
return void 0;
|
|
356
|
+
}
|
|
303
357
|
async function readTextBounded(res, timeoutMs) {
|
|
304
358
|
const body = res.body;
|
|
305
359
|
if (!body || typeof body.getReader !== "function" || !(timeoutMs > 0)) {
|
|
@@ -648,11 +702,12 @@ async function fetchWithAuth(url, init, client) {
|
|
|
648
702
|
try {
|
|
649
703
|
body2 = JSON.parse(errRead.text);
|
|
650
704
|
} catch {
|
|
705
|
+
body2 = { message: errRead.text.trim() };
|
|
651
706
|
}
|
|
652
707
|
} else if (!errRead.ok && errRead.timedOut) {
|
|
653
708
|
emitAuraEvent(client.onEvent, client.debug, { kind: "timeout", url });
|
|
654
709
|
}
|
|
655
|
-
return { data: null, error: new AuraError(res.status, body2) };
|
|
710
|
+
return { data: null, error: new AuraError(res.status, body2, res.headers) };
|
|
656
711
|
}
|
|
657
712
|
const read = await readTextBounded(res, bodyTimeoutMs);
|
|
658
713
|
if (!read.ok) {
|
|
@@ -680,7 +735,11 @@ async function fetchWithAuth(url, init, client) {
|
|
|
680
735
|
}
|
|
681
736
|
const raw = read.text;
|
|
682
737
|
if (raw.trim() === "") {
|
|
683
|
-
|
|
738
|
+
const cr2 = res.headers.get("content-range") ?? res.headers.get("Content-Range");
|
|
739
|
+
const totalFromCr2 = parseContentRangeTotal(cr2);
|
|
740
|
+
const meta2 = totalFromCr2 !== void 0 ? { total: totalFromCr2 } : void 0;
|
|
741
|
+
const count2 = totalFromCr2 !== void 0 ? totalFromCr2 : null;
|
|
742
|
+
return { data: null, error: null, meta: meta2, count: count2 };
|
|
684
743
|
}
|
|
685
744
|
let body;
|
|
686
745
|
try {
|
|
@@ -699,11 +758,15 @@ async function fetchWithAuth(url, init, client) {
|
|
|
699
758
|
};
|
|
700
759
|
}
|
|
701
760
|
const unwrapped = unwrapEnvelope(body);
|
|
702
|
-
const
|
|
761
|
+
const cr = res.headers.get("content-range") ?? res.headers.get("Content-Range");
|
|
762
|
+
const totalFromCr = parseContentRangeTotal(cr);
|
|
763
|
+
const rawMeta = body !== null && typeof body === "object" && "meta" in body ? body.meta : void 0;
|
|
764
|
+
const meta = rawMeta !== void 0 ? rawMeta : totalFromCr !== void 0 ? { total: totalFromCr } : void 0;
|
|
765
|
+
const count = meta?.total !== void 0 ? meta.total : totalFromCr ?? null;
|
|
703
766
|
if (unwrapped === null) {
|
|
704
|
-
return { data: null, error: null, meta };
|
|
767
|
+
return { data: null, error: null, meta, count };
|
|
705
768
|
}
|
|
706
|
-
return { data: unwrapped, error: null, meta };
|
|
769
|
+
return { data: unwrapped, error: null, meta, count };
|
|
707
770
|
}
|
|
708
771
|
}
|
|
709
772
|
|
|
@@ -789,14 +852,15 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
789
852
|
* (`clientScope`, dérivée de l'URL du projet).
|
|
790
853
|
*/
|
|
791
854
|
_removePkceVerifiers() {
|
|
792
|
-
|
|
855
|
+
const storage = this._getStorage();
|
|
856
|
+
if (!storage) return;
|
|
793
857
|
try {
|
|
794
858
|
const toRemove = [];
|
|
795
|
-
for (let i = 0; i <
|
|
796
|
-
const k =
|
|
859
|
+
for (let i = 0; i < storage.length; i++) {
|
|
860
|
+
const k = storage.key(i);
|
|
797
861
|
if (k && /^aura-.*-(pkce-code-verifier|oauth-implicit-initiated)$/.test(k)) toRemove.push(k);
|
|
798
862
|
}
|
|
799
|
-
for (const k of toRemove)
|
|
863
|
+
for (const k of toRemove) storage.removeItem(k);
|
|
800
864
|
} catch {
|
|
801
865
|
this._emitStorageBlocked("removePkceVerifiers");
|
|
802
866
|
}
|
|
@@ -807,17 +871,19 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
807
871
|
// ne survivrait pas à ce cycle de navigation.
|
|
808
872
|
setItem(key, value) {
|
|
809
873
|
super.setItem(key, value);
|
|
810
|
-
|
|
874
|
+
const storage = this._getStorage();
|
|
875
|
+
if (!storage) return;
|
|
811
876
|
try {
|
|
812
|
-
|
|
877
|
+
storage.setItem(key, value);
|
|
813
878
|
} catch {
|
|
814
879
|
this._emitStorageBlocked("setItem");
|
|
815
880
|
}
|
|
816
881
|
}
|
|
817
882
|
getItem(key) {
|
|
818
|
-
|
|
883
|
+
const storage = this._getStorage();
|
|
884
|
+
if (!storage) return super.getItem(key);
|
|
819
885
|
try {
|
|
820
|
-
const v =
|
|
886
|
+
const v = storage.getItem(key);
|
|
821
887
|
if (v !== null) return v;
|
|
822
888
|
} catch {
|
|
823
889
|
this._emitStorageBlocked("getItem");
|
|
@@ -826,9 +892,10 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
826
892
|
}
|
|
827
893
|
removeItem(key) {
|
|
828
894
|
super.removeItem(key);
|
|
829
|
-
|
|
895
|
+
const storage = this._getStorage();
|
|
896
|
+
if (!storage) return;
|
|
830
897
|
try {
|
|
831
|
-
|
|
898
|
+
storage.removeItem(key);
|
|
832
899
|
} catch {
|
|
833
900
|
this._emitStorageBlocked("removeItem");
|
|
834
901
|
}
|
|
@@ -871,10 +938,40 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
871
938
|
return parts.join("; ");
|
|
872
939
|
}
|
|
873
940
|
// -- Private ----------------------------------------------------------------
|
|
941
|
+
_getStorage() {
|
|
942
|
+
if (typeof window !== "undefined" && typeof window.localStorage !== "undefined") {
|
|
943
|
+
return window.localStorage;
|
|
944
|
+
}
|
|
945
|
+
const g = globalThis;
|
|
946
|
+
if (typeof g !== "undefined") {
|
|
947
|
+
const proc = g.process;
|
|
948
|
+
if (typeof proc !== "undefined") {
|
|
949
|
+
const env = proc.env;
|
|
950
|
+
const isTest = !!(env?.VITEST || env?.NODE_ENV === "test" || env?.JEST_WORKER_ID);
|
|
951
|
+
const execArgv = proc.execArgv;
|
|
952
|
+
const hasFlag = Array.isArray(execArgv) && execArgv.some((a) => typeof a === "string" && a.startsWith("--localstorage-file"));
|
|
953
|
+
if (isTest || hasFlag) {
|
|
954
|
+
try {
|
|
955
|
+
const s = g.localStorage;
|
|
956
|
+
if (s && typeof s.getItem === "function") return s;
|
|
957
|
+
} catch {
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return null;
|
|
961
|
+
}
|
|
962
|
+
try {
|
|
963
|
+
const s = g.localStorage;
|
|
964
|
+
if (s && typeof s.getItem === "function") return s;
|
|
965
|
+
} catch {
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return null;
|
|
969
|
+
}
|
|
874
970
|
_loadFromStorage() {
|
|
875
|
-
|
|
971
|
+
const storage = this._getStorage();
|
|
972
|
+
if (!storage) return;
|
|
876
973
|
try {
|
|
877
|
-
const raw =
|
|
974
|
+
const raw = storage.getItem(this.key);
|
|
878
975
|
if (!raw) return;
|
|
879
976
|
const parsed = JSON.parse(raw);
|
|
880
977
|
if (parsed.token && parsed.refreshToken && parsed.user) {
|
|
@@ -885,22 +982,24 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
885
982
|
}
|
|
886
983
|
}
|
|
887
984
|
_persist() {
|
|
888
|
-
|
|
985
|
+
const storage = this._getStorage();
|
|
986
|
+
if (!storage) return;
|
|
889
987
|
const data = {
|
|
890
988
|
token: this.token,
|
|
891
989
|
refreshToken: this.refreshToken,
|
|
892
990
|
user: this.user
|
|
893
991
|
};
|
|
894
992
|
try {
|
|
895
|
-
|
|
993
|
+
storage.setItem(this.key, JSON.stringify(data));
|
|
896
994
|
} catch {
|
|
897
995
|
this._emitStorageBlocked("persist");
|
|
898
996
|
}
|
|
899
997
|
}
|
|
900
998
|
_removeStorage() {
|
|
901
|
-
|
|
999
|
+
const storage = this._getStorage();
|
|
1000
|
+
if (!storage) return;
|
|
902
1001
|
try {
|
|
903
|
-
|
|
1002
|
+
storage.removeItem(this.key);
|
|
904
1003
|
} catch {
|
|
905
1004
|
this._emitStorageBlocked("removeStorage");
|
|
906
1005
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
* - storage/path.ts : invalid_path
|
|
15
15
|
* - db/QueryBuilder.ts: PGRST116 (parité PostgREST : `.single()` sur 0/plusieurs lignes)
|
|
16
16
|
*/
|
|
17
|
-
type AuraErrorCode = 'no_session' | 'timeout' | 'network_error' | 'invalid_response' | 'refresh_discarded' | 'unverifiable_token' | 'no_code_verifier' | 'pkce_generation_failed' | 'missing_email' | 'jwks_fetch_failed' | 'signature_invalid' | 'token_expired' | 'token_not_yet_valid' | 'invalid_jwt' | 'unsupported_alg' | 'no_matching_key' | 'invalid_issuer' | 'invalid_audience' | 'invalid_path' | 'PGRST116' | (string & {});
|
|
17
|
+
type AuraErrorCode = 'no_session' | 'timeout' | 'network_error' | 'invalid_response' | 'refresh_discarded' | 'unverifiable_token' | 'no_code_verifier' | 'pkce_generation_failed' | 'missing_email' | 'jwks_fetch_failed' | 'signature_invalid' | 'token_expired' | 'token_not_yet_valid' | 'invalid_jwt' | 'unsupported_alg' | 'no_matching_key' | 'invalid_issuer' | 'invalid_audience' | 'invalid_path' | 'PGRST116' | 'invalid_credentials' | 'weak_password' | 'email_already_in_use' | 'user_not_found' | 'rate_limit_exceeded' | 'session_expired' | 'session_revoked' | (string & {});
|
|
18
18
|
/**
|
|
19
19
|
* Structured error thrown/returned by the Aurabase SDK.
|
|
20
|
-
* Mirrors the backend's `AuraError` JSON shape.
|
|
20
|
+
* Mirrors the backend's `AuraError` JSON shape with semantic DX normalization.
|
|
21
21
|
*/
|
|
22
22
|
declare class AuraError extends Error {
|
|
23
23
|
readonly status: number;
|
|
24
24
|
readonly code: AuraErrorCode;
|
|
25
25
|
readonly details: unknown;
|
|
26
|
+
readonly retryAfter?: number;
|
|
26
27
|
/** Marqueur runtime pour `isAuraError` (détection cross-realm/cross-bundle). */
|
|
27
28
|
protected readonly __isAuraError = true;
|
|
28
29
|
constructor(status: number, body?: {
|
|
@@ -31,7 +32,7 @@ declare class AuraError extends Error {
|
|
|
31
32
|
message?: string;
|
|
32
33
|
};
|
|
33
34
|
message?: string;
|
|
34
|
-
} | null);
|
|
35
|
+
} | null, headers?: Headers | Record<string, string | null | undefined>);
|
|
35
36
|
get isNotFound(): boolean;
|
|
36
37
|
get isUnauthorized(): boolean;
|
|
37
38
|
get isForbidden(): boolean;
|
|
@@ -93,6 +94,11 @@ interface AuraSuccess<T> {
|
|
|
93
94
|
data: T;
|
|
94
95
|
error: null;
|
|
95
96
|
meta?: Meta;
|
|
97
|
+
/**
|
|
98
|
+
* Nombre total de lignes correspondant à la requête (dérivé de meta.total).
|
|
99
|
+
* Renseigné quand un décompte explicite est demandé (.count('exact' | ...)).
|
|
100
|
+
*/
|
|
101
|
+
count?: number | null;
|
|
96
102
|
}
|
|
97
103
|
/**
|
|
98
104
|
* Réponse en SUCCÈS SANS contenu — `data` ET `error` nuls.
|
|
@@ -117,6 +123,10 @@ interface AuraNoContent {
|
|
|
117
123
|
data: null;
|
|
118
124
|
error: null;
|
|
119
125
|
meta?: Meta;
|
|
126
|
+
/**
|
|
127
|
+
* Nombre total de lignes (dérivé de meta.total).
|
|
128
|
+
*/
|
|
129
|
+
count?: number | null;
|
|
120
130
|
}
|
|
121
131
|
/**
|
|
122
132
|
* Réponse en ÉCHEC. `data` y est `null` par construction — aucun producteur du
|
|
@@ -126,6 +136,7 @@ interface AuraFailure {
|
|
|
126
136
|
data: null;
|
|
127
137
|
error: AuraError;
|
|
128
138
|
meta?: Meta;
|
|
139
|
+
count?: number | null;
|
|
129
140
|
}
|
|
130
141
|
/**
|
|
131
142
|
* Enveloppe de réponse du SDK : union à TROIS membres.
|
|
@@ -175,19 +186,47 @@ interface User {
|
|
|
175
186
|
created_at: string;
|
|
176
187
|
last_sign_in_at?: string | null;
|
|
177
188
|
}
|
|
189
|
+
interface Session {
|
|
190
|
+
access_token: string;
|
|
191
|
+
refresh_token: string;
|
|
192
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
193
|
+
accessToken?: string;
|
|
194
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
195
|
+
refreshToken?: string;
|
|
196
|
+
token_type: string;
|
|
197
|
+
expires_in: number;
|
|
198
|
+
expires_at?: number;
|
|
199
|
+
user: User;
|
|
200
|
+
provider_token?: string | null;
|
|
201
|
+
provider_refresh_token?: string | null;
|
|
202
|
+
}
|
|
178
203
|
interface TokenPair {
|
|
179
204
|
access_token: string;
|
|
180
205
|
refresh_token: string;
|
|
206
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
207
|
+
accessToken?: string;
|
|
208
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
209
|
+
refreshToken?: string;
|
|
181
210
|
token_type: string;
|
|
182
211
|
expires_in: number;
|
|
183
212
|
user: User;
|
|
184
213
|
provider_token?: string | null;
|
|
185
214
|
provider_refresh_token?: string | null;
|
|
215
|
+
/** Sous-objet session pour parité DX Supabase (`data.session.access_token`). */
|
|
216
|
+
session?: Session;
|
|
217
|
+
mfaChallenge?: undefined;
|
|
186
218
|
}
|
|
187
219
|
interface MfaChallenge {
|
|
188
220
|
mfa_required: true;
|
|
189
221
|
mfa_token: string;
|
|
190
222
|
mfa_setup_required?: boolean;
|
|
223
|
+
session?: undefined;
|
|
224
|
+
/** Alias ergonomique aligné sur la documentation officielle */
|
|
225
|
+
mfaChallenge?: {
|
|
226
|
+
mfaRequired: boolean;
|
|
227
|
+
mfaToken: string;
|
|
228
|
+
mfaSetupRequired?: boolean;
|
|
229
|
+
};
|
|
191
230
|
}
|
|
192
231
|
type LoginResponse = TokenPair | MfaChallenge;
|
|
193
232
|
type AuthEvent = 'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'MFA_CHALLENGE' | 'PASSWORD_RECOVERY';
|
|
@@ -204,6 +243,8 @@ interface AuthChangePayload {
|
|
|
204
243
|
event: AuthEvent;
|
|
205
244
|
user: User | null;
|
|
206
245
|
accessToken: string | null;
|
|
246
|
+
/** Session complète pour parité DX Supabase */
|
|
247
|
+
session?: Session | null;
|
|
207
248
|
/** Présent uniquement si `event === 'MFA_CHALLENGE'`. */
|
|
208
249
|
mfaToken?: string;
|
|
209
250
|
/** Présent uniquement si `event === 'MFA_CHALLENGE'`. */
|
|
@@ -674,6 +715,51 @@ interface CdcPayload {
|
|
|
674
715
|
record: Record<string, unknown>;
|
|
675
716
|
old_record: Record<string, unknown> | null;
|
|
676
717
|
_truncated?: boolean;
|
|
718
|
+
[key: string]: unknown;
|
|
719
|
+
}
|
|
720
|
+
/** Base commune des métadonnées pour un événement CDC PostgreSQL */
|
|
721
|
+
interface RealtimePostgresChangesBasePayload {
|
|
722
|
+
schema: string;
|
|
723
|
+
table: string;
|
|
724
|
+
commit_timestamp: string;
|
|
725
|
+
errors?: string[];
|
|
726
|
+
id: string;
|
|
727
|
+
topic: string;
|
|
728
|
+
timestamp: string;
|
|
729
|
+
payload: CdcPayload | Record<string, unknown>;
|
|
730
|
+
event: 'insert' | 'update' | 'delete';
|
|
731
|
+
}
|
|
732
|
+
/** Payload enrichi pour un événement CDC PostgreSQL d'insertion */
|
|
733
|
+
interface RealtimePostgresInsertPayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
734
|
+
eventType: 'INSERT';
|
|
735
|
+
event: 'insert';
|
|
736
|
+
new: T;
|
|
737
|
+
old: null;
|
|
738
|
+
}
|
|
739
|
+
/** Payload enrichi pour un événement CDC PostgreSQL de mise à jour */
|
|
740
|
+
interface RealtimePostgresUpdatePayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
741
|
+
eventType: 'UPDATE';
|
|
742
|
+
event: 'update';
|
|
743
|
+
new: T;
|
|
744
|
+
old: Partial<T>;
|
|
745
|
+
}
|
|
746
|
+
/** Payload enrichi pour un événement CDC PostgreSQL de suppression */
|
|
747
|
+
interface RealtimePostgresDeletePayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
748
|
+
eventType: 'DELETE';
|
|
749
|
+
event: 'delete';
|
|
750
|
+
new: null;
|
|
751
|
+
old: Partial<T> | null;
|
|
752
|
+
}
|
|
753
|
+
/** Union discriminée par eventType pour les événements CDC PostgreSQL */
|
|
754
|
+
type RealtimePostgresChangesPayload<T = Record<string, unknown>> = RealtimePostgresInsertPayload<T> | RealtimePostgresUpdatePayload<T> | RealtimePostgresDeletePayload<T>;
|
|
755
|
+
/** Événement broadcast reçu avec payload typé */
|
|
756
|
+
interface RealtimeBroadcastEvent<T = Record<string, unknown>> {
|
|
757
|
+
event: string;
|
|
758
|
+
payload: T;
|
|
759
|
+
id?: string;
|
|
760
|
+
topic?: string;
|
|
761
|
+
timestamp?: string;
|
|
762
|
+
allowed_sub_ids?: string[];
|
|
677
763
|
}
|
|
678
764
|
/** Status de subscription */
|
|
679
765
|
type RealtimeSubscribeStatus = 'SUBSCRIBED' | 'CLOSED' | 'CHANNEL_ERROR' | 'TIMED_OUT';
|
|
@@ -791,7 +877,12 @@ interface ChannelConfig {
|
|
|
791
877
|
};
|
|
792
878
|
/** Configuration présence directe */
|
|
793
879
|
presence?: {
|
|
794
|
-
/**
|
|
880
|
+
/**
|
|
881
|
+
* @deprecated La présence distribuée est indexée de manière autoritaire par le serveur
|
|
882
|
+
* à l'aide de l'identité vérifiée (`user_id` extrait du JWT) et de l'identifiant de connexion WebSocket
|
|
883
|
+
* (`client_id` dans NATS KV). Une clé libre côté client n'est pas utilisée pour partitionner le cluster
|
|
884
|
+
* afin d'empêcher les collisions d'état et les risques d'usurpation d'identité.
|
|
885
|
+
*/
|
|
795
886
|
key?: string;
|
|
796
887
|
};
|
|
797
888
|
/** Configuration compatible Supabase sous `config` */
|
|
@@ -801,6 +892,9 @@ interface ChannelConfig {
|
|
|
801
892
|
self?: boolean;
|
|
802
893
|
};
|
|
803
894
|
presence?: {
|
|
895
|
+
/**
|
|
896
|
+
* @deprecated Voir `ChannelConfig.presence.key`. L'identité de présence est sécurisée par `user_id`/`client_id`.
|
|
897
|
+
*/
|
|
804
898
|
key?: string;
|
|
805
899
|
};
|
|
806
900
|
private?: boolean;
|
|
@@ -1141,16 +1235,160 @@ interface NotificationStats {
|
|
|
1141
1235
|
dead_lettered: number;
|
|
1142
1236
|
}>;
|
|
1143
1237
|
}
|
|
1238
|
+
type NotificationChannel = 'email' | 'sms' | 'push' | 'webhook';
|
|
1239
|
+
type NotificationStatus = 'queued' | 'processing' | 'sent' | 'failed' | 'delivered' | 'expired' | 'dead_lettered';
|
|
1240
|
+
type NotificationStatsWindow = '1h' | '24h' | '7d' | '30d';
|
|
1241
|
+
type NotificationAttemptStatus = 'processing' | 'sent' | 'failed' | 'retry_scheduled' | 'dead_lettered';
|
|
1242
|
+
type SettingsSource = 'project' | 'environment' | 'none';
|
|
1243
|
+
interface SmtpPublicSettings {
|
|
1244
|
+
configured: boolean;
|
|
1245
|
+
source: SettingsSource;
|
|
1246
|
+
host?: string | null;
|
|
1247
|
+
port?: number | null;
|
|
1248
|
+
user?: string | null;
|
|
1249
|
+
password_set: boolean;
|
|
1250
|
+
from_email?: string | null;
|
|
1251
|
+
from_name?: string | null;
|
|
1252
|
+
tls: boolean;
|
|
1253
|
+
}
|
|
1254
|
+
interface TwilioPublicSettings {
|
|
1255
|
+
configured: boolean;
|
|
1256
|
+
source: SettingsSource;
|
|
1257
|
+
account_sid_prefix?: string | null;
|
|
1258
|
+
auth_token_set: boolean;
|
|
1259
|
+
from_number?: string | null;
|
|
1260
|
+
status_callback_url?: string | null;
|
|
1261
|
+
}
|
|
1262
|
+
interface FcmPublicSettings {
|
|
1263
|
+
configured: boolean;
|
|
1264
|
+
source: SettingsSource;
|
|
1265
|
+
project_id?: string | null;
|
|
1266
|
+
service_account_json_set: boolean;
|
|
1267
|
+
legacy_server_key_present: boolean;
|
|
1268
|
+
api: string;
|
|
1269
|
+
}
|
|
1270
|
+
interface ApnsPublicSettings {
|
|
1271
|
+
configured: boolean;
|
|
1272
|
+
source: SettingsSource;
|
|
1273
|
+
key_id?: string | null;
|
|
1274
|
+
team_id?: string | null;
|
|
1275
|
+
private_key_set: boolean;
|
|
1276
|
+
bundle_id?: string | null;
|
|
1277
|
+
production: boolean;
|
|
1278
|
+
}
|
|
1279
|
+
interface WebhookPublicSettings {
|
|
1280
|
+
configured: boolean;
|
|
1281
|
+
source: SettingsSource;
|
|
1282
|
+
max_retries: number;
|
|
1283
|
+
retry_delay_ms: number;
|
|
1284
|
+
timeout_secs: number;
|
|
1285
|
+
secret_set: boolean;
|
|
1286
|
+
signature_tolerance_secs: number;
|
|
1287
|
+
}
|
|
1288
|
+
interface QuotaPublicSettings {
|
|
1289
|
+
source: SettingsSource;
|
|
1290
|
+
project_rate_limit_per_minute: number;
|
|
1291
|
+
channel_rate_limit_per_minute: number;
|
|
1292
|
+
batch_max_size: number;
|
|
1293
|
+
}
|
|
1294
|
+
interface SmtpSettingsPatch {
|
|
1295
|
+
host?: string | null;
|
|
1296
|
+
port?: number | null;
|
|
1297
|
+
user?: string | null;
|
|
1298
|
+
password?: string | null;
|
|
1299
|
+
from_email?: string | null;
|
|
1300
|
+
from_name?: string | null;
|
|
1301
|
+
tls?: boolean | null;
|
|
1302
|
+
}
|
|
1303
|
+
interface TwilioSettingsPatch {
|
|
1304
|
+
account_sid?: string | null;
|
|
1305
|
+
auth_token?: string | null;
|
|
1306
|
+
from_number?: string | null;
|
|
1307
|
+
}
|
|
1308
|
+
interface FcmSettingsPatch {
|
|
1309
|
+
project_id?: string | null;
|
|
1310
|
+
service_account_json?: string | null;
|
|
1311
|
+
}
|
|
1312
|
+
interface ApnsSettingsPatch {
|
|
1313
|
+
key_id?: string | null;
|
|
1314
|
+
team_id?: string | null;
|
|
1315
|
+
private_key_b64?: string | null;
|
|
1316
|
+
bundle_id?: string | null;
|
|
1317
|
+
production?: boolean | null;
|
|
1318
|
+
}
|
|
1319
|
+
interface WebhookSettingsPatch {
|
|
1320
|
+
max_retries?: number | null;
|
|
1321
|
+
retry_delay_ms?: number | null;
|
|
1322
|
+
timeout_secs?: number | null;
|
|
1323
|
+
secret?: string | null;
|
|
1324
|
+
}
|
|
1325
|
+
interface QuotaSettingsPatch {
|
|
1326
|
+
project_rate_limit_per_minute?: number | null;
|
|
1327
|
+
channel_rate_limit_per_minute?: number | null;
|
|
1328
|
+
batch_max_size?: number | null;
|
|
1329
|
+
}
|
|
1330
|
+
interface NotificationSettingsPatch {
|
|
1331
|
+
smtp?: SmtpSettingsPatch | null;
|
|
1332
|
+
twilio?: TwilioSettingsPatch | null;
|
|
1333
|
+
fcm?: FcmSettingsPatch | null;
|
|
1334
|
+
apns?: ApnsSettingsPatch | null;
|
|
1335
|
+
webhook?: WebhookSettingsPatch | null;
|
|
1336
|
+
quotas?: QuotaSettingsPatch | null;
|
|
1337
|
+
}
|
|
1144
1338
|
interface NotificationSettings {
|
|
1145
1339
|
project_id: string;
|
|
1146
|
-
smtp?: Record<string, unknown>;
|
|
1147
|
-
twilio?: Record<string, unknown>;
|
|
1148
|
-
fcm?: Record<string, unknown>;
|
|
1149
|
-
apns?: Record<string, unknown>;
|
|
1150
|
-
webhook?: Record<string, unknown>;
|
|
1151
|
-
quotas?: Record<string, unknown>;
|
|
1340
|
+
smtp?: SmtpPublicSettings | Record<string, unknown>;
|
|
1341
|
+
twilio?: TwilioPublicSettings | Record<string, unknown>;
|
|
1342
|
+
fcm?: FcmPublicSettings | Record<string, unknown>;
|
|
1343
|
+
apns?: ApnsPublicSettings | Record<string, unknown>;
|
|
1344
|
+
webhook?: WebhookPublicSettings | Record<string, unknown>;
|
|
1345
|
+
quotas?: QuotaPublicSettings | Record<string, unknown>;
|
|
1152
1346
|
updated_at?: string | null;
|
|
1153
1347
|
}
|
|
1348
|
+
type NotificationSettingsPublic = NotificationSettings;
|
|
1349
|
+
interface CreateNotificationRuleRequest {
|
|
1350
|
+
name: string;
|
|
1351
|
+
trigger_type: string;
|
|
1352
|
+
condition?: Record<string, unknown>;
|
|
1353
|
+
template_id?: string | null;
|
|
1354
|
+
channel: NotificationChannel;
|
|
1355
|
+
recipient_expr: string;
|
|
1356
|
+
delay_seconds?: number;
|
|
1357
|
+
}
|
|
1358
|
+
interface UpdateNotificationRuleRequest {
|
|
1359
|
+
name?: string;
|
|
1360
|
+
enabled?: boolean;
|
|
1361
|
+
trigger_type?: string;
|
|
1362
|
+
condition?: Record<string, unknown>;
|
|
1363
|
+
template_id?: string | null;
|
|
1364
|
+
channel?: NotificationChannel;
|
|
1365
|
+
recipient_expr?: string;
|
|
1366
|
+
delay_seconds?: number;
|
|
1367
|
+
}
|
|
1368
|
+
interface SendNotificationOptions {
|
|
1369
|
+
channel: NotificationChannel;
|
|
1370
|
+
recipient: string;
|
|
1371
|
+
body?: string;
|
|
1372
|
+
subject?: string;
|
|
1373
|
+
templateId?: string;
|
|
1374
|
+
template_id?: string;
|
|
1375
|
+
variables?: Record<string, unknown>;
|
|
1376
|
+
metadata?: Record<string, unknown>;
|
|
1377
|
+
idempotencyKey?: string;
|
|
1378
|
+
idempotency_key?: string;
|
|
1379
|
+
}
|
|
1380
|
+
interface SendNotificationItem {
|
|
1381
|
+
channel: NotificationChannel;
|
|
1382
|
+
recipient: string;
|
|
1383
|
+
body?: string;
|
|
1384
|
+
subject?: string;
|
|
1385
|
+
templateId?: string;
|
|
1386
|
+
template_id?: string;
|
|
1387
|
+
variables?: Record<string, unknown>;
|
|
1388
|
+
metadata?: Record<string, unknown>;
|
|
1389
|
+
idempotencyKey?: string;
|
|
1390
|
+
idempotency_key?: string;
|
|
1391
|
+
}
|
|
1154
1392
|
interface NotificationRule {
|
|
1155
1393
|
id: string;
|
|
1156
1394
|
project_id: string;
|
|
@@ -1158,7 +1396,7 @@ interface NotificationRule {
|
|
|
1158
1396
|
trigger_type: string;
|
|
1159
1397
|
condition: Record<string, unknown>;
|
|
1160
1398
|
template_id?: string | null;
|
|
1161
|
-
channel:
|
|
1399
|
+
channel: NotificationChannel;
|
|
1162
1400
|
recipient_expr: string;
|
|
1163
1401
|
enabled: boolean;
|
|
1164
1402
|
delay_seconds: number;
|
|
@@ -1513,6 +1751,10 @@ interface GetClaimsResult {
|
|
|
1513
1751
|
kid?: string;
|
|
1514
1752
|
typ?: string;
|
|
1515
1753
|
};
|
|
1754
|
+
sub?: string;
|
|
1755
|
+
email?: string | null;
|
|
1756
|
+
role?: string;
|
|
1757
|
+
[key: string]: unknown;
|
|
1516
1758
|
}
|
|
1517
1759
|
|
|
1518
1760
|
type AuthChangeCallback = (token: string | null, user: User | null) => void;
|
|
@@ -1584,6 +1826,8 @@ interface AuraClientLike {
|
|
|
1584
1826
|
*/
|
|
1585
1827
|
readonly baseUrl: string;
|
|
1586
1828
|
readonly apiKey: string | null;
|
|
1829
|
+
/** Identifiant optionnel du projet résolu ou configuré sur le client */
|
|
1830
|
+
readonly projectId?: string;
|
|
1587
1831
|
readonly fetchFn: typeof globalThis.fetch;
|
|
1588
1832
|
readonly authStore: BaseAuthStore;
|
|
1589
1833
|
/** Consommé uniquement par le service realtime (refresh proactif du token). */
|
|
@@ -1771,9 +2015,10 @@ declare class LocalAuthStore extends BaseAuthStore {
|
|
|
1771
2015
|
* Serialize current auth state into a `Set-Cookie` value.
|
|
1772
2016
|
*/
|
|
1773
2017
|
exportToCookie(options?: CookieOptions): string;
|
|
2018
|
+
private _getStorage;
|
|
1774
2019
|
private _loadFromStorage;
|
|
1775
2020
|
private _persist;
|
|
1776
2021
|
private _removeStorage;
|
|
1777
2022
|
}
|
|
1778
2023
|
|
|
1779
|
-
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationStats, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInOptions, type ObjectMeta, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeEvent, type RealtimeListenType, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationRequest, type SerializeCookieOptions, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type SessionInfo, type SignInRequest, type SignUpRequest, type StorageBucket, type SubscribeCallback, type TokenPair, type UpdateUserRequest, type UploadResult, type User, type UserStats, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
|
2024
|
+
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInOptions, type ObjectMeta, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
package/dist/index.d.ts
CHANGED
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
* - storage/path.ts : invalid_path
|
|
15
15
|
* - db/QueryBuilder.ts: PGRST116 (parité PostgREST : `.single()` sur 0/plusieurs lignes)
|
|
16
16
|
*/
|
|
17
|
-
type AuraErrorCode = 'no_session' | 'timeout' | 'network_error' | 'invalid_response' | 'refresh_discarded' | 'unverifiable_token' | 'no_code_verifier' | 'pkce_generation_failed' | 'missing_email' | 'jwks_fetch_failed' | 'signature_invalid' | 'token_expired' | 'token_not_yet_valid' | 'invalid_jwt' | 'unsupported_alg' | 'no_matching_key' | 'invalid_issuer' | 'invalid_audience' | 'invalid_path' | 'PGRST116' | (string & {});
|
|
17
|
+
type AuraErrorCode = 'no_session' | 'timeout' | 'network_error' | 'invalid_response' | 'refresh_discarded' | 'unverifiable_token' | 'no_code_verifier' | 'pkce_generation_failed' | 'missing_email' | 'jwks_fetch_failed' | 'signature_invalid' | 'token_expired' | 'token_not_yet_valid' | 'invalid_jwt' | 'unsupported_alg' | 'no_matching_key' | 'invalid_issuer' | 'invalid_audience' | 'invalid_path' | 'PGRST116' | 'invalid_credentials' | 'weak_password' | 'email_already_in_use' | 'user_not_found' | 'rate_limit_exceeded' | 'session_expired' | 'session_revoked' | (string & {});
|
|
18
18
|
/**
|
|
19
19
|
* Structured error thrown/returned by the Aurabase SDK.
|
|
20
|
-
* Mirrors the backend's `AuraError` JSON shape.
|
|
20
|
+
* Mirrors the backend's `AuraError` JSON shape with semantic DX normalization.
|
|
21
21
|
*/
|
|
22
22
|
declare class AuraError extends Error {
|
|
23
23
|
readonly status: number;
|
|
24
24
|
readonly code: AuraErrorCode;
|
|
25
25
|
readonly details: unknown;
|
|
26
|
+
readonly retryAfter?: number;
|
|
26
27
|
/** Marqueur runtime pour `isAuraError` (détection cross-realm/cross-bundle). */
|
|
27
28
|
protected readonly __isAuraError = true;
|
|
28
29
|
constructor(status: number, body?: {
|
|
@@ -31,7 +32,7 @@ declare class AuraError extends Error {
|
|
|
31
32
|
message?: string;
|
|
32
33
|
};
|
|
33
34
|
message?: string;
|
|
34
|
-
} | null);
|
|
35
|
+
} | null, headers?: Headers | Record<string, string | null | undefined>);
|
|
35
36
|
get isNotFound(): boolean;
|
|
36
37
|
get isUnauthorized(): boolean;
|
|
37
38
|
get isForbidden(): boolean;
|
|
@@ -93,6 +94,11 @@ interface AuraSuccess<T> {
|
|
|
93
94
|
data: T;
|
|
94
95
|
error: null;
|
|
95
96
|
meta?: Meta;
|
|
97
|
+
/**
|
|
98
|
+
* Nombre total de lignes correspondant à la requête (dérivé de meta.total).
|
|
99
|
+
* Renseigné quand un décompte explicite est demandé (.count('exact' | ...)).
|
|
100
|
+
*/
|
|
101
|
+
count?: number | null;
|
|
96
102
|
}
|
|
97
103
|
/**
|
|
98
104
|
* Réponse en SUCCÈS SANS contenu — `data` ET `error` nuls.
|
|
@@ -117,6 +123,10 @@ interface AuraNoContent {
|
|
|
117
123
|
data: null;
|
|
118
124
|
error: null;
|
|
119
125
|
meta?: Meta;
|
|
126
|
+
/**
|
|
127
|
+
* Nombre total de lignes (dérivé de meta.total).
|
|
128
|
+
*/
|
|
129
|
+
count?: number | null;
|
|
120
130
|
}
|
|
121
131
|
/**
|
|
122
132
|
* Réponse en ÉCHEC. `data` y est `null` par construction — aucun producteur du
|
|
@@ -126,6 +136,7 @@ interface AuraFailure {
|
|
|
126
136
|
data: null;
|
|
127
137
|
error: AuraError;
|
|
128
138
|
meta?: Meta;
|
|
139
|
+
count?: number | null;
|
|
129
140
|
}
|
|
130
141
|
/**
|
|
131
142
|
* Enveloppe de réponse du SDK : union à TROIS membres.
|
|
@@ -175,19 +186,47 @@ interface User {
|
|
|
175
186
|
created_at: string;
|
|
176
187
|
last_sign_in_at?: string | null;
|
|
177
188
|
}
|
|
189
|
+
interface Session {
|
|
190
|
+
access_token: string;
|
|
191
|
+
refresh_token: string;
|
|
192
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
193
|
+
accessToken?: string;
|
|
194
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
195
|
+
refreshToken?: string;
|
|
196
|
+
token_type: string;
|
|
197
|
+
expires_in: number;
|
|
198
|
+
expires_at?: number;
|
|
199
|
+
user: User;
|
|
200
|
+
provider_token?: string | null;
|
|
201
|
+
provider_refresh_token?: string | null;
|
|
202
|
+
}
|
|
178
203
|
interface TokenPair {
|
|
179
204
|
access_token: string;
|
|
180
205
|
refresh_token: string;
|
|
206
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
207
|
+
accessToken?: string;
|
|
208
|
+
/** Alias camelCase pour parité DX Supabase/JS */
|
|
209
|
+
refreshToken?: string;
|
|
181
210
|
token_type: string;
|
|
182
211
|
expires_in: number;
|
|
183
212
|
user: User;
|
|
184
213
|
provider_token?: string | null;
|
|
185
214
|
provider_refresh_token?: string | null;
|
|
215
|
+
/** Sous-objet session pour parité DX Supabase (`data.session.access_token`). */
|
|
216
|
+
session?: Session;
|
|
217
|
+
mfaChallenge?: undefined;
|
|
186
218
|
}
|
|
187
219
|
interface MfaChallenge {
|
|
188
220
|
mfa_required: true;
|
|
189
221
|
mfa_token: string;
|
|
190
222
|
mfa_setup_required?: boolean;
|
|
223
|
+
session?: undefined;
|
|
224
|
+
/** Alias ergonomique aligné sur la documentation officielle */
|
|
225
|
+
mfaChallenge?: {
|
|
226
|
+
mfaRequired: boolean;
|
|
227
|
+
mfaToken: string;
|
|
228
|
+
mfaSetupRequired?: boolean;
|
|
229
|
+
};
|
|
191
230
|
}
|
|
192
231
|
type LoginResponse = TokenPair | MfaChallenge;
|
|
193
232
|
type AuthEvent = 'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'MFA_CHALLENGE' | 'PASSWORD_RECOVERY';
|
|
@@ -204,6 +243,8 @@ interface AuthChangePayload {
|
|
|
204
243
|
event: AuthEvent;
|
|
205
244
|
user: User | null;
|
|
206
245
|
accessToken: string | null;
|
|
246
|
+
/** Session complète pour parité DX Supabase */
|
|
247
|
+
session?: Session | null;
|
|
207
248
|
/** Présent uniquement si `event === 'MFA_CHALLENGE'`. */
|
|
208
249
|
mfaToken?: string;
|
|
209
250
|
/** Présent uniquement si `event === 'MFA_CHALLENGE'`. */
|
|
@@ -674,6 +715,51 @@ interface CdcPayload {
|
|
|
674
715
|
record: Record<string, unknown>;
|
|
675
716
|
old_record: Record<string, unknown> | null;
|
|
676
717
|
_truncated?: boolean;
|
|
718
|
+
[key: string]: unknown;
|
|
719
|
+
}
|
|
720
|
+
/** Base commune des métadonnées pour un événement CDC PostgreSQL */
|
|
721
|
+
interface RealtimePostgresChangesBasePayload {
|
|
722
|
+
schema: string;
|
|
723
|
+
table: string;
|
|
724
|
+
commit_timestamp: string;
|
|
725
|
+
errors?: string[];
|
|
726
|
+
id: string;
|
|
727
|
+
topic: string;
|
|
728
|
+
timestamp: string;
|
|
729
|
+
payload: CdcPayload | Record<string, unknown>;
|
|
730
|
+
event: 'insert' | 'update' | 'delete';
|
|
731
|
+
}
|
|
732
|
+
/** Payload enrichi pour un événement CDC PostgreSQL d'insertion */
|
|
733
|
+
interface RealtimePostgresInsertPayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
734
|
+
eventType: 'INSERT';
|
|
735
|
+
event: 'insert';
|
|
736
|
+
new: T;
|
|
737
|
+
old: null;
|
|
738
|
+
}
|
|
739
|
+
/** Payload enrichi pour un événement CDC PostgreSQL de mise à jour */
|
|
740
|
+
interface RealtimePostgresUpdatePayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
741
|
+
eventType: 'UPDATE';
|
|
742
|
+
event: 'update';
|
|
743
|
+
new: T;
|
|
744
|
+
old: Partial<T>;
|
|
745
|
+
}
|
|
746
|
+
/** Payload enrichi pour un événement CDC PostgreSQL de suppression */
|
|
747
|
+
interface RealtimePostgresDeletePayload<T = Record<string, unknown>> extends RealtimePostgresChangesBasePayload {
|
|
748
|
+
eventType: 'DELETE';
|
|
749
|
+
event: 'delete';
|
|
750
|
+
new: null;
|
|
751
|
+
old: Partial<T> | null;
|
|
752
|
+
}
|
|
753
|
+
/** Union discriminée par eventType pour les événements CDC PostgreSQL */
|
|
754
|
+
type RealtimePostgresChangesPayload<T = Record<string, unknown>> = RealtimePostgresInsertPayload<T> | RealtimePostgresUpdatePayload<T> | RealtimePostgresDeletePayload<T>;
|
|
755
|
+
/** Événement broadcast reçu avec payload typé */
|
|
756
|
+
interface RealtimeBroadcastEvent<T = Record<string, unknown>> {
|
|
757
|
+
event: string;
|
|
758
|
+
payload: T;
|
|
759
|
+
id?: string;
|
|
760
|
+
topic?: string;
|
|
761
|
+
timestamp?: string;
|
|
762
|
+
allowed_sub_ids?: string[];
|
|
677
763
|
}
|
|
678
764
|
/** Status de subscription */
|
|
679
765
|
type RealtimeSubscribeStatus = 'SUBSCRIBED' | 'CLOSED' | 'CHANNEL_ERROR' | 'TIMED_OUT';
|
|
@@ -791,7 +877,12 @@ interface ChannelConfig {
|
|
|
791
877
|
};
|
|
792
878
|
/** Configuration présence directe */
|
|
793
879
|
presence?: {
|
|
794
|
-
/**
|
|
880
|
+
/**
|
|
881
|
+
* @deprecated La présence distribuée est indexée de manière autoritaire par le serveur
|
|
882
|
+
* à l'aide de l'identité vérifiée (`user_id` extrait du JWT) et de l'identifiant de connexion WebSocket
|
|
883
|
+
* (`client_id` dans NATS KV). Une clé libre côté client n'est pas utilisée pour partitionner le cluster
|
|
884
|
+
* afin d'empêcher les collisions d'état et les risques d'usurpation d'identité.
|
|
885
|
+
*/
|
|
795
886
|
key?: string;
|
|
796
887
|
};
|
|
797
888
|
/** Configuration compatible Supabase sous `config` */
|
|
@@ -801,6 +892,9 @@ interface ChannelConfig {
|
|
|
801
892
|
self?: boolean;
|
|
802
893
|
};
|
|
803
894
|
presence?: {
|
|
895
|
+
/**
|
|
896
|
+
* @deprecated Voir `ChannelConfig.presence.key`. L'identité de présence est sécurisée par `user_id`/`client_id`.
|
|
897
|
+
*/
|
|
804
898
|
key?: string;
|
|
805
899
|
};
|
|
806
900
|
private?: boolean;
|
|
@@ -1141,16 +1235,160 @@ interface NotificationStats {
|
|
|
1141
1235
|
dead_lettered: number;
|
|
1142
1236
|
}>;
|
|
1143
1237
|
}
|
|
1238
|
+
type NotificationChannel = 'email' | 'sms' | 'push' | 'webhook';
|
|
1239
|
+
type NotificationStatus = 'queued' | 'processing' | 'sent' | 'failed' | 'delivered' | 'expired' | 'dead_lettered';
|
|
1240
|
+
type NotificationStatsWindow = '1h' | '24h' | '7d' | '30d';
|
|
1241
|
+
type NotificationAttemptStatus = 'processing' | 'sent' | 'failed' | 'retry_scheduled' | 'dead_lettered';
|
|
1242
|
+
type SettingsSource = 'project' | 'environment' | 'none';
|
|
1243
|
+
interface SmtpPublicSettings {
|
|
1244
|
+
configured: boolean;
|
|
1245
|
+
source: SettingsSource;
|
|
1246
|
+
host?: string | null;
|
|
1247
|
+
port?: number | null;
|
|
1248
|
+
user?: string | null;
|
|
1249
|
+
password_set: boolean;
|
|
1250
|
+
from_email?: string | null;
|
|
1251
|
+
from_name?: string | null;
|
|
1252
|
+
tls: boolean;
|
|
1253
|
+
}
|
|
1254
|
+
interface TwilioPublicSettings {
|
|
1255
|
+
configured: boolean;
|
|
1256
|
+
source: SettingsSource;
|
|
1257
|
+
account_sid_prefix?: string | null;
|
|
1258
|
+
auth_token_set: boolean;
|
|
1259
|
+
from_number?: string | null;
|
|
1260
|
+
status_callback_url?: string | null;
|
|
1261
|
+
}
|
|
1262
|
+
interface FcmPublicSettings {
|
|
1263
|
+
configured: boolean;
|
|
1264
|
+
source: SettingsSource;
|
|
1265
|
+
project_id?: string | null;
|
|
1266
|
+
service_account_json_set: boolean;
|
|
1267
|
+
legacy_server_key_present: boolean;
|
|
1268
|
+
api: string;
|
|
1269
|
+
}
|
|
1270
|
+
interface ApnsPublicSettings {
|
|
1271
|
+
configured: boolean;
|
|
1272
|
+
source: SettingsSource;
|
|
1273
|
+
key_id?: string | null;
|
|
1274
|
+
team_id?: string | null;
|
|
1275
|
+
private_key_set: boolean;
|
|
1276
|
+
bundle_id?: string | null;
|
|
1277
|
+
production: boolean;
|
|
1278
|
+
}
|
|
1279
|
+
interface WebhookPublicSettings {
|
|
1280
|
+
configured: boolean;
|
|
1281
|
+
source: SettingsSource;
|
|
1282
|
+
max_retries: number;
|
|
1283
|
+
retry_delay_ms: number;
|
|
1284
|
+
timeout_secs: number;
|
|
1285
|
+
secret_set: boolean;
|
|
1286
|
+
signature_tolerance_secs: number;
|
|
1287
|
+
}
|
|
1288
|
+
interface QuotaPublicSettings {
|
|
1289
|
+
source: SettingsSource;
|
|
1290
|
+
project_rate_limit_per_minute: number;
|
|
1291
|
+
channel_rate_limit_per_minute: number;
|
|
1292
|
+
batch_max_size: number;
|
|
1293
|
+
}
|
|
1294
|
+
interface SmtpSettingsPatch {
|
|
1295
|
+
host?: string | null;
|
|
1296
|
+
port?: number | null;
|
|
1297
|
+
user?: string | null;
|
|
1298
|
+
password?: string | null;
|
|
1299
|
+
from_email?: string | null;
|
|
1300
|
+
from_name?: string | null;
|
|
1301
|
+
tls?: boolean | null;
|
|
1302
|
+
}
|
|
1303
|
+
interface TwilioSettingsPatch {
|
|
1304
|
+
account_sid?: string | null;
|
|
1305
|
+
auth_token?: string | null;
|
|
1306
|
+
from_number?: string | null;
|
|
1307
|
+
}
|
|
1308
|
+
interface FcmSettingsPatch {
|
|
1309
|
+
project_id?: string | null;
|
|
1310
|
+
service_account_json?: string | null;
|
|
1311
|
+
}
|
|
1312
|
+
interface ApnsSettingsPatch {
|
|
1313
|
+
key_id?: string | null;
|
|
1314
|
+
team_id?: string | null;
|
|
1315
|
+
private_key_b64?: string | null;
|
|
1316
|
+
bundle_id?: string | null;
|
|
1317
|
+
production?: boolean | null;
|
|
1318
|
+
}
|
|
1319
|
+
interface WebhookSettingsPatch {
|
|
1320
|
+
max_retries?: number | null;
|
|
1321
|
+
retry_delay_ms?: number | null;
|
|
1322
|
+
timeout_secs?: number | null;
|
|
1323
|
+
secret?: string | null;
|
|
1324
|
+
}
|
|
1325
|
+
interface QuotaSettingsPatch {
|
|
1326
|
+
project_rate_limit_per_minute?: number | null;
|
|
1327
|
+
channel_rate_limit_per_minute?: number | null;
|
|
1328
|
+
batch_max_size?: number | null;
|
|
1329
|
+
}
|
|
1330
|
+
interface NotificationSettingsPatch {
|
|
1331
|
+
smtp?: SmtpSettingsPatch | null;
|
|
1332
|
+
twilio?: TwilioSettingsPatch | null;
|
|
1333
|
+
fcm?: FcmSettingsPatch | null;
|
|
1334
|
+
apns?: ApnsSettingsPatch | null;
|
|
1335
|
+
webhook?: WebhookSettingsPatch | null;
|
|
1336
|
+
quotas?: QuotaSettingsPatch | null;
|
|
1337
|
+
}
|
|
1144
1338
|
interface NotificationSettings {
|
|
1145
1339
|
project_id: string;
|
|
1146
|
-
smtp?: Record<string, unknown>;
|
|
1147
|
-
twilio?: Record<string, unknown>;
|
|
1148
|
-
fcm?: Record<string, unknown>;
|
|
1149
|
-
apns?: Record<string, unknown>;
|
|
1150
|
-
webhook?: Record<string, unknown>;
|
|
1151
|
-
quotas?: Record<string, unknown>;
|
|
1340
|
+
smtp?: SmtpPublicSettings | Record<string, unknown>;
|
|
1341
|
+
twilio?: TwilioPublicSettings | Record<string, unknown>;
|
|
1342
|
+
fcm?: FcmPublicSettings | Record<string, unknown>;
|
|
1343
|
+
apns?: ApnsPublicSettings | Record<string, unknown>;
|
|
1344
|
+
webhook?: WebhookPublicSettings | Record<string, unknown>;
|
|
1345
|
+
quotas?: QuotaPublicSettings | Record<string, unknown>;
|
|
1152
1346
|
updated_at?: string | null;
|
|
1153
1347
|
}
|
|
1348
|
+
type NotificationSettingsPublic = NotificationSettings;
|
|
1349
|
+
interface CreateNotificationRuleRequest {
|
|
1350
|
+
name: string;
|
|
1351
|
+
trigger_type: string;
|
|
1352
|
+
condition?: Record<string, unknown>;
|
|
1353
|
+
template_id?: string | null;
|
|
1354
|
+
channel: NotificationChannel;
|
|
1355
|
+
recipient_expr: string;
|
|
1356
|
+
delay_seconds?: number;
|
|
1357
|
+
}
|
|
1358
|
+
interface UpdateNotificationRuleRequest {
|
|
1359
|
+
name?: string;
|
|
1360
|
+
enabled?: boolean;
|
|
1361
|
+
trigger_type?: string;
|
|
1362
|
+
condition?: Record<string, unknown>;
|
|
1363
|
+
template_id?: string | null;
|
|
1364
|
+
channel?: NotificationChannel;
|
|
1365
|
+
recipient_expr?: string;
|
|
1366
|
+
delay_seconds?: number;
|
|
1367
|
+
}
|
|
1368
|
+
interface SendNotificationOptions {
|
|
1369
|
+
channel: NotificationChannel;
|
|
1370
|
+
recipient: string;
|
|
1371
|
+
body?: string;
|
|
1372
|
+
subject?: string;
|
|
1373
|
+
templateId?: string;
|
|
1374
|
+
template_id?: string;
|
|
1375
|
+
variables?: Record<string, unknown>;
|
|
1376
|
+
metadata?: Record<string, unknown>;
|
|
1377
|
+
idempotencyKey?: string;
|
|
1378
|
+
idempotency_key?: string;
|
|
1379
|
+
}
|
|
1380
|
+
interface SendNotificationItem {
|
|
1381
|
+
channel: NotificationChannel;
|
|
1382
|
+
recipient: string;
|
|
1383
|
+
body?: string;
|
|
1384
|
+
subject?: string;
|
|
1385
|
+
templateId?: string;
|
|
1386
|
+
template_id?: string;
|
|
1387
|
+
variables?: Record<string, unknown>;
|
|
1388
|
+
metadata?: Record<string, unknown>;
|
|
1389
|
+
idempotencyKey?: string;
|
|
1390
|
+
idempotency_key?: string;
|
|
1391
|
+
}
|
|
1154
1392
|
interface NotificationRule {
|
|
1155
1393
|
id: string;
|
|
1156
1394
|
project_id: string;
|
|
@@ -1158,7 +1396,7 @@ interface NotificationRule {
|
|
|
1158
1396
|
trigger_type: string;
|
|
1159
1397
|
condition: Record<string, unknown>;
|
|
1160
1398
|
template_id?: string | null;
|
|
1161
|
-
channel:
|
|
1399
|
+
channel: NotificationChannel;
|
|
1162
1400
|
recipient_expr: string;
|
|
1163
1401
|
enabled: boolean;
|
|
1164
1402
|
delay_seconds: number;
|
|
@@ -1513,6 +1751,10 @@ interface GetClaimsResult {
|
|
|
1513
1751
|
kid?: string;
|
|
1514
1752
|
typ?: string;
|
|
1515
1753
|
};
|
|
1754
|
+
sub?: string;
|
|
1755
|
+
email?: string | null;
|
|
1756
|
+
role?: string;
|
|
1757
|
+
[key: string]: unknown;
|
|
1516
1758
|
}
|
|
1517
1759
|
|
|
1518
1760
|
type AuthChangeCallback = (token: string | null, user: User | null) => void;
|
|
@@ -1584,6 +1826,8 @@ interface AuraClientLike {
|
|
|
1584
1826
|
*/
|
|
1585
1827
|
readonly baseUrl: string;
|
|
1586
1828
|
readonly apiKey: string | null;
|
|
1829
|
+
/** Identifiant optionnel du projet résolu ou configuré sur le client */
|
|
1830
|
+
readonly projectId?: string;
|
|
1587
1831
|
readonly fetchFn: typeof globalThis.fetch;
|
|
1588
1832
|
readonly authStore: BaseAuthStore;
|
|
1589
1833
|
/** Consommé uniquement par le service realtime (refresh proactif du token). */
|
|
@@ -1771,9 +2015,10 @@ declare class LocalAuthStore extends BaseAuthStore {
|
|
|
1771
2015
|
* Serialize current auth state into a `Set-Cookie` value.
|
|
1772
2016
|
*/
|
|
1773
2017
|
exportToCookie(options?: CookieOptions): string;
|
|
2018
|
+
private _getStorage;
|
|
1774
2019
|
private _loadFromStorage;
|
|
1775
2020
|
private _persist;
|
|
1776
2021
|
private _removeStorage;
|
|
1777
2022
|
}
|
|
1778
2023
|
|
|
1779
|
-
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationStats, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInOptions, type ObjectMeta, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeEvent, type RealtimeListenType, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationRequest, type SerializeCookieOptions, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type SessionInfo, type SignInRequest, type SignUpRequest, type StorageBucket, type SubscribeCallback, type TokenPair, type UpdateUserRequest, type UploadResult, type User, type UserStats, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
|
2024
|
+
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInOptions, type ObjectMeta, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
package/dist/index.js
CHANGED
|
@@ -3,15 +3,60 @@ var AuraError = class _AuraError extends Error {
|
|
|
3
3
|
status;
|
|
4
4
|
code;
|
|
5
5
|
details;
|
|
6
|
+
retryAfter;
|
|
6
7
|
/** Marqueur runtime pour `isAuraError` (détection cross-realm/cross-bundle). */
|
|
7
8
|
__isAuraError = true;
|
|
8
|
-
constructor(status, body) {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
constructor(status, body, headers) {
|
|
10
|
+
let rawMessage = body?.error?.message ?? body?.message ?? (status === 429 ? "Trop de requ\xEAtes, veuillez patienter avant de r\xE9essayer." : `HTTP ${status}`);
|
|
11
|
+
let retryAfterSec;
|
|
12
|
+
if (headers) {
|
|
13
|
+
const getHeader = (name) => {
|
|
14
|
+
if (typeof headers.get === "function") {
|
|
15
|
+
return headers.get(name);
|
|
16
|
+
}
|
|
17
|
+
const record = headers;
|
|
18
|
+
return record[name] ?? record[name.toLowerCase()];
|
|
19
|
+
};
|
|
20
|
+
const ra = getHeader("retry-after") ?? getHeader("x-ratelimit-after");
|
|
21
|
+
if (ra) {
|
|
22
|
+
const sec = parseInt(ra, 10);
|
|
23
|
+
if (!isNaN(sec)) {
|
|
24
|
+
retryAfterSec = sec;
|
|
25
|
+
if (status === 429) {
|
|
26
|
+
rawMessage = `Trop de requ\xEAtes, veuillez patienter ${sec} seconde${sec > 1 ? "s" : ""} avant de r\xE9essayer.`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
super(rawMessage);
|
|
11
32
|
this.name = "AuraError";
|
|
12
33
|
this.status = status;
|
|
13
|
-
this.code = body?.error?.code ?? `http_${status}`;
|
|
14
34
|
this.details = body;
|
|
35
|
+
if (retryAfterSec !== void 0) {
|
|
36
|
+
this.retryAfter = retryAfterSec;
|
|
37
|
+
}
|
|
38
|
+
const rawCode = body?.error?.code;
|
|
39
|
+
const lowerMsg = rawMessage.toLowerCase();
|
|
40
|
+
const isGenericHttpCode = typeof rawCode !== "string" || rawCode === "UNAUTHORIZED" || rawCode === "BAD_REQUEST" || rawCode === "CONFLICT" || rawCode === "RATE_LIMITED" || rawCode.startsWith("http_");
|
|
41
|
+
if (!isGenericHttpCode) {
|
|
42
|
+
this.code = rawCode;
|
|
43
|
+
} else if (status === 429 || rawCode === "RATE_LIMITED" || rawCode === "http_429") {
|
|
44
|
+
this.code = "rate_limit_exceeded";
|
|
45
|
+
} else if (status === 401 && (lowerMsg.includes("identifiants") || lowerMsg.includes("credentials") || lowerMsg.includes("mot de passe incorrect"))) {
|
|
46
|
+
this.code = "invalid_credentials";
|
|
47
|
+
} else if (status === 401 && lowerMsg.includes("r\xE9voqu\xE9e")) {
|
|
48
|
+
this.code = "session_revoked";
|
|
49
|
+
} else if (status === 401 && lowerMsg.includes("expir\xE9")) {
|
|
50
|
+
this.code = "session_expired";
|
|
51
|
+
} else if (status === 400 && (lowerMsg.includes("mot de passe") || lowerMsg.includes("password"))) {
|
|
52
|
+
this.code = "weak_password";
|
|
53
|
+
} else if (status === 409 && (lowerMsg.includes("d\xE9j\xE0 utilis\xE9") || lowerMsg.includes("already exists") || lowerMsg.includes("already in use") || lowerMsg.includes("email"))) {
|
|
54
|
+
this.code = "email_already_in_use";
|
|
55
|
+
} else if (status === 404 && lowerMsg.includes("utilisateur")) {
|
|
56
|
+
this.code = "user_not_found";
|
|
57
|
+
} else {
|
|
58
|
+
this.code = rawCode ?? `http_${status}`;
|
|
59
|
+
}
|
|
15
60
|
Object.setPrototypeOf(this, _AuraError.prototype);
|
|
16
61
|
}
|
|
17
62
|
get isNotFound() {
|
|
@@ -298,6 +343,15 @@ function unwrapEnvelope(body) {
|
|
|
298
343
|
}
|
|
299
344
|
return body;
|
|
300
345
|
}
|
|
346
|
+
function parseContentRangeTotal(headerVal) {
|
|
347
|
+
if (!headerVal) return void 0;
|
|
348
|
+
const parts = headerVal.split("/");
|
|
349
|
+
if (parts.length === 2 && parts[1] !== "*") {
|
|
350
|
+
const n = parseInt(parts[1], 10);
|
|
351
|
+
if (!Number.isNaN(n)) return n;
|
|
352
|
+
}
|
|
353
|
+
return void 0;
|
|
354
|
+
}
|
|
301
355
|
async function readTextBounded(res, timeoutMs) {
|
|
302
356
|
const body = res.body;
|
|
303
357
|
if (!body || typeof body.getReader !== "function" || !(timeoutMs > 0)) {
|
|
@@ -646,11 +700,12 @@ async function fetchWithAuth(url, init, client) {
|
|
|
646
700
|
try {
|
|
647
701
|
body2 = JSON.parse(errRead.text);
|
|
648
702
|
} catch {
|
|
703
|
+
body2 = { message: errRead.text.trim() };
|
|
649
704
|
}
|
|
650
705
|
} else if (!errRead.ok && errRead.timedOut) {
|
|
651
706
|
emitAuraEvent(client.onEvent, client.debug, { kind: "timeout", url });
|
|
652
707
|
}
|
|
653
|
-
return { data: null, error: new AuraError(res.status, body2) };
|
|
708
|
+
return { data: null, error: new AuraError(res.status, body2, res.headers) };
|
|
654
709
|
}
|
|
655
710
|
const read = await readTextBounded(res, bodyTimeoutMs);
|
|
656
711
|
if (!read.ok) {
|
|
@@ -678,7 +733,11 @@ async function fetchWithAuth(url, init, client) {
|
|
|
678
733
|
}
|
|
679
734
|
const raw = read.text;
|
|
680
735
|
if (raw.trim() === "") {
|
|
681
|
-
|
|
736
|
+
const cr2 = res.headers.get("content-range") ?? res.headers.get("Content-Range");
|
|
737
|
+
const totalFromCr2 = parseContentRangeTotal(cr2);
|
|
738
|
+
const meta2 = totalFromCr2 !== void 0 ? { total: totalFromCr2 } : void 0;
|
|
739
|
+
const count2 = totalFromCr2 !== void 0 ? totalFromCr2 : null;
|
|
740
|
+
return { data: null, error: null, meta: meta2, count: count2 };
|
|
682
741
|
}
|
|
683
742
|
let body;
|
|
684
743
|
try {
|
|
@@ -697,11 +756,15 @@ async function fetchWithAuth(url, init, client) {
|
|
|
697
756
|
};
|
|
698
757
|
}
|
|
699
758
|
const unwrapped = unwrapEnvelope(body);
|
|
700
|
-
const
|
|
759
|
+
const cr = res.headers.get("content-range") ?? res.headers.get("Content-Range");
|
|
760
|
+
const totalFromCr = parseContentRangeTotal(cr);
|
|
761
|
+
const rawMeta = body !== null && typeof body === "object" && "meta" in body ? body.meta : void 0;
|
|
762
|
+
const meta = rawMeta !== void 0 ? rawMeta : totalFromCr !== void 0 ? { total: totalFromCr } : void 0;
|
|
763
|
+
const count = meta?.total !== void 0 ? meta.total : totalFromCr ?? null;
|
|
701
764
|
if (unwrapped === null) {
|
|
702
|
-
return { data: null, error: null, meta };
|
|
765
|
+
return { data: null, error: null, meta, count };
|
|
703
766
|
}
|
|
704
|
-
return { data: unwrapped, error: null, meta };
|
|
767
|
+
return { data: unwrapped, error: null, meta, count };
|
|
705
768
|
}
|
|
706
769
|
}
|
|
707
770
|
|
|
@@ -787,14 +850,15 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
787
850
|
* (`clientScope`, dérivée de l'URL du projet).
|
|
788
851
|
*/
|
|
789
852
|
_removePkceVerifiers() {
|
|
790
|
-
|
|
853
|
+
const storage = this._getStorage();
|
|
854
|
+
if (!storage) return;
|
|
791
855
|
try {
|
|
792
856
|
const toRemove = [];
|
|
793
|
-
for (let i = 0; i <
|
|
794
|
-
const k =
|
|
857
|
+
for (let i = 0; i < storage.length; i++) {
|
|
858
|
+
const k = storage.key(i);
|
|
795
859
|
if (k && /^aura-.*-(pkce-code-verifier|oauth-implicit-initiated)$/.test(k)) toRemove.push(k);
|
|
796
860
|
}
|
|
797
|
-
for (const k of toRemove)
|
|
861
|
+
for (const k of toRemove) storage.removeItem(k);
|
|
798
862
|
} catch {
|
|
799
863
|
this._emitStorageBlocked("removePkceVerifiers");
|
|
800
864
|
}
|
|
@@ -805,17 +869,19 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
805
869
|
// ne survivrait pas à ce cycle de navigation.
|
|
806
870
|
setItem(key, value) {
|
|
807
871
|
super.setItem(key, value);
|
|
808
|
-
|
|
872
|
+
const storage = this._getStorage();
|
|
873
|
+
if (!storage) return;
|
|
809
874
|
try {
|
|
810
|
-
|
|
875
|
+
storage.setItem(key, value);
|
|
811
876
|
} catch {
|
|
812
877
|
this._emitStorageBlocked("setItem");
|
|
813
878
|
}
|
|
814
879
|
}
|
|
815
880
|
getItem(key) {
|
|
816
|
-
|
|
881
|
+
const storage = this._getStorage();
|
|
882
|
+
if (!storage) return super.getItem(key);
|
|
817
883
|
try {
|
|
818
|
-
const v =
|
|
884
|
+
const v = storage.getItem(key);
|
|
819
885
|
if (v !== null) return v;
|
|
820
886
|
} catch {
|
|
821
887
|
this._emitStorageBlocked("getItem");
|
|
@@ -824,9 +890,10 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
824
890
|
}
|
|
825
891
|
removeItem(key) {
|
|
826
892
|
super.removeItem(key);
|
|
827
|
-
|
|
893
|
+
const storage = this._getStorage();
|
|
894
|
+
if (!storage) return;
|
|
828
895
|
try {
|
|
829
|
-
|
|
896
|
+
storage.removeItem(key);
|
|
830
897
|
} catch {
|
|
831
898
|
this._emitStorageBlocked("removeItem");
|
|
832
899
|
}
|
|
@@ -869,10 +936,40 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
869
936
|
return parts.join("; ");
|
|
870
937
|
}
|
|
871
938
|
// -- Private ----------------------------------------------------------------
|
|
939
|
+
_getStorage() {
|
|
940
|
+
if (typeof window !== "undefined" && typeof window.localStorage !== "undefined") {
|
|
941
|
+
return window.localStorage;
|
|
942
|
+
}
|
|
943
|
+
const g = globalThis;
|
|
944
|
+
if (typeof g !== "undefined") {
|
|
945
|
+
const proc = g.process;
|
|
946
|
+
if (typeof proc !== "undefined") {
|
|
947
|
+
const env = proc.env;
|
|
948
|
+
const isTest = !!(env?.VITEST || env?.NODE_ENV === "test" || env?.JEST_WORKER_ID);
|
|
949
|
+
const execArgv = proc.execArgv;
|
|
950
|
+
const hasFlag = Array.isArray(execArgv) && execArgv.some((a) => typeof a === "string" && a.startsWith("--localstorage-file"));
|
|
951
|
+
if (isTest || hasFlag) {
|
|
952
|
+
try {
|
|
953
|
+
const s = g.localStorage;
|
|
954
|
+
if (s && typeof s.getItem === "function") return s;
|
|
955
|
+
} catch {
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
return null;
|
|
959
|
+
}
|
|
960
|
+
try {
|
|
961
|
+
const s = g.localStorage;
|
|
962
|
+
if (s && typeof s.getItem === "function") return s;
|
|
963
|
+
} catch {
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
872
968
|
_loadFromStorage() {
|
|
873
|
-
|
|
969
|
+
const storage = this._getStorage();
|
|
970
|
+
if (!storage) return;
|
|
874
971
|
try {
|
|
875
|
-
const raw =
|
|
972
|
+
const raw = storage.getItem(this.key);
|
|
876
973
|
if (!raw) return;
|
|
877
974
|
const parsed = JSON.parse(raw);
|
|
878
975
|
if (parsed.token && parsed.refreshToken && parsed.user) {
|
|
@@ -883,22 +980,24 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
883
980
|
}
|
|
884
981
|
}
|
|
885
982
|
_persist() {
|
|
886
|
-
|
|
983
|
+
const storage = this._getStorage();
|
|
984
|
+
if (!storage) return;
|
|
887
985
|
const data = {
|
|
888
986
|
token: this.token,
|
|
889
987
|
refreshToken: this.refreshToken,
|
|
890
988
|
user: this.user
|
|
891
989
|
};
|
|
892
990
|
try {
|
|
893
|
-
|
|
991
|
+
storage.setItem(this.key, JSON.stringify(data));
|
|
894
992
|
} catch {
|
|
895
993
|
this._emitStorageBlocked("persist");
|
|
896
994
|
}
|
|
897
995
|
}
|
|
898
996
|
_removeStorage() {
|
|
899
|
-
|
|
997
|
+
const storage = this._getStorage();
|
|
998
|
+
if (!storage) return;
|
|
900
999
|
try {
|
|
901
|
-
|
|
1000
|
+
storage.removeItem(this.key);
|
|
902
1001
|
} catch {
|
|
903
1002
|
this._emitStorageBlocked("removeStorage");
|
|
904
1003
|
}
|
package/package.json
CHANGED