@aurabase/core 0.7.3 → 0.7.5

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 CHANGED
@@ -563,16 +563,69 @@ function unwrapEnvelope(body) {
563
563
  }
564
564
  return body;
565
565
  }
566
+ function quoteUnsafeIntsInJson(raw) {
567
+ let out = "";
568
+ let i = 0;
569
+ const n = raw.length;
570
+ while (i < n) {
571
+ const ch = raw[i];
572
+ if (ch === '"') {
573
+ const start = i++;
574
+ while (i < n) {
575
+ const c = raw[i];
576
+ if (c === "\\") {
577
+ i += 2;
578
+ continue;
579
+ }
580
+ if (c === '"') {
581
+ i++;
582
+ break;
583
+ }
584
+ i++;
585
+ }
586
+ out += raw.slice(start, i);
587
+ continue;
588
+ }
589
+ if (ch === "-" || ch >= "0" && ch <= "9") {
590
+ const prev = out.trimEnd().slice(-1);
591
+ const isValueStart = prev === "" || prev === ":" || prev === "[" || prev === ",";
592
+ const start = i;
593
+ if (ch === "-") i++;
594
+ const digitStart = i;
595
+ while (i < n && raw[i] >= "0" && raw[i] <= "9") i++;
596
+ const isFloatOrExp = i < n && (raw[i] === "." || raw[i] === "e" || raw[i] === "E");
597
+ if (isFloatOrExp) {
598
+ while (i < n && /[0-9eE+\-.]/.test(raw[i])) i++;
599
+ out += raw.slice(start, i);
600
+ continue;
601
+ }
602
+ const token = raw.slice(start, i);
603
+ const digits = raw.slice(digitStart, i);
604
+ if (isValueStart && digits.length >= 16) {
605
+ const num = Number(token);
606
+ if (!Number.isSafeInteger(num)) {
607
+ out += `"${token}"`;
608
+ continue;
609
+ }
610
+ }
611
+ out += token;
612
+ continue;
613
+ }
614
+ out += ch;
615
+ i++;
616
+ }
617
+ return out;
618
+ }
566
619
  function parseJsonBody(raw, parseBigIntAsString) {
567
620
  if (parseBigIntAsString) {
568
- const safe = raw.replace(/([:\[,]\s*)(-?\d{16,})(?=\s*[,}\]])/g, '$1"$2"');
569
- return JSON.parse(safe);
621
+ return JSON.parse(quoteUnsafeIntsInJson(raw));
570
622
  }
571
623
  return JSON.parse(raw);
572
624
  }
573
625
  function parseContentRangeTotal(headerVal) {
574
626
  return parseContentRangeDetails(headerVal).total;
575
627
  }
628
+ var SERVER_MAX_ROWS = 1e3;
576
629
  function parseContentRangeDetails(headerVal) {
577
630
  if (!headerVal) return { total: void 0, hasMore: void 0 };
578
631
  const parts = headerVal.split("/");
@@ -592,7 +645,7 @@ function parseContentRangeDetails(headerVal) {
592
645
  if (!Number.isNaN(start) && !Number.isNaN(end)) {
593
646
  if (total !== void 0) {
594
647
  hasMore = end + 1 < total;
595
- } else if (end - start + 1 >= 1e3) {
648
+ } else if (end - start + 1 >= SERVER_MAX_ROWS) {
596
649
  hasMore = true;
597
650
  }
598
651
  }
@@ -839,12 +892,14 @@ async function fetchWithAuth(url, init, client) {
839
892
  await maybeRefresh(client);
840
893
  }
841
894
  const method = (init.method ?? "GET").toUpperCase();
842
- const retryEnabled = !init.skipRetry && (client.retryConfig?.enabled ?? true) && isRetryableMethod(method);
895
+ const retryAllowed = !init.skipRetry && (client.retryConfig?.enabled ?? true);
896
+ const retryEnabled = retryAllowed && isRetryableMethod(method);
843
897
  const maxRetries = client.retryConfig?.maxRetries ?? DEFAULT_MAX_RETRIES;
844
898
  const store = client.authStore;
845
899
  const isFormData = typeof FormData !== "undefined" && init.body instanceof FormData;
900
+ const isBinary = typeof Blob !== "undefined" && init.body instanceof Blob || typeof ArrayBuffer !== "undefined" && init.body instanceof ArrayBuffer || typeof Uint8Array !== "undefined" && init.body instanceof Uint8Array;
846
901
  const timeoutMs = client.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
847
- const applyTimeout = timeoutMs > 0 && init.signal === void 0 && !isFormData;
902
+ const applyTimeout = timeoutMs > 0 && init.signal === void 0 && !isFormData && !isBinary;
848
903
  const bodyTimeoutMs = init.signal === void 0 ? timeoutMs : 0;
849
904
  let attempt = 0;
850
905
  for (; ; ) {
@@ -852,12 +907,13 @@ async function fetchWithAuth(url, init, client) {
852
907
  if (client.apiKey) {
853
908
  headers["apikey"] = client.apiKey;
854
909
  }
910
+ const isServiceRole = client.apiKey?.startsWith("aura_sk_") ?? false;
855
911
  if (init.authToken) {
856
912
  headers["Authorization"] = `Bearer ${init.authToken}`;
857
- } else if (store.token) {
913
+ } else if (store.token && !isServiceRole) {
858
914
  headers["Authorization"] = `Bearer ${store.token}`;
859
915
  }
860
- if (!isFormData && init.body !== void 0) {
916
+ if (!isFormData && !isBinary && init.body !== void 0) {
861
917
  headers["Content-Type"] = headers["Content-Type"] ?? "application/json";
862
918
  }
863
919
  if (attempt > 0) {
@@ -884,7 +940,15 @@ async function fetchWithAuth(url, init, client) {
884
940
  signal: attemptSignal
885
941
  };
886
942
  if (init.body !== void 0) {
887
- requestInit.body = isFormData ? init.body : serializeBody(init.body);
943
+ if (isFormData) {
944
+ requestInit.body = init.body;
945
+ } else if (isBinary) {
946
+ requestInit.body = init.body;
947
+ } else if (typeof init.body === "string") {
948
+ requestInit.body = init.body;
949
+ } else {
950
+ requestInit.body = serializeBody(init.body);
951
+ }
888
952
  }
889
953
  let res;
890
954
  try {
@@ -912,7 +976,7 @@ async function fetchWithAuth(url, init, client) {
912
976
  };
913
977
  }
914
978
  clearTimeoutTimer();
915
- if (retryEnabled && attempt < maxRetries && isRetryableStatus(res.status)) {
979
+ if ((retryEnabled || retryAllowed && res.status === 429) && attempt < maxRetries && isRetryableStatus(res.status)) {
916
980
  const delay = Math.min(
917
981
  parseRetryAfter(res.headers.get("Retry-After")) ?? computeBackoff(attempt),
918
982
  RETRY_AFTER_CAP_MS
@@ -1009,7 +1073,29 @@ async function fetchWithAuth(url, init, client) {
1009
1073
  const cr = res.headers.get("content-range") ?? res.headers.get("Content-Range");
1010
1074
  const crDetails = parseContentRangeDetails(cr);
1011
1075
  const totalFromCr = crDetails.total;
1012
- const hasMore = crDetails.hasMore;
1076
+ let hasMore = crDetails.hasMore;
1077
+ if (hasMore && Array.isArray(unwrapped)) {
1078
+ let requestedLimit;
1079
+ try {
1080
+ const parsedUrl = new URL(url, "http://localhost");
1081
+ const limitParam = parsedUrl.searchParams.get("limit");
1082
+ if (limitParam !== null) {
1083
+ const n = parseInt(limitParam, 10);
1084
+ if (!Number.isNaN(n) && n >= 0) requestedLimit = n;
1085
+ }
1086
+ } catch {
1087
+ }
1088
+ const preferHdr = String(
1089
+ init.headers?.["Prefer"] ?? init.headers?.["prefer"] ?? ""
1090
+ );
1091
+ const isPlanned = preferHdr.includes("count=planned");
1092
+ const effectiveLimit = Math.min(requestedLimit ?? SERVER_MAX_ROWS, SERVER_MAX_ROWS);
1093
+ if (requestedLimit !== void 0 && unwrapped.length < effectiveLimit) {
1094
+ hasMore = false;
1095
+ } else if (isPlanned && unwrapped.length < effectiveLimit) {
1096
+ hasMore = false;
1097
+ }
1098
+ }
1013
1099
  const rawMeta = body !== null && typeof body === "object" && "meta" in body ? body.meta : void 0;
1014
1100
  const meta = rawMeta !== void 0 ? { ...rawMeta, ...hasMore !== void 0 ? { has_more: hasMore } : {} } : totalFromCr !== void 0 || hasMore !== void 0 ? {
1015
1101
  ...totalFromCr !== void 0 ? { total: totalFromCr } : {},
@@ -1019,7 +1105,7 @@ async function fetchWithAuth(url, init, client) {
1019
1105
  const isDev = Boolean(client.debug) || typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
1020
1106
  if (hasMore && isDev) {
1021
1107
  console.warn(
1022
- "[Aurabase] Query result reached pagination limit of 1,000 rows. Use .range() to paginate further results."
1108
+ `[Aurabase] Query result was capped at ${SERVER_MAX_ROWS} rows by the server (meta.has_more = true): more rows match. Paginate with .range(from, to), .offset(n) or a keyset filter (.gt("id", lastId).order("id")).`
1023
1109
  );
1024
1110
  }
1025
1111
  if (unwrapped === null) {
@@ -1206,6 +1292,7 @@ var LocalAuthStore = class extends BaseAuthStore {
1206
1292
 
1207
1293
  exports.AUTH_SETTINGS_WRITABLE_FIELDS = AUTH_SETTINGS_WRITABLE_FIELDS;
1208
1294
  exports.AuraError = AuraError;
1295
+ exports.AurabaseError = AuraError;
1209
1296
  exports.BaseAuthStore = BaseAuthStore;
1210
1297
  exports.BaseService = BaseService;
1211
1298
  exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES;
package/dist/index.d.cts CHANGED
@@ -426,7 +426,7 @@ interface QueryFilter {
426
426
  op: string;
427
427
  value: unknown;
428
428
  }
429
- type CountMode = 'exact' | 'estimated';
429
+ type CountMode = 'exact' | 'planned' | 'estimated';
430
430
  interface QueryOptions {
431
431
  select?: string[];
432
432
  filters?: QueryFilter[];
@@ -442,21 +442,35 @@ interface SchemaColumn {
442
442
  nullable: boolean;
443
443
  unique: boolean;
444
444
  default_val?: string | null;
445
+ is_generated?: boolean;
446
+ is_identity?: boolean;
447
+ identity_generation?: string | null;
445
448
  references?: {
446
449
  table: string;
447
450
  column: string;
448
451
  constraint_name?: string | null;
452
+ on_delete?: string | null;
449
453
  } | null;
450
454
  }
451
455
  interface SchemaIndex {
452
456
  name: string;
453
457
  columns: string[];
454
458
  unique: boolean;
459
+ method?: string | null;
460
+ where_clause?: string | null;
461
+ definition?: string | null;
462
+ }
463
+ interface SchemaCheckConstraint {
464
+ name: string;
465
+ expression: string;
455
466
  }
456
467
  interface SchemaTable {
457
468
  name: string;
458
469
  columns: SchemaColumn[];
459
470
  primary_key?: string;
471
+ primary_key_columns?: string[];
472
+ unique_constraints?: string[][];
473
+ check_constraints?: SchemaCheckConstraint[];
460
474
  indexes: SchemaIndex[];
461
475
  rls_enabled: boolean;
462
476
  realtime_enabled: boolean;
@@ -633,6 +647,14 @@ interface ImageTransform {
633
647
  resize?: 'cover' | 'contain' | 'fill';
634
648
  quality?: number;
635
649
  format?: 'origin' | 'jpeg' | 'png' | 'webp' | 'gif';
650
+ rotate?: 90 | 180 | 270;
651
+ flip_h?: boolean;
652
+ flip_v?: boolean;
653
+ }
654
+ interface UploadProgressEvent {
655
+ loaded: number;
656
+ total?: number;
657
+ percentage?: number;
636
658
  }
637
659
  interface StorageBucket {
638
660
  id: string;
@@ -2138,4 +2160,4 @@ declare class LocalAuthStore extends BaseAuthStore {
2138
2160
  private _removeStorage;
2139
2161
  }
2140
2162
 
2141
- 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 CookieOptions, 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 FunctionPermissions, 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 MfaFactorType, 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 OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, 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 ServerChannelRecoveredMsg, 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 StoredAuth, 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 };
2163
+ 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, AuraError as AurabaseError, 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 CookieOptions, 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 FunctionPermissions, 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 MfaFactorType, 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 OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, 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 SchemaCheckConstraint, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, 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 StoredAuth, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadProgressEvent, 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
@@ -426,7 +426,7 @@ interface QueryFilter {
426
426
  op: string;
427
427
  value: unknown;
428
428
  }
429
- type CountMode = 'exact' | 'estimated';
429
+ type CountMode = 'exact' | 'planned' | 'estimated';
430
430
  interface QueryOptions {
431
431
  select?: string[];
432
432
  filters?: QueryFilter[];
@@ -442,21 +442,35 @@ interface SchemaColumn {
442
442
  nullable: boolean;
443
443
  unique: boolean;
444
444
  default_val?: string | null;
445
+ is_generated?: boolean;
446
+ is_identity?: boolean;
447
+ identity_generation?: string | null;
445
448
  references?: {
446
449
  table: string;
447
450
  column: string;
448
451
  constraint_name?: string | null;
452
+ on_delete?: string | null;
449
453
  } | null;
450
454
  }
451
455
  interface SchemaIndex {
452
456
  name: string;
453
457
  columns: string[];
454
458
  unique: boolean;
459
+ method?: string | null;
460
+ where_clause?: string | null;
461
+ definition?: string | null;
462
+ }
463
+ interface SchemaCheckConstraint {
464
+ name: string;
465
+ expression: string;
455
466
  }
456
467
  interface SchemaTable {
457
468
  name: string;
458
469
  columns: SchemaColumn[];
459
470
  primary_key?: string;
471
+ primary_key_columns?: string[];
472
+ unique_constraints?: string[][];
473
+ check_constraints?: SchemaCheckConstraint[];
460
474
  indexes: SchemaIndex[];
461
475
  rls_enabled: boolean;
462
476
  realtime_enabled: boolean;
@@ -633,6 +647,14 @@ interface ImageTransform {
633
647
  resize?: 'cover' | 'contain' | 'fill';
634
648
  quality?: number;
635
649
  format?: 'origin' | 'jpeg' | 'png' | 'webp' | 'gif';
650
+ rotate?: 90 | 180 | 270;
651
+ flip_h?: boolean;
652
+ flip_v?: boolean;
653
+ }
654
+ interface UploadProgressEvent {
655
+ loaded: number;
656
+ total?: number;
657
+ percentage?: number;
636
658
  }
637
659
  interface StorageBucket {
638
660
  id: string;
@@ -2138,4 +2160,4 @@ declare class LocalAuthStore extends BaseAuthStore {
2138
2160
  private _removeStorage;
2139
2161
  }
2140
2162
 
2141
- 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 CookieOptions, 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 FunctionPermissions, 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 MfaFactorType, 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 OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, 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 ServerChannelRecoveredMsg, 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 StoredAuth, 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 };
2163
+ 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, AuraError as AurabaseError, 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 CookieOptions, 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 FunctionPermissions, 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 MfaFactorType, 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 OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, 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 SchemaCheckConstraint, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, 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 StoredAuth, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadProgressEvent, 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
@@ -561,16 +561,69 @@ function unwrapEnvelope(body) {
561
561
  }
562
562
  return body;
563
563
  }
564
+ function quoteUnsafeIntsInJson(raw) {
565
+ let out = "";
566
+ let i = 0;
567
+ const n = raw.length;
568
+ while (i < n) {
569
+ const ch = raw[i];
570
+ if (ch === '"') {
571
+ const start = i++;
572
+ while (i < n) {
573
+ const c = raw[i];
574
+ if (c === "\\") {
575
+ i += 2;
576
+ continue;
577
+ }
578
+ if (c === '"') {
579
+ i++;
580
+ break;
581
+ }
582
+ i++;
583
+ }
584
+ out += raw.slice(start, i);
585
+ continue;
586
+ }
587
+ if (ch === "-" || ch >= "0" && ch <= "9") {
588
+ const prev = out.trimEnd().slice(-1);
589
+ const isValueStart = prev === "" || prev === ":" || prev === "[" || prev === ",";
590
+ const start = i;
591
+ if (ch === "-") i++;
592
+ const digitStart = i;
593
+ while (i < n && raw[i] >= "0" && raw[i] <= "9") i++;
594
+ const isFloatOrExp = i < n && (raw[i] === "." || raw[i] === "e" || raw[i] === "E");
595
+ if (isFloatOrExp) {
596
+ while (i < n && /[0-9eE+\-.]/.test(raw[i])) i++;
597
+ out += raw.slice(start, i);
598
+ continue;
599
+ }
600
+ const token = raw.slice(start, i);
601
+ const digits = raw.slice(digitStart, i);
602
+ if (isValueStart && digits.length >= 16) {
603
+ const num = Number(token);
604
+ if (!Number.isSafeInteger(num)) {
605
+ out += `"${token}"`;
606
+ continue;
607
+ }
608
+ }
609
+ out += token;
610
+ continue;
611
+ }
612
+ out += ch;
613
+ i++;
614
+ }
615
+ return out;
616
+ }
564
617
  function parseJsonBody(raw, parseBigIntAsString) {
565
618
  if (parseBigIntAsString) {
566
- const safe = raw.replace(/([:\[,]\s*)(-?\d{16,})(?=\s*[,}\]])/g, '$1"$2"');
567
- return JSON.parse(safe);
619
+ return JSON.parse(quoteUnsafeIntsInJson(raw));
568
620
  }
569
621
  return JSON.parse(raw);
570
622
  }
571
623
  function parseContentRangeTotal(headerVal) {
572
624
  return parseContentRangeDetails(headerVal).total;
573
625
  }
626
+ var SERVER_MAX_ROWS = 1e3;
574
627
  function parseContentRangeDetails(headerVal) {
575
628
  if (!headerVal) return { total: void 0, hasMore: void 0 };
576
629
  const parts = headerVal.split("/");
@@ -590,7 +643,7 @@ function parseContentRangeDetails(headerVal) {
590
643
  if (!Number.isNaN(start) && !Number.isNaN(end)) {
591
644
  if (total !== void 0) {
592
645
  hasMore = end + 1 < total;
593
- } else if (end - start + 1 >= 1e3) {
646
+ } else if (end - start + 1 >= SERVER_MAX_ROWS) {
594
647
  hasMore = true;
595
648
  }
596
649
  }
@@ -837,12 +890,14 @@ async function fetchWithAuth(url, init, client) {
837
890
  await maybeRefresh(client);
838
891
  }
839
892
  const method = (init.method ?? "GET").toUpperCase();
840
- const retryEnabled = !init.skipRetry && (client.retryConfig?.enabled ?? true) && isRetryableMethod(method);
893
+ const retryAllowed = !init.skipRetry && (client.retryConfig?.enabled ?? true);
894
+ const retryEnabled = retryAllowed && isRetryableMethod(method);
841
895
  const maxRetries = client.retryConfig?.maxRetries ?? DEFAULT_MAX_RETRIES;
842
896
  const store = client.authStore;
843
897
  const isFormData = typeof FormData !== "undefined" && init.body instanceof FormData;
898
+ const isBinary = typeof Blob !== "undefined" && init.body instanceof Blob || typeof ArrayBuffer !== "undefined" && init.body instanceof ArrayBuffer || typeof Uint8Array !== "undefined" && init.body instanceof Uint8Array;
844
899
  const timeoutMs = client.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
845
- const applyTimeout = timeoutMs > 0 && init.signal === void 0 && !isFormData;
900
+ const applyTimeout = timeoutMs > 0 && init.signal === void 0 && !isFormData && !isBinary;
846
901
  const bodyTimeoutMs = init.signal === void 0 ? timeoutMs : 0;
847
902
  let attempt = 0;
848
903
  for (; ; ) {
@@ -850,12 +905,13 @@ async function fetchWithAuth(url, init, client) {
850
905
  if (client.apiKey) {
851
906
  headers["apikey"] = client.apiKey;
852
907
  }
908
+ const isServiceRole = client.apiKey?.startsWith("aura_sk_") ?? false;
853
909
  if (init.authToken) {
854
910
  headers["Authorization"] = `Bearer ${init.authToken}`;
855
- } else if (store.token) {
911
+ } else if (store.token && !isServiceRole) {
856
912
  headers["Authorization"] = `Bearer ${store.token}`;
857
913
  }
858
- if (!isFormData && init.body !== void 0) {
914
+ if (!isFormData && !isBinary && init.body !== void 0) {
859
915
  headers["Content-Type"] = headers["Content-Type"] ?? "application/json";
860
916
  }
861
917
  if (attempt > 0) {
@@ -882,7 +938,15 @@ async function fetchWithAuth(url, init, client) {
882
938
  signal: attemptSignal
883
939
  };
884
940
  if (init.body !== void 0) {
885
- requestInit.body = isFormData ? init.body : serializeBody(init.body);
941
+ if (isFormData) {
942
+ requestInit.body = init.body;
943
+ } else if (isBinary) {
944
+ requestInit.body = init.body;
945
+ } else if (typeof init.body === "string") {
946
+ requestInit.body = init.body;
947
+ } else {
948
+ requestInit.body = serializeBody(init.body);
949
+ }
886
950
  }
887
951
  let res;
888
952
  try {
@@ -910,7 +974,7 @@ async function fetchWithAuth(url, init, client) {
910
974
  };
911
975
  }
912
976
  clearTimeoutTimer();
913
- if (retryEnabled && attempt < maxRetries && isRetryableStatus(res.status)) {
977
+ if ((retryEnabled || retryAllowed && res.status === 429) && attempt < maxRetries && isRetryableStatus(res.status)) {
914
978
  const delay = Math.min(
915
979
  parseRetryAfter(res.headers.get("Retry-After")) ?? computeBackoff(attempt),
916
980
  RETRY_AFTER_CAP_MS
@@ -1007,7 +1071,29 @@ async function fetchWithAuth(url, init, client) {
1007
1071
  const cr = res.headers.get("content-range") ?? res.headers.get("Content-Range");
1008
1072
  const crDetails = parseContentRangeDetails(cr);
1009
1073
  const totalFromCr = crDetails.total;
1010
- const hasMore = crDetails.hasMore;
1074
+ let hasMore = crDetails.hasMore;
1075
+ if (hasMore && Array.isArray(unwrapped)) {
1076
+ let requestedLimit;
1077
+ try {
1078
+ const parsedUrl = new URL(url, "http://localhost");
1079
+ const limitParam = parsedUrl.searchParams.get("limit");
1080
+ if (limitParam !== null) {
1081
+ const n = parseInt(limitParam, 10);
1082
+ if (!Number.isNaN(n) && n >= 0) requestedLimit = n;
1083
+ }
1084
+ } catch {
1085
+ }
1086
+ const preferHdr = String(
1087
+ init.headers?.["Prefer"] ?? init.headers?.["prefer"] ?? ""
1088
+ );
1089
+ const isPlanned = preferHdr.includes("count=planned");
1090
+ const effectiveLimit = Math.min(requestedLimit ?? SERVER_MAX_ROWS, SERVER_MAX_ROWS);
1091
+ if (requestedLimit !== void 0 && unwrapped.length < effectiveLimit) {
1092
+ hasMore = false;
1093
+ } else if (isPlanned && unwrapped.length < effectiveLimit) {
1094
+ hasMore = false;
1095
+ }
1096
+ }
1011
1097
  const rawMeta = body !== null && typeof body === "object" && "meta" in body ? body.meta : void 0;
1012
1098
  const meta = rawMeta !== void 0 ? { ...rawMeta, ...hasMore !== void 0 ? { has_more: hasMore } : {} } : totalFromCr !== void 0 || hasMore !== void 0 ? {
1013
1099
  ...totalFromCr !== void 0 ? { total: totalFromCr } : {},
@@ -1017,7 +1103,7 @@ async function fetchWithAuth(url, init, client) {
1017
1103
  const isDev = Boolean(client.debug) || typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
1018
1104
  if (hasMore && isDev) {
1019
1105
  console.warn(
1020
- "[Aurabase] Query result reached pagination limit of 1,000 rows. Use .range() to paginate further results."
1106
+ `[Aurabase] Query result was capped at ${SERVER_MAX_ROWS} rows by the server (meta.has_more = true): more rows match. Paginate with .range(from, to), .offset(n) or a keyset filter (.gt("id", lastId).order("id")).`
1021
1107
  );
1022
1108
  }
1023
1109
  if (unwrapped === null) {
@@ -1202,4 +1288,4 @@ var LocalAuthStore = class extends BaseAuthStore {
1202
1288
  }
1203
1289
  };
1204
1290
 
1205
- export { AUTH_SETTINGS_WRITABLE_FIELDS, AuraError, BaseAuthStore, BaseService, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, LocalAuthStore, RETRYABLE_METHODS, RETRYABLE_STATUS, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
1291
+ export { AUTH_SETTINGS_WRITABLE_FIELDS, AuraError, AuraError as AurabaseError, BaseAuthStore, BaseService, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, LocalAuthStore, RETRYABLE_METHODS, RETRYABLE_STATUS, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurabase/core",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Cœur du SDK Aurabase : fetch résilient, erreurs, stores auth, types de réponse (infrastructure interne)",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -48,7 +48,7 @@
48
48
  "@types/node": "20.14.15",
49
49
  "tsup": "^8.0.0",
50
50
  "typescript": "^5.5.0",
51
- "vitest": "^4.1.6"
51
+ "vitest": "^4.1.12"
52
52
  },
53
53
  "scripts": {
54
54
  "build": "tsup",