@aerostack/core 0.7.6 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Product, Cart, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
1
+ import { Product, Cart, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category, CacheListResult, CacheSetEntry, StorageListResult, JobRecord } from './types';
2
2
  /** @deprecated Use AerostackConfig instead. */
3
3
  export interface AerocallConfig {
4
4
  baseUrl?: string;
@@ -15,9 +15,21 @@ export declare class AerocallClient implements AerostackRPC {
15
15
  private jwt?;
16
16
  private projectId?;
17
17
  constructor(config: AerocallConfig);
18
+ private getHeaders;
18
19
  private request;
19
20
  get db(): {
20
21
  query: <T = any>(sql: string, params?: any[]) => Promise<T[]>;
22
+ batch: (queries: Array<{
23
+ sql: string;
24
+ params?: any[];
25
+ }>) => Promise<{
26
+ results: Array<{
27
+ results: any[];
28
+ success: boolean;
29
+ error?: string;
30
+ }>;
31
+ success: boolean;
32
+ }>;
21
33
  };
22
34
  get cache(): {
23
35
  get: <T = any>(key: string) => Promise<{
@@ -30,12 +42,62 @@ export declare class AerocallClient implements AerostackRPC {
30
42
  delete: (key: string) => Promise<{
31
43
  success: boolean;
32
44
  }>;
45
+ list: (prefix?: string, options?: {
46
+ limit?: number;
47
+ cursor?: string;
48
+ }) => Promise<CacheListResult>;
49
+ keys: (prefix?: string) => Promise<string[]>;
50
+ getMany: <T = any>(keys: string[]) => Promise<{
51
+ key: string;
52
+ value: T | null;
53
+ exists: boolean;
54
+ }[]>;
55
+ setMany: (entries: CacheSetEntry[]) => Promise<{
56
+ success: boolean;
57
+ count: number;
58
+ }>;
59
+ deleteMany: (keys: string[]) => Promise<{
60
+ success: boolean;
61
+ count: number;
62
+ deleted: number;
63
+ }>;
64
+ flush: (prefix?: string) => Promise<{
65
+ success: boolean;
66
+ deleted: number;
67
+ }>;
68
+ expire: (key: string, ttl: number) => Promise<{
69
+ success: boolean;
70
+ }>;
71
+ increment: (key: string, amount?: number, options?: {
72
+ initialValue?: number;
73
+ ttl?: number;
74
+ }) => Promise<{
75
+ value: number;
76
+ }>;
33
77
  };
34
78
  get queue(): {
35
79
  enqueue: (type: string, data: any) => Promise<{
36
80
  success: boolean;
37
81
  jobId: string;
38
82
  }>;
83
+ getJob: (jobId: string) => Promise<{
84
+ job: JobRecord | null;
85
+ exists: boolean;
86
+ }>;
87
+ listJobs: (options?: {
88
+ status?: string;
89
+ type?: string;
90
+ limit?: number;
91
+ cursor?: string;
92
+ }) => Promise<{
93
+ jobs: JobRecord[];
94
+ list_complete: boolean;
95
+ cursor?: string;
96
+ }>;
97
+ cancelJob: (jobId: string) => Promise<{
98
+ success: boolean;
99
+ note?: string;
100
+ }>;
39
101
  };
40
102
  get ai(): {
41
103
  chat: (messages: {
@@ -69,12 +131,57 @@ export declare class AerocallClient implements AerostackRPC {
69
131
  }) => Promise<{
70
132
  success: boolean;
71
133
  }>;
134
+ update: (id: string, content: string, options?: {
135
+ type?: string;
136
+ metadata?: Record<string, any>;
137
+ }) => Promise<{
138
+ success: boolean;
139
+ }>;
140
+ get: (id: string) => Promise<{
141
+ result: any | null;
142
+ exists: boolean;
143
+ }>;
144
+ count: (type?: string) => Promise<{
145
+ count: number;
146
+ }>;
72
147
  };
73
148
  };
74
149
  get storage(): {
75
150
  upload: (key: string, file: File | Blob, contentType?: string) => Promise<{
76
151
  url: string;
77
152
  }>;
153
+ get: (key: string) => Promise<{
154
+ data: Response | null;
155
+ exists: boolean;
156
+ }>;
157
+ getUrl: (key: string) => Promise<{
158
+ url: string;
159
+ }>;
160
+ list: (prefix?: string, options?: {
161
+ limit?: number;
162
+ cursor?: string;
163
+ }) => Promise<StorageListResult>;
164
+ delete: (key: string) => Promise<{
165
+ success: boolean;
166
+ }>;
167
+ exists: (key: string) => Promise<{
168
+ exists: boolean;
169
+ }>;
170
+ getMetadata: (key: string) => Promise<{
171
+ exists: boolean;
172
+ size?: number;
173
+ contentType?: string;
174
+ lastModified?: Date;
175
+ etag?: string;
176
+ }>;
177
+ copy: (sourceKey: string, destKey: string) => Promise<{
178
+ success: boolean;
179
+ url: string;
180
+ }>;
181
+ move: (sourceKey: string, destKey: string) => Promise<{
182
+ success: boolean;
183
+ url: string;
184
+ }>;
78
185
  };
79
186
  get services(): {
80
187
  invoke: <T = any>(serviceName: string, data?: any) => Promise<{
package/dist/client.js CHANGED
@@ -9,13 +9,10 @@ class AerocallClient {
9
9
  this.jwt = config.jwt;
10
10
  this.projectId = config.projectId;
11
11
  }
12
- async request(path, method, body, isMultipart = false) {
13
- const headers = {
14
- 'X-SDK-Version': '0.4.0'
15
- };
16
- if (!isMultipart) {
12
+ getHeaders(isMultipart = false) {
13
+ const headers = { 'X-SDK-Version': '0.5.0' };
14
+ if (!isMultipart)
17
15
  headers['Content-Type'] = 'application/json';
18
- }
19
16
  if (this.apiKey)
20
17
  headers['X-API-Key'] = this.apiKey;
21
18
  if (this.jwt)
@@ -23,9 +20,12 @@ class AerocallClient {
23
20
  if (this.projectId)
24
21
  headers['X-Project-Id'] = this.projectId;
25
22
  headers['X-Request-ID'] = crypto.randomUUID();
23
+ return headers;
24
+ }
25
+ async request(path, method, body, isMultipart = false) {
26
26
  const response = await fetch(`${this.baseUrl}${path}`, {
27
27
  method,
28
- headers,
28
+ headers: this.getHeaders(isMultipart),
29
29
  body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
30
30
  });
31
31
  if (!response.ok) {
@@ -39,19 +39,32 @@ class AerocallClient {
39
39
  query: async (sql, params) => {
40
40
  const res = await this.request('/db/query', 'POST', { sql, params });
41
41
  return (res?.results ?? []);
42
- }
42
+ },
43
+ batch: (queries) => this.request('/db/batch', 'POST', { queries }),
43
44
  };
44
45
  }
45
46
  get cache() {
46
47
  return {
47
48
  get: (key) => this.request('/cache/get', 'POST', { key }),
48
49
  set: (key, value, ttl) => this.request('/cache/set', 'POST', { key, value, ttl }),
49
- delete: (key) => this.request('/cache/delete', 'POST', { key })
50
+ delete: (key) => this.request('/cache/delete', 'POST', { key }),
51
+ list: (prefix, options) => this.request('/cache/list', 'POST', { prefix, ...options }),
52
+ keys: (prefix) => this.request('/cache/keys', 'POST', { prefix })
53
+ .then(r => r.keys),
54
+ getMany: (keys) => this.request('/cache/getMany', 'POST', { keys }).then(r => r.results),
55
+ setMany: (entries) => this.request('/cache/setMany', 'POST', { entries }),
56
+ deleteMany: (keys) => this.request('/cache/deleteMany', 'POST', { keys }),
57
+ flush: (prefix) => this.request('/cache/flush', 'POST', { prefix }),
58
+ expire: (key, ttl) => this.request('/cache/expire', 'POST', { key, ttl }),
59
+ increment: (key, amount, options) => this.request('/cache/increment', 'POST', { key, amount, ...options }),
50
60
  };
51
61
  }
52
62
  get queue() {
53
63
  return {
54
- enqueue: (type, data) => this.request('/queue/enqueue', 'POST', { type, data })
64
+ enqueue: (type, data) => this.request('/queue/enqueue', 'POST', { type, data }),
65
+ getJob: (jobId) => this.request('/queue/job', 'POST', { jobId }),
66
+ listJobs: (options) => this.request('/queue/jobs', 'POST', options ?? {}),
67
+ cancelJob: (jobId) => this.request('/queue/cancel', 'POST', { jobId }),
55
68
  };
56
69
  }
57
70
  get ai() {
@@ -63,7 +76,10 @@ class AerocallClient {
63
76
  delete: (id) => this.request('/ai/search/delete', 'POST', { id }),
64
77
  deleteByType: (type) => this.request('/ai/search/deleteByType', 'POST', { type }),
65
78
  listTypes: () => this.request('/ai/search/listTypes', 'GET'),
66
- configure: (options) => this.request('/ai/search/configure', 'POST', options)
79
+ configure: (options) => this.request('/ai/search/configure', 'POST', options),
80
+ update: (id, content, options) => this.request('/ai/search/update', 'POST', { id, content, ...options }),
81
+ get: (id) => this.request('/ai/search/get', 'POST', { id }),
82
+ count: (type) => this.request('/ai/search/count', 'POST', { type }),
67
83
  }
68
84
  };
69
85
  }
@@ -76,7 +92,29 @@ class AerocallClient {
76
92
  if (contentType)
77
93
  formData.append('contentType', contentType);
78
94
  return this.request('/storage/upload', 'POST', formData, true);
79
- }
95
+ },
96
+ // get() returns binary — must bypass request() which calls .json()
97
+ get: async (key) => {
98
+ const response = await fetch(`${this.baseUrl}/storage/get`, {
99
+ method: 'POST',
100
+ headers: this.getHeaders(),
101
+ body: JSON.stringify({ key }),
102
+ });
103
+ if (response.status === 404)
104
+ return { data: null, exists: false };
105
+ if (!response.ok) {
106
+ const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
107
+ throw new Error(err.error?.message || 'Storage get failed');
108
+ }
109
+ return { data: response, exists: true };
110
+ },
111
+ getUrl: (key) => this.request('/storage/getUrl', 'POST', { key }),
112
+ list: (prefix, options) => this.request('/storage/list', 'POST', { prefix, ...options }),
113
+ delete: (key) => this.request('/storage/delete', 'POST', { key }),
114
+ exists: (key) => this.request('/storage/exists', 'POST', { key }),
115
+ getMetadata: (key) => this.request('/storage/getMetadata', 'POST', { key }),
116
+ copy: (sourceKey, destKey) => this.request('/storage/copy', 'POST', { sourceKey, destKey }),
117
+ move: (sourceKey, destKey) => this.request('/storage/move', 'POST', { sourceKey, destKey }),
80
118
  };
81
119
  }
82
120
  get services() {
package/dist/types.d.ts CHANGED
@@ -109,9 +109,54 @@ export interface Customer {
109
109
  phone?: string | null;
110
110
  created_at: number;
111
111
  }
112
+ export interface CacheKeyEntry {
113
+ key: string;
114
+ expiration?: number;
115
+ }
116
+ export interface CacheListResult {
117
+ keys: CacheKeyEntry[];
118
+ list_complete: boolean;
119
+ cursor?: string;
120
+ }
121
+ export interface CacheSetEntry {
122
+ key: string;
123
+ value: any;
124
+ ttl?: number;
125
+ }
126
+ export interface StorageObject {
127
+ key: string;
128
+ size: number;
129
+ lastModified: Date;
130
+ contentType?: string;
131
+ etag?: string;
132
+ }
133
+ export interface StorageListResult {
134
+ objects: StorageObject[];
135
+ truncated: boolean;
136
+ cursor?: string;
137
+ }
138
+ export interface JobRecord {
139
+ id: string;
140
+ type: string;
141
+ data: any;
142
+ status: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled';
143
+ projectId: string;
144
+ createdAt: string;
145
+ }
112
146
  export interface AerostackRPC {
113
147
  db: {
114
148
  query<T = any>(sql: string, params?: any[]): Promise<T[]>;
149
+ batch(queries: Array<{
150
+ sql: string;
151
+ params?: any[];
152
+ }>): Promise<{
153
+ results: Array<{
154
+ results: any[];
155
+ success: boolean;
156
+ error?: string;
157
+ }>;
158
+ success: boolean;
159
+ }>;
115
160
  };
116
161
  cache: {
117
162
  get<T = any>(key: string): Promise<{
@@ -124,12 +169,62 @@ export interface AerostackRPC {
124
169
  delete(key: string): Promise<{
125
170
  success: boolean;
126
171
  }>;
172
+ list(prefix?: string, options?: {
173
+ limit?: number;
174
+ cursor?: string;
175
+ }): Promise<CacheListResult>;
176
+ keys(prefix?: string): Promise<string[]>;
177
+ getMany<T = any>(keys: string[]): Promise<Array<{
178
+ key: string;
179
+ value: T | null;
180
+ exists: boolean;
181
+ }>>;
182
+ setMany(entries: CacheSetEntry[]): Promise<{
183
+ success: boolean;
184
+ count: number;
185
+ }>;
186
+ deleteMany(keys: string[]): Promise<{
187
+ success: boolean;
188
+ count: number;
189
+ deleted: number;
190
+ }>;
191
+ flush(prefix?: string): Promise<{
192
+ success: boolean;
193
+ deleted: number;
194
+ }>;
195
+ expire(key: string, ttl: number): Promise<{
196
+ success: boolean;
197
+ }>;
198
+ increment(key: string, amount?: number, options?: {
199
+ initialValue?: number;
200
+ ttl?: number;
201
+ }): Promise<{
202
+ value: number;
203
+ }>;
127
204
  };
128
205
  queue: {
129
206
  enqueue(type: string, data: any): Promise<{
130
207
  success: boolean;
131
208
  jobId: string;
132
209
  }>;
210
+ getJob(jobId: string): Promise<{
211
+ job: JobRecord | null;
212
+ exists: boolean;
213
+ }>;
214
+ listJobs(options?: {
215
+ status?: string;
216
+ type?: string;
217
+ limit?: number;
218
+ cursor?: string;
219
+ }): Promise<{
220
+ jobs: JobRecord[];
221
+ list_complete: boolean;
222
+ cursor?: string;
223
+ }>;
224
+ cancelJob(jobId: string): Promise<{
225
+ success: boolean;
226
+ note?: string;
227
+ }>;
133
228
  };
134
229
  ai: {
135
230
  chat(messages: Array<{
@@ -163,12 +258,57 @@ export interface AerostackRPC {
163
258
  }): Promise<{
164
259
  success: boolean;
165
260
  }>;
261
+ update(id: string, content: string, options?: {
262
+ type?: string;
263
+ metadata?: Record<string, any>;
264
+ }): Promise<{
265
+ success: boolean;
266
+ }>;
267
+ get(id: string): Promise<{
268
+ result: any | null;
269
+ exists: boolean;
270
+ }>;
271
+ count(type?: string): Promise<{
272
+ count: number;
273
+ }>;
166
274
  };
167
275
  };
168
276
  storage: {
169
277
  upload(key: string, file: any, contentType?: string): Promise<{
170
278
  url: string;
171
279
  }>;
280
+ get(key: string): Promise<{
281
+ data: Response | null;
282
+ exists: boolean;
283
+ }>;
284
+ getUrl(key: string): Promise<{
285
+ url: string;
286
+ }>;
287
+ list(prefix?: string, options?: {
288
+ limit?: number;
289
+ cursor?: string;
290
+ }): Promise<StorageListResult>;
291
+ delete(key: string): Promise<{
292
+ success: boolean;
293
+ }>;
294
+ exists(key: string): Promise<{
295
+ exists: boolean;
296
+ }>;
297
+ getMetadata(key: string): Promise<{
298
+ exists: boolean;
299
+ size?: number;
300
+ contentType?: string;
301
+ lastModified?: Date;
302
+ etag?: string;
303
+ }>;
304
+ copy(sourceKey: string, destKey: string): Promise<{
305
+ success: boolean;
306
+ url: string;
307
+ }>;
308
+ move(sourceKey: string, destKey: string): Promise<{
309
+ success: boolean;
310
+ url: string;
311
+ }>;
172
312
  };
173
313
  services: {
174
314
  invoke<T = any>(serviceName: string, data?: any): Promise<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerostack/core",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "Shared types and RPC client for Aerostack SDKs",
5
5
  "sideEffects": false,
6
6
  "main": "dist/index.js",
package/src/client.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Product, Order, Cart, Customer, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category } from './types';
1
+ import { Product, Order, Cart, Customer, AerostackRPC, CollectionItem, StoreConfig, ProductVariant, Category, CacheListResult, CacheSetEntry, StorageListResult, JobRecord } from './types';
2
2
 
3
3
  /** @deprecated Use AerostackConfig instead. */
4
4
  export interface AerocallConfig {
@@ -24,22 +24,20 @@ export class AerocallClient implements AerostackRPC {
24
24
  this.projectId = config.projectId;
25
25
  }
26
26
 
27
- private async request<T>(path: string, method: string, body?: any, isMultipart = false): Promise<T> {
28
- const headers: Record<string, string> = {
29
- 'X-SDK-Version': '0.4.0'
30
- };
31
- if (!isMultipart) {
32
- headers['Content-Type'] = 'application/json';
33
- }
27
+ private getHeaders(isMultipart = false): Record<string, string> {
28
+ const headers: Record<string, string> = { 'X-SDK-Version': '0.5.0' };
29
+ if (!isMultipart) headers['Content-Type'] = 'application/json';
34
30
  if (this.apiKey) headers['X-API-Key'] = this.apiKey;
35
31
  if (this.jwt) headers['Authorization'] = `Bearer ${this.jwt}`;
36
32
  if (this.projectId) headers['X-Project-Id'] = this.projectId;
37
-
38
33
  headers['X-Request-ID'] = crypto.randomUUID();
34
+ return headers;
35
+ }
39
36
 
37
+ private async request<T>(path: string, method: string, body?: any, isMultipart = false): Promise<T> {
40
38
  const response = await fetch(`${this.baseUrl}${path}`, {
41
39
  method,
42
- headers,
40
+ headers: this.getHeaders(isMultipart),
43
41
  body: isMultipart ? body : (body ? JSON.stringify(body) : undefined)
44
42
  });
45
43
 
@@ -55,21 +53,54 @@ export class AerocallClient implements AerostackRPC {
55
53
  query: async <T = any>(sql: string, params?: any[]) => {
56
54
  const res = await this.request<{ results: T[]; meta?: any }>('/db/query', 'POST', { sql, params });
57
55
  return (res?.results ?? []) as T[];
58
- }
56
+ },
57
+ batch: (queries: Array<{ sql: string; params?: any[] }>) =>
58
+ this.request<{ results: Array<{ results: any[]; success: boolean; error?: string }>; success: boolean }>(
59
+ '/db/batch', 'POST', { queries }
60
+ ),
59
61
  };
60
62
  }
61
63
 
62
64
  public get cache() {
63
65
  return {
64
- get: <T = any>(key: string) => this.request<{ value: T | null, exists: boolean }>('/cache/get', 'POST', { key }),
65
- set: (key: string, value: any, ttl?: number) => this.request<{ success: boolean }>('/cache/set', 'POST', { key, value, ttl }),
66
- delete: (key: string) => this.request<{ success: boolean }>('/cache/delete', 'POST', { key })
66
+ get: <T = any>(key: string) =>
67
+ this.request<{ value: T | null; exists: boolean }>('/cache/get', 'POST', { key }),
68
+ set: (key: string, value: any, ttl?: number) =>
69
+ this.request<{ success: boolean }>('/cache/set', 'POST', { key, value, ttl }),
70
+ delete: (key: string) =>
71
+ this.request<{ success: boolean }>('/cache/delete', 'POST', { key }),
72
+ list: (prefix?: string, options?: { limit?: number; cursor?: string }) =>
73
+ this.request<CacheListResult>('/cache/list', 'POST', { prefix, ...options }),
74
+ keys: (prefix?: string) =>
75
+ this.request<{ keys: string[]; truncated: boolean }>('/cache/keys', 'POST', { prefix })
76
+ .then(r => r.keys),
77
+ getMany: <T = any>(keys: string[]) =>
78
+ this.request<{ results: Array<{ key: string; value: T | null; exists: boolean }> }>(
79
+ '/cache/getMany', 'POST', { keys }
80
+ ).then(r => r.results),
81
+ setMany: (entries: CacheSetEntry[]) =>
82
+ this.request<{ success: boolean; count: number }>('/cache/setMany', 'POST', { entries }),
83
+ deleteMany: (keys: string[]) =>
84
+ this.request<{ success: boolean; count: number; deleted: number }>('/cache/deleteMany', 'POST', { keys }),
85
+ flush: (prefix?: string) =>
86
+ this.request<{ success: boolean; deleted: number }>('/cache/flush', 'POST', { prefix }),
87
+ expire: (key: string, ttl: number) =>
88
+ this.request<{ success: boolean }>('/cache/expire', 'POST', { key, ttl }),
89
+ increment: (key: string, amount?: number, options?: { initialValue?: number; ttl?: number }) =>
90
+ this.request<{ value: number }>('/cache/increment', 'POST', { key, amount, ...options }),
67
91
  };
68
92
  }
69
93
 
70
94
  public get queue() {
71
95
  return {
72
- enqueue: (type: string, data: any) => this.request<{ success: boolean; jobId: string }>('/queue/enqueue', 'POST', { type, data })
96
+ enqueue: (type: string, data: any) =>
97
+ this.request<{ success: boolean; jobId: string }>('/queue/enqueue', 'POST', { type, data }),
98
+ getJob: (jobId: string) =>
99
+ this.request<{ job: JobRecord | null; exists: boolean }>('/queue/job', 'POST', { jobId }),
100
+ listJobs: (options?: { status?: string; type?: string; limit?: number; cursor?: string }) =>
101
+ this.request<{ jobs: JobRecord[]; list_complete: boolean; cursor?: string }>('/queue/jobs', 'POST', options ?? {}),
102
+ cancelJob: (jobId: string) =>
103
+ this.request<{ success: boolean; note?: string }>('/queue/cancel', 'POST', { jobId }),
73
104
  };
74
105
  }
75
106
 
@@ -82,10 +113,20 @@ export class AerocallClient implements AerostackRPC {
82
113
  this.request<{ success: boolean }>('/ai/search/ingest', 'POST', { content, metadata, type }),
83
114
  query: (text: string, options?: { limit?: number; threshold?: number; filter?: Record<string, any> }) =>
84
115
  this.request<{ results: any[] }>('/ai/search/query', 'POST', { text, ...options }),
85
- delete: (id: string) => this.request<{ success: boolean }>('/ai/search/delete', 'POST', { id }),
86
- deleteByType: (type: string) => this.request<{ success: boolean }>('/ai/search/deleteByType', 'POST', { type }),
87
- listTypes: () => this.request<{ types: string[] }>('/ai/search/listTypes', 'GET'),
88
- configure: (options: { embeddingModel: string }) => this.request<{ success: boolean }>('/ai/search/configure', 'POST', options)
116
+ delete: (id: string) =>
117
+ this.request<{ success: boolean }>('/ai/search/delete', 'POST', { id }),
118
+ deleteByType: (type: string) =>
119
+ this.request<{ success: boolean }>('/ai/search/deleteByType', 'POST', { type }),
120
+ listTypes: () =>
121
+ this.request<{ types: string[] }>('/ai/search/listTypes', 'GET'),
122
+ configure: (options: { embeddingModel: string }) =>
123
+ this.request<{ success: boolean }>('/ai/search/configure', 'POST', options),
124
+ update: (id: string, content: string, options?: { type?: string; metadata?: Record<string, any> }) =>
125
+ this.request<{ success: boolean }>('/ai/search/update', 'POST', { id, content, ...options }),
126
+ get: (id: string) =>
127
+ this.request<{ result: any | null; exists: boolean }>('/ai/search/get', 'POST', { id }),
128
+ count: (type?: string) =>
129
+ this.request<{ count: number }>('/ai/search/count', 'POST', { type }),
89
130
  }
90
131
  };
91
132
  }
@@ -98,7 +139,37 @@ export class AerocallClient implements AerostackRPC {
98
139
  formData.append('file', file);
99
140
  if (contentType) formData.append('contentType', contentType);
100
141
  return this.request<{ url: string }>('/storage/upload', 'POST', formData, true);
101
- }
142
+ },
143
+ // get() returns binary — must bypass request() which calls .json()
144
+ get: async (key: string): Promise<{ data: Response | null; exists: boolean }> => {
145
+ const response = await fetch(`${this.baseUrl}/storage/get`, {
146
+ method: 'POST',
147
+ headers: this.getHeaders(),
148
+ body: JSON.stringify({ key }),
149
+ });
150
+ if (response.status === 404) return { data: null, exists: false };
151
+ if (!response.ok) {
152
+ const err = await response.json().catch(() => ({ error: { message: response.statusText } }));
153
+ throw new Error((err as any).error?.message || 'Storage get failed');
154
+ }
155
+ return { data: response, exists: true };
156
+ },
157
+ getUrl: (key: string) =>
158
+ this.request<{ url: string }>('/storage/getUrl', 'POST', { key }),
159
+ list: (prefix?: string, options?: { limit?: number; cursor?: string }) =>
160
+ this.request<StorageListResult>('/storage/list', 'POST', { prefix, ...options }),
161
+ delete: (key: string) =>
162
+ this.request<{ success: boolean }>('/storage/delete', 'POST', { key }),
163
+ exists: (key: string) =>
164
+ this.request<{ exists: boolean }>('/storage/exists', 'POST', { key }),
165
+ getMetadata: (key: string) =>
166
+ this.request<{ exists: boolean; size?: number; contentType?: string; lastModified?: Date; etag?: string }>(
167
+ '/storage/getMetadata', 'POST', { key }
168
+ ),
169
+ copy: (sourceKey: string, destKey: string) =>
170
+ this.request<{ success: boolean; url: string }>('/storage/copy', 'POST', { sourceKey, destKey }),
171
+ move: (sourceKey: string, destKey: string) =>
172
+ this.request<{ success: boolean; url: string }>('/storage/move', 'POST', { sourceKey, destKey }),
102
173
  };
103
174
  }
104
175
 
package/src/types.ts CHANGED
@@ -119,17 +119,74 @@ export interface Customer {
119
119
  created_at: number;
120
120
  }
121
121
 
122
+ // --- Enterprise module types ---
123
+
124
+ export interface CacheKeyEntry {
125
+ key: string;
126
+ expiration?: number; // Unix timestamp when this key expires
127
+ }
128
+
129
+ export interface CacheListResult {
130
+ keys: CacheKeyEntry[];
131
+ list_complete: boolean;
132
+ cursor?: string;
133
+ }
134
+
135
+ export interface CacheSetEntry {
136
+ key: string;
137
+ value: any;
138
+ ttl?: number;
139
+ }
140
+
141
+ export interface StorageObject {
142
+ key: string; // User-facing key (project prefix stripped)
143
+ size: number;
144
+ lastModified: Date;
145
+ contentType?: string;
146
+ etag?: string;
147
+ }
148
+
149
+ export interface StorageListResult {
150
+ objects: StorageObject[];
151
+ truncated: boolean;
152
+ cursor?: string;
153
+ }
154
+
155
+ export interface JobRecord {
156
+ id: string;
157
+ type: string;
158
+ data: any;
159
+ status: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled';
160
+ projectId: string;
161
+ createdAt: string;
162
+ }
163
+
122
164
  export interface AerostackRPC {
123
165
  db: {
124
166
  query<T = any>(sql: string, params?: any[]): Promise<T[]>;
167
+ batch(queries: Array<{ sql: string; params?: any[] }>): Promise<{
168
+ results: Array<{ results: any[]; success: boolean; error?: string }>;
169
+ success: boolean;
170
+ }>;
125
171
  };
126
172
  cache: {
127
173
  get<T = any>(key: string): Promise<{ value: T | null; exists: boolean }>;
128
174
  set(key: string, value: any, ttl?: number): Promise<{ success: boolean }>;
129
175
  delete(key: string): Promise<{ success: boolean }>;
176
+ list(prefix?: string, options?: { limit?: number; cursor?: string }): Promise<CacheListResult>;
177
+ keys(prefix?: string): Promise<string[]>;
178
+ getMany<T = any>(keys: string[]): Promise<Array<{ key: string; value: T | null; exists: boolean }>>;
179
+ setMany(entries: CacheSetEntry[]): Promise<{ success: boolean; count: number }>;
180
+ deleteMany(keys: string[]): Promise<{ success: boolean; count: number; deleted: number }>;
181
+ flush(prefix?: string): Promise<{ success: boolean; deleted: number }>;
182
+ expire(key: string, ttl: number): Promise<{ success: boolean }>;
183
+ increment(key: string, amount?: number, options?: { initialValue?: number; ttl?: number }): Promise<{ value: number }>;
130
184
  };
131
185
  queue: {
132
186
  enqueue(type: string, data: any): Promise<{ success: boolean; jobId: string }>;
187
+ getJob(jobId: string): Promise<{ job: JobRecord | null; exists: boolean }>;
188
+ listJobs(options?: { status?: string; type?: string; limit?: number; cursor?: string }): Promise<{ jobs: JobRecord[]; list_complete: boolean; cursor?: string }>;
189
+ cancelJob(jobId: string): Promise<{ success: boolean; note?: string }>;
133
190
  };
134
191
  ai: {
135
192
  chat(messages: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>, model?: string): Promise<{ response: string }>;
@@ -140,10 +197,21 @@ export interface AerostackRPC {
140
197
  deleteByType(type: string): Promise<{ success: boolean }>;
141
198
  listTypes(): Promise<{ types: string[] }>;
142
199
  configure(options: { embeddingModel: string }): Promise<{ success: boolean }>;
200
+ update(id: string, content: string, options?: { type?: string; metadata?: Record<string, any> }): Promise<{ success: boolean }>;
201
+ get(id: string): Promise<{ result: any | null; exists: boolean }>;
202
+ count(type?: string): Promise<{ count: number }>;
143
203
  };
144
204
  };
145
205
  storage: {
146
206
  upload(key: string, file: any, contentType?: string): Promise<{ url: string }>;
207
+ get(key: string): Promise<{ data: Response | null; exists: boolean }>;
208
+ getUrl(key: string): Promise<{ url: string }>;
209
+ list(prefix?: string, options?: { limit?: number; cursor?: string }): Promise<StorageListResult>;
210
+ delete(key: string): Promise<{ success: boolean }>;
211
+ exists(key: string): Promise<{ exists: boolean }>;
212
+ getMetadata(key: string): Promise<{ exists: boolean; size?: number; contentType?: string; lastModified?: Date; etag?: string }>;
213
+ copy(sourceKey: string, destKey: string): Promise<{ success: boolean; url: string }>;
214
+ move(sourceKey: string, destKey: string): Promise<{ success: boolean; url: string }>;
147
215
  };
148
216
  services: {
149
217
  invoke<T = any>(serviceName: string, data?: any): Promise<{ success: true; result: T }>;