gbaas_sdk 3.1.0
gbaas_sdk: ^3.1.0 copied to clipboard
Dart SDK for BaaS (Backend as a Service) - auth, database, storage, realtime, functions, admin APIs.
3.1.0 — 2026-07-28 #
Protocolo por TÓPICO del hub realtime, agregado sin tocar la API por tabla: las apps publicadas siguen funcionando igual.
Added #
- Realtime por tópico:
subscribeTopic(topic, cb)devuelve la mismaRealtimeSubscriptioncancelable de siempre, ypublishTopic(topic, payload)publica hacia el hub (la ubicación del conductor viaja por acá, autorizada server-side, en vez de por un canal broadcast sin authz). - Detección del router: el cliente lee
GET /api/config→realtime.routery habla el protocolo que ese servidor entiende. Si el campo no está, la red falla o el valor es desconocido, cae alegacy— el default SEGURO: un cliente que asuma tópicos contra un servidor legacy queda mudo. - Estado de conexión observable + señal de reconectado (solo desde la segunda conexión: la primera no perdió nada). Es lo que permite refetchear al volver, porque el socket no guarda lo que pasó mientras estuvo caído.
- Frames de control propagados:
subscribe_deniedysubscription_revokedllegan al llamador en vez de morir en silencio — un tópico denegado es un bug de permisos que hay que ver.
Notes #
- Las suscripciones por tópico se re-registran solas al reconectar, igual que las de tabla.
- El socket sigue siendo LATENCIA, no garantía: el push server-side es el que garantiza la entrega de una oferta.
3.0.0 — 2026-06-05 #
Validated end-to-end (32 live checks) against a running golang-baas server.
BREAKING CHANGES #
auth.verifyMfa({ tempToken })→auth.verifyMfa({ mfaToken }). The backend readsmfa_token; the oldtempTokenwas never sent, so MFA login could not complete.auth.enableMfa({ code })→auth.enableMfa({ required String secret, required String code }). The backend re-validates the TOTP code against the setupsecret. Pass thesecretfromsetupMfa().- Removed
storage.moveFile(...)andstorage.copyFile(...)— the backend has no move/copy routes (they always 404'd). storage.deleteFiles({ bucket, paths })→storage.deleteFilesByIds(List<String> ids).
Added #
database.rpc(fn, { params, get })— invoke PL/pgSQL functions (PostgREST.rpc()parity).- QueryBuilder:
contains/containedBy/overlaps(cs/cd/ov),textSearch(fts/plfts/phfts/wfts),not(condition),and/notAnd/notOrgroups,QueryBuilder.cond(...), multi-columnorderBy, workingcount()(Prefer:count=exact → Content-Range),insertMany(),deleteWhere(). - Auth:
signInAnonymously(),requestOtp(...),verifyOtp(...),upgradeToAccount(...). RateLimitException(HTTP 429) with a parsed retry hint.
Fixed #
executeRawSql()reads the{ "data": ... }envelope (previously read a non-existentrowskey and dropped every row).functions.executeCode()parsesduration_ms/logs;functions.update()upserts by name (noPUTroute exists).storage.download()streams via the backend download route;getFile/download/deletereturn 404 instead of a null-pointer 500.- RLS denials surface as
403, malformed ids as400(instead of500).
2.0.0 — 2026-05-22 #
BREAKING CHANGES #
- Renamed
from(table).inList(col, values)tofrom(table).inFilter(col, values). The old name emitted broken?col=inList.[a, b]syntax — the server silently ignored it and returned zero rows. The new method emits the PostgREST-correct?col=in.(a,b)(values containing,,(,), or"are wrapped in double quotes). storage.upload(bucket: ...)now sends the multipart fieldbucket_idinstead ofbucketand preserves thepathfield. Calls that depended on the previous (broken) behavior landed files in the server's default bucket — re-verify destinations after upgrading.storage.getFile(id)now returnsStorageFileWithUrl(metadata + presigned URL) instead ofStorageFile. Access metadata via.fileand the 15-minute presigned URL via.url.- Removed
auth.updateProfile(...)(calledPUT /api/users/me, a route the backend never implemented). The only working update endpoint is the adminPUT /api/users/{id}and that does not belong on the self-serviceAuthClientsurface. auth.restoreSession()now optionally reads its token fromSessionStoragewhen no argument is provided; thetokenparameter became positional+optional.BaasClient.setAccessTokenandclearAuthare nowasync(they persist throughSessionStorage).- New
BaasClientconstructor parametersessionStorage(defaults toInMemorySessionStorage).
Security #
- Fixed
validateResetTokenreturningtruefor both valid and invalid tokens — the backend always responds 200 with{"valid": bool}, so the previous "did it 200?" check passed everything through. Anyone shipping a password-reset UI built on 1.x should upgrade.
Added #
BaasClient.onAuthStateChangebroadcast stream emittingAuthState.signedIn,signedOut,sessionExpired.SessionStorageinterface (+ defaultInMemorySessionStorage) for pluggable token persistence. Flutter apps wireflutter_secure_storage/shared_preferencesvia an adapter — keeps the SDK pure Dart.- Centralized 401 handling: any authenticated request that comes back 401 clears the local + persisted session, emits
sessionExpired+signedOut, and throws a newUnauthorizedException(subtype ofAuthException). A 401 without a token (i.e. login with bad creds) stays as a plainAuthExceptionwith no side effects. - Realtime: parser for concatenated JSON frames (
{}{}{}in a single WebSocket message) honoring strings/escapes.
Fixed #
getProfile()andrestoreSession()now call the realGET /api/profileroute instead of the phantom/api/users/me.- Query builder operators
isNull,isNotNullemitis.null/not.is.null(PostgREST syntax) instead ofisNull.null. example/main.dartnow compiles against the 2.0 API and demonstratesonAuthStateChange.
Documented #
- Realtime backend limitation (
role=adminis the only role that currently receives events) is now explicitly noted onRealtimeClientandsubscribe()dartdoc, and inKNOWN_ISSUES.md.
Known issues (tracked for v2.1+) #
- Several auth methods (
setupMfa,enableMfa,verifyMfa, OAuth provider config) remain on the API surface but their server-side counterparts have shape mismatches not addressed in 2.0.0. SeeKNOWN_ISSUES.md.
1.0.4 #
- Fixed: await WebSocket handshake (
channel.ready) before marking connected - Added: 30s heartbeat ping to detect dead connections
- Added:
Cache-Control: no-cacheheader on all GET requests to bypass stale Redis cache - Fixed: increased max reconnect attempts from 5 to 10
- Removed: dead subscribe/unsubscribe messages (server broadcasts all events)
- Fixed: auto-disconnect when last subscription removed
- Fixed: proper cleanup of channel/timers on error and disconnect
1.0.3 #
- Fixed Dart SDK constraint to >=3.0.0
- Updated web_socket_channel to support v2.x and v3.x
1.0.2 #
- Minor fixes
1.0.1 #
- Updated web_socket_channel to support v2.x and v3.x
- Updated README with complete documentation for all 23 modules
1.0.0 #
- Initial release
- Auth: login, register, MFA, OAuth, password reset, email verification
- Database: CRUD, query builder with filters, raw SQL, export
- Storage: upload, download, buckets, presigned URLs
- Realtime: WebSocket subscriptions with auto-reconnect
- Functions: edge function execution, hooks
- Admin: webhooks, policies, API keys, backups, migrations, email, jobs, env vars, branches, log drains, audit, metrics, IP whitelist, CORS origins, environments, search, users, GraphQL