@airstore/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +341 -0
  2. package/dist/cjs/airstore.js +127 -0
  3. package/dist/cjs/airstore.js.map +1 -0
  4. package/dist/cjs/client.js +214 -0
  5. package/dist/cjs/client.js.map +1 -0
  6. package/dist/cjs/errors.js +129 -0
  7. package/dist/cjs/errors.js.map +1 -0
  8. package/dist/cjs/index.js +40 -0
  9. package/dist/cjs/index.js.map +1 -0
  10. package/dist/cjs/resources/connections.js +74 -0
  11. package/dist/cjs/resources/connections.js.map +1 -0
  12. package/dist/cjs/resources/filesystem.js +101 -0
  13. package/dist/cjs/resources/filesystem.js.map +1 -0
  14. package/dist/cjs/resources/index.js +18 -0
  15. package/dist/cjs/resources/index.js.map +1 -0
  16. package/dist/cjs/resources/members.js +63 -0
  17. package/dist/cjs/resources/members.js.map +1 -0
  18. package/dist/cjs/resources/oauth.js +85 -0
  19. package/dist/cjs/resources/oauth.js.map +1 -0
  20. package/dist/cjs/resources/smart-folders.js +102 -0
  21. package/dist/cjs/resources/smart-folders.js.map +1 -0
  22. package/dist/cjs/resources/tokens.js +73 -0
  23. package/dist/cjs/resources/tokens.js.map +1 -0
  24. package/dist/cjs/resources/workspaces.js +75 -0
  25. package/dist/cjs/resources/workspaces.js.map +1 -0
  26. package/dist/cjs/types/connections.js +3 -0
  27. package/dist/cjs/types/connections.js.map +1 -0
  28. package/dist/cjs/types/filesystem.js +3 -0
  29. package/dist/cjs/types/filesystem.js.map +1 -0
  30. package/dist/cjs/types/index.js +25 -0
  31. package/dist/cjs/types/index.js.map +1 -0
  32. package/dist/cjs/types/members.js +3 -0
  33. package/dist/cjs/types/members.js.map +1 -0
  34. package/dist/cjs/types/oauth.js +3 -0
  35. package/dist/cjs/types/oauth.js.map +1 -0
  36. package/dist/cjs/types/shared.js +3 -0
  37. package/dist/cjs/types/shared.js.map +1 -0
  38. package/dist/cjs/types/smart-folders.js +3 -0
  39. package/dist/cjs/types/smart-folders.js.map +1 -0
  40. package/dist/cjs/types/tokens.js +3 -0
  41. package/dist/cjs/types/tokens.js.map +1 -0
  42. package/dist/cjs/types/workspaces.js +3 -0
  43. package/dist/cjs/types/workspaces.js.map +1 -0
  44. package/dist/cjs/version.js +6 -0
  45. package/dist/cjs/version.js.map +1 -0
  46. package/dist/esm/airstore.js +123 -0
  47. package/dist/esm/airstore.js.map +1 -0
  48. package/dist/esm/client.js +209 -0
  49. package/dist/esm/client.js.map +1 -0
  50. package/dist/esm/errors.js +115 -0
  51. package/dist/esm/errors.js.map +1 -0
  52. package/dist/esm/index.js +16 -0
  53. package/dist/esm/index.js.map +1 -0
  54. package/dist/esm/resources/connections.js +70 -0
  55. package/dist/esm/resources/connections.js.map +1 -0
  56. package/dist/esm/resources/filesystem.js +97 -0
  57. package/dist/esm/resources/filesystem.js.map +1 -0
  58. package/dist/esm/resources/index.js +8 -0
  59. package/dist/esm/resources/index.js.map +1 -0
  60. package/dist/esm/resources/members.js +59 -0
  61. package/dist/esm/resources/members.js.map +1 -0
  62. package/dist/esm/resources/oauth.js +81 -0
  63. package/dist/esm/resources/oauth.js.map +1 -0
  64. package/dist/esm/resources/smart-folders.js +98 -0
  65. package/dist/esm/resources/smart-folders.js.map +1 -0
  66. package/dist/esm/resources/tokens.js +69 -0
  67. package/dist/esm/resources/tokens.js.map +1 -0
  68. package/dist/esm/resources/workspaces.js +71 -0
  69. package/dist/esm/resources/workspaces.js.map +1 -0
  70. package/dist/esm/types/connections.js +2 -0
  71. package/dist/esm/types/connections.js.map +1 -0
  72. package/dist/esm/types/filesystem.js +2 -0
  73. package/dist/esm/types/filesystem.js.map +1 -0
  74. package/dist/esm/types/index.js +9 -0
  75. package/dist/esm/types/index.js.map +1 -0
  76. package/dist/esm/types/members.js +2 -0
  77. package/dist/esm/types/members.js.map +1 -0
  78. package/dist/esm/types/oauth.js +2 -0
  79. package/dist/esm/types/oauth.js.map +1 -0
  80. package/dist/esm/types/shared.js +2 -0
  81. package/dist/esm/types/shared.js.map +1 -0
  82. package/dist/esm/types/smart-folders.js +2 -0
  83. package/dist/esm/types/smart-folders.js.map +1 -0
  84. package/dist/esm/types/tokens.js +2 -0
  85. package/dist/esm/types/tokens.js.map +1 -0
  86. package/dist/esm/types/workspaces.js +2 -0
  87. package/dist/esm/types/workspaces.js.map +1 -0
  88. package/dist/esm/version.js +3 -0
  89. package/dist/esm/version.js.map +1 -0
  90. package/dist/types/airstore.d.ts +114 -0
  91. package/dist/types/airstore.d.ts.map +1 -0
  92. package/dist/types/client.d.ts +86 -0
  93. package/dist/types/client.d.ts.map +1 -0
  94. package/dist/types/errors.d.ts +61 -0
  95. package/dist/types/errors.d.ts.map +1 -0
  96. package/dist/types/index.d.ts +21 -0
  97. package/dist/types/index.d.ts.map +1 -0
  98. package/dist/types/resources/connections.d.ts +50 -0
  99. package/dist/types/resources/connections.d.ts.map +1 -0
  100. package/dist/types/resources/filesystem.d.ts +81 -0
  101. package/dist/types/resources/filesystem.d.ts.map +1 -0
  102. package/dist/types/resources/index.d.ts +8 -0
  103. package/dist/types/resources/index.d.ts.map +1 -0
  104. package/dist/types/resources/members.d.ts +49 -0
  105. package/dist/types/resources/members.d.ts.map +1 -0
  106. package/dist/types/resources/oauth.d.ts +57 -0
  107. package/dist/types/resources/oauth.d.ts.map +1 -0
  108. package/dist/types/resources/smart-folders.d.ts +70 -0
  109. package/dist/types/resources/smart-folders.d.ts.map +1 -0
  110. package/dist/types/resources/tokens.d.ts +54 -0
  111. package/dist/types/resources/tokens.d.ts.map +1 -0
  112. package/dist/types/resources/workspaces.d.ts +63 -0
  113. package/dist/types/resources/workspaces.d.ts.map +1 -0
  114. package/dist/types/types/connections.d.ts +41 -0
  115. package/dist/types/types/connections.d.ts.map +1 -0
  116. package/dist/types/types/filesystem.d.ts +39 -0
  117. package/dist/types/types/filesystem.d.ts.map +1 -0
  118. package/dist/types/types/index.d.ts +9 -0
  119. package/dist/types/types/index.d.ts.map +1 -0
  120. package/dist/types/types/members.d.ts +30 -0
  121. package/dist/types/types/members.d.ts.map +1 -0
  122. package/dist/types/types/oauth.d.ts +40 -0
  123. package/dist/types/types/oauth.d.ts.map +1 -0
  124. package/dist/types/types/shared.d.ts +27 -0
  125. package/dist/types/types/shared.d.ts.map +1 -0
  126. package/dist/types/types/smart-folders.d.ts +45 -0
  127. package/dist/types/types/smart-folders.d.ts.map +1 -0
  128. package/dist/types/types/tokens.d.ts +40 -0
  129. package/dist/types/types/tokens.d.ts.map +1 -0
  130. package/dist/types/types/workspaces.d.ts +26 -0
  131. package/dist/types/types/workspaces.d.ts.map +1 -0
  132. package/dist/types/version.d.ts +3 -0
  133. package/dist/types/version.d.ts.map +1 -0
  134. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,341 @@
1
+ # @airstore/sdk
2
+
3
+ Official TypeScript SDK for the [Airstore](https://airstore.ai) API. Provision workspaces, manage connections, configure smart folders, and generate mount tokens — all from your backend.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @airstore/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import Airstore from '@airstore/sdk';
15
+
16
+ const airstore = new Airstore({
17
+ apiKey: 'org_...', // or set AIRSTORE_API_KEY env var
18
+ });
19
+
20
+ const workspace = await airstore.workspaces.create({ name: 'user-123' });
21
+ console.log(workspace.external_id);
22
+ ```
23
+
24
+ ## Full Provisioning Flow
25
+
26
+ This is the typical flow when a new user signs up on your platform:
27
+
28
+ ```typescript
29
+ import Airstore from '@airstore/sdk';
30
+
31
+ const airstore = new Airstore({ apiKey: process.env.AIRSTORE_API_KEY });
32
+
33
+ async function provisionUser(
34
+ userId: string,
35
+ gmailTokens: { accessToken: string; refreshToken: string },
36
+ ) {
37
+ // 1. Create a workspace
38
+ const ws = await airstore.workspaces.create({ name: `user-${userId}` });
39
+
40
+ // 2. Add a member (so we can create a scoped token)
41
+ const member = await airstore.members.create(ws.external_id, {
42
+ email: `${userId}@internal`,
43
+ name: userId,
44
+ role: 'member',
45
+ });
46
+
47
+ // 3. Connect Gmail with existing OAuth tokens
48
+ await airstore.connections.create(ws.external_id, {
49
+ integrationType: 'gmail',
50
+ accessToken: gmailTokens.accessToken,
51
+ refreshToken: gmailTokens.refreshToken,
52
+ });
53
+
54
+ // 4. Set up smart folders for what the agent should see
55
+ await airstore.smartFolders.create(ws.external_id, {
56
+ integration: 'gmail',
57
+ name: 'Recent Emails',
58
+ guidance: 'Last 7 days of emails from the inbox',
59
+ outputFormat: 'folder',
60
+ });
61
+
62
+ // 5. Generate a mount token for the user's VM
63
+ const token = await airstore.tokens.create(ws.external_id, {
64
+ email: `${userId}@internal`,
65
+ name: 'vm-mount',
66
+ });
67
+
68
+ // 6. Pass this to the VM:
69
+ // airstore start --token <token.token>
70
+ return {
71
+ workspaceId: ws.external_id,
72
+ mountToken: token.token,
73
+ };
74
+ }
75
+ ```
76
+
77
+ ## Configuration
78
+
79
+ ```typescript
80
+ const airstore = new Airstore({
81
+ // Required — org token or cluster admin token
82
+ apiKey: 'org_...',
83
+
84
+ // Override the base URL (default: https://api.airstore.ai/api/v1)
85
+ baseURL: 'https://api.airstore.ai/api/v1',
86
+
87
+ // Request timeout in ms (default: 60000)
88
+ timeout: 30_000,
89
+
90
+ // Max retries for 429/5xx errors (default: 2)
91
+ maxRetries: 3,
92
+
93
+ // Default headers for every request
94
+ defaultHeaders: { 'X-Custom-Header': 'value' },
95
+ });
96
+ ```
97
+
98
+ ### Environment Variables
99
+
100
+ | Variable | Description |
101
+ |---|---|
102
+ | `AIRSTORE_API_KEY` | Default API key if not passed to constructor |
103
+ | `AIRSTORE_BASE_URL` | Default base URL if not passed to constructor |
104
+
105
+ ## API Reference
106
+
107
+ ### Workspaces
108
+
109
+ ```typescript
110
+ // Create
111
+ const ws = await airstore.workspaces.create({ name: 'my-workspace' });
112
+
113
+ // List all (org tokens only see their tenant's workspaces)
114
+ const workspaces = await airstore.workspaces.list();
115
+
116
+ // Retrieve by ID
117
+ const ws = await airstore.workspaces.retrieve('ws_abc123');
118
+
119
+ // Delete
120
+ await airstore.workspaces.del('ws_abc123');
121
+ ```
122
+
123
+ ### Connections
124
+
125
+ ```typescript
126
+ // Create with existing OAuth tokens
127
+ const conn = await airstore.connections.create('ws_abc123', {
128
+ integrationType: 'gmail',
129
+ accessToken: '...',
130
+ refreshToken: '...',
131
+ });
132
+
133
+ // Create with API key
134
+ const conn = await airstore.connections.create('ws_abc123', {
135
+ integrationType: 'github',
136
+ apiKey: 'ghp_...',
137
+ });
138
+
139
+ // List
140
+ const connections = await airstore.connections.list('ws_abc123');
141
+
142
+ // Delete
143
+ await airstore.connections.del('ws_abc123', 'conn_abc123');
144
+ ```
145
+
146
+ ### Smart Folders
147
+
148
+ ```typescript
149
+ // Create
150
+ const folder = await airstore.smartFolders.create('ws_abc123', {
151
+ integration: 'gmail',
152
+ name: 'Important Emails',
153
+ guidance: 'Emails marked as important from the last month',
154
+ outputFormat: 'folder', // or 'file'
155
+ });
156
+
157
+ // List all
158
+ const folders = await airstore.smartFolders.list('ws_abc123');
159
+
160
+ // Retrieve by path
161
+ const folder = await airstore.smartFolders.retrieve('ws_abc123', '/Sources/gmail/Important Emails');
162
+
163
+ // Update
164
+ const updated = await airstore.smartFolders.update('ws_abc123', 'query_abc', {
165
+ guidance: 'Updated guidance text',
166
+ });
167
+
168
+ // Delete
169
+ await airstore.smartFolders.del('ws_abc123', 'query_abc');
170
+ ```
171
+
172
+ ### Tokens
173
+
174
+ ```typescript
175
+ // Create a workspace-scoped token (for CLI mounting)
176
+ const token = await airstore.tokens.create('ws_abc123', {
177
+ email: 'agent@internal',
178
+ name: 'vm-mount',
179
+ expiresIn: 86400, // optional, seconds
180
+ });
181
+ console.log(token.token); // raw value — only shown once
182
+
183
+ // List tokens (values are never returned)
184
+ const tokens = await airstore.tokens.list('ws_abc123');
185
+
186
+ // Revoke
187
+ await airstore.tokens.revoke('ws_abc123', 'tok_abc123');
188
+ ```
189
+
190
+ ### Members
191
+
192
+ ```typescript
193
+ // Add a member
194
+ const member = await airstore.members.create('ws_abc123', {
195
+ email: 'user@example.com',
196
+ name: 'Jane Doe',
197
+ role: 'member', // 'admin' | 'member' | 'viewer'
198
+ });
199
+
200
+ // List
201
+ const members = await airstore.members.list('ws_abc123');
202
+
203
+ // Remove
204
+ await airstore.members.del('ws_abc123', 'mem_abc123');
205
+ ```
206
+
207
+ ### OAuth Sessions
208
+
209
+ For interactive connection setup where users authorize via browser redirect:
210
+
211
+ ```typescript
212
+ // Create an OAuth session
213
+ const session = await airstore.oauth.createSession({
214
+ integrationType: 'gmail',
215
+ returnTo: 'https://myapp.com/callback',
216
+ });
217
+ console.log(session.authorize_url); // redirect user here
218
+
219
+ // Check status
220
+ const status = await airstore.oauth.getSession(session.session_id);
221
+
222
+ // Or poll until completion (default: 5 min timeout, 2s interval)
223
+ const completed = await airstore.oauth.poll(session.session_id, {
224
+ timeout: 120_000,
225
+ interval: 3_000,
226
+ });
227
+ console.log(completed.connection_id);
228
+ ```
229
+
230
+ ### Filesystem
231
+
232
+ Read-only access to the virtual filesystem:
233
+
234
+ ```typescript
235
+ // List directory contents
236
+ const entries = await airstore.fs.list('ws_abc123', { path: '/' });
237
+
238
+ // Read file contents
239
+ const content = await airstore.fs.read('ws_abc123', {
240
+ path: '/Sources/gmail/inbox/email.txt',
241
+ });
242
+
243
+ // Get directory tree
244
+ const tree = await airstore.fs.tree('ws_abc123', {
245
+ path: '/',
246
+ maxKeys: 100,
247
+ });
248
+
249
+ // Stat a file
250
+ const meta = await airstore.fs.stat('ws_abc123', '/Sources/gmail/inbox/email.txt');
251
+ ```
252
+
253
+ ## Per-Request Options
254
+
255
+ Every method accepts an optional last argument for per-request overrides:
256
+
257
+ ```typescript
258
+ const ws = await airstore.workspaces.list({
259
+ timeout: 10_000,
260
+ maxRetries: 5,
261
+ signal: controller.signal,
262
+ headers: { 'X-Trace-Id': 'abc' },
263
+ });
264
+ ```
265
+
266
+ ## Error Handling
267
+
268
+ The SDK throws typed errors for easy programmatic handling:
269
+
270
+ ```typescript
271
+ import {
272
+ AuthenticationError,
273
+ NotFoundError,
274
+ RateLimitError,
275
+ } from '@airstore/sdk';
276
+
277
+ try {
278
+ await airstore.workspaces.retrieve('ws_nonexistent');
279
+ } catch (err) {
280
+ if (err instanceof NotFoundError) {
281
+ console.log('Workspace not found');
282
+ } else if (err instanceof AuthenticationError) {
283
+ console.log('Invalid API key');
284
+ } else if (err instanceof RateLimitError) {
285
+ console.log('Rate limited, retry after:', err.headers.get('retry-after'));
286
+ }
287
+ }
288
+ ```
289
+
290
+ ### Error Hierarchy
291
+
292
+ | Class | Status | Description |
293
+ |---|---|---|
294
+ | `AirstoreError` | — | Base error for all SDK errors |
295
+ | `APIError` | varies | Base for HTTP errors |
296
+ | `AuthenticationError` | 401 | Invalid or missing API key |
297
+ | `PermissionDeniedError` | 403 | Token lacks permission |
298
+ | `NotFoundError` | 404 | Resource not found |
299
+ | `ConflictError` | 409 | Conflicting operation |
300
+ | `UnprocessableEntityError` | 422 | Validation failed |
301
+ | `RateLimitError` | 429 | Rate limit exceeded |
302
+ | `InternalServerError` | 5xx | Server error (retried automatically) |
303
+ | `APIConnectionError` | — | Network failure |
304
+ | `APIConnectionTimeoutError` | — | Request timed out |
305
+
306
+ ## Response Metadata
307
+
308
+ Every response object includes a non-enumerable `lastResponse` property:
309
+
310
+ ```typescript
311
+ const ws = await airstore.workspaces.create({ name: 'test' });
312
+ console.log(ws.lastResponse.statusCode); // 200
313
+ console.log(ws.lastResponse.requestId); // 'req_abc123'
314
+ console.log(ws.lastResponse.headers); // Headers object
315
+ ```
316
+
317
+ ## Automatic Retries
318
+
319
+ The SDK automatically retries on transient errors (408, 409, 429, 500, 502, 503, 504) with exponential backoff and jitter. The `Retry-After` header is respected when present.
320
+
321
+ ## Raw Requests
322
+
323
+ For endpoints not yet covered by the SDK, use the escape hatch:
324
+
325
+ ```typescript
326
+ const response = await airstore.rawRequest('POST', '/some/new/endpoint', {
327
+ body: { key: 'value' },
328
+ timeout: 5_000,
329
+ });
330
+ const data = await response.json();
331
+ ```
332
+
333
+ ## Requirements
334
+
335
+ - Node.js 18+ (uses native `fetch`)
336
+ - TypeScript 5.0+ (for type-only imports)
337
+ - Zero runtime dependencies
338
+
339
+ ## License
340
+
341
+ Apache-2.0
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Airstore = void 0;
4
+ const client_js_1 = require("./client.js");
5
+ const workspaces_js_1 = require("./resources/workspaces.js");
6
+ const connections_js_1 = require("./resources/connections.js");
7
+ const smart_folders_js_1 = require("./resources/smart-folders.js");
8
+ const tokens_js_1 = require("./resources/tokens.js");
9
+ const members_js_1 = require("./resources/members.js");
10
+ const oauth_js_1 = require("./resources/oauth.js");
11
+ const filesystem_js_1 = require("./resources/filesystem.js");
12
+ /**
13
+ * The Airstore SDK client.
14
+ *
15
+ * Create an instance with your API key to interact with workspaces,
16
+ * connections, smart folders, tokens, members, the virtual filesystem,
17
+ * and OAuth sessions.
18
+ *
19
+ * @example Basic provisioning flow
20
+ * ```ts
21
+ * import Airstore from '@airstore/sdk';
22
+ *
23
+ * const airstore = new Airstore({ apiKey: 'org_...' });
24
+ *
25
+ * // 1. Create a workspace for a new user
26
+ * const ws = await airstore.workspaces.create({ name: 'user-123' });
27
+ *
28
+ * // 2. Connect their Gmail with existing OAuth tokens
29
+ * await airstore.connections.create(ws.external_id, {
30
+ * integrationType: 'gmail',
31
+ * accessToken: existingAccessToken,
32
+ * refreshToken: existingRefreshToken,
33
+ * });
34
+ *
35
+ * // 3. Set up a smart folder
36
+ * await airstore.smartFolders.create(ws.external_id, {
37
+ * integration: 'gmail',
38
+ * name: 'Recent Emails',
39
+ * guidance: 'Last 7 days of emails from the inbox',
40
+ * });
41
+ *
42
+ * // 4. Generate a mount token for the user's VM
43
+ * const token = await airstore.tokens.create(ws.external_id, {
44
+ * email: 'agent@internal',
45
+ * name: 'vm-mount',
46
+ * });
47
+ * // Pass token.token to: airstore start --token <token>
48
+ * ```
49
+ *
50
+ * @example Per-request options
51
+ * ```ts
52
+ * const ws = await airstore.workspaces.list({
53
+ * timeout: 10_000,
54
+ * maxRetries: 5,
55
+ * });
56
+ * ```
57
+ */
58
+ class Airstore extends client_js_1.CoreClient {
59
+ /**
60
+ * Manage workspaces.
61
+ *
62
+ * Workspaces are the top-level container for connections, smart folders,
63
+ * members, and the virtual filesystem.
64
+ */
65
+ workspaces;
66
+ /**
67
+ * Manage connections (integrations) within a workspace.
68
+ *
69
+ * Pass existing OAuth tokens or API keys to connect external services
70
+ * like Gmail, GitHub, Notion, etc.
71
+ */
72
+ connections;
73
+ /**
74
+ * Manage smart folders (filesystem queries).
75
+ *
76
+ * Smart folders use LLM inference to automatically organize and filter
77
+ * data from connected integrations into virtual folders or files.
78
+ */
79
+ smartFolders;
80
+ /**
81
+ * Manage workspace-scoped authentication tokens.
82
+ *
83
+ * Tokens are used for CLI mounting and per-workspace programmatic access.
84
+ */
85
+ tokens;
86
+ /**
87
+ * Manage workspace members.
88
+ *
89
+ * Members are users with roles (admin, member, viewer) in a workspace.
90
+ */
91
+ members;
92
+ /**
93
+ * OAuth session management for interactive connection setup.
94
+ *
95
+ * Use this for browser-redirect flows where users authorize
96
+ * integrations themselves.
97
+ */
98
+ oauth;
99
+ /**
100
+ * Read-only access to the workspace virtual filesystem.
101
+ *
102
+ * Browse directories, read files, and inspect metadata across
103
+ * all connected integrations.
104
+ */
105
+ fs;
106
+ /**
107
+ * Create a new Airstore SDK client.
108
+ *
109
+ * @param opts - Client configuration. At minimum, provide an `apiKey`
110
+ * or set the `AIRSTORE_API_KEY` environment variable.
111
+ *
112
+ * @throws {AirstoreError} If no API key is provided.
113
+ */
114
+ constructor(opts) {
115
+ super(opts);
116
+ this.workspaces = new workspaces_js_1.Workspaces(this);
117
+ this.connections = new connections_js_1.Connections(this);
118
+ this.smartFolders = new smart_folders_js_1.SmartFolders(this);
119
+ this.tokens = new tokens_js_1.Tokens(this);
120
+ this.members = new members_js_1.Members(this);
121
+ this.oauth = new oauth_js_1.OAuth(this);
122
+ this.fs = new filesystem_js_1.Filesystem(this);
123
+ }
124
+ }
125
+ exports.Airstore = Airstore;
126
+ exports.default = Airstore;
127
+ //# sourceMappingURL=airstore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airstore.js","sourceRoot":"","sources":["../../src/airstore.ts"],"names":[],"mappings":";;;AAAA,2CAA6D;AAC7D,6DAAuD;AACvD,+DAAyD;AACzD,mEAA4D;AAC5D,qDAA+C;AAC/C,uDAAiD;AACjD,mDAA6C;AAC7C,6DAAuD;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAa,QAAS,SAAQ,sBAAU;IACtC;;;;;OAKG;IACM,UAAU,CAAa;IAEhC;;;;;OAKG;IACM,WAAW,CAAc;IAElC;;;;;OAKG;IACM,YAAY,CAAe;IAEpC;;;;OAIG;IACM,MAAM,CAAS;IAExB;;;;OAIG;IACM,OAAO,CAAU;IAE1B;;;;;OAKG;IACM,KAAK,CAAQ;IAEtB;;;;;OAKG;IACM,EAAE,CAAa;IAExB;;;;;;;OAOG;IACH,YAAY,IAAoB;QAC9B,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,UAAU,GAAG,IAAI,0BAAU,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,IAAI,4BAAW,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,+BAAY,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,oBAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,GAAG,IAAI,0BAAU,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;CACF;AAzED,4BAyEC;AAED,kBAAe,QAAQ,CAAC"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CoreClient = void 0;
4
+ exports.attachResponseMeta = attachResponseMeta;
5
+ const version_js_1 = require("./version.js");
6
+ const errors_js_1 = require("./errors.js");
7
+ function attachResponseMeta(obj, meta) {
8
+ Object.defineProperty(obj, 'lastResponse', {
9
+ value: meta,
10
+ enumerable: false,
11
+ configurable: true,
12
+ });
13
+ return obj;
14
+ }
15
+ /** Retryable status codes. */
16
+ const RETRYABLE_STATUS_CODES = new Set([408, 409, 429, 500, 502, 503, 504]);
17
+ /** Base backoff in ms. */
18
+ const BASE_BACKOFF_MS = 500;
19
+ /** Max backoff in ms. */
20
+ const MAX_BACKOFF_MS = 8000;
21
+ /**
22
+ * Core HTTP client for the Airstore API.
23
+ *
24
+ * Handles authentication, automatic retries with exponential backoff,
25
+ * timeout, and per-request option overrides.
26
+ */
27
+ class CoreClient {
28
+ apiKey;
29
+ baseURL;
30
+ timeout;
31
+ maxRetries;
32
+ defaultHeaders;
33
+ constructor(opts = {}) {
34
+ this.apiKey =
35
+ opts.apiKey ??
36
+ (typeof process !== 'undefined' ? process.env?.['AIRSTORE_API_KEY'] ?? '' : '');
37
+ if (!this.apiKey) {
38
+ throw new errors_js_1.AirstoreError('API key is required. Pass it via the `apiKey` option or set the AIRSTORE_API_KEY environment variable.');
39
+ }
40
+ const envBaseURL = typeof process !== 'undefined'
41
+ ? (process.env?.['AIRSTORE_BASE_URL'] ?? '')
42
+ : '';
43
+ this.baseURL = (opts.baseURL ?? (envBaseURL || 'https://api.airstore.ai/api/v1')).replace(/\/+$/, '');
44
+ this.timeout = opts.timeout ?? 60_000;
45
+ this.maxRetries = opts.maxRetries ?? 2;
46
+ this.defaultHeaders = opts.defaultHeaders ?? {};
47
+ }
48
+ /** Make an API request with retry and timeout. */
49
+ async request(method, path, body, params, reqOpts) {
50
+ const url = this._buildURL(path, params);
51
+ const timeout = reqOpts?.timeout ?? this.timeout;
52
+ const maxRetries = reqOpts?.maxRetries ?? this.maxRetries;
53
+ const headers = this._buildHeaders(reqOpts?.headers);
54
+ let lastError;
55
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
56
+ if (attempt > 0) {
57
+ await this._sleep(this._backoffMs(attempt, lastError));
58
+ }
59
+ const controller = new AbortController();
60
+ if (reqOpts?.signal) {
61
+ reqOpts.signal.addEventListener('abort', () => controller.abort(), { once: true });
62
+ }
63
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
64
+ try {
65
+ const fetchOpts = {
66
+ method,
67
+ headers,
68
+ signal: controller.signal,
69
+ };
70
+ if (body !== undefined && method !== 'GET' && method !== 'HEAD') {
71
+ fetchOpts.body = JSON.stringify(body);
72
+ }
73
+ const response = await fetch(url, fetchOpts);
74
+ clearTimeout(timeoutId);
75
+ const meta = {
76
+ statusCode: response.status,
77
+ headers: response.headers,
78
+ requestId: response.headers.get('x-request-id') ??
79
+ response.headers.get('X-Request-Id') ??
80
+ undefined,
81
+ };
82
+ if (response.ok) {
83
+ const data = (await response.json());
84
+ // Airstore API wraps responses in { success, data }
85
+ const result = (data.data ?? data);
86
+ return attachResponseMeta(result, meta);
87
+ }
88
+ // Non-retryable error
89
+ if (!RETRYABLE_STATUS_CODES.has(response.status) || attempt === maxRetries) {
90
+ let errorMessage = `Request failed with status ${response.status}`;
91
+ try {
92
+ const errBody = await response.json();
93
+ errorMessage = errBody?.error ?? errBody?.message ?? errorMessage;
94
+ }
95
+ catch {
96
+ // ignore parse errors
97
+ }
98
+ throw errors_js_1.APIError.generate(response.status, null, errorMessage, response.headers);
99
+ }
100
+ // Retryable — store error and continue
101
+ lastError = errors_js_1.APIError.generate(response.status, null, `Retryable error (${response.status})`, response.headers);
102
+ }
103
+ catch (err) {
104
+ clearTimeout(timeoutId);
105
+ if (err instanceof errors_js_1.APIError) {
106
+ if (!RETRYABLE_STATUS_CODES.has(err.status) || attempt === maxRetries) {
107
+ throw err;
108
+ }
109
+ lastError = err;
110
+ continue;
111
+ }
112
+ if (err instanceof DOMException && err.name === 'AbortError') {
113
+ if (reqOpts?.signal?.aborted) {
114
+ throw new errors_js_1.AirstoreError('Request was cancelled');
115
+ }
116
+ throw new errors_js_1.APIConnectionTimeoutError();
117
+ }
118
+ if (attempt === maxRetries) {
119
+ throw new errors_js_1.APIConnectionError(`Connection error: ${err instanceof Error ? err.message : String(err)}`, err);
120
+ }
121
+ lastError = err;
122
+ }
123
+ }
124
+ throw lastError ?? new errors_js_1.AirstoreError('Request failed after retries');
125
+ }
126
+ /**
127
+ * Build full URL with query params.
128
+ *
129
+ * Uses string concatenation to preserve the base path prefix (e.g. `/api/v1`).
130
+ * `new URL(path, base)` would resolve absolute paths against the origin,
131
+ * dropping the base path — so we avoid it.
132
+ */
133
+ _buildURL(path, params) {
134
+ const suffix = path.startsWith('/') ? path : `/${path}`;
135
+ const url = new URL(`${this.baseURL}${suffix}`);
136
+ if (params) {
137
+ for (const [key, value] of Object.entries(params)) {
138
+ if (value !== undefined && value !== '') {
139
+ url.searchParams.set(key, value);
140
+ }
141
+ }
142
+ }
143
+ return url.toString();
144
+ }
145
+ /** Build request headers. */
146
+ _buildHeaders(extra) {
147
+ return {
148
+ 'Content-Type': 'application/json',
149
+ Authorization: `Bearer ${this.apiKey}`,
150
+ 'User-Agent': `airstore-sdk-typescript/${version_js_1.VERSION}`,
151
+ ...this.defaultHeaders,
152
+ ...extra,
153
+ };
154
+ }
155
+ /** Calculate backoff with jitter. */
156
+ _backoffMs(attempt, lastError) {
157
+ // Respect Retry-After headers if present.
158
+ // retry-after-ms is already in milliseconds; retry-after is in seconds.
159
+ if (lastError instanceof errors_js_1.APIError) {
160
+ const retryAfterMs = lastError.headers.get('retry-after-ms');
161
+ if (retryAfterMs) {
162
+ const ms = Number(retryAfterMs);
163
+ if (!isNaN(ms))
164
+ return ms;
165
+ }
166
+ const retryAfter = lastError.headers.get('retry-after');
167
+ if (retryAfter) {
168
+ const seconds = Number(retryAfter);
169
+ if (!isNaN(seconds))
170
+ return seconds * 1000;
171
+ }
172
+ }
173
+ const base = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
174
+ const jitter = Math.random() * base * 0.5;
175
+ return Math.min(base + jitter, MAX_BACKOFF_MS);
176
+ }
177
+ /** Sleep helper. */
178
+ _sleep(ms) {
179
+ return new Promise((resolve) => setTimeout(resolve, ms));
180
+ }
181
+ /**
182
+ * Make a raw HTTP request to any API path.
183
+ * Escape hatch for endpoints not yet covered by the SDK.
184
+ */
185
+ async rawRequest(method, path, opts) {
186
+ const url = this._buildURL(path, opts?.params);
187
+ const headers = this._buildHeaders(opts?.headers);
188
+ const controller = new AbortController();
189
+ if (opts?.signal) {
190
+ opts.signal.addEventListener('abort', () => controller.abort(), { once: true });
191
+ }
192
+ const timeoutMs = opts?.timeout ?? this.timeout;
193
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
194
+ try {
195
+ const fetchOpts = {
196
+ method,
197
+ headers,
198
+ signal: controller.signal,
199
+ };
200
+ if (opts?.body !== undefined) {
201
+ fetchOpts.body = JSON.stringify(opts.body);
202
+ }
203
+ const resp = await fetch(url, fetchOpts);
204
+ clearTimeout(timeoutId);
205
+ return resp;
206
+ }
207
+ catch (err) {
208
+ clearTimeout(timeoutId);
209
+ throw new errors_js_1.APIConnectionError(`Raw request failed: ${err instanceof Error ? err.message : String(err)}`, err);
210
+ }
211
+ }
212
+ }
213
+ exports.CoreClient = CoreClient;
214
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}