@objectstack/client 1.0.11 → 1.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.
package/dist/index.mjs CHANGED
@@ -215,16 +215,21 @@ var ObjectStackClient = class {
215
215
  getTypes: async () => {
216
216
  const route = this.getRoute("metadata");
217
217
  const res = await this.fetch(`${this.baseUrl}${route}`);
218
- return res.json();
218
+ return this.unwrapResponse(res);
219
219
  },
220
220
  /**
221
221
  * Get all items of a specific metadata type
222
222
  * @param type - Metadata type name (e.g., 'object', 'plugin')
223
+ * @param options - Optional filters (e.g., packageId to scope by package)
223
224
  */
224
- getItems: async (type) => {
225
+ getItems: async (type, options) => {
225
226
  const route = this.getRoute("metadata");
226
- const res = await this.fetch(`${this.baseUrl}${route}/${type}`);
227
- return res.json();
227
+ const params = new URLSearchParams();
228
+ if (options?.packageId) params.set("package", options.packageId);
229
+ const qs = params.toString();
230
+ const url = `${this.baseUrl}${route}/${type}${qs ? `?${qs}` : ""}`;
231
+ const res = await this.fetch(url);
232
+ return this.unwrapResponse(res);
228
233
  },
229
234
  /**
230
235
  * Get a specific object definition by name
@@ -234,7 +239,7 @@ var ObjectStackClient = class {
234
239
  getObject: async (name) => {
235
240
  const route = this.getRoute("metadata");
236
241
  const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);
237
- return res.json();
242
+ return this.unwrapResponse(res);
238
243
  },
239
244
  /**
240
245
  * Get a specific metadata item by type and name
@@ -244,7 +249,7 @@ var ObjectStackClient = class {
244
249
  getItem: async (type, name) => {
245
250
  const route = this.getRoute("metadata");
246
251
  const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`);
247
- return res.json();
252
+ return this.unwrapResponse(res);
248
253
  },
249
254
  /**
250
255
  * Save a metadata item
@@ -258,7 +263,7 @@ var ObjectStackClient = class {
258
263
  method: "PUT",
259
264
  body: JSON.stringify(item)
260
265
  });
261
- return res.json();
266
+ return this.unwrapResponse(res);
262
267
  },
263
268
  /**
264
269
  * Get object metadata with cache support
@@ -301,7 +306,7 @@ var ObjectStackClient = class {
301
306
  getView: async (object, type = "list") => {
302
307
  const route = this.getRoute("ui");
303
308
  const res = await this.fetch(`${this.baseUrl}${route}/view/${object}?type=${type}`);
304
- return res.json();
309
+ return this.unwrapResponse(res);
305
310
  }
306
311
  };
307
312
  /**
@@ -360,6 +365,91 @@ var ObjectStackClient = class {
360
365
  }
361
366
  }
362
367
  };
368
+ /**
369
+ * Package Management Services
370
+ *
371
+ * Manages the lifecycle of installed packages.
372
+ * A package (ManifestSchema) is the unit of installation.
373
+ * An app (AppSchema) is a UI navigation definition within a package.
374
+ * A package may contain 0, 1, or many apps, or be a pure functionality plugin.
375
+ *
376
+ * Endpoints:
377
+ * - GET /packages → list installed packages
378
+ * - GET /packages/:id → get package details
379
+ * - POST /packages → install a package
380
+ * - DELETE /packages/:id → uninstall a package
381
+ * - PATCH /packages/:id/enable → enable a package
382
+ * - PATCH /packages/:id/disable → disable a package
383
+ */
384
+ this.packages = {
385
+ /**
386
+ * List all installed packages with optional filters.
387
+ */
388
+ list: async (filters) => {
389
+ const route = this.getRoute("packages");
390
+ const params = new URLSearchParams();
391
+ if (filters?.status) params.set("status", filters.status);
392
+ if (filters?.type) params.set("type", filters.type);
393
+ if (filters?.enabled !== void 0) params.set("enabled", String(filters.enabled));
394
+ const qs = params.toString();
395
+ const url = `${this.baseUrl}${route}${qs ? "?" + qs : ""}`;
396
+ const res = await this.fetch(url);
397
+ return this.unwrapResponse(res);
398
+ },
399
+ /**
400
+ * Get a specific installed package by its ID (reverse domain identifier).
401
+ */
402
+ get: async (id) => {
403
+ const route = this.getRoute("packages");
404
+ const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}`);
405
+ return this.unwrapResponse(res);
406
+ },
407
+ /**
408
+ * Install a new package from its manifest.
409
+ */
410
+ install: async (manifest, options) => {
411
+ const route = this.getRoute("packages");
412
+ const res = await this.fetch(`${this.baseUrl}${route}`, {
413
+ method: "POST",
414
+ body: JSON.stringify({
415
+ manifest,
416
+ settings: options?.settings,
417
+ enableOnInstall: options?.enableOnInstall
418
+ })
419
+ });
420
+ return this.unwrapResponse(res);
421
+ },
422
+ /**
423
+ * Uninstall a package by its ID.
424
+ */
425
+ uninstall: async (id) => {
426
+ const route = this.getRoute("packages");
427
+ const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}`, {
428
+ method: "DELETE"
429
+ });
430
+ return this.unwrapResponse(res);
431
+ },
432
+ /**
433
+ * Enable a disabled package.
434
+ */
435
+ enable: async (id) => {
436
+ const route = this.getRoute("packages");
437
+ const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}/enable`, {
438
+ method: "PATCH"
439
+ });
440
+ return this.unwrapResponse(res);
441
+ },
442
+ /**
443
+ * Disable an installed package.
444
+ */
445
+ disable: async (id) => {
446
+ const route = this.getRoute("packages");
447
+ const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}/disable`, {
448
+ method: "PATCH"
449
+ });
450
+ return this.unwrapResponse(res);
451
+ }
452
+ };
363
453
  /**
364
454
  * Authentication Services
365
455
  */
@@ -455,7 +545,7 @@ var ObjectStackClient = class {
455
545
  method: "POST",
456
546
  body: JSON.stringify(query)
457
547
  });
458
- return res.json();
548
+ return this.unwrapResponse(res);
459
549
  },
460
550
  find: async (object, options = {}) => {
461
551
  const route = this.getRoute("data");
@@ -491,12 +581,12 @@ var ObjectStackClient = class {
491
581
  queryParams.set("groupBy", options.groupBy.join(","));
492
582
  }
493
583
  const res = await this.fetch(`${this.baseUrl}${route}/${object}?${queryParams.toString()}`);
494
- return res.json();
584
+ return this.unwrapResponse(res);
495
585
  },
496
586
  get: async (object, id) => {
497
587
  const route = this.getRoute("data");
498
588
  const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`);
499
- return res.json();
589
+ return this.unwrapResponse(res);
500
590
  },
501
591
  create: async (object, data) => {
502
592
  const route = this.getRoute("data");
@@ -504,7 +594,7 @@ var ObjectStackClient = class {
504
594
  method: "POST",
505
595
  body: JSON.stringify(data)
506
596
  });
507
- return res.json();
597
+ return this.unwrapResponse(res);
508
598
  },
509
599
  createMany: async (object, data) => {
510
600
  const route = this.getRoute("data");
@@ -512,7 +602,7 @@ var ObjectStackClient = class {
512
602
  method: "POST",
513
603
  body: JSON.stringify(data)
514
604
  });
515
- return res.json();
605
+ return this.unwrapResponse(res);
516
606
  },
517
607
  update: async (object, id, data) => {
518
608
  const route = this.getRoute("data");
@@ -520,7 +610,7 @@ var ObjectStackClient = class {
520
610
  method: "PATCH",
521
611
  body: JSON.stringify(data)
522
612
  });
523
- return res.json();
613
+ return this.unwrapResponse(res);
524
614
  },
525
615
  /**
526
616
  * Batch update multiple records
@@ -532,7 +622,7 @@ var ObjectStackClient = class {
532
622
  method: "POST",
533
623
  body: JSON.stringify(request)
534
624
  });
535
- return res.json();
625
+ return this.unwrapResponse(res);
536
626
  },
537
627
  /**
538
628
  * Update multiple records (simplified batch update)
@@ -548,14 +638,14 @@ var ObjectStackClient = class {
548
638
  method: "POST",
549
639
  body: JSON.stringify(request)
550
640
  });
551
- return res.json();
641
+ return this.unwrapResponse(res);
552
642
  },
553
643
  delete: async (object, id) => {
554
644
  const route = this.getRoute("data");
555
645
  const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {
556
646
  method: "DELETE"
557
647
  });
558
- return res.json();
648
+ return this.unwrapResponse(res);
559
649
  },
560
650
  /**
561
651
  * Delete multiple records by IDs
@@ -570,7 +660,7 @@ var ObjectStackClient = class {
570
660
  method: "POST",
571
661
  body: JSON.stringify(request)
572
662
  });
573
- return res.json();
663
+ return this.unwrapResponse(res);
574
664
  }
575
665
  };
576
666
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
@@ -600,7 +690,8 @@ var ObjectStackClient = class {
600
690
  this.logger.debug("Probing .well-known discovery", { url: wellKnownUrl });
601
691
  const res = await this.fetchImpl(wellKnownUrl);
602
692
  if (res.ok) {
603
- data = await res.json();
693
+ const body = await res.json();
694
+ data = body.data || body;
604
695
  this.logger.debug("Discovered via .well-known");
605
696
  }
606
697
  } catch (e) {
@@ -613,7 +704,8 @@ var ObjectStackClient = class {
613
704
  if (!res.ok) {
614
705
  throw new Error(`Failed to connect to ${fallbackUrl}: ${res.statusText}`);
615
706
  }
616
- data = await res.json();
707
+ const body = await res.json();
708
+ data = body.data || body;
617
709
  }
618
710
  if (!data) {
619
711
  throw new Error("Connection failed: No discovery data returned");
@@ -636,6 +728,20 @@ var ObjectStackClient = class {
636
728
  isFilterAST(filter) {
637
729
  return Array.isArray(filter);
638
730
  }
731
+ /**
732
+ * Unwrap the standard REST API response envelope.
733
+ * The HTTP layer wraps responses as `{ success: boolean, data: T, meta? }`
734
+ * (see BaseResponseSchema in contract.zod.ts).
735
+ * This method strips the envelope and returns the inner `data` payload
736
+ * so callers receive the spec-level type (e.g. GetMetaTypesResponse).
737
+ */
738
+ async unwrapResponse(res) {
739
+ const body = await res.json();
740
+ if (body && typeof body.success === "boolean" && "data" in body) {
741
+ return body.data;
742
+ }
743
+ return body;
744
+ }
639
745
  async fetch(url, options = {}) {
640
746
  this.logger.debug("HTTP request", {
641
747
  method: options.method || "GET",
@@ -697,7 +803,8 @@ var ObjectStackClient = class {
697
803
  analytics: "/api/v1/analytics",
698
804
  hub: "/api/v1/hub",
699
805
  storage: "/api/v1/storage",
700
- automation: "/api/v1/automation"
806
+ automation: "/api/v1/automation",
807
+ packages: "/api/v1/packages"
701
808
  };
702
809
  return routeMap[type] || `/api/v1/${type}`;
703
810
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/query-builder.ts"],"sourcesContent":["import { QueryAST, SortNode, AggregationNode } from '@objectstack/spec/data';\nimport { \n BatchUpdateRequest, \n BatchUpdateResponse, \n UpdateManyRequest,\n DeleteManyRequest,\n BatchOptions,\n MetadataCacheRequest,\n MetadataCacheResponse,\n StandardErrorCode,\n ErrorCategory,\n GetDiscoveryResponse,\n GetMetaTypesResponse,\n GetMetaItemsResponse,\n LoginRequest,\n SessionResponse,\n GetPresignedUrlRequest,\n PresignedUrlResponse,\n CompleteUploadRequest,\n FileUploadResponse\n} from '@objectstack/spec/api';\nimport { Logger, createLogger } from '@objectstack/core';\n\nexport interface ClientConfig {\n baseUrl: string;\n token?: string;\n /**\n * Custom fetch implementation (e.g. node-fetch or for Next.js caching)\n */\n fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n /**\n * Logger instance for debugging\n */\n logger?: Logger;\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Discovery Result\n * Re-export from @objectstack/spec/api for convenience\n */\nexport type DiscoveryResult = GetDiscoveryResponse;\n\nexport interface QueryOptions {\n select?: string[]; // Simplified Selection\n filters?: Record<string, any>; // Map or AST\n sort?: string | string[] | SortNode[]; // 'name' or ['-created_at'] or AST\n top?: number;\n skip?: number;\n // Advanced features\n aggregations?: AggregationNode[];\n groupBy?: string[];\n}\n\nexport interface PaginatedResult<T = any> {\n value: T[];\n count: number;\n}\n\nexport interface StandardError {\n code: StandardErrorCode;\n message: string;\n category: ErrorCategory;\n httpStatus: number;\n retryable: boolean;\n details?: Record<string, any>;\n}\n\nexport class ObjectStackClient {\n private baseUrl: string;\n private token?: string;\n private fetchImpl: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n private discoveryInfo?: DiscoveryResult;\n private logger: Logger;\n\n constructor(config: ClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.token = config.token;\n this.fetchImpl = config.fetch || globalThis.fetch.bind(globalThis);\n \n // Initialize logger\n this.logger = config.logger || createLogger({ \n level: config.debug ? 'debug' : 'info',\n format: 'pretty'\n });\n \n this.logger.debug('ObjectStack client created', { baseUrl: this.baseUrl });\n }\n\n /**\n * Initialize the client by discovering server capabilities.\n */\n async connect() {\n this.logger.debug('Connecting to ObjectStack server', { baseUrl: this.baseUrl });\n \n try {\n let data: DiscoveryResult | undefined;\n\n // 1. Try Standard Discovery (.well-known)\n try {\n let wellKnownUrl: string;\n try {\n // If baseUrl is absolute, get origin\n const url = new URL(this.baseUrl);\n wellKnownUrl = `${url.origin}/.well-known/objectstack`;\n } catch {\n // If baseUrl is relative, use absolute path from root\n wellKnownUrl = '/.well-known/objectstack';\n }\n\n this.logger.debug('Probing .well-known discovery', { url: wellKnownUrl });\n const res = await this.fetchImpl(wellKnownUrl);\n if (res.ok) {\n data = await res.json();\n this.logger.debug('Discovered via .well-known');\n }\n } catch (e) {\n this.logger.debug('Standard discovery probe failed', { error: (e as Error).message });\n }\n\n // 2. Fallback to Legacy/Direct Path /api/v1\n if (!data) {\n const fallbackUrl = `${this.baseUrl}/api/v1`;\n this.logger.debug('Falling back to legacy discovery', { url: fallbackUrl });\n const res = await this.fetchImpl(fallbackUrl);\n if (!res.ok) {\n throw new Error(`Failed to connect to ${fallbackUrl}: ${res.statusText}`);\n }\n data = await res.json();\n }\n\n if (!data) {\n throw new Error('Connection failed: No discovery data returned');\n }\n\n this.discoveryInfo = data;\n \n this.logger.info('Connected to ObjectStack server', { \n version: data.version,\n apiName: data.apiName,\n capabilities: data.capabilities \n });\n \n return data as DiscoveryResult;\n } catch (e) {\n this.logger.error('Failed to connect to ObjectStack server', e as Error, { baseUrl: this.baseUrl });\n throw e;\n }\n }\n\n /**\n * Metadata Operations\n */\n meta = {\n /**\n * Get all available metadata types\n * Returns types like 'object', 'plugin', 'view', etc.\n */\n getTypes: async (): Promise<GetMetaTypesResponse> => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}`);\n return res.json();\n },\n\n /**\n * Get all items of a specific metadata type\n * @param type - Metadata type name (e.g., 'object', 'plugin')\n */\n getItems: async (type: string): Promise<GetMetaItemsResponse> => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/${type}`);\n return res.json();\n },\n\n /**\n * Get a specific object definition by name\n * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol\n * @param name - Object name (snake_case identifier)\n */\n getObject: async (name: string) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);\n return res.json();\n },\n\n /**\n * Get a specific metadata item by type and name\n * @param type - Metadata type (e.g., 'object', 'plugin')\n * @param name - Item name (snake_case identifier)\n */\n getItem: async (type: string, name: string) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`);\n return res.json();\n },\n\n /**\n * Save a metadata item\n * @param type - Metadata type (e.g., 'object', 'plugin')\n * @param name - Item name\n * @param item - The metadata content to save\n */\n saveItem: async (type: string, name: string, item: any) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`, {\n method: 'PUT',\n body: JSON.stringify(item)\n });\n return res.json();\n },\n \n /**\n * Get object metadata with cache support\n * Supports ETag-based conditional requests for efficient caching\n */\n getCached: async (name: string, cacheOptions?: MetadataCacheRequest): Promise<MetadataCacheResponse> => {\n const route = this.getRoute('metadata');\n const headers: Record<string, string> = {};\n \n if (cacheOptions?.ifNoneMatch) {\n headers['If-None-Match'] = cacheOptions.ifNoneMatch;\n }\n if (cacheOptions?.ifModifiedSince) {\n headers['If-Modified-Since'] = cacheOptions.ifModifiedSince;\n }\n \n const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`, {\n headers\n });\n \n // Check for 304 Not Modified\n if (res.status === 304) {\n return {\n notModified: true,\n etag: cacheOptions?.ifNoneMatch ? { \n value: cacheOptions.ifNoneMatch.replace(/^W\\/|\"/g, ''),\n weak: cacheOptions.ifNoneMatch.startsWith('W/')\n } : undefined\n };\n }\n \n const data = await res.json();\n const etag = res.headers.get('ETag');\n const lastModified = res.headers.get('Last-Modified');\n \n return {\n data,\n etag: etag ? { \n value: etag.replace(/^W\\/|\"/g, ''), \n weak: etag.startsWith('W/') \n } : undefined,\n lastModified: lastModified || undefined,\n notModified: false\n };\n },\n \n getView: async (object: string, type: 'list' | 'form' = 'list') => {\n const route = this.getRoute('ui');\n const res = await this.fetch(`${this.baseUrl}${route}/view/${object}?type=${type}`);\n return res.json();\n }\n };\n\n /**\n * Analytics Services\n */\n analytics = {\n query: async (payload: any) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/query`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n },\n meta: async (cube: string) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/meta/${cube}`);\n return res.json();\n },\n explain: async (payload: any) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/explain`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n };\n\n /**\n * Hub Management Services\n */\n hub = {\n spaces: {\n list: async () => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/spaces`);\n return res.json();\n },\n create: async (payload: any) => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/spaces`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n },\n plugins: {\n install: async (pkg: string, version?: string) => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/plugins/install`, {\n method: 'POST',\n body: JSON.stringify({ pkg, version })\n });\n return res.json();\n }\n }\n };\n\n /**\n * Authentication Services\n */\n auth = {\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/login`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n // Auto-set token if present in response\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n \n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/logout`, { method: 'POST' });\n this.token = undefined;\n },\n\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/me`);\n return res.json();\n }\n };\n\n /**\n * Storage Services\n */\n storage = {\n upload: async (file: any, scope: string = 'user'): Promise<FileUploadResponse> => {\n // 1. Get Presigned URL\n const presignedReq: GetPresignedUrlRequest = {\n filename: file.name,\n mimeType: file.type,\n size: file.size,\n scope\n };\n \n const route = this.getRoute('storage');\n const presignedRes = await this.fetch(`${this.baseUrl}${route}/upload/presigned`, {\n method: 'POST',\n body: JSON.stringify(presignedReq)\n });\n const { data: presigned } = await presignedRes.json() as { data: PresignedUrlResponse['data'] };\n\n // 2. Upload to Cloud directly (Bypass API Middleware to avoid Auth headers if using S3)\n // Use fetchImpl directly\n const uploadRes = await this.fetchImpl(presigned.uploadUrl, {\n method: presigned.method,\n headers: presigned.headers,\n body: file\n });\n\n if (!uploadRes.ok) {\n throw new Error(`Storage Upload Failed: ${uploadRes.statusText}`);\n }\n\n // 3. Complete Upload\n const completeReq: CompleteUploadRequest = {\n fileId: presigned.fileId\n };\n const completeRes = await this.fetch(`${this.baseUrl}${route}/upload/complete`, {\n method: 'POST',\n body: JSON.stringify(completeReq)\n });\n \n return completeRes.json();\n },\n \n getDownloadUrl: async (fileId: string): Promise<string> => {\n const route = this.getRoute('storage');\n const res = await this.fetch(`${this.baseUrl}${route}/files/${fileId}/url`);\n const data = await res.json();\n return data.url;\n }\n };\n\n /**\n * Automation Services\n */\n automation = {\n trigger: async (triggerName: string, payload: any) => {\n const route = this.getRoute('automation');\n const res = await this.fetch(`${this.baseUrl}${route}/trigger/${triggerName}`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n };\n\n /**\n * Data Operations\n */\n data = {\n /**\n * Advanced Query using ObjectStack Query Protocol\n * Supports both simplified options and full AST\n */\n query: async <T = any>(object: string, query: Partial<QueryAST>): Promise<PaginatedResult<T>> => {\n const route = this.getRoute('data');\n // POST for complex query to avoid URL length limits and allow clean JSON AST\n // Convention: POST /api/v1/data/:object/query\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/query`, {\n method: 'POST',\n body: JSON.stringify(query)\n });\n return res.json();\n },\n\n find: async <T = any>(object: string, options: QueryOptions = {}): Promise<PaginatedResult<T>> => {\n const route = this.getRoute('data');\n const queryParams = new URLSearchParams();\n \n // 1. Handle Pagination\n if (options.top) queryParams.set('top', options.top.toString());\n if (options.skip) queryParams.set('skip', options.skip.toString());\n\n // 2. Handle Sort\n if (options.sort) {\n // Check if it's AST \n if (Array.isArray(options.sort) && typeof options.sort[0] === 'object') {\n queryParams.set('sort', JSON.stringify(options.sort));\n } else {\n const sortVal = Array.isArray(options.sort) ? options.sort.join(',') : options.sort;\n queryParams.set('sort', sortVal as string);\n }\n }\n \n // 3. Handle Select\n if (options.select) {\n queryParams.set('select', options.select.join(','));\n }\n\n // 4. Handle Filters (Simple vs AST)\n if (options.filters) {\n // If looks like AST (not plain object map)\n // TODO: robust check. safely assuming map for simplified find, and recommending .query() for AST\n if (this.isFilterAST(options.filters)) {\n queryParams.set('filters', JSON.stringify(options.filters));\n } else {\n Object.entries(options.filters).forEach(([k, v]) => {\n if (v !== undefined && v !== null) {\n queryParams.append(k, String(v));\n }\n });\n }\n }\n \n // 5. Handle Aggregations & GroupBy (Pass through as JSON if present)\n if (options.aggregations) {\n queryParams.set('aggregations', JSON.stringify(options.aggregations));\n }\n if (options.groupBy) {\n queryParams.set('groupBy', options.groupBy.join(','));\n }\n\n const res = await this.fetch(`${this.baseUrl}${route}/${object}?${queryParams.toString()}`);\n return res.json();\n },\n\n get: async <T = any>(object: string, id: string): Promise<T> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`);\n return res.json();\n },\n\n create: async <T = any>(object: string, data: Partial<T>): Promise<T> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}`, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n return res.json();\n },\n\n createMany: async <T = any>(object: string, data: Partial<T>[]): Promise<T[]> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/createMany`, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n return res.json();\n },\n\n update: async <T = any>(object: string, id: string, data: Partial<T>): Promise<T> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {\n method: 'PATCH',\n body: JSON.stringify(data)\n });\n return res.json();\n },\n\n /**\n * Batch update multiple records\n * Uses the new BatchUpdateRequest schema with full control over options\n */\n batch: async (object: string, request: BatchUpdateRequest): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/batch`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return res.json();\n },\n\n /**\n * Update multiple records (simplified batch update)\n * Convenience method for batch updates without full BatchUpdateRequest\n */\n updateMany: async <T = any>(\n object: string, \n records: Array<{ id: string; data: Partial<T> }>,\n options?: BatchOptions\n ): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const request: UpdateManyRequest = {\n records,\n options\n };\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/updateMany`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return res.json();\n },\n\n delete: async (object: string, id: string): Promise<{ success: boolean }> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {\n method: 'DELETE'\n });\n return res.json();\n },\n\n /**\n * Delete multiple records by IDs\n */\n deleteMany: async(object: string, ids: string[], options?: BatchOptions): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const request: DeleteManyRequest = {\n ids,\n options\n };\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/deleteMany`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return res.json();\n }\n };\n\n\n\n /**\n * Private Helpers\n */\n\n private isFilterAST(filter: any): boolean {\n // Basic check: if array, it's [field, op, val] or [logic, node, node]\n // If object but not basic KV map... harder to tell without schema\n // For now, assume if it passes Array.isArray it's an AST root\n return Array.isArray(filter);\n }\n\n private async fetch(url: string, options: RequestInit = {}): Promise<Response> {\n this.logger.debug('HTTP request', { \n method: options.method || 'GET',\n url,\n hasBody: !!options.body\n });\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {}),\n };\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const res = await this.fetchImpl(url, { ...options, headers });\n \n this.logger.debug('HTTP response', { \n method: options.method || 'GET',\n url,\n status: res.status,\n ok: res.ok\n });\n \n if (!res.ok) {\n let errorBody: any;\n try {\n errorBody = await res.json();\n } catch {\n errorBody = { message: res.statusText };\n }\n \n this.logger.error('HTTP request failed', undefined, { \n method: options.method || 'GET',\n url,\n status: res.status,\n error: errorBody\n });\n \n // Create a standardized error if the response includes error details\n const errorMessage = errorBody?.message || errorBody?.error?.message || res.statusText;\n const errorCode = errorBody?.code || errorBody?.error?.code;\n const error = new Error(`[ObjectStack] ${errorCode ? `${errorCode}: ` : ''}${errorMessage}`) as any;\n \n // Attach error details for programmatic access\n error.code = errorCode;\n error.category = errorBody?.category;\n error.httpStatus = res.status;\n error.retryable = errorBody?.retryable;\n error.details = errorBody?.details || errorBody;\n \n throw error;\n }\n \n return res;\n }\n\n /**\n * Get the conventional route path for a given API endpoint type\n * ObjectStack uses standard conventions: /api/v1/data, /api/v1/meta, /api/v1/ui\n */\n private getRoute(type: 'data' | 'metadata' | 'ui' | 'auth' | 'analytics' | 'hub' | 'storage' | 'automation'): string {\n // 1. Use discovered routes if available\n // Note: Spec uses 'endpoints', mapped dynamically\n if (this.discoveryInfo?.endpoints && (this.discoveryInfo.endpoints as any)[type]) {\n return (this.discoveryInfo.endpoints as any)[type];\n }\n\n // 2. Fallback to conventions\n const routeMap: Record<string, string> = {\n data: '/api/v1/data',\n metadata: '/api/v1/meta',\n ui: '/api/v1/ui',\n auth: '/api/v1/auth',\n analytics: '/api/v1/analytics',\n hub: '/api/v1/hub',\n storage: '/api/v1/storage',\n automation: '/api/v1/automation'\n };\n \n return routeMap[type] || `/api/v1/${type}`;\n }\n}\n\n// Re-export type-safe query builder\nexport { QueryBuilder, FilterBuilder, createQuery, createFilter } from './query-builder';\n\n// Re-export commonly used types from @objectstack/spec/api for convenience\nexport type {\n BatchUpdateRequest,\n BatchUpdateResponse,\n UpdateManyRequest,\n DeleteManyRequest,\n BatchOptions,\n BatchRecord,\n BatchOperationResult,\n MetadataCacheRequest,\n MetadataCacheResponse,\n StandardErrorCode,\n ErrorCategory,\n GetDiscoveryResponse,\n GetMetaTypesResponse,\n GetMetaItemsResponse\n} from '@objectstack/spec/api';\n","/**\n * Type-Safe Query Builder\n * \n * Provides a fluent API for building ObjectStack queries with:\n * - Compile-time type checking\n * - Intelligent code completion\n * - Runtime validation\n * - Type-safe filters and selections\n */\n\nimport { QueryAST, FilterCondition, SortNode } from '@objectstack/spec/data';\n\n/**\n * Type-safe filter builder\n */\nexport class FilterBuilder<T = any> {\n private conditions: FilterCondition[] = [];\n\n /**\n * Equality filter: field = value\n */\n equals<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '=', value]);\n return this;\n }\n\n /**\n * Not equals filter: field != value\n */\n notEquals<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '!=', value]);\n return this;\n }\n\n /**\n * Greater than filter: field > value\n */\n greaterThan<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '>', value]);\n return this;\n }\n\n /**\n * Greater than or equal filter: field >= value\n */\n greaterThanOrEqual<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '>=', value]);\n return this;\n }\n\n /**\n * Less than filter: field < value\n */\n lessThan<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '<', value]);\n return this;\n }\n\n /**\n * Less than or equal filter: field <= value\n */\n lessThanOrEqual<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '<=', value]);\n return this;\n }\n\n /**\n * IN filter: field IN (value1, value2, ...)\n */\n in<K extends keyof T>(field: K, values: T[K][]): this {\n this.conditions.push([field as string, 'in', values]);\n return this;\n }\n\n /**\n * NOT IN filter: field NOT IN (value1, value2, ...)\n */\n notIn<K extends keyof T>(field: K, values: T[K][]): this {\n this.conditions.push([field as string, 'not_in', values]);\n return this;\n }\n\n /**\n * LIKE filter: field LIKE pattern\n */\n like<K extends keyof T>(field: K, pattern: string): this {\n this.conditions.push([field as string, 'like', pattern]);\n return this;\n }\n\n /**\n * IS NULL filter: field IS NULL\n */\n isNull<K extends keyof T>(field: K): this {\n this.conditions.push([field as string, 'is_null', null]);\n return this;\n }\n\n /**\n * IS NOT NULL filter: field IS NOT NULL\n */\n isNotNull<K extends keyof T>(field: K): this {\n this.conditions.push([field as string, 'is_not_null', null]);\n return this;\n }\n\n /**\n * Build the filter condition\n */\n build(): FilterCondition {\n if (this.conditions.length === 0) {\n throw new Error('Filter builder has no conditions');\n }\n if (this.conditions.length === 1) {\n return this.conditions[0];\n }\n // Combine multiple conditions with AND\n return ['and', ...this.conditions];\n }\n\n /**\n * Get raw conditions array\n */\n getConditions(): FilterCondition[] {\n return this.conditions;\n }\n}\n\n/**\n * Type-safe query builder\n */\nexport class QueryBuilder<T = any> {\n private query: Partial<QueryAST> = {};\n private _object: string;\n\n constructor(object: string) {\n this._object = object;\n this.query.object = object;\n }\n\n /**\n * Select specific fields\n */\n select<K extends keyof T>(...fields: K[]): this {\n this.query.fields = fields as string[];\n return this;\n }\n\n /**\n * Add filters using a builder function\n */\n where(builderFn: (builder: FilterBuilder<T>) => void): this {\n const builder = new FilterBuilder<T>();\n builderFn(builder);\n const conditions = builder.getConditions();\n \n if (conditions.length === 1) {\n this.query.where = conditions[0];\n } else if (conditions.length > 1) {\n this.query.where = ['and', ...conditions] as FilterCondition;\n }\n \n return this;\n }\n\n /**\n * Add raw filter condition\n */\n filter(condition: FilterCondition): this {\n this.query.where = condition;\n return this;\n }\n\n /**\n * Sort by fields\n */\n orderBy<K extends keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n if (!this.query.orderBy) {\n this.query.orderBy = [];\n }\n (this.query.orderBy as SortNode[]).push({\n field: field as string,\n order\n });\n return this;\n }\n\n /**\n * Limit the number of results\n */\n limit(count: number): this {\n this.query.limit = count;\n return this;\n }\n\n /**\n * Skip records (for pagination)\n */\n skip(count: number): this {\n this.query.offset = count;\n return this;\n }\n\n /**\n * Paginate results\n */\n paginate(page: number, pageSize: number): this {\n this.query.limit = pageSize;\n this.query.offset = (page - 1) * pageSize;\n return this;\n }\n\n /**\n * Group by fields\n */\n groupBy<K extends keyof T>(...fields: K[]): this {\n this.query.groupBy = fields as string[];\n return this;\n }\n\n /**\n * Build the final query AST\n */\n build(): QueryAST {\n return {\n object: this._object,\n ...this.query\n } as QueryAST;\n }\n\n /**\n * Get the current query state\n */\n getQuery(): Partial<QueryAST> {\n return { ...this.query };\n }\n}\n\n/**\n * Create a type-safe query builder for an object\n */\nexport function createQuery<T = any>(object: string): QueryBuilder<T> {\n return new QueryBuilder<T>(object);\n}\n\n/**\n * Create a type-safe filter builder\n */\nexport function createFilter<T = any>(): FilterBuilder<T> {\n return new FilterBuilder<T>();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/query-builder.ts"],"sourcesContent":["import { QueryAST, SortNode, AggregationNode } from '@objectstack/spec/data';\nimport { \n BatchUpdateRequest, \n BatchUpdateResponse, \n UpdateManyRequest,\n DeleteManyRequest,\n BatchOptions,\n MetadataCacheRequest,\n MetadataCacheResponse,\n StandardErrorCode,\n ErrorCategory,\n GetDiscoveryResponse,\n GetMetaTypesResponse,\n GetMetaItemsResponse,\n LoginRequest,\n SessionResponse,\n GetPresignedUrlRequest,\n PresignedUrlResponse,\n CompleteUploadRequest,\n FileUploadResponse\n} from '@objectstack/spec/api';\nimport { Logger, createLogger } from '@objectstack/core';\n\nexport interface ClientConfig {\n baseUrl: string;\n token?: string;\n /**\n * Custom fetch implementation (e.g. node-fetch or for Next.js caching)\n */\n fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n /**\n * Logger instance for debugging\n */\n logger?: Logger;\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Discovery Result\n * Re-export from @objectstack/spec/api for convenience\n */\nexport type DiscoveryResult = GetDiscoveryResponse;\n\nexport interface QueryOptions {\n select?: string[]; // Simplified Selection\n filters?: Record<string, any>; // Map or AST\n sort?: string | string[] | SortNode[]; // 'name' or ['-created_at'] or AST\n top?: number;\n skip?: number;\n // Advanced features\n aggregations?: AggregationNode[];\n groupBy?: string[];\n}\n\nexport interface PaginatedResult<T = any> {\n /** @deprecated Use `records` — aligned with FindDataResponseSchema */\n value?: T[];\n /** Spec-compliant: array of matching records */\n records: T[];\n /** @deprecated Use `total` — aligned with FindDataResponseSchema */\n count?: number;\n /** Total number of matching records (if requested) */\n total?: number;\n /** The object name */\n object?: string;\n /** Whether more records are available */\n hasMore?: boolean;\n}\n\n/** Spec: GetDataResponseSchema */\nexport interface GetDataResult<T = any> {\n object: string;\n id: string;\n record: T;\n}\n\n/** Spec: CreateDataResponseSchema */\nexport interface CreateDataResult<T = any> {\n object: string;\n id: string;\n record: T;\n}\n\n/** Spec: UpdateDataResponseSchema */\nexport interface UpdateDataResult<T = any> {\n object: string;\n id: string;\n record: T;\n}\n\n/** Spec: DeleteDataResponseSchema */\nexport interface DeleteDataResult {\n object: string;\n id: string;\n deleted: boolean;\n}\n\nexport interface StandardError {\n code: StandardErrorCode;\n message: string;\n category: ErrorCategory;\n httpStatus: number;\n retryable: boolean;\n details?: Record<string, any>;\n}\n\nexport class ObjectStackClient {\n private baseUrl: string;\n private token?: string;\n private fetchImpl: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n private discoveryInfo?: DiscoveryResult;\n private logger: Logger;\n\n constructor(config: ClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.token = config.token;\n this.fetchImpl = config.fetch || globalThis.fetch.bind(globalThis);\n \n // Initialize logger\n this.logger = config.logger || createLogger({ \n level: config.debug ? 'debug' : 'info',\n format: 'pretty'\n });\n \n this.logger.debug('ObjectStack client created', { baseUrl: this.baseUrl });\n }\n\n /**\n * Initialize the client by discovering server capabilities.\n */\n async connect() {\n this.logger.debug('Connecting to ObjectStack server', { baseUrl: this.baseUrl });\n \n try {\n let data: DiscoveryResult | undefined;\n\n // 1. Try Standard Discovery (.well-known)\n try {\n let wellKnownUrl: string;\n try {\n // If baseUrl is absolute, get origin\n const url = new URL(this.baseUrl);\n wellKnownUrl = `${url.origin}/.well-known/objectstack`;\n } catch {\n // If baseUrl is relative, use absolute path from root\n wellKnownUrl = '/.well-known/objectstack';\n }\n\n this.logger.debug('Probing .well-known discovery', { url: wellKnownUrl });\n const res = await this.fetchImpl(wellKnownUrl);\n if (res.ok) {\n const body = await res.json();\n data = body.data || body;\n this.logger.debug('Discovered via .well-known');\n }\n } catch (e) {\n this.logger.debug('Standard discovery probe failed', { error: (e as Error).message });\n }\n\n // 2. Fallback to Legacy/Direct Path /api/v1\n if (!data) {\n const fallbackUrl = `${this.baseUrl}/api/v1`;\n this.logger.debug('Falling back to legacy discovery', { url: fallbackUrl });\n const res = await this.fetchImpl(fallbackUrl);\n if (!res.ok) {\n throw new Error(`Failed to connect to ${fallbackUrl}: ${res.statusText}`);\n }\n const body = await res.json();\n data = body.data || body;\n }\n\n if (!data) {\n throw new Error('Connection failed: No discovery data returned');\n }\n\n this.discoveryInfo = data;\n \n this.logger.info('Connected to ObjectStack server', { \n version: data.version,\n apiName: data.apiName,\n capabilities: data.capabilities \n });\n \n return data as DiscoveryResult;\n } catch (e) {\n this.logger.error('Failed to connect to ObjectStack server', e as Error, { baseUrl: this.baseUrl });\n throw e;\n }\n }\n\n /**\n * Metadata Operations\n */\n meta = {\n /**\n * Get all available metadata types\n * Returns types like 'object', 'plugin', 'view', etc.\n */\n getTypes: async (): Promise<GetMetaTypesResponse> => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}`);\n return this.unwrapResponse<GetMetaTypesResponse>(res);\n },\n\n /**\n * Get all items of a specific metadata type\n * @param type - Metadata type name (e.g., 'object', 'plugin')\n * @param options - Optional filters (e.g., packageId to scope by package)\n */\n getItems: async (type: string, options?: { packageId?: string }): Promise<GetMetaItemsResponse> => {\n const route = this.getRoute('metadata');\n const params = new URLSearchParams();\n if (options?.packageId) params.set('package', options.packageId);\n const qs = params.toString();\n const url = `${this.baseUrl}${route}/${type}${qs ? `?${qs}` : ''}`;\n const res = await this.fetch(url);\n return this.unwrapResponse<GetMetaItemsResponse>(res);\n },\n\n /**\n * Get a specific object definition by name\n * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol\n * @param name - Object name (snake_case identifier)\n */\n getObject: async (name: string) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);\n return this.unwrapResponse(res);\n },\n\n /**\n * Get a specific metadata item by type and name\n * @param type - Metadata type (e.g., 'object', 'plugin')\n * @param name - Item name (snake_case identifier)\n */\n getItem: async (type: string, name: string) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`);\n return this.unwrapResponse(res);\n },\n\n /**\n * Save a metadata item\n * @param type - Metadata type (e.g., 'object', 'plugin')\n * @param name - Item name\n * @param item - The metadata content to save\n */\n saveItem: async (type: string, name: string, item: any) => {\n const route = this.getRoute('metadata');\n const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`, {\n method: 'PUT',\n body: JSON.stringify(item)\n });\n return this.unwrapResponse(res);\n },\n \n /**\n * Get object metadata with cache support\n * Supports ETag-based conditional requests for efficient caching\n */\n getCached: async (name: string, cacheOptions?: MetadataCacheRequest): Promise<MetadataCacheResponse> => {\n const route = this.getRoute('metadata');\n const headers: Record<string, string> = {};\n \n if (cacheOptions?.ifNoneMatch) {\n headers['If-None-Match'] = cacheOptions.ifNoneMatch;\n }\n if (cacheOptions?.ifModifiedSince) {\n headers['If-Modified-Since'] = cacheOptions.ifModifiedSince;\n }\n \n const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`, {\n headers\n });\n \n // Check for 304 Not Modified\n if (res.status === 304) {\n return {\n notModified: true,\n etag: cacheOptions?.ifNoneMatch ? { \n value: cacheOptions.ifNoneMatch.replace(/^W\\/|\"/g, ''),\n weak: cacheOptions.ifNoneMatch.startsWith('W/')\n } : undefined\n };\n }\n \n const data = await res.json();\n const etag = res.headers.get('ETag');\n const lastModified = res.headers.get('Last-Modified');\n \n return {\n data,\n etag: etag ? { \n value: etag.replace(/^W\\/|\"/g, ''), \n weak: etag.startsWith('W/') \n } : undefined,\n lastModified: lastModified || undefined,\n notModified: false\n };\n },\n \n getView: async (object: string, type: 'list' | 'form' = 'list') => {\n const route = this.getRoute('ui');\n const res = await this.fetch(`${this.baseUrl}${route}/view/${object}?type=${type}`);\n return this.unwrapResponse(res);\n }\n };\n\n /**\n * Analytics Services\n */\n analytics = {\n query: async (payload: any) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/query`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n },\n meta: async (cube: string) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/meta/${cube}`);\n return res.json();\n },\n explain: async (payload: any) => {\n const route = this.getRoute('analytics');\n const res = await this.fetch(`${this.baseUrl}${route}/explain`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n };\n\n /**\n * Hub Management Services\n */\n hub = {\n spaces: {\n list: async () => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/spaces`);\n return res.json();\n },\n create: async (payload: any) => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/spaces`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n },\n plugins: {\n install: async (pkg: string, version?: string) => {\n const route = this.getRoute('hub');\n const res = await this.fetch(`${this.baseUrl}${route}/plugins/install`, {\n method: 'POST',\n body: JSON.stringify({ pkg, version })\n });\n return res.json();\n }\n }\n };\n\n /**\n * Package Management Services\n * \n * Manages the lifecycle of installed packages.\n * A package (ManifestSchema) is the unit of installation.\n * An app (AppSchema) is a UI navigation definition within a package.\n * A package may contain 0, 1, or many apps, or be a pure functionality plugin.\n * \n * Endpoints:\n * - GET /packages → list installed packages\n * - GET /packages/:id → get package details \n * - POST /packages → install a package\n * - DELETE /packages/:id → uninstall a package\n * - PATCH /packages/:id/enable → enable a package\n * - PATCH /packages/:id/disable → disable a package\n */\n packages = {\n /**\n * List all installed packages with optional filters.\n */\n list: async (filters?: { status?: string; type?: string; enabled?: boolean }) => {\n const route = this.getRoute('packages');\n const params = new URLSearchParams();\n if (filters?.status) params.set('status', filters.status);\n if (filters?.type) params.set('type', filters.type);\n if (filters?.enabled !== undefined) params.set('enabled', String(filters.enabled));\n const qs = params.toString();\n const url = `${this.baseUrl}${route}${qs ? '?' + qs : ''}`;\n const res = await this.fetch(url);\n return this.unwrapResponse<{ packages: any[]; total: number }>(res);\n },\n\n /**\n * Get a specific installed package by its ID (reverse domain identifier).\n */\n get: async (id: string) => {\n const route = this.getRoute('packages');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}`);\n return this.unwrapResponse<{ package: any }>(res);\n },\n\n /**\n * Install a new package from its manifest.\n */\n install: async (manifest: any, options?: { settings?: Record<string, any>; enableOnInstall?: boolean }) => {\n const route = this.getRoute('packages');\n const res = await this.fetch(`${this.baseUrl}${route}`, {\n method: 'POST',\n body: JSON.stringify({\n manifest,\n settings: options?.settings,\n enableOnInstall: options?.enableOnInstall,\n }),\n });\n return this.unwrapResponse<{ package: any; message?: string }>(res);\n },\n\n /**\n * Uninstall a package by its ID.\n */\n uninstall: async (id: string) => {\n const route = this.getRoute('packages');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n return this.unwrapResponse<{ id: string; success: boolean; message?: string }>(res);\n },\n\n /**\n * Enable a disabled package.\n */\n enable: async (id: string) => {\n const route = this.getRoute('packages');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}/enable`, {\n method: 'PATCH',\n });\n return this.unwrapResponse<{ package: any; message?: string }>(res);\n },\n\n /**\n * Disable an installed package.\n */\n disable: async (id: string) => {\n const route = this.getRoute('packages');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(id)}/disable`, {\n method: 'PATCH',\n });\n return this.unwrapResponse<{ package: any; message?: string }>(res);\n },\n };\n\n /**\n * Authentication Services\n */\n auth = {\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/login`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n // Auto-set token if present in response\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n \n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/logout`, { method: 'POST' });\n this.token = undefined;\n },\n\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/me`);\n return res.json();\n }\n };\n\n /**\n * Storage Services\n */\n storage = {\n upload: async (file: any, scope: string = 'user'): Promise<FileUploadResponse> => {\n // 1. Get Presigned URL\n const presignedReq: GetPresignedUrlRequest = {\n filename: file.name,\n mimeType: file.type,\n size: file.size,\n scope\n };\n \n const route = this.getRoute('storage');\n const presignedRes = await this.fetch(`${this.baseUrl}${route}/upload/presigned`, {\n method: 'POST',\n body: JSON.stringify(presignedReq)\n });\n const { data: presigned } = await presignedRes.json() as { data: PresignedUrlResponse['data'] };\n\n // 2. Upload to Cloud directly (Bypass API Middleware to avoid Auth headers if using S3)\n // Use fetchImpl directly\n const uploadRes = await this.fetchImpl(presigned.uploadUrl, {\n method: presigned.method,\n headers: presigned.headers,\n body: file\n });\n\n if (!uploadRes.ok) {\n throw new Error(`Storage Upload Failed: ${uploadRes.statusText}`);\n }\n\n // 3. Complete Upload\n const completeReq: CompleteUploadRequest = {\n fileId: presigned.fileId\n };\n const completeRes = await this.fetch(`${this.baseUrl}${route}/upload/complete`, {\n method: 'POST',\n body: JSON.stringify(completeReq)\n });\n \n return completeRes.json();\n },\n \n getDownloadUrl: async (fileId: string): Promise<string> => {\n const route = this.getRoute('storage');\n const res = await this.fetch(`${this.baseUrl}${route}/files/${fileId}/url`);\n const data = await res.json();\n return data.url;\n }\n };\n\n /**\n * Automation Services\n */\n automation = {\n trigger: async (triggerName: string, payload: any) => {\n const route = this.getRoute('automation');\n const res = await this.fetch(`${this.baseUrl}${route}/trigger/${triggerName}`, {\n method: 'POST',\n body: JSON.stringify(payload)\n });\n return res.json();\n }\n };\n\n /**\n * Data Operations\n */\n data = {\n /**\n * Advanced Query using ObjectStack Query Protocol\n * Supports both simplified options and full AST\n */\n query: async <T = any>(object: string, query: Partial<QueryAST>): Promise<PaginatedResult<T>> => {\n const route = this.getRoute('data');\n // POST for complex query to avoid URL length limits and allow clean JSON AST\n // Convention: POST /api/v1/data/:object/query\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/query`, {\n method: 'POST',\n body: JSON.stringify(query)\n });\n return this.unwrapResponse<PaginatedResult<T>>(res);\n },\n\n find: async <T = any>(object: string, options: QueryOptions = {}): Promise<PaginatedResult<T>> => {\n const route = this.getRoute('data');\n const queryParams = new URLSearchParams();\n \n // 1. Handle Pagination\n if (options.top) queryParams.set('top', options.top.toString());\n if (options.skip) queryParams.set('skip', options.skip.toString());\n\n // 2. Handle Sort\n if (options.sort) {\n // Check if it's AST \n if (Array.isArray(options.sort) && typeof options.sort[0] === 'object') {\n queryParams.set('sort', JSON.stringify(options.sort));\n } else {\n const sortVal = Array.isArray(options.sort) ? options.sort.join(',') : options.sort;\n queryParams.set('sort', sortVal as string);\n }\n }\n \n // 3. Handle Select\n if (options.select) {\n queryParams.set('select', options.select.join(','));\n }\n\n // 4. Handle Filters (Simple vs AST)\n if (options.filters) {\n // If looks like AST (not plain object map)\n // TODO: robust check. safely assuming map for simplified find, and recommending .query() for AST\n if (this.isFilterAST(options.filters)) {\n queryParams.set('filters', JSON.stringify(options.filters));\n } else {\n Object.entries(options.filters).forEach(([k, v]) => {\n if (v !== undefined && v !== null) {\n queryParams.append(k, String(v));\n }\n });\n }\n }\n \n // 5. Handle Aggregations & GroupBy (Pass through as JSON if present)\n if (options.aggregations) {\n queryParams.set('aggregations', JSON.stringify(options.aggregations));\n }\n if (options.groupBy) {\n queryParams.set('groupBy', options.groupBy.join(','));\n }\n\n const res = await this.fetch(`${this.baseUrl}${route}/${object}?${queryParams.toString()}`);\n return this.unwrapResponse<PaginatedResult<T>>(res);\n },\n\n get: async <T = any>(object: string, id: string): Promise<GetDataResult<T>> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`);\n return this.unwrapResponse<GetDataResult<T>>(res);\n },\n\n create: async <T = any>(object: string, data: Partial<T>): Promise<CreateDataResult<T>> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}`, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n return this.unwrapResponse<CreateDataResult<T>>(res);\n },\n\n createMany: async <T = any>(object: string, data: Partial<T>[]): Promise<T[]> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/createMany`, {\n method: 'POST',\n body: JSON.stringify(data)\n });\n return this.unwrapResponse<T[]>(res);\n },\n\n update: async <T = any>(object: string, id: string, data: Partial<T>): Promise<UpdateDataResult<T>> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {\n method: 'PATCH',\n body: JSON.stringify(data)\n });\n return this.unwrapResponse<UpdateDataResult<T>>(res);\n },\n\n /**\n * Batch update multiple records\n * Uses the new BatchUpdateRequest schema with full control over options\n */\n batch: async (object: string, request: BatchUpdateRequest): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/batch`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<BatchUpdateResponse>(res);\n },\n\n /**\n * Update multiple records (simplified batch update)\n * Convenience method for batch updates without full BatchUpdateRequest\n */\n updateMany: async <T = any>(\n object: string, \n records: Array<{ id: string; data: Partial<T> }>,\n options?: BatchOptions\n ): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const request: UpdateManyRequest = {\n records,\n options\n };\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/updateMany`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<BatchUpdateResponse>(res);\n },\n\n delete: async (object: string, id: string): Promise<DeleteDataResult> => {\n const route = this.getRoute('data');\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<DeleteDataResult>(res);\n },\n\n /**\n * Delete multiple records by IDs\n */\n deleteMany: async(object: string, ids: string[], options?: BatchOptions): Promise<BatchUpdateResponse> => {\n const route = this.getRoute('data');\n const request: DeleteManyRequest = {\n ids,\n options\n };\n const res = await this.fetch(`${this.baseUrl}${route}/${object}/deleteMany`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<BatchUpdateResponse>(res);\n }\n };\n\n\n\n /**\n * Private Helpers\n */\n\n private isFilterAST(filter: any): boolean {\n // Basic check: if array, it's [field, op, val] or [logic, node, node]\n // If object but not basic KV map... harder to tell without schema\n // For now, assume if it passes Array.isArray it's an AST root\n return Array.isArray(filter);\n }\n\n /**\n * Unwrap the standard REST API response envelope.\n * The HTTP layer wraps responses as `{ success: boolean, data: T, meta? }`\n * (see BaseResponseSchema in contract.zod.ts).\n * This method strips the envelope and returns the inner `data` payload\n * so callers receive the spec-level type (e.g. GetMetaTypesResponse).\n */\n private async unwrapResponse<T>(res: Response): Promise<T> {\n const body = await res.json();\n // If the body has a `success` flag it's a BaseResponse envelope\n if (body && typeof body.success === 'boolean' && 'data' in body) {\n return body.data as T;\n }\n // Already unwrapped or non-standard\n return body as T;\n }\n\n private async fetch(url: string, options: RequestInit = {}): Promise<Response> {\n this.logger.debug('HTTP request', { \n method: options.method || 'GET',\n url,\n hasBody: !!options.body\n });\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {}),\n };\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n const res = await this.fetchImpl(url, { ...options, headers });\n \n this.logger.debug('HTTP response', { \n method: options.method || 'GET',\n url,\n status: res.status,\n ok: res.ok\n });\n \n if (!res.ok) {\n let errorBody: any;\n try {\n errorBody = await res.json();\n } catch {\n errorBody = { message: res.statusText };\n }\n \n this.logger.error('HTTP request failed', undefined, { \n method: options.method || 'GET',\n url,\n status: res.status,\n error: errorBody\n });\n \n // Create a standardized error if the response includes error details\n const errorMessage = errorBody?.message || errorBody?.error?.message || res.statusText;\n const errorCode = errorBody?.code || errorBody?.error?.code;\n const error = new Error(`[ObjectStack] ${errorCode ? `${errorCode}: ` : ''}${errorMessage}`) as any;\n \n // Attach error details for programmatic access\n error.code = errorCode;\n error.category = errorBody?.category;\n error.httpStatus = res.status;\n error.retryable = errorBody?.retryable;\n error.details = errorBody?.details || errorBody;\n \n throw error;\n }\n \n return res;\n }\n\n /**\n * Get the conventional route path for a given API endpoint type\n * ObjectStack uses standard conventions: /api/v1/data, /api/v1/meta, /api/v1/ui\n */\n private getRoute(type: 'data' | 'metadata' | 'ui' | 'auth' | 'analytics' | 'hub' | 'storage' | 'automation' | 'packages'): string {\n // 1. Use discovered routes if available\n // Note: Spec uses 'endpoints', mapped dynamically\n if (this.discoveryInfo?.endpoints && (this.discoveryInfo.endpoints as any)[type]) {\n return (this.discoveryInfo.endpoints as any)[type];\n }\n\n // 2. Fallback to conventions\n const routeMap: Record<string, string> = {\n data: '/api/v1/data',\n metadata: '/api/v1/meta',\n ui: '/api/v1/ui',\n auth: '/api/v1/auth',\n analytics: '/api/v1/analytics',\n hub: '/api/v1/hub',\n storage: '/api/v1/storage',\n automation: '/api/v1/automation',\n packages: '/api/v1/packages',\n };\n \n return routeMap[type] || `/api/v1/${type}`;\n }\n}\n\n// Re-export type-safe query builder\nexport { QueryBuilder, FilterBuilder, createQuery, createFilter } from './query-builder';\n\n// Re-export commonly used types from @objectstack/spec/api for convenience\nexport type {\n BatchUpdateRequest,\n BatchUpdateResponse,\n UpdateManyRequest,\n DeleteManyRequest,\n BatchOptions,\n BatchRecord,\n BatchOperationResult,\n MetadataCacheRequest,\n MetadataCacheResponse,\n StandardErrorCode,\n ErrorCategory,\n GetDiscoveryResponse,\n GetMetaTypesResponse,\n GetMetaItemsResponse\n} from '@objectstack/spec/api';\n","/**\n * Type-Safe Query Builder\n * \n * Provides a fluent API for building ObjectStack queries with:\n * - Compile-time type checking\n * - Intelligent code completion\n * - Runtime validation\n * - Type-safe filters and selections\n */\n\nimport { QueryAST, FilterCondition, SortNode } from '@objectstack/spec/data';\n\n/**\n * Type-safe filter builder\n */\nexport class FilterBuilder<T = any> {\n private conditions: FilterCondition[] = [];\n\n /**\n * Equality filter: field = value\n */\n equals<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '=', value]);\n return this;\n }\n\n /**\n * Not equals filter: field != value\n */\n notEquals<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '!=', value]);\n return this;\n }\n\n /**\n * Greater than filter: field > value\n */\n greaterThan<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '>', value]);\n return this;\n }\n\n /**\n * Greater than or equal filter: field >= value\n */\n greaterThanOrEqual<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '>=', value]);\n return this;\n }\n\n /**\n * Less than filter: field < value\n */\n lessThan<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '<', value]);\n return this;\n }\n\n /**\n * Less than or equal filter: field <= value\n */\n lessThanOrEqual<K extends keyof T>(field: K, value: T[K]): this {\n this.conditions.push([field as string, '<=', value]);\n return this;\n }\n\n /**\n * IN filter: field IN (value1, value2, ...)\n */\n in<K extends keyof T>(field: K, values: T[K][]): this {\n this.conditions.push([field as string, 'in', values]);\n return this;\n }\n\n /**\n * NOT IN filter: field NOT IN (value1, value2, ...)\n */\n notIn<K extends keyof T>(field: K, values: T[K][]): this {\n this.conditions.push([field as string, 'not_in', values]);\n return this;\n }\n\n /**\n * LIKE filter: field LIKE pattern\n */\n like<K extends keyof T>(field: K, pattern: string): this {\n this.conditions.push([field as string, 'like', pattern]);\n return this;\n }\n\n /**\n * IS NULL filter: field IS NULL\n */\n isNull<K extends keyof T>(field: K): this {\n this.conditions.push([field as string, 'is_null', null]);\n return this;\n }\n\n /**\n * IS NOT NULL filter: field IS NOT NULL\n */\n isNotNull<K extends keyof T>(field: K): this {\n this.conditions.push([field as string, 'is_not_null', null]);\n return this;\n }\n\n /**\n * Build the filter condition\n */\n build(): FilterCondition {\n if (this.conditions.length === 0) {\n throw new Error('Filter builder has no conditions');\n }\n if (this.conditions.length === 1) {\n return this.conditions[0];\n }\n // Combine multiple conditions with AND\n return ['and', ...this.conditions];\n }\n\n /**\n * Get raw conditions array\n */\n getConditions(): FilterCondition[] {\n return this.conditions;\n }\n}\n\n/**\n * Type-safe query builder\n */\nexport class QueryBuilder<T = any> {\n private query: Partial<QueryAST> = {};\n private _object: string;\n\n constructor(object: string) {\n this._object = object;\n this.query.object = object;\n }\n\n /**\n * Select specific fields\n */\n select<K extends keyof T>(...fields: K[]): this {\n this.query.fields = fields as string[];\n return this;\n }\n\n /**\n * Add filters using a builder function\n */\n where(builderFn: (builder: FilterBuilder<T>) => void): this {\n const builder = new FilterBuilder<T>();\n builderFn(builder);\n const conditions = builder.getConditions();\n \n if (conditions.length === 1) {\n this.query.where = conditions[0];\n } else if (conditions.length > 1) {\n this.query.where = ['and', ...conditions] as FilterCondition;\n }\n \n return this;\n }\n\n /**\n * Add raw filter condition\n */\n filter(condition: FilterCondition): this {\n this.query.where = condition;\n return this;\n }\n\n /**\n * Sort by fields\n */\n orderBy<K extends keyof T>(field: K, order: 'asc' | 'desc' = 'asc'): this {\n if (!this.query.orderBy) {\n this.query.orderBy = [];\n }\n (this.query.orderBy as SortNode[]).push({\n field: field as string,\n order\n });\n return this;\n }\n\n /**\n * Limit the number of results\n */\n limit(count: number): this {\n this.query.limit = count;\n return this;\n }\n\n /**\n * Skip records (for pagination)\n */\n skip(count: number): this {\n this.query.offset = count;\n return this;\n }\n\n /**\n * Paginate results\n */\n paginate(page: number, pageSize: number): this {\n this.query.limit = pageSize;\n this.query.offset = (page - 1) * pageSize;\n return this;\n }\n\n /**\n * Group by fields\n */\n groupBy<K extends keyof T>(...fields: K[]): this {\n this.query.groupBy = fields as string[];\n return this;\n }\n\n /**\n * Build the final query AST\n */\n build(): QueryAST {\n return {\n object: this._object,\n ...this.query\n } as QueryAST;\n }\n\n /**\n * Get the current query state\n */\n getQuery(): Partial<QueryAST> {\n return { ...this.query };\n }\n}\n\n/**\n * Create a type-safe query builder for an object\n */\nexport function createQuery<T = any>(object: string): QueryBuilder<T> {\n return new QueryBuilder<T>(object);\n}\n\n/**\n * Create a type-safe filter builder\n */\nexport function createFilter<T = any>(): FilterBuilder<T> {\n return new FilterBuilder<T>();\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,25 +1,32 @@
1
1
  {
2
2
  "name": "@objectstack/client",
3
- "version": "1.0.11",
3
+ "version": "1.1.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Official Client SDK for ObjectStack Protocol",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
8
15
  "dependencies": {
9
- "@objectstack/core": "1.0.11",
10
- "@objectstack/spec": "1.0.11"
16
+ "@objectstack/core": "1.1.0",
17
+ "@objectstack/spec": "1.1.0"
11
18
  },
12
19
  "devDependencies": {
13
20
  "@hono/node-server": "^1.2.0",
14
21
  "msw": "^2.0.0",
15
22
  "typescript": "^5.0.0",
16
23
  "vitest": "^4.0.18",
17
- "@objectstack/driver-memory": "1.0.11",
18
- "@objectstack/hono": "1.0.11",
19
- "@objectstack/objectql": "1.0.11",
20
- "@objectstack/plugin-hono-server": "1.0.11",
21
- "@objectstack/plugin-msw": "1.0.11",
22
- "@objectstack/runtime": "1.0.11"
24
+ "@objectstack/driver-memory": "1.1.0",
25
+ "@objectstack/hono": "1.1.0",
26
+ "@objectstack/objectql": "1.1.0",
27
+ "@objectstack/plugin-hono-server": "1.1.0",
28
+ "@objectstack/plugin-msw": "1.1.0",
29
+ "@objectstack/runtime": "1.1.0"
23
30
  },
24
31
  "scripts": {
25
32
  "build": "tsup --config ../../tsup.config.ts",