Migration to Nuxt v4 file structure and dependencies update

This commit is contained in:
Clément Pons
2025-11-13 10:05:41 +01:00
parent dd4191bea6
commit dfbb31595e
90 changed files with 652 additions and 924 deletions

86
app/types/api.d.ts vendored Normal file
View File

@@ -0,0 +1,86 @@
import type { FileType } from '~/types/content';
export interface SuccessHandler
{
success: true;
session: UserSession;
}
export interface ErrorHandler
{
success: false;
error: Error | ZodError;
}
export type Return = SuccessHandler | ErrorHandler;
export interface Project {
id: number;
name: string;
owner: number;
home: string;
summary: string;
}
export interface Navigation {
title: string;
path: string;
type: string;
private: boolean;
children?: Navigation[];
}
export type FileMetadata = Record<string, boolean | string | number>;
export interface File {
path: string;
owner: number;
title: string;
order: number;
type: FileType;
content: string;
navigable: boolean;
private: boolean;
metadata: FileMetadata;
}
export interface Comment {
project: number;
path: number;
user_id: number;
sequence: number;
position: number;
length: number;
content: string;
}
export interface User {
id: number;
username: string;
}
export interface Tag {
tag: string;
project: number;
description: string;
}
export type ProjectSearch = Project &
{
pages: number;
username: string;
}
export type FileSearch = Omit<File, 'content'> &
{
comments: number;
username: string;
}
export type CommentSearch = Comment &
{
username: string;
}
export type UserSearch = User &
{
}
export type CommentedFile = File &
{
comments: CommentSearch[];
}
export interface Search {
projects: ProjectSearch[];
files: FileSearch[];
users: UserSearch[];
}

77
app/types/auth.d.ts vendored Normal file
View File

@@ -0,0 +1,77 @@
import type { ComputedRef, Ref } from 'vue';
import type { SessionConfig } from 'h3'
import 'vue-router';
declare module 'vue-router'
{
interface RouteMeta
{
requiresAuth?: boolean;
guestsGoesTo?: string;
usersGoesTo?: string;
rights?: string[];
validState?: boolean;
}
}
import '@nuxt/schema';
declare module '@nuxt/schema'
{
interface RuntimeConfig
{
session: SessionConfig;
}
}
export interface UserRawData {
id: number;
username: string;
email: string;
state: number;
}
export interface UserExtendedData {
signin: Date;
lastTimestamp: Date;
}
export type Permissions = { permissions: string[] };
export type User = UserRawData & UserExtendedData & Permissions;
export interface UserSession {
user?: User;
id?: string;
}
export interface UserSessionRequired extends UserSession {
user: User;
id: string;
}
export interface UserSessionComposable {
/**
* Computed indicating if the auth session is ready
*/
ready: ComputedRef<boolean>
/**
* Computed indicating if the user is logged in.
*/
loggedIn: ComputedRef<boolean>
/**
* The user object if logged in, null otherwise.
*/
user: ComputedRef<User | null>
/**
* The session object.
*/
session: Ref<UserSession>
/**
* Fetch the user session from the server.
*/
fetch: () => Promise<boolean>
/**
* Clear the user session and remove the session cookie.
*/
clear: () => Promise<void>
}

34
app/types/canvas.d.ts vendored Normal file
View File

@@ -0,0 +1,34 @@
export interface CanvasContent {
nodes?: CanvasNode[];
edges?: CanvasEdge[];
groups?: CanvasGroup[];
}
export type CanvasColor = {
class?: string;
} & {
hex?: string;
};
export interface CanvasNode {
type: 'group' | 'text';
id: string;
x: number;
y: number;
width: number;
height: number;
color?: CanvasColor;
label?: string;
text?: string;
};
export interface CanvasEdge {
id: string;
fromNode: string;
fromSide: 'bottom' | 'top' | 'left' | 'right';
toNode: string;
toSide: 'bottom' | 'top' | 'left' | 'right';
color?: CanvasColor;
label?: string;
};
export interface CanvasGroup {
name: string;
nodes: string[];
}

248
app/types/character.d.ts vendored Normal file
View File

@@ -0,0 +1,248 @@
import type { MAIN_STATS, ABILITIES, LEVELS, TRAINING_LEVELS, SPELL_TYPES, CATEGORIES, SPELL_ELEMENTS, ALIGNMENTS, RESISTANCES, DAMAGE_TYPES, WEAPON_TYPES } from "#shared/character.util";
import type { Localized } from "../types/general";
export type MainStat = typeof MAIN_STATS[number];
export type Ability = typeof ABILITIES[number];
export type Level = typeof LEVELS[number];
export type TrainingLevel = typeof TRAINING_LEVELS[number];
export type SpellType = typeof SPELL_TYPES[number];
export type Category = typeof CATEGORIES[number];
export type SpellElement = typeof SPELL_ELEMENTS[number];
export type Alignment = typeof ALIGNMENTS[number];
export type Resistance = typeof RESISTANCES[number];
export type DamageType = typeof DAMAGE_TYPES[number];
export type WeaponType = typeof WEAPON_TYPES[number];
export type FeatureID = string;
export type i18nID = string;
export type RecursiveKeyOf<TObj extends object> = {
[TKey in keyof TObj & (string | number)]:
TObj[TKey] extends any[] ? `${TKey}` :
TObj[TKey] extends object
? `${TKey}` | `${TKey}/${RecursiveKeyOf<TObj[TKey]>}`
: `${TKey}`;
}[keyof TObj & (string | number)];
export type Character = {
id: number;
name: string; //Free text
people?: string; //People ID
level: number;
aspect?: number;
notes?: { public?: string, private?: string }; //Free text
training: Record<MainStat, Partial<Record<TrainingLevel, number>>>;
leveling: Partial<Record<Level, number>>;
abilities: Partial<Record<Ability, number>>;
variables: CharacterVariables;
choices: Record<FeatureID, number[]>;
owner: number;
username?: string;
visibility: "private" | "public";
};
export type CharacterVariables = {
health: number;
mana: number;
exhaustion: number;
sickness: Array<{ id: string, state: number | true }>;
poisons: Array<{ id: string, state: number | true }>;
spells: string[]; //Spell ID
items: ItemState[];
money: number;
};
type ItemState = {
id: string;
amount: number;
enchantments?: string[];
charges?: number;
equipped?: boolean;
state?: any;
};
export type CharacterConfig = {
peoples: Record<string, RaceConfig>;
training: Record<MainStat, Record<TrainingLevel, FeatureID[]>>;
spells: SpellConfig[];
aspects: AspectConfig[];
features: Record<FeatureID, Feature>;
enchantments: Record<string, EnchantementConfig>; //TODO
items: Record<string, ItemConfig>;
sickness: Record<string, { id: string, name: string, description: string, effect: FeatureID[] }>;
action: Record<string, { id: string, name: string, description: string, cost: number }>;
reaction: Record<string, { id: string, name: string, description: string, cost: number }>;
freeaction: Record<string, { id: string, name: string, description: string }>;
passive: Record<string, { id: string, name: string, description: string }>;
texts: Record<i18nID, Localized>;
};
export type EnchantementConfig = {
name: string; //TODO -> TextID
effect: Array<FeatureEquipment | FeatureValue | FeatureList>;
power: number;
}
export type ItemConfig = CommonItemConfig & (ArmorConfig | WeaponConfig | WondrousConfig | MundaneConfig);
type CommonItemConfig = {
id: string;
name: string; //TODO -> TextID
description: i18nID;
rarity: 'common' | 'uncommon' | 'rare' | 'legendary';
weight?: number; //Optionnal but highly recommended
price?: number; //Optionnal but highly recommended
capacity?: number; //Optionnal as most mundane items should not receive enchantments (potions, herbal heals, etc...)
powercost?: number; //Optionnal
charge?: number //Max amount of charges
enchantments?: string[]; //Enchantment ID
effects?: Array<FeatureValue | FeatureEquipment | FeatureList>;
equippable: boolean;
consummable: boolean;
}
type ArmorConfig = {
category: 'armor';
health: number;
type: 'light' | 'medium' | 'heavy';
absorb: { static: number, percent: number };
};
type WeaponConfig = {
category: 'weapon';
type: Array<WeaponType>;
damage: {
value: string; //Dice formula
type: DamageType;
};
};
type WondrousConfig = {
category: 'wondrous';
};
type MundaneConfig = {
category: 'mundane';
};
export type SpellConfig = {
id: string;
name: string; //TODO -> TextID
rank: 1 | 2 | 3 | 4;
type: SpellType;
cost: number;
speed: "action" | "reaction" | number;
elements: Array<SpellElement>;
description: string; //TODO -> TextID
concentration: boolean;
range: 'personnal' | number;
tags?: string[];
};
export type RaceConfig = {
id: string;
name: string; //TODO -> TextID
description: string; //TODO -> TextID
options: Record<Level, FeatureID[]>;
};
export type AspectConfig = {
name: string;
description: string; //TODO -> TextID
stat: MainStat | 'special';
alignment: Alignment;
magic: boolean;
difficulty: number;
physic: { min: number, max: number };
mental: { min: number, max: number };
personality: { min: number, max: number };
options: FeatureItem[];
};
export type FeatureValue = {
id: FeatureID;
category: "value";
operation: "add" | "set" | "min";
property: RecursiveKeyOf<CompiledCharacter> | 'spec' | 'ability' | 'training';
value: number | `modifier/${MainStat}` | false;
}
export type FeatureEquipment = {
id: FeatureID;
category: "value";
operation: "add" | "set" | "min";
property: 'weapon/damage/value' | 'armor/health' | 'armor/absorb/flat' | 'armor/absorb/percent';
value: number | `modifier/${MainStat}` | false;
}
export type FeatureList = {
id: FeatureID;
category: "list";
list: "spells" | "sickness" | "action" | "reaction" | "freeaction" | "passive";
action: "add" | "remove";
item: string;
};
export type FeatureChoice = {
id: FeatureID;
category: "choice";
text: string; //TODO -> TextID
settings?: { //If undefined, amount is 1 by default
amount: number;
exclusive: boolean; //Disallow to pick the same option twice
};
options: Array<{ text: string, effects: Array<FeatureValue | FeatureList> }>; //TODO -> TextID
};
export type FeatureItem = FeatureValue | FeatureList | FeatureChoice;
export type Feature = {
id: FeatureID;
description: string; //TODO -> TextID
effect: FeatureItem[];
};
export type CompiledCharacter = {
id: number;
owner?: number;
username?: string;
name: string;
health: number; //Max
mana: number; //Max
race: string;
spellslots: number; //Max
artslots: number; //Max
spellranks: Record<SpellType, 0 | 1 | 2 | 3>;
aspect: string; //ID
speed: number | false;
capacity: number | false;
initiative: number;
exhaust: number;
itempower: number;
action: number;
reaction: number;
variables: CharacterVariables,
defense: {
hardcap: number;
static: number;
activeparry: number;
activedodge: number;
passiveparry: number;
passivedodge: number;
};
mastery: {
strength: number;
dexterity: number;
shield: number;
armor: number;
multiattack: number;
magicpower: number;
magicspeed: number;
magicelement: number;
magicinstinct: number;
};
bonus: {
defense: Partial<Record<MainStat, number>>;
abilities: Partial<Record<Ability, number>>;
}; //Any special bonus goes here
resistance: Record<string, number>;
modifier: Record<MainStat, number>;
abilities: Partial<Record<Ability, number>>;
level: number;
lists: { [K in FeatureList['list']]?: string[] }; //string => ListItem ID
notes: { public: string, private: string };
};

0
app/types/content.d.ts vendored Normal file
View File

21
app/types/general.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
export type Preferences = {
markdown: MarkdownPreferences,
canvas: CanvasPreferences,
} & GeneralPreferences;
type GeneralPreferences = {
};
type MarkdownPreferences = {
editing: 'split' |'reading' | 'editing';
};
type CanvasPreferences = {
gridSnap: boolean;
spacing?: number;
neighborSnap: boolean;
};
export type Localized = {
fr_FR?: string;
en_US?: string;
default: string;
}

17
app/types/map.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
export interface MapContent
{
bg: string;
interests: MapInterest[];
}
export interface MapInterest
{
id: string;
x: number;
y: number;
text: string;
width?: number;
height?: number;
color?: CanvasColor;
valign?: 'start' | 'center' | 'end';
halign?: 'start' | 'center' | 'end';
}