yd-admin 0.1.9 → 0.1.11

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
@@ -332,6 +332,11 @@ vp test
332
332
 
333
333
  ## 📋 更新日志
334
334
 
335
+ ### v0.1.11
336
+
337
+ - **release**: 版本号更新至 v0.1.11
338
+ - **enhancement**: 优化构建配置
339
+
335
340
  ### v0.1.9
336
341
 
337
342
  - **feat(AI Chat)**: AI 聊天页面组件 (YdChatPage) - 支持会话列表、模型选择、流式输出
package/dist/index.js CHANGED
@@ -18,9 +18,15 @@ var __exportAll = (all, no_symbols) => {
18
18
  /**
19
19
  * Web Crypto API 加密工具
20
20
  * 使用 AES-GCM 算法进行对称加密
21
+ *
22
+ * 环境变量:
23
+ * - VITE_CRYPTO_SALT: 自定义盐值 (允许使用项目覆盖)
24
+ * 示例: VITE_CRYPTO_SALT=your-project-salt
21
25
  */
22
26
  const encoder = new TextEncoder();
23
27
  const decoder = new TextDecoder();
28
+ const CRYPTO_SALT = import.meta.env.VITE_CRYPTO_SALT;
29
+ if (!CRYPTO_SALT) throw new Error("[crypto] VITE_CRYPTO_SALT 环境变量未配置。请在 .env 文件中设置 VITE_CRYPTO_SALT");
24
30
  /**
25
31
  * 密钥派生缓存
26
32
  * 避免每次加密/解密都重新派生密钥 (PBKDF2 100000 次迭代开销较大)
@@ -41,7 +47,7 @@ async function deriveKey(password) {
41
47
  const cached = keyCache.get(password);
42
48
  if (cached) return cached.key;
43
49
  const keyMaterial = await crypto.subtle.importKey("raw", encoder.encode(password), { name: "PBKDF2" }, false, ["deriveKey"]);
44
- const salt = encoder.encode("yd-admin-salt-fixed");
50
+ const salt = encoder.encode(CRYPTO_SALT);
45
51
  const key = await crypto.subtle.deriveKey({
46
52
  name: "PBKDF2",
47
53
  salt,
@@ -105,11 +111,33 @@ async function decrypt(base64Data, key) {
105
111
  return null;
106
112
  }
107
113
  }
114
+ //#endregion
115
+ //#region src/utils/secure-storage.ts
116
+ /**
117
+ * 安全存储工具
118
+ * 混合加密策略:
119
+ * - sessionStorage: 使用动态会话密钥 (内存中,刷新即焚)
120
+ * - localStorage: 使用 Vite 环境变量密钥 (防普通篡改)
121
+ *
122
+ * 密钥来源优先级:
123
+ * localStorage: 配置文件 → 运行时 → init配置 → 环境变量 VITE_STORAGE_KEY
124
+ * sessionStorage: 运行时 → init配置 → 动态生成(每次会话)
125
+ */
126
+ /**
127
+ * 全局密钥存储(用于运行时/API注入)
128
+ */
129
+ let globalLocalStorageKey = null;
130
+ let globalSessionStorageKey = null;
108
131
  /**
109
132
  * 配置文件中的密钥缓存
110
133
  */
111
134
  let configLocalStorageKey;
112
135
  let configSessionStorageKey;
136
+ /**
137
+ * 密钥来源追踪
138
+ */
139
+ let localKeySource = "default";
140
+ let sessionKeySource = "dynamic";
113
141
  let sessionKey = null;
114
142
  let sessionKeyIsString = false;
115
143
  let storageReadyResolve = null;
@@ -117,8 +145,57 @@ const storageReady = new Promise((resolve) => {
117
145
  storageReadyResolve = resolve;
118
146
  });
119
147
  let localStorageKey = null;
120
- const ENV_KEY = import.meta.env.VITE_STORAGE_KEY || "yd-admin-default-key";
121
- const ENV_SESSION_KEY = import.meta.env.VITE_SESSION_STORAGE_KEY || "yd-admin-session-key";
148
+ const ENV_KEY = import.meta.env.VITE_STORAGE_KEY;
149
+ const ENV_SESSION_KEY = import.meta.env.VITE_SESSION_STORAGE_KEY;
150
+ if (import.meta.env.PROD) {
151
+ if (!ENV_KEY) throw new Error("[secure-storage] 生产环境必须配置 VITE_STORAGE_KEY 环境变量");
152
+ if (!ENV_SESSION_KEY) throw new Error("[secure-storage] 生产环境必须配置 VITE_SESSION_STORAGE_KEY 环境变量");
153
+ }
154
+ /**
155
+ * 设置 localStorage 运行时密钥
156
+ * @param key 加密密钥
157
+ */
158
+ function setStorageEncryptionKey(key) {
159
+ globalLocalStorageKey = key;
160
+ localKeySource = "runtime";
161
+ }
162
+ /**
163
+ * 设置 sessionStorage 运行时密钥
164
+ * @param key 加密密钥
165
+ */
166
+ function setSessionStorageEncryptionKey(key) {
167
+ globalSessionStorageKey = key;
168
+ sessionKeySource = "runtime";
169
+ }
170
+ /**
171
+ * 获取密钥来源
172
+ * @param type 存储类型
173
+ * @returns 密钥来源
174
+ */
175
+ function getKeySource(type) {
176
+ return type === "local" ? localKeySource : sessionKeySource;
177
+ }
178
+ /**
179
+ * 重置密钥
180
+ * @param type 存储类型
181
+ */
182
+ function resetStorageKey(type) {
183
+ if (type === "local") {
184
+ globalLocalStorageKey = null;
185
+ localKeySource = "dynamic";
186
+ } else {
187
+ globalSessionStorageKey = null;
188
+ sessionKeySource = "dynamic";
189
+ sessionKey = null;
190
+ }
191
+ }
192
+ /**
193
+ * 检查存储是否就绪
194
+ * @returns 是否就绪
195
+ */
196
+ function isStorageReady() {
197
+ return !!localStorageKey || !!sessionKey || !!globalLocalStorageKey || !!globalSessionStorageKey;
198
+ }
122
199
  /**
123
200
  * 从配置文件加载密钥
124
201
  * @param filePath 配置文件路径,默认 config/storage.json
@@ -148,6 +225,10 @@ async function loadKeyFromConfig(filePath) {
148
225
  * 解析 localStorage 密钥(按优先级)
149
226
  */
150
227
  async function resolveLocalKey(config) {
228
+ if (globalLocalStorageKey) return {
229
+ key: globalLocalStorageKey,
230
+ source: "runtime"
231
+ };
151
232
  if (config?.localStorageKey || config?.storageKey) return {
152
233
  key: config.localStorageKey || config.storageKey,
153
234
  source: "init"
@@ -163,7 +244,7 @@ async function resolveLocalKey(config) {
163
244
  source: "env"
164
245
  };
165
246
  return {
166
- key: ENV_KEY,
247
+ key: (import.meta.env.DEV ? "yd-admin-dev-local-key" : "") || ENV_KEY,
167
248
  source: "default"
168
249
  };
169
250
  }
@@ -171,6 +252,10 @@ async function resolveLocalKey(config) {
171
252
  * 解析 sessionStorage 密钥(按优先级)
172
253
  */
173
254
  async function resolveSessionKey(config) {
255
+ if (globalSessionStorageKey) return {
256
+ key: globalSessionStorageKey,
257
+ source: "runtime"
258
+ };
174
259
  if (config?.sessionStorageKey || config?.storageKey) return {
175
260
  key: config.sessionStorageKey || config.storageKey,
176
261
  source: "init"
@@ -187,7 +272,7 @@ async function resolveSessionKey(config) {
187
272
  source: "env"
188
273
  };
189
274
  return {
190
- key: ENV_SESSION_KEY,
275
+ key: (import.meta.env.DEV ? "yd-admin-dev-session-key" : "") || ENV_SESSION_KEY,
191
276
  source: "dynamic"
192
277
  };
193
278
  }
@@ -197,14 +282,18 @@ async function resolveSessionKey(config) {
197
282
  * @param config 可选的初始化配置
198
283
  */
199
284
  async function initSecureStorage(config) {
200
- localStorageKey = (await resolveLocalKey(config)).key;
201
- if ((await resolveSessionKey(config)).source === "dynamic") {
285
+ const localResolved = await resolveLocalKey(config);
286
+ localStorageKey = localResolved.key;
287
+ localKeySource = localResolved.source;
288
+ const sessionResolved = await resolveSessionKey(config);
289
+ if (sessionResolved.source === "dynamic") {
202
290
  sessionKey = await generateSessionKey();
203
291
  sessionKeyIsString = false;
204
292
  } else {
205
293
  sessionKey = null;
206
294
  sessionKeyIsString = true;
207
295
  }
296
+ sessionKeySource = sessionResolved.source;
208
297
  if (storageReadyResolve) {
209
298
  storageReadyResolve();
210
299
  storageReadyResolve = null;
@@ -230,7 +319,7 @@ var SecureStorage = class {
230
319
  * 是否就绪
231
320
  */
232
321
  get ready() {
233
- return this.storageType === "session" ? !!sessionKey || !!ENV_SESSION_KEY : !!localStorageKey || !!ENV_KEY;
322
+ return this.storageType === "session" ? !!sessionKey || !!globalSessionStorageKey || !!ENV_SESSION_KEY : !!localStorageKey || !!ENV_KEY;
234
323
  }
235
324
  /**
236
325
  * 获取密钥(根据存储类型)
@@ -240,6 +329,7 @@ var SecureStorage = class {
240
329
  if (this.storageType === "session") {
241
330
  if (sessionKey) return sessionKey;
242
331
  if (sessionKeyIsString) {
332
+ if (globalSessionStorageKey) return globalSessionStorageKey;
243
333
  if (import.meta.env.VITE_SESSION_STORAGE_KEY) return import.meta.env.VITE_SESSION_STORAGE_KEY;
244
334
  }
245
335
  return ENV_SESSION_KEY;
@@ -254,7 +344,7 @@ var SecureStorage = class {
254
344
  */
255
345
  async setItem(key, value, options) {
256
346
  const currentKey = this.getCurrentKey();
257
- if (this.storageType === "session" && !sessionKey && true) {
347
+ if (this.storageType === "session" && !sessionKey && !globalSessionStorageKey) {
258
348
  console.warn(`[secureStorage] sessionStorage key not ready, write "${key}" skipped`);
259
349
  return;
260
350
  }
@@ -350,8 +440,90 @@ var SecureStorage = class {
350
440
  this.storage.clear();
351
441
  }
352
442
  };
443
+ /**
444
+ * 创建独立的 SecureStorage 实例
445
+ * @param type 存储类型
446
+ * @param key 可选的独立密钥
447
+ * @returns SecureStorage 实例
448
+ */
449
+ function createSecureStorage(type, key) {
450
+ const instance = new SecureStorage(type);
451
+ if (key) if (type === "local") setStorageEncryptionKey(key);
452
+ else setSessionStorageEncryptionKey(key);
453
+ return instance;
454
+ }
353
455
  const secureLocal = new SecureStorage("local");
354
456
  const secureSession = new SecureStorage("session");
457
+ /**
458
+ * 密钥轮换
459
+ * @param type 存储类型
460
+ * @param newKey 新密钥
461
+ */
462
+ async function rotateStorageKey(type, newKey) {
463
+ const storage = type === "local" ? localStorage : sessionStorage;
464
+ const keys = [];
465
+ for (let i = 0; i < storage.length; i++) keys.push(storage.key(i));
466
+ if (type === "local") {
467
+ const oldKey = globalLocalStorageKey || localStorageKey || ENV_KEY;
468
+ globalLocalStorageKey = newKey;
469
+ localKeySource = "runtime";
470
+ for (const key of keys) try {
471
+ const encrypted = storage.getItem(key);
472
+ if (!encrypted) continue;
473
+ const decrypted = await decrypt(encrypted, oldKey);
474
+ if (!decrypted) continue;
475
+ const reEncrypted = await encrypt(decrypted, newKey);
476
+ storage.setItem(key, reEncrypted);
477
+ } catch {}
478
+ } else {
479
+ const oldKey = globalSessionStorageKey || ENV_SESSION_KEY;
480
+ globalSessionStorageKey = newKey;
481
+ sessionKeySource = "runtime";
482
+ for (const key of keys) try {
483
+ const encrypted = storage.getItem(key);
484
+ if (!encrypted) continue;
485
+ const decrypted = await decrypt(encrypted, oldKey);
486
+ if (!decrypted) continue;
487
+ const reEncrypted = await encrypt(decrypted, newKey);
488
+ storage.setItem(key, reEncrypted);
489
+ } catch {}
490
+ }
491
+ }
492
+ /**
493
+ * 生成 HMAC 签名
494
+ * @param data 数据字符串
495
+ * @param key 密钥
496
+ * @returns 签名
497
+ */
498
+ async function signData(data, key) {
499
+ const encoder = new TextEncoder();
500
+ const keyData = await crypto.subtle.importKey("raw", encoder.encode(key), {
501
+ name: "HMAC",
502
+ hash: "SHA-256"
503
+ }, false, ["sign"]);
504
+ const signature = await crypto.subtle.sign("HMAC", keyData, encoder.encode(data));
505
+ return btoa(String.fromCharCode(...new Uint8Array(signature)));
506
+ }
507
+ /**
508
+ * 验证签名
509
+ * @param data 数据字符串
510
+ * @param signature 签名
511
+ * @param key 密钥
512
+ * @returns 是否有效
513
+ */
514
+ async function verifyData(data, signature, key) {
515
+ try {
516
+ const encoder = new TextEncoder();
517
+ const keyData = await crypto.subtle.importKey("raw", encoder.encode(key), {
518
+ name: "HMAC",
519
+ hash: "SHA-256"
520
+ }, false, ["verify"]);
521
+ const signatureBytes = Uint8Array.from(atob(signature), (c) => c.charCodeAt(0));
522
+ return crypto.subtle.verify("HMAC", keyData, signatureBytes, encoder.encode(data));
523
+ } catch {
524
+ return false;
525
+ }
526
+ }
355
527
  //#endregion
356
528
  //#region src/utils/router.ts
357
529
  /**
@@ -792,9 +964,20 @@ var icon_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
792
964
  function e(element) {
793
965
  return `yd-icon__${element}`;
794
966
  }
967
+ /**
968
+ * 清理 SVG 内容以防止 XSS 攻击
969
+ * 移除 script 标签、事件处理器等危险内容
970
+ */
971
+ function sanitizeSvg(svg) {
972
+ let cleaned = svg.replace(/<script[\s\S]*?<\/script>/gi, "");
973
+ cleaned = cleaned.replace(/\s*on\w+\s*=\s*(["'])[^"']*\1/gi, "");
974
+ cleaned = cleaned.replace(/javascript:/gi, "");
975
+ cleaned = cleaned.replace(/data:/gi, "");
976
+ return cleaned;
977
+ }
795
978
  const svgContent = computed(() => {
796
979
  if (!props.name) return "";
797
- if (props.name.includes("<svg") || props.name.includes("<path")) return props.name;
980
+ if (props.name.includes("<svg") || props.name.includes("<path")) return sanitizeSvg(props.name);
798
981
  return getIcon(props.name) || "";
799
982
  });
800
983
  const iconStyle = computed(() => {
@@ -823,7 +1006,7 @@ var icon_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
823
1006
  }, null, 10, _hoisted_1$56)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Slot Fallback "), renderSlot(_ctx.$slots, "default", {}, void 0, true)], 2112))], 16);
824
1007
  };
825
1008
  }
826
- }), [["__scopeId", "data-v-20774ae9"]]);
1009
+ }), [["__scopeId", "data-v-bb6b8302"]]);
827
1010
  //#endregion
828
1011
  //#region src/components/base/input/input.vue
829
1012
  const _hoisted_1$55 = [
@@ -15790,17 +15973,19 @@ function createPermissionGuard(options) {
15790
15973
  * @returns 角色守卫函数
15791
15974
  */
15792
15975
  function createRoleGuard(options) {
15793
- const { checker, forbiddenPath = "/403" } = options;
15976
+ const { checker, forbiddenPath = "/403", getUserPermissions } = options;
15794
15977
  return async (to, _from, next) => {
15795
15978
  const requiredRoles = to.meta?.roles;
15796
15979
  if (!requiredRoles || requiredRoles.length === 0) {
15797
15980
  next();
15798
15981
  return;
15799
15982
  }
15800
- if (!await checker(requiredRoles, {
15983
+ let userPermissions = {
15801
15984
  roles: [],
15802
15985
  permissions: []
15803
- })) {
15986
+ };
15987
+ if (getUserPermissions) userPermissions = await getUserPermissions() ?? userPermissions;
15988
+ if (!await checker(requiredRoles, userPermissions)) {
15804
15989
  next({ path: forbiddenPath });
15805
15990
  return;
15806
15991
  }
@@ -16052,4 +16237,4 @@ var router_exports = /* @__PURE__ */ __exportAll({
16052
16237
  setRouter: () => setRouter
16053
16238
  });
16054
16239
  //#endregion
16055
- export { ANIMATION_DURATION, COMPONENT_PREFIX, CSS_PREFIX, DEBOUNCE_DEFAULTS, DEBOUNCE_DELAY, DEFAULT_LAYOUT_SIZE, Message, Notification, THROTTLE_DEFAULTS, THROTTLE_DELAY, YdAdminResolver, ai_loader_default as YdAiLoader, anchor_default as YdAnchor, auto_complete_default as YdAutoComplete, avatar_default as YdAvatar, badge_default as YdBadge, breadcrumb_default as YdBreadcrumb, button_default as YdButton, calendar_default as YdCalendar, captcha_default as YdCaptcha, card_default as YdCard, cascader_default as YdCascader, chat_bubble_default as YdChatBubble, chat_page_default as YdChatPage, checkbox_default as YdCheckbox, checkbox_group_default as YdCheckboxGroup, code_block_default as YdCodeBlock, collapse_default as YdCollapse, color_picker_default as YdColorPicker, config_provider_default as YdConfigProvider, context_menu_default as YdContextMenu, conversation_default as YdConversation, crud_page_default as YdCrudPage, date_picker_default as YdDatePicker, date_range_picker_default as YdDateRangePicker, divider_default as YdDivider, drawer_default as YdDrawer, dropdown_default as YdDropdown, empty_default as YdEmpty, flow_chart_default as YdFlowChart, form_default as YdForm, form_item_default as YdFormItem, icon_default as YdIcon, image_default as YdImage, image_preview_group_default as YdImagePreviewGroup, input_default as YdInput, input_number_default as YdInputNumber, layout_default as YdLayout, layout_content_default as YdLayoutContent, layout_header_default as YdLayoutHeader, layout_sidebar_default as YdLayoutSidebar, list_default as YdList, loading_bar_default as YdLoadingBar, login_default as YdLogin, login_centered_default as YdLoginCentered, menu_default as YdMenu, modal_default as YdModal, model_selector_default as YdModelSelector, pagination_default as YdPagination, pin_input_default as YdPinInput, popconfirm_default as YdPopconfirm, progress_default as YdProgress, prompt_input_default as YdPromptInput, radio_default as YdRadio, radio_group_default as YdRadioGroup, rate_default as YdRate, reasoning_default as YdReasoning, result_default as YdResult, router_exports as YdRouter, SchemaForm_default as YdSchemaForm, select_default as YdSelect, skeleton_default as YdSkeleton, slider_default as YdSlider, sources_default as YdSources, space_default as YdSpace, spin_default as YdSpin, statistic_default as YdStatistic, stepper_default as YdStepper, steps_default as YdSteps, streaming_text_default as YdStreamingText, suggestion_default as YdSuggestion, switch_default as YdSwitch, table_default as YdTable, tabs_default as YdTabs, tag_default as YdTag, textarea_default as YdTextarea, time_picker_default as YdTimePicker, timeline_default as YdTimeline, tooltip_default as YdTooltip, transfer_default as YdTransfer, tree_default as YdTree, tree_select_default as YdTreeSelect, upload_default as YdUpload, watermark_default as YdWatermark, Z_INDEX, buildBreadcrumb, changeLocale, checkRoutePermission, clearKeyCache, cn, convertToSimpleRoute, createWatermark, debounce, decrypt, deepClone, dt, dynamicRouter, encrypt, filterMenuItems, findMenuItem, findMenuPath, flattenMenuItems, generateId, generateRouteTitle, generateSessionKey, getBreadcrumbPaths, getCurrentLocale, getIcon, getIconRegistry, i18n, initSecureStorage, isArray, isDate, isEmpty, isEmptyObject, isFunction, isObject, isPathMatch, isPromise, joinPath, loadingBar, menuToRoutes, nf, normalizePath, registerIcon, registerLazyLocale, removeWatermark, searchMenuItems, secureLocal, secureSession, secureStoragePlugin, setLocale, setupI18n, supportedLocales, t, tc, themes, throttle, useConfig, useFormSchema, useFormValidate, useLoading, useLoadingBar, useLoginForm, useNamespace };
16240
+ export { ANIMATION_DURATION, COMPONENT_PREFIX, CSS_PREFIX, DEBOUNCE_DEFAULTS, DEBOUNCE_DELAY, DEFAULT_LAYOUT_SIZE, Message, Notification, THROTTLE_DEFAULTS, THROTTLE_DELAY, YdAdminResolver, ai_loader_default as YdAiLoader, anchor_default as YdAnchor, auto_complete_default as YdAutoComplete, avatar_default as YdAvatar, badge_default as YdBadge, breadcrumb_default as YdBreadcrumb, button_default as YdButton, calendar_default as YdCalendar, captcha_default as YdCaptcha, card_default as YdCard, cascader_default as YdCascader, chat_bubble_default as YdChatBubble, chat_page_default as YdChatPage, checkbox_default as YdCheckbox, checkbox_group_default as YdCheckboxGroup, code_block_default as YdCodeBlock, collapse_default as YdCollapse, color_picker_default as YdColorPicker, config_provider_default as YdConfigProvider, context_menu_default as YdContextMenu, conversation_default as YdConversation, crud_page_default as YdCrudPage, date_picker_default as YdDatePicker, date_range_picker_default as YdDateRangePicker, divider_default as YdDivider, drawer_default as YdDrawer, dropdown_default as YdDropdown, empty_default as YdEmpty, flow_chart_default as YdFlowChart, form_default as YdForm, form_item_default as YdFormItem, icon_default as YdIcon, image_default as YdImage, image_preview_group_default as YdImagePreviewGroup, input_default as YdInput, input_number_default as YdInputNumber, layout_default as YdLayout, layout_content_default as YdLayoutContent, layout_header_default as YdLayoutHeader, layout_sidebar_default as YdLayoutSidebar, list_default as YdList, loading_bar_default as YdLoadingBar, login_default as YdLogin, login_centered_default as YdLoginCentered, menu_default as YdMenu, modal_default as YdModal, model_selector_default as YdModelSelector, pagination_default as YdPagination, pin_input_default as YdPinInput, popconfirm_default as YdPopconfirm, progress_default as YdProgress, prompt_input_default as YdPromptInput, radio_default as YdRadio, radio_group_default as YdRadioGroup, rate_default as YdRate, reasoning_default as YdReasoning, result_default as YdResult, router_exports as YdRouter, SchemaForm_default as YdSchemaForm, select_default as YdSelect, skeleton_default as YdSkeleton, slider_default as YdSlider, sources_default as YdSources, space_default as YdSpace, spin_default as YdSpin, statistic_default as YdStatistic, stepper_default as YdStepper, steps_default as YdSteps, streaming_text_default as YdStreamingText, suggestion_default as YdSuggestion, switch_default as YdSwitch, table_default as YdTable, tabs_default as YdTabs, tag_default as YdTag, textarea_default as YdTextarea, time_picker_default as YdTimePicker, timeline_default as YdTimeline, tooltip_default as YdTooltip, transfer_default as YdTransfer, tree_default as YdTree, tree_select_default as YdTreeSelect, upload_default as YdUpload, watermark_default as YdWatermark, Z_INDEX, buildBreadcrumb, changeLocale, checkRoutePermission, clearKeyCache, cn, convertToSimpleRoute, createSecureStorage, createWatermark, debounce, decrypt, deepClone, dt, dynamicRouter, encrypt, filterMenuItems, findMenuItem, findMenuPath, flattenMenuItems, generateId, generateRouteTitle, generateSessionKey, getBreadcrumbPaths, getCurrentLocale, getIcon, getIconRegistry, getKeySource, i18n, initSecureStorage, isArray, isDate, isEmpty, isEmptyObject, isFunction, isObject, isPathMatch, isPromise, isStorageReady, joinPath, loadingBar, menuToRoutes, nf, normalizePath, registerIcon, registerLazyLocale, removeWatermark, resetStorageKey, rotateStorageKey, searchMenuItems, secureLocal, secureSession, secureStoragePlugin, setLocale, setSessionStorageEncryptionKey, setStorageEncryptionKey, setupI18n, signData, storageReady, supportedLocales, t, tc, themes, throttle, useConfig, useFormSchema, useFormValidate, useLoading, useLoadingBar, useLoginForm, useNamespace, verifyData };
package/dist/style.css CHANGED
@@ -113,24 +113,24 @@
113
113
  animation: yd-spin 1s linear infinite;
114
114
  }
115
115
 
116
- .yd-icon[data-v-20774ae9] {
116
+ .yd-icon[data-v-bb6b8302] {
117
117
  display: inline-flex;
118
118
  align-items: center;
119
119
  justify-content: center;
120
120
  vertical-align: middle;
121
121
  line-height: 1;
122
122
  }
123
- .yd-icon__svg[data-v-20774ae9] {
123
+ .yd-icon__svg[data-v-bb6b8302] {
124
124
  width: 100%;
125
125
  height: 100%;
126
126
  fill: none;
127
127
  }
128
128
  /* Spin animation */
129
- .yd-icon[style*="animation"] .yd-icon__svg[data-v-20774ae9],
130
- .yd-icon__svg--spin[data-v-20774ae9] {
131
- animation: yd-icon-spin-20774ae9 1s linear infinite;
129
+ .yd-icon[style*="animation"] .yd-icon__svg[data-v-bb6b8302],
130
+ .yd-icon__svg--spin[data-v-bb6b8302] {
131
+ animation: yd-icon-spin-bb6b8302 1s linear infinite;
132
132
  }
133
- @keyframes yd-icon-spin-20774ae9 {
133
+ @keyframes yd-icon-spin-bb6b8302 {
134
134
  from {
135
135
  transform: rotate(0deg);
136
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yd-admin",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "基于 Vue 3 的后台管理框架通用组件库 - 轻量、高效、主题可定制",
5
5
  "keywords": [
6
6
  "admin",