mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-05-11 20:05:34 +00:00
Add automation settings modal
This commit is contained in:
parent
6f756b89aa
commit
6963d0d42f
12 changed files with 575 additions and 6 deletions
web-frontend
config
modules
automation
builder/locales
core/assets/scss/components
|
@ -35,7 +35,11 @@ export default function (
|
|||
const modules = baseModules.concat(additionalModules)
|
||||
return {
|
||||
modules,
|
||||
buildModules: ['@nuxtjs/stylelint-module', '@nuxtjs/svg'],
|
||||
buildModules: [
|
||||
'@nuxtjs/stylelint-module',
|
||||
'@nuxtjs/svg',
|
||||
'@nuxtjs/composition-api/module',
|
||||
],
|
||||
sentry: {
|
||||
clientIntegrations: {
|
||||
Dedupe: {},
|
||||
|
|
69
web-frontend/modules/automation/automationSettingTypes.js
Normal file
69
web-frontend/modules/automation/automationSettingTypes.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { Registerable } from '@baserow/modules/core/registry'
|
||||
import GeneralSettings from '@baserow/modules/automation/components/settings/GeneralSettings'
|
||||
import IntegrationSettings from '@baserow/modules/automation/components/settings/IntegrationSettings'
|
||||
|
||||
class AutomationSettingType extends Registerable {
|
||||
static getType() {
|
||||
return null
|
||||
}
|
||||
|
||||
get name() {
|
||||
return null
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return null
|
||||
}
|
||||
|
||||
get component() {
|
||||
return null
|
||||
}
|
||||
|
||||
get componentPadding() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class GeneralAutomationSettingsType extends AutomationSettingType {
|
||||
static getType() {
|
||||
return 'general'
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.app.i18n.t('builderSettingTypes.generalName')
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return 'iconoir-settings'
|
||||
}
|
||||
|
||||
getOrder() {
|
||||
return 1
|
||||
}
|
||||
|
||||
get component() {
|
||||
return GeneralSettings
|
||||
}
|
||||
}
|
||||
|
||||
export class IntegrationsAutomationSettingsType extends AutomationSettingType {
|
||||
static getType() {
|
||||
return 'integrations'
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.app.i18n.t('builderSettingTypes.integrationsName')
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return 'iconoir-ev-plug'
|
||||
}
|
||||
|
||||
getOrder() {
|
||||
return 10
|
||||
}
|
||||
|
||||
get component() {
|
||||
return IntegrationSettings
|
||||
}
|
||||
}
|
|
@ -5,18 +5,42 @@
|
|||
:application="application"
|
||||
:workspace="workspace"
|
||||
>
|
||||
<template #additional-context-items></template>
|
||||
<template #additional-context-items>
|
||||
<li
|
||||
v-if="
|
||||
$hasPermission(
|
||||
'application.update',
|
||||
application,
|
||||
application.workspace.id
|
||||
)
|
||||
"
|
||||
class="context__menu-item"
|
||||
>
|
||||
<a class="context__menu-item-link" @click="openSettingsModal">
|
||||
<i class="context__menu-item-icon iconoir-settings"></i>
|
||||
{{ $t('sidebarComponentBuilder.settings') }}
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ApplicationContext>
|
||||
|
||||
<AutomationSettingsModal
|
||||
ref="automationSettingsModal"
|
||||
:automation="application"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import AutomationSettingsModal from '@baserow/modules/automation/components/settings/AutomationSettingsModal'
|
||||
import ApplicationContext from '@baserow/modules/core/components/application/ApplicationContext'
|
||||
import applicationContext from '@baserow/modules/core/mixins/applicationContext'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ApplicationContext,
|
||||
AutomationSettingsModal,
|
||||
},
|
||||
mixins: [applicationContext],
|
||||
props: {
|
||||
|
@ -29,5 +53,20 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
setup() {
|
||||
const context = ref(null)
|
||||
const automationSettingsModal = ref(null)
|
||||
|
||||
const openSettingsModal = () => {
|
||||
automationSettingsModal.value.show()
|
||||
context.value.hide()
|
||||
}
|
||||
|
||||
return {
|
||||
context,
|
||||
automationSettingsModal,
|
||||
openSettingsModal,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<Modal
|
||||
left-sidebar
|
||||
left-sidebar-scrollable
|
||||
:content-padding="
|
||||
settingSelected == null ? true : settingSelected.componentPadding
|
||||
"
|
||||
>
|
||||
<template #sidebar>
|
||||
<div class="modal-sidebar__head">
|
||||
<div class="modal-sidebar__head-name">
|
||||
{{ $t('automationSettingsModal.title') }}
|
||||
</div>
|
||||
</div>
|
||||
<ul class="modal-sidebar__nav">
|
||||
<li v-for="setting in registeredSettings" :key="setting.getType()">
|
||||
<a
|
||||
class="modal-sidebar__nav-link"
|
||||
:class="{ active: setting === settingSelected }"
|
||||
@click="settingSelected = setting"
|
||||
>
|
||||
<i class="modal-sidebar__nav-icon" :class="setting.icon"></i>
|
||||
{{ setting.name }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-if="settingSelected" #content>
|
||||
<component
|
||||
:is="settingSelected.component"
|
||||
ref="settingSelected"
|
||||
:automation="automation"
|
||||
:default-values="automation"
|
||||
:hide-after-create="hideAfterCreate"
|
||||
:force-display-form="displaySelectedSettingForm"
|
||||
@hide-modal="emitCreatedRecord($event)"
|
||||
></component>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from '@baserow/modules/core/mixins/modal'
|
||||
import { defineComponent, ref, computed, watch, getCurrentInstance } from 'vue'
|
||||
import { useContext } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AutomationSettingsModal',
|
||||
mixins: [modal],
|
||||
props: {
|
||||
automation: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
/**
|
||||
* If you want the selected setting form to hide the builder settings modal
|
||||
* after a record is created, set this to `true`.
|
||||
*/
|
||||
hideAfterCreate: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { emit }) {
|
||||
const instance = getCurrentInstance()
|
||||
const { app } = useContext()
|
||||
|
||||
const settingSelected = ref(null)
|
||||
const displaySelectedSettingForm = ref(false)
|
||||
|
||||
const registeredSettings = computed(() => {
|
||||
return app.$registry.getOrderedList('automationSettings')
|
||||
})
|
||||
|
||||
// Watch for changes in the selected setting
|
||||
watch(settingSelected, (newSetting, oldSetting) => {
|
||||
if (
|
||||
oldSetting &&
|
||||
newSetting !== oldSetting &&
|
||||
displaySelectedSettingForm.value
|
||||
) {
|
||||
displaySelectedSettingForm.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// Method to emit the created record and hide the modal
|
||||
const emitCreatedRecord = (createdRecordId) => {
|
||||
instance.proxy.hide()
|
||||
emit('created', createdRecordId)
|
||||
}
|
||||
|
||||
return {
|
||||
registeredSettings,
|
||||
emitCreatedRecord,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
settingSelected: null,
|
||||
displaySelectedSettingForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Override show method from the modal mixin to handle setting selection.
|
||||
*/
|
||||
show(
|
||||
selectSettingType = null,
|
||||
displaySelectedSettingFormValue = false,
|
||||
...args
|
||||
) {
|
||||
// If we've been instructed to show a specific setting component,
|
||||
// then ensure it's displayed first.
|
||||
if (selectSettingType) {
|
||||
this.settingSelected = this.$registry.get(
|
||||
'automationSettings',
|
||||
selectSettingType
|
||||
)
|
||||
}
|
||||
|
||||
// If no `selectSettingType` was provided then choose the first setting.
|
||||
if (!this.settingSelected) {
|
||||
this.settingSelected = this.registeredSettings[0]
|
||||
}
|
||||
|
||||
// If we've been instructed to show the modal, and make the
|
||||
// selected setting component's form display, then do so.
|
||||
this.displaySelectedSettingForm = displaySelectedSettingFormValue
|
||||
|
||||
// Call the original show method from the mixin
|
||||
return modal.methods.show.call(this, ...args)
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,125 @@
|
|||
<template>
|
||||
<div>
|
||||
<h2 class="box__title">{{ $t('generalSettings.titleOverview') }}</h2>
|
||||
|
||||
<FormGroup
|
||||
small-label
|
||||
:label="$t('generalSettings.nameLabel')"
|
||||
:error="fieldHasErrors('name')"
|
||||
required
|
||||
class="margin-bottom-2"
|
||||
>
|
||||
<FormInput
|
||||
v-model="v$.values.name.$model"
|
||||
:error="fieldHasErrors('name')"
|
||||
size="large"
|
||||
></FormInput>
|
||||
<template #error>
|
||||
{{ v$.values.name.$errors[0].$message }}
|
||||
</template>
|
||||
</FormGroup>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<FormGroup
|
||||
small-label
|
||||
:label="$t('generalSettings.notificationLabel')"
|
||||
:error="fieldHasErrors('notification')"
|
||||
required
|
||||
class="margin-bottom-2"
|
||||
>
|
||||
<Checkbox v-model="v$.values.notification.$model" class="margin-top-1">{{
|
||||
$t('generalSettings.notificationCheckboxLabel')
|
||||
}}</Checkbox>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useVuelidate } from '@vuelidate/core'
|
||||
import {
|
||||
reactive,
|
||||
getCurrentInstance,
|
||||
defineComponent,
|
||||
toRefs,
|
||||
watch,
|
||||
} from 'vue'
|
||||
import { useStore, useContext } from '@nuxtjs/composition-api'
|
||||
import { required, helpers } from '@vuelidate/validators'
|
||||
import form from '@baserow/modules/core/mixins/form'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'GeneralSettings',
|
||||
mixins: [form],
|
||||
props: {
|
||||
automation: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const instance = getCurrentInstance()
|
||||
const { app } = useContext()
|
||||
const i18n = app.i18n
|
||||
const store = useStore()
|
||||
const { automation } = toRefs(props)
|
||||
|
||||
const values = reactive({
|
||||
values: {
|
||||
name: '',
|
||||
notification: false,
|
||||
},
|
||||
})
|
||||
|
||||
const rules = {
|
||||
values: {
|
||||
name: {
|
||||
required: helpers.withMessage(
|
||||
i18n.t('error.requiredField'),
|
||||
required
|
||||
),
|
||||
},
|
||||
notification: {},
|
||||
},
|
||||
}
|
||||
|
||||
const v$ = useVuelidate(rules, values, { $lazy: true })
|
||||
|
||||
const updateAutomation = async (updatedValues) => {
|
||||
if (_.isMatch(automation.value, updatedValues)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await store.dispatch('application/update', {
|
||||
automation: automation.value,
|
||||
values: updatedValues,
|
||||
})
|
||||
} catch (error) {
|
||||
const title = i18n.t('generalSettings.cantUpdateAutomationTitle')
|
||||
const message = i18n.t(
|
||||
'generalSettings.cantUpdateAutomationDescription'
|
||||
)
|
||||
store.dispatch('toast/error', { title, message })
|
||||
instance.proxy.reset()
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => values.values,
|
||||
(newValues) => {
|
||||
updateAutomation(newValues)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
return {
|
||||
values: values.values,
|
||||
v$,
|
||||
updateAutomation,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div>
|
||||
<h2 class="box__title">{{ $t('integrationSettings.title') }}</h2>
|
||||
<div v-if="state === 'pending'" class="integration-settings__loader" />
|
||||
<template v-if="state === 'loaded'">
|
||||
<template v-if="integrations && integrations.length > 0">
|
||||
<p class="margin-top-3">
|
||||
{{ $t('integrationSettings.integrationMessage') }}
|
||||
</p>
|
||||
<div
|
||||
v-for="integration in integrations"
|
||||
:key="integration.id"
|
||||
class="integration-settings__integration"
|
||||
>
|
||||
<Presentation
|
||||
:image="getIntegrationType(integration).image"
|
||||
:title="integration.name"
|
||||
:subtitle="getIntegrationType(integration).getSummary(integration)"
|
||||
:rounded-icon="false"
|
||||
avatar-color="transparent"
|
||||
style="flex: 1"
|
||||
/>
|
||||
<div class="integration-settings__integration-actions">
|
||||
<ButtonIcon
|
||||
icon="iconoir-edit"
|
||||
@click="
|
||||
$refs[`IntegrationCreateEditModal_${integration.id}`][0].show()
|
||||
"
|
||||
/>
|
||||
<ButtonIcon
|
||||
icon="iconoir-bin"
|
||||
@click="deleteIntegration(integration)"
|
||||
/>
|
||||
</div>
|
||||
<IntegrationCreateEditModal
|
||||
:ref="`IntegrationCreateEditModal_${integration.id}`"
|
||||
:data-integration-id="integration.id"
|
||||
:application="automation"
|
||||
:integration="integration"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<p v-else class="margin-top-3">
|
||||
{{ $t('integrationSettings.noIntegrationMessage') }}
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IntegrationCreateEditModal from '@baserow/modules/core/components/integrations/IntegrationCreateEditModal'
|
||||
import { notifyIf } from '@baserow/modules/core/utils/error'
|
||||
import { defineComponent, ref, computed, onMounted, toRefs } from 'vue'
|
||||
import { useStore, useContext } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'IntegrationSettings',
|
||||
components: { IntegrationCreateEditModal },
|
||||
props: {
|
||||
automation: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const { automation } = toRefs(props)
|
||||
const store = useStore()
|
||||
const { app } = useContext()
|
||||
const state = ref('loaded')
|
||||
|
||||
const integrationTypes = computed(() => {
|
||||
return app.$registry.getOrderedList('integration')
|
||||
})
|
||||
|
||||
const integrations = computed(() => {
|
||||
return store.getters['integration/getIntegrations'](automation.value)
|
||||
})
|
||||
|
||||
const getIntegrationType = (integration) => {
|
||||
return app.$registry.get('integration', integration.type)
|
||||
}
|
||||
|
||||
const fetchIntegrations = async () => {
|
||||
try {
|
||||
state.value = 'pending'
|
||||
await store.dispatch('integration/fetch', {
|
||||
application: automation.value,
|
||||
})
|
||||
state.value = 'loaded'
|
||||
} catch (error) {
|
||||
notifyIf(error)
|
||||
state.value = 'loaded'
|
||||
}
|
||||
}
|
||||
|
||||
const deleteIntegration = async (integration) => {
|
||||
try {
|
||||
await store.dispatch('integration/delete', {
|
||||
application: automation.value,
|
||||
integrationId: integration.id,
|
||||
})
|
||||
} catch (error) {
|
||||
notifyIf(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchIntegrations()
|
||||
})
|
||||
|
||||
return {
|
||||
state,
|
||||
integrationTypes,
|
||||
integrations,
|
||||
getIntegrationType,
|
||||
deleteIntegration,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
|
@ -22,5 +22,18 @@
|
|||
},
|
||||
"trashType": {
|
||||
"workflow": "workflow"
|
||||
},
|
||||
"generalSettings": {
|
||||
"titleOverview": "General",
|
||||
"nameLabel": "Automation name",
|
||||
"notificationLabel": "Notifications",
|
||||
"notificationCheckboxLabel": "Get notified when this automation fails",
|
||||
"cantUpdateAutomationTitle": "Couldn't Update Automation",
|
||||
"cantUpdateAutomationDescription": "Sorry, could not update the automation."
|
||||
},
|
||||
"integrationSettings": {
|
||||
"title": "Integrations",
|
||||
"noIntegrationMessage": "You have not yet created any integrations. They can be created by adding data source, action or user authentication.",
|
||||
"integrationMessage": "You can create new integrations by adding data source, action or user authentication."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import es from '@baserow/modules/automation/locales/es.json'
|
|||
import it from '@baserow/modules/automation/locales/it.json'
|
||||
import pl from '@baserow/modules/automation/locales/pl.json'
|
||||
import ko from '@baserow/modules/automation/locales/ko.json'
|
||||
import {
|
||||
GeneralAutomationSettingsType,
|
||||
IntegrationsAutomationSettingsType,
|
||||
} from '@baserow/modules/automation/automationSettingTypes'
|
||||
|
||||
import { registerRealtimeEvents } from '@baserow/modules/automation/realtime'
|
||||
import { AutomationApplicationType } from '@baserow/modules/automation/applicationTypes'
|
||||
|
@ -48,5 +52,15 @@ export default (context) => {
|
|||
'job',
|
||||
new DuplicateAutomationWorkflowJobType(context)
|
||||
)
|
||||
|
||||
app.$registry.registerNamespace('automationSettings')
|
||||
app.$registry.register(
|
||||
'automationSettings',
|
||||
new GeneralAutomationSettingsType(context)
|
||||
)
|
||||
app.$registry.register(
|
||||
'automationSettings',
|
||||
new IntegrationsAutomationSettingsType(context)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1017,5 +1017,8 @@
|
|||
"smile": "Smile",
|
||||
"thumbsUp": "Thumbs Up",
|
||||
"flag": "Flag"
|
||||
},
|
||||
"automationSettingsModal": {
|
||||
"title": "Workflow"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.separator {
|
||||
margin: 30px 0;
|
||||
border-bottom: solid 1px $color-neutral-200;
|
||||
border-bottom: solid 1px $palette-neutral-200;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"test-storybook": "test-storybook"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/composition-api": "^0.34.0",
|
||||
"@nuxtjs/i18n": "7.3.1",
|
||||
"@nuxtjs/sentry": "7.5.0",
|
||||
"@storybook/core-client": "6.5.9",
|
||||
|
|
|
@ -2256,6 +2256,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
|
||||
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9":
|
||||
version "0.3.20"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f"
|
||||
|
@ -2720,6 +2725,18 @@
|
|||
webpack-node-externals "^3.0.0"
|
||||
webpackbar "^5.0.2"
|
||||
|
||||
"@nuxtjs/composition-api@^0.34.0":
|
||||
version "0.34.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.34.0.tgz#4608b712164958c0efdbd3e8195137a2d6243391"
|
||||
integrity sha512-2BWv4zmlFhu09eo8oeXk11jVdsRLh6vXwtaDADMaZ8Do8SoY2fEk3dmtAkr3aUQuSIzOD/jdWBnd0h99/YIrSA==
|
||||
dependencies:
|
||||
defu "^6.1.4"
|
||||
estree-walker "^2.0.2"
|
||||
fs-extra "^11.2.0"
|
||||
magic-string "^0.30.9"
|
||||
pathe "^1.1.2"
|
||||
ufo "^1.5.3"
|
||||
|
||||
"@nuxtjs/eslint-config@12.0.0":
|
||||
version "12.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/eslint-config/-/eslint-config-12.0.0.tgz#36ac450efd20e3efb8f8a961e094b267c49adac4"
|
||||
|
@ -8211,6 +8228,11 @@ defu@^6.0.0, defu@^6.1.2, defu@^6.1.3:
|
|||
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd"
|
||||
integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==
|
||||
|
||||
defu@^6.1.4:
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
|
||||
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
|
||||
|
||||
del@^6.0.0:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a"
|
||||
|
@ -9969,6 +9991,15 @@ fs-extra@^11.1.0:
|
|||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs-extra@^11.2.0:
|
||||
version "11.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d"
|
||||
integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs-extra@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||
|
@ -13203,6 +13234,13 @@ magic-string@^0.30.5:
|
|||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.4.15"
|
||||
|
||||
magic-string@^0.30.9:
|
||||
version "0.30.17"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||
integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||
|
@ -14911,7 +14949,7 @@ pathe@^0.3.0:
|
|||
resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.9.tgz#4baff768f37f03e3d9341502865fb93116f65191"
|
||||
integrity sha512-6Y6s0vT112P3jD8dGfuS6r+lpa0qqNrLyHPOwvXMnyNTQaYiwgau2DP3aNDsR13xqtGj7rrPo+jFUATpU6/s+g==
|
||||
|
||||
pathe@^1.1.1:
|
||||
pathe@^1.1.1, pathe@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
|
||||
integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
|
||||
|
@ -19158,6 +19196,11 @@ ufo@^1.3.1:
|
|||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496"
|
||||
integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==
|
||||
|
||||
ufo@^1.5.3:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b"
|
||||
integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==
|
||||
|
||||
ufo@^1.5.4:
|
||||
version "1.5.4"
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue