zone4code-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # zone4code-sdk
2
+
3
+ Official TypeScript & JavaScript Client SDK for the **Zone4Code Platform** & **Singulary**.
4
+
5
+ Provides a type-safe, chainable interface (similar to Supabase / Prisma) for **Keycloak Authentication**, **Adaptive Object-Model (AOM) Dynamic Schemas**, and **JSONB Querying** over the Unified API Gateway.
6
+
7
+ ---
8
+
9
+ ## 📦 Installation
10
+
11
+ ```bash
12
+ npm install zone4code-sdk
13
+ # or
14
+ pnpm add zone4code-sdk
15
+ ```
16
+
17
+ ---
18
+
19
+ ## 🚀 Quick Start
20
+
21
+ ```typescript
22
+ import { createClient } from 'zone4code-sdk';
23
+
24
+ const client = createClient({
25
+ gatewayUrl: 'http://localhost:8080', // Or your remote server: https://api.yourdomain.com
26
+ tenantId: 'my-workspace-id'
27
+ });
28
+
29
+ // 1. Check Gateway Health
30
+ const health = await client.health();
31
+ console.log('Connected to Gateway:', health.licenseTier);
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 🔐 Authentication
37
+
38
+ ```typescript
39
+ // Register a new user
40
+ await client.auth.register({
41
+ email: 'alice@example.com',
42
+ password: 'SecurePassword123!',
43
+ name: 'Alice Smith'
44
+ });
45
+
46
+ // Login (JWT token is automatically saved to localStorage/Memory)
47
+ const { token } = await client.auth.login({
48
+ email: 'alice@example.com',
49
+ password: 'SecurePassword123!'
50
+ });
51
+
52
+ // Check status & profile
53
+ if (client.auth.isAuthenticated()) {
54
+ const profile = await client.auth.getProfile();
55
+ console.log('Logged in as:', profile.email);
56
+ }
57
+
58
+ // Logout
59
+ client.auth.logout();
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 📊 Database CRUD & Fluent Query Builder
65
+
66
+ ### 1. Create a Record
67
+ ```typescript
68
+ const newOrder = await client.from('order').create({
69
+ orderNumber: 'ORD-9021',
70
+ amount: 250.00,
71
+ status: 'pending',
72
+ customer: 'Acme Corp'
73
+ });
74
+ console.log('Created order ID:', newOrder.id);
75
+ ```
76
+
77
+ ### 2. Query with Chainable Filters
78
+ ```typescript
79
+ const { data, total } = await client.from('order')
80
+ .eq('status', 'pending')
81
+ .gte('amount', 100)
82
+ .like('customer', 'Acme') // Case-insensitive ILIKE %Acme%
83
+ .orderBy('amount', 'desc') // Sort highest amount first
84
+ .page(1, 20) // Page 1, 20 items per page
85
+ .list();
86
+
87
+ console.log(`Found ${total} orders:`, data);
88
+ ```
89
+
90
+ ### 3. Update & Delete
91
+ ```typescript
92
+ // Update
93
+ await client.from('order').update(orderId, {
94
+ status: 'paid'
95
+ });
96
+
97
+ // Soft Delete
98
+ await client.from('order').delete(orderId);
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 🛠️ Dynamic Schema Alteration
104
+
105
+ ```typescript
106
+ await client.schema.define({
107
+ typeName: 'invoice',
108
+ schema: {
109
+ type: 'object',
110
+ required: ['invoiceNumber', 'total'],
111
+ properties: {
112
+ invoiceNumber: { type: 'string' },
113
+ total: { type: 'number' },
114
+ dueDate: { type: 'string', format: 'date-time' }
115
+ }
116
+ }
117
+ });
118
+ ```
119
+
120
+ ---
121
+
122
+ ## 🛡️ Complete Operator Reference
123
+
124
+ | Method | Generated SQL Clause | Description |
125
+ |---|---|---|
126
+ | `.eq(field, value)` | `data->>'field' = value` | Exact equality |
127
+ | `.ne(field, value)` | `data->>'field' != value` | Not equal |
128
+ | `.gt(field, number)` | `(data->>'field')::numeric > number` | Numeric greater than |
129
+ | `.gte(field, number)` | `(data->>'field')::numeric >= number` | Numeric greater than or equal |
130
+ | `.lt(field, number)` | `(data->>'field')::numeric < number` | Numeric less than |
131
+ | `.lte(field, number)` | `(data->>'field')::numeric <= number` | Numeric less than or equal |
132
+ | `.like(field, sub)` | `data->>'field' ILIKE '%sub%'` | Substring search (case-insensitive) |
133
+ | `.in(field, [a, b])` | `data->>'field' = ANY(ARRAY['a', 'b'])` | In set |
134
+ | `.isNull(field)` | `data->>'field' IS NULL` | Field is null or missing |
135
+ | `.isNotNull(field)` | `data->>'field' IS NOT NULL` | Field is present |
136
+ | `.related(name, ids)`| `EXISTS (entity_relations)` | Graph relation filter |
137
+
138
+ ---
139
+
140
+ ## 📄 License
141
+ MIT © Zone4Code
package/dist/index.cjs ADDED
@@ -0,0 +1,476 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthClient: () => AuthClient,
24
+ EntityQueryBuilder: () => EntityQueryBuilder,
25
+ MemoryStorage: () => MemoryStorage,
26
+ SchemaClient: () => SchemaClient,
27
+ Zone4CodeClient: () => Zone4CodeClient,
28
+ createClient: () => createClient,
29
+ default: () => createClient,
30
+ getDefaultStorage: () => getDefaultStorage
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/storage.ts
35
+ var MemoryStorage = class {
36
+ store = /* @__PURE__ */ new Map();
37
+ getItem(key) {
38
+ return this.store.get(key) ?? null;
39
+ }
40
+ setItem(key, value) {
41
+ this.store.set(key, value);
42
+ }
43
+ removeItem(key) {
44
+ this.store.delete(key);
45
+ }
46
+ };
47
+ function getDefaultStorage() {
48
+ if (typeof window !== "undefined" && window.localStorage) {
49
+ return window.localStorage;
50
+ }
51
+ return new MemoryStorage();
52
+ }
53
+
54
+ // src/auth.ts
55
+ var AuthClient = class _AuthClient {
56
+ gatewayUrl;
57
+ tenantId;
58
+ storage;
59
+ token = null;
60
+ fetchFn;
61
+ static TOKEN_KEY_PREFIX = "z4c_token_";
62
+ constructor(options) {
63
+ this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
64
+ this.tenantId = options.tenantId;
65
+ this.storage = options.storage;
66
+ this.fetchFn = options.fetchFn || (typeof fetch !== "undefined" ? fetch : globalThis.fetch);
67
+ if (options.initialToken) {
68
+ this.setToken(options.initialToken);
69
+ } else {
70
+ Promise.resolve(this.storage.getItem(_AuthClient.TOKEN_KEY_PREFIX + this.tenantId)).then((stored) => {
71
+ if (stored) this.token = stored;
72
+ }).catch(() => {
73
+ });
74
+ }
75
+ }
76
+ getToken() {
77
+ return this.token;
78
+ }
79
+ setToken(token) {
80
+ this.token = token;
81
+ const storageKey = _AuthClient.TOKEN_KEY_PREFIX + this.tenantId;
82
+ if (token) {
83
+ this.storage.setItem(storageKey, token);
84
+ } else {
85
+ this.storage.removeItem(storageKey);
86
+ }
87
+ }
88
+ isAuthenticated() {
89
+ return !!this.token;
90
+ }
91
+ /**
92
+ * Register a new user in the tenant realm
93
+ */
94
+ async register(data) {
95
+ const url = `${this.gatewayUrl}/auth/${this.tenantId}/user/register`;
96
+ const res = await this.fetchFn(url, {
97
+ method: "POST",
98
+ headers: {
99
+ "Content-Type": "application/json",
100
+ "x-tenant-id": this.tenantId
101
+ },
102
+ body: JSON.stringify(data)
103
+ });
104
+ if (!res.ok) {
105
+ const err = await res.json().catch(() => ({ message: res.statusText }));
106
+ throw new Error(err.message || err.error || `Registration failed with HTTP ${res.status}`);
107
+ }
108
+ const json = await res.json();
109
+ const token = json.token || json.access_token;
110
+ if (token) {
111
+ this.setToken(token);
112
+ }
113
+ return json;
114
+ }
115
+ /**
116
+ * Log in an existing user and store their JWT token
117
+ */
118
+ async login(credentials) {
119
+ const url = `${this.gatewayUrl}/auth/${this.tenantId}/login`;
120
+ const res = await this.fetchFn(url, {
121
+ method: "POST",
122
+ headers: {
123
+ "Content-Type": "application/json",
124
+ "x-tenant-id": this.tenantId
125
+ },
126
+ body: JSON.stringify(credentials)
127
+ });
128
+ if (!res.ok) {
129
+ const err = await res.json().catch(() => ({ message: res.statusText }));
130
+ throw new Error(err.message || err.error || `Login failed with HTTP ${res.status}`);
131
+ }
132
+ const json = await res.json();
133
+ const token = json.token || json.access_token;
134
+ if (token) {
135
+ this.setToken(token);
136
+ }
137
+ return json;
138
+ }
139
+ /**
140
+ * Fetch current authenticated user profile
141
+ */
142
+ async getProfile() {
143
+ if (!this.token) {
144
+ throw new Error("Not authenticated: please call login() or setToken() first");
145
+ }
146
+ const url = `${this.gatewayUrl}/auth/${this.tenantId}/user/profile`;
147
+ const res = await this.fetchFn(url, {
148
+ headers: {
149
+ "Authorization": `Bearer ${this.token}`,
150
+ "x-tenant-id": this.tenantId
151
+ }
152
+ });
153
+ if (!res.ok) {
154
+ const err = await res.json().catch(() => ({ message: res.statusText }));
155
+ throw new Error(err.message || `Failed to fetch profile (HTTP ${res.status})`);
156
+ }
157
+ return res.json();
158
+ }
159
+ /**
160
+ * Log out and clear saved token
161
+ */
162
+ logout() {
163
+ this.setToken(null);
164
+ }
165
+ };
166
+
167
+ // src/schema.ts
168
+ var SchemaClient = class {
169
+ gatewayUrl;
170
+ tenantId;
171
+ getToken;
172
+ fetchFn;
173
+ constructor(options) {
174
+ this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
175
+ this.tenantId = options.tenantId;
176
+ this.getToken = options.getToken;
177
+ this.fetchFn = options.fetchFn || (typeof fetch !== "undefined" ? fetch : globalThis.fetch);
178
+ }
179
+ getHeaders() {
180
+ const headers = {
181
+ "Content-Type": "application/json",
182
+ "x-tenant-id": this.tenantId
183
+ };
184
+ const token = this.getToken();
185
+ if (token) {
186
+ headers["Authorization"] = `Bearer ${token}`;
187
+ }
188
+ return headers;
189
+ }
190
+ /**
191
+ * Define a new JSON Schema or alter an existing schema for an entity type in real-time
192
+ */
193
+ async define(definition) {
194
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/definition`;
195
+ const res = await this.fetchFn(url, {
196
+ method: "POST",
197
+ headers: this.getHeaders(),
198
+ body: JSON.stringify(definition)
199
+ });
200
+ if (!res.ok) {
201
+ const err = await res.json().catch(() => ({ message: res.statusText }));
202
+ throw new Error(err.message || `Failed to define schema for ${definition.typeName}`);
203
+ }
204
+ return res.json();
205
+ }
206
+ };
207
+
208
+ // src/query-builder.ts
209
+ var EntityQueryBuilder = class {
210
+ gatewayUrl;
211
+ tenantId;
212
+ typeName;
213
+ getToken;
214
+ fetchFn;
215
+ queryParams = new URLSearchParams();
216
+ constructor(options) {
217
+ this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
218
+ this.tenantId = options.tenantId;
219
+ this.typeName = options.typeName;
220
+ this.getToken = options.getToken;
221
+ this.fetchFn = options.fetchFn || (typeof fetch !== "undefined" ? fetch : globalThis.fetch);
222
+ }
223
+ getHeaders() {
224
+ const headers = {
225
+ "Content-Type": "application/json",
226
+ "x-tenant-id": this.tenantId
227
+ };
228
+ const token = this.getToken();
229
+ if (token) {
230
+ headers["Authorization"] = `Bearer ${token}`;
231
+ }
232
+ return headers;
233
+ }
234
+ // ----------------------------------------------------
235
+ // Filter Operators
236
+ // ----------------------------------------------------
237
+ eq(field, value) {
238
+ this.queryParams.append(`${field}[eq]`, String(value));
239
+ return this;
240
+ }
241
+ ne(field, value) {
242
+ this.queryParams.append(`${field}[ne]`, String(value));
243
+ return this;
244
+ }
245
+ gt(field, value) {
246
+ this.queryParams.append(`${field}[gt]`, String(value));
247
+ return this;
248
+ }
249
+ gte(field, value) {
250
+ this.queryParams.append(`${field}[gte]`, String(value));
251
+ return this;
252
+ }
253
+ lt(field, value) {
254
+ this.queryParams.append(`${field}[lt]`, String(value));
255
+ return this;
256
+ }
257
+ lte(field, value) {
258
+ this.queryParams.append(`${field}[lte]`, String(value));
259
+ return this;
260
+ }
261
+ /**
262
+ * Case-insensitive substring search (ILIKE %substring%)
263
+ */
264
+ like(field, substring) {
265
+ this.queryParams.append(`${field}[like]`, substring);
266
+ return this;
267
+ }
268
+ /**
269
+ * Set membership: matches if field value is in the array
270
+ */
271
+ in(field, values) {
272
+ this.queryParams.append(`${field}[in]`, values.map(String).join(","));
273
+ return this;
274
+ }
275
+ isNull(field) {
276
+ this.queryParams.append(`${field}[null]`, "true");
277
+ return this;
278
+ }
279
+ isNotNull(field) {
280
+ this.queryParams.append(`${field}[null]`, "false");
281
+ return this;
282
+ }
283
+ /**
284
+ * Filter entities connected by graph relationship
285
+ */
286
+ related(relationName, entityIds) {
287
+ const ids = Array.isArray(entityIds) ? entityIds.join(",") : entityIds;
288
+ this.queryParams.append(`related[${relationName}]`, ids);
289
+ return this;
290
+ }
291
+ // ----------------------------------------------------
292
+ // Sorting, Pagination & Modifiers
293
+ // ----------------------------------------------------
294
+ orderBy(field, direction = "asc") {
295
+ const sortVal = direction === "desc" ? `-${field}` : field;
296
+ this.queryParams.append("sort", sortVal);
297
+ return this;
298
+ }
299
+ limit(limit) {
300
+ this.queryParams.set("limit", String(limit));
301
+ return this;
302
+ }
303
+ page(page, limit) {
304
+ this.queryParams.set("page", String(page));
305
+ if (limit) this.queryParams.set("limit", String(limit));
306
+ return this;
307
+ }
308
+ offset(offset) {
309
+ this.queryParams.set("offset", String(offset));
310
+ return this;
311
+ }
312
+ cursor(token) {
313
+ this.queryParams.set("cursor", token);
314
+ return this;
315
+ }
316
+ flat(enabled = true) {
317
+ this.queryParams.set("flat", enabled ? "true" : "false");
318
+ return this;
319
+ }
320
+ // ----------------------------------------------------
321
+ // Execution Methods
322
+ // ----------------------------------------------------
323
+ /**
324
+ * Execute query and list matching records with pagination metadata
325
+ */
326
+ async list() {
327
+ const qs = this.queryParams.toString();
328
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}${qs ? `?${qs}` : ""}`;
329
+ const res = await this.fetchFn(url, {
330
+ headers: this.getHeaders()
331
+ });
332
+ if (!res.ok) {
333
+ const err = await res.json().catch(() => ({ message: res.statusText }));
334
+ throw new Error(err.message || `Query failed with HTTP ${res.status}`);
335
+ }
336
+ return res.json();
337
+ }
338
+ /**
339
+ * Fetch a single entity by ID
340
+ */
341
+ async get(id) {
342
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;
343
+ const res = await this.fetchFn(url, {
344
+ headers: this.getHeaders()
345
+ });
346
+ if (!res.ok) {
347
+ const err = await res.json().catch(() => ({ message: res.statusText }));
348
+ throw new Error(err.message || `Failed to fetch ${this.typeName}/${id}`);
349
+ }
350
+ return res.json();
351
+ }
352
+ /**
353
+ * Create a new entity record matching schema
354
+ */
355
+ async create(data) {
356
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}`;
357
+ const res = await this.fetchFn(url, {
358
+ method: "POST",
359
+ headers: this.getHeaders(),
360
+ body: JSON.stringify(data)
361
+ });
362
+ if (!res.ok) {
363
+ const err = await res.json().catch(() => ({ message: res.statusText }));
364
+ throw new Error(err.message || `Failed to create record in ${this.typeName}`);
365
+ }
366
+ return res.json();
367
+ }
368
+ /**
369
+ * Update an existing entity record
370
+ */
371
+ async update(id, partialData) {
372
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;
373
+ const res = await this.fetchFn(url, {
374
+ method: "PATCH",
375
+ headers: this.getHeaders(),
376
+ body: JSON.stringify(partialData)
377
+ });
378
+ if (!res.ok) {
379
+ const err = await res.json().catch(() => ({ message: res.statusText }));
380
+ throw new Error(err.message || `Failed to update ${this.typeName}/${id}`);
381
+ }
382
+ return res.json();
383
+ }
384
+ /**
385
+ * Soft-delete an entity record
386
+ */
387
+ async delete(id) {
388
+ const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;
389
+ const res = await this.fetchFn(url, {
390
+ method: "DELETE",
391
+ headers: this.getHeaders()
392
+ });
393
+ if (!res.ok) {
394
+ const err = await res.json().catch(() => ({ message: res.statusText }));
395
+ throw new Error(err.message || `Failed to delete ${this.typeName}/${id}`);
396
+ }
397
+ return { success: true };
398
+ }
399
+ };
400
+
401
+ // src/client.ts
402
+ var Zone4CodeClient = class {
403
+ gatewayUrl;
404
+ tenantId;
405
+ auth;
406
+ schema;
407
+ storage;
408
+ fetchFn;
409
+ constructor(config) {
410
+ if (!config.gatewayUrl) {
411
+ throw new Error("Zone4CodeClient requires a `gatewayUrl` (e.g., http://localhost:8080)");
412
+ }
413
+ if (!config.tenantId) {
414
+ throw new Error("Zone4CodeClient requires a `tenantId` (workspace identifier)");
415
+ }
416
+ this.gatewayUrl = config.gatewayUrl.replace(/\/+$/, "");
417
+ this.tenantId = config.tenantId;
418
+ this.storage = config.storage || getDefaultStorage();
419
+ this.fetchFn = config.fetch || (typeof fetch !== "undefined" ? fetch : globalThis.fetch);
420
+ this.auth = new AuthClient({
421
+ gatewayUrl: this.gatewayUrl,
422
+ tenantId: this.tenantId,
423
+ storage: this.storage,
424
+ initialToken: config.token,
425
+ fetchFn: this.fetchFn
426
+ });
427
+ this.schema = new SchemaClient({
428
+ gatewayUrl: this.gatewayUrl,
429
+ tenantId: this.tenantId,
430
+ getToken: () => this.auth.getToken(),
431
+ fetchFn: this.fetchFn
432
+ });
433
+ }
434
+ /**
435
+ * Access an entity collection with chainable query builder (like Supabase .from('orders'))
436
+ */
437
+ from(typeName) {
438
+ return new EntityQueryBuilder({
439
+ gatewayUrl: this.gatewayUrl,
440
+ tenantId: this.tenantId,
441
+ typeName,
442
+ getToken: () => this.auth.getToken(),
443
+ fetchFn: this.fetchFn
444
+ });
445
+ }
446
+ /**
447
+ * Alias for .from(typeName)
448
+ */
449
+ entities(typeName) {
450
+ return this.from(typeName);
451
+ }
452
+ /**
453
+ * Check gateway connectivity & health
454
+ */
455
+ async health() {
456
+ const res = await this.fetchFn(`${this.gatewayUrl}/health`);
457
+ if (!res.ok) {
458
+ throw new Error(`Gateway health check failed with HTTP ${res.status}`);
459
+ }
460
+ return res.json();
461
+ }
462
+ };
463
+ function createClient(config) {
464
+ return new Zone4CodeClient(config);
465
+ }
466
+ // Annotate the CommonJS export names for ESM import in node:
467
+ 0 && (module.exports = {
468
+ AuthClient,
469
+ EntityQueryBuilder,
470
+ MemoryStorage,
471
+ SchemaClient,
472
+ Zone4CodeClient,
473
+ createClient,
474
+ getDefaultStorage
475
+ });
476
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/storage.ts","../src/auth.ts","../src/schema.ts","../src/query-builder.ts","../src/client.ts"],"sourcesContent":["export * from './types';\nexport * from './storage';\nexport * from './auth';\nexport * from './schema';\nexport * from './query-builder';\nexport * from './client';\n\nexport { createClient as default } from './client';\n","import { StorageAdapter } from './types';\n\nexport class MemoryStorage implements StorageAdapter {\n private store = new Map<string, string>();\n\n getItem(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n removeItem(key: string): void {\n this.store.delete(key);\n }\n}\n\nexport function getDefaultStorage(): StorageAdapter {\n if (typeof window !== 'undefined' && window.localStorage) {\n return window.localStorage;\n }\n return new MemoryStorage();\n}\n","import { AuthResponse, AuthUser, StorageAdapter } from './types';\n\nexport class AuthClient {\n private gatewayUrl: string;\n private tenantId: string;\n private storage: StorageAdapter;\n private token: string | null = null;\n private fetchFn: typeof fetch;\n\n private static TOKEN_KEY_PREFIX = 'z4c_token_';\n\n constructor(options: {\n gatewayUrl: string;\n tenantId: string;\n storage: StorageAdapter;\n initialToken?: string;\n fetchFn?: typeof fetch;\n }) {\n this.gatewayUrl = options.gatewayUrl.replace(/\\/+$/, '');\n this.tenantId = options.tenantId;\n this.storage = options.storage;\n this.fetchFn = options.fetchFn || (typeof fetch !== 'undefined' ? fetch : (globalThis.fetch as any));\n\n if (options.initialToken) {\n this.setToken(options.initialToken);\n } else {\n // Attempt load from storage\n Promise.resolve(this.storage.getItem(AuthClient.TOKEN_KEY_PREFIX + this.tenantId))\n .then((stored) => {\n if (stored) this.token = stored;\n })\n .catch(() => {});\n }\n }\n\n public getToken(): string | null {\n return this.token;\n }\n\n public setToken(token: string | null): void {\n this.token = token;\n const storageKey = AuthClient.TOKEN_KEY_PREFIX + this.tenantId;\n if (token) {\n this.storage.setItem(storageKey, token);\n } else {\n this.storage.removeItem(storageKey);\n }\n }\n\n public isAuthenticated(): boolean {\n return !!this.token;\n }\n\n /**\n * Register a new user in the tenant realm\n */\n async register(data: {\n email: string;\n password: string;\n name?: string;\n username?: string;\n attributes?: Record<string, any>;\n }): Promise<AuthResponse> {\n const url = `${this.gatewayUrl}/auth/${this.tenantId}/user/register`;\n const res = await this.fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-tenant-id': this.tenantId\n },\n body: JSON.stringify(data)\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || err.error || `Registration failed with HTTP ${res.status}`);\n }\n\n const json = await res.json();\n const token = json.token || json.access_token;\n if (token) {\n this.setToken(token);\n }\n return json;\n }\n\n /**\n * Log in an existing user and store their JWT token\n */\n async login(credentials: {\n email?: string;\n username?: string;\n password: string;\n }): Promise<AuthResponse> {\n const url = `${this.gatewayUrl}/auth/${this.tenantId}/login`;\n const res = await this.fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-tenant-id': this.tenantId\n },\n body: JSON.stringify(credentials)\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || err.error || `Login failed with HTTP ${res.status}`);\n }\n\n const json = await res.json();\n const token = json.token || json.access_token;\n if (token) {\n this.setToken(token);\n }\n return json;\n }\n\n /**\n * Fetch current authenticated user profile\n */\n async getProfile(): Promise<AuthUser> {\n if (!this.token) {\n throw new Error('Not authenticated: please call login() or setToken() first');\n }\n\n const url = `${this.gatewayUrl}/auth/${this.tenantId}/user/profile`;\n const res = await this.fetchFn(url, {\n headers: {\n 'Authorization': `Bearer ${this.token}`,\n 'x-tenant-id': this.tenantId\n }\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to fetch profile (HTTP ${res.status})`);\n }\n\n return res.json();\n }\n\n /**\n * Log out and clear saved token\n */\n logout(): void {\n this.setToken(null);\n }\n}\n","import { EntitySchemaDefinition } from './types';\n\nexport class SchemaClient {\n private gatewayUrl: string;\n private tenantId: string;\n private getToken: () => string | null;\n private fetchFn: typeof fetch;\n\n constructor(options: {\n gatewayUrl: string;\n tenantId: string;\n getToken: () => string | null;\n fetchFn?: typeof fetch;\n }) {\n this.gatewayUrl = options.gatewayUrl.replace(/\\/+$/, '');\n this.tenantId = options.tenantId;\n this.getToken = options.getToken;\n this.fetchFn = options.fetchFn || (typeof fetch !== 'undefined' ? fetch : (globalThis.fetch as any));\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-tenant-id': this.tenantId\n };\n const token = this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n return headers;\n }\n\n /**\n * Define a new JSON Schema or alter an existing schema for an entity type in real-time\n */\n async define(definition: EntitySchemaDefinition): Promise<{ success: boolean; version?: number }> {\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/definition`;\n const res = await this.fetchFn(url, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(definition)\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to define schema for ${definition.typeName}`);\n }\n\n return res.json();\n }\n}\n","import { EntityListResponse, EntityRecord, FilterOperator } from './types';\n\nexport class EntityQueryBuilder<T = Record<string, any>> {\n private gatewayUrl: string;\n private tenantId: string;\n private typeName: string;\n private getToken: () => string | null;\n private fetchFn: typeof fetch;\n\n private queryParams = new URLSearchParams();\n\n constructor(options: {\n gatewayUrl: string;\n tenantId: string;\n typeName: string;\n getToken: () => string | null;\n fetchFn?: typeof fetch;\n }) {\n this.gatewayUrl = options.gatewayUrl.replace(/\\/+$/, '');\n this.tenantId = options.tenantId;\n this.typeName = options.typeName;\n this.getToken = options.getToken;\n this.fetchFn = options.fetchFn || (typeof fetch !== 'undefined' ? fetch : (globalThis.fetch as any));\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-tenant-id': this.tenantId\n };\n const token = this.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n return headers;\n }\n\n // ----------------------------------------------------\n // Filter Operators\n // ----------------------------------------------------\n\n eq(field: string, value: string | number | boolean): this {\n this.queryParams.append(`${field}[eq]`, String(value));\n return this;\n }\n\n ne(field: string, value: string | number | boolean): this {\n this.queryParams.append(`${field}[ne]`, String(value));\n return this;\n }\n\n gt(field: string, value: number): this {\n this.queryParams.append(`${field}[gt]`, String(value));\n return this;\n }\n\n gte(field: string, value: number): this {\n this.queryParams.append(`${field}[gte]`, String(value));\n return this;\n }\n\n lt(field: string, value: number): this {\n this.queryParams.append(`${field}[lt]`, String(value));\n return this;\n }\n\n lte(field: string, value: number): this {\n this.queryParams.append(`${field}[lte]`, String(value));\n return this;\n }\n\n /**\n * Case-insensitive substring search (ILIKE %substring%)\n */\n like(field: string, substring: string): this {\n this.queryParams.append(`${field}[like]`, substring);\n return this;\n }\n\n /**\n * Set membership: matches if field value is in the array\n */\n in(field: string, values: Array<string | number>): this {\n this.queryParams.append(`${field}[in]`, values.map(String).join(','));\n return this;\n }\n\n isNull(field: string): this {\n this.queryParams.append(`${field}[null]`, 'true');\n return this;\n }\n\n isNotNull(field: string): this {\n this.queryParams.append(`${field}[null]`, 'false');\n return this;\n }\n\n /**\n * Filter entities connected by graph relationship\n */\n related(relationName: string, entityIds: string | string[]): this {\n const ids = Array.isArray(entityIds) ? entityIds.join(',') : entityIds;\n this.queryParams.append(`related[${relationName}]`, ids);\n return this;\n }\n\n // ----------------------------------------------------\n // Sorting, Pagination & Modifiers\n // ----------------------------------------------------\n\n orderBy(field: string, direction: 'asc' | 'desc' = 'asc'): this {\n const sortVal = direction === 'desc' ? `-${field}` : field;\n this.queryParams.append('sort', sortVal);\n return this;\n }\n\n limit(limit: number): this {\n this.queryParams.set('limit', String(limit));\n return this;\n }\n\n page(page: number, limit?: number): this {\n this.queryParams.set('page', String(page));\n if (limit) this.queryParams.set('limit', String(limit));\n return this;\n }\n\n offset(offset: number): this {\n this.queryParams.set('offset', String(offset));\n return this;\n }\n\n cursor(token: string): this {\n this.queryParams.set('cursor', token);\n return this;\n }\n\n flat(enabled: boolean = true): this {\n this.queryParams.set('flat', enabled ? 'true' : 'false');\n return this;\n }\n\n // ----------------------------------------------------\n // Execution Methods\n // ----------------------------------------------------\n\n /**\n * Execute query and list matching records with pagination metadata\n */\n async list(): Promise<EntityListResponse<T>> {\n const qs = this.queryParams.toString();\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}${qs ? `?${qs}` : ''}`;\n \n const res = await this.fetchFn(url, {\n headers: this.getHeaders()\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Query failed with HTTP ${res.status}`);\n }\n\n return res.json();\n }\n\n /**\n * Fetch a single entity by ID\n */\n async get(id: string): Promise<EntityRecord<T>> {\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;\n const res = await this.fetchFn(url, {\n headers: this.getHeaders()\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to fetch ${this.typeName}/${id}`);\n }\n\n return res.json();\n }\n\n /**\n * Create a new entity record matching schema\n */\n async create(data: T): Promise<EntityRecord<T>> {\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}`;\n const res = await this.fetchFn(url, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(data)\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to create record in ${this.typeName}`);\n }\n\n return res.json();\n }\n\n /**\n * Update an existing entity record\n */\n async update(id: string, partialData: Partial<T>): Promise<EntityRecord<T>> {\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;\n const res = await this.fetchFn(url, {\n method: 'PATCH',\n headers: this.getHeaders(),\n body: JSON.stringify(partialData)\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to update ${this.typeName}/${id}`);\n }\n\n return res.json();\n }\n\n /**\n * Soft-delete an entity record\n */\n async delete(id: string): Promise<{ success: boolean }> {\n const url = `${this.gatewayUrl}/generic/${this.tenantId}/${this.typeName}/${id}`;\n const res = await this.fetchFn(url, {\n method: 'DELETE',\n headers: this.getHeaders()\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(err.message || `Failed to delete ${this.typeName}/${id}`);\n }\n\n return { success: true };\n }\n}\n","import { AuthClient } from './auth';\nimport { EntityQueryBuilder } from './query-builder';\nimport { SchemaClient } from './schema';\nimport { getDefaultStorage } from './storage';\nimport { StorageAdapter, Zone4CodeConfig } from './types';\n\nexport class Zone4CodeClient {\n public readonly gatewayUrl: string;\n public readonly tenantId: string;\n public readonly auth: AuthClient;\n public readonly schema: SchemaClient;\n\n private storage: StorageAdapter;\n private fetchFn: typeof fetch;\n\n constructor(config: Zone4CodeConfig) {\n if (!config.gatewayUrl) {\n throw new Error('Zone4CodeClient requires a `gatewayUrl` (e.g., http://localhost:8080)');\n }\n if (!config.tenantId) {\n throw new Error('Zone4CodeClient requires a `tenantId` (workspace identifier)');\n }\n\n this.gatewayUrl = config.gatewayUrl.replace(/\\/+$/, '');\n this.tenantId = config.tenantId;\n this.storage = config.storage || getDefaultStorage();\n this.fetchFn = config.fetch || (typeof fetch !== 'undefined' ? fetch : (globalThis.fetch as any));\n\n this.auth = new AuthClient({\n gatewayUrl: this.gatewayUrl,\n tenantId: this.tenantId,\n storage: this.storage,\n initialToken: config.token,\n fetchFn: this.fetchFn\n });\n\n this.schema = new SchemaClient({\n gatewayUrl: this.gatewayUrl,\n tenantId: this.tenantId,\n getToken: () => this.auth.getToken(),\n fetchFn: this.fetchFn\n });\n }\n\n /**\n * Access an entity collection with chainable query builder (like Supabase .from('orders'))\n */\n public from<T = Record<string, any>>(typeName: string): EntityQueryBuilder<T> {\n return new EntityQueryBuilder<T>({\n gatewayUrl: this.gatewayUrl,\n tenantId: this.tenantId,\n typeName,\n getToken: () => this.auth.getToken(),\n fetchFn: this.fetchFn\n });\n }\n\n /**\n * Alias for .from(typeName)\n */\n public entities<T = Record<string, any>>(typeName: string): EntityQueryBuilder<T> {\n return this.from<T>(typeName);\n }\n\n /**\n * Check gateway connectivity & health\n */\n public async health(): Promise<{ status: string; licenseTier?: string }> {\n const res = await this.fetchFn(`${this.gatewayUrl}/health`);\n if (!res.ok) {\n throw new Error(`Gateway health check failed with HTTP ${res.status}`);\n }\n return res.json();\n }\n}\n\n/**\n * Factory function to instantiate a new Zone4Code client\n */\nexport function createClient(config: Zone4CodeConfig): Zone4CodeClient {\n return new Zone4CodeClient(config);\n}\n"],"mappings":"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","names":[]}