@hanzo/base 0.2.0 → 0.2.1
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/{chunk-LBAV5X5P.js → chunk-3WOGNODW.js} +17 -17
- package/dist/{chunk-LBAV5X5P.js.map → chunk-3WOGNODW.js.map} +1 -1
- package/dist/chunk-DC6LDHAD.js +244 -0
- package/dist/chunk-DC6LDHAD.js.map +1 -0
- package/dist/{chunk-5NHFZRMO.js → chunk-FTBTJJQY.js} +3 -3
- package/dist/chunk-FTBTJJQY.js.map +1 -0
- package/dist/client-Ckpi5rr9.d.ts +368 -0
- package/dist/compat/index.d.ts +203 -1
- package/dist/compat/index.js +2 -1
- package/dist/compat/index.js.map +1 -1
- package/dist/core/index.d.ts +7 -363
- package/dist/core/index.js +2 -1
- package/dist/crdt/index.d.ts +1 -1
- package/dist/crdt/index.js +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +5 -5
- package/dist/react/index.js.map +1 -1
- package/package.json +4 -6
- package/src/compat/index.ts +33 -10
- package/src/core/auth-stores.ts +222 -0
- package/src/core/client.ts +12 -12
- package/src/core/collection.ts +2 -2
- package/src/core/index.ts +27 -2
- package/src/core/realtime.ts +3 -3
- package/src/core/tokens.ts +139 -0
- package/src/core/types.ts +100 -0
- package/src/crdt/sync.ts +1 -1
- package/src/react/hooks.ts +3 -3
- package/dist/chunk-5NHFZRMO.js.map +0 -1
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State version tracking (Convex-inspired).
|
|
3
|
+
*
|
|
4
|
+
* Each query result is tagged with a StateVersion so the client can
|
|
5
|
+
* detect ordering, replay transitions, and drive optimistic rollbacks.
|
|
6
|
+
*/
|
|
7
|
+
interface StateVersion {
|
|
8
|
+
/** Monotonically increasing counter bumped on every query-set change. */
|
|
9
|
+
querySet: number;
|
|
10
|
+
/** Server timestamp (microseconds since epoch) of the latest known event. */
|
|
11
|
+
ts: bigint;
|
|
12
|
+
/** Identity hash -- changes when the authenticated user changes. */
|
|
13
|
+
identity: number;
|
|
14
|
+
}
|
|
15
|
+
type Modification = {
|
|
16
|
+
type: 'QueryUpdated';
|
|
17
|
+
collection: string;
|
|
18
|
+
record: BaseRecord;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'QueryRemoved';
|
|
21
|
+
collection: string;
|
|
22
|
+
id: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'QueryFailed';
|
|
25
|
+
collection: string;
|
|
26
|
+
error: string;
|
|
27
|
+
};
|
|
28
|
+
interface Transition {
|
|
29
|
+
startVersion: StateVersion;
|
|
30
|
+
endVersion: StateVersion;
|
|
31
|
+
modifications: Modification[];
|
|
32
|
+
}
|
|
33
|
+
/** Minimal record shape that every Base record satisfies. */
|
|
34
|
+
interface BaseRecord {
|
|
35
|
+
id: string;
|
|
36
|
+
collectionId?: string;
|
|
37
|
+
collectionName?: string;
|
|
38
|
+
created?: string;
|
|
39
|
+
updated?: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
declare class VersionTracker {
|
|
43
|
+
private _version;
|
|
44
|
+
private _history;
|
|
45
|
+
private readonly _maxHistory;
|
|
46
|
+
constructor(maxHistory?: number);
|
|
47
|
+
get current(): Readonly<StateVersion>;
|
|
48
|
+
get history(): readonly Transition[];
|
|
49
|
+
/**
|
|
50
|
+
* Advance the version and record a transition.
|
|
51
|
+
* Returns the new version.
|
|
52
|
+
*/
|
|
53
|
+
advance(modifications: Modification[], serverTs?: bigint): StateVersion;
|
|
54
|
+
/** Update identity hash (e.g. on auth change). */
|
|
55
|
+
setIdentity(identity: number): void;
|
|
56
|
+
/** Update the high-water timestamp without bumping querySet. */
|
|
57
|
+
updateTimestamp(ts: bigint): void;
|
|
58
|
+
/** Simple FNV-1a-like hash for identity derivation. */
|
|
59
|
+
static hashIdentity(token: string): number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface QueryKey {
|
|
63
|
+
collection: string;
|
|
64
|
+
filter: string;
|
|
65
|
+
}
|
|
66
|
+
type StoreCallback = (records: BaseRecord[]) => void;
|
|
67
|
+
declare class QueryStore {
|
|
68
|
+
private readonly _slots;
|
|
69
|
+
private readonly _optimistic;
|
|
70
|
+
private readonly _version;
|
|
71
|
+
get version(): Readonly<StateVersion>;
|
|
72
|
+
/** Return cached effective (server+optimistic) result or undefined. */
|
|
73
|
+
getQuery(collection: string, filter?: string): BaseRecord[] | undefined;
|
|
74
|
+
/** Overwrite the server-truth cache for a query and notify. */
|
|
75
|
+
setQuery(collection: string, filter: string, data: BaseRecord[]): void;
|
|
76
|
+
/** Apply an optimistic create/update. Returns a mutationId for rollback. */
|
|
77
|
+
optimisticSet(collection: string, record: BaseRecord): string;
|
|
78
|
+
/** Apply an optimistic delete. */
|
|
79
|
+
optimisticDelete(collection: string, id: string): string;
|
|
80
|
+
/** Remove a single optimistic mutation and re-derive. */
|
|
81
|
+
rollbackOptimistic(mutationId: string): void;
|
|
82
|
+
/** Drop all optimistic entries for a collection. */
|
|
83
|
+
clearOptimistic(collection: string): void;
|
|
84
|
+
/**
|
|
85
|
+
* Apply a realtime SSE event from the server.
|
|
86
|
+
* `action` is one of "create", "update", "delete".
|
|
87
|
+
*/
|
|
88
|
+
applyServerUpdate(collection: string, action: 'create' | 'update' | 'delete', record: BaseRecord): void;
|
|
89
|
+
/** Subscribe to effective-state changes for a query. Returns unsubscribe. */
|
|
90
|
+
subscribe(collection: string, filter: string, callback: StoreCallback): () => void;
|
|
91
|
+
private _notify;
|
|
92
|
+
private _notifyCollection;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* RealtimeService -- SSE-based subscription manager.
|
|
97
|
+
*
|
|
98
|
+
* Features:
|
|
99
|
+
* - Query deduplication via hash(collection+topic) with reference counting
|
|
100
|
+
* - Auto-reconnect with exponential backoff
|
|
101
|
+
* - Max observed timestamp tracking
|
|
102
|
+
* - Connection state notifications
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
type ConnectionState = 'disconnected' | 'connecting' | 'connected';
|
|
106
|
+
interface RealtimeEvent {
|
|
107
|
+
action: 'create' | 'update' | 'delete';
|
|
108
|
+
record: BaseRecord;
|
|
109
|
+
}
|
|
110
|
+
type RealtimeCallback = (event: RealtimeEvent) => void;
|
|
111
|
+
type ConnectionCallback = (state: ConnectionState) => void;
|
|
112
|
+
declare class RealtimeService {
|
|
113
|
+
private readonly _baseUrl;
|
|
114
|
+
private readonly _getToken;
|
|
115
|
+
private _eventSource;
|
|
116
|
+
private _state;
|
|
117
|
+
private _connectionListeners;
|
|
118
|
+
/** Dedup map: hash -> Subscription. */
|
|
119
|
+
private _subscriptions;
|
|
120
|
+
/** SSE client id assigned by the server on connect. */
|
|
121
|
+
private _clientId;
|
|
122
|
+
/** Reconnect state. */
|
|
123
|
+
private _reconnectAttempts;
|
|
124
|
+
private _reconnectTimer;
|
|
125
|
+
private _maxReconnectDelay;
|
|
126
|
+
private _baseReconnectDelay;
|
|
127
|
+
/** High-water mark of observed server timestamps. */
|
|
128
|
+
private _maxTimestamp;
|
|
129
|
+
/** Set to true when disconnect() is called explicitly. */
|
|
130
|
+
private _intentionalDisconnect;
|
|
131
|
+
constructor(baseUrl: string, getToken: () => string);
|
|
132
|
+
get state(): ConnectionState;
|
|
133
|
+
get maxTimestamp(): bigint;
|
|
134
|
+
/**
|
|
135
|
+
* Subscribe to realtime events for a collection topic.
|
|
136
|
+
*
|
|
137
|
+
* Topic is usually "*" (all changes) or a record id.
|
|
138
|
+
* Returns an unsubscribe function.
|
|
139
|
+
*/
|
|
140
|
+
subscribe(collection: string, topic: string, callback: RealtimeCallback): () => void;
|
|
141
|
+
/** Remove all subscribers for a topic, or all topics if none specified. */
|
|
142
|
+
unsubscribe(topic?: string): void;
|
|
143
|
+
/** Register a connection-state listener. Returns unsubscribe. */
|
|
144
|
+
onConnectionChange(callback: ConnectionCallback): () => void;
|
|
145
|
+
/** Explicitly disconnect. */
|
|
146
|
+
disconnect(): void;
|
|
147
|
+
private _connect;
|
|
148
|
+
private _handleMessage;
|
|
149
|
+
/** Submit current subscription set to the server via POST. */
|
|
150
|
+
private _submitSubscriptions;
|
|
151
|
+
private _scheduleReconnect;
|
|
152
|
+
private _clearReconnect;
|
|
153
|
+
private _setState;
|
|
154
|
+
private _hash;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* CollectionService -- typed CRUD + auth + realtime for a single collection.
|
|
159
|
+
*
|
|
160
|
+
* API-compatible with the upstream RecordService interface, extended with
|
|
161
|
+
* reactive features (subscribe/unsubscribe, optimistic writes).
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
interface ListResult$1<T = BaseRecord> {
|
|
165
|
+
page: number;
|
|
166
|
+
perPage: number;
|
|
167
|
+
totalItems: number;
|
|
168
|
+
totalPages: number;
|
|
169
|
+
items: T[];
|
|
170
|
+
}
|
|
171
|
+
interface RecordQueryOptions {
|
|
172
|
+
filter?: string;
|
|
173
|
+
sort?: string;
|
|
174
|
+
expand?: string;
|
|
175
|
+
fields?: string;
|
|
176
|
+
headers?: Record<string, string>;
|
|
177
|
+
/** Extra query params merged into the URL. */
|
|
178
|
+
query?: Record<string, string>;
|
|
179
|
+
/** Request-scoped AbortSignal. */
|
|
180
|
+
signal?: AbortSignal;
|
|
181
|
+
}
|
|
182
|
+
interface RecordFullListOptions extends RecordQueryOptions {
|
|
183
|
+
/** Batch size for pagination (default 200). */
|
|
184
|
+
batch?: number;
|
|
185
|
+
}
|
|
186
|
+
interface FileOptions {
|
|
187
|
+
thumb?: string;
|
|
188
|
+
token?: string;
|
|
189
|
+
}
|
|
190
|
+
interface AuthResponse<T = BaseRecord> {
|
|
191
|
+
token: string;
|
|
192
|
+
record: T;
|
|
193
|
+
}
|
|
194
|
+
interface OAuth2Options {
|
|
195
|
+
provider: string;
|
|
196
|
+
code: string;
|
|
197
|
+
codeVerifier: string;
|
|
198
|
+
redirectUrl: string;
|
|
199
|
+
createData?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
declare class CollectionService {
|
|
202
|
+
readonly collectionIdOrName: string;
|
|
203
|
+
private readonly _baseUrl;
|
|
204
|
+
private readonly _getToken;
|
|
205
|
+
private readonly _setAuth;
|
|
206
|
+
private readonly _store;
|
|
207
|
+
private readonly _realtime;
|
|
208
|
+
constructor(collectionIdOrName: string, baseUrl: string, getToken: () => string, setAuth: (token: string, record: BaseRecord) => void, store: QueryStore, realtime: RealtimeService);
|
|
209
|
+
getList<T extends BaseRecord = BaseRecord>(page?: number, perPage?: number, options?: RecordQueryOptions): Promise<ListResult$1<T>>;
|
|
210
|
+
getFullList<T extends BaseRecord = BaseRecord>(options?: RecordFullListOptions): Promise<T[]>;
|
|
211
|
+
getOne<T extends BaseRecord = BaseRecord>(id: string, options?: RecordQueryOptions): Promise<T>;
|
|
212
|
+
getFirstListItem<T extends BaseRecord = BaseRecord>(filter: string, options?: RecordQueryOptions): Promise<T>;
|
|
213
|
+
create<T extends BaseRecord = BaseRecord>(data: Record<string, unknown> | FormData, options?: RecordQueryOptions): Promise<T>;
|
|
214
|
+
update<T extends BaseRecord = BaseRecord>(id: string, data: Record<string, unknown> | FormData, options?: RecordQueryOptions): Promise<T>;
|
|
215
|
+
delete(id: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
216
|
+
/**
|
|
217
|
+
* Subscribe to realtime events for this collection.
|
|
218
|
+
* `topic` is "*" for all changes or a specific record id.
|
|
219
|
+
*/
|
|
220
|
+
subscribe(topic: string, callback: RealtimeCallback): () => void;
|
|
221
|
+
/** Unsubscribe from a specific topic or all topics for this collection. */
|
|
222
|
+
unsubscribe(topic?: string): void;
|
|
223
|
+
authWithPassword<T extends BaseRecord = BaseRecord>(identity: string, password: string, options?: RecordQueryOptions): Promise<AuthResponse<T>>;
|
|
224
|
+
authWithOAuth2<T extends BaseRecord = BaseRecord>(oauthOptions: OAuth2Options, options?: RecordQueryOptions): Promise<AuthResponse<T>>;
|
|
225
|
+
requestVerification(email: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
226
|
+
confirmVerification(token: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
227
|
+
requestPasswordReset(email: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
228
|
+
confirmPasswordReset(token: string, password: string, passwordConfirm: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
229
|
+
private _collectionPath;
|
|
230
|
+
private _applyOptions;
|
|
231
|
+
private _request;
|
|
232
|
+
}
|
|
233
|
+
interface ClientResponseErrorData {
|
|
234
|
+
url: string;
|
|
235
|
+
status: number;
|
|
236
|
+
data: Record<string, unknown>;
|
|
237
|
+
}
|
|
238
|
+
declare class ClientResponseError extends Error {
|
|
239
|
+
url: string;
|
|
240
|
+
status: number;
|
|
241
|
+
data: Record<string, unknown>;
|
|
242
|
+
isAbort: boolean;
|
|
243
|
+
constructor(errorData: ClientResponseErrorData);
|
|
244
|
+
toJSON(): ClientResponseErrorData;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface AuthStore {
|
|
248
|
+
token: string;
|
|
249
|
+
record: BaseRecord | null;
|
|
250
|
+
onChange(callback: (token: string, record: BaseRecord | null) => void): () => void;
|
|
251
|
+
save(token: string, record: BaseRecord | null): void;
|
|
252
|
+
clear(): void;
|
|
253
|
+
readonly isValid: boolean;
|
|
254
|
+
}
|
|
255
|
+
type AuthChangeCallback = (token: string, record: BaseRecord | null) => void;
|
|
256
|
+
/**
|
|
257
|
+
* Default in-memory auth store.
|
|
258
|
+
* Validates JWT exp claim without external dependencies.
|
|
259
|
+
*/
|
|
260
|
+
declare class MemoryAuthStore implements AuthStore {
|
|
261
|
+
private _token;
|
|
262
|
+
private _record;
|
|
263
|
+
private _listeners;
|
|
264
|
+
get token(): string;
|
|
265
|
+
get record(): BaseRecord | null;
|
|
266
|
+
get isValid(): boolean;
|
|
267
|
+
save(token: string, record: BaseRecord | null): void;
|
|
268
|
+
clear(): void;
|
|
269
|
+
onChange(callback: AuthChangeCallback): () => void;
|
|
270
|
+
private _notify;
|
|
271
|
+
}
|
|
272
|
+
declare class FileService {
|
|
273
|
+
private readonly _baseUrl;
|
|
274
|
+
constructor(baseUrl: string);
|
|
275
|
+
/**
|
|
276
|
+
* Build a full URL to a record file.
|
|
277
|
+
* Compatible with Base's files.getURL().
|
|
278
|
+
*/
|
|
279
|
+
getURL(record: BaseRecord, filename: string, options?: FileOptions): string;
|
|
280
|
+
}
|
|
281
|
+
interface ClientConfig {
|
|
282
|
+
/** Base URL of the Hanzo Base instance (e.g. "https://myapp.hanzo.ai"). */
|
|
283
|
+
url: string;
|
|
284
|
+
/** Optional external auth store. Defaults to in-memory store. */
|
|
285
|
+
authStore?: AuthStore;
|
|
286
|
+
}
|
|
287
|
+
interface ListOptions {
|
|
288
|
+
filter?: string;
|
|
289
|
+
sort?: string;
|
|
290
|
+
expand?: string;
|
|
291
|
+
fields?: string;
|
|
292
|
+
page?: number;
|
|
293
|
+
perPage?: number;
|
|
294
|
+
}
|
|
295
|
+
interface ListResult<T = BaseRecord> {
|
|
296
|
+
page: number;
|
|
297
|
+
perPage: number;
|
|
298
|
+
totalItems: number;
|
|
299
|
+
totalPages: number;
|
|
300
|
+
items: T[];
|
|
301
|
+
}
|
|
302
|
+
declare class BaseClient {
|
|
303
|
+
readonly url: string;
|
|
304
|
+
readonly authStore: AuthStore;
|
|
305
|
+
readonly store: QueryStore;
|
|
306
|
+
readonly realtime: RealtimeService;
|
|
307
|
+
readonly files: FileService;
|
|
308
|
+
private readonly _versionTracker;
|
|
309
|
+
private readonly _collections;
|
|
310
|
+
/**
|
|
311
|
+
* Create a BaseClient.
|
|
312
|
+
*
|
|
313
|
+
* Accepts either a config object or a plain URL string for convenience:
|
|
314
|
+
* new BaseClient('https://myapp.hanzo.ai')
|
|
315
|
+
* new BaseClient({ url: 'https://myapp.hanzo.ai' })
|
|
316
|
+
*/
|
|
317
|
+
constructor(configOrUrl: ClientConfig | string);
|
|
318
|
+
/** Get or create a CollectionService for the given name/id. */
|
|
319
|
+
collection(nameOrId: string): CollectionService;
|
|
320
|
+
/** Current state version from the QueryStore's internal tracker. */
|
|
321
|
+
get version(): Readonly<StateVersion>;
|
|
322
|
+
private _headers;
|
|
323
|
+
private _request;
|
|
324
|
+
list(collection: string, options?: ListOptions): Promise<ListResult>;
|
|
325
|
+
getOne(collection: string, id: string, options?: Pick<ListOptions, 'expand' | 'fields'>): Promise<BaseRecord>;
|
|
326
|
+
create(collection: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
327
|
+
update(collection: string, id: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
328
|
+
delete(collection: string, id: string): Promise<void>;
|
|
329
|
+
signInWithPassword(collection: string, identity: string, password: string): Promise<{
|
|
330
|
+
token: string;
|
|
331
|
+
record: BaseRecord;
|
|
332
|
+
}>;
|
|
333
|
+
signUp(collection: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
334
|
+
refreshAuth(collection: string): Promise<{
|
|
335
|
+
token: string;
|
|
336
|
+
record: BaseRecord;
|
|
337
|
+
}>;
|
|
338
|
+
signOut(): void;
|
|
339
|
+
/**
|
|
340
|
+
* Send a raw request to the Base API.
|
|
341
|
+
* Convenience for endpoints not covered by CollectionService.
|
|
342
|
+
*/
|
|
343
|
+
send<T = unknown>(path: string, options?: {
|
|
344
|
+
method?: string;
|
|
345
|
+
headers?: Record<string, string>;
|
|
346
|
+
body?: string | FormData;
|
|
347
|
+
query?: Record<string, string>;
|
|
348
|
+
signal?: AbortSignal;
|
|
349
|
+
}): Promise<T>;
|
|
350
|
+
health(): Promise<{
|
|
351
|
+
code: number;
|
|
352
|
+
message: string;
|
|
353
|
+
}>;
|
|
354
|
+
/**
|
|
355
|
+
* Subscribe to realtime events for a collection topic.
|
|
356
|
+
* Also wires events into the QueryStore automatically.
|
|
357
|
+
*/
|
|
358
|
+
subscribeAndSync(collection: string, topic?: string, callback?: (e: RealtimeEvent) => void): () => void;
|
|
359
|
+
/** Disconnect realtime and clear caches. */
|
|
360
|
+
disconnect(): void;
|
|
361
|
+
}
|
|
362
|
+
declare class BaseClientError extends Error {
|
|
363
|
+
readonly status: number;
|
|
364
|
+
readonly detail: unknown;
|
|
365
|
+
constructor(status: number, detail: unknown);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export { type AuthChangeCallback as A, BaseClient as B, type ClientConfig as C, type FileOptions as F, type ListOptions as L, MemoryAuthStore as M, type OAuth2Options as O, type QueryKey as Q, type RealtimeCallback as R, type StateVersion as S, type Transition as T, VersionTracker as V, type AuthResponse as a, type AuthStore as b, BaseClientError as c, type BaseRecord as d, ClientResponseError as e, type ClientResponseErrorData as f, CollectionService as g, type ConnectionCallback as h, type ConnectionState as i, FileService as j, type ListResult as k, type Modification as l, QueryStore as m, type RealtimeEvent as n, RealtimeService as o, type RecordFullListOptions as p, type RecordQueryOptions as q, type StoreCallback as r };
|
package/dist/compat/index.d.ts
CHANGED
|
@@ -1 +1,203 @@
|
|
|
1
|
-
|
|
1
|
+
import { d as BaseRecord, b as AuthStore, A as AuthChangeCallback } from '../client-Ckpi5rr9.js';
|
|
2
|
+
export { a as AuthResponse, B as Base, B as BaseClient, C as ClientConfig, e as ClientResponseError, f as ClientResponseErrorData, F as FileOptions, L as ListOptions, k as ListResult, M as MemoryAuthStore, O as OAuth2Options, p as RecordFullListOptions, q as RecordQueryOptions, B as default } from '../client-Ckpi5rr9.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Schema types — collection + field model shapes the admin UI needs.
|
|
6
|
+
*
|
|
7
|
+
* Defined natively in @hanzo/base so the SDK has no upstream
|
|
8
|
+
* dependency. Admin pages import `CollectionModel` / `CollectionField`
|
|
9
|
+
* directly from `@hanzo/base`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A single field in a collection schema.
|
|
14
|
+
*
|
|
15
|
+
* Field types and their option shapes mirror the Base admin API
|
|
16
|
+
* (`/v1/collections/{id}` → `fields[]`), so existing admin UIs read
|
|
17
|
+
* the structure unchanged.
|
|
18
|
+
*/
|
|
19
|
+
interface CollectionField {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
type: 'text' | 'number' | 'bool' | 'email' | 'url' | 'editor' | 'date' | 'autodate' | 'select' | 'json' | 'file' | 'relation' | 'password';
|
|
23
|
+
system?: boolean;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
presentable?: boolean;
|
|
26
|
+
hidden?: boolean;
|
|
27
|
+
unique?: boolean;
|
|
28
|
+
min?: number | string | null;
|
|
29
|
+
max?: number | string | null;
|
|
30
|
+
pattern?: string;
|
|
31
|
+
maxSelect?: number;
|
|
32
|
+
values?: string[];
|
|
33
|
+
collectionId?: string;
|
|
34
|
+
cascadeDelete?: boolean;
|
|
35
|
+
minSelect?: number;
|
|
36
|
+
options?: Record<string, unknown>;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A collection definition. Mirrors the Base admin API
|
|
41
|
+
* `/v1/collections/{id}` payload.
|
|
42
|
+
*
|
|
43
|
+
* `type` selects the back-end behaviour: `base` is a regular collection,
|
|
44
|
+
* `auth` is an auth collection (users), `view` is a virtual read-only
|
|
45
|
+
* SQL-defined view.
|
|
46
|
+
*/
|
|
47
|
+
interface CollectionModel {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
type: 'base' | 'auth' | 'view';
|
|
51
|
+
system?: boolean;
|
|
52
|
+
fields: CollectionField[];
|
|
53
|
+
indexes?: string[];
|
|
54
|
+
listRule?: string | null;
|
|
55
|
+
viewRule?: string | null;
|
|
56
|
+
createRule?: string | null;
|
|
57
|
+
updateRule?: string | null;
|
|
58
|
+
deleteRule?: string | null;
|
|
59
|
+
authRule?: string | null;
|
|
60
|
+
manageRule?: string | null;
|
|
61
|
+
authAlert?: {
|
|
62
|
+
enabled?: boolean;
|
|
63
|
+
emailTemplate?: Record<string, unknown>;
|
|
64
|
+
};
|
|
65
|
+
oauth2?: Record<string, unknown>;
|
|
66
|
+
passwordAuth?: {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
identityFields?: string[];
|
|
69
|
+
};
|
|
70
|
+
otp?: Record<string, unknown>;
|
|
71
|
+
mfa?: Record<string, unknown>;
|
|
72
|
+
fileToken?: Record<string, unknown>;
|
|
73
|
+
authToken?: Record<string, unknown>;
|
|
74
|
+
passwordResetToken?: Record<string, unknown>;
|
|
75
|
+
emailChangeToken?: Record<string, unknown>;
|
|
76
|
+
verificationToken?: Record<string, unknown>;
|
|
77
|
+
viewQuery?: string;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Alias for `BaseRecord` so consumers migrating from the upstream
|
|
82
|
+
* client can keep using `RecordModel`. New code should prefer
|
|
83
|
+
* `BaseRecord` from `./state.js`.
|
|
84
|
+
*/
|
|
85
|
+
type RecordModel = BaseRecord;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Auth-store implementations beyond the in-memory default.
|
|
89
|
+
*
|
|
90
|
+
* Native `LocalAuthStore` / `AsyncAuthStore` implementations so the
|
|
91
|
+
* SDK has zero upstream client dependency. The shape matches the
|
|
92
|
+
* legacy client's auth stores so existing apps migrating to
|
|
93
|
+
* `@hanzo/base` keep working.
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Type alias matching the upstream interface name. New code should use
|
|
98
|
+
* `AuthStore`.
|
|
99
|
+
*/
|
|
100
|
+
type BaseAuthStore = AuthStore;
|
|
101
|
+
/**
|
|
102
|
+
* Synchronous localStorage-backed auth store. Suitable for browser SPAs.
|
|
103
|
+
* Falls back to in-memory storage when `window.localStorage` is absent
|
|
104
|
+
* (SSR, sandboxed iframes, etc.).
|
|
105
|
+
*/
|
|
106
|
+
declare class LocalAuthStore implements AuthStore {
|
|
107
|
+
private _storageKey;
|
|
108
|
+
private _listeners;
|
|
109
|
+
private _memToken;
|
|
110
|
+
private _memRecord;
|
|
111
|
+
constructor(storageKey?: string);
|
|
112
|
+
private get _storage();
|
|
113
|
+
private _read;
|
|
114
|
+
private _write;
|
|
115
|
+
get token(): string;
|
|
116
|
+
get record(): BaseRecord | null;
|
|
117
|
+
get isValid(): boolean;
|
|
118
|
+
save(token: string, record: BaseRecord | null): void;
|
|
119
|
+
clear(): void;
|
|
120
|
+
onChange(callback: AuthChangeCallback): () => void;
|
|
121
|
+
private _notify;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Async auth store — wraps any async storage backend (cookies via
|
|
125
|
+
* fetch, encrypted SecureStore on mobile, KV namespace on the edge,
|
|
126
|
+
* etc.). Reads and writes are buffered through an in-memory cache so
|
|
127
|
+
* the `token`/`record` accessors stay synchronous (matching upstream).
|
|
128
|
+
*
|
|
129
|
+
* Pass a `save` function that persists the serialized payload to your
|
|
130
|
+
* backend, and an `initial` value loaded synchronously at app boot.
|
|
131
|
+
*/
|
|
132
|
+
declare class AsyncAuthStore implements AuthStore {
|
|
133
|
+
private _token;
|
|
134
|
+
private _record;
|
|
135
|
+
private _listeners;
|
|
136
|
+
private readonly _save;
|
|
137
|
+
private readonly _clear?;
|
|
138
|
+
constructor(config: {
|
|
139
|
+
save: (serialized: string) => Promise<void> | void;
|
|
140
|
+
initial?: string | null;
|
|
141
|
+
clear?: () => Promise<void> | void;
|
|
142
|
+
});
|
|
143
|
+
get token(): string;
|
|
144
|
+
get record(): BaseRecord | null;
|
|
145
|
+
get isValid(): boolean;
|
|
146
|
+
save(token: string, record: BaseRecord | null): void;
|
|
147
|
+
clear(): void;
|
|
148
|
+
onChange(callback: AuthChangeCallback): () => void;
|
|
149
|
+
private _notify;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* JWT + cookie helpers — small utilities the compat layer used to
|
|
154
|
+
* re-export from the upstream client. Implemented natively so the SDK
|
|
155
|
+
* has zero upstream dependency.
|
|
156
|
+
*/
|
|
157
|
+
/**
|
|
158
|
+
* Decode the payload of a JWT without verifying its signature.
|
|
159
|
+
* Returns `null` for malformed tokens. Safe for browser + Node use
|
|
160
|
+
* (relies only on global `atob`).
|
|
161
|
+
*/
|
|
162
|
+
declare function getTokenPayload<T = Record<string, unknown>>(token: string): T | null;
|
|
163
|
+
/**
|
|
164
|
+
* Check whether a JWT's `exp` claim has passed.
|
|
165
|
+
* `expirationThreshold` (seconds) is subtracted from `exp` to expire
|
|
166
|
+
* tokens early — set this when you want to refresh before the actual
|
|
167
|
+
* expiration. Tokens without an `exp` claim are treated as
|
|
168
|
+
* non-expiring.
|
|
169
|
+
*/
|
|
170
|
+
declare function isTokenExpired(token: string, expirationThreshold?: number): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Cookie parsing — extracts a name→value map from a Set-Cookie or
|
|
173
|
+
* Cookie header value. Decodes URI-encoded values. Mirrors the
|
|
174
|
+
* `cookie` npm package's signature so it's drop-in for the upstream
|
|
175
|
+
* client's `cookieParse`.
|
|
176
|
+
*/
|
|
177
|
+
declare function cookieParse(input: string): Record<string, string>;
|
|
178
|
+
interface CookieSerializeOptions {
|
|
179
|
+
encode?: (value: string) => string;
|
|
180
|
+
maxAge?: number;
|
|
181
|
+
domain?: string;
|
|
182
|
+
path?: string;
|
|
183
|
+
expires?: Date;
|
|
184
|
+
httpOnly?: boolean;
|
|
185
|
+
secure?: boolean;
|
|
186
|
+
sameSite?: 'strict' | 'lax' | 'none' | boolean;
|
|
187
|
+
priority?: 'low' | 'medium' | 'high';
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Cookie serialization — builds a `Set-Cookie` header value.
|
|
191
|
+
* `encode` defaults to `encodeURIComponent`. Throws if the name or
|
|
192
|
+
* encoded value contain invalid characters.
|
|
193
|
+
*/
|
|
194
|
+
declare function cookieSerialize(name: string, value: string, options?: CookieSerializeOptions): string;
|
|
195
|
+
/**
|
|
196
|
+
* Normalize a query-param record so values are always strings (or
|
|
197
|
+
* arrays of strings). Mirrors the upstream `normalizeUnknownQueryParams`
|
|
198
|
+
* helper used by the auto-encoding URL builder. Nullish entries are
|
|
199
|
+
* dropped; non-primitive entries are JSON-stringified.
|
|
200
|
+
*/
|
|
201
|
+
declare function normalizeUnknownQueryParams(params: Record<string, unknown> | null | undefined): Record<string, string | string[]>;
|
|
202
|
+
|
|
203
|
+
export { AsyncAuthStore, AuthChangeCallback, AuthStore, type BaseAuthStore, BaseRecord, type CollectionField, type CollectionModel, type CookieSerializeOptions, LocalAuthStore, type RecordModel, cookieParse, cookieSerialize, getTokenPayload, isTokenExpired, normalizeUnknownQueryParams };
|
package/dist/compat/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { AsyncAuthStore,
|
|
1
|
+
export { AsyncAuthStore, core_default as Base, LocalAuthStore, cookieParse, cookieSerialize, core_default as default, getTokenPayload, isTokenExpired, normalizeUnknownQueryParams } from '../chunk-DC6LDHAD.js';
|
|
2
|
+
export { BaseClient, ClientResponseError, MemoryAuthStore } from '../chunk-3WOGNODW.js';
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/dist/compat/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|