@objectstack/client 2.0.6 → 3.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @objectstack/client@2.0.6 build /home/runner/work/spec/spec/packages/client
2
+ > @objectstack/client@3.0.0 build /home/runner/work/spec/spec/packages/client
3
3
  > tsup --config ../../tsup.config.ts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- CJS dist/index.js 40.50 KB
14
- CJS dist/index.js.map 79.61 KB
15
- CJS ⚡️ Build success in 33ms
16
- ESM dist/index.mjs 39.35 KB
17
- ESM dist/index.mjs.map 79.55 KB
18
- ESM ⚡️ Build success in 35ms
13
+ CJS dist/index.js 40.06 KB
14
+ CJS dist/index.js.map 78.74 KB
15
+ CJS ⚡️ Build success in 28ms
16
+ ESM dist/index.mjs 38.90 KB
17
+ ESM dist/index.mjs.map 78.68 KB
18
+ ESM ⚡️ Build success in 38ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 2888ms
21
- DTS dist/index.d.mts 23.61 KB
22
- DTS dist/index.d.ts 23.61 KB
20
+ DTS ⚡️ Build success in 3297ms
21
+ DTS dist/index.d.mts 22.83 KB
22
+ DTS dist/index.d.ts 22.83 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @objectstack/client
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Release v3.0.0 — unified version bump for all ObjectStack packages.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @objectstack/spec@3.0.0
13
+ - @objectstack/core@3.0.0
14
+
15
+ ## 2.0.7
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+ - @objectstack/spec@2.0.7
21
+ - @objectstack/core@2.0.7
22
+
3
23
  ## 2.0.6
4
24
 
5
25
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -198,12 +198,8 @@ interface QueryOptions {
198
198
  groupBy?: string[];
199
199
  }
200
200
  interface PaginatedResult<T = any> {
201
- /** @deprecated Use `records` — aligned with FindDataResponseSchema */
202
- value?: T[];
203
201
  /** Spec-compliant: array of matching records */
204
202
  records: T[];
205
- /** @deprecated Use `total` — aligned with FindDataResponseSchema */
206
- count?: number;
207
203
  /** Total number of matching records (if requested) */
208
204
  total?: number;
209
205
  /** The object name */
@@ -256,18 +252,7 @@ declare class ObjectStackClient {
256
252
  connect(): Promise<{
257
253
  version: string;
258
254
  apiName: string;
259
- capabilities?: {
260
- graphql: boolean;
261
- search: boolean;
262
- websockets: boolean;
263
- files: boolean;
264
- analytics: boolean;
265
- ai: boolean;
266
- workflow: boolean;
267
- notifications: boolean;
268
- i18n: boolean;
269
- } | undefined;
270
- endpoints?: {
255
+ routes?: {
271
256
  data: string;
272
257
  metadata: string;
273
258
  ui?: string | undefined;
@@ -285,7 +270,7 @@ declare class ObjectStackClient {
285
270
  } | undefined;
286
271
  services?: Record<string, {
287
272
  enabled: boolean;
288
- status: "degraded" | "available" | "unavailable" | "stub";
273
+ status: "degraded" | "stub" | "available" | "unavailable";
289
274
  route?: string | undefined;
290
275
  provider?: string | undefined;
291
276
  message?: string | undefined;
@@ -308,12 +293,6 @@ declare class ObjectStackClient {
308
293
  getItems: (type: string, options?: {
309
294
  packageId?: string;
310
295
  }) => Promise<GetMetaItemsResponse>;
311
- /**
312
- * Get a specific object definition by name
313
- * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
314
- * @param name - Object name (snake_case identifier)
315
- */
316
- getObject: (name: string) => Promise<unknown>;
317
296
  /**
318
297
  * Get a specific metadata item by type and name
319
298
  * @param type - Metadata type (e.g., 'object', 'plugin')
package/dist/index.d.ts CHANGED
@@ -198,12 +198,8 @@ interface QueryOptions {
198
198
  groupBy?: string[];
199
199
  }
200
200
  interface PaginatedResult<T = any> {
201
- /** @deprecated Use `records` — aligned with FindDataResponseSchema */
202
- value?: T[];
203
201
  /** Spec-compliant: array of matching records */
204
202
  records: T[];
205
- /** @deprecated Use `total` — aligned with FindDataResponseSchema */
206
- count?: number;
207
203
  /** Total number of matching records (if requested) */
208
204
  total?: number;
209
205
  /** The object name */
@@ -256,18 +252,7 @@ declare class ObjectStackClient {
256
252
  connect(): Promise<{
257
253
  version: string;
258
254
  apiName: string;
259
- capabilities?: {
260
- graphql: boolean;
261
- search: boolean;
262
- websockets: boolean;
263
- files: boolean;
264
- analytics: boolean;
265
- ai: boolean;
266
- workflow: boolean;
267
- notifications: boolean;
268
- i18n: boolean;
269
- } | undefined;
270
- endpoints?: {
255
+ routes?: {
271
256
  data: string;
272
257
  metadata: string;
273
258
  ui?: string | undefined;
@@ -285,7 +270,7 @@ declare class ObjectStackClient {
285
270
  } | undefined;
286
271
  services?: Record<string, {
287
272
  enabled: boolean;
288
- status: "degraded" | "available" | "unavailable" | "stub";
273
+ status: "degraded" | "stub" | "available" | "unavailable";
289
274
  route?: string | undefined;
290
275
  provider?: string | undefined;
291
276
  message?: string | undefined;
@@ -308,12 +293,6 @@ declare class ObjectStackClient {
308
293
  getItems: (type: string, options?: {
309
294
  packageId?: string;
310
295
  }) => Promise<GetMetaItemsResponse>;
311
- /**
312
- * Get a specific object definition by name
313
- * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
314
- * @param name - Object name (snake_case identifier)
315
- */
316
- getObject: (name: string) => Promise<unknown>;
317
296
  /**
318
297
  * Get a specific metadata item by type and name
319
298
  * @param type - Metadata type (e.g., 'object', 'plugin')
package/dist/index.js CHANGED
@@ -325,16 +325,6 @@ var ObjectStackClient = class {
325
325
  const res = await this.fetch(url);
326
326
  return this.unwrapResponse(res);
327
327
  },
328
- /**
329
- * Get a specific object definition by name
330
- * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
331
- * @param name - Object name (snake_case identifier)
332
- */
333
- getObject: async (name) => {
334
- const route = this.getRoute("metadata");
335
- const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);
336
- return this.unwrapResponse(res);
337
- },
338
328
  /**
339
329
  * Get a specific metadata item by type and name
340
330
  * @param type - Metadata type (e.g., 'object', 'plugin')
@@ -1200,7 +1190,7 @@ var ObjectStackClient = class {
1200
1190
  this.logger.info("Connected to ObjectStack server", {
1201
1191
  version: data.version,
1202
1192
  apiName: data.apiName,
1203
- capabilities: data.capabilities
1193
+ services: data.services
1204
1194
  });
1205
1195
  return data;
1206
1196
  } catch (e) {
@@ -1278,8 +1268,8 @@ var ObjectStackClient = class {
1278
1268
  * ObjectStack uses standard conventions: /api/v1/data, /api/v1/meta, /api/v1/ui
1279
1269
  */
1280
1270
  getRoute(type) {
1281
- if (this.discoveryInfo?.endpoints && this.discoveryInfo.endpoints[type]) {
1282
- return this.discoveryInfo.endpoints[type];
1271
+ if (this.discoveryInfo?.routes && this.discoveryInfo.routes[type]) {
1272
+ return this.discoveryInfo.routes[type];
1283
1273
  }
1284
1274
  const routeMap = {
1285
1275
  data: "/api/v1/data",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/query-builder.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { 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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n SetPresenceRequest,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewRequest,\n CreateViewResponse,\n UpdateViewRequest,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n UnregisterDeviceResponse,\n GetNotificationPreferencesResponse,\n UpdateNotificationPreferencesRequest,\n UpdateNotificationPreferencesResponse,\n ListNotificationsResponse,\n MarkNotificationsReadResponse,\n MarkAllNotificationsReadResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest\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 * 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 /**\n * Login with email and password\n * Uses better-auth endpoint: POST /sign-in/email\n */\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-in/email`, {\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 /**\n * Logout current user\n * Uses better-auth endpoint: POST /sign-out\n */\n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/sign-out`, { method: 'POST' });\n this.token = undefined;\n },\n\n /**\n * Get current user session\n * Uses better-auth endpoint: GET /get-session\n */\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`);\n return res.json();\n },\n\n /**\n * Register a new user account\n * Uses better-auth endpoint: POST /sign-up/email\n */\n register: async (request: RegisterRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-up/email`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n\n /**\n * Refresh an authentication token\n * Note: better-auth handles token refresh automatically via /get-session\n * @param _refreshToken - Not used (better-auth handles refresh automatically)\n */\n refreshToken: async (_refreshToken: string): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n // better-auth doesn't have a separate refresh endpoint\n // Session refresh is handled automatically when calling /get-session\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`, {\n method: 'GET'\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\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 * Permissions Services\n */\n permissions = {\n /**\n * Check if current user has permission for an action on an object\n */\n check: async (request: CheckPermissionRequest): Promise<CheckPermissionResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/check`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<CheckPermissionResponse>(res);\n },\n\n /**\n * Get all permissions for a specific object\n */\n getObjectPermissions: async (object: string): Promise<GetObjectPermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/${encodeURIComponent(object)}`);\n return this.unwrapResponse<GetObjectPermissionsResponse>(res);\n },\n\n /**\n * Get effective permissions for the current user\n */\n getEffectivePermissions: async (): Promise<GetEffectivePermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/effective`);\n return this.unwrapResponse<GetEffectivePermissionsResponse>(res);\n }\n };\n\n /**\n * Realtime Services\n */\n realtime = {\n /**\n * Establish a realtime connection\n */\n connect: async (request?: RealtimeConnectRequest): Promise<RealtimeConnectResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/connect`, {\n method: 'POST',\n body: JSON.stringify(request || {})\n });\n return this.unwrapResponse<RealtimeConnectResponse>(res);\n },\n\n /**\n * Disconnect from realtime services\n */\n disconnect: async (): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/disconnect`, {\n method: 'POST'\n });\n },\n\n /**\n * Subscribe to a channel\n */\n subscribe: async (request: RealtimeSubscribeRequest): Promise<RealtimeSubscribeResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/subscribe`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RealtimeSubscribeResponse>(res);\n },\n\n /**\n * Unsubscribe from a channel\n */\n unsubscribe: async (subscriptionId: string): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/unsubscribe`, {\n method: 'POST',\n body: JSON.stringify({ subscriptionId })\n });\n },\n\n /**\n * Set presence state on a channel\n */\n setPresence: async (channel: string, state: SetPresenceRequest['state']): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/presence`, {\n method: 'PUT',\n body: JSON.stringify({ channel, state })\n });\n },\n\n /**\n * Get presence information for a channel\n */\n getPresence: async (channel: string): Promise<GetPresenceResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/presence/${encodeURIComponent(channel)}`);\n return this.unwrapResponse<GetPresenceResponse>(res);\n }\n };\n\n /**\n * Workflow Services\n */\n workflow = {\n /**\n * Get workflow configuration for an object\n */\n getConfig: async (object: string): Promise<GetWorkflowConfigResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/config`);\n return this.unwrapResponse<GetWorkflowConfigResponse>(res);\n },\n\n /**\n * Get current workflow state for a record\n */\n getState: async (object: string, recordId: string): Promise<GetWorkflowStateResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/state`);\n return this.unwrapResponse<GetWorkflowStateResponse>(res);\n },\n\n /**\n * Execute a workflow state transition\n */\n transition: async (request: WorkflowTransitionRequest): Promise<WorkflowTransitionResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/transition`, {\n method: 'POST',\n body: JSON.stringify({\n transition: request.transition,\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowTransitionResponse>(res);\n },\n\n /**\n * Approve a workflow step\n */\n approve: async (request: WorkflowApproveRequest): Promise<WorkflowApproveResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/approve`, {\n method: 'POST',\n body: JSON.stringify({\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowApproveResponse>(res);\n },\n\n /**\n * Reject a workflow step\n */\n reject: async (request: WorkflowRejectRequest): Promise<WorkflowRejectResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/reject`, {\n method: 'POST',\n body: JSON.stringify({\n reason: request.reason,\n comment: request.comment\n })\n });\n return this.unwrapResponse<WorkflowRejectResponse>(res);\n }\n };\n\n /**\n * Views CRUD Services\n */\n views = {\n /**\n * List views for an object\n */\n list: async (object: string, type?: 'list' | 'form'): Promise<ListViewsResponse> => {\n const route = this.getRoute('views');\n const params = new URLSearchParams();\n if (type) params.set('type', type);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListViewsResponse>(res);\n },\n\n /**\n * Get a specific view\n */\n get: async (object: string, viewId: string): Promise<GetViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`);\n return this.unwrapResponse<GetViewResponse>(res);\n },\n\n /**\n * Create a new view\n */\n create: async (object: string, data: CreateViewRequest['data']): Promise<CreateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}`, {\n method: 'POST',\n body: JSON.stringify({ object, data })\n });\n return this.unwrapResponse<CreateViewResponse>(res);\n },\n\n /**\n * Update an existing view\n */\n update: async (object: string, viewId: string, data: UpdateViewRequest['data']): Promise<UpdateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'PUT',\n body: JSON.stringify({ object, viewId, data })\n });\n return this.unwrapResponse<UpdateViewResponse>(res);\n },\n\n /**\n * Delete a view\n */\n delete: async (object: string, viewId: string): Promise<DeleteViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<DeleteViewResponse>(res);\n }\n };\n\n /**\n * Notification Services\n */\n notifications = {\n /**\n * Register a device for push notifications\n */\n registerDevice: async (request: RegisterDeviceRequest): Promise<RegisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RegisterDeviceResponse>(res);\n },\n\n /**\n * Unregister a device from push notifications\n */\n unregisterDevice: async (deviceId: string): Promise<UnregisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices/${encodeURIComponent(deviceId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<UnregisterDeviceResponse>(res);\n },\n\n /**\n * Get notification preferences for the current user\n */\n getPreferences: async (): Promise<GetNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`);\n return this.unwrapResponse<GetNotificationPreferencesResponse>(res);\n },\n\n /**\n * Update notification preferences\n */\n updatePreferences: async (preferences: UpdateNotificationPreferencesRequest['preferences']): Promise<UpdateNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`, {\n method: 'PUT',\n body: JSON.stringify({ preferences })\n });\n return this.unwrapResponse<UpdateNotificationPreferencesResponse>(res);\n },\n\n /**\n * List notifications for the current user\n */\n list: async (options?: { read?: boolean; type?: string; limit?: number; cursor?: string }): Promise<ListNotificationsResponse> => {\n const route = this.getRoute('notifications');\n const params = new URLSearchParams();\n if (options?.read !== undefined) params.set('read', String(options.read));\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListNotificationsResponse>(res);\n },\n\n /**\n * Mark specific notifications as read\n */\n markRead: async (ids: string[]): Promise<MarkNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read`, {\n method: 'POST',\n body: JSON.stringify({ ids })\n });\n return this.unwrapResponse<MarkNotificationsReadResponse>(res);\n },\n\n /**\n * Mark all notifications as read\n */\n markAllRead: async (): Promise<MarkAllNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read/all`, {\n method: 'POST'\n });\n return this.unwrapResponse<MarkAllNotificationsReadResponse>(res);\n }\n };\n\n /**\n * AI Services\n */\n ai = {\n /**\n * Natural language query — converts natural language to structured query\n */\n nlq: async (request: AiNlqRequest): Promise<AiNlqResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/nlq`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiNlqResponse>(res);\n },\n\n /**\n * Multi-turn AI chat\n */\n chat: async (request: AiChatRequest): Promise<AiChatResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/chat`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiChatResponse>(res);\n },\n\n /**\n * AI-powered field value suggestions\n */\n suggest: async (request: AiSuggestRequest): Promise<AiSuggestResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/suggest`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiSuggestResponse>(res);\n },\n\n /**\n * AI-powered data insights\n */\n insights: async (request: AiInsightsRequest): Promise<AiInsightsResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/insights`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiInsightsResponse>(res);\n }\n };\n\n /**\n * Internationalization Services\n */\n i18n = {\n /**\n * Get available locales\n */\n getLocales: async (): Promise<GetLocalesResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/locales`);\n return this.unwrapResponse<GetLocalesResponse>(res);\n },\n\n /**\n * Get translations for a locale\n */\n getTranslations: async (locale: string, options?: { namespace?: string; keys?: string[] }): Promise<GetTranslationsResponse> => {\n const route = this.getRoute('i18n');\n const params = new URLSearchParams();\n params.set('locale', locale);\n if (options?.namespace) params.set('namespace', options.namespace);\n if (options?.keys) params.set('keys', options.keys.join(','));\n const res = await this.fetch(`${this.baseUrl}${route}/translations?${params.toString()}`);\n return this.unwrapResponse<GetTranslationsResponse>(res);\n },\n\n /**\n * Get translated field labels for an object\n */\n getFieldLabels: async (object: string, locale: string): Promise<GetFieldLabelsResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/labels/${encodeURIComponent(object)}?locale=${encodeURIComponent(locale)}`);\n return this.unwrapResponse<GetFieldLabelsResponse>(res);\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 // Detect AST filter format vs simple key-value map. AST filters use an array structure\n // with [field, operator, value] or [logicOp, ...nodes] shape (see isFilterAST).\n // For complex filter expressions, use .query() which builds a proper QueryAST.\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' | 'storage' | 'automation' | 'packages' | 'permissions' | 'realtime' | 'workflow' | 'views' | 'notifications' | 'ai' | 'i18n'): 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 storage: '/api/v1/storage',\n automation: '/api/v1/automation',\n packages: '/api/v1/packages',\n permissions: '/api/v1/auth', // Permission endpoints are under /api/v1/auth per spec\n realtime: '/api/v1/realtime',\n workflow: '/api/v1/workflow',\n views: '/api/v1/ui/views',\n notifications: '/api/v1/notifications',\n ai: '/api/v1/ai',\n i18n: '/api/v1/i18n',\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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewResponse,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n ListNotificationsResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest,\n RefreshTokenRequest\n} from '@objectstack/spec/api';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\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 * BETWEEN filter: field BETWEEN min AND max\n */\n between<K extends keyof T>(field: K, min: T[K], max: T[K]): this {\n this.conditions.push(['and', [field as string, '>=', min], [field as string, '<=', max]] as FilterCondition);\n return this;\n }\n\n /**\n * CONTAINS filter: field contains value (case-insensitive LIKE %value%)\n */\n contains<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}%`]);\n return this;\n }\n\n /**\n * STARTS WITH filter: field starts with value (LIKE value%)\n */\n startsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `${value}%`]);\n return this;\n }\n\n /**\n * ENDS WITH filter: field ends with value (LIKE %value)\n */\n endsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}`]);\n return this;\n }\n\n /**\n * EXISTS filter: field is not null (alias for isNotNull)\n */\n exists<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 * Expand (eager-load) a related object with an optional sub-query\n */\n expand(relation: string, subQuery?: Partial<QueryAST>): this {\n if (!this.query.expand) {\n this.query.expand = {};\n }\n (this.query.expand as Record<string, any>)[relation] = subQuery || {};\n return this;\n }\n\n /**\n * Add full-text search\n */\n search(query: string, options?: { fields?: string[]; fuzzy?: boolean }): this {\n (this.query as any).search = { query, ...options };\n return this;\n }\n\n /**\n * Set cursor for keyset pagination\n */\n cursor(cursor: Record<string, any>): this {\n (this.query as any).cursor = cursor;\n return this;\n }\n\n /**\n * Enable SELECT DISTINCT\n */\n distinct(): this {\n (this.query as any).distinct = true;\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":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { 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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n SetPresenceRequest,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewRequest,\n CreateViewResponse,\n UpdateViewRequest,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n UnregisterDeviceResponse,\n GetNotificationPreferencesResponse,\n UpdateNotificationPreferencesRequest,\n UpdateNotificationPreferencesResponse,\n ListNotificationsResponse,\n MarkNotificationsReadResponse,\n MarkAllNotificationsReadResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest\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 /** Spec-compliant: array of matching records */\n records: T[];\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 services: data.services \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 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 * 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 /**\n * Login with email and password\n * Uses better-auth endpoint: POST /sign-in/email\n */\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-in/email`, {\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 /**\n * Logout current user\n * Uses better-auth endpoint: POST /sign-out\n */\n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/sign-out`, { method: 'POST' });\n this.token = undefined;\n },\n\n /**\n * Get current user session\n * Uses better-auth endpoint: GET /get-session\n */\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`);\n return res.json();\n },\n\n /**\n * Register a new user account\n * Uses better-auth endpoint: POST /sign-up/email\n */\n register: async (request: RegisterRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-up/email`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n\n /**\n * Refresh an authentication token\n * Note: better-auth handles token refresh automatically via /get-session\n * @param _refreshToken - Not used (better-auth handles refresh automatically)\n */\n refreshToken: async (_refreshToken: string): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n // better-auth doesn't have a separate refresh endpoint\n // Session refresh is handled automatically when calling /get-session\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`, {\n method: 'GET'\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\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 * Permissions Services\n */\n permissions = {\n /**\n * Check if current user has permission for an action on an object\n */\n check: async (request: CheckPermissionRequest): Promise<CheckPermissionResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/check`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<CheckPermissionResponse>(res);\n },\n\n /**\n * Get all permissions for a specific object\n */\n getObjectPermissions: async (object: string): Promise<GetObjectPermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/${encodeURIComponent(object)}`);\n return this.unwrapResponse<GetObjectPermissionsResponse>(res);\n },\n\n /**\n * Get effective permissions for the current user\n */\n getEffectivePermissions: async (): Promise<GetEffectivePermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/effective`);\n return this.unwrapResponse<GetEffectivePermissionsResponse>(res);\n }\n };\n\n /**\n * Realtime Services\n */\n realtime = {\n /**\n * Establish a realtime connection\n */\n connect: async (request?: RealtimeConnectRequest): Promise<RealtimeConnectResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/connect`, {\n method: 'POST',\n body: JSON.stringify(request || {})\n });\n return this.unwrapResponse<RealtimeConnectResponse>(res);\n },\n\n /**\n * Disconnect from realtime services\n */\n disconnect: async (): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/disconnect`, {\n method: 'POST'\n });\n },\n\n /**\n * Subscribe to a channel\n */\n subscribe: async (request: RealtimeSubscribeRequest): Promise<RealtimeSubscribeResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/subscribe`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RealtimeSubscribeResponse>(res);\n },\n\n /**\n * Unsubscribe from a channel\n */\n unsubscribe: async (subscriptionId: string): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/unsubscribe`, {\n method: 'POST',\n body: JSON.stringify({ subscriptionId })\n });\n },\n\n /**\n * Set presence state on a channel\n */\n setPresence: async (channel: string, state: SetPresenceRequest['state']): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/presence`, {\n method: 'PUT',\n body: JSON.stringify({ channel, state })\n });\n },\n\n /**\n * Get presence information for a channel\n */\n getPresence: async (channel: string): Promise<GetPresenceResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/presence/${encodeURIComponent(channel)}`);\n return this.unwrapResponse<GetPresenceResponse>(res);\n }\n };\n\n /**\n * Workflow Services\n */\n workflow = {\n /**\n * Get workflow configuration for an object\n */\n getConfig: async (object: string): Promise<GetWorkflowConfigResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/config`);\n return this.unwrapResponse<GetWorkflowConfigResponse>(res);\n },\n\n /**\n * Get current workflow state for a record\n */\n getState: async (object: string, recordId: string): Promise<GetWorkflowStateResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/state`);\n return this.unwrapResponse<GetWorkflowStateResponse>(res);\n },\n\n /**\n * Execute a workflow state transition\n */\n transition: async (request: WorkflowTransitionRequest): Promise<WorkflowTransitionResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/transition`, {\n method: 'POST',\n body: JSON.stringify({\n transition: request.transition,\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowTransitionResponse>(res);\n },\n\n /**\n * Approve a workflow step\n */\n approve: async (request: WorkflowApproveRequest): Promise<WorkflowApproveResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/approve`, {\n method: 'POST',\n body: JSON.stringify({\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowApproveResponse>(res);\n },\n\n /**\n * Reject a workflow step\n */\n reject: async (request: WorkflowRejectRequest): Promise<WorkflowRejectResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/reject`, {\n method: 'POST',\n body: JSON.stringify({\n reason: request.reason,\n comment: request.comment\n })\n });\n return this.unwrapResponse<WorkflowRejectResponse>(res);\n }\n };\n\n /**\n * Views CRUD Services\n */\n views = {\n /**\n * List views for an object\n */\n list: async (object: string, type?: 'list' | 'form'): Promise<ListViewsResponse> => {\n const route = this.getRoute('views');\n const params = new URLSearchParams();\n if (type) params.set('type', type);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListViewsResponse>(res);\n },\n\n /**\n * Get a specific view\n */\n get: async (object: string, viewId: string): Promise<GetViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`);\n return this.unwrapResponse<GetViewResponse>(res);\n },\n\n /**\n * Create a new view\n */\n create: async (object: string, data: CreateViewRequest['data']): Promise<CreateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}`, {\n method: 'POST',\n body: JSON.stringify({ object, data })\n });\n return this.unwrapResponse<CreateViewResponse>(res);\n },\n\n /**\n * Update an existing view\n */\n update: async (object: string, viewId: string, data: UpdateViewRequest['data']): Promise<UpdateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'PUT',\n body: JSON.stringify({ object, viewId, data })\n });\n return this.unwrapResponse<UpdateViewResponse>(res);\n },\n\n /**\n * Delete a view\n */\n delete: async (object: string, viewId: string): Promise<DeleteViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<DeleteViewResponse>(res);\n }\n };\n\n /**\n * Notification Services\n */\n notifications = {\n /**\n * Register a device for push notifications\n */\n registerDevice: async (request: RegisterDeviceRequest): Promise<RegisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RegisterDeviceResponse>(res);\n },\n\n /**\n * Unregister a device from push notifications\n */\n unregisterDevice: async (deviceId: string): Promise<UnregisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices/${encodeURIComponent(deviceId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<UnregisterDeviceResponse>(res);\n },\n\n /**\n * Get notification preferences for the current user\n */\n getPreferences: async (): Promise<GetNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`);\n return this.unwrapResponse<GetNotificationPreferencesResponse>(res);\n },\n\n /**\n * Update notification preferences\n */\n updatePreferences: async (preferences: UpdateNotificationPreferencesRequest['preferences']): Promise<UpdateNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`, {\n method: 'PUT',\n body: JSON.stringify({ preferences })\n });\n return this.unwrapResponse<UpdateNotificationPreferencesResponse>(res);\n },\n\n /**\n * List notifications for the current user\n */\n list: async (options?: { read?: boolean; type?: string; limit?: number; cursor?: string }): Promise<ListNotificationsResponse> => {\n const route = this.getRoute('notifications');\n const params = new URLSearchParams();\n if (options?.read !== undefined) params.set('read', String(options.read));\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListNotificationsResponse>(res);\n },\n\n /**\n * Mark specific notifications as read\n */\n markRead: async (ids: string[]): Promise<MarkNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read`, {\n method: 'POST',\n body: JSON.stringify({ ids })\n });\n return this.unwrapResponse<MarkNotificationsReadResponse>(res);\n },\n\n /**\n * Mark all notifications as read\n */\n markAllRead: async (): Promise<MarkAllNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read/all`, {\n method: 'POST'\n });\n return this.unwrapResponse<MarkAllNotificationsReadResponse>(res);\n }\n };\n\n /**\n * AI Services\n */\n ai = {\n /**\n * Natural language query — converts natural language to structured query\n */\n nlq: async (request: AiNlqRequest): Promise<AiNlqResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/nlq`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiNlqResponse>(res);\n },\n\n /**\n * Multi-turn AI chat\n */\n chat: async (request: AiChatRequest): Promise<AiChatResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/chat`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiChatResponse>(res);\n },\n\n /**\n * AI-powered field value suggestions\n */\n suggest: async (request: AiSuggestRequest): Promise<AiSuggestResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/suggest`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiSuggestResponse>(res);\n },\n\n /**\n * AI-powered data insights\n */\n insights: async (request: AiInsightsRequest): Promise<AiInsightsResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/insights`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiInsightsResponse>(res);\n }\n };\n\n /**\n * Internationalization Services\n */\n i18n = {\n /**\n * Get available locales\n */\n getLocales: async (): Promise<GetLocalesResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/locales`);\n return this.unwrapResponse<GetLocalesResponse>(res);\n },\n\n /**\n * Get translations for a locale\n */\n getTranslations: async (locale: string, options?: { namespace?: string; keys?: string[] }): Promise<GetTranslationsResponse> => {\n const route = this.getRoute('i18n');\n const params = new URLSearchParams();\n params.set('locale', locale);\n if (options?.namespace) params.set('namespace', options.namespace);\n if (options?.keys) params.set('keys', options.keys.join(','));\n const res = await this.fetch(`${this.baseUrl}${route}/translations?${params.toString()}`);\n return this.unwrapResponse<GetTranslationsResponse>(res);\n },\n\n /**\n * Get translated field labels for an object\n */\n getFieldLabels: async (object: string, locale: string): Promise<GetFieldLabelsResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/labels/${encodeURIComponent(object)}?locale=${encodeURIComponent(locale)}`);\n return this.unwrapResponse<GetFieldLabelsResponse>(res);\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 // Detect AST filter format vs simple key-value map. AST filters use an array structure\n // with [field, operator, value] or [logicOp, ...nodes] shape (see isFilterAST).\n // For complex filter expressions, use .query() which builds a proper QueryAST.\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' | 'storage' | 'automation' | 'packages' | 'permissions' | 'realtime' | 'workflow' | 'views' | 'notifications' | 'ai' | 'i18n'): string {\n // 1. Use discovered routes if available\n if (this.discoveryInfo?.routes && (this.discoveryInfo.routes as any)[type]) {\n return (this.discoveryInfo.routes 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 storage: '/api/v1/storage',\n automation: '/api/v1/automation',\n packages: '/api/v1/packages',\n permissions: '/api/v1/auth', // Permission endpoints are under /api/v1/auth per spec\n realtime: '/api/v1/realtime',\n workflow: '/api/v1/workflow',\n views: '/api/v1/ui/views',\n notifications: '/api/v1/notifications',\n ai: '/api/v1/ai',\n i18n: '/api/v1/i18n',\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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewResponse,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n ListNotificationsResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest,\n RefreshTokenRequest\n} from '@objectstack/spec/api';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\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 * BETWEEN filter: field BETWEEN min AND max\n */\n between<K extends keyof T>(field: K, min: T[K], max: T[K]): this {\n this.conditions.push(['and', [field as string, '>=', min], [field as string, '<=', max]] as FilterCondition);\n return this;\n }\n\n /**\n * CONTAINS filter: field contains value (case-insensitive LIKE %value%)\n */\n contains<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}%`]);\n return this;\n }\n\n /**\n * STARTS WITH filter: field starts with value (LIKE value%)\n */\n startsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `${value}%`]);\n return this;\n }\n\n /**\n * ENDS WITH filter: field ends with value (LIKE %value)\n */\n endsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}`]);\n return this;\n }\n\n /**\n * EXISTS filter: field is not null (alias for isNotNull)\n */\n exists<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 * Expand (eager-load) a related object with an optional sub-query\n */\n expand(relation: string, subQuery?: Partial<QueryAST>): this {\n if (!this.query.expand) {\n this.query.expand = {};\n }\n (this.query.expand as Record<string, any>)[relation] = subQuery || {};\n return this;\n }\n\n /**\n * Add full-text search\n */\n search(query: string, options?: { fields?: string[]; fuzzy?: boolean }): this {\n (this.query as any).search = { query, ...options };\n return this;\n }\n\n /**\n * Set cursor for keyset pagination\n */\n cursor(cursor: Record<string, any>): this {\n (this.query as any).cursor = cursor;\n return this;\n }\n\n /**\n * Enable SELECT DISTINCT\n */\n distinct(): this {\n (this.query as any).distinct = true;\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/dist/index.mjs CHANGED
@@ -297,16 +297,6 @@ var ObjectStackClient = class {
297
297
  const res = await this.fetch(url);
298
298
  return this.unwrapResponse(res);
299
299
  },
300
- /**
301
- * Get a specific object definition by name
302
- * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
303
- * @param name - Object name (snake_case identifier)
304
- */
305
- getObject: async (name) => {
306
- const route = this.getRoute("metadata");
307
- const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);
308
- return this.unwrapResponse(res);
309
- },
310
300
  /**
311
301
  * Get a specific metadata item by type and name
312
302
  * @param type - Metadata type (e.g., 'object', 'plugin')
@@ -1172,7 +1162,7 @@ var ObjectStackClient = class {
1172
1162
  this.logger.info("Connected to ObjectStack server", {
1173
1163
  version: data.version,
1174
1164
  apiName: data.apiName,
1175
- capabilities: data.capabilities
1165
+ services: data.services
1176
1166
  });
1177
1167
  return data;
1178
1168
  } catch (e) {
@@ -1250,8 +1240,8 @@ var ObjectStackClient = class {
1250
1240
  * ObjectStack uses standard conventions: /api/v1/data, /api/v1/meta, /api/v1/ui
1251
1241
  */
1252
1242
  getRoute(type) {
1253
- if (this.discoveryInfo?.endpoints && this.discoveryInfo.endpoints[type]) {
1254
- return this.discoveryInfo.endpoints[type];
1243
+ if (this.discoveryInfo?.routes && this.discoveryInfo.routes[type]) {
1244
+ return this.discoveryInfo.routes[type];
1255
1245
  }
1256
1246
  const routeMap = {
1257
1247
  data: "/api/v1/data",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/query-builder.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { 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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n SetPresenceRequest,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewRequest,\n CreateViewResponse,\n UpdateViewRequest,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n UnregisterDeviceResponse,\n GetNotificationPreferencesResponse,\n UpdateNotificationPreferencesRequest,\n UpdateNotificationPreferencesResponse,\n ListNotificationsResponse,\n MarkNotificationsReadResponse,\n MarkAllNotificationsReadResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest\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 * 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 /**\n * Login with email and password\n * Uses better-auth endpoint: POST /sign-in/email\n */\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-in/email`, {\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 /**\n * Logout current user\n * Uses better-auth endpoint: POST /sign-out\n */\n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/sign-out`, { method: 'POST' });\n this.token = undefined;\n },\n\n /**\n * Get current user session\n * Uses better-auth endpoint: GET /get-session\n */\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`);\n return res.json();\n },\n\n /**\n * Register a new user account\n * Uses better-auth endpoint: POST /sign-up/email\n */\n register: async (request: RegisterRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-up/email`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n\n /**\n * Refresh an authentication token\n * Note: better-auth handles token refresh automatically via /get-session\n * @param _refreshToken - Not used (better-auth handles refresh automatically)\n */\n refreshToken: async (_refreshToken: string): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n // better-auth doesn't have a separate refresh endpoint\n // Session refresh is handled automatically when calling /get-session\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`, {\n method: 'GET'\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\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 * Permissions Services\n */\n permissions = {\n /**\n * Check if current user has permission for an action on an object\n */\n check: async (request: CheckPermissionRequest): Promise<CheckPermissionResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/check`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<CheckPermissionResponse>(res);\n },\n\n /**\n * Get all permissions for a specific object\n */\n getObjectPermissions: async (object: string): Promise<GetObjectPermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/${encodeURIComponent(object)}`);\n return this.unwrapResponse<GetObjectPermissionsResponse>(res);\n },\n\n /**\n * Get effective permissions for the current user\n */\n getEffectivePermissions: async (): Promise<GetEffectivePermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/effective`);\n return this.unwrapResponse<GetEffectivePermissionsResponse>(res);\n }\n };\n\n /**\n * Realtime Services\n */\n realtime = {\n /**\n * Establish a realtime connection\n */\n connect: async (request?: RealtimeConnectRequest): Promise<RealtimeConnectResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/connect`, {\n method: 'POST',\n body: JSON.stringify(request || {})\n });\n return this.unwrapResponse<RealtimeConnectResponse>(res);\n },\n\n /**\n * Disconnect from realtime services\n */\n disconnect: async (): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/disconnect`, {\n method: 'POST'\n });\n },\n\n /**\n * Subscribe to a channel\n */\n subscribe: async (request: RealtimeSubscribeRequest): Promise<RealtimeSubscribeResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/subscribe`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RealtimeSubscribeResponse>(res);\n },\n\n /**\n * Unsubscribe from a channel\n */\n unsubscribe: async (subscriptionId: string): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/unsubscribe`, {\n method: 'POST',\n body: JSON.stringify({ subscriptionId })\n });\n },\n\n /**\n * Set presence state on a channel\n */\n setPresence: async (channel: string, state: SetPresenceRequest['state']): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/presence`, {\n method: 'PUT',\n body: JSON.stringify({ channel, state })\n });\n },\n\n /**\n * Get presence information for a channel\n */\n getPresence: async (channel: string): Promise<GetPresenceResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/presence/${encodeURIComponent(channel)}`);\n return this.unwrapResponse<GetPresenceResponse>(res);\n }\n };\n\n /**\n * Workflow Services\n */\n workflow = {\n /**\n * Get workflow configuration for an object\n */\n getConfig: async (object: string): Promise<GetWorkflowConfigResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/config`);\n return this.unwrapResponse<GetWorkflowConfigResponse>(res);\n },\n\n /**\n * Get current workflow state for a record\n */\n getState: async (object: string, recordId: string): Promise<GetWorkflowStateResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/state`);\n return this.unwrapResponse<GetWorkflowStateResponse>(res);\n },\n\n /**\n * Execute a workflow state transition\n */\n transition: async (request: WorkflowTransitionRequest): Promise<WorkflowTransitionResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/transition`, {\n method: 'POST',\n body: JSON.stringify({\n transition: request.transition,\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowTransitionResponse>(res);\n },\n\n /**\n * Approve a workflow step\n */\n approve: async (request: WorkflowApproveRequest): Promise<WorkflowApproveResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/approve`, {\n method: 'POST',\n body: JSON.stringify({\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowApproveResponse>(res);\n },\n\n /**\n * Reject a workflow step\n */\n reject: async (request: WorkflowRejectRequest): Promise<WorkflowRejectResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/reject`, {\n method: 'POST',\n body: JSON.stringify({\n reason: request.reason,\n comment: request.comment\n })\n });\n return this.unwrapResponse<WorkflowRejectResponse>(res);\n }\n };\n\n /**\n * Views CRUD Services\n */\n views = {\n /**\n * List views for an object\n */\n list: async (object: string, type?: 'list' | 'form'): Promise<ListViewsResponse> => {\n const route = this.getRoute('views');\n const params = new URLSearchParams();\n if (type) params.set('type', type);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListViewsResponse>(res);\n },\n\n /**\n * Get a specific view\n */\n get: async (object: string, viewId: string): Promise<GetViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`);\n return this.unwrapResponse<GetViewResponse>(res);\n },\n\n /**\n * Create a new view\n */\n create: async (object: string, data: CreateViewRequest['data']): Promise<CreateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}`, {\n method: 'POST',\n body: JSON.stringify({ object, data })\n });\n return this.unwrapResponse<CreateViewResponse>(res);\n },\n\n /**\n * Update an existing view\n */\n update: async (object: string, viewId: string, data: UpdateViewRequest['data']): Promise<UpdateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'PUT',\n body: JSON.stringify({ object, viewId, data })\n });\n return this.unwrapResponse<UpdateViewResponse>(res);\n },\n\n /**\n * Delete a view\n */\n delete: async (object: string, viewId: string): Promise<DeleteViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<DeleteViewResponse>(res);\n }\n };\n\n /**\n * Notification Services\n */\n notifications = {\n /**\n * Register a device for push notifications\n */\n registerDevice: async (request: RegisterDeviceRequest): Promise<RegisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RegisterDeviceResponse>(res);\n },\n\n /**\n * Unregister a device from push notifications\n */\n unregisterDevice: async (deviceId: string): Promise<UnregisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices/${encodeURIComponent(deviceId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<UnregisterDeviceResponse>(res);\n },\n\n /**\n * Get notification preferences for the current user\n */\n getPreferences: async (): Promise<GetNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`);\n return this.unwrapResponse<GetNotificationPreferencesResponse>(res);\n },\n\n /**\n * Update notification preferences\n */\n updatePreferences: async (preferences: UpdateNotificationPreferencesRequest['preferences']): Promise<UpdateNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`, {\n method: 'PUT',\n body: JSON.stringify({ preferences })\n });\n return this.unwrapResponse<UpdateNotificationPreferencesResponse>(res);\n },\n\n /**\n * List notifications for the current user\n */\n list: async (options?: { read?: boolean; type?: string; limit?: number; cursor?: string }): Promise<ListNotificationsResponse> => {\n const route = this.getRoute('notifications');\n const params = new URLSearchParams();\n if (options?.read !== undefined) params.set('read', String(options.read));\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListNotificationsResponse>(res);\n },\n\n /**\n * Mark specific notifications as read\n */\n markRead: async (ids: string[]): Promise<MarkNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read`, {\n method: 'POST',\n body: JSON.stringify({ ids })\n });\n return this.unwrapResponse<MarkNotificationsReadResponse>(res);\n },\n\n /**\n * Mark all notifications as read\n */\n markAllRead: async (): Promise<MarkAllNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read/all`, {\n method: 'POST'\n });\n return this.unwrapResponse<MarkAllNotificationsReadResponse>(res);\n }\n };\n\n /**\n * AI Services\n */\n ai = {\n /**\n * Natural language query — converts natural language to structured query\n */\n nlq: async (request: AiNlqRequest): Promise<AiNlqResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/nlq`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiNlqResponse>(res);\n },\n\n /**\n * Multi-turn AI chat\n */\n chat: async (request: AiChatRequest): Promise<AiChatResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/chat`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiChatResponse>(res);\n },\n\n /**\n * AI-powered field value suggestions\n */\n suggest: async (request: AiSuggestRequest): Promise<AiSuggestResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/suggest`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiSuggestResponse>(res);\n },\n\n /**\n * AI-powered data insights\n */\n insights: async (request: AiInsightsRequest): Promise<AiInsightsResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/insights`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiInsightsResponse>(res);\n }\n };\n\n /**\n * Internationalization Services\n */\n i18n = {\n /**\n * Get available locales\n */\n getLocales: async (): Promise<GetLocalesResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/locales`);\n return this.unwrapResponse<GetLocalesResponse>(res);\n },\n\n /**\n * Get translations for a locale\n */\n getTranslations: async (locale: string, options?: { namespace?: string; keys?: string[] }): Promise<GetTranslationsResponse> => {\n const route = this.getRoute('i18n');\n const params = new URLSearchParams();\n params.set('locale', locale);\n if (options?.namespace) params.set('namespace', options.namespace);\n if (options?.keys) params.set('keys', options.keys.join(','));\n const res = await this.fetch(`${this.baseUrl}${route}/translations?${params.toString()}`);\n return this.unwrapResponse<GetTranslationsResponse>(res);\n },\n\n /**\n * Get translated field labels for an object\n */\n getFieldLabels: async (object: string, locale: string): Promise<GetFieldLabelsResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/labels/${encodeURIComponent(object)}?locale=${encodeURIComponent(locale)}`);\n return this.unwrapResponse<GetFieldLabelsResponse>(res);\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 // Detect AST filter format vs simple key-value map. AST filters use an array structure\n // with [field, operator, value] or [logicOp, ...nodes] shape (see isFilterAST).\n // For complex filter expressions, use .query() which builds a proper QueryAST.\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' | 'storage' | 'automation' | 'packages' | 'permissions' | 'realtime' | 'workflow' | 'views' | 'notifications' | 'ai' | 'i18n'): 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 storage: '/api/v1/storage',\n automation: '/api/v1/automation',\n packages: '/api/v1/packages',\n permissions: '/api/v1/auth', // Permission endpoints are under /api/v1/auth per spec\n realtime: '/api/v1/realtime',\n workflow: '/api/v1/workflow',\n views: '/api/v1/ui/views',\n notifications: '/api/v1/notifications',\n ai: '/api/v1/ai',\n i18n: '/api/v1/i18n',\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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewResponse,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n ListNotificationsResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest,\n RefreshTokenRequest\n} from '@objectstack/spec/api';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\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 * BETWEEN filter: field BETWEEN min AND max\n */\n between<K extends keyof T>(field: K, min: T[K], max: T[K]): this {\n this.conditions.push(['and', [field as string, '>=', min], [field as string, '<=', max]] as FilterCondition);\n return this;\n }\n\n /**\n * CONTAINS filter: field contains value (case-insensitive LIKE %value%)\n */\n contains<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}%`]);\n return this;\n }\n\n /**\n * STARTS WITH filter: field starts with value (LIKE value%)\n */\n startsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `${value}%`]);\n return this;\n }\n\n /**\n * ENDS WITH filter: field ends with value (LIKE %value)\n */\n endsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}`]);\n return this;\n }\n\n /**\n * EXISTS filter: field is not null (alias for isNotNull)\n */\n exists<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 * Expand (eager-load) a related object with an optional sub-query\n */\n expand(relation: string, subQuery?: Partial<QueryAST>): this {\n if (!this.query.expand) {\n this.query.expand = {};\n }\n (this.query.expand as Record<string, any>)[relation] = subQuery || {};\n return this;\n }\n\n /**\n * Add full-text search\n */\n search(query: string, options?: { fields?: string[]; fuzzy?: boolean }): this {\n (this.query as any).search = { query, ...options };\n return this;\n }\n\n /**\n * Set cursor for keyset pagination\n */\n cursor(cursor: Record<string, any>): this {\n (this.query as any).cursor = cursor;\n return this;\n }\n\n /**\n * Enable SELECT DISTINCT\n */\n distinct(): this {\n (this.query as any).distinct = true;\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":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { 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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n SetPresenceRequest,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewRequest,\n CreateViewResponse,\n UpdateViewRequest,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n UnregisterDeviceResponse,\n GetNotificationPreferencesResponse,\n UpdateNotificationPreferencesRequest,\n UpdateNotificationPreferencesResponse,\n ListNotificationsResponse,\n MarkNotificationsReadResponse,\n MarkAllNotificationsReadResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest\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 /** Spec-compliant: array of matching records */\n records: T[];\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 services: data.services \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 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 * 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 /**\n * Login with email and password\n * Uses better-auth endpoint: POST /sign-in/email\n */\n login: async (request: LoginRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-in/email`, {\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 /**\n * Logout current user\n * Uses better-auth endpoint: POST /sign-out\n */\n logout: async () => {\n const route = this.getRoute('auth');\n await this.fetch(`${this.baseUrl}${route}/sign-out`, { method: 'POST' });\n this.token = undefined;\n },\n\n /**\n * Get current user session\n * Uses better-auth endpoint: GET /get-session\n */\n me: async (): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`);\n return res.json();\n },\n\n /**\n * Register a new user account\n * Uses better-auth endpoint: POST /sign-up/email\n */\n register: async (request: RegisterRequest): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n const res = await this.fetch(`${this.baseUrl}${route}/sign-up/email`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\n },\n\n /**\n * Refresh an authentication token\n * Note: better-auth handles token refresh automatically via /get-session\n * @param _refreshToken - Not used (better-auth handles refresh automatically)\n */\n refreshToken: async (_refreshToken: string): Promise<SessionResponse> => {\n const route = this.getRoute('auth');\n // better-auth doesn't have a separate refresh endpoint\n // Session refresh is handled automatically when calling /get-session\n const res = await this.fetch(`${this.baseUrl}${route}/get-session`, {\n method: 'GET'\n });\n const data = await res.json();\n if (data.data?.token) {\n this.token = data.data.token;\n }\n return data;\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 * Permissions Services\n */\n permissions = {\n /**\n * Check if current user has permission for an action on an object\n */\n check: async (request: CheckPermissionRequest): Promise<CheckPermissionResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/check`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<CheckPermissionResponse>(res);\n },\n\n /**\n * Get all permissions for a specific object\n */\n getObjectPermissions: async (object: string): Promise<GetObjectPermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/${encodeURIComponent(object)}`);\n return this.unwrapResponse<GetObjectPermissionsResponse>(res);\n },\n\n /**\n * Get effective permissions for the current user\n */\n getEffectivePermissions: async (): Promise<GetEffectivePermissionsResponse> => {\n const route = this.getRoute('permissions');\n const res = await this.fetch(`${this.baseUrl}${route}/permissions/effective`);\n return this.unwrapResponse<GetEffectivePermissionsResponse>(res);\n }\n };\n\n /**\n * Realtime Services\n */\n realtime = {\n /**\n * Establish a realtime connection\n */\n connect: async (request?: RealtimeConnectRequest): Promise<RealtimeConnectResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/connect`, {\n method: 'POST',\n body: JSON.stringify(request || {})\n });\n return this.unwrapResponse<RealtimeConnectResponse>(res);\n },\n\n /**\n * Disconnect from realtime services\n */\n disconnect: async (): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/disconnect`, {\n method: 'POST'\n });\n },\n\n /**\n * Subscribe to a channel\n */\n subscribe: async (request: RealtimeSubscribeRequest): Promise<RealtimeSubscribeResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/subscribe`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RealtimeSubscribeResponse>(res);\n },\n\n /**\n * Unsubscribe from a channel\n */\n unsubscribe: async (subscriptionId: string): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/unsubscribe`, {\n method: 'POST',\n body: JSON.stringify({ subscriptionId })\n });\n },\n\n /**\n * Set presence state on a channel\n */\n setPresence: async (channel: string, state: SetPresenceRequest['state']): Promise<void> => {\n const route = this.getRoute('realtime');\n await this.fetch(`${this.baseUrl}${route}/presence`, {\n method: 'PUT',\n body: JSON.stringify({ channel, state })\n });\n },\n\n /**\n * Get presence information for a channel\n */\n getPresence: async (channel: string): Promise<GetPresenceResponse> => {\n const route = this.getRoute('realtime');\n const res = await this.fetch(`${this.baseUrl}${route}/presence/${encodeURIComponent(channel)}`);\n return this.unwrapResponse<GetPresenceResponse>(res);\n }\n };\n\n /**\n * Workflow Services\n */\n workflow = {\n /**\n * Get workflow configuration for an object\n */\n getConfig: async (object: string): Promise<GetWorkflowConfigResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/config`);\n return this.unwrapResponse<GetWorkflowConfigResponse>(res);\n },\n\n /**\n * Get current workflow state for a record\n */\n getState: async (object: string, recordId: string): Promise<GetWorkflowStateResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(recordId)}/state`);\n return this.unwrapResponse<GetWorkflowStateResponse>(res);\n },\n\n /**\n * Execute a workflow state transition\n */\n transition: async (request: WorkflowTransitionRequest): Promise<WorkflowTransitionResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/transition`, {\n method: 'POST',\n body: JSON.stringify({\n transition: request.transition,\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowTransitionResponse>(res);\n },\n\n /**\n * Approve a workflow step\n */\n approve: async (request: WorkflowApproveRequest): Promise<WorkflowApproveResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/approve`, {\n method: 'POST',\n body: JSON.stringify({\n comment: request.comment,\n data: request.data\n })\n });\n return this.unwrapResponse<WorkflowApproveResponse>(res);\n },\n\n /**\n * Reject a workflow step\n */\n reject: async (request: WorkflowRejectRequest): Promise<WorkflowRejectResponse> => {\n const route = this.getRoute('workflow');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(request.object)}/${encodeURIComponent(request.recordId)}/reject`, {\n method: 'POST',\n body: JSON.stringify({\n reason: request.reason,\n comment: request.comment\n })\n });\n return this.unwrapResponse<WorkflowRejectResponse>(res);\n }\n };\n\n /**\n * Views CRUD Services\n */\n views = {\n /**\n * List views for an object\n */\n list: async (object: string, type?: 'list' | 'form'): Promise<ListViewsResponse> => {\n const route = this.getRoute('views');\n const params = new URLSearchParams();\n if (type) params.set('type', type);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListViewsResponse>(res);\n },\n\n /**\n * Get a specific view\n */\n get: async (object: string, viewId: string): Promise<GetViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`);\n return this.unwrapResponse<GetViewResponse>(res);\n },\n\n /**\n * Create a new view\n */\n create: async (object: string, data: CreateViewRequest['data']): Promise<CreateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}`, {\n method: 'POST',\n body: JSON.stringify({ object, data })\n });\n return this.unwrapResponse<CreateViewResponse>(res);\n },\n\n /**\n * Update an existing view\n */\n update: async (object: string, viewId: string, data: UpdateViewRequest['data']): Promise<UpdateViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'PUT',\n body: JSON.stringify({ object, viewId, data })\n });\n return this.unwrapResponse<UpdateViewResponse>(res);\n },\n\n /**\n * Delete a view\n */\n delete: async (object: string, viewId: string): Promise<DeleteViewResponse> => {\n const route = this.getRoute('views');\n const res = await this.fetch(`${this.baseUrl}${route}/${encodeURIComponent(object)}/${encodeURIComponent(viewId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<DeleteViewResponse>(res);\n }\n };\n\n /**\n * Notification Services\n */\n notifications = {\n /**\n * Register a device for push notifications\n */\n registerDevice: async (request: RegisterDeviceRequest): Promise<RegisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<RegisterDeviceResponse>(res);\n },\n\n /**\n * Unregister a device from push notifications\n */\n unregisterDevice: async (deviceId: string): Promise<UnregisterDeviceResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/devices/${encodeURIComponent(deviceId)}`, {\n method: 'DELETE'\n });\n return this.unwrapResponse<UnregisterDeviceResponse>(res);\n },\n\n /**\n * Get notification preferences for the current user\n */\n getPreferences: async (): Promise<GetNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`);\n return this.unwrapResponse<GetNotificationPreferencesResponse>(res);\n },\n\n /**\n * Update notification preferences\n */\n updatePreferences: async (preferences: UpdateNotificationPreferencesRequest['preferences']): Promise<UpdateNotificationPreferencesResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/preferences`, {\n method: 'PUT',\n body: JSON.stringify({ preferences })\n });\n return this.unwrapResponse<UpdateNotificationPreferencesResponse>(res);\n },\n\n /**\n * List notifications for the current user\n */\n list: async (options?: { read?: boolean; type?: string; limit?: number; cursor?: string }): Promise<ListNotificationsResponse> => {\n const route = this.getRoute('notifications');\n const params = new URLSearchParams();\n if (options?.read !== undefined) params.set('read', String(options.read));\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.cursor) params.set('cursor', options.cursor);\n const qs = params.toString();\n const res = await this.fetch(`${this.baseUrl}${route}${qs ? `?${qs}` : ''}`);\n return this.unwrapResponse<ListNotificationsResponse>(res);\n },\n\n /**\n * Mark specific notifications as read\n */\n markRead: async (ids: string[]): Promise<MarkNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read`, {\n method: 'POST',\n body: JSON.stringify({ ids })\n });\n return this.unwrapResponse<MarkNotificationsReadResponse>(res);\n },\n\n /**\n * Mark all notifications as read\n */\n markAllRead: async (): Promise<MarkAllNotificationsReadResponse> => {\n const route = this.getRoute('notifications');\n const res = await this.fetch(`${this.baseUrl}${route}/read/all`, {\n method: 'POST'\n });\n return this.unwrapResponse<MarkAllNotificationsReadResponse>(res);\n }\n };\n\n /**\n * AI Services\n */\n ai = {\n /**\n * Natural language query — converts natural language to structured query\n */\n nlq: async (request: AiNlqRequest): Promise<AiNlqResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/nlq`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiNlqResponse>(res);\n },\n\n /**\n * Multi-turn AI chat\n */\n chat: async (request: AiChatRequest): Promise<AiChatResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/chat`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiChatResponse>(res);\n },\n\n /**\n * AI-powered field value suggestions\n */\n suggest: async (request: AiSuggestRequest): Promise<AiSuggestResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/suggest`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiSuggestResponse>(res);\n },\n\n /**\n * AI-powered data insights\n */\n insights: async (request: AiInsightsRequest): Promise<AiInsightsResponse> => {\n const route = this.getRoute('ai');\n const res = await this.fetch(`${this.baseUrl}${route}/insights`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n return this.unwrapResponse<AiInsightsResponse>(res);\n }\n };\n\n /**\n * Internationalization Services\n */\n i18n = {\n /**\n * Get available locales\n */\n getLocales: async (): Promise<GetLocalesResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/locales`);\n return this.unwrapResponse<GetLocalesResponse>(res);\n },\n\n /**\n * Get translations for a locale\n */\n getTranslations: async (locale: string, options?: { namespace?: string; keys?: string[] }): Promise<GetTranslationsResponse> => {\n const route = this.getRoute('i18n');\n const params = new URLSearchParams();\n params.set('locale', locale);\n if (options?.namespace) params.set('namespace', options.namespace);\n if (options?.keys) params.set('keys', options.keys.join(','));\n const res = await this.fetch(`${this.baseUrl}${route}/translations?${params.toString()}`);\n return this.unwrapResponse<GetTranslationsResponse>(res);\n },\n\n /**\n * Get translated field labels for an object\n */\n getFieldLabels: async (object: string, locale: string): Promise<GetFieldLabelsResponse> => {\n const route = this.getRoute('i18n');\n const res = await this.fetch(`${this.baseUrl}${route}/labels/${encodeURIComponent(object)}?locale=${encodeURIComponent(locale)}`);\n return this.unwrapResponse<GetFieldLabelsResponse>(res);\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 // Detect AST filter format vs simple key-value map. AST filters use an array structure\n // with [field, operator, value] or [logicOp, ...nodes] shape (see isFilterAST).\n // For complex filter expressions, use .query() which builds a proper QueryAST.\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' | 'storage' | 'automation' | 'packages' | 'permissions' | 'realtime' | 'workflow' | 'views' | 'notifications' | 'ai' | 'i18n'): string {\n // 1. Use discovered routes if available\n if (this.discoveryInfo?.routes && (this.discoveryInfo.routes as any)[type]) {\n return (this.discoveryInfo.routes 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 storage: '/api/v1/storage',\n automation: '/api/v1/automation',\n packages: '/api/v1/packages',\n permissions: '/api/v1/auth', // Permission endpoints are under /api/v1/auth per spec\n realtime: '/api/v1/realtime',\n workflow: '/api/v1/workflow',\n views: '/api/v1/ui/views',\n notifications: '/api/v1/notifications',\n ai: '/api/v1/ai',\n i18n: '/api/v1/i18n',\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 CheckPermissionRequest,\n CheckPermissionResponse,\n GetObjectPermissionsResponse,\n GetEffectivePermissionsResponse,\n RealtimeConnectRequest,\n RealtimeConnectResponse,\n RealtimeSubscribeRequest,\n RealtimeSubscribeResponse,\n GetPresenceResponse,\n GetWorkflowConfigResponse,\n GetWorkflowStateResponse,\n WorkflowTransitionRequest,\n WorkflowTransitionResponse,\n WorkflowApproveRequest,\n WorkflowApproveResponse,\n WorkflowRejectRequest,\n WorkflowRejectResponse,\n ListViewsResponse,\n GetViewResponse,\n CreateViewResponse,\n UpdateViewResponse,\n DeleteViewResponse,\n RegisterDeviceRequest,\n RegisterDeviceResponse,\n ListNotificationsResponse,\n AiNlqRequest,\n AiNlqResponse,\n AiChatRequest,\n AiChatResponse,\n AiSuggestRequest,\n AiSuggestResponse,\n AiInsightsRequest,\n AiInsightsResponse,\n GetLocalesResponse,\n GetTranslationsResponse,\n GetFieldLabelsResponse,\n RegisterRequest,\n RefreshTokenRequest\n} from '@objectstack/spec/api';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\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 * BETWEEN filter: field BETWEEN min AND max\n */\n between<K extends keyof T>(field: K, min: T[K], max: T[K]): this {\n this.conditions.push(['and', [field as string, '>=', min], [field as string, '<=', max]] as FilterCondition);\n return this;\n }\n\n /**\n * CONTAINS filter: field contains value (case-insensitive LIKE %value%)\n */\n contains<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}%`]);\n return this;\n }\n\n /**\n * STARTS WITH filter: field starts with value (LIKE value%)\n */\n startsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `${value}%`]);\n return this;\n }\n\n /**\n * ENDS WITH filter: field ends with value (LIKE %value)\n */\n endsWith<K extends keyof T>(field: K, value: string): this {\n this.conditions.push([field as string, 'like', `%${value}`]);\n return this;\n }\n\n /**\n * EXISTS filter: field is not null (alias for isNotNull)\n */\n exists<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 * Expand (eager-load) a related object with an optional sub-query\n */\n expand(relation: string, subQuery?: Partial<QueryAST>): this {\n if (!this.query.expand) {\n this.query.expand = {};\n }\n (this.query.expand as Record<string, any>)[relation] = subQuery || {};\n return this;\n }\n\n /**\n * Add full-text search\n */\n search(query: string, options?: { fields?: string[]; fuzzy?: boolean }): this {\n (this.query as any).search = { query, ...options };\n return this;\n }\n\n /**\n * Set cursor for keyset pagination\n */\n cursor(cursor: Record<string, any>): this {\n (this.query as any).cursor = cursor;\n return this;\n }\n\n /**\n * Enable SELECT DISTINCT\n */\n distinct(): this {\n (this.query as any).distinct = true;\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,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/client",
3
- "version": "2.0.6",
3
+ "version": "3.0.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Official Client SDK for ObjectStack Protocol",
6
6
  "main": "dist/index.js",
@@ -13,20 +13,20 @@
13
13
  }
14
14
  },
15
15
  "dependencies": {
16
- "@objectstack/core": "2.0.6",
17
- "@objectstack/spec": "2.0.6"
16
+ "@objectstack/core": "3.0.0",
17
+ "@objectstack/spec": "3.0.0"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@hono/node-server": "^1.2.0",
21
21
  "msw": "^2.12.9",
22
22
  "typescript": "^5.0.0",
23
23
  "vitest": "^4.0.18",
24
- "@objectstack/hono": "2.0.6",
25
- "@objectstack/driver-memory": "2.0.6",
26
- "@objectstack/objectql": "2.0.6",
27
- "@objectstack/plugin-hono-server": "2.0.6",
28
- "@objectstack/plugin-msw": "2.0.6",
29
- "@objectstack/runtime": "2.0.6"
24
+ "@objectstack/driver-memory": "3.0.0",
25
+ "@objectstack/hono": "3.0.0",
26
+ "@objectstack/objectql": "3.0.0",
27
+ "@objectstack/plugin-hono-server": "3.0.0",
28
+ "@objectstack/plugin-msw": "3.0.0",
29
+ "@objectstack/runtime": "3.0.0"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup --config ../../tsup.config.ts",
package/src/index.ts CHANGED
@@ -104,12 +104,8 @@ export interface QueryOptions {
104
104
  }
105
105
 
106
106
  export interface PaginatedResult<T = any> {
107
- /** @deprecated Use `records` — aligned with FindDataResponseSchema */
108
- value?: T[];
109
107
  /** Spec-compliant: array of matching records */
110
108
  records: T[];
111
- /** @deprecated Use `total` — aligned with FindDataResponseSchema */
112
- count?: number;
113
109
  /** Total number of matching records (if requested) */
114
110
  total?: number;
115
111
  /** The object name */
@@ -229,7 +225,7 @@ export class ObjectStackClient {
229
225
  this.logger.info('Connected to ObjectStack server', {
230
226
  version: data.version,
231
227
  apiName: data.apiName,
232
- capabilities: data.capabilities
228
+ services: data.services
233
229
  });
234
230
 
235
231
  return data as DiscoveryResult;
@@ -268,17 +264,6 @@ export class ObjectStackClient {
268
264
  return this.unwrapResponse<GetMetaItemsResponse>(res);
269
265
  },
270
266
 
271
- /**
272
- * Get a specific object definition by name
273
- * @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
274
- * @param name - Object name (snake_case identifier)
275
- */
276
- getObject: async (name: string) => {
277
- const route = this.getRoute('metadata');
278
- const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);
279
- return this.unwrapResponse(res);
280
- },
281
-
282
267
  /**
283
268
  * Get a specific metadata item by type and name
284
269
  * @param type - Metadata type (e.g., 'object', 'plugin')
@@ -1288,9 +1273,8 @@ export class ObjectStackClient {
1288
1273
  */
1289
1274
  private getRoute(type: 'data' | 'metadata' | 'ui' | 'auth' | 'analytics' | 'storage' | 'automation' | 'packages' | 'permissions' | 'realtime' | 'workflow' | 'views' | 'notifications' | 'ai' | 'i18n'): string {
1290
1275
  // 1. Use discovered routes if available
1291
- // Note: Spec uses 'endpoints', mapped dynamically
1292
- if (this.discoveryInfo?.endpoints && (this.discoveryInfo.endpoints as any)[type]) {
1293
- return (this.discoveryInfo.endpoints as any)[type];
1276
+ if (this.discoveryInfo?.routes && (this.discoveryInfo.routes as any)[type]) {
1277
+ return (this.discoveryInfo.routes as any)[type];
1294
1278
  }
1295
1279
 
1296
1280
  // 2. Fallback to conventions
@@ -24,8 +24,8 @@ describe('Discovery & Connection', () => {
24
24
 
25
25
  expect(discovery.version).toBeDefined();
26
26
  expect(discovery.apiName).toBeDefined();
27
- expect(discovery.capabilities).toBeDefined();
28
- expect(discovery.endpoints).toBeDefined();
27
+ expect(discovery.routes).toBeDefined();
28
+ expect(discovery.services).toBeDefined();
29
29
  });
30
30
  });
31
31