@emailmaker/filemanager 0.10.87 → 0.10.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- export{D as FileContent,J as FileManagerApiError,C as FileManagerApp,x as FileManagerAppWithContext,E as FileModals,G as FolderSidebar,P as PixieOnlyApp,B as default,v as init,A as initFileManager,y as initPixieEditor,H as installResizeObserverErrorHandler,K as mapHttpStatusToErrorCode,I as uninstallResizeObserverErrorHandler,w as unmount,z as unmountPixieEditor}from"./file-manager-index-CDath1LU.js";import"react/jsx-runtime";import"react";import"react-dom/client";import"antd";import"antd/es/alert/ErrorBoundary";import"@ant-design/icons";import"react-dom";
1
+ export{D as FileContent,J as FileManagerApiError,C as FileManagerApp,x as FileManagerAppWithContext,E as FileModals,G as FolderSidebar,P as PixieOnlyApp,B as default,L as fetchRemoteImageBlobByUrl,v as init,A as initFileManager,y as initPixieEditor,H as installResizeObserverErrorHandler,K as mapHttpStatusToErrorCode,I as uninstallResizeObserverErrorHandler,w as unmount,z as unmountPixieEditor}from"./file-manager-index-D14X20BS.js";import"react/jsx-runtime";import"react";import"react-dom/client";import"antd";import"antd/es/alert/ErrorBoundary";import"@ant-design/icons";import"react-dom";
2
2
  //# sourceMappingURL=file-manager.esm.js.map
package/file-manager.js CHANGED
@@ -27116,6 +27116,110 @@ if (true) {
27116
27116
  "use strict";
27117
27117
  module.exports = __WEBPACK_EXTERNAL_MODULE__5442__;
27118
27118
 
27119
+ /***/ }),
27120
+
27121
+ /***/ 5597:
27122
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
27123
+
27124
+ "use strict";
27125
+
27126
+ // EXPORTS
27127
+ __webpack_require__.d(__webpack_exports__, {
27128
+ n: () => (/* binding */ fetchRemoteImageBlobByUrl)
27129
+ });
27130
+
27131
+ // EXTERNAL MODULE: ./src/shared/fileManagerApiError.ts
27132
+ var fileManagerApiError = __webpack_require__(7036);
27133
+ ;// ./src/utils/directResourceFetchError.ts
27134
+ /**
27135
+ * Detects a final direct-fetch failure from the host resource proxy engine.
27136
+ * Uses error.name for cross-package compatibility (no instanceof across bundles).
27137
+ */
27138
+ function isFinalDirectResourceFetchError(error) {
27139
+ if (typeof error !== 'object' || error === null) {
27140
+ return false;
27141
+ }
27142
+ if ('name' in error && error.name === 'DirectResourceFetchError') {
27143
+ return !('final' in error) || error.final !== false;
27144
+ }
27145
+ return 'final' in error && error.final === true;
27146
+ }
27147
+
27148
+ ;// ./src/utils/remoteFileFetchPipeline.ts
27149
+
27150
+
27151
+ function rethrowNonRetryablePipelineError(error) {
27152
+ if (isFinalDirectResourceFetchError(error) || error instanceof fileManagerApiError/* FileManagerApiError */.m) {
27153
+ throw error;
27154
+ }
27155
+ }
27156
+ /**
27157
+ * ADR-aligned blob fetch ladder for upload-by-URL:
27158
+ * 1. handleFileProxy (plugin Blob)
27159
+ * 2. handleProxyUrl → fetch rewritten URL (outside engine)
27160
+ * 3. fetchWithProxy (host engine / policy v2)
27161
+ * 4. direct fetch — only without `fetchWithProxy` (engine already includes direct fallback in its chain)
27162
+ */
27163
+ async function fetchRemoteImageBlobByUrl(normalizedUrl, handlers, fetchBlobFromUrl, validateImageBlob, options) {
27164
+ const { fetchWithProxy, handleFileProxy, handleProxyUrl } = handlers;
27165
+ const fetchInit = Object.assign({ mode: 'cors' }, options === null || options === void 0 ? void 0 : options.fetchInit);
27166
+ let lastError;
27167
+ if (handleFileProxy) {
27168
+ try {
27169
+ const proxiedBlob = await Promise.resolve(handleFileProxy(normalizedUrl));
27170
+ if (proxiedBlob) {
27171
+ return validateImageBlob(proxiedBlob);
27172
+ }
27173
+ }
27174
+ catch (error) {
27175
+ rethrowNonRetryablePipelineError(error);
27176
+ lastError = error;
27177
+ console.warn('handleFileProxy failed, falling back to next strategy', error);
27178
+ }
27179
+ }
27180
+ if (handleProxyUrl) {
27181
+ try {
27182
+ const proxiedUrl = await Promise.resolve(handleProxyUrl(normalizedUrl));
27183
+ if (proxiedUrl && proxiedUrl !== normalizedUrl) {
27184
+ const proxiedBlob = await fetchBlobFromUrl(proxiedUrl);
27185
+ return validateImageBlob(proxiedBlob);
27186
+ }
27187
+ }
27188
+ catch (error) {
27189
+ rethrowNonRetryablePipelineError(error);
27190
+ lastError = error;
27191
+ console.warn('handleProxyUrl fetch failed, falling back to next strategy', error);
27192
+ }
27193
+ }
27194
+ if (fetchWithProxy) {
27195
+ try {
27196
+ const proxiedResponse = await Promise.resolve(fetchWithProxy(normalizedUrl, fetchInit, { intent: 'downloadBlob' }));
27197
+ if (!proxiedResponse.ok) {
27198
+ throw new Error(`HTTP ${proxiedResponse.status}`);
27199
+ }
27200
+ const proxiedBlob = await proxiedResponse.blob();
27201
+ return validateImageBlob(proxiedBlob);
27202
+ }
27203
+ catch (error) {
27204
+ rethrowNonRetryablePipelineError(error);
27205
+ lastError = error;
27206
+ console.warn('fetchWithProxy failed', error);
27207
+ }
27208
+ }
27209
+ if (!fetchWithProxy) {
27210
+ try {
27211
+ const directBlob = await fetchBlobFromUrl(normalizedUrl);
27212
+ return validateImageBlob(directBlob);
27213
+ }
27214
+ catch (error) {
27215
+ rethrowNonRetryablePipelineError(error);
27216
+ lastError = error;
27217
+ }
27218
+ }
27219
+ throw lastError instanceof Error ? lastError : new Error('Failed to download file from the URL');
27220
+ }
27221
+
27222
+
27119
27223
  /***/ }),
27120
27224
 
27121
27225
  /***/ 5748:
@@ -28789,6 +28893,37 @@ const RU_TO_EN = {
28789
28893
  * Включает: < > : " / \ | ? * ( ) # и control characters (0x00-0x1f)
28790
28894
  */
28791
28895
  const FORBIDDEN_CHARS_PATTERN = /[<>:"/\\|?*()#\x00-\x1f]/g;
28896
+ /** Дефисы и минусы: en/em dash, minus sign, non-breaking hyphen, fullwidth hyphen */
28897
+ const DASH_LIKE_CHARS = /[\u2010-\u2015\u2212\uFE63\uFF0D]/g;
28898
+ /** Знак умножения и декоративные крестики (из Word, иконок) */
28899
+ const MULTIPLICATION_LIKE_CHARS = /[\u00D7\u2715\u2716\u2A2F]/g;
28900
+ /** Неразрывные и прочие Unicode-пробелы (часто из Word/PDF/веба) */
28901
+ const UNICODE_SPACE_CHARS = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
28902
+ /** Нулевой ширины и мягкий перенос — невидимы, удаляем */
28903
+ const INVISIBLE_CHARS = /[\u00AD\u200B-\u200D\u2060\uFEFF]/g;
28904
+ /** Типографские, «ёлочки» и ASCII-кавычки — удаляем */
28905
+ const QUOTE_CHARS = /[\u2018\u2019\u201A\u201B\u00AB\u00BB\u201C\u201D\u201E\u201F'"`]/g;
28906
+ /** Маркеры списков, дробная черта, точка по центру */
28907
+ const BULLET_LIKE_CHARS = /[\u2022\u2044]/g;
28908
+ /**
28909
+ * Заменяет типографские символы на ASCII-эквиваленты.
28910
+ * Типичные источники: Word, Google Docs, PDF, копипаст из браузера.
28911
+ */
28912
+ function replaceSpecialChars(text) {
28913
+ return text
28914
+ .replace(/\u2026/g, '...')
28915
+ .replace(DASH_LIKE_CHARS, '-')
28916
+ .replace(MULTIPLICATION_LIKE_CHARS, 'x')
28917
+ .replace(UNICODE_SPACE_CHARS, ' ')
28918
+ .replace(INVISIBLE_CHARS, '')
28919
+ .replace(QUOTE_CHARS, '')
28920
+ .replace(BULLET_LIKE_CHARS, '-')
28921
+ .replace(/\u00B7/g, '-')
28922
+ .replace(/\u00A9/g, 'c')
28923
+ .replace(/\u00AE/g, 'r')
28924
+ .replace(/\u2122/g, 'tm')
28925
+ .replace(/\./g, '-');
28926
+ }
28792
28927
  const DEFAULT_OPTIONS = {
28793
28928
  transliterate: true,
28794
28929
  replaceSpaces: true,
@@ -28815,23 +28950,27 @@ function normalizeName(name, options) {
28815
28950
  if (options.transliterate) {
28816
28951
  result = transliterateRuToEn(result);
28817
28952
  }
28818
- // 2. Удаление запрещенных символов
28953
+ // 2. NFKC: fullwidth-символы (A, -, 1) → обычные ASCII
28954
+ result = result.normalize('NFKC');
28955
+ // 3. Замена типографских символов на ASCII
28956
+ result = replaceSpecialChars(result);
28957
+ // 4. Удаление запрещенных символов
28819
28958
  if (options.removeForbiddenChars) {
28820
28959
  result = result.replace(FORBIDDEN_CHARS_PATTERN, '_');
28821
28960
  }
28822
- // 3. Замена пробелов на подчеркивание
28961
+ // 5. Замена пробелов на подчеркивание
28823
28962
  if (options.replaceSpaces) {
28824
28963
  result = result.replace(/\s+/g, '_');
28825
28964
  }
28826
- // 4. Приведение к нижнему регистру
28965
+ // 6. Приведение к нижнему регистру
28827
28966
  if (options.toLowerCase) {
28828
28967
  result = result.toLowerCase();
28829
28968
  }
28830
- // 5. Убираем множественные подчеркивания
28969
+ // 7. Убираем множественные подчеркивания
28831
28970
  result = result.replace(/_{2,}/g, '_');
28832
- // 6. Убираем подчеркивания в начале и конце
28971
+ // 8. Убираем подчеркивания в начале и конце
28833
28972
  result = result.replace(/^_+|_+$/g, '');
28834
- // 7. Ограничиваем длину (максимум для большинства файловых систем)
28973
+ // 9. Ограничиваем длину (максимум для большинства файловых систем)
28835
28974
  if (result.length > 255) {
28836
28975
  result = result.substring(0, 255);
28837
28976
  }
@@ -31059,6 +31198,8 @@ function isUrlSameOriginAsCurrentPage(url) {
31059
31198
  }
31060
31199
  }
31061
31200
 
31201
+ // EXTERNAL MODULE: ./src/utils/remoteFileFetchPipeline.ts + 1 modules
31202
+ var remoteFileFetchPipeline = __webpack_require__(5597);
31062
31203
  // EXTERNAL MODULE: ./src/utils/dedupeUploadNamesOnClient.ts
31063
31204
  var dedupeUploadNamesOnClient = __webpack_require__(3795);
31064
31205
  // EXTERNAL MODULE: ./src/utils/resolveUniqueUploadName.ts
@@ -31093,6 +31234,7 @@ var fileManagerApiError = __webpack_require__(7036);
31093
31234
 
31094
31235
 
31095
31236
 
31237
+
31096
31238
 
31097
31239
 
31098
31240
  /**
@@ -31404,66 +31546,21 @@ const useFilesAPI = () => {
31404
31546
  }
31405
31547
  let resolvedBlob;
31406
31548
  let resolvedMimeType;
31407
- let lastError;
31408
- const fetchWithProxy = (_a = options === null || options === void 0 ? void 0 : options.config) === null || _a === void 0 ? void 0 : _a.fetchWithProxy;
31409
- const handleFileProxy = (_b = options === null || options === void 0 ? void 0 : options.config) === null || _b === void 0 ? void 0 : _b.handleFileProxy;
31410
- const handleProxyUrl = (_c = options === null || options === void 0 ? void 0 : options.config) === null || _c === void 0 ? void 0 : _c.handleProxyUrl;
31411
- const skipProxy = isUrlSameOriginAsCurrentPage(normalizedUrl);
31412
- if (!skipProxy && fetchWithProxy) {
31413
- try {
31414
- const proxiedResponse = await Promise.resolve(fetchWithProxy(normalizedUrl, { mode: 'cors' }, { intent: 'downloadBlob' }));
31415
- if (!proxiedResponse.ok) {
31416
- throw new fileManagerApiError/* FileManagerApiError */.m(`HTTP ${proxiedResponse.status}`, 'UploadUrlDownloadFailed', proxiedResponse.status);
31417
- }
31418
- const proxiedBlob = await proxiedResponse.blob();
31419
- const validated = validateImageBlob(proxiedBlob, t);
31420
- resolvedBlob = validated.blob;
31421
- resolvedMimeType = validated.mimeType;
31422
- }
31423
- catch (error) {
31424
- lastError = error;
31425
- console.warn('fetchWithProxy failed or returned a non-image blob, falling back to next strategy', error);
31426
- }
31427
- }
31428
- if (!skipProxy && !resolvedBlob && handleFileProxy) {
31429
- try {
31430
- const proxiedBlob = await Promise.resolve(handleFileProxy(normalizedUrl));
31431
- const validated = validateImageBlob(proxiedBlob, t);
31432
- resolvedBlob = validated.blob;
31433
- resolvedMimeType = validated.mimeType;
31434
- }
31435
- catch (error) {
31436
- lastError = error;
31437
- console.warn('handleFileProxy failed or returned a non-image blob, falling back to next strategy', error);
31438
- }
31439
- }
31440
- if (!skipProxy && !resolvedBlob && handleProxyUrl) {
31441
- try {
31442
- const proxiedUrl = await Promise.resolve(handleProxyUrl(normalizedUrl));
31443
- const proxiedBlob = await fetchBlobFromUrl(proxiedUrl);
31444
- const validated = validateImageBlob(proxiedBlob, t);
31445
- resolvedBlob = validated.blob;
31446
- resolvedMimeType = validated.mimeType;
31447
- }
31448
- catch (error) {
31449
- lastError = error;
31450
- console.warn('handleProxyUrl fetch failed or returned a non-image blob, falling back to direct fetch', error);
31451
- }
31549
+ try {
31550
+ const validated = await (0,remoteFileFetchPipeline/* fetchRemoteImageBlobByUrl */.n)(normalizedUrl, {
31551
+ fetchWithProxy: (_a = options === null || options === void 0 ? void 0 : options.config) === null || _a === void 0 ? void 0 : _a.fetchWithProxy,
31552
+ handleFileProxy: (_b = options === null || options === void 0 ? void 0 : options.config) === null || _b === void 0 ? void 0 : _b.handleFileProxy,
31553
+ handleProxyUrl: (_c = options === null || options === void 0 ? void 0 : options.config) === null || _c === void 0 ? void 0 : _c.handleProxyUrl,
31554
+ }, fetchBlobFromUrl, (blob) => validateImageBlob(blob, t));
31555
+ resolvedBlob = validated.blob;
31556
+ resolvedMimeType = validated.mimeType;
31452
31557
  }
31453
- if (!resolvedBlob) {
31454
- try {
31455
- const directBlob = await fetchBlobFromUrl(normalizedUrl);
31456
- const validated = validateImageBlob(directBlob, t);
31457
- resolvedBlob = validated.blob;
31458
- resolvedMimeType = validated.mimeType;
31459
- }
31460
- catch (error) {
31461
- lastError = error;
31558
+ catch (error) {
31559
+ if (error instanceof fileManagerApiError/* FileManagerApiError */.m) {
31560
+ throw error;
31462
31561
  }
31463
- }
31464
- if (!resolvedBlob || !resolvedMimeType) {
31465
- throw lastError instanceof Error
31466
- ? lastError
31562
+ throw error instanceof Error
31563
+ ? error
31467
31564
  : new fileManagerApiError/* FileManagerApiError */.m(t('Failed to download file from the URL.'), 'UploadUrlDownloadFailed');
31468
31565
  }
31469
31566
  const extension = (0,mimeUtils/* getExtensionFromMime */.wh)(resolvedMimeType);
@@ -34807,7 +34904,7 @@ __webpack_require__.d(__webpack_exports__, {
34807
34904
  "default": () => (/* binding */ src)
34808
34905
  });
34809
34906
 
34810
- // UNUSED EXPORTS: FileContent, FileManagerApiError, FileManagerApp, FileManagerAppWithContext, FileModals, FolderSidebar, PixieOnlyApp, init, initFileManager, initPixieEditor, installResizeObserverErrorHandler, mapHttpStatusToErrorCode, uninstallResizeObserverErrorHandler, unmount, unmountPixieEditor
34907
+ // UNUSED EXPORTS: FileContent, FileManagerApiError, FileManagerApp, FileManagerAppWithContext, FileModals, FolderSidebar, PixieOnlyApp, fetchRemoteImageBlobByUrl, init, initFileManager, initPixieEditor, installResizeObserverErrorHandler, mapHttpStatusToErrorCode, uninstallResizeObserverErrorHandler, unmount, unmountPixieEditor
34811
34908
 
34812
34909
  // EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js
34813
34910
  var jsx_runtime = __webpack_require__(4848);
@@ -91130,7 +91227,13 @@ const ImageGif = ({ setImageGifList, imageGifList = [], currentReqGif, setCurren
91130
91227
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
91131
91228
  const handleProxyUrl = config === null || config === void 0 ? void 0 : config.handleProxyUrl;
91132
91229
  const fetchWithProxy = config === null || config === void 0 ? void 0 : config.fetchWithProxy;
91133
- const proxy = async (url) => (handleProxyUrl ? Promise.resolve(handleProxyUrl(url)) : url);
91230
+ const proxy = async (url) => {
91231
+ if (!handleProxyUrl) {
91232
+ return url;
91233
+ }
91234
+ const proxied = await Promise.resolve(handleProxyUrl(url));
91235
+ return proxied !== null && proxied !== void 0 ? proxied : url;
91236
+ };
91134
91237
  const fetchJson = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useCallback)(async (url) => {
91135
91238
  if (fetchWithProxy) {
91136
91239
  return Promise.resolve(fetchWithProxy(url, undefined, { intent: 'metadata' }));
@@ -91446,7 +91549,13 @@ const ImageStock = ({ imageStockList, setImageStockList, currentReq, setCurrentR
91446
91549
  const searchSeqRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(0);
91447
91550
  const nextPageRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(1);
91448
91551
  const inFlightRequestKeysRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(new Set());
91449
- const proxy = async (url) => (handleProxyUrl ? Promise.resolve(handleProxyUrl(url)) : url);
91552
+ const proxy = async (url) => {
91553
+ if (!handleProxyUrl) {
91554
+ return url;
91555
+ }
91556
+ const proxied = await Promise.resolve(handleProxyUrl(url));
91557
+ return proxied !== null && proxied !== void 0 ? proxied : url;
91558
+ };
91450
91559
  const fetchJson = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useCallback)(async (url) => {
91451
91560
  if (fetchWithProxy) {
91452
91561
  return Promise.resolve(fetchWithProxy(url, undefined, { intent: 'metadata' }));
@@ -94464,6 +94573,8 @@ const initFileManager = (options) => {
94464
94573
 
94465
94574
  // EXTERNAL MODULE: ./src/shared/fileManagerApiError.ts
94466
94575
  var fileManagerApiError = __webpack_require__(7036);
94576
+ // EXTERNAL MODULE: ./src/utils/remoteFileFetchPipeline.ts + 1 modules
94577
+ var remoteFileFetchPipeline = __webpack_require__(5597);
94467
94578
  ;// ./src/index.ts
94468
94579
 
94469
94580
 
@@ -94476,6 +94587,7 @@ var fileManagerApiError = __webpack_require__(7036);
94476
94587
 
94477
94588
 
94478
94589
 
94590
+
94479
94591
  })();
94480
94592
 
94481
94593
  __webpack_exports__ = __webpack_exports__["default"];
package/index.d.ts CHANGED
@@ -20,4 +20,5 @@ export { installResizeObserverErrorHandler, uninstallResizeObserverErrorHandler
20
20
  export { type Folder, type File, type PathItem, type MenuItem, type FileManagerOptions, type FileManagerHookReturn, type FileManagerErrorCode, type IFileManagerApiError, type SortOptionType, type FileManagerItemMeta, } from './types';
21
21
  export { FileManagerApiError } from './shared/fileManagerApiError';
22
22
  export { mapHttpStatusToErrorCode } from './shared/mapHttpStatusToErrorCode';
23
+ export { fetchRemoteImageBlobByUrl, type FetchRemoteImageBlobOptions, type RemoteFileFetchHandlers, type RemoteFileFetchIntent, } from './utils/remoteFileFetchPipeline';
23
24
  export { type InitPixieEditorOptions, type Options as FileManagerInitOptions, type UniversalInitOptions, } from './file-manager';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emailmaker/filemanager",
3
- "version": "0.10.87",
3
+ "version": "0.10.89",
4
4
  "main": "./file-manager.js",
5
5
  "module": "./file-manager.esm.js",
6
6
  "types": "./index.d.ts",
package/types.d.ts CHANGED
@@ -507,8 +507,11 @@ export interface Config {
507
507
  * Запрос уходит только для строк с кириллицей. При 404/ошибке сети поиск продолжается по исходной строке (локальный RU-словарь).
508
508
  */
509
509
  iconStockTranslateUrl?: string;
510
- /** Единый хендлер: принимает оригинальный URL, возвращает проксированный (sync или async). Используется для Unsplash, Giphy. */
511
- handleProxyUrl?: (url: string) => string | Promise<string>;
510
+ /**
511
+ * Plugin URL override (PROXY_URL). Возвращает переписанный URL или undefined — тогда
512
+ * upload/metadata идут через `fetchWithProxy` / `getProxiedUrl`, не через display-default proxy.
513
+ */
514
+ handleProxyUrl?: (url: string) => string | null | undefined | Promise<string | null | undefined>;
512
515
  /** Display-controller для `<img src>` через общий proxy runtime-state хоста. */
513
516
  getProxiedUrl?: (url: string) => {
514
517
  src: string;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detects a final direct-fetch failure from the host resource proxy engine.
3
+ * Uses error.name for cross-package compatibility (no instanceof across bundles).
4
+ */
5
+ export declare function isFinalDirectResourceFetchError(error: unknown): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ export type RemoteFileFetchIntent = 'display' | 'downloadBlob' | 'metadata';
2
+ export type RemoteFileFetchHandlers = {
3
+ fetchWithProxy?: (url: string, init?: RequestInit, options?: {
4
+ intent?: RemoteFileFetchIntent;
5
+ }) => Response | Promise<Response>;
6
+ handleFileProxy?: (url: string) => Blob | Promise<Blob | null | undefined>;
7
+ handleProxyUrl?: (url: string) => string | null | undefined | Promise<string | null | undefined>;
8
+ };
9
+ export type FetchBlobFromUrl = (url: string) => Promise<Blob>;
10
+ export type ValidateImageBlobResult = {
11
+ blob: Blob;
12
+ mimeType: string;
13
+ };
14
+ export type ValidateImageBlob = (blob: Blob) => ValidateImageBlobResult;
15
+ export type FetchRemoteImageBlobOptions = {
16
+ fetchInit?: RequestInit;
17
+ };
18
+ /**
19
+ * ADR-aligned blob fetch ladder for upload-by-URL:
20
+ * 1. handleFileProxy (plugin Blob)
21
+ * 2. handleProxyUrl → fetch rewritten URL (outside engine)
22
+ * 3. fetchWithProxy (host engine / policy v2)
23
+ * 4. direct fetch — only without `fetchWithProxy` (engine already includes direct fallback in its chain)
24
+ */
25
+ export declare function fetchRemoteImageBlobByUrl(normalizedUrl: string, handlers: RemoteFileFetchHandlers, fetchBlobFromUrl: FetchBlobFromUrl, validateImageBlob: ValidateImageBlob, options?: FetchRemoteImageBlobOptions): Promise<ValidateImageBlobResult>;
@@ -0,0 +1 @@
1
+ export {};