@ezwrld/ezbase 0.1.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.
@@ -0,0 +1,104 @@
1
+ type WhereOp = '==' | '!=' | '<' | '>' | '<=' | '>=';
2
+ type OrderDir = 'asc' | 'desc';
3
+ interface Document<T = Record<string, unknown>> {
4
+ id: string;
5
+ data: T;
6
+ created: number;
7
+ updated: number;
8
+ }
9
+ interface EzBaseOptions {
10
+ url: string;
11
+ adminKey?: string;
12
+ }
13
+ interface AuthUser {
14
+ id: string;
15
+ email: string;
16
+ role: string;
17
+ created?: number;
18
+ updated?: number;
19
+ }
20
+ type AuthStateCallback = (user: AuthUser | null) => void;
21
+ declare class AuthClient {
22
+ private ez;
23
+ private _token;
24
+ private _currentUser;
25
+ private _listeners;
26
+ constructor(ez: EzBase);
27
+ get currentUser(): AuthUser | null;
28
+ /** @internal */
29
+ _getToken(): string | null;
30
+ signUp(opts: {
31
+ email: string;
32
+ password: string;
33
+ }): Promise<{
34
+ token: string;
35
+ user: AuthUser;
36
+ }>;
37
+ signIn(opts: {
38
+ email: string;
39
+ password: string;
40
+ }): Promise<{
41
+ token: string;
42
+ user: AuthUser;
43
+ }>;
44
+ signOut(): void;
45
+ restoreSession(token: string, user: AuthUser): void;
46
+ onAuthStateChanged(callback: AuthStateCallback): () => void;
47
+ private _notify;
48
+ }
49
+ declare class EzBase {
50
+ private url;
51
+ private adminKey?;
52
+ readonly auth: AuthClient;
53
+ constructor(urlOrOpts: string | EzBaseOptions);
54
+ collection<T = Record<string, unknown>>(name: string): CollectionRef<T>;
55
+ /** @internal */
56
+ _getUrl(): string;
57
+ /** @internal */
58
+ _authHeaders(): Record<string, string>;
59
+ /** @internal — append token as query param for SSE (EventSource can't send headers) */
60
+ _sseTokenParam(): string;
61
+ }
62
+ declare class CollectionRef<T = Record<string, unknown>> {
63
+ private ez;
64
+ private name;
65
+ constructor(ez: EzBase, name: string);
66
+ doc(id: string): DocRef<T>;
67
+ where(field: string, op: WhereOp, value: unknown): QueryRef<T>;
68
+ orderBy(field: string, direction?: OrderDir): QueryRef<T>;
69
+ limit(n: number): QueryRef<T>;
70
+ add(data: Partial<T>): Promise<Document<T>>;
71
+ get(): Promise<Document<T>[]>;
72
+ onSnapshot(callback: (docs: Document<T>[]) => void, onError?: (err: Error) => void): () => void;
73
+ }
74
+ declare class DocRef<T = Record<string, unknown>> {
75
+ private ez;
76
+ private collection;
77
+ private id;
78
+ constructor(ez: EzBase, collection: string, id: string);
79
+ private path;
80
+ get(): Promise<Document<T> | null>;
81
+ set(data: T): Promise<Document<T>>;
82
+ update(data: Partial<T>): Promise<Document<T>>;
83
+ delete(): Promise<void>;
84
+ onSnapshot(callback: (doc: Document<T> | null) => void, onError?: (err: Error) => void): () => void;
85
+ }
86
+ declare class QueryRef<T = Record<string, unknown>> {
87
+ private ez;
88
+ private collection;
89
+ private wheres;
90
+ private _orderBy?;
91
+ private _order?;
92
+ private _limit?;
93
+ constructor(ez: EzBase, collection: string);
94
+ where(field: string, op: WhereOp, value: unknown): this;
95
+ orderBy(field: string, direction?: OrderDir): this;
96
+ limit(n: number): this;
97
+ private buildParams;
98
+ get(): Promise<Document<T>[]>;
99
+ onSnapshot(callback: (docs: Document<T>[]) => void, onError?: (err: Error) => void): () => void;
100
+ }
101
+ export { EzBase, CollectionRef, DocRef, QueryRef, AuthClient };
102
+ export type { Document, WhereOp, OrderDir, EzBaseOptions, AuthUser };
103
+ export default EzBase;
104
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,315 @@
1
+ // ── SSE helper (works in Node 18+, browsers, Deno, Bun) ──────
2
+ function sseConnect(url, headers, onSnapshot, onError) {
3
+ const controller = new AbortController();
4
+ (async () => {
5
+ try {
6
+ const res = await fetch(url, {
7
+ headers: { Accept: 'text/event-stream', ...headers },
8
+ signal: controller.signal,
9
+ });
10
+ if (!res.ok || !res.body) {
11
+ throw new Error(`SSE connect failed: ${res.status}`);
12
+ }
13
+ const reader = res.body.getReader();
14
+ const decoder = new TextDecoder();
15
+ let buf = '';
16
+ let eventType = '';
17
+ let dataLines = [];
18
+ while (true) {
19
+ const { done, value } = await reader.read();
20
+ if (done)
21
+ break;
22
+ buf += decoder.decode(value, { stream: true });
23
+ const lines = buf.split('\n');
24
+ buf = lines.pop();
25
+ for (const line of lines) {
26
+ if (line.startsWith('event:')) {
27
+ eventType = line.slice(6).trim();
28
+ }
29
+ else if (line.startsWith('data:')) {
30
+ dataLines.push(line.slice(5).trim());
31
+ }
32
+ else if (line === '' || line === '\r') {
33
+ if (eventType === 'snapshot' && dataLines.length > 0) {
34
+ onSnapshot(dataLines.join('\n'));
35
+ }
36
+ eventType = '';
37
+ dataLines = [];
38
+ }
39
+ }
40
+ }
41
+ }
42
+ catch (err) {
43
+ if (err instanceof Error && err.name !== 'AbortError') {
44
+ onError?.(err);
45
+ }
46
+ }
47
+ })();
48
+ return () => controller.abort();
49
+ }
50
+ // ── Auth client ───────────────────────────────────────────────
51
+ class AuthClient {
52
+ ez;
53
+ _token = null;
54
+ _currentUser = null;
55
+ _listeners = new Set();
56
+ constructor(ez) {
57
+ this.ez = ez;
58
+ }
59
+ get currentUser() {
60
+ return this._currentUser;
61
+ }
62
+ /** @internal */
63
+ _getToken() {
64
+ return this._token;
65
+ }
66
+ async signUp(opts) {
67
+ const res = await fetch(`${this.ez['url']}/api/auth/signup`, {
68
+ method: 'POST',
69
+ headers: { 'Content-Type': 'application/json', ...this.ez['_authHeaders']() },
70
+ body: JSON.stringify(opts),
71
+ });
72
+ if (!res.ok) {
73
+ const body = await res.json().catch(() => ({ error: res.statusText }));
74
+ throw new Error(`ezbase: ${body.error || res.statusText}`);
75
+ }
76
+ const data = await res.json();
77
+ this._token = data.token;
78
+ this._currentUser = data.user;
79
+ this._notify();
80
+ return data;
81
+ }
82
+ async signIn(opts) {
83
+ const res = await fetch(`${this.ez['url']}/api/auth/signin`, {
84
+ method: 'POST',
85
+ headers: { 'Content-Type': 'application/json', ...this.ez['_authHeaders']() },
86
+ body: JSON.stringify(opts),
87
+ });
88
+ if (!res.ok) {
89
+ const body = await res.json().catch(() => ({ error: res.statusText }));
90
+ throw new Error(`ezbase: ${body.error || res.statusText}`);
91
+ }
92
+ const data = await res.json();
93
+ this._token = data.token;
94
+ this._currentUser = data.user;
95
+ this._notify();
96
+ return data;
97
+ }
98
+ signOut() {
99
+ this._token = null;
100
+ this._currentUser = null;
101
+ this._notify();
102
+ }
103
+ restoreSession(token, user) {
104
+ this._token = token;
105
+ this._currentUser = user;
106
+ this._notify();
107
+ }
108
+ onAuthStateChanged(callback) {
109
+ this._listeners.add(callback);
110
+ return () => { this._listeners.delete(callback); };
111
+ }
112
+ _notify() {
113
+ for (const cb of this._listeners) {
114
+ try {
115
+ cb(this._currentUser);
116
+ }
117
+ catch { }
118
+ }
119
+ }
120
+ }
121
+ // ── EzBase client ─────────────────────────────────────────────
122
+ class EzBase {
123
+ url;
124
+ adminKey;
125
+ auth;
126
+ constructor(urlOrOpts) {
127
+ if (typeof urlOrOpts === 'string') {
128
+ this.url = urlOrOpts.replace(/\/$/, '');
129
+ }
130
+ else {
131
+ this.url = urlOrOpts.url.replace(/\/$/, '');
132
+ this.adminKey = urlOrOpts.adminKey;
133
+ }
134
+ this.auth = new AuthClient(this);
135
+ }
136
+ collection(name) {
137
+ return new CollectionRef(this, name);
138
+ }
139
+ /** @internal */
140
+ _getUrl() {
141
+ return this.url;
142
+ }
143
+ /** @internal */
144
+ _authHeaders() {
145
+ const token = this.adminKey || this.auth._getToken();
146
+ if (token)
147
+ return { Authorization: `Bearer ${token}` };
148
+ return {};
149
+ }
150
+ /** @internal — append token as query param for SSE (EventSource can't send headers) */
151
+ _sseTokenParam() {
152
+ const token = this.adminKey || this.auth._getToken();
153
+ if (token)
154
+ return `token=${encodeURIComponent(token)}`;
155
+ return '';
156
+ }
157
+ }
158
+ // ── Collection reference ──────────────────────────────────────
159
+ class CollectionRef {
160
+ ez;
161
+ name;
162
+ constructor(ez, name) {
163
+ this.ez = ez;
164
+ this.name = name;
165
+ }
166
+ doc(id) {
167
+ return new DocRef(this.ez, this.name, id);
168
+ }
169
+ where(field, op, value) {
170
+ return new QueryRef(this.ez, this.name).where(field, op, value);
171
+ }
172
+ orderBy(field, direction) {
173
+ return new QueryRef(this.ez, this.name).orderBy(field, direction);
174
+ }
175
+ limit(n) {
176
+ return new QueryRef(this.ez, this.name).limit(n);
177
+ }
178
+ async add(data) {
179
+ const res = await fetch(`${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}`, {
180
+ method: 'POST',
181
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
182
+ body: JSON.stringify(data),
183
+ });
184
+ if (!res.ok)
185
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
186
+ return res.json();
187
+ }
188
+ async get() {
189
+ const res = await fetch(`${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}`, { headers: this.ez._authHeaders() });
190
+ if (!res.ok)
191
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
192
+ return res.json();
193
+ }
194
+ onSnapshot(callback, onError) {
195
+ const tp = this.ez._sseTokenParam();
196
+ const sep = tp ? '?' : '';
197
+ const url = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}/sse${sep}${tp}`;
198
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError);
199
+ }
200
+ }
201
+ // ── Document reference ────────────────────────────────────────
202
+ class DocRef {
203
+ ez;
204
+ collection;
205
+ id;
206
+ constructor(ez, collection, id) {
207
+ this.ez = ez;
208
+ this.collection = collection;
209
+ this.id = id;
210
+ }
211
+ path() {
212
+ return `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}/${encodeURIComponent(this.id)}`;
213
+ }
214
+ async get() {
215
+ const res = await fetch(this.path(), { headers: this.ez._authHeaders() });
216
+ if (res.status === 404)
217
+ return null;
218
+ if (!res.ok)
219
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
220
+ return res.json();
221
+ }
222
+ async set(data) {
223
+ const res = await fetch(this.path(), {
224
+ method: 'PUT',
225
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
226
+ body: JSON.stringify(data),
227
+ });
228
+ if (!res.ok)
229
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
230
+ return res.json();
231
+ }
232
+ async update(data) {
233
+ const res = await fetch(this.path(), {
234
+ method: 'PATCH',
235
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
236
+ body: JSON.stringify(data),
237
+ });
238
+ if (!res.ok)
239
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
240
+ return res.json();
241
+ }
242
+ async delete() {
243
+ const res = await fetch(this.path(), {
244
+ method: 'DELETE',
245
+ headers: this.ez._authHeaders(),
246
+ });
247
+ if (!res.ok)
248
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
249
+ }
250
+ onSnapshot(callback, onError) {
251
+ const tp = this.ez._sseTokenParam();
252
+ const sep = tp ? '?' : '';
253
+ const url = `${this.path()}/sse${sep}${tp}`;
254
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError);
255
+ }
256
+ }
257
+ // ── Query reference (chainable) ──────────────────────────────
258
+ class QueryRef {
259
+ ez;
260
+ collection;
261
+ wheres = [];
262
+ _orderBy;
263
+ _order;
264
+ _limit;
265
+ constructor(ez, collection) {
266
+ this.ez = ez;
267
+ this.collection = collection;
268
+ }
269
+ where(field, op, value) {
270
+ this.wheres.push([field, op, value]);
271
+ return this;
272
+ }
273
+ orderBy(field, direction = 'asc') {
274
+ this._orderBy = field;
275
+ this._order = direction;
276
+ return this;
277
+ }
278
+ limit(n) {
279
+ this._limit = n;
280
+ return this;
281
+ }
282
+ buildParams() {
283
+ const params = new URLSearchParams();
284
+ if (this.wheres.length > 0) {
285
+ params.set('where', JSON.stringify(this.wheres));
286
+ }
287
+ if (this._orderBy) {
288
+ params.set('orderBy', this._orderBy);
289
+ if (this._order)
290
+ params.set('order', this._order);
291
+ }
292
+ if (this._limit !== undefined) {
293
+ params.set('limit', String(this._limit));
294
+ }
295
+ const qs = params.toString();
296
+ return qs ? '?' + qs : '';
297
+ }
298
+ async get() {
299
+ const url = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}${this.buildParams()}`;
300
+ const res = await fetch(url, { headers: this.ez._authHeaders() });
301
+ if (!res.ok)
302
+ throw new Error(`ezbase: ${res.status} ${await res.text()}`);
303
+ return res.json();
304
+ }
305
+ onSnapshot(callback, onError) {
306
+ const base = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}/sse${this.buildParams()}`;
307
+ const tp = this.ez._sseTokenParam();
308
+ const sep = base.includes('?') ? '&' : '?';
309
+ const url = tp ? `${base}${sep}${tp}` : base;
310
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError);
311
+ }
312
+ }
313
+ export { EzBase, CollectionRef, DocRef, QueryRef, AuthClient };
314
+ export default EzBase;
315
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@ezwrld/ezbase",
3
+ "version": "0.1.0",
4
+ "description": "Client SDK for ezbase — a self-hosted document database with real-time subscriptions",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "src",
17
+ "tsconfig.json"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "prepublishOnly": "tsc"
23
+ },
24
+ "keywords": [
25
+ "database",
26
+ "document-database",
27
+ "realtime",
28
+ "sse",
29
+ "firebase-alternative",
30
+ "self-hosted",
31
+ "baas"
32
+ ],
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/ezwrld/ezbase",
37
+ "directory": "sdk"
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "^5.5.0"
41
+ }
42
+ }
package/src/index.ts ADDED
@@ -0,0 +1,379 @@
1
+ type WhereOp = '==' | '!=' | '<' | '>' | '<=' | '>='
2
+ type WhereClause = [string, WhereOp, unknown]
3
+ type OrderDir = 'asc' | 'desc'
4
+
5
+ interface Document<T = Record<string, unknown>> {
6
+ id: string
7
+ data: T
8
+ created: number
9
+ updated: number
10
+ }
11
+
12
+ interface EzBaseOptions {
13
+ url: string
14
+ adminKey?: string
15
+ }
16
+
17
+ interface AuthUser {
18
+ id: string
19
+ email: string
20
+ role: string
21
+ created?: number
22
+ updated?: number
23
+ }
24
+
25
+ type AuthStateCallback = (user: AuthUser | null) => void
26
+
27
+ // ── SSE helper (works in Node 18+, browsers, Deno, Bun) ──────
28
+ function sseConnect(
29
+ url: string,
30
+ headers: Record<string, string>,
31
+ onSnapshot: (data: string) => void,
32
+ onError?: (err: Error) => void
33
+ ): () => void {
34
+ const controller = new AbortController()
35
+
36
+ ;(async () => {
37
+ try {
38
+ const res = await fetch(url, {
39
+ headers: { Accept: 'text/event-stream', ...headers },
40
+ signal: controller.signal,
41
+ })
42
+
43
+ if (!res.ok || !res.body) {
44
+ throw new Error(`SSE connect failed: ${res.status}`)
45
+ }
46
+
47
+ const reader = res.body.getReader()
48
+ const decoder = new TextDecoder()
49
+ let buf = ''
50
+ let eventType = ''
51
+ let dataLines: string[] = []
52
+
53
+ while (true) {
54
+ const { done, value } = await reader.read()
55
+ if (done) break
56
+
57
+ buf += decoder.decode(value, { stream: true })
58
+ const lines = buf.split('\n')
59
+ buf = lines.pop()!
60
+
61
+ for (const line of lines) {
62
+ if (line.startsWith('event:')) {
63
+ eventType = line.slice(6).trim()
64
+ } else if (line.startsWith('data:')) {
65
+ dataLines.push(line.slice(5).trim())
66
+ } else if (line === '' || line === '\r') {
67
+ if (eventType === 'snapshot' && dataLines.length > 0) {
68
+ onSnapshot(dataLines.join('\n'))
69
+ }
70
+ eventType = ''
71
+ dataLines = []
72
+ }
73
+ }
74
+ }
75
+ } catch (err: unknown) {
76
+ if (err instanceof Error && err.name !== 'AbortError') {
77
+ onError?.(err)
78
+ }
79
+ }
80
+ })()
81
+
82
+ return () => controller.abort()
83
+ }
84
+
85
+ // ── Auth client ───────────────────────────────────────────────
86
+ class AuthClient {
87
+ private _token: string | null = null
88
+ private _currentUser: AuthUser | null = null
89
+ private _listeners = new Set<AuthStateCallback>()
90
+
91
+ constructor(private ez: EzBase) {}
92
+
93
+ get currentUser(): AuthUser | null {
94
+ return this._currentUser
95
+ }
96
+
97
+ /** @internal */
98
+ _getToken(): string | null {
99
+ return this._token
100
+ }
101
+
102
+ async signUp(opts: { email: string; password: string }): Promise<{ token: string; user: AuthUser }> {
103
+ const res = await fetch(`${this.ez['url']}/api/auth/signup`, {
104
+ method: 'POST',
105
+ headers: { 'Content-Type': 'application/json', ...this.ez['_authHeaders']() },
106
+ body: JSON.stringify(opts),
107
+ })
108
+ if (!res.ok) {
109
+ const body = await res.json().catch(() => ({ error: res.statusText }))
110
+ throw new Error(`ezbase: ${body.error || res.statusText}`)
111
+ }
112
+ const data = await res.json()
113
+ this._token = data.token
114
+ this._currentUser = data.user
115
+ this._notify()
116
+ return data
117
+ }
118
+
119
+ async signIn(opts: { email: string; password: string }): Promise<{ token: string; user: AuthUser }> {
120
+ const res = await fetch(`${this.ez['url']}/api/auth/signin`, {
121
+ method: 'POST',
122
+ headers: { 'Content-Type': 'application/json', ...this.ez['_authHeaders']() },
123
+ body: JSON.stringify(opts),
124
+ })
125
+ if (!res.ok) {
126
+ const body = await res.json().catch(() => ({ error: res.statusText }))
127
+ throw new Error(`ezbase: ${body.error || res.statusText}`)
128
+ }
129
+ const data = await res.json()
130
+ this._token = data.token
131
+ this._currentUser = data.user
132
+ this._notify()
133
+ return data
134
+ }
135
+
136
+ signOut() {
137
+ this._token = null
138
+ this._currentUser = null
139
+ this._notify()
140
+ }
141
+
142
+ restoreSession(token: string, user: AuthUser) {
143
+ this._token = token
144
+ this._currentUser = user
145
+ this._notify()
146
+ }
147
+
148
+ onAuthStateChanged(callback: AuthStateCallback): () => void {
149
+ this._listeners.add(callback)
150
+ return () => { this._listeners.delete(callback) }
151
+ }
152
+
153
+ private _notify() {
154
+ for (const cb of this._listeners) {
155
+ try { cb(this._currentUser) } catch {}
156
+ }
157
+ }
158
+ }
159
+
160
+ // ── EzBase client ─────────────────────────────────────────────
161
+ class EzBase {
162
+ private url: string
163
+ private adminKey?: string
164
+ readonly auth: AuthClient
165
+
166
+ constructor(urlOrOpts: string | EzBaseOptions) {
167
+ if (typeof urlOrOpts === 'string') {
168
+ this.url = urlOrOpts.replace(/\/$/, '')
169
+ } else {
170
+ this.url = urlOrOpts.url.replace(/\/$/, '')
171
+ this.adminKey = urlOrOpts.adminKey
172
+ }
173
+ this.auth = new AuthClient(this)
174
+ }
175
+
176
+ collection<T = Record<string, unknown>>(name: string): CollectionRef<T> {
177
+ return new CollectionRef<T>(this, name)
178
+ }
179
+
180
+ /** @internal */
181
+ _getUrl(): string {
182
+ return this.url
183
+ }
184
+
185
+ /** @internal */
186
+ _authHeaders(): Record<string, string> {
187
+ const token = this.adminKey || this.auth._getToken()
188
+ if (token) return { Authorization: `Bearer ${token}` }
189
+ return {}
190
+ }
191
+
192
+ /** @internal — append token as query param for SSE (EventSource can't send headers) */
193
+ _sseTokenParam(): string {
194
+ const token = this.adminKey || this.auth._getToken()
195
+ if (token) return `token=${encodeURIComponent(token)}`
196
+ return ''
197
+ }
198
+ }
199
+
200
+ // ── Collection reference ──────────────────────────────────────
201
+ class CollectionRef<T = Record<string, unknown>> {
202
+ constructor(
203
+ private ez: EzBase,
204
+ private name: string
205
+ ) {}
206
+
207
+ doc(id: string): DocRef<T> {
208
+ return new DocRef<T>(this.ez, this.name, id)
209
+ }
210
+
211
+ where(field: string, op: WhereOp, value: unknown): QueryRef<T> {
212
+ return new QueryRef<T>(this.ez, this.name).where(field, op, value)
213
+ }
214
+
215
+ orderBy(field: string, direction?: OrderDir): QueryRef<T> {
216
+ return new QueryRef<T>(this.ez, this.name).orderBy(field, direction)
217
+ }
218
+
219
+ limit(n: number): QueryRef<T> {
220
+ return new QueryRef<T>(this.ez, this.name).limit(n)
221
+ }
222
+
223
+ async add(data: Partial<T>): Promise<Document<T>> {
224
+ const res = await fetch(
225
+ `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}`,
226
+ {
227
+ method: 'POST',
228
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
229
+ body: JSON.stringify(data),
230
+ }
231
+ )
232
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
233
+ return res.json()
234
+ }
235
+
236
+ async get(): Promise<Document<T>[]> {
237
+ const res = await fetch(
238
+ `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}`,
239
+ { headers: this.ez._authHeaders() }
240
+ )
241
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
242
+ return res.json()
243
+ }
244
+
245
+ onSnapshot(
246
+ callback: (docs: Document<T>[]) => void,
247
+ onError?: (err: Error) => void
248
+ ): () => void {
249
+ const tp = this.ez._sseTokenParam()
250
+ const sep = tp ? '?' : ''
251
+ const url = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.name)}/sse${sep}${tp}`
252
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError)
253
+ }
254
+ }
255
+
256
+ // ── Document reference ────────────────────────────────────────
257
+ class DocRef<T = Record<string, unknown>> {
258
+ constructor(
259
+ private ez: EzBase,
260
+ private collection: string,
261
+ private id: string
262
+ ) {}
263
+
264
+ private path(): string {
265
+ return `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}/${encodeURIComponent(this.id)}`
266
+ }
267
+
268
+ async get(): Promise<Document<T> | null> {
269
+ const res = await fetch(this.path(), { headers: this.ez._authHeaders() })
270
+ if (res.status === 404) return null
271
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
272
+ return res.json()
273
+ }
274
+
275
+ async set(data: T): Promise<Document<T>> {
276
+ const res = await fetch(this.path(), {
277
+ method: 'PUT',
278
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
279
+ body: JSON.stringify(data),
280
+ })
281
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
282
+ return res.json()
283
+ }
284
+
285
+ async update(data: Partial<T>): Promise<Document<T>> {
286
+ const res = await fetch(this.path(), {
287
+ method: 'PATCH',
288
+ headers: { 'Content-Type': 'application/json', ...this.ez._authHeaders() },
289
+ body: JSON.stringify(data),
290
+ })
291
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
292
+ return res.json()
293
+ }
294
+
295
+ async delete(): Promise<void> {
296
+ const res = await fetch(this.path(), {
297
+ method: 'DELETE',
298
+ headers: this.ez._authHeaders(),
299
+ })
300
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
301
+ }
302
+
303
+ onSnapshot(
304
+ callback: (doc: Document<T> | null) => void,
305
+ onError?: (err: Error) => void
306
+ ): () => void {
307
+ const tp = this.ez._sseTokenParam()
308
+ const sep = tp ? '?' : ''
309
+ const url = `${this.path()}/sse${sep}${tp}`
310
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError)
311
+ }
312
+ }
313
+
314
+ // ── Query reference (chainable) ──────────────────────────────
315
+ class QueryRef<T = Record<string, unknown>> {
316
+ private wheres: WhereClause[] = []
317
+ private _orderBy?: string
318
+ private _order?: OrderDir
319
+ private _limit?: number
320
+
321
+ constructor(
322
+ private ez: EzBase,
323
+ private collection: string
324
+ ) {}
325
+
326
+ where(field: string, op: WhereOp, value: unknown): this {
327
+ this.wheres.push([field, op, value])
328
+ return this
329
+ }
330
+
331
+ orderBy(field: string, direction: OrderDir = 'asc'): this {
332
+ this._orderBy = field
333
+ this._order = direction
334
+ return this
335
+ }
336
+
337
+ limit(n: number): this {
338
+ this._limit = n
339
+ return this
340
+ }
341
+
342
+ private buildParams(): string {
343
+ const params = new URLSearchParams()
344
+ if (this.wheres.length > 0) {
345
+ params.set('where', JSON.stringify(this.wheres))
346
+ }
347
+ if (this._orderBy) {
348
+ params.set('orderBy', this._orderBy)
349
+ if (this._order) params.set('order', this._order)
350
+ }
351
+ if (this._limit !== undefined) {
352
+ params.set('limit', String(this._limit))
353
+ }
354
+ const qs = params.toString()
355
+ return qs ? '?' + qs : ''
356
+ }
357
+
358
+ async get(): Promise<Document<T>[]> {
359
+ const url = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}${this.buildParams()}`
360
+ const res = await fetch(url, { headers: this.ez._authHeaders() })
361
+ if (!res.ok) throw new Error(`ezbase: ${res.status} ${await res.text()}`)
362
+ return res.json()
363
+ }
364
+
365
+ onSnapshot(
366
+ callback: (docs: Document<T>[]) => void,
367
+ onError?: (err: Error) => void
368
+ ): () => void {
369
+ const base = `${this.ez._getUrl()}/api/collections/${encodeURIComponent(this.collection)}/sse${this.buildParams()}`
370
+ const tp = this.ez._sseTokenParam()
371
+ const sep = base.includes('?') ? '&' : '?'
372
+ const url = tp ? `${base}${sep}${tp}` : base
373
+ return sseConnect(url, this.ez._authHeaders(), (data) => callback(JSON.parse(data)), onError)
374
+ }
375
+ }
376
+
377
+ export { EzBase, CollectionRef, DocRef, QueryRef, AuthClient }
378
+ export type { Document, WhereOp, OrderDir, EzBaseOptions, AuthUser }
379
+ export default EzBase
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "skipLibCheck": true
13
+ },
14
+ "include": ["src"]
15
+ }