feat(home): update and fix home page

feat(campaigns): add campaigns page

chore: add oxlint linter on top of eslint

refactor(pocketbase): rework typing of Pocketbase store
This commit is contained in:
Lucien Cartier-Tilet 2024-02-14 06:58:17 +01:00
parent 0da40ebf42
commit dd4ebefedc
17 changed files with 442 additions and 126 deletions

View File

@ -10,19 +10,20 @@
"test:unit": "vitest",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"lint": "yarn lint:eslint && yarn lint:oxlint",
"lint:eslint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"lint:oxlint": "oxlint -D perf",
"format": "prettier --write src/"
},
"dependencies": {
"@fontsource/poppins": "^5.0.8",
"@fontsource/roboto": "^5.0.8",
"@vueuse/core": "^10.7.2",
"@vueuse/rxjs": "^10.7.2",
"less": "^4.2.0",
"pinia": "^2.1.7",
"pocketbase": "^0.21.1",
"rxjs": "^7.8.1",
"vue": "^3.4.18",
"vue": "^3.4.19",
"vue-router": "^4.2.5"
},
"devDependencies": {
@ -39,6 +40,7 @@
"eslint-plugin-vue": "^9.21.1",
"jsdom": "^24.0.0",
"npm-run-all2": "^6.1.2",
"oxlint": "^0.2.8",
"prettier": "^3.2.5",
"typescript": "~5.3.3",
"vite": "^5.1.1",

View File

@ -12,6 +12,10 @@
flex-direction: row;
}
.center {
margin: 0 auto;
}
.flex-center {
align-items: center;
}
@ -30,6 +34,22 @@
justify-content: space-between;
}
.flex-even {
justify-content: space-around;
}
.flex-wrap {
.flex;
flex-wrap: wrap;
}
.flex-size-even {
* {
flex: 1;
flex-basis: 100%;
}
}
.themed(@property, @light, @dark) {
@{property}: @light;
html.dark & {
@ -67,3 +87,7 @@
.flex-row;
justify-content: end;
}
.text-center {
text-align: center;
}

View File

@ -51,15 +51,15 @@ button,
}
&.h2 {
padding: (@h2-size / 2) (@h2-size * (2 / 3));
padding: (@h2-size / 2) @h2-size;
}
&.h3 {
padding: (@h3-size / 2) (@h3-size * (2 / 3));
padding: (@h3-size / 2) @h3-size;
}
&.h4 {
padding: (@h4-size / 2) (@h4-size * (2 / 3));
padding: (@h4-size / 2) @h4-size;
}
header & {

View File

@ -23,7 +23,7 @@ body {
ul.no-style {
list-style: none;
list-style-type: none;
padding-left: 0;
padding: 0;
margin-top: 0;
margin-bottom: 0;
}

View File

@ -2,9 +2,9 @@
<header class="flex-row-center flex-spread">
<RouterLink class="title h4" :to="{ name: 'home' }">{{ appTitle }}</RouterLink>
<div class="buttons gap-1rem">
<button @click="toggleDark()" class="secondary">{{ isDark ? 'Dark' : 'Light' }}</button>
<button v-if="!loggedIn" @click="login()" class="secondary">Login</button>
<RouterLink v-else :to="{ name: 'account' }" class="button secondary">Account</RouterLink>
<button @click="toggleDark()" class="secondary">{{ isDark ? 'Sombre' : 'Clair' }}</button>
<button v-if="!loggedIn" @click="login()" class="secondary">Connexion</button>
<RouterLink v-else :to="{ name: 'account' }" class="button secondary">Compte</RouterLink>
</div>
</header>
</template>

View File

@ -1,28 +1,21 @@
<template>
<div class="h3">Bonjour {{ pbStore.auth.username }}&nbsp;!</div>
<div class="h2">Bonjour {{ pbStore.auth.username }}&nbsp;!</div>
<div class="campagnes flex-col-center gap-2rem">
<h1>Campagnes</h1>
<RouterLink :to="{ name: 'new-campaign' }" class="button">Créer une campagne</RouterLink>
<ul v-if="campaigns.length > 0">
<li v-for="campaign in campaigns" :key="campaign.id">{{ campaign }}</li>
</ul>
<div v-else>Pas de campagnes pour linstant</div>
<div class="h4">Actions</div>
<RouterLink :to="{ name: 'campaigns' }" class="button">Mes campagnes</RouterLink>
</div>
</template>
<script setup="" lang="ts">
<script setup lang="ts">
import { usePocketbaseStore } from '@/stores/pocketbase';
import { type RecordModel } from 'pocketbase';
import { onMounted, ref } from 'vue';
import { RouterLink } from 'vue-router';
const pbStore = usePocketbaseStore();
const campaigns = ref<RecordModel[]>([]);
onMounted(() => {
pbStore.campaign.listCampaigns().subscribe({
next: (result) => (campaigns.value = result),
});
});
</script>
<style scoped lang="less">
.campaigns {
max-width: 80%;
}
</style>

View File

@ -6,12 +6,12 @@
<h2 class="card">
L&apos;application web pour vous accompagner pour votre JDR avec Gégé, le bot discord.
</h2>
<div class="flex-col-center gap-1rem">
<div class="flex-col-center flex-size-even gap-1rem">
<h3>Pourquoi&nbsp;?</h3>
<ul class="flex-row gap-1rem no-style">
<li class="card more">Accéder à ses fiche personnage</li>
<li class="card more">Faire évoluer ses personnage</li>
<li class="card more">Créer ses personnages</li>
<li class="card more text-center">Créer ses personnages</li>
<li class="card more text-center">Gérer ses fiche personnage</li>
<li class="card more text-center">Faire évoluer ses personnage</li>
</ul>
</div>
<button class="h4 raise margin-3rem">Se connecter avec Discord</button>

View File

@ -0,0 +1,30 @@
<template>
<div class="card primary flex-col gap-1rem">
<div class="h4" id="name">
{{ props.campaign.name }}
</div>
<div id="dm">
{{ displayName(props.campaign.expand!.game_master!) }}
</div>
<ul id="players" class="no-style">
<li v-for="player in props.campaign.expand!.players" :key="player.id">
{{ displayName(player) }}
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import type { Campaign } from '@/models/Campaign';
import { displayName } from '@/models/User';
const props = defineProps<{
campaign: Campaign;
}>();
</script>
<style scoped lang="less">
.card {
min-width: 20rem;
}
</style>

View File

@ -14,9 +14,8 @@ router.beforeEach((to, from, next) => {
const pbStore = usePocketbaseStore();
if (!pbStore.auth.loggedIn && ['home', 'login'].every((path) => path != to.name)) {
next({ name: 'home' });
} else {
next();
}
next();
});
app.use(createPinia());

20
src/models/Campaign.ts Normal file
View File

@ -0,0 +1,20 @@
import { type RecordModel } from 'pocketbase';
import { type User } from './User';
interface CampaignDetails {
game_master?: User;
players?: User[];
}
export interface Campaign extends RecordModel {
expand?: CampaignDetails;
game_master: string;
name: string;
players: string[];
}
export interface NewCampaign {
game_master: string | null;
name: string | null;
players: string[];
}

48
src/models/Character.ts Normal file
View File

@ -0,0 +1,48 @@
import type { RecordModel } from "pocketbase"
interface Effect {
name: string,
effect: string
}
interface BaseSkill {
name: string,
mastery: number,
}
interface FavourableSkill extends BaseSkill {
favourable: boolean
}
export interface PremadeCharacter extends RecordModel {
first_name: string
last_name: string
age: number
heroic_culture: string
particularities: string
description: string
stamina: number
hope: number
defense: number
valour: number
wisdom: number
rewards: Effect[],
virtues: Effect[],
travelling_equipment: Effect[],
image: string
body: number
heart: number
spirit: number
skills: FavourableSkill[]
combat_skills: BaseSkill[]
}
export interface Character extends PremadeCharacter {
campaign: string
current_stamina: number
current_load: number
current_fatigue: number
current_hope: number
status: string
user: string
}

20
src/models/User.ts Normal file
View File

@ -0,0 +1,20 @@
import type { RecordModel } from 'pocketbase';
export interface SimpleUser extends RecordModel {
username: string;
name?: string;
}
export interface User extends SimpleUser {
avatar?: string;
email?: string;
emailVisibility: boolean;
verified: boolean;
}
export function displayName(user: SimpleUser): string {
if (user.name && user.name.trim() !== '') {
return user.name;
}
return user.username;
}

View File

@ -13,6 +13,11 @@ const router = createRouter({
name: 'account',
component: () => import('@/views/AccountView.vue'),
},
{
path: '/campaigns',
name: 'campaigns',
component: () => import('@/views/CampaignsView.vue'),
},
{
path: '/new-campaign',
name: 'new-campaign',

View File

@ -3,11 +3,8 @@ import { defineStore } from 'pinia';
import { from, map, Observable, tap } from 'rxjs';
import { computed, ref } from 'vue';
export interface NewCampaign {
name: string | null;
game_master: string | null;
players: string[] | null;
}
import type { Campaign, NewCampaign } from '@/models/Campaign';
import type { SimpleUser } from '@/models/User';
export const usePocketbaseStore = defineStore('pocketbase', () => {
const pb = new PocketBase(import.meta.env.VITE_PB_URL);
@ -47,22 +44,15 @@ export const usePocketbaseStore = defineStore('pocketbase', () => {
);
}
function simpleUserList(): Observable<RecordModel[]> {
return from(
pb.collection('public_users').getFullList({
sort: 'username',
})
);
}
/////////////////////////////////////////////////////////////////////////////
// Campaigns //
/////////////////////////////////////////////////////////////////////////////
function listCampaigns(): Observable<RecordModel[]> {
function listCampaigns(): Observable<Campaign[]> {
return from(
pb.collection('campaign').getFullList({
pb.collection('campaigns_simple_view').getFullList<Campaign>({
sort: 'name',
expand: 'players,game_master',
})
);
}
@ -71,9 +61,20 @@ export const usePocketbaseStore = defineStore('pocketbase', () => {
return from(pb.collection('campaign').create(campaign));
}
/////////////////////////////////////////////////////////////////////////////
// Users //
/////////////////////////////////////////////////////////////////////////////
function allUsersSimple(): Observable<SimpleUser[]> {
return from(
pb.collection('public_users').getFullList<SimpleUser>({
sort: 'username',
})
);
}
return {
auth: {
authData,
authStore,
loggedIn,
username,
@ -88,7 +89,7 @@ export const usePocketbaseStore = defineStore('pocketbase', () => {
createCampaign,
},
users: {
simpleUserList,
allUsersSimple,
},
};
});

View File

@ -0,0 +1,61 @@
<template>
<h1>Campagnes</h1>
<div class="flex-col gap-2rem">
<div class="flex-col flex-center">
<RouterLink :to="{ name: 'new-campaign' }" class="button">Créer une campagne</RouterLink>
</div>
<h2>Campagnes que je gère</h2>
<div>
<ul
v-if="campaignsGameMaster.length > 0"
class="no-style center flex-wrap flex-size-even flex-even gap-1rem">
<li v-for="campaign in campaignsGameMaster" :key="campaign.id">
<SmallCampaignCard :campaign="campaign" />
</li>
</ul>
<div v-else>Pas de campagne pour linstant</div>
</div>
</div>
<div>
<h2>Campagnes je joue</h2>
<div>
<ul
v-if="campaignsPlayer.length > 0"
class="no-style center flex-wrap flex-size-even flex-even gap-1rem">
<li v-for="campaign in campaignsGameMaster" :key="campaign.id">
<SmallCampaignCard :campaign="campaign" />
</li>
</ul>
<div v-else class="card">Pas de campagne pour linstant</div>
</div>
</div>
</template>
<script setup lang="ts">
import { usePocketbaseStore } from '@/stores/pocketbase';
import SmallCampaignCard from '@/components/SmallCampaignCard.vue';
import { computed, onMounted, ref } from 'vue';
import { RouterLink } from 'vue-router';
import type { Campaign } from '@/models/Campaign';
const pbStore = usePocketbaseStore();
const campaigns = ref<Campaign[]>([]);
const campaignsGameMaster = computed<Campaign[]>(() =>
campaigns.value.filter((campaign) => campaign.game_master === pbStore.auth.userId)
);
const campaignsPlayer = computed<Campaign[]>(() =>
campaigns.value.filter((campaign) =>
campaign.players.some((player) => player === pbStore.auth.userId)
)
);
onMounted(() => {
pbStore.campaign.listCampaigns().subscribe({
next: (result) => (campaigns.value = result),
error: (err) => console.warn(err),
complete: () => console.log('List campaigns completed'),
});
});
</script>

View File

@ -1,9 +1,6 @@
<template>
<h1>Création dune campagne</h1>
<div class="h3 card" v-if="campaign.name">
{{ campaign.name }}
</div>
<form @submit.prevent="createCampaign" class="flex-col gap-2rem card">
<form @submit.prevent="createCampaign" class="flex-col gap-2rem card" autocomplete="off">
<label for="campaign-name" class="flex-col gap-1rem">Nom de la nouvelle campagne</label>
<input
name="campaign-name"
@ -11,6 +8,13 @@
v-model="campaign.name"
placeholder="Nom de la nouvelle campagne" />
<label class="flex-col gap-1rem" for="players" autocomplete="off">Joueurs (2 à 10)</label>
<select id="players" name="players" multiple v-model="campaign.players">
<option v-for="user in users" :key="user.id" :value="user.id">
{{ displayName(user) }}
</option>
</select>
<div class="buttons gap-1rem">
<RouterLink :to="{ name: 'home' }" class="button faded">Annuler</RouterLink>
<button type="submit">Envoyer</button>
@ -19,33 +23,33 @@
</template>
<script setup lang="ts">
import router from '@/router';
import { usePocketbaseStore, type NewCampaign } from '@/stores/pocketbase';
import { type RecordModel } from 'pocketbase';
import { onMounted, ref } from 'vue';
import router from '@/router';
import { usePocketbaseStore } from '@/stores/pocketbase';
import { type NewCampaign } from '@/models/Campaign';
import { type SimpleUser, displayName } from '@/models/User';
const pbStore = usePocketbaseStore();
const simpleUsers = ref<RecordModel[]>([]);
const users = ref<SimpleUser[]>([]);
const campaign = ref<NewCampaign>({
name: null,
game_master: pbStore.auth.userId,
players: null,
players: [],
});
const createCampaign = () => {
pbStore.campaign.createCampaign(campaign.value).subscribe({
next: () => {
router.push({ name: 'home' });
router.go(0);
},
});
};
onMounted(() => {
pbStore.users.simpleUserList().subscribe({
next: (result) => (simpleUsers.value = result),
error: (err) => console.error('Failed to create campaign:', err),
pbStore.users.allUsersSimple().subscribe({
next: (results) => (users.value = results.filter((user) => user.id !== pbStore.auth.userId)),
error: (err) => console.warn('Failed to fetch all users', err),
});
});
</script>

233
yarn.lock
View File

@ -374,6 +374,62 @@ __metadata:
languageName: node
linkType: hard
"@oxlint/darwin-arm64@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/darwin-arm64@npm:0.2.8"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@oxlint/darwin-x64@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/darwin-x64@npm:0.2.8"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@oxlint/linux-arm64-gnu@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/linux-arm64-gnu@npm:0.2.8"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@oxlint/linux-arm64-musl@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/linux-arm64-musl@npm:0.2.8"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@oxlint/linux-x64-gnu@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/linux-x64-gnu@npm:0.2.8"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@oxlint/linux-x64-musl@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/linux-x64-musl@npm:0.2.8"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@oxlint/win32-arm64@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/win32-arm64@npm:0.2.8"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@oxlint/win32-x64@npm:0.2.8":
version: 0.2.8
resolution: "@oxlint/win32-x64@npm:0.2.8"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@pkgjs/parseargs@npm:^0.11.0":
version: 0.11.0
resolution: "@pkgjs/parseargs@npm:0.11.0"
@ -790,7 +846,30 @@ __metadata:
languageName: node
linkType: hard
"@vue/compiler-dom@npm:3.4.18, @vue/compiler-dom@npm:^3.3.0":
"@vue/compiler-core@npm:3.4.19":
version: 3.4.19
resolution: "@vue/compiler-core@npm:3.4.19"
dependencies:
"@babel/parser": "npm:^7.23.9"
"@vue/shared": "npm:3.4.19"
entities: "npm:^4.5.0"
estree-walker: "npm:^2.0.2"
source-map-js: "npm:^1.0.2"
checksum: 10c0/94b021dc5d29564f94aa0bb7a5b03203e68b332ed165799f88c2de579a58730f4eca9c8c92d041a03843a3b8e378857485f7672be880781fe53133bfafb93d79
languageName: node
linkType: hard
"@vue/compiler-dom@npm:3.4.19":
version: 3.4.19
resolution: "@vue/compiler-dom@npm:3.4.19"
dependencies:
"@vue/compiler-core": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
checksum: 10c0/348aecff6ade0b023ff6b7bec572ba3fa6e2450530f15acb743a5679c3612fd6d3b15f87aafa00e1d8258f637397657e2e6ae1546c41f838da23a631e9b276f8
languageName: node
linkType: hard
"@vue/compiler-dom@npm:^3.3.0":
version: 3.4.18
resolution: "@vue/compiler-dom@npm:3.4.18"
dependencies:
@ -800,30 +879,30 @@ __metadata:
languageName: node
linkType: hard
"@vue/compiler-sfc@npm:3.4.18":
version: 3.4.18
resolution: "@vue/compiler-sfc@npm:3.4.18"
"@vue/compiler-sfc@npm:3.4.19":
version: 3.4.19
resolution: "@vue/compiler-sfc@npm:3.4.19"
dependencies:
"@babel/parser": "npm:^7.23.9"
"@vue/compiler-core": "npm:3.4.18"
"@vue/compiler-dom": "npm:3.4.18"
"@vue/compiler-ssr": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
"@vue/compiler-core": "npm:3.4.19"
"@vue/compiler-dom": "npm:3.4.19"
"@vue/compiler-ssr": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
estree-walker: "npm:^2.0.2"
magic-string: "npm:^0.30.6"
postcss: "npm:^8.4.33"
source-map-js: "npm:^1.0.2"
checksum: 10c0/8c25ef66d0de168a7f482cc86a2b826d4684c8975cf4cd86974df6f69afbe2b59181d9c5ea8a915099f6ea425d31e988b5100d33a6c71966ee2b75bd3e6a5d0f
checksum: 10c0/eb3c6a136c677cf31b624a27f3c23a6511f54b97607a66ef3625ab25ff56370cc589fe2dfa3ef487746a15f4e4033e63e261eb3a76842a5bbe149da1048dfa46
languageName: node
linkType: hard
"@vue/compiler-ssr@npm:3.4.18":
version: 3.4.18
resolution: "@vue/compiler-ssr@npm:3.4.18"
"@vue/compiler-ssr@npm:3.4.19":
version: 3.4.19
resolution: "@vue/compiler-ssr@npm:3.4.19"
dependencies:
"@vue/compiler-dom": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
checksum: 10c0/34676a7c061ee4ff73692e46524cf27da60e134a4477c8fbafa5c998a718dc9df189a66a4417c5018daa913eeb77a7b0510d35209e7da75c08422fdf7bbcdb79
"@vue/compiler-dom": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
checksum: 10c0/190dfbe89ad6f662276684ef2931fd67c6e6b7e3d008d6368498481f0632cf4ad06db257f5345336403404050e1791f3ba719dc460029cf9fbbe24abe39adcff
languageName: node
linkType: hard
@ -887,45 +966,45 @@ __metadata:
languageName: node
linkType: hard
"@vue/reactivity@npm:3.4.18":
version: 3.4.18
resolution: "@vue/reactivity@npm:3.4.18"
"@vue/reactivity@npm:3.4.19":
version: 3.4.19
resolution: "@vue/reactivity@npm:3.4.19"
dependencies:
"@vue/shared": "npm:3.4.18"
checksum: 10c0/f0bc2d126420464603eb56fc93837e1679a462b0f029f38064aea1332ed717a4b717edf473adfd2b487e78deb8da52395fa043191af1ba827f2ddc5bd3efb523
"@vue/shared": "npm:3.4.19"
checksum: 10c0/a3febaa2a1a59b428d341db7099238a6182c63d21f1975cf5c3b107a653521163e34ae865d9fca8589b8d3e0d63f3257b8ec57ae276ff47aded5b9797f9583f8
languageName: node
linkType: hard
"@vue/runtime-core@npm:3.4.18":
version: 3.4.18
resolution: "@vue/runtime-core@npm:3.4.18"
"@vue/runtime-core@npm:3.4.19":
version: 3.4.19
resolution: "@vue/runtime-core@npm:3.4.19"
dependencies:
"@vue/reactivity": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
checksum: 10c0/73c02094ba6e5f243e5fcdb0ac93a940b2a2ba899dab005d06cff827dcd90289b56fb7248ccc3b40ec36f37c1953647f22585fbec4052765c1e2b4fa6b80d10a
"@vue/reactivity": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
checksum: 10c0/03e399a3e5183dd89e471d57a392006bf8145dcd4a2db903e4a07a2951ddd8d258791392da2c9ca8e76def0c9657fd3fbeda8efe0f053099cd73afedd8e9cd61
languageName: node
linkType: hard
"@vue/runtime-dom@npm:3.4.18":
version: 3.4.18
resolution: "@vue/runtime-dom@npm:3.4.18"
"@vue/runtime-dom@npm:3.4.19":
version: 3.4.19
resolution: "@vue/runtime-dom@npm:3.4.19"
dependencies:
"@vue/runtime-core": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
"@vue/runtime-core": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
csstype: "npm:^3.1.3"
checksum: 10c0/049588abf076f246e1c2fad58a3b421b680840a9abc3462991f6b221589e4d86d11ca38b23368d92626ef2269ad8663e111e5410c939084d419a63dbc27b5845
checksum: 10c0/b26ef26d06fd89b7549534c9d53eb10047b4adbea305e80730bd50e17b4859ea67ba782af71624cafc7c83f5249da71fc101c566d76e32437a4645303656b51b
languageName: node
linkType: hard
"@vue/server-renderer@npm:3.4.18":
version: 3.4.18
resolution: "@vue/server-renderer@npm:3.4.18"
"@vue/server-renderer@npm:3.4.19":
version: 3.4.19
resolution: "@vue/server-renderer@npm:3.4.19"
dependencies:
"@vue/compiler-ssr": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
"@vue/compiler-ssr": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
peerDependencies:
vue: 3.4.18
checksum: 10c0/69743873c97fc8db54a4cbd071c6a91aac62a40bcb141b1e47fbfa2d8922b8c3f832eed6a471ed94d3a700d966570c2561f237624848f3fd1f135a3144d1e7af
vue: 3.4.19
checksum: 10c0/2156362185d62222db060c66d7fa31d2420708f22e491fe1b616008e931be7fcf9cf47e9cca5135359839c269389b475492657948ea3d6756f6a790fcddc34bf
languageName: node
linkType: hard
@ -936,6 +1015,13 @@ __metadata:
languageName: node
linkType: hard
"@vue/shared@npm:3.4.19":
version: 3.4.19
resolution: "@vue/shared@npm:3.4.19"
checksum: 10c0/bd4a060b0064f0e183e5bb8e346f3be6ff7046793b0765a407e5334860ffd646b28a4ef53652b644e83bd473cea91189377cd83c933bb638d1da143d28f779ff
languageName: node
linkType: hard
"@vue/test-utils@npm:^2.4.4":
version: 2.4.4
resolution: "@vue/test-utils@npm:2.4.4"
@ -978,18 +1064,6 @@ __metadata:
languageName: node
linkType: hard
"@vueuse/rxjs@npm:^10.7.2":
version: 10.7.2
resolution: "@vueuse/rxjs@npm:10.7.2"
dependencies:
"@vueuse/shared": "npm:10.7.2"
vue-demi: "npm:>=0.14.6"
peerDependencies:
rxjs: ">=6.0.0"
checksum: 10c0/83c8ab403ecb396af31d76ecfb476ec003d7a6a54a1682775633dba718204eea92a39983619fd55e30fcefaae0154971b5db985482d62c65468f63be358a76ec
languageName: node
linkType: hard
"@vueuse/shared@npm:10.7.2":
version: 10.7.2
resolution: "@vueuse/shared@npm:10.7.2"
@ -1972,12 +2046,12 @@ __metadata:
"@vue/test-utils": "npm:^2.4.4"
"@vue/tsconfig": "npm:^0.5.1"
"@vueuse/core": "npm:^10.7.2"
"@vueuse/rxjs": "npm:^10.7.2"
eslint: "npm:^8.56.0"
eslint-plugin-vue: "npm:^9.21.1"
jsdom: "npm:^24.0.0"
less: "npm:^4.2.0"
npm-run-all2: "npm:^6.1.2"
oxlint: "npm:^0.2.8"
pinia: "npm:^2.1.7"
pocketbase: "npm:^0.21.1"
prettier: "npm:^3.2.5"
@ -1985,7 +2059,7 @@ __metadata:
typescript: "npm:~5.3.3"
vite: "npm:^5.1.1"
vitest: "npm:^1.2.2"
vue: "npm:^3.4.18"
vue: "npm:^3.4.19"
vue-router: "npm:^4.2.5"
vue-tsc: "npm:^1.8.27"
languageName: unknown
@ -2925,6 +2999,41 @@ __metadata:
languageName: node
linkType: hard
"oxlint@npm:^0.2.8":
version: 0.2.8
resolution: "oxlint@npm:0.2.8"
dependencies:
"@oxlint/darwin-arm64": "npm:0.2.8"
"@oxlint/darwin-x64": "npm:0.2.8"
"@oxlint/linux-arm64-gnu": "npm:0.2.8"
"@oxlint/linux-arm64-musl": "npm:0.2.8"
"@oxlint/linux-x64-gnu": "npm:0.2.8"
"@oxlint/linux-x64-musl": "npm:0.2.8"
"@oxlint/win32-arm64": "npm:0.2.8"
"@oxlint/win32-x64": "npm:0.2.8"
dependenciesMeta:
"@oxlint/darwin-arm64":
optional: true
"@oxlint/darwin-x64":
optional: true
"@oxlint/linux-arm64-gnu":
optional: true
"@oxlint/linux-arm64-musl":
optional: true
"@oxlint/linux-x64-gnu":
optional: true
"@oxlint/linux-x64-musl":
optional: true
"@oxlint/win32-arm64":
optional: true
"@oxlint/win32-x64":
optional: true
bin:
oxlint: bin/oxlint
checksum: 10c0/f795a4eedd60234fab26ecadb41742fd2b4f0d7fd2cd6b4bfe00e979b3d9a466d7fe6eca2d92900aae79aaf515a728e55be67762376d16352f9e6a9e9af0a1d0
languageName: node
linkType: hard
"p-limit@npm:^3.0.2":
version: 3.1.0
resolution: "p-limit@npm:3.1.0"
@ -3996,21 +4105,21 @@ __metadata:
languageName: node
linkType: hard
"vue@npm:^3.4.18":
version: 3.4.18
resolution: "vue@npm:3.4.18"
"vue@npm:^3.4.19":
version: 3.4.19
resolution: "vue@npm:3.4.19"
dependencies:
"@vue/compiler-dom": "npm:3.4.18"
"@vue/compiler-sfc": "npm:3.4.18"
"@vue/runtime-dom": "npm:3.4.18"
"@vue/server-renderer": "npm:3.4.18"
"@vue/shared": "npm:3.4.18"
"@vue/compiler-dom": "npm:3.4.19"
"@vue/compiler-sfc": "npm:3.4.19"
"@vue/runtime-dom": "npm:3.4.19"
"@vue/server-renderer": "npm:3.4.19"
"@vue/shared": "npm:3.4.19"
peerDependencies:
typescript: "*"
peerDependenciesMeta:
typescript:
optional: true
checksum: 10c0/ed62926d19ca9b92662d65221be94f24383202e3bc565e000f75511250c7808f031272e1fdd83da28da12e9ca3444af31d57392f11b5b890467aca9827ad53a9
checksum: 10c0/90d45a30b096d3a2445314cf5a94db6f56b854bd483a706bc7ec358b555e2c6dba8ce7b6a976d52af2a8ba92fb3caab4b77b50886f732857320073753152528d
languageName: node
linkType: hard