Migrate configStore to ts
This commit is contained in:
parent
bd695e7067
commit
b37d614e27
9 changed files with 247 additions and 150 deletions
5
.github/workflows/main.yml
vendored
5
.github/workflows/main.yml
vendored
|
|
@ -131,17 +131,20 @@ jobs:
|
||||||
VERSION="${GITHUB_REF##*/}"
|
VERSION="${GITHUB_REF##*/}"
|
||||||
SHA=$(git rev-parse HEAD)
|
SHA=$(git rev-parse HEAD)
|
||||||
DATE=$(date -u +"%Y%m%d")
|
DATE=$(date -u +"%Y%m%d")
|
||||||
|
BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | sed 's/\//-/g')
|
||||||
|
|
||||||
echo "Current version: ${VERSION}, SHA: ${SHA}, Date: ${DATE}"
|
echo "Current version: ${VERSION}, Branch: ${BRANCH}, SHA: ${SHA}, Date: ${DATE}"
|
||||||
|
|
||||||
echo "APP_VERSION=${VERSION}" >> $"$GITHUB_ENV"
|
echo "APP_VERSION=${VERSION}" >> $"$GITHUB_ENV"
|
||||||
echo "APP_SHA=${SHA}" >> "$GITHUB_ENV"
|
echo "APP_SHA=${SHA}" >> "$GITHUB_ENV"
|
||||||
echo "APP_DATE=${DATE}" >> "$GITHUB_ENV"
|
echo "APP_DATE=${DATE}" >> "$GITHUB_ENV"
|
||||||
|
echo "APP_BRANCH=${BRANCH}" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
sed -i \
|
sed -i \
|
||||||
-e "s/^APP_VERSION = \".*\"/APP_VERSION = \"${VERSION}\"/" \
|
-e "s/^APP_VERSION = \".*\"/APP_VERSION = \"${VERSION}\"/" \
|
||||||
-e "s/^APP_COMMIT_SHA = \".*\"/APP_COMMIT_SHA = \"${SHA}\"/" \
|
-e "s/^APP_COMMIT_SHA = \".*\"/APP_COMMIT_SHA = \"${SHA}\"/" \
|
||||||
-e "s/^APP_BUILD_DATE = \".*\"/APP_BUILD_DATE = \"${DATE}\"/" \
|
-e "s/^APP_BUILD_DATE = \".*\"/APP_BUILD_DATE = \"${DATE}\"/" \
|
||||||
|
-e "s/^APP_BRANCH = \".*\"/APP_BRANCH = \"${BRANCH}\"/" \
|
||||||
app/library/version.py
|
app/library/version.py
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import coloredlogs
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from .Utils import FileLogFormatter, arg_converter
|
from .Utils import FileLogFormatter, arg_converter
|
||||||
from .version import APP_BUILD_DATE, APP_COMMIT_SHA, APP_VERSION
|
from .version import APP_BRANCH, APP_BUILD_DATE, APP_COMMIT_SHA, APP_VERSION
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
@ -122,6 +122,9 @@ class Config:
|
||||||
app_build_date: str = APP_BUILD_DATE
|
app_build_date: str = APP_BUILD_DATE
|
||||||
"The build date of the application."
|
"The build date of the application."
|
||||||
|
|
||||||
|
app_branch: str = APP_BRANCH
|
||||||
|
"The branch of the application."
|
||||||
|
|
||||||
__instance = None
|
__instance = None
|
||||||
"The instance of the class."
|
"The instance of the class."
|
||||||
|
|
||||||
|
|
@ -201,6 +204,7 @@ class Config:
|
||||||
"app_version",
|
"app_version",
|
||||||
"app_commit_sha",
|
"app_commit_sha",
|
||||||
"app_build_date",
|
"app_build_date",
|
||||||
|
"app_branch",
|
||||||
)
|
)
|
||||||
"The variables that are immutable."
|
"The variables that are immutable."
|
||||||
|
|
||||||
|
|
@ -257,6 +261,7 @@ class Config:
|
||||||
"app_version",
|
"app_version",
|
||||||
"app_commit_sha",
|
"app_commit_sha",
|
||||||
"app_build_date",
|
"app_build_date",
|
||||||
|
"app_branch",
|
||||||
)
|
)
|
||||||
"The variables that are relevant to the frontend."
|
"The variables that are relevant to the frontend."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,6 @@ APP_COMMIT_SHA = "unknown"
|
||||||
|
|
||||||
APP_BUILD_DATE = "unknown"
|
APP_BUILD_DATE = "unknown"
|
||||||
"Build date of the application"
|
"Build date of the application"
|
||||||
|
|
||||||
|
APP_BRANCH = "unknown"
|
||||||
|
"Branch of the application"
|
||||||
|
|
|
||||||
18
ui/@types/changelogs.d.ts
vendored
Normal file
18
ui/@types/changelogs.d.ts
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
type changelogs = changeset[]
|
||||||
|
|
||||||
|
type changeset = {
|
||||||
|
tag: string
|
||||||
|
full_sha: string
|
||||||
|
date: string
|
||||||
|
commits: Commit[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Commit = {
|
||||||
|
sha: string
|
||||||
|
full_sha: string
|
||||||
|
message: string
|
||||||
|
author: string
|
||||||
|
date: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {changelogs, changeset, Commit}
|
||||||
79
ui/@types/config.d.ts
vendored
Normal file
79
ui/@types/config.d.ts
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
|
||||||
|
type AppConfig = {
|
||||||
|
/** Path where downloaded files will be saved */
|
||||||
|
download_path: string
|
||||||
|
/** Indicates if the app should keep an archive of downloaded files */
|
||||||
|
keep_archive: boolean
|
||||||
|
/** Indicates if files should be removed after download */
|
||||||
|
remove_files: boolean
|
||||||
|
/** Indicates if the UI should update the title with the current download status */
|
||||||
|
ui_update_title: boolean
|
||||||
|
/** Output template for yt-dlp, e.g. "%(title)s.%(ext)s" */
|
||||||
|
output_template: string
|
||||||
|
/** yt-dlp version, e.g. "2023.10.01" */
|
||||||
|
ytdlp_version: string
|
||||||
|
/** Maximum number of concurrent download workers */
|
||||||
|
max_workers: number
|
||||||
|
/** Indicates if the app is in basic mode, which may limit some features */
|
||||||
|
basic_mode: boolean
|
||||||
|
/** Default preset name, e.g. "default" */
|
||||||
|
default_preset: string
|
||||||
|
/** Instance title for the app, null if not set */
|
||||||
|
instance_title: string | null
|
||||||
|
/** Sentry DSN for error tracking, null if not configured */
|
||||||
|
sentry_dsn: string | null
|
||||||
|
/** Indicates if the console is enabled */
|
||||||
|
console_enabled: boolean
|
||||||
|
/** Indicates if the file browser is enabled */
|
||||||
|
browser_enabled: boolean
|
||||||
|
/** Command options for yt-dlp */
|
||||||
|
ytdlp_cli: string
|
||||||
|
/** Indicates if file logging is enabled */
|
||||||
|
file_logging: boolean
|
||||||
|
/** Indicates if the app is running in a native environment (e.g., Electron) */
|
||||||
|
is_native: boolean
|
||||||
|
/** App version in format "1.0.0" */
|
||||||
|
app_version: string
|
||||||
|
/** App version in semantic versioning format, e.g. "1.0.0" */
|
||||||
|
app_commit_sha: string
|
||||||
|
/** App build date in ISO format, e.g. "2023-10-01T12:00:00Z" */
|
||||||
|
app_build_date: string
|
||||||
|
/** App branch name, e.g. "main" or "develop" */
|
||||||
|
app_branch: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Preset = {
|
||||||
|
/** Unique identifier for the preset */
|
||||||
|
id?: string
|
||||||
|
/** Preset name, e.g. "default" */
|
||||||
|
name: string
|
||||||
|
/** Optional description for the preset */
|
||||||
|
description: string
|
||||||
|
/** Folder where files will be saved, e.g. "/downloads" */
|
||||||
|
folder: string
|
||||||
|
/** Output template for the preset, e.g. "%(title)s.%(ext)s" */
|
||||||
|
template: string
|
||||||
|
/** Cookies for the preset, e.g. "cookies.txt" */
|
||||||
|
cookies: string
|
||||||
|
/** Additional command line options for yt-dlp */
|
||||||
|
cli: string
|
||||||
|
/** Indicates if this is the default preset */
|
||||||
|
default: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigState = {
|
||||||
|
/** Show or hide the download form */
|
||||||
|
showForm: RemovableRef<boolean>
|
||||||
|
/** Application configuration */
|
||||||
|
app: AppConfig
|
||||||
|
/** List of presets */
|
||||||
|
presets: Preset[]
|
||||||
|
/** List of folders where files can be saved */
|
||||||
|
folders: string[]
|
||||||
|
/** Indicates if downloads are currently paused */
|
||||||
|
paused: boolean
|
||||||
|
/** Indicates if the configuration has been loaded */
|
||||||
|
is_loaded: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { AppConfig, Preset, ConfigState }
|
||||||
|
|
@ -113,14 +113,14 @@
|
||||||
|
|
||||||
<div class="columns mt-3 is-mobile">
|
<div class="columns mt-3 is-mobile">
|
||||||
<div class="column is-8-mobile">
|
<div class="column is-8-mobile">
|
||||||
<div class="has-text-left" v-if="config.app?.version">
|
<div class="has-text-left" v-if="config.app?.app_version">
|
||||||
© {{ Year }} - <NuxtLink href="https://github.com/ArabCoders/ytptube" target="_blank">YTPTube</NuxtLink>
|
© {{ Year }} - <NuxtLink href="https://github.com/ArabCoders/ytptube" target="_blank">YTPTube</NuxtLink>
|
||||||
<span class="is-hidden-mobile"
|
<span class="is-hidden-mobile"
|
||||||
v-tooltip="`Build Date: ${config.app?.app_build_date}, commit: ${config.app?.app_commit_sha}`">
|
v-tooltip="`Build Date: ${config.app?.app_build_date}, Branch: ${config.app?.app_branch}, commit: ${config.app?.app_commit_sha}`">
|
||||||
({{ config?.app?.version || 'unknown' }})</span>
|
({{ config?.app?.app_version || 'unknown' }})</span>
|
||||||
- <NuxtLink target="_blank" href="https://github.com/yt-dlp/yt-dlp">yt-dlp</NuxtLink>
|
- <NuxtLink target="_blank" href="https://github.com/yt-dlp/yt-dlp">yt-dlp</NuxtLink>
|
||||||
<span class="is-hidden-mobile"> ({{ config?.app?.ytdlp_version || 'unknown' }})</span>
|
<span class="is-hidden-mobile"> ({{ config?.app?.ytdlp_version || 'unknown' }})</span>
|
||||||
- <NuxtLink :to="`/changelog?version=${config?.app?.version || 'unknown'}`">CHANGELOG</NuxtLink>
|
- <NuxtLink to="/changelog">CHANGELOG</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-4-mobile" v-if="config.app?.started">
|
<div class="column is-4-mobile" v-if="config.app?.started">
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
<style scoped>
|
||||||
|
.logs-container {
|
||||||
|
padding: 1rem;
|
||||||
|
min-width: 100%;
|
||||||
|
max-height: 73vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: unset;
|
||||||
|
border-bottom: 1px solid var(--bulma-grey-light) !important
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
<div class="mt-1 columns is-multiline">
|
<div class="mt-1 columns is-multiline">
|
||||||
|
|
@ -51,8 +66,9 @@
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
import type { changelogs, changeset } from '~/@types/changelogs'
|
||||||
|
|
||||||
const toast = useNotification()
|
const toast = useNotification()
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
|
|
@ -63,63 +79,38 @@ const PROJECT = 'ytptube'
|
||||||
const REPO = `https://github.com/arabcoders/${PROJECT}`
|
const REPO = `https://github.com/arabcoders/${PROJECT}`
|
||||||
const REPO_URL = `https://arabcoders.github.io/${PROJECT}/CHANGELOG.json?version={version}`
|
const REPO_URL = `https://arabcoders.github.io/${PROJECT}/CHANGELOG.json?version={version}`
|
||||||
|
|
||||||
const logs = ref([])
|
const logs = ref<changelogs>([])
|
||||||
const api_version = ref('')
|
const api_version = ref('')
|
||||||
const isLoading = ref(false)
|
const api_branch = ref('')
|
||||||
const hashLength = ref(7)
|
const api_sha = ref('')
|
||||||
|
const isLoading = ref(true)
|
||||||
const branch = computed(() => {
|
|
||||||
const branch = String(api_version.value).split('-')[0] ?? 'master'
|
|
||||||
return ['master', 'dev'].includes(branch) ? branch : 'master'
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(() => config.app.version, async value => {
|
|
||||||
if (!value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
api_version.value = value
|
|
||||||
hashLength.value = value.split('-').pop().length
|
|
||||||
|
|
||||||
await nextTick()
|
|
||||||
await loadContent()
|
|
||||||
}, { immediate: true })
|
|
||||||
|
|
||||||
const loadContent = async () => {
|
const loadContent = async () => {
|
||||||
if ('' === api_version.value) {
|
if ('' === api_version.value || logs.value.length > 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoading.value = true
|
|
||||||
try {
|
try {
|
||||||
try{
|
try {
|
||||||
logs.value = await (await request(uri('/CHANGELOG.json'), { method: 'GET' })).json()
|
const changes = await fetch(REPO_URL.replace('{branch}', api_branch.value).replace('{version}', api_version.value))
|
||||||
}catch(e){
|
|
||||||
console.error(e)
|
|
||||||
const changes = await fetch(REPO_URL.replace('{branch}', branch.value).replace('{version}', api_version.value))
|
|
||||||
logs.value = await changes.json()
|
logs.value = await changes.json()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
logs.value = await (await request(uri('/CHANGELOG.json'), { method: 'GET' })).json()
|
||||||
}
|
}
|
||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
logs.value = logs.value.slice(0, 10)
|
||||||
logs.value = logs.value.slice(0, 10).map(log => {
|
} catch (e: any) {
|
||||||
log.commits = log.commits.map(commit => {
|
|
||||||
commit.full_sha = commit.sha.padEnd(hashLength.value, '0')
|
|
||||||
return commit
|
|
||||||
})
|
|
||||||
log.full_sha = log.tag.padEnd(hashLength.value, '0')
|
|
||||||
return log
|
|
||||||
})
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
console.error(e)
|
||||||
toast.error('error', 'Error', `Failed to fetch changelog. ${e.message}`)
|
toast.error(`Failed to fetch changelog. ${e.message}`)
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isInstalled = log => {
|
const isInstalled = (log: changeset) => {
|
||||||
const installed = String(api_version.value).split('-').pop()
|
const installed = String(api_sha.value)
|
||||||
|
|
||||||
if (log.full_sha.startsWith(installed)) {
|
if (log.full_sha.startsWith(installed)) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -134,20 +125,11 @@ const isInstalled = log => {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => loadContent())
|
onMounted(async () => {
|
||||||
|
await awaiter(config.isLoaded)
|
||||||
|
api_branch.value = config.app.app_branch
|
||||||
|
api_version.value = config.app.app_version
|
||||||
|
api_sha.value = config.app.app_commit_sha
|
||||||
|
loadContent()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.logs-container {
|
|
||||||
padding: 1rem;
|
|
||||||
min-width: 100%;
|
|
||||||
max-height: 73vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
background-color: unset;
|
|
||||||
border-bottom: 1px solid var(--bulma-grey-light) !important
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import { useStorage } from '@vueuse/core'
|
|
||||||
|
|
||||||
const CONFIG_KEYS = {
|
|
||||||
showForm: useStorage('showForm', false),
|
|
||||||
app: {
|
|
||||||
download_path: '/downloads',
|
|
||||||
keep_archive: false,
|
|
||||||
remove_files: false,
|
|
||||||
ui_update_title: true,
|
|
||||||
output_template: '',
|
|
||||||
ytdlp_version: '',
|
|
||||||
max_workers: 1,
|
|
||||||
version: '',
|
|
||||||
basic_mode: true,
|
|
||||||
default_preset: 'default',
|
|
||||||
instance_title: null,
|
|
||||||
sentry_dsn: null,
|
|
||||||
console_enabled: false,
|
|
||||||
browser_enabled: false,
|
|
||||||
ytdlp_cli: '',
|
|
||||||
file_logging: false,
|
|
||||||
is_native: false,
|
|
||||||
app_version: '',
|
|
||||||
app_commit_sha: '',
|
|
||||||
app_build_date: '',
|
|
||||||
},
|
|
||||||
presets: [
|
|
||||||
{
|
|
||||||
'name': 'default',
|
|
||||||
'format': 'default',
|
|
||||||
'folder': '',
|
|
||||||
'template': '',
|
|
||||||
'cookies': '',
|
|
||||||
'cli': '',
|
|
||||||
'default': true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
folders: [],
|
|
||||||
tasks: [],
|
|
||||||
paused: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useConfigStore = defineStore('config', () => {
|
|
||||||
const state = reactive(CONFIG_KEYS);
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
add(key, value) {
|
|
||||||
if (key.includes('.')) {
|
|
||||||
const [parentKey, subKey] = key.split('.');
|
|
||||||
state[parentKey][subKey] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state[key] = value;
|
|
||||||
},
|
|
||||||
get(key, defaultValue = null) {
|
|
||||||
if (key.includes('.')) {
|
|
||||||
const [parentKey, subKey] = key.split('.');
|
|
||||||
return state[parentKey][subKey] || defaultValue;
|
|
||||||
}
|
|
||||||
return state[key] || defaultValue;
|
|
||||||
},
|
|
||||||
update(key, value) {
|
|
||||||
if (key.includes('.')) {
|
|
||||||
const [parentKey, subKey] = key.split('.');
|
|
||||||
state[parentKey][subKey] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state[key] = value;
|
|
||||||
},
|
|
||||||
getAll() {
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
setAll(data) {
|
|
||||||
Object.keys(data).forEach((key) => {
|
|
||||||
if (key.includes('.')) {
|
|
||||||
const [parentKey, subKey] = key.split('.');
|
|
||||||
state[parentKey][subKey] = data[key];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state[key] = data[key];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return { ...toRefs(state), ...actions };
|
|
||||||
});
|
|
||||||
93
ui/stores/ConfigStore.ts
Normal file
93
ui/stores/ConfigStore.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
import { useStorage } from '@vueuse/core'
|
||||||
|
import type { ConfigState } from '~/@types/config';
|
||||||
|
|
||||||
|
export const useConfigStore = defineStore('config', () => {
|
||||||
|
const state = reactive<ConfigState>({
|
||||||
|
showForm: useStorage('showForm', false),
|
||||||
|
app: {
|
||||||
|
download_path: '/downloads',
|
||||||
|
keep_archive: false,
|
||||||
|
remove_files: false,
|
||||||
|
ui_update_title: true,
|
||||||
|
output_template: '',
|
||||||
|
ytdlp_version: '',
|
||||||
|
max_workers: 1,
|
||||||
|
basic_mode: true,
|
||||||
|
default_preset: 'default',
|
||||||
|
instance_title: null,
|
||||||
|
sentry_dsn: null,
|
||||||
|
console_enabled: false,
|
||||||
|
browser_enabled: false,
|
||||||
|
ytdlp_cli: '',
|
||||||
|
file_logging: false,
|
||||||
|
is_native: false,
|
||||||
|
app_version: '',
|
||||||
|
app_commit_sha: '',
|
||||||
|
app_build_date: '',
|
||||||
|
app_branch: '',
|
||||||
|
},
|
||||||
|
presets: [
|
||||||
|
{
|
||||||
|
'name': 'default',
|
||||||
|
'description': 'Default preset for downloads',
|
||||||
|
'folder': '',
|
||||||
|
'template': '',
|
||||||
|
'cookies': '',
|
||||||
|
'cli': '',
|
||||||
|
'default': true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
folders: [],
|
||||||
|
paused: false,
|
||||||
|
is_loaded: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const add = (key: string, value: any) => {
|
||||||
|
if (key.includes('.')) {
|
||||||
|
const [parentKey, subKey] = key.split('.') as [keyof ConfigState, string]
|
||||||
|
state[parentKey][subKey] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(state as any)[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
const get = (key: string, defaultValue: any = null): any => {
|
||||||
|
if (key.includes('.')) {
|
||||||
|
const [parentKey, subKey] = key.split('.') as [keyof ConfigState, string]
|
||||||
|
const parent = state[parentKey] as any
|
||||||
|
return parent?.[subKey] ?? defaultValue
|
||||||
|
}
|
||||||
|
return (state as any)[key] ?? defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = add
|
||||||
|
|
||||||
|
const getAll = (): ConfigState => state
|
||||||
|
|
||||||
|
const setAll = (data: Record<string, any>) => {
|
||||||
|
Object.keys(data).forEach((key) => {
|
||||||
|
if (key.includes('.')) {
|
||||||
|
const [parentKey, subKey] = key.split('.') as [keyof ConfigState, string]
|
||||||
|
const parent = state[parentKey] as any
|
||||||
|
parent[subKey] = data[key]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
(state as any)[key] = data[key]
|
||||||
|
})
|
||||||
|
|
||||||
|
state.is_loaded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLoaded = () => state.is_loaded
|
||||||
|
|
||||||
|
return {
|
||||||
|
...toRefs(state), add, get, update, getAll, setAll, isLoaded,
|
||||||
|
} as { [K in keyof ConfigState]: Ref<ConfigState[K]> } & {
|
||||||
|
add: typeof add
|
||||||
|
get: typeof get
|
||||||
|
update: typeof update
|
||||||
|
getAll: typeof getAll
|
||||||
|
setAll: typeof setAll
|
||||||
|
isLoaded: typeof isLoaded
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue