knt-shared 1.10.5 → 1.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1824,6 +1824,19 @@ const DEFAULT_CONFIG = {
1824
1824
  filePath: "filePath",
1825
1825
  fullFilePath: "fullFilePath"
1826
1826
  };
1827
+ function generateBackfillUid(fileObj, config, url, index = 0) {
1828
+ if ((fileObj == null ? void 0 : fileObj.id) != null) {
1829
+ return `back-${fileObj.id}`;
1830
+ }
1831
+ const path = fileObj == null ? void 0 : fileObj[config.filePath];
1832
+ if (path) {
1833
+ return `back-${path}`;
1834
+ }
1835
+ if (url) {
1836
+ return `back-${url}`;
1837
+ }
1838
+ return `back-${Date.now()}-${index}`;
1839
+ }
1827
1840
  function transformUploadUrl(transferUrl) {
1828
1841
  var _a;
1829
1842
  if (isNullOrUnDef(transferUrl)) {
@@ -1842,13 +1855,13 @@ function transformUploadUrl(transferUrl) {
1842
1855
  }
1843
1856
  return void 0;
1844
1857
  }
1845
- function transformBackUrl(transferUrl, config) {
1858
+ function transformBackUrl(transferUrl, config, index = 0) {
1846
1859
  const mergedConfig = { ...DEFAULT_CONFIG, ...config };
1847
1860
  if (!isArray(transferUrl) && (isNullOrUnDef(transferUrl) || isNullOrUnDef(transferUrl[mergedConfig.fullFilePath]) || isNullOrUnDef(transferUrl[mergedConfig.filePath]))) {
1848
1861
  return void 0;
1849
1862
  }
1850
1863
  if (isArray(transferUrl)) {
1851
- const result = transferUrl.map((item) => transformBackUrl(item, config)).filter((item) => !isNullOrUnDef(item));
1864
+ const result = transferUrl.map((item, index2) => transformBackUrl(item, config, index2)).filter((item) => !isNullOrUnDef(item));
1852
1865
  if (mergedConfig.backType === "object") {
1853
1866
  return result;
1854
1867
  }
@@ -1857,14 +1870,19 @@ function transformBackUrl(transferUrl, config) {
1857
1870
  let resultObj;
1858
1871
  if (isString(transferUrl)) {
1859
1872
  resultObj = {
1873
+ uid: generateBackfillUid(null, mergedConfig, transferUrl, index),
1874
+ name: transferUrl.split("/").pop() || `file-${index}`,
1860
1875
  url: transferUrl,
1861
1876
  path: void 0,
1862
1877
  status: "done"
1863
1878
  };
1864
1879
  } else if (isObject(transferUrl)) {
1865
1880
  const fileObj = transferUrl;
1881
+ const url = fileObj[mergedConfig.fullFilePath];
1866
1882
  resultObj = {
1867
- url: fileObj[mergedConfig.fullFilePath],
1883
+ uid: generateBackfillUid(fileObj, mergedConfig, url, index),
1884
+ name: (url == null ? void 0 : url.split("/").pop()) || `file-${index}`,
1885
+ url,
1868
1886
  path: fileObj[mergedConfig.filePath],
1869
1887
  status: "done"
1870
1888
  };
@@ -2440,7 +2458,7 @@ const _hoisted_4$4 = {
2440
2458
  const _hoisted_5$4 = { class: "progress-bar" };
2441
2459
  const _hoisted_6$3 = { class: "controls-bottom" };
2442
2460
  const _hoisted_7$2 = { class: "controls-left" };
2443
- const _hoisted_8$1 = { class: "volume-slider-container" };
2461
+ const _hoisted_8$2 = { class: "volume-slider-container" };
2444
2462
  const _hoisted_9 = { class: "time-display" };
2445
2463
  const _hoisted_10 = { class: "controls-right" };
2446
2464
  const _hoisted_11 = { class: "control-button" };
@@ -2728,7 +2746,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
2728
2746
  size: 20
2729
2747
  }))
2730
2748
  ]),
2731
- withDirectives(createElementVNode("div", _hoisted_8$1, [
2749
+ withDirectives(createElementVNode("div", _hoisted_8$2, [
2732
2750
  withDirectives(createElementVNode("input", {
2733
2751
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => volume.value = $event),
2734
2752
  type: "range",
@@ -2888,7 +2906,7 @@ const _hoisted_7$1 = {
2888
2906
  key: 1,
2889
2907
  class: "upload-tip sortable-tip"
2890
2908
  };
2891
- const _hoisted_8 = {
2909
+ const _hoisted_8$1 = {
2892
2910
  key: 5,
2893
2911
  class: "inline-video-preview"
2894
2912
  };
@@ -2956,7 +2974,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2956
2974
  emits: ["register", "update:modelValue", "change", "success", "handleSuccess", "error", "handlError", "progress", "remove", "preview", "exceed", "sortChange"],
2957
2975
  setup(__props, { expose: __expose, emit: __emit }) {
2958
2976
  useCssVars((_ctx) => ({
2959
- "v74ec8601": cardSizeValue.value
2977
+ "eb56f194": cardSizeValue.value
2960
2978
  }));
2961
2979
  const MAX_SIZE_UNIT_BYTES = {
2962
2980
  B: 1,
@@ -3342,10 +3360,30 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
3342
3360
  emit("update:modelValue", fileList);
3343
3361
  }
3344
3362
  };
3363
+ const normalizeFileItem = (item, index) => {
3364
+ var _a;
3365
+ return {
3366
+ ...item,
3367
+ uid: item.uid || `file-${item.path || item.url || index}-${index}`,
3368
+ name: item.name || ((_a = item.url) == null ? void 0 : _a.split("/").pop()) || `file-${index}`,
3369
+ status: item.status || "done"
3370
+ };
3371
+ };
3372
+ const findFileIndex = (fileItem) => {
3373
+ if (fileItem.uid != null) {
3374
+ const index = fileListRef.value.findIndex(
3375
+ (item) => item.uid != null && item.uid === fileItem.uid
3376
+ );
3377
+ if (index !== -1) return index;
3378
+ }
3379
+ return fileListRef.value.findIndex(
3380
+ (item) => item.url === fileItem.url && item.path === fileItem.path
3381
+ );
3382
+ };
3345
3383
  const parseModelValue = (value) => {
3346
3384
  if (!value) return [];
3347
3385
  if (Array.isArray(value) && value.length > 0 && typeof value[0] === "object") {
3348
- return value;
3386
+ return value.map(normalizeFileItem);
3349
3387
  }
3350
3388
  if (Array.isArray(value)) {
3351
3389
  return value.map((url, index) => ({
@@ -3399,18 +3437,14 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
3399
3437
  updateModelValue(fileListRef.value);
3400
3438
  };
3401
3439
  const removeFile = (fileItem) => {
3402
- const index = fileListRef.value.findIndex(
3403
- (item) => item.uid === fileItem.uid
3404
- );
3440
+ const index = findFileIndex(fileItem);
3405
3441
  if (index !== -1) {
3406
3442
  fileListRef.value.splice(index, 1);
3407
3443
  updateModelValue(fileListRef.value);
3408
3444
  }
3409
3445
  };
3410
3446
  const updateFile = (fileItem) => {
3411
- const index = fileListRef.value.findIndex(
3412
- (item) => item.uid === fileItem.uid
3413
- );
3447
+ const index = findFileIndex(fileItem);
3414
3448
  if (index !== -1) {
3415
3449
  fileListRef.value[index] = { ...fileListRef.value[index], ...fileItem };
3416
3450
  updateModelValue(fileListRef.value);
@@ -3598,7 +3632,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
3598
3632
  "file-name": previewFileName.value,
3599
3633
  "player-options": getProps.value.videoPlayerOptions
3600
3634
  }, null, 8, ["visible", "video-url", "file-name", "player-options"])) : createCommentVNode("", true),
3601
- getProps.value.videoPreviewMode === "inline" && previewVideoVisible.value ? (openBlock(), createElementBlock("div", _hoisted_8, [
3635
+ getProps.value.videoPreviewMode === "inline" && previewVideoVisible.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, [
3602
3636
  createVNode(VideoPreview, {
3603
3637
  "video-url": previewVideoUrl.value,
3604
3638
  "player-options": getProps.value.videoPlayerOptions
@@ -3617,7 +3651,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
3617
3651
  };
3618
3652
  }
3619
3653
  });
3620
- const BasicUpload = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-d316e747"]]);
3654
+ const BasicUpload = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-3a5bef91"]]);
3621
3655
  function useUpload(props) {
3622
3656
  const uploadRef = ref(null);
3623
3657
  const fileListRef = ref((props == null ? void 0 : props.defaultFileList) || []);
@@ -10163,17 +10197,17 @@ function useDescription(props) {
10163
10197
  }
10164
10198
  ];
10165
10199
  }
10166
- const _hoisted_1$2 = { class: "basic-image" };
10167
- const _hoisted_2$1 = {
10200
+ const _hoisted_1$2 = {
10168
10201
  key: 0,
10169
10202
  class: "basic-image-empty"
10170
10203
  };
10171
- const _hoisted_3$1 = { class: "empty-text" };
10172
- const _hoisted_4 = {
10204
+ const _hoisted_2$1 = { class: "empty-text" };
10205
+ const _hoisted_3$1 = {
10173
10206
  key: 0,
10174
10207
  class: "basic-image-simple"
10175
10208
  };
10176
- const _hoisted_5 = { class: "image-wrapper" };
10209
+ const _hoisted_4 = { class: "image-wrapper" };
10210
+ const _hoisted_5 = ["src", "width", "height", "alt"];
10177
10211
  const _hoisted_6 = {
10178
10212
  key: 0,
10179
10213
  class: "image-count-badge"
@@ -10182,6 +10216,7 @@ const _hoisted_7 = {
10182
10216
  key: 0,
10183
10217
  style: { "display": "none" }
10184
10218
  };
10219
+ const _hoisted_8 = ["src", "width", "height", "alt"];
10185
10220
  const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10186
10221
  ...{
10187
10222
  name: "BasicImage"
@@ -10209,21 +10244,45 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10209
10244
  const getProps = computed(() => {
10210
10245
  return { ...props, ...innerPropsRef.value };
10211
10246
  });
10247
+ function isSafeImageUrl(url) {
10248
+ if (!url || typeof url !== "string") return false;
10249
+ const trimmed = url.trim();
10250
+ if (trimmed.startsWith("/") || trimmed.startsWith("./") || trimmed.startsWith("../")) {
10251
+ return true;
10252
+ }
10253
+ if (/^data:/i.test(trimmed)) {
10254
+ return /^data:image\/(?!svg\+xml)/i.test(trimmed);
10255
+ }
10256
+ try {
10257
+ const { protocol } = new URL(trimmed);
10258
+ return protocol === "http:" || protocol === "https:" || protocol === "blob:";
10259
+ } catch {
10260
+ return false;
10261
+ }
10262
+ }
10212
10263
  const normalizedImages = computed(() => {
10213
10264
  const images = getProps.value.images || [];
10214
10265
  if (!Array.isArray(images) || images.length === 0) {
10215
10266
  return [];
10216
10267
  }
10217
10268
  return images.map((item) => {
10218
- if (typeof item === "string") {
10219
- return { url: item };
10269
+ const normalized = typeof item === "string" ? { url: item } : item;
10270
+ if (!isSafeImageUrl(normalized.url)) {
10271
+ return { ...normalized, url: "" };
10220
10272
  }
10221
- return item;
10273
+ return normalized;
10222
10274
  });
10223
10275
  });
10276
+ const safeErrorImage = computed(() => {
10277
+ const url = getProps.value.errorImage;
10278
+ if (!url || !isSafeImageUrl(url)) return void 0;
10279
+ return url;
10280
+ });
10224
10281
  const gridStyle = computed(() => {
10282
+ const rawGap = getProps.value.gap ?? 8;
10283
+ const gap = Number.isFinite(rawGap) ? Math.max(0, rawGap) : 8;
10225
10284
  return {
10226
- gap: `${getProps.value.gap}px`
10285
+ gap: `${gap}px`
10227
10286
  };
10228
10287
  });
10229
10288
  const handleImageClick = (item, index) => {
@@ -10231,6 +10290,9 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10231
10290
  return;
10232
10291
  }
10233
10292
  emit("click", item, index);
10293
+ if (getProps.value.preview) {
10294
+ emit("preview", item, index);
10295
+ }
10234
10296
  };
10235
10297
  const getImages = () => {
10236
10298
  return normalizedImages.value;
@@ -10250,41 +10312,52 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10250
10312
  getProps: getPropsValue,
10251
10313
  setProps
10252
10314
  };
10253
- watch(
10254
- () => props,
10255
- () => {
10256
- },
10257
- { deep: true }
10258
- );
10259
10315
  onMounted(() => {
10260
10316
  emit("register", methods);
10261
10317
  });
10262
10318
  __expose(methods);
10263
10319
  return (_ctx, _cache) => {
10264
- return openBlock(), createElementBlock("div", _hoisted_1$2, [
10265
- normalizedImages.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
10320
+ return openBlock(), createElementBlock("div", {
10321
+ class: normalizeClass(["basic-image", { "basic-image--disabled": getProps.value.disabled }])
10322
+ }, [
10323
+ normalizedImages.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
10266
10324
  renderSlot(_ctx.$slots, "empty", {}, () => [
10267
- createElementVNode("span", _hoisted_3$1, toDisplayString(getProps.value.emptyText), 1)
10325
+ createElementVNode("span", _hoisted_2$1, toDisplayString(getProps.value.emptyText), 1)
10268
10326
  ], true)
10269
10327
  ])) : (openBlock(), createBlock(resolveDynamicComponent(getProps.value.preview ? unref(ImagePreviewGroup) : "div"), { key: 1 }, {
10270
10328
  default: withCtx(() => [
10271
- !getProps.value.showAll ? (openBlock(), createElementBlock("div", _hoisted_4, [
10272
- createElementVNode("div", _hoisted_5, [
10329
+ !getProps.value.showAll ? (openBlock(), createElementBlock("div", _hoisted_3$1, [
10330
+ createElementVNode("div", _hoisted_4, [
10273
10331
  createVNode(unref(Image$1), {
10274
10332
  src: normalizedImages.value[0].url,
10275
10333
  width: getProps.value.width,
10276
10334
  height: getProps.value.height,
10277
10335
  fit: getProps.value.fit,
10278
10336
  preview: getProps.value.preview,
10337
+ "show-loader": getProps.value.loading,
10279
10338
  alt: normalizedImages.value[0].name || "图片",
10280
10339
  onClick: _cache[0] || (_cache[0] = ($event) => handleImageClick(normalizedImages.value[0], 0))
10281
- }, null, 8, ["src", "width", "height", "fit", "preview", "alt"]),
10282
- normalizedImages.value.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_6, " +" + toDisplayString(normalizedImages.value.length - 1), 1)) : createCommentVNode("", true)
10340
+ }, createSlots({ _: 2 }, [
10341
+ safeErrorImage.value ? {
10342
+ name: "error",
10343
+ fn: withCtx(() => [
10344
+ createElementVNode("img", {
10345
+ src: safeErrorImage.value,
10346
+ width: getProps.value.width,
10347
+ height: getProps.value.height,
10348
+ style: normalizeStyle({ display: "block", objectFit: getProps.value.fit }),
10349
+ alt: normalizedImages.value[0].name || "图片"
10350
+ }, null, 12, _hoisted_5)
10351
+ ]),
10352
+ key: "0"
10353
+ } : void 0
10354
+ ]), 1032, ["src", "width", "height", "fit", "preview", "show-loader", "alt"]),
10355
+ normalizedImages.value.length > (getProps.value.maxCount ?? 1) ? (openBlock(), createElementBlock("div", _hoisted_6, " +" + toDisplayString(normalizedImages.value.length - (getProps.value.maxCount ?? 1)), 1)) : createCommentVNode("", true)
10283
10356
  ]),
10284
- getProps.value.preview && normalizedImages.value.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_7, [
10285
- (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value.slice(1), (item, index) => {
10357
+ getProps.value.preview && normalizedImages.value.length > (getProps.value.maxCount ?? 1) ? (openBlock(), createElementBlock("div", _hoisted_7, [
10358
+ (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value.slice(getProps.value.maxCount ?? 1), (item, index) => {
10286
10359
  return openBlock(), createBlock(unref(Image$1), {
10287
- key: index,
10360
+ key: `${item.url}-${index}`,
10288
10361
  src: item.url,
10289
10362
  alt: item.name || "图片"
10290
10363
  }, null, 8, ["src", "alt"]);
@@ -10297,7 +10370,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10297
10370
  }, [
10298
10371
  (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedImages.value, (item, index) => {
10299
10372
  return openBlock(), createElementBlock("div", {
10300
- key: index,
10373
+ key: `${item.url}-${index}`,
10301
10374
  class: "image-item"
10302
10375
  }, [
10303
10376
  createVNode(unref(Image$1), {
@@ -10306,33 +10379,46 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
10306
10379
  height: getProps.value.height,
10307
10380
  fit: getProps.value.fit,
10308
10381
  preview: getProps.value.preview,
10382
+ "show-loader": getProps.value.loading,
10309
10383
  alt: item.name || "图片",
10310
10384
  onClick: ($event) => handleImageClick(item, index)
10311
- }, null, 8, ["src", "width", "height", "fit", "preview", "alt", "onClick"])
10385
+ }, createSlots({ _: 2 }, [
10386
+ safeErrorImage.value ? {
10387
+ name: "error",
10388
+ fn: withCtx(() => [
10389
+ createElementVNode("img", {
10390
+ src: safeErrorImage.value,
10391
+ width: getProps.value.width,
10392
+ height: getProps.value.height,
10393
+ style: normalizeStyle({ display: "block", objectFit: getProps.value.fit }),
10394
+ alt: item.name || "图片"
10395
+ }, null, 12, _hoisted_8)
10396
+ ]),
10397
+ key: "0"
10398
+ } : void 0
10399
+ ]), 1032, ["src", "width", "height", "fit", "preview", "show-loader", "alt", "onClick"])
10312
10400
  ]);
10313
10401
  }), 128))
10314
10402
  ], 4))
10315
10403
  ]),
10316
10404
  _: 1
10317
10405
  }))
10318
- ]);
10406
+ ], 2);
10319
10407
  };
10320
10408
  }
10321
10409
  });
10322
- const BasicImage = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-04c54d5a"]]);
10410
+ const BasicImage = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-71d2eff3"]]);
10323
10411
  function useImage(options) {
10324
10412
  const imageRef = ref(null);
10325
10413
  const loadedRef = ref(false);
10326
10414
  const register = (instance) => {
10327
- if (unref(imageRef) && instance === unref(imageRef)) {
10415
+ if (instance === unref(imageRef)) {
10328
10416
  return;
10329
10417
  }
10330
10418
  imageRef.value = instance;
10331
10419
  loadedRef.value = true;
10332
10420
  if (options) {
10333
- nextTick(() => {
10334
- instance.setProps(options);
10335
- });
10421
+ instance.setProps(options);
10336
10422
  }
10337
10423
  };
10338
10424
  const getInstance = () => {