@spacelr/sdk 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +52 -19
- package/dist/index.d.ts +52 -19
- package/dist/index.js +60 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -516,6 +516,28 @@ declare class SpacelrEmailVerificationRequiredError extends SpacelrError {
|
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
type ConnectionState = 'connected' | 'reconnecting' | 'disconnected';
|
|
519
|
+
/** A single primitive `where` candidate. */
|
|
520
|
+
type WhereScalar = string | number | boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Multi-value `where` operators (Firestore-style) for realtime subscriptions:
|
|
523
|
+
* - `in`: the document field is a **scalar** equal to any candidate.
|
|
524
|
+
* - `array-contains-any`: the document field is an **array** sharing at least
|
|
525
|
+
* one element with the candidates.
|
|
526
|
+
*
|
|
527
|
+
* The single-value form (`where: { field: scalar }`) stays polymorphic — it
|
|
528
|
+
* matches a scalar field by equality OR an array field by element membership.
|
|
529
|
+
*
|
|
530
|
+
* Mirrors the server definition in `@spacelr-workspace/shared-types`
|
|
531
|
+
* (`realtime-where.ts`); the two must stay structurally identical.
|
|
532
|
+
*/
|
|
533
|
+
type WhereOperator = {
|
|
534
|
+
in: WhereScalar[];
|
|
535
|
+
} | {
|
|
536
|
+
'array-contains-any': WhereScalar[];
|
|
537
|
+
};
|
|
538
|
+
type WhereValue = WhereScalar | WhereOperator;
|
|
539
|
+
/** A realtime subscription `where` filter: field name → scalar or operator. */
|
|
540
|
+
type WhereFilter = Record<string, WhereValue>;
|
|
519
541
|
interface DatabaseChangeEvent {
|
|
520
542
|
type: 'insert' | 'update' | 'delete';
|
|
521
543
|
projectId: string;
|
|
@@ -553,7 +575,7 @@ interface StreamSubscriptionOptions {
|
|
|
553
575
|
projectId: string;
|
|
554
576
|
collectionName: string;
|
|
555
577
|
sinceId?: string;
|
|
556
|
-
where?:
|
|
578
|
+
where?: WhereFilter;
|
|
557
579
|
/**
|
|
558
580
|
* Called for each delivered event. Awaited — the cursor does NOT advance
|
|
559
581
|
* until this resolves. If the callback throws, the cursor is NOT advanced
|
|
@@ -584,7 +606,7 @@ declare class RealtimeClient {
|
|
|
584
606
|
private connectionStateListeners;
|
|
585
607
|
private streamSubscriptions;
|
|
586
608
|
constructor(config: RealtimeConfig);
|
|
587
|
-
subscribe(projectId: string, collectionName: string, callback: (event: DatabaseChangeEvent) => void, onError?: (error: Error) => void, where?:
|
|
609
|
+
subscribe(projectId: string, collectionName: string, callback: (event: DatabaseChangeEvent) => void, onError?: (error: Error) => void, where?: WhereFilter): Promise<() => void>;
|
|
588
610
|
/**
|
|
589
611
|
* Subscribe to a stream-mode collection using Redis Streams replay +
|
|
590
612
|
* cursor-based delivery. Parallel to `subscribe()` (which targets
|
|
@@ -1089,16 +1111,18 @@ interface SubscribeWithSnapshotOptions<T> {
|
|
|
1089
1111
|
* **Snapshot semantics** (full MongoDB query): supports operators like
|
|
1090
1112
|
* `{ status: { $in: [...] } }`, `{ ts: { $gt: ... } }`, etc.
|
|
1091
1113
|
*
|
|
1092
|
-
* **Live-stream semantics** (
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1114
|
+
* **Live-stream semantics** (top-level primitives only): this helper
|
|
1115
|
+
* forwards only top-level primitive values (`string | number | boolean`)
|
|
1116
|
+
* from the Mongo-query `where` to the live filter. MongoDB operators
|
|
1117
|
+
* (`$in`, `$gt`, …) are silently dropped at handshake time and are NOT
|
|
1118
|
+
* translated into the gateway's realtime `in` / `array-contains-any`
|
|
1119
|
+
* operators — the remaining primitive entries still apply, so a typical
|
|
1120
|
+
* chat-style `{ chatId: 'c1' }` filter works identically on both sides. If
|
|
1121
|
+
* you pass a mixed `{ chatId: 'c1', status: { $in: [...] } }`, the snapshot
|
|
1122
|
+
* is fully filtered but the live stream filters by `chatId` only; you may
|
|
1123
|
+
* receive `onChange` events for documents whose `status` is outside your
|
|
1124
|
+
* `$in` set. Re-check in the handler, or use `subscribeEvents()` directly
|
|
1125
|
+
* with a realtime `{ status: { in: [...] } }` operator for live filtering.
|
|
1102
1126
|
*/
|
|
1103
1127
|
where?: Record<string, unknown>;
|
|
1104
1128
|
sort?: Record<string, 1 | -1>;
|
|
@@ -1159,7 +1183,7 @@ interface SubscribeWithSnapshotOptions<T> {
|
|
|
1159
1183
|
interface SubscribeEventsHandlers<T = Record<string, unknown>> {
|
|
1160
1184
|
/** Cursor to resume from. Undefined = fresh subscription, deliver only new events. */
|
|
1161
1185
|
sinceId?: string;
|
|
1162
|
-
where?:
|
|
1186
|
+
where?: WhereFilter;
|
|
1163
1187
|
/**
|
|
1164
1188
|
* Optional resume-cursor store. When set, the SDK loads the previous cursor
|
|
1165
1189
|
* before subscribing and persists the new cursor after each delivered
|
|
@@ -1216,7 +1240,7 @@ interface StreamSubscription {
|
|
|
1216
1240
|
getCursor(): string | undefined;
|
|
1217
1241
|
}
|
|
1218
1242
|
interface SubscribeHandlers<T = Record<string, unknown>> {
|
|
1219
|
-
where?:
|
|
1243
|
+
where?: WhereFilter;
|
|
1220
1244
|
onInsert?: (doc: T & {
|
|
1221
1245
|
_id: string;
|
|
1222
1246
|
}) => void;
|
|
@@ -1546,6 +1570,11 @@ interface FunctionInvokeOptions {
|
|
|
1546
1570
|
*
|
|
1547
1571
|
* If `true` but the user is not signed in, the header is simply omitted —
|
|
1548
1572
|
* safe for `public` invokeMode.
|
|
1573
|
+
*
|
|
1574
|
+
* Note: for `authenticated`/`hybrid` invokeMode, the server additionally
|
|
1575
|
+
* requires the token's user to be a member of the target project — this
|
|
1576
|
+
* flag only controls whether the header is attached, not who the server
|
|
1577
|
+
* accepts.
|
|
1549
1578
|
*/
|
|
1550
1579
|
authenticated?: boolean;
|
|
1551
1580
|
payload?: Record<string, unknown>;
|
|
@@ -1564,10 +1593,14 @@ declare class FunctionsModule {
|
|
|
1564
1593
|
* `config.apiUrl` (which already carries the `/api/v1` prefix).
|
|
1565
1594
|
*
|
|
1566
1595
|
* Auth defaults, based on `invokeMode` semantics:
|
|
1567
|
-
* - webhook:
|
|
1568
|
-
* - authenticated:
|
|
1569
|
-
*
|
|
1570
|
-
* -
|
|
1596
|
+
* - webhook: pass `secret` → Authorization is NOT attached
|
|
1597
|
+
* - authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
1598
|
+
* caller must be a member of the target project
|
|
1599
|
+
* - public: pass nothing → Authorization is attached if logged in, else omitted
|
|
1600
|
+
* - hybrid: pass both `secret` and `authenticated: true`; JWT path
|
|
1601
|
+
* requires project membership like `authenticated`
|
|
1602
|
+
* - platform-authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
1603
|
+
* any signed-in user is accepted, still just attaches the bearer token
|
|
1571
1604
|
*
|
|
1572
1605
|
* To force a specific behaviour, set `authenticated` explicitly — it wins
|
|
1573
1606
|
* over the `secret`-based default.
|
|
@@ -1763,4 +1796,4 @@ interface SpacelrClient {
|
|
|
1763
1796
|
}
|
|
1764
1797
|
declare function createClient(config: SpacelrClientConfig): SpacelrClient;
|
|
1765
1798
|
|
|
1766
|
-
export { type ApiResponse, type AuthLostReason, type AuthState, type AuthStateListener, type AuthorizationUrlParams, BrowserTokenStorage, CodeChallengeMethod, type ConnectionState, CursorInvalidError, type CursorStorage, type DatabaseChangeEvent, type DownloadUrlResponse, type ExchangeCodeParams, type FileInfo, type FileListResponse, FileVisibility, ForbiddenError, type FunctionInvokeOptions, type FunctionInvokeResult, type GapReason, GrantType, type InitMultipartUploadParams, type InitMultipartUploadResponse, type JWK, type JWKSResponse, type ListFilesParams, type LoginParams, type LoginResponse, MemoryTokenStorage, NotFoundError, type OpenIDConfiguration, type PKCEChallenge, type PartEtag, type PasskeyAuthenticationOptionsJSON, type PasskeyAuthenticationResponseJSON, type PasskeyCredential, type PasskeyCredentialDescriptorJSON, type PasskeyLoginResponse, type PasskeyRegistrationOptionsJSON, type PasskeyRegistrationResponseJSON, type PasskeyRegistrationResult, type PushSubscriptionInfo, type QuotaInfo, type RegisterParams, type RegisterResponse, type Schedule, type ScheduleInvokeOptions, type ScheduleListOptions, type ScheduleStatus, type SearchOptions, ServerConfigError, type ShareFileParams, SharePermission, SpacelrAuthError, type SpacelrClient, type SpacelrClientConfig, SpacelrEmailVerificationRequiredError, SpacelrError, SpacelrNetworkError, SpacelrSearchFilterRequiredError, SpacelrTimeoutError, SpacelrTwoFactorRequiredError, type StoredTokens, type StreamGapInfo, type StreamSubscription, type SubscribeEventsHandlers, type SubscribeHandlers, type SubscribeWithSnapshotOptions, type TimelineAndFilter, TimelineError, type TimelineFieldFilter, type TimelineFilter, type TimelineLeafFilter, TimelineModule, type TimelineOrderBy, type TimelineQueryOptions, type TimelineQueryResponse, type TimelineScalar, type TimelineSourceStats, TimeoutError, type TokenResponse, type TokenStorage, type TwoFactorResponse, type TwoFactorVerifyParams, type UnshareFileParams, type UploadFileParams, type UploadLargeFileParams, type UploadProgress, type UserInfo, type UserProfile, ValidationError, type VapidKeyResponse, createClient, generatePKCEChallenge, localStorageCursorStorage, memoryCursorStorage };
|
|
1799
|
+
export { type ApiResponse, type AuthLostReason, type AuthState, type AuthStateListener, type AuthorizationUrlParams, BrowserTokenStorage, CodeChallengeMethod, type ConnectionState, CursorInvalidError, type CursorStorage, type DatabaseChangeEvent, type DownloadUrlResponse, type ExchangeCodeParams, type FileInfo, type FileListResponse, FileVisibility, ForbiddenError, type FunctionInvokeOptions, type FunctionInvokeResult, type GapReason, GrantType, type InitMultipartUploadParams, type InitMultipartUploadResponse, type JWK, type JWKSResponse, type ListFilesParams, type LoginParams, type LoginResponse, MemoryTokenStorage, NotFoundError, type OpenIDConfiguration, type PKCEChallenge, type PartEtag, type PasskeyAuthenticationOptionsJSON, type PasskeyAuthenticationResponseJSON, type PasskeyCredential, type PasskeyCredentialDescriptorJSON, type PasskeyLoginResponse, type PasskeyRegistrationOptionsJSON, type PasskeyRegistrationResponseJSON, type PasskeyRegistrationResult, type PushSubscriptionInfo, type QuotaInfo, type RegisterParams, type RegisterResponse, type Schedule, type ScheduleInvokeOptions, type ScheduleListOptions, type ScheduleStatus, type SearchOptions, ServerConfigError, type ShareFileParams, SharePermission, SpacelrAuthError, type SpacelrClient, type SpacelrClientConfig, SpacelrEmailVerificationRequiredError, SpacelrError, SpacelrNetworkError, SpacelrSearchFilterRequiredError, SpacelrTimeoutError, SpacelrTwoFactorRequiredError, type StoredTokens, type StreamGapInfo, type StreamSubscription, type SubscribeEventsHandlers, type SubscribeHandlers, type SubscribeWithSnapshotOptions, type TimelineAndFilter, TimelineError, type TimelineFieldFilter, type TimelineFilter, type TimelineLeafFilter, TimelineModule, type TimelineOrderBy, type TimelineQueryOptions, type TimelineQueryResponse, type TimelineScalar, type TimelineSourceStats, TimeoutError, type TokenResponse, type TokenStorage, type TwoFactorResponse, type TwoFactorVerifyParams, type UnshareFileParams, type UploadFileParams, type UploadLargeFileParams, type UploadProgress, type UserInfo, type UserProfile, ValidationError, type VapidKeyResponse, type WhereFilter, type WhereOperator, type WhereScalar, type WhereValue, createClient, generatePKCEChallenge, localStorageCursorStorage, memoryCursorStorage };
|
package/dist/index.d.ts
CHANGED
|
@@ -516,6 +516,28 @@ declare class SpacelrEmailVerificationRequiredError extends SpacelrError {
|
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
type ConnectionState = 'connected' | 'reconnecting' | 'disconnected';
|
|
519
|
+
/** A single primitive `where` candidate. */
|
|
520
|
+
type WhereScalar = string | number | boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Multi-value `where` operators (Firestore-style) for realtime subscriptions:
|
|
523
|
+
* - `in`: the document field is a **scalar** equal to any candidate.
|
|
524
|
+
* - `array-contains-any`: the document field is an **array** sharing at least
|
|
525
|
+
* one element with the candidates.
|
|
526
|
+
*
|
|
527
|
+
* The single-value form (`where: { field: scalar }`) stays polymorphic — it
|
|
528
|
+
* matches a scalar field by equality OR an array field by element membership.
|
|
529
|
+
*
|
|
530
|
+
* Mirrors the server definition in `@spacelr-workspace/shared-types`
|
|
531
|
+
* (`realtime-where.ts`); the two must stay structurally identical.
|
|
532
|
+
*/
|
|
533
|
+
type WhereOperator = {
|
|
534
|
+
in: WhereScalar[];
|
|
535
|
+
} | {
|
|
536
|
+
'array-contains-any': WhereScalar[];
|
|
537
|
+
};
|
|
538
|
+
type WhereValue = WhereScalar | WhereOperator;
|
|
539
|
+
/** A realtime subscription `where` filter: field name → scalar or operator. */
|
|
540
|
+
type WhereFilter = Record<string, WhereValue>;
|
|
519
541
|
interface DatabaseChangeEvent {
|
|
520
542
|
type: 'insert' | 'update' | 'delete';
|
|
521
543
|
projectId: string;
|
|
@@ -553,7 +575,7 @@ interface StreamSubscriptionOptions {
|
|
|
553
575
|
projectId: string;
|
|
554
576
|
collectionName: string;
|
|
555
577
|
sinceId?: string;
|
|
556
|
-
where?:
|
|
578
|
+
where?: WhereFilter;
|
|
557
579
|
/**
|
|
558
580
|
* Called for each delivered event. Awaited — the cursor does NOT advance
|
|
559
581
|
* until this resolves. If the callback throws, the cursor is NOT advanced
|
|
@@ -584,7 +606,7 @@ declare class RealtimeClient {
|
|
|
584
606
|
private connectionStateListeners;
|
|
585
607
|
private streamSubscriptions;
|
|
586
608
|
constructor(config: RealtimeConfig);
|
|
587
|
-
subscribe(projectId: string, collectionName: string, callback: (event: DatabaseChangeEvent) => void, onError?: (error: Error) => void, where?:
|
|
609
|
+
subscribe(projectId: string, collectionName: string, callback: (event: DatabaseChangeEvent) => void, onError?: (error: Error) => void, where?: WhereFilter): Promise<() => void>;
|
|
588
610
|
/**
|
|
589
611
|
* Subscribe to a stream-mode collection using Redis Streams replay +
|
|
590
612
|
* cursor-based delivery. Parallel to `subscribe()` (which targets
|
|
@@ -1089,16 +1111,18 @@ interface SubscribeWithSnapshotOptions<T> {
|
|
|
1089
1111
|
* **Snapshot semantics** (full MongoDB query): supports operators like
|
|
1090
1112
|
* `{ status: { $in: [...] } }`, `{ ts: { $gt: ... } }`, etc.
|
|
1091
1113
|
*
|
|
1092
|
-
* **Live-stream semantics** (
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1114
|
+
* **Live-stream semantics** (top-level primitives only): this helper
|
|
1115
|
+
* forwards only top-level primitive values (`string | number | boolean`)
|
|
1116
|
+
* from the Mongo-query `where` to the live filter. MongoDB operators
|
|
1117
|
+
* (`$in`, `$gt`, …) are silently dropped at handshake time and are NOT
|
|
1118
|
+
* translated into the gateway's realtime `in` / `array-contains-any`
|
|
1119
|
+
* operators — the remaining primitive entries still apply, so a typical
|
|
1120
|
+
* chat-style `{ chatId: 'c1' }` filter works identically on both sides. If
|
|
1121
|
+
* you pass a mixed `{ chatId: 'c1', status: { $in: [...] } }`, the snapshot
|
|
1122
|
+
* is fully filtered but the live stream filters by `chatId` only; you may
|
|
1123
|
+
* receive `onChange` events for documents whose `status` is outside your
|
|
1124
|
+
* `$in` set. Re-check in the handler, or use `subscribeEvents()` directly
|
|
1125
|
+
* with a realtime `{ status: { in: [...] } }` operator for live filtering.
|
|
1102
1126
|
*/
|
|
1103
1127
|
where?: Record<string, unknown>;
|
|
1104
1128
|
sort?: Record<string, 1 | -1>;
|
|
@@ -1159,7 +1183,7 @@ interface SubscribeWithSnapshotOptions<T> {
|
|
|
1159
1183
|
interface SubscribeEventsHandlers<T = Record<string, unknown>> {
|
|
1160
1184
|
/** Cursor to resume from. Undefined = fresh subscription, deliver only new events. */
|
|
1161
1185
|
sinceId?: string;
|
|
1162
|
-
where?:
|
|
1186
|
+
where?: WhereFilter;
|
|
1163
1187
|
/**
|
|
1164
1188
|
* Optional resume-cursor store. When set, the SDK loads the previous cursor
|
|
1165
1189
|
* before subscribing and persists the new cursor after each delivered
|
|
@@ -1216,7 +1240,7 @@ interface StreamSubscription {
|
|
|
1216
1240
|
getCursor(): string | undefined;
|
|
1217
1241
|
}
|
|
1218
1242
|
interface SubscribeHandlers<T = Record<string, unknown>> {
|
|
1219
|
-
where?:
|
|
1243
|
+
where?: WhereFilter;
|
|
1220
1244
|
onInsert?: (doc: T & {
|
|
1221
1245
|
_id: string;
|
|
1222
1246
|
}) => void;
|
|
@@ -1546,6 +1570,11 @@ interface FunctionInvokeOptions {
|
|
|
1546
1570
|
*
|
|
1547
1571
|
* If `true` but the user is not signed in, the header is simply omitted —
|
|
1548
1572
|
* safe for `public` invokeMode.
|
|
1573
|
+
*
|
|
1574
|
+
* Note: for `authenticated`/`hybrid` invokeMode, the server additionally
|
|
1575
|
+
* requires the token's user to be a member of the target project — this
|
|
1576
|
+
* flag only controls whether the header is attached, not who the server
|
|
1577
|
+
* accepts.
|
|
1549
1578
|
*/
|
|
1550
1579
|
authenticated?: boolean;
|
|
1551
1580
|
payload?: Record<string, unknown>;
|
|
@@ -1564,10 +1593,14 @@ declare class FunctionsModule {
|
|
|
1564
1593
|
* `config.apiUrl` (which already carries the `/api/v1` prefix).
|
|
1565
1594
|
*
|
|
1566
1595
|
* Auth defaults, based on `invokeMode` semantics:
|
|
1567
|
-
* - webhook:
|
|
1568
|
-
* - authenticated:
|
|
1569
|
-
*
|
|
1570
|
-
* -
|
|
1596
|
+
* - webhook: pass `secret` → Authorization is NOT attached
|
|
1597
|
+
* - authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
1598
|
+
* caller must be a member of the target project
|
|
1599
|
+
* - public: pass nothing → Authorization is attached if logged in, else omitted
|
|
1600
|
+
* - hybrid: pass both `secret` and `authenticated: true`; JWT path
|
|
1601
|
+
* requires project membership like `authenticated`
|
|
1602
|
+
* - platform-authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
1603
|
+
* any signed-in user is accepted, still just attaches the bearer token
|
|
1571
1604
|
*
|
|
1572
1605
|
* To force a specific behaviour, set `authenticated` explicitly — it wins
|
|
1573
1606
|
* over the `secret`-based default.
|
|
@@ -1763,4 +1796,4 @@ interface SpacelrClient {
|
|
|
1763
1796
|
}
|
|
1764
1797
|
declare function createClient(config: SpacelrClientConfig): SpacelrClient;
|
|
1765
1798
|
|
|
1766
|
-
export { type ApiResponse, type AuthLostReason, type AuthState, type AuthStateListener, type AuthorizationUrlParams, BrowserTokenStorage, CodeChallengeMethod, type ConnectionState, CursorInvalidError, type CursorStorage, type DatabaseChangeEvent, type DownloadUrlResponse, type ExchangeCodeParams, type FileInfo, type FileListResponse, FileVisibility, ForbiddenError, type FunctionInvokeOptions, type FunctionInvokeResult, type GapReason, GrantType, type InitMultipartUploadParams, type InitMultipartUploadResponse, type JWK, type JWKSResponse, type ListFilesParams, type LoginParams, type LoginResponse, MemoryTokenStorage, NotFoundError, type OpenIDConfiguration, type PKCEChallenge, type PartEtag, type PasskeyAuthenticationOptionsJSON, type PasskeyAuthenticationResponseJSON, type PasskeyCredential, type PasskeyCredentialDescriptorJSON, type PasskeyLoginResponse, type PasskeyRegistrationOptionsJSON, type PasskeyRegistrationResponseJSON, type PasskeyRegistrationResult, type PushSubscriptionInfo, type QuotaInfo, type RegisterParams, type RegisterResponse, type Schedule, type ScheduleInvokeOptions, type ScheduleListOptions, type ScheduleStatus, type SearchOptions, ServerConfigError, type ShareFileParams, SharePermission, SpacelrAuthError, type SpacelrClient, type SpacelrClientConfig, SpacelrEmailVerificationRequiredError, SpacelrError, SpacelrNetworkError, SpacelrSearchFilterRequiredError, SpacelrTimeoutError, SpacelrTwoFactorRequiredError, type StoredTokens, type StreamGapInfo, type StreamSubscription, type SubscribeEventsHandlers, type SubscribeHandlers, type SubscribeWithSnapshotOptions, type TimelineAndFilter, TimelineError, type TimelineFieldFilter, type TimelineFilter, type TimelineLeafFilter, TimelineModule, type TimelineOrderBy, type TimelineQueryOptions, type TimelineQueryResponse, type TimelineScalar, type TimelineSourceStats, TimeoutError, type TokenResponse, type TokenStorage, type TwoFactorResponse, type TwoFactorVerifyParams, type UnshareFileParams, type UploadFileParams, type UploadLargeFileParams, type UploadProgress, type UserInfo, type UserProfile, ValidationError, type VapidKeyResponse, createClient, generatePKCEChallenge, localStorageCursorStorage, memoryCursorStorage };
|
|
1799
|
+
export { type ApiResponse, type AuthLostReason, type AuthState, type AuthStateListener, type AuthorizationUrlParams, BrowserTokenStorage, CodeChallengeMethod, type ConnectionState, CursorInvalidError, type CursorStorage, type DatabaseChangeEvent, type DownloadUrlResponse, type ExchangeCodeParams, type FileInfo, type FileListResponse, FileVisibility, ForbiddenError, type FunctionInvokeOptions, type FunctionInvokeResult, type GapReason, GrantType, type InitMultipartUploadParams, type InitMultipartUploadResponse, type JWK, type JWKSResponse, type ListFilesParams, type LoginParams, type LoginResponse, MemoryTokenStorage, NotFoundError, type OpenIDConfiguration, type PKCEChallenge, type PartEtag, type PasskeyAuthenticationOptionsJSON, type PasskeyAuthenticationResponseJSON, type PasskeyCredential, type PasskeyCredentialDescriptorJSON, type PasskeyLoginResponse, type PasskeyRegistrationOptionsJSON, type PasskeyRegistrationResponseJSON, type PasskeyRegistrationResult, type PushSubscriptionInfo, type QuotaInfo, type RegisterParams, type RegisterResponse, type Schedule, type ScheduleInvokeOptions, type ScheduleListOptions, type ScheduleStatus, type SearchOptions, ServerConfigError, type ShareFileParams, SharePermission, SpacelrAuthError, type SpacelrClient, type SpacelrClientConfig, SpacelrEmailVerificationRequiredError, SpacelrError, SpacelrNetworkError, SpacelrSearchFilterRequiredError, SpacelrTimeoutError, SpacelrTwoFactorRequiredError, type StoredTokens, type StreamGapInfo, type StreamSubscription, type SubscribeEventsHandlers, type SubscribeHandlers, type SubscribeWithSnapshotOptions, type TimelineAndFilter, TimelineError, type TimelineFieldFilter, type TimelineFilter, type TimelineLeafFilter, TimelineModule, type TimelineOrderBy, type TimelineQueryOptions, type TimelineQueryResponse, type TimelineScalar, type TimelineSourceStats, TimeoutError, type TokenResponse, type TokenStorage, type TwoFactorResponse, type TwoFactorVerifyParams, type UnshareFileParams, type UploadFileParams, type UploadLargeFileParams, type UploadProgress, type UserInfo, type UserProfile, ValidationError, type VapidKeyResponse, type WhereFilter, type WhereOperator, type WhereScalar, type WhereValue, createClient, generatePKCEChallenge, localStorageCursorStorage, memoryCursorStorage };
|
package/dist/index.js
CHANGED
|
@@ -657,6 +657,57 @@ var PERMANENT_STREAM_ACK_ERRORS = /* @__PURE__ */ new Set([
|
|
|
657
657
|
"Not a member of this project",
|
|
658
658
|
"Subscribe denied"
|
|
659
659
|
]);
|
|
660
|
+
function isWhereScalar(value) {
|
|
661
|
+
const t = typeof value;
|
|
662
|
+
return t === "string" || t === "number" || t === "boolean";
|
|
663
|
+
}
|
|
664
|
+
function isWhereOperator(value) {
|
|
665
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
const keys = Object.keys(value);
|
|
669
|
+
if (keys.length !== 1) return false;
|
|
670
|
+
const op = keys[0];
|
|
671
|
+
if (op !== "in" && op !== "array-contains-any") return false;
|
|
672
|
+
const candidates = value[op];
|
|
673
|
+
return Array.isArray(candidates) && candidates.every(isWhereScalar);
|
|
674
|
+
}
|
|
675
|
+
var WHERE_PATH_ABSENT = /* @__PURE__ */ Symbol("where-path-absent");
|
|
676
|
+
var WHERE_PATH_UNRESOLVABLE = /* @__PURE__ */ Symbol("where-path-unresolvable");
|
|
677
|
+
var RESERVED_PATH_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
678
|
+
var MAX_WHERE_PATH_SEGMENTS = 16;
|
|
679
|
+
function resolveWherePath(document2, key) {
|
|
680
|
+
const segments = key.split(".");
|
|
681
|
+
if (segments.length > MAX_WHERE_PATH_SEGMENTS) return WHERE_PATH_ABSENT;
|
|
682
|
+
let cur = document2;
|
|
683
|
+
for (const segment of segments) {
|
|
684
|
+
if (RESERVED_PATH_SEGMENTS.has(segment)) return WHERE_PATH_ABSENT;
|
|
685
|
+
if (cur === null || cur === void 0) return WHERE_PATH_ABSENT;
|
|
686
|
+
if (Array.isArray(cur)) return WHERE_PATH_UNRESOLVABLE;
|
|
687
|
+
if (typeof cur !== "object") return WHERE_PATH_ABSENT;
|
|
688
|
+
if (!Object.prototype.hasOwnProperty.call(cur, segment)) {
|
|
689
|
+
return WHERE_PATH_ABSENT;
|
|
690
|
+
}
|
|
691
|
+
cur = cur[segment];
|
|
692
|
+
}
|
|
693
|
+
return cur === void 0 ? WHERE_PATH_ABSENT : cur;
|
|
694
|
+
}
|
|
695
|
+
function whereValueMatches(actual, expected) {
|
|
696
|
+
if (actual === WHERE_PATH_ABSENT || actual === WHERE_PATH_UNRESOLVABLE) {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
if (isWhereOperator(expected)) {
|
|
700
|
+
if ("in" in expected) {
|
|
701
|
+
if (Array.isArray(actual)) return false;
|
|
702
|
+
return expected.in.includes(actual);
|
|
703
|
+
}
|
|
704
|
+
if (!Array.isArray(actual)) return false;
|
|
705
|
+
const candidates = expected["array-contains-any"];
|
|
706
|
+
return actual.some((el) => candidates.includes(el));
|
|
707
|
+
}
|
|
708
|
+
if (Array.isArray(actual)) return actual.includes(expected);
|
|
709
|
+
return actual === expected;
|
|
710
|
+
}
|
|
660
711
|
var RealtimeClient = class {
|
|
661
712
|
constructor(config) {
|
|
662
713
|
this.socket = null;
|
|
@@ -1045,12 +1096,7 @@ var RealtimeClient = class {
|
|
|
1045
1096
|
if (!where) return false;
|
|
1046
1097
|
if (!event.document) return false;
|
|
1047
1098
|
for (const [key, value] of Object.entries(where)) {
|
|
1048
|
-
|
|
1049
|
-
if (Array.isArray(docValue)) {
|
|
1050
|
-
if (!docValue.includes(value)) {
|
|
1051
|
-
return false;
|
|
1052
|
-
}
|
|
1053
|
-
} else if (docValue !== value) {
|
|
1099
|
+
if (!whereValueMatches(resolveWherePath(event.document, key), value)) {
|
|
1054
1100
|
return false;
|
|
1055
1101
|
}
|
|
1056
1102
|
}
|
|
@@ -3011,10 +3057,14 @@ var FunctionsModule = class {
|
|
|
3011
3057
|
* `config.apiUrl` (which already carries the `/api/v1` prefix).
|
|
3012
3058
|
*
|
|
3013
3059
|
* Auth defaults, based on `invokeMode` semantics:
|
|
3014
|
-
* - webhook:
|
|
3015
|
-
* - authenticated:
|
|
3016
|
-
*
|
|
3017
|
-
* -
|
|
3060
|
+
* - webhook: pass `secret` → Authorization is NOT attached
|
|
3061
|
+
* - authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
3062
|
+
* caller must be a member of the target project
|
|
3063
|
+
* - public: pass nothing → Authorization is attached if logged in, else omitted
|
|
3064
|
+
* - hybrid: pass both `secret` and `authenticated: true`; JWT path
|
|
3065
|
+
* requires project membership like `authenticated`
|
|
3066
|
+
* - platform-authenticated: pass nothing → Authorization IS attached (from token manager);
|
|
3067
|
+
* any signed-in user is accepted, still just attaches the bearer token
|
|
3018
3068
|
*
|
|
3019
3069
|
* To force a specific behaviour, set `authenticated` explicitly — it wins
|
|
3020
3070
|
* over the `secret`-based default.
|