From 4ff1c408dc1acfc49e0adc61dc2e539c0c198158 Mon Sep 17 00:00:00 2001 From: vben <anncwb@126.com> Date: 星期五, 25 十二月 2020 01:09:44 +0800 Subject: [PATCH] wip(form): perf form --- src/components/Form/src/components/RadioButtonGroup.vue | 43 src/directives/ripple/index.ts | 8 src/hooks/event/useKeyPress.ts | 6 src/utils/helper/persistent.ts | 4 src/components/Table/src/BasicTable.vue | 2 src/components/Form/src/props.ts | 91 +- src/components/Form/src/hooks/useAdvanced.ts | 50 - src/types/global.d.ts | 10 src/components/util.tsx | 6 src/components/Container/src/collapse/CollapseContainer.vue | 3 src/components/Form/src/helper.ts | 11 src/components/Scrollbar/src/util.ts | 2 src/components/Form/src/hooks/useFormValues.ts | 17 src/components/Form/src/types/form.ts | 34 src/settings/colorSetting.ts | 2 src/components/Table/src/components/renderEditable.tsx | 2 src/router/guard/permissionGuard.ts | 2 src/components/Form/src/componentMap.ts | 5 src/components/VirtualScroll/src/index.tsx | 2 src/components/Form/src/components/FormItem.tsx | 132 ++-- src/hooks/web/useI18n.ts | 2 src/utils/helper/tsxHelper.tsx | 2 src/components/Form/src/components/FormAction.vue | 139 ++++ src/hooks/component/useFormItem.ts | 35 + src/router/types.ts | 2 src/components/Form/src/hooks/useComponentRegister.ts | 4 src/components/Form/src/hooks/useLabelWidth.ts | 19 src/utils/helper/vueHelper.ts | 3 src/components/Modal/src/useModalContext.ts | 6 src/hooks/core/useAttrs.ts | 39 + src/components/Form/src/hooks/useForm.ts | 91 ++ src/components/Form/src/BasicForm.vue | 102 +- src/utils/log.ts | 4 /dev/null | 141 ---- src/utils/http/axios/types.ts | 2 src/utils/index.ts | 2 src/components/Basic/index.ts | 5 src/components/Transition/src/CreateTransition.tsx | 2 yarn.lock | 599 +++++++++---------- src/views/demo/form/RuleForm.vue | 5 package.json | 6 src/components/Table/src/types/column.ts | 2 src/components/Form/src/hooks/useFormContext.ts | 17 src/layouts/page/index.tsx | 2 src/components/Form/src/hooks/useFormEvents.ts | 100 +- 45 files changed, 901 insertions(+), 862 deletions(-) diff --git a/package.json b/package.json index e86aa54..7af8cb7 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,11 @@ "devDependencies": { "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", - "@iconify/json": "^1.1.275", + "@iconify/json": "^1.1.276", "@ls-lint/ls-lint": "^1.9.2", "@purge-icons/generated": "^0.4.1", "@types/echarts": "^4.9.3", - "@types/fs-extra": "^9.0.5", + "@types/fs-extra": "^9.0.6", "@types/globrex": "^0.1.0", "@types/koa-static": "^4.0.1", "@types/lodash-es": "^4.17.4", @@ -102,7 +102,7 @@ "vite-plugin-html": "^1.0.0-beta.2", "vite-plugin-mock": "^1.0.9", "vite-plugin-purge-icons": "^0.4.5", - "vite-plugin-pwa": "^0.1.7", + "vite-plugin-pwa": "^0.2.0", "vue-eslint-parser": "^7.3.0", "yargs": "^16.2.0" }, diff --git a/src/components/Basic/index.ts b/src/components/Basic/index.ts index 73fed74..5c86c28 100644 --- a/src/components/Basic/index.ts +++ b/src/components/Basic/index.ts @@ -1,5 +1,8 @@ import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; +import BasicArrow from './src/BasicArrow.vue'; -export const BasicArrow = createAsyncComponent(() => import('./src/BasicArrow.vue')); +export { BasicArrow }; + +// export const BasicArrow = createAsyncComponent(() => import('./src/BasicArrow.vue')); export const BasicHelp = createAsyncComponent(() => import('./src/BasicHelp.vue')); export const BasicTitle = createAsyncComponent(() => import('./src/BasicTitle.vue')); diff --git a/src/components/Container/src/collapse/CollapseContainer.vue b/src/components/Container/src/collapse/CollapseContainer.vue index a064214..bf20cc1 100644 --- a/src/components/Container/src/collapse/CollapseContainer.vue +++ b/src/components/Container/src/collapse/CollapseContainer.vue @@ -101,7 +101,10 @@ &__action { display: flex; + text-align: right; + flex: 1; align-items: center; + justify-content: flex-end; } } </style> diff --git a/src/components/Form/src/BasicForm.vue b/src/components/Form/src/BasicForm.vue index d1fd566..fd2f697 100644 --- a/src/components/Form/src/BasicForm.vue +++ b/src/components/Form/src/BasicForm.vue @@ -1,6 +1,6 @@ <template> <Form v-bind="{ ...$attrs, ...$props }" ref="formElRef" :model="formModel"> - <Row :class="getProps.compact ? 'compact-form-row' : ''" :style="getRowWrapStyleRef"> + <Row :class="getProps.compact ? 'compact-form-row' : ''" :style="getRowWrapStyle"> <slot name="formHeader" /> <template v-for="schema in getSchema" :key="schema.field"> <FormItem @@ -10,6 +10,7 @@ :formProps="getProps" :allDefaultValues="defaultValueRef" :formModel="formModel" + :setFormModel="setFormModel" > <template #[item]="data" v-for="item in Object.keys($slots)"> <slot :name="item" v-bind="data" /> @@ -17,8 +18,9 @@ </FormItem> </template> + <!-- --> <FormAction - v-bind="{ ...getActionPropsRef, ...advanceState }" + v-bind="{ ...getProps, ...advanceState }" @toggle-advanced="handleToggleAdvanced" /> <slot name="formFooter" /> @@ -28,14 +30,12 @@ <script lang="ts"> import type { FormActionType, FormProps, FormSchema } from './types/form'; import type { AdvanceState } from './types/hooks'; - import type { Ref, WatchStopHandle } from 'vue'; - import type { ValidateFields } from 'ant-design-vue/lib/form/interface'; + import type { CSSProperties, Ref, WatchStopHandle } from 'vue'; import { defineComponent, reactive, ref, computed, unref, onMounted, watch, toRefs } from 'vue'; import { Form, Row } from 'ant-design-vue'; - import FormItem from './FormItem'; - import { basicProps } from './props'; - import FormAction from './FormAction'; + import FormItem from './components/FormItem'; + import FormAction from './components/FormAction.vue'; import { dateItemType } from './helper'; import moment from 'moment'; @@ -44,7 +44,11 @@ import { useFormValues } from './hooks/useFormValues'; import useAdvanced from './hooks/useAdvanced'; - import { useFormAction } from './hooks/useFormAction'; + import { useFormEvents } from './hooks/useFormEvents'; + import { createFormContext } from './hooks/useFormContext'; + + import { basicProps } from './props'; + export default defineComponent({ name: 'BasicForm', components: { FormItem, Form, Row, FormAction }, @@ -52,12 +56,7 @@ props: basicProps, emits: ['advanced-change', 'reset', 'submit', 'register'], setup(props, { emit }) { - const formModel = reactive({}); - - const actionState = reactive({ - resetAction: {}, - submitAction: {}, - }); + const formModel = reactive<Recordable>({}); const advanceState = reactive<AdvanceState>({ isAdvanced: true, @@ -66,37 +65,24 @@ actionSpan: 6, }); - const defaultValueRef = ref<any>({}); + const defaultValueRef = ref<Recordable>({}); const isInitedDefaultRef = ref(false); const propsRef = ref<Partial<FormProps>>({}); const schemaRef = ref<Nullable<FormSchema[]>>(null); const formElRef = ref<Nullable<FormActionType>>(null); - const getMergePropsRef = computed( + // Get the basic configuration of the form + const getProps = computed( (): FormProps => { return deepMerge(cloneDeep(props), unref(propsRef)); } ); - const getRowWrapStyleRef = computed((): any => { - const { baseRowStyle } = unref(getMergePropsRef); - return baseRowStyle || {}; - }); - - // 鑾峰彇琛ㄥ崟鍩烘湰閰嶇疆 - const getProps = computed( - (): FormProps => { - return { - ...unref(getMergePropsRef), - resetButtonOptions: deepMerge( - actionState.resetAction, - unref(getMergePropsRef).resetButtonOptions || {} - ), - submitButtonOptions: deepMerge( - actionState.submitAction, - unref(getMergePropsRef).submitButtonOptions || {} - ), - }; + // Get uniform row style + const getRowWrapStyle = computed( + (): CSSProperties => { + const { baseRowStyle = {} } = unref(getProps); + return baseRowStyle; } ); @@ -120,18 +106,19 @@ return schemas as FormSchema[]; }); - const { getActionPropsRef, handleToggleAdvanced } = useAdvanced({ + const { handleToggleAdvanced } = useAdvanced({ advanceState, emit, - getMergePropsRef, getProps, getSchema, formModel, defaultValueRef, }); + const { transformDateFunc, fieldMapToTime } = toRefs(props); + const { handleFormValues, initDefault } = useFormValues({ - transformDateFuncRef: transformDateFunc as Ref<Fn<any>>, + transformDateFuncRef: transformDateFunc, fieldMapToTimeRef: fieldMapToTime, defaultValueRef, getSchema, @@ -139,7 +126,7 @@ }); const { - // handleSubmit, + handleSubmit, setFieldsValue, clearValidate, validate, @@ -149,7 +136,8 @@ appendSchemaByField, removeSchemaByFiled, resetFields, - } = useFormAction({ + scrollToField, + } = useFormEvents({ emit, getProps, formModel, @@ -158,14 +146,19 @@ formElRef: formElRef as Ref<FormActionType>, schemaRef: schemaRef as Ref<FormSchema[]>, handleFormValues, - actionState, + }); + + createFormContext({ + resetAction: resetFields, + submitAction: handleSubmit, }); watch( - () => unref(getMergePropsRef).model, + () => unref(getProps).model, () => { - if (!unref(getMergePropsRef).model) return; - setFieldsValue(unref(getMergePropsRef).model); + const { model } = unref(getProps); + if (!model) return; + setFieldsValue(model); }, { immediate: true, @@ -178,16 +171,19 @@ if (unref(isInitedDefaultRef)) { return stopWatch(); } - if (schema && schema.length) { + if (schema?.length) { initDefault(); isInitedDefaultRef.value = true; } } ); - function setProps(formProps: Partial<FormProps>): void { - const mergeProps = deepMerge(unref(propsRef) || {}, formProps); - propsRef.value = mergeProps; + async function setProps(formProps: Partial<FormProps>): Promise<void> { + propsRef.value = deepMerge(unref(propsRef) || {}, formProps); + } + + function setFormModel(key: string, value: any) { + formModel[key] = value; } const formActionType: Partial<FormActionType> = { @@ -199,8 +195,10 @@ removeSchemaByFiled, appendSchemaByField, clearValidate, - validateFields: validateFields as ValidateFields, - validate: validate as ValidateFields, + validateFields, + validate, + submit: handleSubmit, + scrollToField: scrollToField, }; onMounted(() => { @@ -211,14 +209,14 @@ return { handleToggleAdvanced, formModel, - getActionPropsRef, defaultValueRef, advanceState, - getRowWrapStyleRef, + getRowWrapStyle, getProps, formElRef, getSchema, formActionType, + setFormModel, ...formActionType, }; }, diff --git a/src/components/Form/src/FormAction.tsx b/src/components/Form/src/FormAction.tsx deleted file mode 100644 index 2d2fb89..0000000 --- a/src/components/Form/src/FormAction.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import type { ColEx } from './types/index'; - -import { defineComponent, unref, computed, PropType } from 'vue'; -import { Form, Col } from 'ant-design-vue'; -import { Button } from '/@/components/Button'; -import { BasicArrow } from '/@/components/Basic/index'; - -import { getSlot } from '/@/utils/helper/tsxHelper'; -import { useI18n } from '/@/hooks/web/useI18n'; -import { propTypes } from '/@/utils/propTypes'; - -const { t } = useI18n(); - -export default defineComponent({ - name: 'BasicFormAction', - props: { - show: propTypes.bool.def(true), - showResetButton: propTypes.bool.def(true), - showSubmitButton: propTypes.bool.def(true), - showAdvancedButton: propTypes.bool.def(true), - resetButtonOptions: { - type: Object as PropType<any>, - default: {}, - }, - submitButtonOptions: { - type: Object as PropType<any>, - default: {}, - }, - actionColOptions: { - type: Object as PropType<any>, - default: {}, - }, - actionSpan: propTypes.number.def(6), - isAdvanced: propTypes.bool, - hideAdvanceBtn: propTypes.bool, - }, - emits: ['toggle-advanced'], - setup(props, { slots, emit }) { - const getResetBtnOptionsRef = computed(() => { - return { - text: t('component.form.resetButton'), - ...props.resetButtonOptions, - }; - }); - - const getSubmitBtnOptionsRef = computed(() => { - return { - text: t('component.form.submitButton'), - // htmlType: 'submit', - ...props.submitButtonOptions, - }; - }); - - const actionColOpt = computed(() => { - const { showAdvancedButton, actionSpan: span, actionColOptions } = props; - const actionSpan = 24 - span; - const advancedSpanObj = showAdvancedButton ? { span: actionSpan < 6 ? 24 : actionSpan } : {}; - const actionColOpt: Partial<ColEx> = { - span: showAdvancedButton ? 6 : 4, - ...advancedSpanObj, - ...actionColOptions, - }; - return actionColOpt; - }); - - function toggleAdvanced() { - emit('toggle-advanced'); - } - - function renderAdvanceButton() { - const { showAdvancedButton, hideAdvanceBtn, isAdvanced } = props; - - if (!showAdvancedButton || !!hideAdvanceBtn) { - return null; - } - return ( - <Button type="default" class="mr-2" onClick={toggleAdvanced}> - {() => ( - <> - {isAdvanced ? t('component.form.putAway') : t('component.form.unfold')} - <BasicArrow expand={!isAdvanced} top /> - </> - )} - </Button> - ); - } - - function renderResetButton() { - const { showResetButton } = props; - if (!showResetButton) { - return null; - } - return ( - <Button type="default" class="mr-2" {...unref(getResetBtnOptionsRef)}> - {() => unref(getResetBtnOptionsRef).text} - </Button> - ); - } - - function renderSubmitButton() { - const { showSubmitButton } = props; - if (!showSubmitButton) { - return null; - } - return ( - <Button type="primary" {...unref(getSubmitBtnOptionsRef)}> - {() => unref(getSubmitBtnOptionsRef).text} - </Button> - ); - } - - return () => { - if (!props.show) { - return null; - } - - return ( - <Col {...unref(actionColOpt)} style={{ textAlign: 'right' }}> - {() => ( - <Form.Item> - {() => ( - <> - {getSlot(slots, 'advanceBefore')} - {renderAdvanceButton()} - - {getSlot(slots, 'resetBefore')} - {renderResetButton()} - - {getSlot(slots, 'submitBefore')} - {renderSubmitButton()} - - {getSlot(slots, 'submitAfter')} - </> - )} - </Form.Item> - )} - </Col> - ); - }; - }, -}); diff --git a/src/components/Form/src/componentMap.ts b/src/components/Form/src/componentMap.ts index b86e7b3..bf63b4d 100644 --- a/src/components/Form/src/componentMap.ts +++ b/src/components/Form/src/componentMap.ts @@ -1,4 +1,4 @@ -import { Component } from 'vue'; +import type { Component } from 'vue'; import type { ComponentType } from './types/index'; /** @@ -17,10 +17,11 @@ TimePicker, TreeSelect, } from 'ant-design-vue'; + import RadioButtonGroup from './components/RadioButtonGroup.vue'; import { BasicUpload } from '/@/components/Upload'; -const componentMap = new Map<ComponentType, any>(); +const componentMap = new Map<ComponentType, Component>(); componentMap.set('Input', Input); componentMap.set('InputGroup', Input.Group); diff --git a/src/components/Form/src/components/FormAction.vue b/src/components/Form/src/components/FormAction.vue new file mode 100644 index 0000000..4c47ea8 --- /dev/null +++ b/src/components/Form/src/components/FormAction.vue @@ -0,0 +1,139 @@ +<template> + <a-col + v-bind="actionColOpt" + class="mb-2" + :style="{ textAlign: 'right' }" + v-if="showActionButtonGroup" + > + <FormItem> + <slot name="resetBefore" /> + <Button + type="default" + class="mr-2" + v-bind="getResetBtnOptions" + @click="resetAction" + v-if="showResetButton" + > + {{ getResetBtnOptions.text }} + </Button> + <slot name="submitBefore" /> + + <Button + type="primary" + class="mr-2" + v-bind="getSubmitBtnOptions" + @click="submitAction" + v-if="showSubmitButton" + > + {{ getSubmitBtnOptions.text }} + </Button> + + <slot name="advanceBefore" /> + <Button + type="link" + size="small" + @click="toggleAdvanced" + v-if="showAdvancedButton && !hideAdvanceBtn" + > + {{ isAdvanced ? t('component.form.putAway') : t('component.form.unfold') }} + <BasicArrow class="ml-1" :expand="!isAdvanced" top /> + </Button> + <slot name="advanceAfter" /> + </FormItem> + </a-col> +</template> +<script lang="ts"> + import type { ColEx } from '../types/index'; + import type { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; + + import { defineComponent, computed, PropType } from 'vue'; + import { Form } from 'ant-design-vue'; + import { Button } from '/@/components/Button'; + import { BasicArrow } from '/@/components/Basic/index'; + import { useFormContext } from '../hooks/useFormContext'; + + import { useI18n } from '/@/hooks/web/useI18n'; + import { propTypes } from '/@/utils/propTypes'; + + type ButtonOptions = Partial<ButtonProps> & { text: string }; + + export default defineComponent({ + name: 'BasicFormAction', + components: { + FormItem: Form, + Button, + BasicArrow, + }, + props: { + showActionButtonGroup: propTypes.bool.def(true), + showResetButton: propTypes.bool.def(true), + showSubmitButton: propTypes.bool.def(true), + showAdvancedButton: propTypes.bool.def(true), + resetButtonOptions: { + type: Object as PropType<ButtonOptions>, + default: {}, + }, + submitButtonOptions: { + type: Object as PropType<ButtonOptions>, + default: {}, + }, + actionColOptions: { + type: Object as PropType<Partial<ColEx>>, + default: {}, + }, + actionSpan: propTypes.number.def(6), + isAdvanced: propTypes.bool, + hideAdvanceBtn: propTypes.bool, + }, + setup(props, { emit }) { + const { t } = useI18n(); + + const actionColOpt = computed(() => { + const { showAdvancedButton, actionSpan: span, actionColOptions } = props; + const actionSpan = 24 - span; + const advancedSpanObj = showAdvancedButton + ? { span: actionSpan < 6 ? 24 : actionSpan } + : {}; + const actionColOpt: Partial<ColEx> = { + span: showAdvancedButton ? 6 : 4, + ...advancedSpanObj, + ...actionColOptions, + }; + return actionColOpt; + }); + + const getResetBtnOptions = computed( + (): ButtonOptions => { + return Object.assign( + { + text: t('component.form.resetButton'), + }, + props.resetButtonOptions + ); + } + ); + + const getSubmitBtnOptions = computed(() => { + return Object.assign( + { + text: t('component.form.submitButton'), + }, + props.submitButtonOptions + ); + }); + + function toggleAdvanced() { + emit('toggle-advanced'); + } + + return { + t, + actionColOpt, + getResetBtnOptions, + getSubmitBtnOptions, + toggleAdvanced, + ...useFormContext(), + }; + }, + }); +</script> diff --git a/src/components/Form/src/FormItem.tsx b/src/components/Form/src/components/FormItem.tsx similarity index 74% rename from src/components/Form/src/FormItem.tsx rename to src/components/Form/src/components/FormItem.tsx index 50eab6f..e952f27 100644 --- a/src/components/Form/src/FormItem.tsx +++ b/src/components/Form/src/components/FormItem.tsx @@ -1,21 +1,21 @@ -import type { PropType } from 'vue'; -import type { FormActionType, FormProps } from './types/form'; -import type { FormSchema } from './types/form'; +import type { PropType, Ref } from 'vue'; +import type { FormActionType, FormProps } from '../types/form'; +import type { FormSchema } from '../types/form'; import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; import type { TableActionType } from '/@/components/Table'; +import type { ComponentType } from '../types'; -import { defineComponent, computed, unref, toRef } from 'vue'; +import { defineComponent, computed, unref, toRefs } from 'vue'; import { Form, Col } from 'ant-design-vue'; -import { componentMap } from './componentMap'; +import { componentMap } from '../componentMap'; import { BasicHelp } from '/@/components/Basic'; import { isBoolean, isFunction } from '/@/utils/is'; import { getSlot } from '/@/utils/helper/tsxHelper'; -import { createPlaceholderMessage } from './helper'; +import { createPlaceholderMessage, setComponentRuleType } from '../helper'; import { upperFirst, cloneDeep } from 'lodash-es'; -import { useItemLabelWidth } from './hooks/useLabelWidth'; -import { ComponentType } from './types'; +import { useItemLabelWidth } from '../hooks/useLabelWidth'; import { isNumber } from '/@/utils/is'; import { useI18n } from '/@/hooks/web/useI18n'; @@ -32,12 +32,16 @@ default: {}, }, allDefaultValues: { - type: Object as PropType<any>, + type: Object as PropType<Recordable>, default: {}, }, formModel: { - type: Object as PropType<any>, + type: Object as PropType<Recordable>, default: {}, + }, + setFormModel: { + type: Function as PropType<(key: string, value: any) => void>, + default: null, }, tableAction: { type: Object as PropType<TableActionType>, @@ -48,10 +52,15 @@ }, setup(props, { slots }) { const { t } = useI18n(); - // @ts-ignore - const itemLabelWidthRef = useItemLabelWidth(toRef(props, 'schema'), toRef(props, 'formProps')); - const getValuesRef = computed(() => { + const { schema, formProps } = toRefs(props) as { + schema: Ref<FormSchema>; + formProps: Ref<FormProps>; + }; + + const itemLabelWidthProp = useItemLabelWidth(schema, formProps); + + const getValues = computed(() => { const { allDefaultValues, formModel, schema } = props; const { mergeDynamicData } = props.formProps; return { @@ -61,12 +70,12 @@ ...mergeDynamicData, ...allDefaultValues, ...formModel, - }, + } as Recordable, schema: schema, }; }); - const getComponentsPropsRef = computed(() => { + const getComponentsProps = computed(() => { const { schema, tableAction, formModel, formActionType } = props; const { componentProps = {} } = schema; if (!isFunction(componentProps)) { @@ -75,19 +84,18 @@ return componentProps({ schema, tableAction, formModel, formActionType }) || {}; }); - const getDisableRef = computed(() => { + const getDisable = computed(() => { const { disabled: globDisabled } = props.formProps; const { dynamicDisabled } = props.schema; - const { disabled: itemDisabled = false } = unref(getComponentsPropsRef); + const { disabled: itemDisabled = false } = unref(getComponentsProps); let disabled = !!globDisabled || itemDisabled; if (isBoolean(dynamicDisabled)) { disabled = dynamicDisabled; } if (isFunction(dynamicDisabled)) { - disabled = dynamicDisabled(unref(getValuesRef)); + disabled = dynamicDisabled(unref(getValues)); } - return disabled; }); @@ -109,10 +117,10 @@ isIfShow = ifShow; } if (isFunction(show)) { - isShow = show(unref(getValuesRef)); + isShow = show(unref(getValues)); } if (isFunction(ifShow)) { - isIfShow = ifShow(unref(getValuesRef)); + isIfShow = ifShow(unref(getValues)); } isShow = isShow && itemIsAdvanced; return { isShow, isIfShow }; @@ -129,7 +137,7 @@ } = props.schema; if (isFunction(dynamicRules)) { - return dynamicRules(unref(getValuesRef)) as ValidationRule[]; + return dynamicRules(unref(getValues)) as ValidationRule[]; } let rules: ValidationRule[] = cloneDeep(defRules) as ValidationRule[]; @@ -151,23 +159,15 @@ const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel') ? rulesMessageJoinLabel : globalRulesMessageJoinLabel; + rule.message = rule.message || createPlaceholderMessage(component) + `${joinLabel ? label : ''}`; + if (component.includes('Input') || component.includes('Textarea')) { rule.whitespace = true; } - if ( - component.includes('DatePicker') || - component.includes('MonthPicker') || - component.includes('WeekPicker') || - component.includes('TimePicker') - ) { - rule.type = 'object'; - } else if (component.includes('RangePicker') || component.includes('Upload')) { - rule.type = 'array'; - } else if (component.includes('InputNumber')) { - rule.type = 'number'; - } + + setComponentRuleType(rule, component); } } @@ -181,10 +181,12 @@ } function handleValue(component: ComponentType, field: string) { - const val = (props.formModel as any)[field]; + const val = props.formModel[field]; if (['Input', 'InputPassword', 'InputSearch', 'InputTextArea'].includes(component)) { if (val && isNumber(val)) { - (props.formModel as any)[field] = `${val}`; + props.setFormModel(field, `${val}`); + + // props.formModel[field] = `${val}`; return `${val}`; } return val; @@ -206,56 +208,59 @@ const eventKey = `on${upperFirst(changeEvent)}`; const on = { - [eventKey]: (e: any) => { + [eventKey]: (e: Nullable<Recordable>) => { if (propsData[eventKey]) { propsData[eventKey](e); } const target = e ? e.target : null; + const value = target ? (isCheck ? target.checked : target.value) : e; - (props.formModel as any)[field] = value; + props.setFormModel(field, value); + // props.formModel[field] = value; }, }; - const Comp = componentMap.get(component); + const Comp = componentMap.get(component) as typeof defineComponent; const { autoSetPlaceHolder, size } = props.formProps; - const propsData: any = { + const propsData: Recordable = { allowClear: true, getPopupContainer: (trigger: Element) => trigger.parentNode, size, - ...unref(getComponentsPropsRef), - disabled: unref(getDisableRef), + ...unref(getComponentsProps), + disabled: unref(getDisable), }; const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder; let placeholder; // RangePicker place涓烘暟缁� if (isCreatePlaceholder && component !== 'RangePicker' && component) { - placeholder = - (unref(getComponentsPropsRef) && unref(getComponentsPropsRef).placeholder) || - createPlaceholderMessage(component); + placeholder = unref(getComponentsProps)?.placeholder || createPlaceholderMessage(component); } propsData.placeholder = placeholder; propsData.codeField = field; - propsData.formValues = unref(getValuesRef); - const bindValue = { + propsData.formValues = unref(getValues); + + const bindValue: Recordable = { [valueField || (isCheck ? 'checked' : 'value')]: handleValue(component, field), }; + const compAttr: Recordable = { + ...propsData, + ...on, + ...bindValue, + }; + if (!renderComponentContent) { - return <Comp {...propsData} {...on} {...bindValue} />; + return <Comp {...compAttr} />; } const compSlot = isFunction(renderComponentContent) - ? { ...renderComponentContent(unref(getValuesRef)) } + ? { ...renderComponentContent(unref(getValues)) } : { default: () => renderComponentContent, }; - return ( - <Comp {...propsData} {...on} {...bindValue}> - {compSlot} - </Comp> - ); + return <Comp {...compAttr}>{compSlot}</Comp>; } function renderLabelHelpMessage() { @@ -280,20 +285,22 @@ function renderItem() { const { itemProps, slot, render, field } = props.schema; - const { labelCol, wrapperCol } = unref(itemLabelWidthRef); + const { labelCol, wrapperCol } = unref(itemLabelWidthProp); const { colon } = props.formProps; + const getContent = () => { return slot - ? getSlot(slots, slot, unref(getValuesRef)) + ? getSlot(slots, slot, unref(getValues)) : render - ? render(unref(getValuesRef)) + ? render(unref(getValues)) : renderComponent(); }; + return ( <Form.Item name={field} colon={colon} - {...(itemProps as any)} + {...(itemProps as Recordable)} label={renderLabelHelpMessage()} rules={handleRules()} labelCol={labelCol} @@ -306,20 +313,23 @@ return () => { const { colProps = {}, colSlot, renderColContent, component } = props.schema; if (!componentMap.has(component)) return null; + const { baseColProps = {} } = props.formProps; const realColProps = { ...baseColProps, ...colProps }; const { isIfShow, isShow } = getShow(); + const getContent = () => { return colSlot - ? getSlot(slots, colSlot, unref(getValuesRef)) + ? getSlot(slots, colSlot, unref(getValues)) : renderColContent - ? renderColContent(unref(getValuesRef)) + ? renderColContent(unref(getValues)) : renderItem(); }; + return ( isIfShow && ( - <Col {...realColProps} class={!isShow ? 'hidden' : ''}> + <Col {...realColProps} class={{ hidden: !isShow }}> {() => getContent()} </Col> ) diff --git a/src/components/Form/src/components/RadioButtonGroup.vue b/src/components/Form/src/components/RadioButtonGroup.vue index 5585a62..a6bb774 100644 --- a/src/components/Form/src/components/RadioButtonGroup.vue +++ b/src/components/Form/src/components/RadioButtonGroup.vue @@ -1,18 +1,23 @@ +<!-- + * @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component +--> + <template> - <RadioGroup v-bind="$attrs" v-model:value="valueRef" button-style="solid"> + <RadioGroup v-bind="attrs" v-model:value="state" button-style="solid"> <template v-for="item in getOptions" :key="`${item.value}`"> <RadioButton :value="item.value"> {{ item.label }} </RadioButton> </template> </RadioGroup> </template> <script lang="ts"> - import { defineComponent, ref, PropType, watch, unref, computed } from 'vue'; + import { defineComponent, PropType, computed } from 'vue'; import { Radio } from 'ant-design-vue'; - import {} from 'ant-design-vue/es/radio/Group'; import { isString } from '/@/utils/is'; - + import { useRuleFormItem } from '/@/hooks/component/useFormItem'; + import { useAttrs } from '/@/hooks/core/useAttrs'; type OptionsItem = { label: string; value: string; disabled?: boolean }; type RadioItem = string | OptionsItem; + export default defineComponent({ name: 'RadioButtonGroup', components: { @@ -28,34 +33,22 @@ default: () => [], }, }, - setup(props, { emit }) { - const valueRef = ref(''); - - watch( - () => props.value, - (v = '') => { - valueRef.value = v; - }, - { immediate: true } - ); - - watch( - () => unref(valueRef), - () => { - emit('change', valueRef.value); - }, - { immediate: true } - ); - + setup(props) { + const attrs = useAttrs(); + // Embedded in the form, just use the hook binding to perform form verification + const [state] = useRuleFormItem(props); + // Processing options value const getOptions = computed((): OptionsItem[] => { const { options } = props; - if (!options || options.length === 0) return []; + if (!options || options?.length === 0) return []; + const isStringArr = options.some((item) => isString(item)); if (!isStringArr) return options as OptionsItem[]; + return options.map((item) => ({ label: item, value: item })) as OptionsItem[]; }); - return { valueRef, getOptions }; + return { state, getOptions, attrs }; }, }); </script> diff --git a/src/components/Form/src/helper.ts b/src/components/Form/src/helper.ts index e1c64c3..938101e 100644 --- a/src/components/Form/src/helper.ts +++ b/src/components/Form/src/helper.ts @@ -1,3 +1,4 @@ +import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; import type { ComponentType } from './types/index'; import { useI18n } from '/@/hooks/web/useI18n'; @@ -30,6 +31,16 @@ return ['DatePicker', 'MonthPicker', 'RangePicker', 'WeekPicker', 'TimePicker']; } +export function setComponentRuleType(rule: ValidationRule, component: ComponentType) { + if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) { + rule.type = 'object'; + } else if (['RangePicker', 'Upload', 'CheckboxGroup', 'TimePicker'].includes(component)) { + rule.type = 'array'; + } else if (['InputNumber'].includes(component)) { + rule.type = 'number'; + } +} + /** * 鏃堕棿瀛楁 */ diff --git a/src/components/Form/src/hooks/useAdvanced.ts b/src/components/Form/src/hooks/useAdvanced.ts index 560751d..dee5c12 100644 --- a/src/components/Form/src/hooks/useAdvanced.ts +++ b/src/components/Form/src/hooks/useAdvanced.ts @@ -13,28 +13,28 @@ interface UseAdvancedContext { advanceState: AdvanceState; emit: EmitType; - getMergePropsRef: ComputedRef<FormProps>; getProps: ComputedRef<FormProps>; getSchema: ComputedRef<FormSchema[]>; - formModel: any; - defaultValueRef: Ref<any>; + formModel: Recordable; + defaultValueRef: Ref<Recordable>; } export default function ({ advanceState, emit, - getMergePropsRef, getProps, getSchema, formModel, defaultValueRef, }: UseAdvancedContext) { const { realWidthRef, screenEnum, screenRef } = useBreakpoint(); - const getEmptySpanRef = computed((): number => { + + const getEmptySpan = computed((): number => { if (!advanceState.isAdvanced) { return 0; } - const emptySpan = unref(getMergePropsRef).emptySpan || 0; + // For some special cases, you need to manually specify additional blank lines + const emptySpan = unref(getProps).emptySpan || 0; if (isNumber(emptySpan)) { return emptySpan; @@ -47,27 +47,6 @@ return screenSpan || span || 0; } return 0; - }); - - const getActionPropsRef = computed(() => { - const { - resetButtonOptions, - submitButtonOptions, - showActionButtonGroup, - showResetButton, - showSubmitButton, - showAdvancedButton, - actionColOptions, - } = unref(getProps); - return { - resetButtonOptions, - submitButtonOptions, - show: showActionButtonGroup, - showResetButton, - showSubmitButton, - showAdvancedButton, - actionColOptions, - }; }); watch( @@ -90,6 +69,7 @@ parseInt(itemCol.sm as string) || (itemCol.span as number) || BASIC_COL_LEN; + const lgWidth = parseInt(itemCol.lg as string) || mdWidth; const xlWidth = parseInt(itemCol.xl as string) || lgWidth; const xxlWidth = parseInt(itemCol.xxl as string) || xlWidth; @@ -102,15 +82,16 @@ } else { itemColSum += xxlWidth; } + if (isLastAction) { advanceState.hideAdvanceBtn = false; if (itemColSum <= BASIC_COL_LEN * 2) { - // 灏忎簬绛変簬2琛屾椂锛屼笉鏄剧ず鏀惰捣灞曞紑鎸夐挳 + // When less than or equal to 2 lines, the collapse and expand buttons are not displayed advanceState.hideAdvanceBtn = true; advanceState.isAdvanced = true; } else if ( itemColSum > BASIC_COL_LEN * 2 && - itemColSum <= BASIC_COL_LEN * (unref(getMergePropsRef).autoAdvancedLine || 3) + itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3) ) { advanceState.hideAdvanceBtn = false; @@ -168,13 +149,9 @@ } } - advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpanRef); + advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpan); - getAdvanced( - unref(getActionPropsRef).actionColOptions || { span: BASIC_COL_LEN }, - itemColSum, - true - ); + getAdvanced(unref(getProps).actionColOptions || { span: BASIC_COL_LEN }, itemColSum, true); emit('advanced-change'); } @@ -182,5 +159,6 @@ function handleToggleAdvanced() { advanceState.isAdvanced = !advanceState.isAdvanced; } - return { getActionPropsRef, handleToggleAdvanced }; + + return { handleToggleAdvanced }; } diff --git a/src/components/Form/src/hooks/useComponentRegister.ts b/src/components/Form/src/hooks/useComponentRegister.ts index 753e99b..d203480 100644 --- a/src/components/Form/src/hooks/useComponentRegister.ts +++ b/src/components/Form/src/hooks/useComponentRegister.ts @@ -1,7 +1,9 @@ import type { ComponentType } from '../types/index'; import { tryOnUnmounted } from '/@/utils/helper/vueHelper'; import { add, del } from '../componentMap'; -export function useComponentRegister(compName: ComponentType, comp: any) { +import type { Component } from 'vue'; + +export function useComponentRegister(compName: ComponentType, comp: Component) { add(compName, comp); tryOnUnmounted(() => { del(compName); diff --git a/src/components/Form/src/hooks/useForm.ts b/src/components/Form/src/hooks/useForm.ts index e856faf..4ba2ba9 100644 --- a/src/components/Form/src/hooks/useForm.ts +++ b/src/components/Form/src/hooks/useForm.ts @@ -1,23 +1,28 @@ -import { ref, onUnmounted, unref } from 'vue'; +import { ref, onUnmounted, unref, nextTick } from 'vue'; import { isInSetup } from '/@/utils/helper/vueHelper'; import { isProdMode } from '/@/utils/env'; +import { error } from '/@/utils/log'; import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form'; import type { NamePath } from 'ant-design-vue/lib/form/interface'; -export declare type ValidateFields = (nameList?: NamePath[]) => Promise<any>; +export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>; export function useForm(props?: Partial<FormProps>): UseFormReturnType { isInSetup(); - const formRef = ref<FormActionType | null>(null); - const loadedRef = ref<boolean | null>(false); - function getForm() { + const formRef = ref<Nullable<FormActionType>>(null); + const loadedRef = ref<Nullable<boolean>>(false); + + async function getForm() { const form = unref(formRef); if (!form) { - throw new Error('formRef is Null'); + error( + 'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!' + ); } + await nextTick(); return form as FormActionType; } function register(instance: FormActionType) { @@ -27,45 +32,73 @@ loadedRef.value = null; }); if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return; + formRef.value = instance; props && instance.setProps(props); loadedRef.value = true; } const methods: FormActionType = { - setProps: (formProps: Partial<FormProps>) => { - getForm().setProps(formProps); + scrollToField: async (name: NamePath, options?: ScrollOptions | undefined) => { + const form = await getForm(); + form.scrollToField(name, options); }, - updateSchema: (data: Partial<FormSchema> | Partial<FormSchema>[]) => { - getForm().updateSchema(data); + setProps: async (formProps: Partial<FormProps>) => { + const form = await getForm(); + form.setProps(formProps); }, - clearValidate: (name?: string | string[]) => { - getForm().clearValidate(name); + + updateSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => { + const form = await getForm(); + form.updateSchema(data); }, + + clearValidate: async (name?: string | string[]) => { + const form = await getForm(); + form.clearValidate(name); + }, + resetFields: async () => { - await getForm().resetFields(); + getForm().then(async (form) => { + await form.resetFields(); + }); }, - removeSchemaByFiled: (field: string | string[]) => { - getForm().removeSchemaByFiled(field); + + removeSchemaByFiled: async (field: string | string[]) => { + const form = await getForm(); + form.removeSchemaByFiled(field); }, - getFieldsValue: () => { - return getForm().getFieldsValue(); + + // TODO promisify + getFieldsValue: <T>() => { + return unref(formRef)?.getFieldsValue() as T; }, - setFieldsValue: <T>(values: T) => { - getForm().setFieldsValue<T>(values); + + setFieldsValue: async <T>(values: T) => { + const form = await getForm(); + form.setFieldsValue<T>(values); }, - appendSchemaByField: (schema: FormSchema, prefixField?: string | undefined) => { - getForm().appendSchemaByField(schema, prefixField); + + appendSchemaByField: async (schema: FormSchema, prefixField?: string | undefined) => { + const form = await getForm(); + form.appendSchemaByField(schema, prefixField); }, + submit: async (): Promise<any> => { - return getForm().submit(); + const form = await getForm(); + return form.submit(); }, - validate: ((async (nameList?: NamePath[]): Promise<any> => { - return getForm().validate(nameList); - }) as any) as ValidateFields, - validateFields: ((async (nameList?: NamePath[]): Promise<any> => { - return getForm().validate(nameList); - }) as any) as ValidateFields, - } as FormActionType; + + validate: async (nameList?: NamePath[]): Promise<Recordable> => { + const form = await getForm(); + return form.validate(nameList); + }, + + validateFields: async (nameList?: NamePath[]): Promise<Recordable> => { + const form = await getForm(); + return form.validateFields(nameList); + }, + }; + return [register, methods]; } diff --git a/src/components/Form/src/hooks/useFormContext.ts b/src/components/Form/src/hooks/useFormContext.ts new file mode 100644 index 0000000..9bfc925 --- /dev/null +++ b/src/components/Form/src/hooks/useFormContext.ts @@ -0,0 +1,17 @@ +import { InjectionKey } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface FormContextProps { + resetAction: () => Promise<void>; + submitAction: () => Promise<void>; +} + +const key: InjectionKey<FormContextProps> = Symbol(); + +export function createFormContext(context: FormContextProps) { + return createContext<FormContextProps>(context, key); +} + +export function useFormContext() { + return useContext<FormContextProps>(key); +} diff --git a/src/components/Form/src/hooks/useFormAction.ts b/src/components/Form/src/hooks/useFormEvents.ts similarity index 70% rename from src/components/Form/src/hooks/useFormAction.ts rename to src/components/Form/src/hooks/useFormEvents.ts index 1a156c4..74dc32d 100644 --- a/src/components/Form/src/hooks/useFormAction.ts +++ b/src/components/Form/src/hooks/useFormEvents.ts @@ -9,22 +9,19 @@ import { dateItemType } from '../helper'; import moment from 'moment'; import { cloneDeep } from 'lodash-es'; +import { error } from '/@/utils/log'; interface UseFormActionContext { emit: EmitType; getProps: ComputedRef<FormProps>; getSchema: ComputedRef<FormSchema[]>; - formModel: any; - defaultValueRef: Ref<any>; + formModel: Recordable; + defaultValueRef: Ref<Recordable>; formElRef: Ref<FormActionType>; schemaRef: Ref<FormSchema[]>; handleFormValues: Fn; - actionState: { - resetAction: any; - submitAction: any; - }; } -export function useFormAction({ +export function useFormEvents({ emit, getProps, formModel, @@ -33,34 +30,34 @@ formElRef, schemaRef, handleFormValues, - actionState, }: UseFormActionContext) { - async function resetFields(): Promise<any> { + async function resetFields(): Promise<void> { const { resetFunc, submitOnReset } = unref(getProps); resetFunc && isFunction(resetFunc) && (await resetFunc()); + const formEl = unref(formElRef); if (!formEl) return; + Object.keys(formModel).forEach((key) => { - (formModel as any)[key] = defaultValueRef.value[key]; + formModel[key] = defaultValueRef.value[key]; }); clearValidate(); emit('reset', toRaw(formModel)); - // return values; submitOnReset && handleSubmit(); } /** - * @description: 璁剧疆琛ㄥ崟鍊� + * @description: Set form value */ async function setFieldsValue(values: any): Promise<void> { const fields = unref(getSchema) .map((item) => item.field) .filter(Boolean); - // const formEl = unref(formElRef); const validKeys: string[] = []; Object.keys(values).forEach((key) => { const element = values[key]; + // 0| '' is allow if (element !== undefined && element !== null && fields.includes(key)) { // time type if (itemIsDateType(key)) { @@ -69,12 +66,12 @@ for (const ele of element) { arr.push(moment(ele)); } - (formModel as any)[key] = arr; + formModel[key] = arr; } else { - (formModel as any)[key] = moment(element); + formModel[key] = moment(element); } } else { - (formModel as any)[key] = element; + formModel[key] = element; } validKeys.push(key); } @@ -84,19 +81,18 @@ /** * @description: Delete based on field name */ - function removeSchemaByFiled(fields: string | string[]): void { + async function removeSchemaByFiled(fields: string | string[]): Promise<void> { const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); - if (!fields) { - return; - } - let fieldList: string[] = fields as string[]; + if (!fields) return; + + let fieldList: string[] = isString(fields) ? [fields] : fields; if (isString(fields)) { fieldList = [fields]; } for (const field of fieldList) { _removeSchemaByFiled(field, schemaList); } - schemaRef.value = schemaList as any; + schemaRef.value = schemaList; } /** @@ -114,27 +110,26 @@ /** * @description: Insert after a certain field, if not insert the last */ - function appendSchemaByField(schema: FormSchema, prefixField?: string) { + async function appendSchemaByField(schema: FormSchema, prefixField?: string, first = false) { const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); const index = schemaList.findIndex((schema) => schema.field === prefixField); - const hasInList = schemaList.find((item) => item.field === schema.field); + const hasInList = schemaList.some((item) => item.field === schema.field); - if (hasInList) { - return; - } - if (!prefixField || index === -1) { - schemaList.push(schema); - schemaRef.value = schemaList as any; + if (!hasInList) return; + + if (!prefixField || index === -1 || first) { + first ? schemaList.unshift(schema) : schemaList.push(schema); + schemaRef.value = schemaList; return; } if (index !== -1) { schemaList.splice(index + 1, 0, schema); } - schemaRef.value = schemaList as any; + schemaRef.value = schemaList; } - function updateSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) { + async function updateSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) { let updateData: Partial<FormSchema>[] = []; if (isObject(data)) { updateData.push(data as FormSchema); @@ -142,9 +137,13 @@ if (isArray(data)) { updateData = [...data]; } + const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field); + if (!hasField) { - throw new Error('Must pass in the `field` field!'); + error( + 'All children of the form Schema array that need to be updated must contain the `field` field' + ); } const schema: FormSchema[] = []; updateData.forEach((item) => { @@ -157,12 +156,12 @@ } }); }); - schemaRef.value = unique(schema, 'field') as any; + schemaRef.value = unique(schema, 'field'); } - function getFieldsValue(): any { + function getFieldsValue(): Recordable { const formEl = unref(formElRef); - if (!formEl) return; + if (!formEl) return {}; return handleFormValues(toRaw(unref(formModel))); } @@ -171,23 +170,24 @@ */ function itemIsDateType(key: string) { return unref(getSchema).some((item) => { - return item.field === key ? dateItemType.includes(item.component!) : false; + return item.field === key ? dateItemType.includes(item.component) : false; }); } - function validateFields(nameList?: NamePath[] | undefined) { - if (!formElRef.value) return; - return formElRef.value.validateFields(nameList); + async function validateFields(nameList?: NamePath[] | undefined) { + return await unref(formElRef)?.validateFields(nameList); } - function validate(nameList?: NamePath[] | undefined) { - if (!formElRef.value) return; - return formElRef.value.validate(nameList); + async function validate(nameList?: NamePath[] | undefined) { + return await unref(formElRef)?.validate(nameList); } - function clearValidate(name?: string | string[]) { - if (!formElRef.value) return; - formElRef.value.clearValidate(name); + async function clearValidate(name?: string | string[]) { + await unref(formElRef)?.clearValidate(name); + } + + async function scrollToField(name: NamePath, options?: ScrollOptions | undefined) { + await unref(formElRef)?.scrollToField(name, options); } /** @@ -208,13 +208,6 @@ emit('submit', res); } catch (error) {} } - actionState.resetAction = { - onClick: resetFields, - }; - - actionState.submitAction = { - onClick: handleSubmit, - }; return { handleSubmit, @@ -227,5 +220,6 @@ removeSchemaByFiled, resetFields, setFieldsValue, + scrollToField, }; } diff --git a/src/components/Form/src/hooks/useFormValues.ts b/src/components/Form/src/hooks/useFormValues.ts index 428f83d..2514cb2 100644 --- a/src/components/Form/src/hooks/useFormValues.ts +++ b/src/components/Form/src/hooks/useFormValues.ts @@ -9,7 +9,7 @@ fieldMapToTimeRef: Ref<FieldMapToTime>; defaultValueRef: Ref<any>; getSchema: ComputedRef<FormSchema[]>; - formModel: any; + formModel: Recordable; } export function useFormValues({ transformDateFuncRef, @@ -19,11 +19,11 @@ formModel, }: UseFormValuesContext) { // Processing form values - function handleFormValues(values: Record<string, any>) { + function handleFormValues(values: Recordable) { if (!isObject(values)) { return {}; } - const resMap: Record<string, any> = {}; + const res: Recordable = {}; for (const item of Object.entries(values)) { let [, value] = item; const [key] = item; @@ -41,15 +41,15 @@ if (isString(value)) { value = value.trim(); } - resMap[key] = value; + res[key] = value; } - return handleRangeTimeValue(resMap); + return handleRangeTimeValue(res); } /** * @description: Processing time interval parameters */ - function handleRangeTimeValue(values: Record<string, any>) { + function handleRangeTimeValue(values: Recordable) { const fieldMapToTime = unref(fieldMapToTimeRef); if (!fieldMapToTime || !Array.isArray(fieldMapToTime)) { @@ -65,6 +65,7 @@ values[startTimeKey] = moment(startTime).format(format); values[endTimeKey] = moment(endTime).format(format); + Reflect.deleteProperty(values, field); } return values; @@ -72,11 +73,11 @@ function initDefault() { const schemas = unref(getSchema); - const obj: Record<string, any> = {}; + const obj: Recordable = {}; schemas.forEach((item) => { if (item.defaultValue) { obj[item.field] = item.defaultValue; - (formModel as any)[item.field] = item.defaultValue; + formModel[item.field] = item.defaultValue; } }); defaultValueRef.value = obj; diff --git a/src/components/Form/src/hooks/useLabelWidth.ts b/src/components/Form/src/hooks/useLabelWidth.ts index 522f44d..ae4274d 100644 --- a/src/components/Form/src/hooks/useLabelWidth.ts +++ b/src/components/Form/src/hooks/useLabelWidth.ts @@ -4,23 +4,8 @@ import { computed, unref } from 'vue'; import { isNumber } from '/@/utils/is'; -// export function useGlobalLabelWidth(propsRef: ComputedRef<FormProps>) { -// return computed(() => { -// const { labelWidth, labelCol, wrapperCol } = unref(propsRef); -// if (!labelWidth) { -// return { labelCol, wrapperCol }; -// } - -// const width = isNumber(labelWidth) ? `${labelWidth}px` : labelWidth; -// return { -// labelCol: { style: { width }, span: 1, ...labelCol }, -// wrapperCol: { style: { width: `calc(100% - ${width})` }, span: 23, ...wrapperCol }, -// }; -// }); -// } - export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<FormProps>) { - return computed((): any => { + return computed(() => { const schemaItem = unref(schemaItemRef); const { labelCol = {}, wrapperCol = {} } = schemaItem.itemProps || {}; const { labelWidth, disabledLabelWidth } = schemaItem; @@ -29,7 +14,7 @@ labelWidth: globalLabelWidth, labelCol: globalLabelCol, wrapperCol: globWrapperCol, - } = unref(propsRef) as any; + } = unref(propsRef); // If labelWidth is set globally, all items setting if ((!globalLabelWidth && !labelWidth && !globalLabelCol) || disabledLabelWidth) { diff --git a/src/components/Form/src/props.ts b/src/components/Form/src/props.ts index 2b55070..8dc5fb9 100644 --- a/src/components/Form/src/props.ts +++ b/src/components/Form/src/props.ts @@ -1,11 +1,14 @@ import type { FieldMapToTime, FormSchema } from './types/form'; -import type { PropType } from 'vue'; +import type { CSSProperties, PropType } from 'vue'; import type { ColEx } from './types'; -import { TableActionType } from '/@/components/Table'; +import type { TableActionType } from '/@/components/Table'; +import type { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; + +import { propTypes } from '/@/utils/propTypes'; export const basicProps = { model: { - type: Object as PropType<Record<string, any>>, + type: Object as PropType<Recordable>, default: {}, }, // 鏍囩瀹藉害 鍥哄畾瀹藉害 @@ -17,7 +20,7 @@ type: Array as PropType<FieldMapToTime>, default: () => [], }, - compact: Boolean as PropType<boolean>, + compact: propTypes.bool, // 琛ㄥ崟閰嶇疆瑙勫垯 schemas: { type: [Array] as PropType<FormSchema[]>, @@ -25,98 +28,68 @@ required: true, }, mergeDynamicData: { - type: Object as PropType<any>, + type: Object as PropType<Recordable>, default: null, }, baseRowStyle: { - type: Object as PropType<any>, + type: Object as PropType<CSSProperties>, }, baseColProps: { - type: Object as PropType<any>, + type: Object as PropType<Partial<ColEx>>, }, - autoSetPlaceHolder: { - type: Boolean, - default: true, - }, - submitOnReset: { - type: Boolean, - default: false, - }, - size: { - type: String as PropType<'default' | 'small' | 'large'>, - default: 'default', - }, + autoSetPlaceHolder: propTypes.bool.def(true), + submitOnReset: propTypes.bool, + size: propTypes.oneOf(['default', 'small', 'large']).def('default'), // 绂佺敤琛ㄥ崟 - disabled: Boolean as PropType<boolean>, + disabled: propTypes.bool, emptySpan: { type: [Number, Object] as PropType<number>, default: 0, }, // 鏄惁鏄剧ず鏀惰捣灞曞紑鎸夐挳 - showAdvancedButton: { type: Boolean as PropType<boolean>, default: false }, + showAdvancedButton: propTypes.bool, // 杞寲鏃堕棿 transformDateFunc: { type: Function as PropType<Fn>, default: (date: any) => { - return date._isAMomentObject ? date.format('YYYY-MM-DD HH:mm:ss') : date; + return date._isAMomentObject ? date?.format('YYYY-MM-DD HH:mm:ss') : date; }, }, - rulesMessageJoinLabel: { - type: Boolean, - default: true, - }, + rulesMessageJoinLabel: propTypes.bool.def(true), // 瓒呰繃3琛岃嚜鍔ㄦ姌鍙� - autoAdvancedLine: { - type: Number as PropType<number>, - default: 3, - }, + autoAdvancedLine: propTypes.number.def(3), // 鏄惁鏄剧ず鎿嶄綔鎸夐挳 - showActionButtonGroup: { - type: Boolean as PropType<boolean>, - default: true, - }, + showActionButtonGroup: propTypes.bool.def(true), // 鎿嶄綔鍒桟ol閰嶇疆 - actionColOptions: Object as PropType<ColEx>, + actionColOptions: Object as PropType<Partial<ColEx>>, // 鏄剧ず閲嶇疆鎸夐挳 - showResetButton: { - type: Boolean as PropType<boolean>, - default: true, - }, + showResetButton: propTypes.bool.def(true), // 閲嶇疆鎸夐挳閰嶇疆 - resetButtonOptions: Object as PropType<any>, + resetButtonOptions: Object as PropType<Partial<ButtonProps>>, // 鏄剧ず纭鎸夐挳 - showSubmitButton: { - type: Boolean as PropType<boolean>, - default: true, - }, + showSubmitButton: propTypes.bool.def(true), // 纭鎸夐挳閰嶇疆 - submitButtonOptions: Object as PropType<any>, + submitButtonOptions: Object as PropType<Partial<ButtonProps>>, // 鑷畾涔夐噸缃嚱鏁� - resetFunc: Function as PropType<Fn>, - submitFunc: Function as PropType<Fn>, + resetFunc: Function as PropType<() => Promise<void>>, + submitFunc: Function as PropType<() => Promise<void>>, // 浠ヤ笅涓洪粯璁rops - hideRequiredMark: Boolean as PropType<boolean>, + hideRequiredMark: propTypes.bool, - labelCol: Object as PropType<ColEx>, + labelCol: Object as PropType<Partial<ColEx>>, - layout: { - type: String as PropType<'horizontal' | 'vertical' | 'inline'>, - default: 'horizontal', - }, + layout: propTypes.oneOf(['horizontal', 'vertical', 'inline']).def('horizontal'), tableAction: { type: Object as PropType<TableActionType>, }, - wrapperCol: Object as PropType<any>, + wrapperCol: Object as PropType<Partial<ColEx>>, - colon: { - type: Boolean as PropType<boolean>, - default: false, - }, + colon: propTypes.bool, - labelAlign: String as PropType<string>, + labelAlign: propTypes.string, }; diff --git a/src/components/Form/src/types/form.ts b/src/components/Form/src/types/form.ts index b12713a..78c8567 100644 --- a/src/components/Form/src/types/form.ts +++ b/src/components/Form/src/types/form.ts @@ -5,6 +5,7 @@ import type { FormItem } from './formItem'; import type { ColEx, ComponentType } from './index'; import type { TableActionType } from '/@/components/Table/src/types/table'; +import type { CSSProperties } from 'vue'; export type FieldMapToTime = [string, [string, string], string?][]; @@ -14,8 +15,8 @@ export interface RenderCallbackParams { schema: FormSchema; - values: any; - model: any; + values: Recordable; + model: Recordable; field: string; } @@ -25,18 +26,19 @@ export interface FormActionType { submit: () => Promise<void>; - setFieldsValue: <T>(values: T) => void; - resetFields: () => Promise<any>; - getFieldsValue: () => any; - clearValidate: (name?: string | string[]) => void; - updateSchema: (data: Partial<FormSchema> | Partial<FormSchema>[]) => void; - setProps: (formProps: Partial<FormProps>) => void; - removeSchemaByFiled: (field: string | string[]) => void; - appendSchemaByField: (schema: FormSchema, prefixField?: string) => void; + setFieldsValue: <T>(values: T) => Promise<void>; + resetFields: () => Promise<void>; + getFieldsValue: () => Recordable; + clearValidate: (name?: string | string[]) => Promise<void>; + updateSchema: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>; + setProps: (formProps: Partial<FormProps>) => Promise<void>; + removeSchemaByFiled: (field: string | string[]) => Promise<void>; + appendSchemaByField: (schema: FormSchema, prefixField?: string) => Promise<void>; validateFields: (nameList?: NamePath[]) => Promise<any>; validate: (nameList?: NamePath[]) => Promise<any>; - scrollToField: (name: NamePath, options?: ScrollOptions) => void; + scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>; } + export type RegisterFn = (formInstance: FormActionType) => void; export type UseFormReturnType = [RegisterFn, FormActionType]; @@ -44,7 +46,7 @@ export interface FormProps { // layout?: 'vertical' | 'inline' | 'horizontal'; // Form value - model?: any; + model?: Recordable; // The width of all items in the entire form labelWidth?: number | string; // Submit form on reset @@ -55,7 +57,7 @@ wrapperCol?: Partial<ColEx>; // General row style - baseRowStyle?: object; + baseRowStyle?: CSSProperties; // General col configuration baseColProps?: Partial<ColEx>; @@ -63,7 +65,7 @@ // Form configuration rules schemas?: FormSchema[]; // Function values used to merge into dynamic control form items - mergeDynamicData?: any; + mergeDynamicData?: Recordable; // Compact mode for search forms compact?: boolean; // Blank line span @@ -131,8 +133,8 @@ schema: FormSchema; tableAction: TableActionType; formActionType: FormActionType; - formModel: any; - }) => any) + formModel: Recordable; + }) => Recordable) | object; // Required required?: boolean; diff --git a/src/components/Modal/src/useModalContext.ts b/src/components/Modal/src/useModalContext.ts index 6d8c2fb..94d4c4e 100644 --- a/src/components/Modal/src/useModalContext.ts +++ b/src/components/Modal/src/useModalContext.ts @@ -5,12 +5,12 @@ redoModalHeight: () => void; } -const modalContextInjectKey: InjectionKey<ModalContextProps> = Symbol(); +const key: InjectionKey<ModalContextProps> = Symbol(); export function createModalContext(context: ModalContextProps) { - return createContext<ModalContextProps>(context, modalContextInjectKey); + return createContext<ModalContextProps>(context, key); } export function useModalContext() { - return useContext<ModalContextProps>(modalContextInjectKey); + return useContext<ModalContextProps>(key); } diff --git a/src/components/Scrollbar/src/util.ts b/src/components/Scrollbar/src/util.ts index 3d32d30..b7c4845 100644 --- a/src/components/Scrollbar/src/util.ts +++ b/src/components/Scrollbar/src/util.ts @@ -39,7 +39,7 @@ return Object.assign(to, _from); } -export function toObject<T>(arr: Array<T>): Record<string, T> { +export function toObject<T>(arr: Array<T>): Recordable<T> { const res = {}; for (let i = 0; i < arr.length; i++) { if (arr[i]) { diff --git a/src/components/Table/src/BasicTable.vue b/src/components/Table/src/BasicTable.vue index 5554848..1b9960f 100644 --- a/src/components/Table/src/BasicTable.vue +++ b/src/components/Table/src/BasicTable.vue @@ -221,7 +221,7 @@ function handleTableChange( pagination: PaginationProps, // @ts-ignore - filters: Partial<Record<string, string[]>>, + filters: Partial<Recordable<string[]>>, sorter: SorterResult ) { const { clearSelectOnPageChange, sortFn } = unref(getMergeProps); diff --git a/src/components/Table/src/components/renderEditable.tsx b/src/components/Table/src/components/renderEditable.tsx index 5e2b95b..a576152 100644 --- a/src/components/Table/src/components/renderEditable.tsx +++ b/src/components/Table/src/components/renderEditable.tsx @@ -232,7 +232,7 @@ }; } -export type EditRecordRow<T = { [key: string]: any }> = { +export type EditRecordRow<T = Hash<any>> = { editable: boolean; onCancel: Fn; onSubmit: Fn; diff --git a/src/components/Table/src/types/column.ts b/src/components/Table/src/types/column.ts index 4df61bb..785e6df 100644 --- a/src/components/Table/src/types/column.ts +++ b/src/components/Table/src/types/column.ts @@ -194,5 +194,5 @@ * such as slots: { filterIcon: 'XXX'} * @type object */ - slots?: Record<string, string>; + slots?: Recordable<string>; } diff --git a/src/components/Transition/src/CreateTransition.tsx b/src/components/Transition/src/CreateTransition.tsx index 24ab1c9..ba5ee13 100644 --- a/src/components/Transition/src/CreateTransition.tsx +++ b/src/components/Transition/src/CreateTransition.tsx @@ -40,7 +40,7 @@ } export function createJavascriptTransition( name: string, - functions: Record<string, any>, + functions: Recordable, mode: Mode = 'in-out' ) { return defineComponent({ diff --git a/src/components/VirtualScroll/src/index.tsx b/src/components/VirtualScroll/src/index.tsx index b447ff1..1e17ee6 100644 --- a/src/components/VirtualScroll/src/index.tsx +++ b/src/components/VirtualScroll/src/index.tsx @@ -54,7 +54,7 @@ const getWrapStyleRef = computed( (): CSSProperties => { - const styles: Record<string, string> = {}; + const styles: Recordable<string> = {}; const height = convertToUnit(props.height); const minHeight = convertToUnit(props.minHeight); const minWidth = convertToUnit(props.minWidth); diff --git a/src/components/util.tsx b/src/components/util.tsx index c1d7a3c..2010d87 100644 --- a/src/components/util.tsx +++ b/src/components/util.tsx @@ -40,7 +40,7 @@ } as const; function parseStyle(style: string) { - const styleMap: Dictionary<any> = {}; + const styleMap: Recordable = {}; for (const s of style.split(pattern.styleList)) { let [key, val] = s.split(pattern.styleProp); @@ -161,8 +161,8 @@ } export function mergeListeners( - target: { [key: string]: Function | Function[] } | undefined, - source: { [key: string]: Function | Function[] } | undefined + target: Indexable<Function | Function[]> | undefined, + source: Indexable<Function | Function[]> | undefined ) { if (!target) return source; if (!source) return target; diff --git a/src/directives/ripple/index.ts b/src/directives/ripple/index.ts index 8863b91..c8d614b 100644 --- a/src/directives/ripple/index.ts +++ b/src/directives/ripple/index.ts @@ -154,7 +154,7 @@ setTimeout(() => { let clearPosition = true; for (let i = 0; i < el.childNodes.length; i++) { - if ((el.childNodes[i] as any).className === 'ripple-container') { + if ((el.childNodes[i] as Recordable).className === 'ripple-container') { clearPosition = false; } } @@ -173,7 +173,7 @@ clearRipple(); } - (el as any).setBackground = (bgColor: string) => { + (el as Recordable).setBackground = (bgColor: string) => { if (!bgColor) { return; } @@ -181,8 +181,8 @@ }; } -function setProps(modifiers: { [key: string]: any }, props: Record<string, any>) { - modifiers.forEach((item: any) => { +function setProps(modifiers: Hash<any>, props: Recordable) { + modifiers.forEach((item: Recordable) => { if (isNaN(Number(item))) props.event = item; else props.transition = item; }); diff --git a/src/hooks/component/useFormItem.ts b/src/hooks/component/useFormItem.ts new file mode 100644 index 0000000..8fa3cb3 --- /dev/null +++ b/src/hooks/component/useFormItem.ts @@ -0,0 +1,35 @@ +import type { UnwrapRef } from 'vue'; +import { reactive, readonly, computed, getCurrentInstance } from 'vue'; + +import { isEqual } from 'lodash-es'; + +export function useRuleFormItem<T extends Indexable>( + props: T, + key: keyof T = 'value', + changeEvent = 'change' +) { + const instance = getCurrentInstance(); + const emit = instance?.emit; + + const innerState = reactive({ + value: props[key], + }); + + const defaultState = readonly(innerState); + + const setState = (val: UnwrapRef<T[keyof T]>) => { + innerState.value = val as T[keyof T]; + }; + const state = computed({ + get() { + return innerState.value; + }, + set(value) { + if (isEqual(value, defaultState.value)) return; + innerState.value = value as T[keyof T]; + emit?.(changeEvent, value); + }, + }); + + return [state, setState, defaultState]; +} diff --git a/src/hooks/core/useAttrs.ts b/src/hooks/core/useAttrs.ts new file mode 100644 index 0000000..94665ab --- /dev/null +++ b/src/hooks/core/useAttrs.ts @@ -0,0 +1,39 @@ +import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue'; + +interface Params { + excludeListeners?: boolean; + excludeKeys?: string[]; +} + +const DEFAULT_EXCLUDE_KEYS = ['class', 'style']; +const LISTENER_PREFIX = /^on[A-Z]/; + +export function entries<T>(obj: Hash<T>): [string, T][] { + return Object.keys(obj).map((key: string) => [key, obj[key]]); +} + +export function useAttrs(params: Params = {}) { + const instance = getCurrentInstance(); + if (!instance) return {}; + + const { excludeListeners = false, excludeKeys = [] } = params; + const attrs = shallowRef({}); + const allExcludeKeys = excludeKeys.concat(DEFAULT_EXCLUDE_KEYS); + + // Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance + instance.attrs = reactive(instance.attrs); + + watchEffect(() => { + const res = entries(instance.attrs).reduce((acm, [key, val]) => { + if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) { + acm[key] = val; + } + + return acm; + }, {} as Hash<any>); + + attrs.value = res; + }); + + return attrs; +} diff --git a/src/hooks/event/useKeyPress.ts b/src/hooks/event/useKeyPress.ts index 72338d6..2cabbbe 100644 --- a/src/hooks/event/useKeyPress.ts +++ b/src/hooks/event/useKeyPress.ts @@ -23,7 +23,7 @@ const defaultEvents: keyEvent[] = ['keydown']; // 閿洏浜嬩欢 keyCode 鍒悕 -const aliasKeyCodeMap: Record<string, number | number[]> = { +const aliasKeyCodeMap: Recordable<number | number[]> = { esc: 27, tab: 9, enter: 13, @@ -36,7 +36,7 @@ }; // 閿洏浜嬩欢 key 鍒悕 -const aliasKeyMap: Record<string, string | string[]> = { +const aliasKeyMap: Recordable<string | string[]> = { esc: 'Escape', tab: 'Tab', enter: 'Enter', @@ -50,7 +50,7 @@ }; // 淇グ閿� -const modifierKey: Record<string, (event: KeyboardEvent) => boolean> = { +const modifierKey: Recordable<(event: KeyboardEvent) => boolean> = { ctrl: (event: KeyboardEvent) => event.ctrlKey, shift: (event: KeyboardEvent) => event.shiftKey, alt: (event: KeyboardEvent) => event.altKey, diff --git a/src/hooks/web/useI18n.ts b/src/hooks/web/useI18n.ts index feccc2d..2b143dd 100644 --- a/src/hooks/web/useI18n.ts +++ b/src/hooks/web/useI18n.ts @@ -24,7 +24,7 @@ return { ...methods, - t: (key: string, ...arg: any) => { + t: (key: string, ...arg: any): string => { if (!key) return ''; return t(getKey(key), ...(arg as Parameters<typeof t>)); }, diff --git a/src/layouts/page/index.tsx b/src/layouts/page/index.tsx index a09bda3..d223e08 100644 --- a/src/layouts/page/index.tsx +++ b/src/layouts/page/index.tsx @@ -13,7 +13,7 @@ // import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; interface DefaultContext { - Component: FunctionalComponent & { type: { [key: string]: any } }; + Component: FunctionalComponent & { type: Indexable }; route: RouteLocation; } diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts index 624c160..a8f3d4f 100644 --- a/src/router/guard/permissionGuard.ts +++ b/src/router/guard/permissionGuard.ts @@ -40,7 +40,7 @@ return; } // redirect login page - const redirectData: { path: string; replace: boolean; query?: { [key: string]: string } } = { + const redirectData: { path: string; replace: boolean; query?: Indexable<string> } = { path: LOGIN_PATH, replace: true, }; diff --git a/src/router/types.ts b/src/router/types.ts index 2f96e96..2bb5802 100644 --- a/src/router/types.ts +++ b/src/router/types.ts @@ -48,7 +48,7 @@ component?: Component | string; components?: Component; children?: AppRouteRecordRaw[]; - props?: Record<string, any>; + props?: Recordable; fullPath?: string; } export interface MenuTag { diff --git a/src/settings/colorSetting.ts b/src/settings/colorSetting.ts index be15876..0b498a3 100644 --- a/src/settings/colorSetting.ts +++ b/src/settings/colorSetting.ts @@ -2,7 +2,7 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ '#ffffff', '#009688', - '#18bc9c', + '#5172DC', '#1E9FFF', '#018ffb', '#409eff', diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 0874781..c4ab5ae 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -15,17 +15,19 @@ declare function parseFloat(string: string | number): number; -declare type Dictionary<T> = Record<string, T>; - declare type Nullable<T> = T | null; + +declare type NonNullable<T> = T extends null | undefined ? never : T; declare type RefType<T> = T | null; declare type CustomizedHTMLElement<T> = HTMLElement & T; -declare type Indexable<T = any> = { +declare type Indexable<T extends any = any> = { [key: string]: T; }; + +declare type Recordable<T extends any = any> = Record<string, T>; declare type Hash<T> = Indexable<T>; @@ -59,3 +61,5 @@ declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null; declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>; + +type IsSame<A, B> = A | B extends A & B ? true : false; diff --git a/src/utils/helper/persistent.ts b/src/utils/helper/persistent.ts index 46f99c8..bb99089 100644 --- a/src/utils/helper/persistent.ts +++ b/src/utils/helper/persistent.ts @@ -7,8 +7,8 @@ const ss = createStorage(); interface CacheStore { - local: Record<string, any>; - session: Record<string, any>; + local: Recordable; + session: Recordable; } /** diff --git a/src/utils/helper/tsxHelper.tsx b/src/utils/helper/tsxHelper.tsx index e4aaa00..bd41cb7 100644 --- a/src/utils/helper/tsxHelper.tsx +++ b/src/utils/helper/tsxHelper.tsx @@ -35,7 +35,7 @@ } // Get events on attrs -export function getListeners(attrs: Record<string, unknown>) { +export function getListeners(attrs: Recordable<unknown>) { const listeners: any = {}; Object.keys(attrs).forEach((key) => { if (/^on/.test(key)) { diff --git a/src/utils/helper/vueHelper.ts b/src/utils/helper/vueHelper.ts index cd04bea..8cead80 100644 --- a/src/utils/helper/vueHelper.ts +++ b/src/utils/helper/vueHelper.ts @@ -9,6 +9,7 @@ reactive, ComponentInternalInstance, } from 'vue'; +import { error } from '../log'; export function explicitComputed<T, S>(source: WatchSource<S>, fn: () => T) { const v = reactive<any>({ value: fn() }); @@ -39,6 +40,6 @@ export function isInSetup() { if (!getCurrentInstance()) { - throw new Error('Please put useForm function in the setup function!'); + error('Please put useForm function in the setup function!'); } } diff --git a/src/utils/http/axios/types.ts b/src/utils/http/axios/types.ts index 90b1619..b151ed5 100644 --- a/src/utils/http/axios/types.ts +++ b/src/utils/http/axios/types.ts @@ -35,7 +35,7 @@ // multipart/form-data锛氫笂浼犳枃浠� export interface UploadFileParams { // 鍏朵粬鍙傛暟 - data?: { [key: string]: any }; + data?: Indexable; // 鏂囦欢鍙傛暟鐨勬帴鍙e瓧娈靛悕 name?: string; // 鏂囦欢 diff --git a/src/utils/index.ts b/src/utils/index.ts index d37797e..b24685f 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -38,7 +38,7 @@ return url; } -export function deepMerge<T = any>(src: any, target: any): T { +export function deepMerge<T = any>(src: any = {}, target: any = {}): T { let key: string; for (key in target) { src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]); diff --git a/src/utils/log.ts b/src/utils/log.ts index 81cded0..8f79800 100644 --- a/src/utils/log.ts +++ b/src/utils/log.ts @@ -3,3 +3,7 @@ export function warn(message: string) { console.warn(`[${projectName} warn]:${message}`); } + +export function error(message: string) { + throw new Error(`[${projectName} error]:${message}`); +} diff --git a/src/views/demo/form/RuleForm.vue b/src/views/demo/form/RuleForm.vue index 4851c66..6023777 100644 --- a/src/views/demo/form/RuleForm.vue +++ b/src/views/demo/form/RuleForm.vue @@ -84,12 +84,15 @@ required: true, // @ts-ignore validator: async (rule, value) => { + if (!value) { + return Promise.reject('鍊间笉鑳戒负绌�'); + } if (value === '1') { return Promise.reject('鍊间笉鑳戒负1'); } return Promise.resolve(); }, - trigger: 'blur', + trigger: 'change', }, ], }, diff --git a/yarn.lock b/yarn.lock index ceb4b38..84693b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,7 +35,7 @@ "@types/lodash" "^4.14.165" lodash "^4.17.15" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== @@ -47,7 +47,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== -"@babel/core@>=7.9.0", "@babel/core@^7.8.4": +"@babel/core@>=7.9.0", "@babel/core@^7.11.1": version "7.12.10" resolved "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== @@ -167,7 +167,7 @@ dependencies: "@babel/types" "^7.12.7" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": version "7.12.5" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== @@ -246,10 +246,20 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + "@babel/helper-validator-option@^7.12.1": version "7.12.1" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== + +"@babel/helper-validator-option@^7.12.11": + version "7.12.11" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" + integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== "@babel/helper-wrap-function@^7.10.4": version "7.12.3" @@ -498,10 +508,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.12.1": - version "7.12.1" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" - integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== +"@babel/plugin-transform-block-scoping@^7.12.11": + version "7.12.12" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" + integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" @@ -724,16 +734,16 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/preset-env@^7.8.4": - version "7.12.10" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.10.tgz#ca981b95f641f2610531bd71948656306905e6ab" - integrity sha512-Gz9hnBT/tGeTE2DBNDkD7BiWRELZt+8lSysHuDwmYXUIvtwZl0zI+D6mZgXZX0u8YBlLS4tmai9ONNY9tjRgRA== +"@babel/preset-env@^7.11.0": + version "7.12.11" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" + integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== dependencies: "@babel/compat-data" "^7.12.7" "@babel/helper-compilation-targets" "^7.12.5" "@babel/helper-module-imports" "^7.12.5" "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.1" + "@babel/helper-validator-option" "^7.12.11" "@babel/plugin-proposal-async-generator-functions" "^7.12.1" "@babel/plugin-proposal-class-properties" "^7.12.1" "@babel/plugin-proposal-dynamic-import" "^7.12.1" @@ -762,7 +772,7 @@ "@babel/plugin-transform-arrow-functions" "^7.12.1" "@babel/plugin-transform-async-to-generator" "^7.12.1" "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.11" "@babel/plugin-transform-classes" "^7.12.1" "@babel/plugin-transform-computed-properties" "^7.12.1" "@babel/plugin-transform-destructuring" "^7.12.1" @@ -792,7 +802,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.12.1" "@babel/plugin-transform-unicode-regex" "^7.12.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.10" + "@babel/types" "^7.12.11" core-js-compat "^3.8.0" semver "^5.5.0" @@ -844,6 +854,15 @@ integrity sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw== dependencies: "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@babel/types@^7.12.11": + version "7.12.12" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" to-fast-properties "^2.0.0" @@ -1004,32 +1023,38 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@hapi/address@2.x.x": +"@hapi/address@^2.1.2": version "2.1.4" resolved "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== -"@hapi/bourne@1.x.x": - version "1.3.2" - resolved "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" - integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== +"@hapi/formula@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd" + integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA== -"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": +"@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0": version "8.5.1" resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== -"@hapi/joi@^15.1.0": - version "15.1.1" - resolved "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" - integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== +"@hapi/joi@^16.1.8": + version "16.1.8" + resolved "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839" + integrity sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg== dependencies: - "@hapi/address" "2.x.x" - "@hapi/bourne" "1.x.x" - "@hapi/hoek" "8.x.x" - "@hapi/topo" "3.x.x" + "@hapi/address" "^2.1.2" + "@hapi/formula" "^1.2.0" + "@hapi/hoek" "^8.2.4" + "@hapi/pinpoint" "^1.0.2" + "@hapi/topo" "^3.1.3" -"@hapi/topo@3.x.x": +"@hapi/pinpoint@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13" + integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ== + +"@hapi/topo@^3.1.3": version "3.1.6" resolved "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== @@ -1051,10 +1076,10 @@ resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.4.tgz#46098fb544a4eb3af724219e4955c9022801835e" integrity sha512-YCSECbeXKFJEIVkKgKMjUzJ439ysufmL/a31B1j7dCvnHaBWsX9J4XehhJgg/aTy3yvhHaVhI6xt1kSMZP799A== -"@iconify/json@^1.1.275": - version "1.1.275" - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.275.tgz#ac9a706cdc7c9e64ab8e8bb09ae770f551f7496f" - integrity sha512-Nt6tXJpZFd/gFRV24BvmlIdxnbMxgshIKFPQwOWgeVjKiOKEwiBKjXUzBE74As7/Olps/ac1gEB40N9/DGOJ3Q== +"@iconify/json@^1.1.276": + version "1.1.276" + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.276.tgz#c8d51751abc84cc73a466f55bc2f352686451786" + integrity sha512-Ra/mGT+n38vhi/i1cjsPYOmSR2d6rNIXZ+OsrIWp9J35zAPQ93sSTQMpTyxZdLu3QxU0vYwtcaC7h/Y1/3H3wg== "@intlify/core-base@9.0.0-beta.14": version "9.0.0-beta.14" @@ -1170,6 +1195,14 @@ dependencies: "@iconify/iconify" ">=2.0.0-rc.1" +"@rollup/plugin-babel@^5.2.0": + version "5.2.2" + resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz#e5623a01dd8e37e004ba87f2de218c611727d9b2" + integrity sha512-MjmH7GvFT4TW8xFdIeFS3wqIX646y5tACdxkTO+khbHvS3ZcVJL6vkAHLw2wqPmkhwCfWHoNsp15VYNwW6JEJA== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + "@rollup/plugin-commonjs@^16.0.0": version "16.0.0" resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz#169004d56cd0f0a1d0f35915d31a036b0efe281f" @@ -1214,31 +1247,31 @@ is-module "^1.0.0" resolve "^1.19.0" -"@rollup/plugin-node-resolve@^7.1.1": - version "7.1.3" - resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" - integrity sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q== - dependencies: - "@rollup/pluginutils" "^3.0.8" - "@types/resolve" "0.0.8" - builtin-modules "^3.1.0" - is-module "^1.0.0" - resolve "^1.14.2" - -"@rollup/plugin-node-resolve@^8.4.0": - version "8.4.0" - resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.4.0.tgz#261d79a680e9dc3d86761c14462f24126ba83575" - integrity sha512-LFqKdRLn0ShtQyf6SBYO69bGE1upV6wUhBX0vFOUnLAyzx5cwp8svA0eHUnu8+YU57XOkrMtfG63QOpQx25pHQ== +"@rollup/plugin-node-resolve@^11.0.1": + version "11.0.1" + resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.0.1.tgz#d3765eec4bccf960801439a999382aed2dca959b" + integrity sha512-ltlsj/4Bhwwhb+Nb5xCz/6vieuEj2/BAkkqVIKmZwC7pIdl8srmgmglE4S0jFlZa32K4qvdQ6NHdmpRKD/LwoQ== dependencies: "@rollup/pluginutils" "^3.1.0" "@types/resolve" "1.17.1" builtin-modules "^3.1.0" - deep-freeze "^0.0.1" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-node-resolve@^9.0.0": + version "9.0.0" + resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" + integrity sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" deepmerge "^4.2.2" is-module "^1.0.0" resolve "^1.17.0" -"@rollup/plugin-replace@^2.3.1", "@rollup/plugin-replace@^2.3.3": +"@rollup/plugin-replace@^2.3.3", "@rollup/plugin-replace@^2.3.4": version "2.3.4" resolved "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.4.tgz#7dd84c17755d62b509577f2db37eb524d7ca88ca" integrity sha512-waBhMzyAtjCL1GwZes2jaE9MjuQ/DQF2BatH3fRivUF3z0JBFrU0U6iBNC/4WR+2rLKhaAhPWDNPYp4mI6RqdQ== @@ -1286,7 +1319,7 @@ remark "^13.0.0" unist-util-find-all-after "^3.0.2" -"@surma/rollup-plugin-off-main-thread@^1.1.1": +"@surma/rollup-plugin-off-main-thread@^1.4.1": version "1.4.2" resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58" integrity sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A== @@ -1367,10 +1400,10 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/fs-extra@^9.0.5": - version "9.0.5" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.5.tgz#2afb76a43a4bef80a363b94b314d0ca1694fc4f8" - integrity sha512-wr3t7wIW1c0A2BIJtdVp4EflriVaVVAsCAIHVzzh8B+GiFv9X1xeJjCs4upRXtzp7kQ6lP5xvskjoD4awJ1ZeA== +"@types/fs-extra@^9.0.6": + version "9.0.6" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.6.tgz#488e56b77299899a608b8269719c1d133027a6ab" + integrity sha512-ecNRHw4clCkowNOBJH1e77nvbPxHYnWIXMv1IAoG/9+MYGkgoyr3Ppxr7XYFNL41V422EDhyV4/4SSK8L2mlig== dependencies: "@types/node" "*" @@ -1517,13 +1550,6 @@ version "1.2.3" resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - -"@types/resolve@0.0.8": - version "0.0.8" - resolved "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" - integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== - dependencies: - "@types/node" "*" "@types/resolve@1.17.1": version "1.17.1" @@ -1841,7 +1867,7 @@ resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -2105,13 +2131,6 @@ dependencies: follow-redirects "^1.10.0" -babel-extract-comments@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" - integrity sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ== - dependencies: - babylon "^6.18.0" - babel-helper-vue-jsx-merge-props@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" @@ -2123,32 +2142,6 @@ integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" - -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= - -babel-plugin-transform-object-rest-spread@^6.26.0: - version "6.26.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== bail@^1.0.0: version "1.0.5" @@ -2950,11 +2943,6 @@ browserslist "^4.15.0" semver "7.0.0" -core-js@^2.4.0: - version "2.6.12" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - core-js@^3.6.1, core-js@^3.6.5: version "3.8.1" resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz#f51523668ac8a294d1285c3b9db44025fda66d47" @@ -3010,10 +2998,10 @@ resolved "https://registry.npmjs.org/crypto-es/-/crypto-es-1.2.6.tgz#468f3573a5d7b82e3b63b0004f55f905a6d3b12c" integrity sha512-PQnrovdr5ibmOxqAh/Vy+A30RokHom7kb9Z61EPwfASfbcJCrCG4+vNNegmebNVHiXvS7WjYpHDePxnE/biEbA== -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== cssesc@^3.0.0: version "3.0.0" @@ -3094,6 +3082,13 @@ dependencies: ms "2.1.2" +debug@^4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debug@~3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -3128,11 +3123,6 @@ version "1.0.1" resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= - -deep-freeze@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz#3a0b0005de18672819dfd38cd31f91179c893e84" - integrity sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ= deep-is@^0.1.3: version "0.1.3" @@ -3912,7 +3902,7 @@ resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-extra@8.1.0, fs-extra@^8.1.0: +fs-extra@8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -4863,15 +4853,7 @@ resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -jest-worker@^26.0.0, jest-worker@^26.2.1: +jest-worker@^26.2.1: version "26.6.2" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -5265,7 +5247,7 @@ resolved "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= -lodash.template@^4.0.2, lodash.template@^4.5.0: +lodash.template@^4.0.2: version "4.5.0" resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== @@ -6440,6 +6422,11 @@ resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz#cd89f79bbcef21e3d21eb0da68ffe93f803e884b" integrity sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA== +pretty-bytes@^5.4.1: + version "5.5.0" + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" + integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== + printj@~1.1.0, printj@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" @@ -6667,11 +6654,6 @@ resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -6824,7 +6806,7 @@ resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.17.0, resolve@^1.19.0: version "1.19.0" resolved "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -6865,14 +6847,6 @@ dependencies: glob "^7.1.3" -rollup-plugin-babel@^4.3.3: - version "4.4.0" - resolved "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz#d15bd259466a9d1accbdb2fe2fff17c52d030acb" - integrity sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - rollup-pluginutils "^2.8.1" - rollup-plugin-dynamic-import-variables@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/rollup-plugin-dynamic-import-variables/-/rollup-plugin-dynamic-import-variables-1.1.0.tgz#4981d38907a471b35234398a09047bef47a2006a" @@ -6900,28 +6874,7 @@ "@purge-icons/core" "^0.4.5" "@purge-icons/generated" "^0.4.1" -rollup-plugin-terser@^5.3.1: - version "5.3.1" - resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz#8c650062c22a8426c64268548957463bf981b413" - integrity sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w== - dependencies: - "@babel/code-frame" "^7.5.5" - jest-worker "^24.9.0" - rollup-pluginutils "^2.8.2" - serialize-javascript "^4.0.0" - terser "^4.6.2" - -rollup-plugin-terser@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-6.1.0.tgz#071866585aea104bfbb9dd1019ac523e63c81e45" - integrity sha512-4fB3M9nuoWxrwm39habpd4hvrbrde2W2GG4zEGPQg1YITNkM3Tqur5jSuXlWNzbv/2aMLJ+dZJaySc3GCD8oDw== - dependencies: - "@babel/code-frame" "^7.8.3" - jest-worker "^26.0.0" - serialize-javascript "^3.0.0" - terser "^4.7.0" - -rollup-plugin-terser@^7.0.2: +rollup-plugin-terser@^7.0.0, rollup-plugin-terser@^7.0.2: version "7.0.2" resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== @@ -6955,18 +6908,18 @@ resolved "https://registry.npmjs.org/rollup-plugin-web-worker-loader/-/rollup-plugin-web-worker-loader-1.5.0.tgz#df21973426c6f95b238a84698ae27f8d8aab6b83" integrity sha512-Zx5l370yGDje35rFkM/wbT4dMIq2+kSBdLWQpqLkBuxmrQJcx0umA05kSbNRzccFsudQH4FKYCK8GtSBQRQBBg== -rollup-plugin-workbox@^5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/rollup-plugin-workbox/-/rollup-plugin-workbox-5.2.1.tgz#371b0753667df03886742ec072281525803c2c75" - integrity sha512-C+yIoYkZ3VUcJTZpOH2zbaarHCwy8eQod987eS8hXE6qwfMLDqV3RkLYNplnO0PcMi+3JgZPiE6d1zuXgwkO7Q== +rollup-plugin-workbox@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/rollup-plugin-workbox/-/rollup-plugin-workbox-6.1.0.tgz#120cde36547769fc8cc45eae97a338c4017ed936" + integrity sha512-BqeEBj53fiqNLjiiyVvuBlic3Apg2Us1mpTkn3zgqaipJoAOC3soi+W9vrOQcm190lHLo9WNvi1wQg/M7olJHg== dependencies: - "@rollup/plugin-node-resolve" "^8.4.0" - "@rollup/plugin-replace" "^2.3.3" - pretty-bytes "^5.3.0" - rollup-plugin-terser "^6.1.0" - workbox-build "^5.0.0" + "@rollup/plugin-node-resolve" "^11.0.1" + "@rollup/plugin-replace" "^2.3.4" + pretty-bytes "^5.4.1" + rollup-plugin-terser "^7.0.2" + workbox-build "^6.0.2" -rollup-pluginutils@^2.8.1, rollup-pluginutils@^2.8.2: +rollup-pluginutils@^2.8.2: version "2.8.2" resolved "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== @@ -6981,14 +6934,12 @@ "@types/estree" "0.0.39" "@types/node" "*" -rollup@^1.31.1: - version "1.32.1" - resolved "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" - integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== - dependencies: - "@types/estree" "*" - "@types/node" "*" - acorn "^7.1.0" +rollup@^2.25.0: + version "2.35.1" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.35.1.tgz#e6bc8d10893556a638066f89e8c97f422d03968c" + integrity sha512-q5KxEyWpprAIcainhVy6HfRttD9kutQpHbeqDTWnqAFNJotiojetK6uqmcydNMymBEtC4I8bCYR+J3mTMqeaUA== + optionalDependencies: + fsevents "~2.1.2" rollup@^2.32.1, rollup@^2.34.1: version "2.34.2" @@ -7086,13 +7037,6 @@ integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: lru-cache "^6.0.0" - -serialize-javascript@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" - integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== - dependencies: - randombytes "^2.1.0" serialize-javascript@^4.0.0: version "4.0.0" @@ -7448,13 +7392,10 @@ resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= -strip-comments@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" - integrity sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw== - dependencies: - babel-extract-comments "^1.0.0" - babel-plugin-transform-object-rest-spread "^6.26.0" +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== strip-final-newline@^2.0.0: version "2.0.0" @@ -7689,11 +7630,6 @@ "@pawelgalazka/shell" "2.0.0" chalk "2.3.0" -temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= - temp-dir@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" @@ -7707,16 +7643,17 @@ temp-dir "^2.0.0" uuid "^3.3.2" -tempy@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" - integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== dependencies: - temp-dir "^1.0.0" - type-fest "^0.3.1" - unique-string "^1.0.0" + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" -terser@^4.6.2, terser@^4.6.3, terser@^4.7.0: +terser@^4.6.3: version "4.8.0" resolved "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -7898,15 +7835,15 @@ resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + type-fest@^0.18.0: version "0.18.1" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" - integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== type-fest@^0.6.0: version "0.6.0" @@ -7998,12 +7935,12 @@ resolved "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: - crypto-random-string "^1.0.0" + crypto-random-string "^2.0.0" unist-util-find-all-after@^3.0.2: version "3.0.2" @@ -8159,14 +8096,14 @@ "@purge-icons/generated" "^0.4.1" rollup-plugin-purge-icons "^0.4.5" -vite-plugin-pwa@^0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.1.7.tgz#3e13faf2d61b1f5a1b341f6b08f32216ffae1f55" - integrity sha512-S5Hc1x/rcfb6cgKjlW7yxSTv1er6fquzGZt/+xC1wavSBa7Qf6wdf6QzYiYdwmUom5yUSDEawc2gEYgq5SsZFg== +vite-plugin-pwa@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.2.0.tgz#e9368530c97537bdad7279f05de061ab9b024cce" + integrity sha512-OBNhlSqvqH9af9i8HsetmaRTrUjit3UP0rx33Sr0iBapM0gtuAmTjS4JPdSM54cGC1aVaIC3Rn3sY9wL0uxBrw== dependencies: - debug "^4.3.0" + debug "^4.3.2" fast-glob "^3.2.4" - rollup-plugin-workbox "^5.2.1" + rollup-plugin-workbox "^6.1.0" vite@^1.0.0-rc.13: version "1.0.0-rc.13" @@ -8354,146 +8291,160 @@ resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -workbox-background-sync@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz#5ae0bbd455f4e9c319e8d827c055bb86c894fd12" - integrity sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA== +workbox-background-sync@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.0.2.tgz#9205f5ef7fbf68203b925bdc85bdaa31a34fbbe6" + integrity sha512-KQU2ntvbvFoBvCRm+EDpWAaykt4u/oaF5j3C6io0dZVWhFc/ZwgYDii8fb34LTenug3VPWQELdw9dNBCoP4b0w== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-broadcast-update@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz#0eeb89170ddca7f6914fa3523fb14462891f2cfc" - integrity sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA== +workbox-broadcast-update@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.0.2.tgz#fc034277e631e4193dcee9f6b0a77e415b4ddefb" + integrity sha512-yCXYEln7nU8FkMDysYQPirpgFXtsdBtxruHbvZzRsxMHvAELf3j/o6Ufae1zjl8XanLF696sqSNxehpCGSD6tw== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-build@^5.0.0: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-5.1.4.tgz#23d17ed5c32060c363030c8823b39d0eabf4c8c7" - integrity sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow== +workbox-build@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-6.0.2.tgz#a23eebd6556cf473fedda77c08421b2d093efc32" + integrity sha512-Dukbt+p62Yzb12SXAmycTYvHngJ8aRtXy3hymsC8B6gxTCZmCZ0u5JuKhu7lNLbDwDkYE78lhFvT9SF+MXFz5A== dependencies: - "@babel/core" "^7.8.4" - "@babel/preset-env" "^7.8.4" - "@babel/runtime" "^7.8.4" - "@hapi/joi" "^15.1.0" - "@rollup/plugin-node-resolve" "^7.1.1" - "@rollup/plugin-replace" "^2.3.1" - "@surma/rollup-plugin-off-main-thread" "^1.1.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@hapi/joi" "^16.1.8" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^9.0.0" + "@rollup/plugin-replace" "^2.3.3" + "@surma/rollup-plugin-off-main-thread" "^1.4.1" common-tags "^1.8.0" fast-json-stable-stringify "^2.1.0" - fs-extra "^8.1.0" + fs-extra "^9.0.1" glob "^7.1.6" - lodash.template "^4.5.0" + lodash "^4.17.20" pretty-bytes "^5.3.0" - rollup "^1.31.1" - rollup-plugin-babel "^4.3.3" - rollup-plugin-terser "^5.3.1" + rollup "^2.25.0" + rollup-plugin-terser "^7.0.0" source-map "^0.7.3" source-map-url "^0.4.0" stringify-object "^3.3.0" - strip-comments "^1.0.2" - tempy "^0.3.0" + strip-comments "^2.0.1" + tempy "^0.6.0" upath "^1.2.0" - workbox-background-sync "^5.1.4" - workbox-broadcast-update "^5.1.4" - workbox-cacheable-response "^5.1.4" - workbox-core "^5.1.4" - workbox-expiration "^5.1.4" - workbox-google-analytics "^5.1.4" - workbox-navigation-preload "^5.1.4" - workbox-precaching "^5.1.4" - workbox-range-requests "^5.1.4" - workbox-routing "^5.1.4" - workbox-strategies "^5.1.4" - workbox-streams "^5.1.4" - workbox-sw "^5.1.4" - workbox-window "^5.1.4" + workbox-background-sync "^6.0.2" + workbox-broadcast-update "^6.0.2" + workbox-cacheable-response "^6.0.2" + workbox-core "^6.0.2" + workbox-expiration "^6.0.2" + workbox-google-analytics "^6.0.2" + workbox-navigation-preload "^6.0.2" + workbox-precaching "^6.0.2" + workbox-range-requests "^6.0.2" + workbox-recipes "^6.0.2" + workbox-routing "^6.0.2" + workbox-strategies "^6.0.2" + workbox-streams "^6.0.2" + workbox-sw "^6.0.2" + workbox-window "^6.0.2" -workbox-cacheable-response@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz#9ff26e1366214bdd05cf5a43da9305b274078a54" - integrity sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA== +workbox-cacheable-response@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.0.2.tgz#00b1133c4c846a2874f32ae14206c0636bacfd87" + integrity sha512-OrgFiYWkmFXDIbNRYSu+fchcfoZqyJ4yZbdc8WKUjr9v/MghKHfR9u7UI077xBkjno5J3YNpbwx73/no3HkrzA== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-core@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.4.tgz#8bbfb2362ecdff30e25d123c82c79ac65d9264f4" - integrity sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg== +workbox-core@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-6.0.2.tgz#2f865cfe633890b4210fd6d6fdb049a6daed0914" + integrity sha512-Ksl6qeikGb+BOCILoCUJGxwlEQOeeqdpOnpOr9UDt3NtacPYbfYBmpYpKArw5DFWK+5geBsFqgUUlXThlCYfKQ== -workbox-expiration@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.1.4.tgz#92b5df461e8126114943a3b15c55e4ecb920b163" - integrity sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ== +workbox-expiration@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.0.2.tgz#ac01e8d17f48daa31dc0872c09ee6f4d2cf28ccb" + integrity sha512-6+nbR18cklAdI3BPT675ytftXPwnVbXGR8mPWNWTJtl5y2urRYv56ZOJLD7FBFVkZ8EjWiRhNP/A0fkxgdKtWQ== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-google-analytics@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz#b3376806b1ac7d7df8418304d379707195fa8517" - integrity sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA== +workbox-google-analytics@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.0.2.tgz#7e3641adb30a3acb25006b244035631cf6f65019" + integrity sha512-xmYJurR1M6Pzc2SBM/E7AgwmBszhu/YYDzBnU+HJPZFLbTG97ASIJyTXV1vcczA/dNaS0miIf0cFqneozVlDRw== dependencies: - workbox-background-sync "^5.1.4" - workbox-core "^5.1.4" - workbox-routing "^5.1.4" - workbox-strategies "^5.1.4" + workbox-background-sync "^6.0.2" + workbox-core "^6.0.2" + workbox-routing "^6.0.2" + workbox-strategies "^6.0.2" -workbox-navigation-preload@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz#30d1b720d26a05efc5fa11503e5cc1ed5a78902a" - integrity sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ== +workbox-navigation-preload@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.0.2.tgz#bfd9c61096be921b830153a3004b7212220748dc" + integrity sha512-7+ojLrjXmTFZBfGmUQIcBWB+xrFgXLMJGNQAtxT7Ta9A23rEWo8jqAgeuwAylebcORUlM+ztgYTV7eGp+AD+Yg== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-precaching@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.1.4.tgz#874f7ebdd750dd3e04249efae9a1b3f48285fe6b" - integrity sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA== +workbox-precaching@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.0.2.tgz#cb45f290b0604bef1d9fc96bf42df82385d54e54" + integrity sha512-sqKWL2emzmGnfJpna+9RjUkUiqQO++AKfwljCbgkHg8wBbVLy/rnui3eelKgAI7D8R31LJFfiZkY/kXmwkjtlQ== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" + workbox-routing "^6.0.2" + workbox-strategies "^6.0.2" -workbox-range-requests@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz#7066a12c121df65bf76fdf2b0868016aa2bab859" - integrity sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw== +workbox-range-requests@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.0.2.tgz#3b50cbe8ddaaed7e3bfaa2dfdcd6a22e02fe7770" + integrity sha512-qCrDbH9AzDbCErde71Nys2iNZO9I9M9Jgl/9/Q67dGQVwFsEq73SuIzS2DGIBKqtIdC5QUigC3d7XJONajclUQ== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" -workbox-routing@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.4.tgz#3e8cd86bd3b6573488d1a2ce7385e547b547e970" - integrity sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw== +workbox-recipes@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.0.2.tgz#ad4b3f26a71a7396004c4f617af318f3fd072208" + integrity sha512-ewZIHO4jYE6bnEeUIYS6joQy3l+MydpOsVr2F6EpE8ps++z1ScbSdLtJU+yu6WuO3lH44HFZLeFxYQqYm50QAA== dependencies: - workbox-core "^5.1.4" + workbox-cacheable-response "^6.0.2" + workbox-core "^6.0.2" + workbox-expiration "^6.0.2" + workbox-precaching "^6.0.2" + workbox-routing "^6.0.2" + workbox-strategies "^6.0.2" -workbox-strategies@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.4.tgz#96b1418ccdfde5354612914964074d466c52d08c" - integrity sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA== +workbox-routing@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.0.2.tgz#8380bc322a2b1c44978df8ff6ae4e4d723f4e3f8" + integrity sha512-iQ9ch3fL1YpztDLfHNURaHQ0ispgPCdzWmZZhtSHUyy/+YkTlIiDVTbOQCIpHIrWlKQiim6X3K2ItIy1FW9+wA== dependencies: - workbox-core "^5.1.4" - workbox-routing "^5.1.4" + workbox-core "^6.0.2" -workbox-streams@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.1.4.tgz#05754e5e3667bdc078df2c9315b3f41210d8cac0" - integrity sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw== +workbox-strategies@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.0.2.tgz#f4383e2e5d46c1546e6e08048c9f5c9a7beb5137" + integrity sha512-HjLnYCVS60U7OKhl5NIq8NAQXrotJQRDakmIONnRlQIlP2If/kAiQSUP3QCHMq4EeXGiF+/CdlR1/bhYBHZzZg== dependencies: - workbox-core "^5.1.4" - workbox-routing "^5.1.4" + workbox-core "^6.0.2" -workbox-sw@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.1.4.tgz#2bb34c9f7381f90d84cef644816d45150011d3db" - integrity sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA== - -workbox-window@^5.1.4: - version "5.1.4" - resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-5.1.4.tgz#2740f7dea7f93b99326179a62f1cc0ca2c93c863" - integrity sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw== +workbox-streams@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.0.2.tgz#07c19025af309ad3475e737018a05ed538bffacd" + integrity sha512-bckftu/iMlg5LFXPZ6NX/FUc/w4illgxSuwtsZkQAO6Uen1EeegjfLyenO01/dwoyc3D/AlZepMdhv87XhE7HQ== dependencies: - workbox-core "^5.1.4" + workbox-core "^6.0.2" + workbox-routing "^6.0.2" + +workbox-sw@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.0.2.tgz#cd1b8b02ceaaf1abe5804936158a87ec605d271e" + integrity sha512-EoOjbyy5bpoBoSqt2PIeDOZ/JJ41f+WJjb979PkfIUWw4F+F/w2uKJJrMA5fk+nWnVge83Fwy8nF3dWNsqOrdg== + +workbox-window@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.0.2.tgz#9b47fdb7c088aa4e8b7d0c6cfda17c8bfca6bf7f" + integrity sha512-I/X+qUh1AwN9x/MxFbXsPn7DA27BMtzkXo55w1tBD8V54fv8nUCeC5E4RpXt/mlgdSwBztnURCQTWsdhTrSUjg== + dependencies: + workbox-core "^6.0.2" wrap-ansi@^5.1.0: version "5.1.0" -- Gitblit v1.8.0