@autorender/sdk-core 0.1.21 → 0.1.23

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/README.md CHANGED
@@ -112,6 +112,7 @@ Creates a new AutoRender client instance for image transformations.
112
112
  ### `ARInstance`
113
113
 
114
114
  - `url(src: string, transform?: TransformOptions): string` - Generate transformed image URL
115
+ - `src` supports workspace paths (e.g., `products/shoe.jpg`) and absolute remote URLs (e.g., `https://example.com/image.jpg`).
115
116
  - `transformString(transform: TransformOptions): string` - Get transformation string only
116
117
  - `responsiveImageAttributes(options: ResponsiveOptions): ResponsiveAttributes` - Generate responsive image attributes
117
118
  - `getDPR(): number` - Get device pixel ratio (1 or 2)
package/dist/index.cjs CHANGED
@@ -23,6 +23,7 @@ __export(src_exports, {
23
23
  createAR: () => createAR,
24
24
  createUploader: () => createUploader,
25
25
  detectBestFormat: () => detectBestFormat,
26
+ encodeAssetPathForDelivery: () => encodeAssetPathForDelivery,
26
27
  getBestFormatSync: () => getBestFormatSync,
27
28
  registerAutorenderUploaderElement: () => registerAutorenderUploaderElement,
28
29
  resetFormatCache: () => resetFormatCache
@@ -183,129 +184,86 @@ var AutorenderApiClient = class {
183
184
  this.apiKey = opts.apiKey;
184
185
  this.baseUrl = (opts.baseUrl || getBaseUrl(opts.environment || "prod")).replace(/\/+$/, "");
185
186
  }
186
- async generateToken(params) {
187
+ uploadFile(params, onProgress, signal) {
187
188
  return new Promise((resolve, reject) => {
189
+ if (signal?.aborted) {
190
+ reject(new DOMException("Upload aborted", "AbortError"));
191
+ return;
192
+ }
188
193
  const xhr = new XMLHttpRequest();
194
+ if (signal) {
195
+ signal.addEventListener("abort", () => {
196
+ xhr.abort();
197
+ reject(new DOMException("Upload aborted", "AbortError"));
198
+ });
199
+ }
200
+ let lastProgress = 0;
201
+ xhr.upload.onprogress = (event) => {
202
+ if (event.lengthComputable && onProgress) {
203
+ const progress = Math.round(event.loaded / event.total * 100);
204
+ lastProgress = progress;
205
+ onProgress(progress);
206
+ } else if (onProgress && event.loaded > 0) {
207
+ const estimatedProgress = Math.min(
208
+ 95,
209
+ Math.round(event.loaded / (event.loaded + 1e6) * 100)
210
+ );
211
+ if (estimatedProgress > lastProgress) {
212
+ lastProgress = estimatedProgress;
213
+ onProgress(estimatedProgress);
214
+ }
215
+ }
216
+ };
189
217
  xhr.onerror = () => {
190
- reject(new Error(`Failed to generate token: ${xhr.statusText}`));
218
+ reject(new Error(`Upload failed: ${xhr.statusText}`));
191
219
  };
192
220
  xhr.onload = () => {
193
221
  try {
194
222
  if (xhr.status < 200 || xhr.status >= 300) {
195
223
  const errorText = xhr.responseText || xhr.statusText;
196
- reject(new Error(`Failed to generate token: ${errorText}`));
197
- return;
198
- }
199
- const response = JSON.parse(xhr.responseText);
200
- if (!response.token) {
201
- reject(new Error("Token not found in response"));
224
+ reject(new Error(`Upload failed: ${errorText}`));
202
225
  return;
203
226
  }
204
- resolve(response.token);
227
+ const newResponse = JSON.parse(xhr.responseText);
228
+ const response = {
229
+ success: true,
230
+ file_no: newResponse.file_no || newResponse.id,
231
+ name: newResponse.name,
232
+ url: newResponse.url,
233
+ file_size: newResponse.size,
234
+ format: newResponse.format,
235
+ width: newResponse.width,
236
+ height: newResponse.height,
237
+ created_at: newResponse.created_at,
238
+ path: newResponse.path,
239
+ workspace_no: newResponse.workspace_id,
240
+ isDuplicate: newResponse.is_duplicate || false
241
+ };
242
+ resolve(response);
205
243
  } catch (error) {
206
- reject(new Error("Failed to parse token response"));
244
+ reject(new Error("Failed to parse response"));
207
245
  }
208
246
  };
209
- let folder = params.folderPath || "";
210
- if (params.relativePath) {
211
- folder = folder ? `${folder}/${params.relativePath}` : params.relativePath;
247
+ const endpoint = `${this.baseUrl}/uploads`;
248
+ const formData = new FormData();
249
+ formData.append("file", params.file);
250
+ formData.append("file_name", params.file.name);
251
+ if (params.folderPath) {
252
+ formData.append("folder", params.folderPath);
212
253
  }
213
- if (folder && !folder.endsWith("/")) {
214
- folder += "/";
254
+ if (params.settings?.tags?.length) {
255
+ formData.append("tags", params.settings.tags.join(","));
256
+ }
257
+ if (params.settings?.pretransformations) {
258
+ formData.append("transform", params.settings.pretransformations);
259
+ }
260
+ if (params.settings?.custom_id) {
261
+ formData.append("custom_id", params.settings.custom_id);
215
262
  }
216
- const tokenRequest = {
217
- file_name: params.file.name,
218
- ...folder && { folder },
219
- ...params.settings?.tags && { tags: params.settings.tags },
220
- ...params.settings?.pretransformations && { transform: params.settings.pretransformations },
221
- max_file_size: params.file.size,
222
- allow_override: {
223
- folder: true,
224
- tags: true,
225
- transform: true
226
- },
227
- random_prefix: !params.settings?.is_unique_suffix_name
228
- };
229
- const endpoint = `${this.baseUrl}/generate-token`;
230
263
  xhr.open("POST", endpoint);
231
264
  xhr.setRequestHeader("Authorization", `Bearer ${this.apiKey}`);
232
- xhr.setRequestHeader("Content-Type", "application/json");
233
265
  xhr.setRequestHeader("accept", "application/json");
234
- xhr.send(JSON.stringify(tokenRequest));
235
- });
236
- }
237
- uploadFile(params, onProgress, signal) {
238
- return new Promise(async (resolve, reject) => {
239
- if (signal?.aborted) {
240
- reject(new DOMException("Upload aborted", "AbortError"));
241
- return;
242
- }
243
- try {
244
- const token = await this.generateToken(params);
245
- if (signal?.aborted) {
246
- reject(new DOMException("Upload aborted", "AbortError"));
247
- return;
248
- }
249
- const xhr = new XMLHttpRequest();
250
- if (signal) {
251
- signal.addEventListener("abort", () => {
252
- xhr.abort();
253
- reject(new DOMException("Upload aborted", "AbortError"));
254
- });
255
- }
256
- let lastProgress = 0;
257
- xhr.upload.onprogress = (event) => {
258
- if (event.lengthComputable && onProgress) {
259
- const progress = Math.round(event.loaded / event.total * 100);
260
- lastProgress = progress;
261
- onProgress(progress);
262
- } else if (onProgress && event.loaded > 0) {
263
- const estimatedProgress = Math.min(95, Math.round(event.loaded / (event.loaded + 1e6) * 100));
264
- if (estimatedProgress > lastProgress) {
265
- lastProgress = estimatedProgress;
266
- onProgress(estimatedProgress);
267
- }
268
- }
269
- };
270
- xhr.onerror = () => {
271
- reject(new Error(`Upload failed: ${xhr.statusText}`));
272
- };
273
- xhr.onload = () => {
274
- try {
275
- if (xhr.status < 200 || xhr.status >= 300) {
276
- const errorText = xhr.responseText || xhr.statusText;
277
- reject(new Error(`Upload failed: ${errorText}`));
278
- return;
279
- }
280
- const newResponse = JSON.parse(xhr.responseText);
281
- const response = {
282
- success: true,
283
- file_no: newResponse.file_no || newResponse.id,
284
- name: newResponse.name,
285
- url: newResponse.url,
286
- file_size: newResponse.size,
287
- format: newResponse.format,
288
- width: newResponse.width,
289
- height: newResponse.height,
290
- created_at: newResponse.created_at,
291
- path: newResponse.path,
292
- workspace_no: newResponse.workspace_id,
293
- isDuplicate: newResponse.is_duplicate || false
294
- };
295
- resolve(response);
296
- } catch (error) {
297
- reject(new Error("Failed to parse response"));
298
- }
299
- };
300
- const endpoint = `${this.baseUrl}/uploads/${token}`;
301
- xhr.open("POST", endpoint);
302
- xhr.setRequestHeader("accept", "application/json");
303
- const mimeType = params.file.type || "application/octet-stream";
304
- xhr.setRequestHeader("Content-Type", mimeType);
305
- xhr.send(params.file);
306
- } catch (error) {
307
- reject(error);
308
- }
266
+ xhr.send(formData);
309
267
  });
310
268
  }
311
269
  };
@@ -708,7 +666,8 @@ var UploaderController = class extends EventTarget {
708
666
  settings: uploadSettings ? {
709
667
  pretransformations: uploadSettings.pretransformations,
710
668
  tags: uploadSettings.tags,
711
- is_unique_suffix_name: uploadSettings.is_unique_suffix_name ?? false
669
+ is_unique_suffix_name: uploadSettings.is_unique_suffix_name ?? false,
670
+ custom_id: uploadSettings.custom_id
712
671
  } : void 0
713
672
  },
714
673
  (progress) => {
@@ -3576,15 +3535,40 @@ function normalizePlacement(placement) {
3576
3535
  }
3577
3536
 
3578
3537
  // src/viewtag/url-builder.ts
3538
+ var ABSOLUTE_URL_RE = /^https?:\/\//i;
3539
+ function encodeAssetPathForDelivery(src) {
3540
+ const trimmed = src.trim();
3541
+ if (!trimmed) {
3542
+ return "";
3543
+ }
3544
+ if (ABSOLUTE_URL_RE.test(trimmed)) {
3545
+ const fetchPayload = `fetch_${trimmed}`;
3546
+ return encodeURIComponent(fetchPayload);
3547
+ }
3548
+ if (trimmed.startsWith("fetch_")) {
3549
+ return encodeURIComponent(trimmed);
3550
+ }
3551
+ return trimmed.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
3552
+ }
3579
3553
  function buildImageUrl(baseUrl, workspace, src, transform, defaults, enableDPR = true, connectionQuality) {
3580
3554
  const normalizedBase = baseUrl.replace(/\/+$/, "");
3581
3555
  const transformStr = buildTransformString(transform || {}, defaults, enableDPR, connectionQuality);
3582
- const encodedPath = src.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
3556
+ const trimmedSrc = src.trim();
3557
+ if (ABSOLUTE_URL_RE.test(trimmedSrc)) {
3558
+ const fetchPart = `fetch_${trimmedSrc}`;
3559
+ const transformWithFetch = transformStr ? `${transformStr},${fetchPart}` : fetchPart;
3560
+ return `${normalizedBase}/${workspace}/${transformWithFetch}`;
3561
+ }
3562
+ if (trimmedSrc.startsWith("fetch_")) {
3563
+ const fetchPart = trimmedSrc;
3564
+ const transformWithFetch = transformStr ? `${transformStr},${fetchPart}` : fetchPart;
3565
+ return `${normalizedBase}/${workspace}/${transformWithFetch}`;
3566
+ }
3567
+ const encodedPath = encodeAssetPathForDelivery(trimmedSrc);
3583
3568
  if (transformStr) {
3584
3569
  return `${normalizedBase}/${workspace}/${transformStr}/${encodedPath}`;
3585
- } else {
3586
- return `${normalizedBase}/${workspace}/${encodedPath}`;
3587
3570
  }
3571
+ return `${normalizedBase}/${workspace}/${encodedPath}`;
3588
3572
  }
3589
3573
 
3590
3574
  // src/viewtag/responsive.ts
@@ -3967,6 +3951,7 @@ function registerAutorenderUploaderElement() {
3967
3951
  createAR,
3968
3952
  createUploader,
3969
3953
  detectBestFormat,
3954
+ encodeAssetPathForDelivery,
3970
3955
  getBestFormatSync,
3971
3956
  registerAutorenderUploaderElement,
3972
3957
  resetFormatCache