oblien 1.3.0 → 2.0.1

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 (187) hide show
  1. package/README.md +482 -422
  2. package/dist/client.d.ts +31 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +33 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/error.d.ts +29 -0
  7. package/dist/error.d.ts.map +1 -0
  8. package/dist/error.js +52 -0
  9. package/dist/error.js.map +1 -0
  10. package/dist/http.d.ts +20 -0
  11. package/dist/http.d.ts.map +1 -0
  12. package/dist/http.js +108 -0
  13. package/dist/http.js.map +1 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +10 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/resources/api-access.d.ts +21 -0
  19. package/dist/resources/api-access.d.ts.map +1 -0
  20. package/dist/resources/api-access.js +32 -0
  21. package/dist/resources/api-access.js.map +1 -0
  22. package/dist/resources/base.d.ts +17 -0
  23. package/dist/resources/base.d.ts.map +1 -0
  24. package/dist/resources/base.js +21 -0
  25. package/dist/resources/base.js.map +1 -0
  26. package/dist/resources/images.d.ts +11 -0
  27. package/dist/resources/images.d.ts.map +1 -0
  28. package/dist/resources/images.js +16 -0
  29. package/dist/resources/images.js.map +1 -0
  30. package/dist/resources/lifecycle.d.ts +23 -0
  31. package/dist/resources/lifecycle.d.ts.map +1 -0
  32. package/dist/resources/lifecycle.js +32 -0
  33. package/dist/resources/lifecycle.js.map +1 -0
  34. package/dist/resources/logs.d.ts +25 -0
  35. package/dist/resources/logs.d.ts.map +1 -0
  36. package/dist/resources/logs.js +51 -0
  37. package/dist/resources/logs.js.map +1 -0
  38. package/dist/resources/metadata.d.ts +15 -0
  39. package/dist/resources/metadata.d.ts.map +1 -0
  40. package/dist/resources/metadata.js +20 -0
  41. package/dist/resources/metadata.js.map +1 -0
  42. package/dist/resources/metrics.d.ts +17 -0
  43. package/dist/resources/metrics.d.ts.map +1 -0
  44. package/dist/resources/metrics.js +27 -0
  45. package/dist/resources/metrics.js.map +1 -0
  46. package/dist/resources/network.d.ts +17 -0
  47. package/dist/resources/network.d.ts.map +1 -0
  48. package/dist/resources/network.js +20 -0
  49. package/dist/resources/network.js.map +1 -0
  50. package/dist/resources/public-access.d.ts +15 -0
  51. package/dist/resources/public-access.d.ts.map +1 -0
  52. package/dist/resources/public-access.js +21 -0
  53. package/dist/resources/public-access.js.map +1 -0
  54. package/dist/resources/resources.d.ts +15 -0
  55. package/dist/resources/resources.d.ts.map +1 -0
  56. package/dist/resources/resources.js +20 -0
  57. package/dist/resources/resources.js.map +1 -0
  58. package/dist/resources/snapshots.d.ts +27 -0
  59. package/dist/resources/snapshots.d.ts.map +1 -0
  60. package/dist/resources/snapshots.js +45 -0
  61. package/dist/resources/snapshots.js.map +1 -0
  62. package/dist/resources/ssh.d.ts +19 -0
  63. package/dist/resources/ssh.d.ts.map +1 -0
  64. package/dist/resources/ssh.js +28 -0
  65. package/dist/resources/ssh.js.map +1 -0
  66. package/dist/resources/usage.d.ts +25 -0
  67. package/dist/resources/usage.d.ts.map +1 -0
  68. package/dist/resources/usage.js +44 -0
  69. package/dist/resources/usage.js.map +1 -0
  70. package/dist/resources/workloads.d.ts +39 -0
  71. package/dist/resources/workloads.d.ts.map +1 -0
  72. package/dist/resources/workloads.js +83 -0
  73. package/dist/resources/workloads.js.map +1 -0
  74. package/dist/runtime/exec.d.ts +71 -0
  75. package/dist/runtime/exec.d.ts.map +1 -0
  76. package/dist/runtime/exec.js +163 -0
  77. package/dist/runtime/exec.js.map +1 -0
  78. package/dist/runtime/files.d.ts +39 -0
  79. package/dist/runtime/files.d.ts.map +1 -0
  80. package/dist/runtime/files.js +143 -0
  81. package/dist/runtime/files.js.map +1 -0
  82. package/dist/runtime/search.d.ts +23 -0
  83. package/dist/runtime/search.d.ts.map +1 -0
  84. package/dist/runtime/search.js +65 -0
  85. package/dist/runtime/search.js.map +1 -0
  86. package/dist/runtime/terminal.d.ts +29 -0
  87. package/dist/runtime/terminal.d.ts.map +1 -0
  88. package/dist/runtime/terminal.js +58 -0
  89. package/dist/runtime/terminal.js.map +1 -0
  90. package/dist/runtime/watcher.d.ts +27 -0
  91. package/dist/runtime/watcher.d.ts.map +1 -0
  92. package/dist/runtime/watcher.js +53 -0
  93. package/dist/runtime/watcher.js.map +1 -0
  94. package/dist/runtime/ws.d.ts +92 -0
  95. package/dist/runtime/ws.d.ts.map +1 -0
  96. package/dist/runtime/ws.js +228 -0
  97. package/dist/runtime/ws.js.map +1 -0
  98. package/dist/runtime-http.d.ts +35 -0
  99. package/dist/runtime-http.d.ts.map +1 -0
  100. package/dist/runtime-http.js +99 -0
  101. package/dist/runtime-http.js.map +1 -0
  102. package/dist/runtime.d.ts +77 -0
  103. package/dist/runtime.d.ts.map +1 -0
  104. package/dist/runtime.js +97 -0
  105. package/dist/runtime.js.map +1 -0
  106. package/dist/types/client.d.ts +7 -0
  107. package/dist/types/client.d.ts.map +1 -0
  108. package/dist/types/client.js +3 -0
  109. package/dist/types/client.js.map +1 -0
  110. package/dist/types/common.d.ts +13 -0
  111. package/dist/types/common.d.ts.map +1 -0
  112. package/dist/types/common.js +3 -0
  113. package/dist/types/common.js.map +1 -0
  114. package/dist/types/index.d.ts +8 -0
  115. package/dist/types/index.d.ts.map +1 -0
  116. package/dist/types/index.js +2 -0
  117. package/dist/types/index.js.map +1 -0
  118. package/dist/types/network.d.ts +15 -0
  119. package/dist/types/network.d.ts.map +1 -0
  120. package/dist/types/network.js +3 -0
  121. package/dist/types/network.js.map +1 -0
  122. package/dist/types/resources.d.ts +10 -0
  123. package/dist/types/resources.d.ts.map +1 -0
  124. package/dist/types/resources.js +3 -0
  125. package/dist/types/resources.js.map +1 -0
  126. package/dist/types/runtime.d.ts +302 -0
  127. package/dist/types/runtime.d.ts.map +1 -0
  128. package/dist/types/runtime.js +3 -0
  129. package/dist/types/runtime.js.map +1 -0
  130. package/dist/types/workspace-resources.d.ts +186 -0
  131. package/dist/types/workspace-resources.d.ts.map +1 -0
  132. package/dist/types/workspace-resources.js +3 -0
  133. package/dist/types/workspace-resources.js.map +1 -0
  134. package/dist/types/workspace.d.ts +41 -0
  135. package/dist/types/workspace.d.ts.map +1 -0
  136. package/dist/types/workspace.js +3 -0
  137. package/dist/types/workspace.js.map +1 -0
  138. package/dist/workspace.d.ts +135 -0
  139. package/dist/workspace.d.ts.map +1 -0
  140. package/dist/workspace.js +194 -0
  141. package/dist/workspace.js.map +1 -0
  142. package/package.json +30 -69
  143. package/LICENSE +0 -21
  144. package/agents.js +0 -14
  145. package/browser.js +0 -6
  146. package/cdn.js +0 -6
  147. package/chat.js +0 -21
  148. package/credits.js +0 -11
  149. package/icons.js +0 -11
  150. package/index.d.ts +0 -986
  151. package/index.js +0 -63
  152. package/namespaces.js +0 -12
  153. package/sandbox.js +0 -12
  154. package/search.js +0 -11
  155. package/src/agents/agent.js +0 -229
  156. package/src/agents/index.js +0 -227
  157. package/src/agents/settings.js +0 -100
  158. package/src/agents/tools.js +0 -155
  159. package/src/browser/index.js +0 -474
  160. package/src/cdn/index.js +0 -769
  161. package/src/chat/index.js +0 -724
  162. package/src/chat/session.js +0 -93
  163. package/src/client.js +0 -175
  164. package/src/credits/index.js +0 -492
  165. package/src/icons/index.js +0 -185
  166. package/src/namespaces/index.js +0 -236
  167. package/src/namespaces/namespace.js +0 -274
  168. package/src/sandbox/core/api/base.js +0 -89
  169. package/src/sandbox/core/api/database.js +0 -340
  170. package/src/sandbox/core/api/files.js +0 -141
  171. package/src/sandbox/core/api/git.js +0 -174
  172. package/src/sandbox/core/api/search.js +0 -29
  173. package/src/sandbox/core/api/snapshots.js +0 -132
  174. package/src/sandbox/core/api/terminal.js +0 -20
  175. package/src/sandbox/core/auth.js +0 -256
  176. package/src/sandbox/core/client.js +0 -197
  177. package/src/sandbox/core/index.js +0 -22
  178. package/src/sandbox/core/managers/terminal.js +0 -453
  179. package/src/sandbox/core/managers/watcher.js +0 -197
  180. package/src/sandbox/core/types.js +0 -92
  181. package/src/sandbox/core/utils/http.js +0 -89
  182. package/src/sandbox/core/websocket/connection.js +0 -479
  183. package/src/sandbox/index.d.ts +0 -542
  184. package/src/sandbox/index.js +0 -234
  185. package/src/sandbox/sandbox.js +0 -313
  186. package/src/search/index.js +0 -206
  187. package/src/utils/guest-manager.js +0 -454
package/src/cdn/index.js DELETED
@@ -1,769 +0,0 @@
1
- /**
2
- * Oblien CDN Module
3
- * Upload and manage files on Oblien CDN with automatic token management
4
- */
5
-
6
- import { OblienClient } from '../client.js';
7
-
8
- export class OblienCDN {
9
- /**
10
- * @param {import('../client.js').OblienClient|Object} clientOrConfig - Oblien client instance or config
11
- * @param {string} [clientOrConfig.clientId] - Client ID (if not using client instance)
12
- * @param {string} [clientOrConfig.clientSecret] - Client Secret (if not using client instance)
13
- * @param {string} [clientOrConfig.baseURL] - Base URL (optional)
14
- * @param {string} [clientOrConfig.cdnURL] - CDN URL (optional)
15
- * @param {Object} [config] - Additional config (if first param is client instance)
16
- * @param {string} [config.cdnURL] - CDN URL
17
- */
18
- constructor(clientOrConfig, config = {}) {
19
- if (!clientOrConfig) {
20
- throw new Error('Oblien client or credentials are required');
21
- }
22
-
23
- // If it's already a client instance
24
- if (clientOrConfig.clientId && clientOrConfig.clientSecret && typeof clientOrConfig.get === 'function') {
25
- this.client = clientOrConfig;
26
- this.cdnURL = config.cdnURL || 'https://cdn.oblien.com/api';
27
- }
28
- // If credentials provided, create client
29
- else if (clientOrConfig.clientId && clientOrConfig.clientSecret) {
30
- this.client = new OblienClient(clientOrConfig);
31
- this.cdnURL = clientOrConfig.cdnURL || 'https://cdn.oblien.com/api';
32
- }
33
- else {
34
- throw new Error('Either provide OblienClient instance or { clientId, clientSecret }');
35
- }
36
-
37
- // Token cache for reuse within expiration window
38
- this._tokenCache = {
39
- user: null,
40
- admin: null
41
- };
42
- }
43
-
44
- /**
45
- * Generate a user CDN token (upload/process permissions)
46
- * Tokens expire in 1 minute for security
47
- *
48
- * @returns {Promise<Object>} Token response with token, scope, and permissions
49
- *
50
- * @example
51
- * const tokenData = await cdn.generateUserToken();
52
- * // Returns:
53
- * // {
54
- * // success: true,
55
- * // token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
56
- * // scope: 'user',
57
- * // permissions: ['upload', 'process'],
58
- * // expiresIn: '1m'
59
- * // }
60
- */
61
- async generateUserToken() {
62
- const response = await this.client.post('cdn/token');
63
-
64
- // Cache token for reuse
65
- if (response.success && response.token) {
66
- this._tokenCache.user = {
67
- token: response.token,
68
- expiresAt: Date.now() + 50000 // 50 seconds (buffer before 1m expiry)
69
- };
70
- }
71
-
72
- return response;
73
- }
74
-
75
- /**
76
- * Generate an admin CDN token (full access permissions)
77
- * Requires admin privileges on the API account
78
- * Tokens expire in 1 minute for security
79
- *
80
- * @returns {Promise<Object>} Token response with token, scope, and permissions
81
- * @throws {Error} If user doesn't have admin privileges
82
- *
83
- * @example
84
- * const tokenData = await cdn.generateAdminToken();
85
- * // Returns:
86
- * // {
87
- * // success: true,
88
- * // token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
89
- * // scope: 'admin',
90
- * // permissions: ['upload', 'process', 'read', 'list', 'info', 'delete'],
91
- * // expiresIn: '1m'
92
- * // }
93
- */
94
- async generateAdminToken() {
95
- const response = await this.client.post('cdn/token/admin');
96
-
97
- // Cache token for reuse
98
- if (response.success && response.token) {
99
- this._tokenCache.admin = {
100
- token: response.token,
101
- expiresAt: Date.now() + 50000 // 50 seconds (buffer before 1m expiry)
102
- };
103
- }
104
-
105
- return response;
106
- }
107
-
108
- /**
109
- * Get a valid token (user or admin)
110
- * Automatically generates new token if cache is empty or expired
111
- * @private
112
- */
113
- async _getToken(scope = 'user') {
114
- const cached = this._tokenCache[scope];
115
-
116
- // Use cached token if still valid
117
- if (cached && cached.expiresAt > Date.now()) {
118
- return cached.token;
119
- }
120
-
121
- // Generate new token
122
- const tokenData = scope === 'admin'
123
- ? await this.generateAdminToken()
124
- : await this.generateUserToken();
125
-
126
- return tokenData.token;
127
- }
128
-
129
- /**
130
- * Normalize file input to buffer and filename
131
- * Supports: Buffer, Base64, Multer files, Stream
132
- * @private
133
- */
134
- _normalizeFile(file, providedFilename) {
135
- let buffer;
136
- let filename = providedFilename;
137
- let mimetype;
138
-
139
- // Handle Multer file object (from Express.js file uploads)
140
- if (file && file.buffer && file.originalname) {
141
- buffer = file.buffer;
142
- filename = filename || file.originalname;
143
- mimetype = file.mimetype;
144
- }
145
- // Handle Base64 string
146
- else if (typeof file === 'string') {
147
- // Check if it's a data URL (data:image/jpeg;base64,...)
148
- const base64Match = file.match(/^data:([^;]+);base64,(.+)$/);
149
- if (base64Match) {
150
- mimetype = base64Match[1];
151
- buffer = Buffer.from(base64Match[2], 'base64');
152
- // Extract extension from mimetype if no filename
153
- if (!filename) {
154
- const ext = mimetype.split('/')[1] || 'bin';
155
- filename = `file.${ext}`;
156
- }
157
- } else {
158
- // Plain base64 string
159
- buffer = Buffer.from(file, 'base64');
160
- filename = filename || 'file.bin';
161
- }
162
- }
163
- // Handle Buffer or Uint8Array
164
- else if (file instanceof Buffer || file instanceof Uint8Array) {
165
- buffer = file;
166
- filename = filename || 'file.bin';
167
- }
168
- // Handle Node.js ReadableStream
169
- else if (file && typeof file.pipe === 'function') {
170
- throw new Error('Streams are not directly supported. Please convert to Buffer first using stream.toArray() or similar.');
171
- }
172
- // Handle other types (File, Blob, etc.) - pass through
173
- else {
174
- return { file, filename: filename || 'file' };
175
- }
176
-
177
- return { buffer, filename, mimetype };
178
- }
179
-
180
- /**
181
- * Upload a single file to CDN
182
- * Automatically handles token generation if not provided
183
- * Supports: Buffer, Base64 strings, Multer file objects
184
- *
185
- * @param {Buffer|string|Object} file - File to upload
186
- * - Buffer: Raw file buffer
187
- * - string: Base64 encoded file or data URL (data:image/jpeg;base64,...)
188
- * - Object: Multer file object ({ buffer, originalname, mimetype })
189
- * @param {Object} options - Upload options
190
- * @param {string} options.token - CDN token (optional, will auto-generate if not provided)
191
- * @param {string} options.filename - Custom filename (optional)
192
- * @param {string} options.mimetype - File mimetype (optional)
193
- * @param {string} options.scope - Token scope to use: 'user' or 'admin' (default: 'user')
194
- * @returns {Promise<Object>} Upload result with file URL and metadata
195
- *
196
- * @example
197
- * // Upload from Buffer
198
- * const fs = require('fs');
199
- * const fileBuffer = fs.readFileSync('image.jpg');
200
- * const result = await cdn.upload(fileBuffer, { filename: 'image.jpg' });
201
- *
202
- * @example
203
- * // Upload from Base64
204
- * const base64 = 'data:image/jpeg;base64,/9j/4AAQSkZJRg...';
205
- * const result = await cdn.upload(base64, { filename: 'image.jpg' });
206
- *
207
- * @example
208
- * // Upload from Base64 (plain)
209
- * const base64 = '/9j/4AAQSkZJRg...';
210
- * const result = await cdn.upload(base64, { filename: 'image.jpg' });
211
- *
212
- * @example
213
- * // Upload from Multer (Express.js)
214
- * app.post('/upload', upload.single('file'), async (req, res) => {
215
- * const result = await cdn.upload(req.file);
216
- * res.json(result);
217
- * });
218
- *
219
- * // Returns:
220
- * // {
221
- * // success: true,
222
- * // file: {
223
- * // url: 'https://cdn.oblien.com/abc123/image.jpg',
224
- * // filename: 'image.jpg',
225
- * // size: 102400,
226
- * // mimetype: 'image/jpeg'
227
- * // }
228
- * // }
229
- */
230
- async upload(file, options = {}) {
231
- const { token, filename, mimetype, scope = 'user' } = options;
232
-
233
- // Get token (use provided or generate new one)
234
- const cdnToken = token || await this._getToken(scope);
235
-
236
- // Normalize file input
237
- const normalized = this._normalizeFile(file, filename);
238
-
239
- // Create FormData
240
- const FormData = globalThis.FormData || (await import('form-data')).default;
241
- const formData = new FormData();
242
-
243
- // Add file to form data
244
- if (normalized.buffer) {
245
- const Blob = globalThis.Blob || (await import('buffer')).Blob;
246
- const fileBlob = new Blob([normalized.buffer], {
247
- type: mimetype || normalized.mimetype || 'application/octet-stream'
248
- });
249
- formData.append('file', fileBlob, normalized.filename);
250
- } else {
251
- formData.append('file', normalized.file, normalized.filename);
252
- }
253
-
254
- // Upload to CDN
255
- const response = await fetch(`${this.cdnURL}/`, {
256
- method: 'POST',
257
- headers: {
258
- 'Authorization': `Bearer ${cdnToken}`
259
- },
260
- body: formData
261
- });
262
-
263
- if (!response.ok) {
264
- const error = await response.json().catch(() => ({}));
265
- throw new Error(error.message || `Upload failed: ${response.status}`);
266
- }
267
-
268
- return response.json();
269
- }
270
-
271
- /**
272
- * Upload multiple files to CDN
273
- * Automatically handles token generation if not provided
274
- * Supports: Buffers, Base64 strings, Multer file objects
275
- *
276
- * @param {Array<Buffer|string|Object>} files - Array of files to upload
277
- * - Buffer: Raw file buffers
278
- * - string: Base64 encoded files
279
- * - Object: Multer file objects
280
- * @param {Object} options - Upload options
281
- * @param {string} options.token - CDN token (optional, will auto-generate if not provided)
282
- * @param {Array<string>} options.filenames - Array of custom filenames (optional)
283
- * @param {string} options.scope - Token scope to use: 'user' or 'admin' (default: 'user')
284
- * @returns {Promise<Object>} Upload result with array of file URLs and metadata
285
- *
286
- * @example
287
- * // Upload multiple buffers
288
- * const files = [
289
- * fs.readFileSync('image1.jpg'),
290
- * fs.readFileSync('image2.jpg')
291
- * ];
292
- * const result = await cdn.uploadMultiple(files, {
293
- * filenames: ['image1.jpg', 'image2.jpg']
294
- * });
295
- *
296
- * @example
297
- * // Upload multiple base64 strings
298
- * const files = [
299
- * 'data:image/jpeg;base64,/9j/4AAQ...',
300
- * 'data:image/png;base64,iVBORw0KGgo...'
301
- * ];
302
- * const result = await cdn.uploadMultiple(files);
303
- *
304
- * @example
305
- * // Upload from Multer (Express.js)
306
- * app.post('/upload', upload.array('files'), async (req, res) => {
307
- * const result = await cdn.uploadMultiple(req.files);
308
- * res.json(result);
309
- * });
310
- *
311
- * // Returns:
312
- * // {
313
- * // success: true,
314
- * // files: [
315
- * // { url: 'https://cdn.oblien.com/abc123/image1.jpg', ... },
316
- * // { url: 'https://cdn.oblien.com/def456/image2.jpg', ... }
317
- * // ]
318
- * // }
319
- */
320
- async uploadMultiple(files, options = {}) {
321
- if (!Array.isArray(files) || files.length === 0) {
322
- throw new Error('Files must be a non-empty array');
323
- }
324
-
325
- const { token, filenames = [], scope = 'user' } = options;
326
-
327
- // Get token (use provided or generate new one)
328
- const cdnToken = token || await this._getToken(scope);
329
-
330
- // Create FormData
331
- const FormData = globalThis.FormData || (await import('form-data')).default;
332
- const formData = new FormData();
333
-
334
- // Add all files
335
- for (let i = 0; i < files.length; i++) {
336
- const file = files[i];
337
- const filename = filenames[i];
338
-
339
- // Normalize file input
340
- const normalized = this._normalizeFile(file, filename);
341
-
342
- if (normalized.buffer) {
343
- const Blob = globalThis.Blob || (await import('buffer')).Blob;
344
- const fileBlob = new Blob([normalized.buffer], {
345
- type: normalized.mimetype || 'application/octet-stream'
346
- });
347
- formData.append('files', fileBlob, normalized.filename);
348
- } else {
349
- formData.append('files', normalized.file, normalized.filename);
350
- }
351
- }
352
-
353
- // Upload to CDN
354
- const response = await fetch(`${this.cdnURL}/multiple`, {
355
- method: 'POST',
356
- headers: {
357
- 'Authorization': `Bearer ${cdnToken}`
358
- },
359
- body: formData
360
- });
361
-
362
- if (!response.ok) {
363
- const error = await response.json().catch(() => ({}));
364
- throw new Error(error.message || `Upload failed: ${response.status}`);
365
- }
366
-
367
- return response.json();
368
- }
369
-
370
- /**
371
- * Upload files from URLs (download and upload to CDN)
372
- * CDN will download the images from URLs and process them
373
- * Automatically handles token generation if not provided
374
- *
375
- * @param {Array<string>} urls - Array of image URLs to download and upload
376
- * @param {Object} options - Upload options
377
- * @param {string} options.token - CDN token (optional, will auto-generate if not provided)
378
- * @param {string} options.scope - Token scope to use: 'user' or 'admin' (default: 'user')
379
- * @returns {Promise<Object>} Upload result with processed file URLs
380
- *
381
- * @example
382
- * const result = await cdn.uploadFromUrls([
383
- * 'https://example.com/image1.jpg',
384
- * 'https://example.com/image2.png'
385
- * ]);
386
- *
387
- * // Returns:
388
- * // {
389
- * // success: true,
390
- * // files: [
391
- * // {
392
- * // url: 'https://cdn.oblien.com/abc123/image1.jpg',
393
- * // originalUrl: 'https://example.com/image1.jpg',
394
- * // filename: 'image1.jpg',
395
- * // size: 102400,
396
- * // mimetype: 'image/jpeg',
397
- * // variants: { ... }
398
- * // },
399
- * // {
400
- * // url: 'https://cdn.oblien.com/def456/image2.png',
401
- * // originalUrl: 'https://example.com/image2.png',
402
- * // filename: 'image2.png',
403
- * // size: 204800,
404
- * // mimetype: 'image/png',
405
- * // variants: { ... }
406
- * // }
407
- * // ]
408
- * // }
409
- */
410
- async uploadFromUrls(urls, options = {}) {
411
- if (!Array.isArray(urls) || urls.length === 0) {
412
- throw new Error('URLs must be a non-empty array');
413
- }
414
-
415
- const { token, scope = 'user' } = options;
416
-
417
- // Get token (use provided or generate new one)
418
- const cdnToken = token || await this._getToken(scope);
419
-
420
- // Upload from URLs
421
- const response = await fetch(`${this.cdnURL}/process-urls`, {
422
- method: 'POST',
423
- headers: {
424
- 'Authorization': `Bearer ${cdnToken}`,
425
- 'Content-Type': 'application/json'
426
- },
427
- body: JSON.stringify({ urls })
428
- });
429
-
430
- if (!response.ok) {
431
- const error = await response.json().catch(() => ({}));
432
- throw new Error(error.message || `Upload from URLs failed: ${response.status}`);
433
- }
434
-
435
- return response.json();
436
- }
437
-
438
- /**
439
- * @deprecated Use uploadFromUrls() instead
440
- * Process URLs (download and process images from URLs)
441
- */
442
- async processUrls(urls, options = {}) {
443
- console.warn('cdn.processUrls() is deprecated. Use cdn.uploadFromUrls() instead.');
444
- return this.uploadFromUrls(urls, options);
445
- }
446
-
447
- /**
448
- * Get file information (ADMIN ONLY)
449
- * Requires admin token
450
- *
451
- * @param {string} filePath - File path on CDN
452
- * @param {Object} options - Options
453
- * @param {string} options.token - Admin CDN token (optional, will auto-generate if not provided)
454
- * @returns {Promise<Object>} File information
455
- *
456
- * @example
457
- * const info = await cdn.getFileInfo('abc123/image.jpg');
458
- *
459
- * // Returns:
460
- * // {
461
- * // success: true,
462
- * // file: {
463
- * // path: 'abc123/image.jpg',
464
- * // size: 102400,
465
- * // mimetype: 'image/jpeg',
466
- * // created: '2024-01-01T00:00:00.000Z'
467
- * // }
468
- * // }
469
- */
470
- async getFileInfo(filePath, options = {}) {
471
- if (!filePath) {
472
- throw new Error('File path is required');
473
- }
474
-
475
- const { token } = options;
476
-
477
- // Get admin token (use provided or generate new one)
478
- const cdnToken = token || await this._getToken('admin');
479
-
480
- // Get file info
481
- const response = await fetch(`${this.cdnURL}/info/${filePath}`, {
482
- method: 'GET',
483
- headers: {
484
- 'Authorization': `Bearer ${cdnToken}`
485
- }
486
- });
487
-
488
- if (!response.ok) {
489
- const error = await response.json().catch(() => ({}));
490
- throw new Error(error.message || `Failed to get file info: ${response.status}`);
491
- }
492
-
493
- return response.json();
494
- }
495
-
496
- /**
497
- * Get available image variant options
498
- *
499
- * @param {Object} options - Options
500
- * @param {string} options.token - CDN token (optional, will auto-generate if not provided)
501
- * @returns {Promise<Object>} Available variants
502
- *
503
- * @example
504
- * const variants = await cdn.getVariants();
505
- *
506
- * // Returns:
507
- * // {
508
- * // variants: {
509
- * // thumb: { width: 150, height: 150, fit: 'inside' },
510
- * // medium: { width: 800, height: 600, fit: 'inside' },
511
- * // blur: { width: 75, height: 75, fit: 'cover', blur: 5 }
512
- * // }
513
- * // }
514
- */
515
- async getVariants(options = {}) {
516
- const { token } = options;
517
-
518
- // Get token (use provided or generate new one)
519
- const cdnToken = token || await this._getToken('user');
520
-
521
- const response = await fetch(`${this.cdnURL}/variants`, {
522
- method: 'GET',
523
- headers: {
524
- 'Authorization': `Bearer ${cdnToken}`
525
- }
526
- });
527
-
528
- if (!response.ok) {
529
- const error = await response.json().catch(() => ({}));
530
- throw new Error(error.message || `Failed to get variants: ${response.status}`);
531
- }
532
-
533
- return response.json();
534
- }
535
-
536
- /**
537
- * Get file size limits
538
- *
539
- * @param {Object} options - Options
540
- * @param {string} options.token - CDN token (optional, will auto-generate if not provided)
541
- * @returns {Promise<Object>} File size limits
542
- *
543
- * @example
544
- * const limits = await cdn.getLimits();
545
- *
546
- * // Returns:
547
- * // {
548
- * // limits: {
549
- * // 'image/jpeg': 5242880,
550
- * // 'image/png': 8388608,
551
- * // 'default': 10485760
552
- * // }
553
- * // }
554
- */
555
- async getLimits(options = {}) {
556
- const { token } = options;
557
-
558
- // Get token (use provided or generate new one)
559
- const cdnToken = token || await this._getToken('user');
560
-
561
- const response = await fetch(`${this.cdnURL}/limits`, {
562
- method: 'GET',
563
- headers: {
564
- 'Authorization': `Bearer ${cdnToken}`
565
- }
566
- });
567
-
568
- if (!response.ok) {
569
- const error = await response.json().catch(() => ({}));
570
- throw new Error(error.message || `Failed to get limits: ${response.status}`);
571
- }
572
-
573
- return response.json();
574
- }
575
-
576
- /**
577
- * Clear token cache
578
- * Useful when you want to force fresh token generation
579
- *
580
- * @param {string} scope - Scope to clear: 'user', 'admin', or 'all' (default: 'all')
581
- *
582
- * @example
583
- * cdn.clearTokenCache(); // Clear all
584
- * cdn.clearTokenCache('user'); // Clear user token only
585
- */
586
- clearTokenCache(scope = 'all') {
587
- if (scope === 'all') {
588
- this._tokenCache.user = null;
589
- this._tokenCache.admin = null;
590
- } else if (scope === 'user' || scope === 'admin') {
591
- this._tokenCache[scope] = null;
592
- }
593
- }
594
-
595
- // ===== FILE MANAGEMENT ENDPOINTS =====
596
- // These endpoints use session authentication (not CDN tokens)
597
-
598
- /**
599
- * List user's uploaded files
600
- * Uses session authentication (requires logged in user)
601
- *
602
- * @param {Object} options - Query options
603
- * @param {number} options.page - Page number (default: 1)
604
- * @param {number} options.limit - Items per page (default: 50, max: 100)
605
- * @param {boolean} options.includeDeleted - Include soft-deleted files (default: false)
606
- * @param {string} options.uploadType - Filter by upload type: 'upload' or 'url'
607
- * @param {string} options.sortBy - Sort column: 'created_at', 'size', 'filename' (default: 'created_at')
608
- * @param {string} options.sortOrder - Sort order: 'ASC' or 'DESC' (default: 'DESC')
609
- * @returns {Promise<Object>} Paginated list of files
610
- *
611
- * @example
612
- * const result = await cdn.listFiles({ page: 1, limit: 50 });
613
- *
614
- * // Returns:
615
- * // {
616
- * // success: true,
617
- * // data: {
618
- * // files: [
619
- * // {
620
- * // id: 123,
621
- * // filename: 'image.jpg',
622
- * // cdn_url: 'https://cdn.oblien.com/...',
623
- * // size: 102400,
624
- * // mime_type: 'image/jpeg',
625
- * // variants: [...],
626
- * // upload_type: 'upload',
627
- * // created_at: '2024-01-01T00:00:00.000Z'
628
- * // }
629
- * // ],
630
- * // pagination: {
631
- * // page: 1,
632
- * // limit: 50,
633
- * // total: 150,
634
- * // totalPages: 3,
635
- * // hasMore: true
636
- * // }
637
- * // }
638
- * // }
639
- */
640
- async listFiles(options = {}) {
641
- const {
642
- page = 1,
643
- limit = 50,
644
- includeDeleted = false,
645
- uploadType = null,
646
- sortBy = 'created_at',
647
- sortOrder = 'DESC'
648
- } = options;
649
-
650
- const queryParams = new URLSearchParams({
651
- page: page.toString(),
652
- limit: limit.toString(),
653
- include_deleted: includeDeleted.toString(),
654
- sort_by: sortBy,
655
- sort_order: sortOrder
656
- });
657
-
658
- if (uploadType) {
659
- queryParams.append('upload_type', uploadType);
660
- }
661
-
662
- return this.client.get(`cdn/files?${queryParams.toString()}`);
663
- }
664
-
665
- /**
666
- * Get user storage statistics
667
- * Uses session authentication (requires logged in user)
668
- *
669
- * @returns {Promise<Object>} Storage statistics
670
- *
671
- * @example
672
- * const stats = await cdn.getStats();
673
- *
674
- * // Returns:
675
- * // {
676
- * // success: true,
677
- * // data: {
678
- * // totalFiles: 150,
679
- * // totalSize: 157286400,
680
- * // activeFiles: 145,
681
- * // activeSize: 152166400,
682
- * // uploadedFiles: 100,
683
- * // urlFiles: 50
684
- * // }
685
- * // }
686
- */
687
- async getStats() {
688
- return this.client.get('cdn/stats');
689
- }
690
-
691
- /**
692
- * Get file by ID
693
- * Uses session authentication (requires logged in user)
694
- *
695
- * @param {number|string} fileId - File ID
696
- * @returns {Promise<Object>} File details
697
- *
698
- * @example
699
- * const file = await cdn.getFile(123);
700
- *
701
- * // Returns:
702
- * // {
703
- * // success: true,
704
- * // data: {
705
- * // id: 123,
706
- * // filename: 'image.jpg',
707
- * // cdn_url: 'https://cdn.oblien.com/...',
708
- * // size: 102400,
709
- * // mime_type: 'image/jpeg',
710
- * // variants: [...],
711
- * // is_deleted: false,
712
- * // created_at: '2024-01-01T00:00:00.000Z'
713
- * // }
714
- * // }
715
- */
716
- async getFile(fileId) {
717
- if (!fileId) {
718
- throw new Error('File ID is required');
719
- }
720
- return this.client.get(`cdn/files/${fileId}`);
721
- }
722
-
723
- /**
724
- * Delete file (soft delete)
725
- * Uses session authentication (requires logged in user)
726
- *
727
- * @param {number|string} fileId - File ID to delete
728
- * @returns {Promise<Object>} Delete result
729
- *
730
- * @example
731
- * const result = await cdn.deleteFile(123);
732
- *
733
- * // Returns:
734
- * // {
735
- * // success: true,
736
- * // message: 'File marked as deleted'
737
- * // }
738
- */
739
- async deleteFile(fileId) {
740
- if (!fileId) {
741
- throw new Error('File ID is required');
742
- }
743
- return this.client.delete(`cdn/files/${fileId}`);
744
- }
745
-
746
- /**
747
- * Restore a soft-deleted file
748
- * Uses session authentication (requires logged in user)
749
- *
750
- * @param {number|string} fileId - File ID to restore
751
- * @returns {Promise<Object>} Restore result
752
- *
753
- * @example
754
- * const result = await cdn.restoreFile(123);
755
- *
756
- * // Returns:
757
- * // {
758
- * // success: true,
759
- * // message: 'File restored successfully'
760
- * // }
761
- */
762
- async restoreFile(fileId) {
763
- if (!fileId) {
764
- throw new Error('File ID is required');
765
- }
766
- return this.client.post(`cdn/files/${fileId}/restore`);
767
- }
768
- }
769
-