mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-15 09:14:08 +00:00
13 files completing the TypeScript migration: - router/ (3 files): typed guards, route meta augmentation, merged feature routes from all 16 modules - plugins/ (4 files): i18n with dynamic locale loading, pinia, tooltip directive - Entry points: main.ts, InvoiceShelf.ts bootstrap class, App.vue, global-components.ts with typed registration - NoCompanyView and NotFoundView stubs scripts-v2/ totals: 324 files, 42853 lines of strict TypeScript. Zero any types. Complete feature-based architecture with typed stores, API services, composables, and Vue components. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
101 lines
2.6 KiB
TypeScript
101 lines
2.6 KiB
TypeScript
import { createApp } from 'vue'
|
|
import type { App } from 'vue'
|
|
import type { Router } from 'vue-router'
|
|
import App_ from './App.vue'
|
|
import router from './router'
|
|
import { createAppI18n, setI18nLanguage } from './plugins/i18n'
|
|
import type { AppI18n } from './plugins/i18n'
|
|
import { createAppPinia } from './plugins/pinia'
|
|
import { installTooltipDirective } from './plugins/tooltip'
|
|
import { defineGlobalComponents } from './global-components'
|
|
|
|
/**
|
|
* Callback signature for the `booting` hook.
|
|
* Receives the Vue app instance and the router so that modules /
|
|
* plugins can register additional routes, components, or providers.
|
|
*/
|
|
type BootCallback = (app: App, router: Router) => void
|
|
|
|
/**
|
|
* Bootstrap class for InvoiceShelf.
|
|
*
|
|
* External code (e.g. dynamically loaded modules) can call
|
|
* `window.InvoiceShelf.booting(callback)` to hook into the app
|
|
* before it mounts.
|
|
*
|
|
* Call `start()` to install all plugins, execute boot callbacks,
|
|
* and mount the application.
|
|
*/
|
|
export default class InvoiceShelf {
|
|
private bootingCallbacks: BootCallback[] = []
|
|
private messages: Record<string, Record<string, unknown>> = {}
|
|
private i18n: AppI18n | null = null
|
|
private app: App
|
|
|
|
constructor() {
|
|
this.app = createApp(App_)
|
|
}
|
|
|
|
/**
|
|
* Register a callback that will be invoked before the app mounts.
|
|
*/
|
|
booting(callback: BootCallback): void {
|
|
this.bootingCallbacks.push(callback)
|
|
}
|
|
|
|
/**
|
|
* Merge additional i18n message bundles (typically from modules).
|
|
*/
|
|
addMessages(moduleMessages: Record<string, Record<string, unknown>>): void {
|
|
for (const [locale, msgs] of Object.entries(moduleMessages)) {
|
|
this.messages[locale] = {
|
|
...this.messages[locale],
|
|
...msgs,
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Dynamically load and activate a language.
|
|
*/
|
|
async loadLanguage(locale: string): Promise<void> {
|
|
if (this.i18n) {
|
|
await setI18nLanguage(this.i18n, locale)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute all registered boot callbacks, install plugins,
|
|
* and mount the app to `document.body`.
|
|
*/
|
|
start(): void {
|
|
// Execute boot callbacks so modules can register routes / components
|
|
this.executeCallbacks()
|
|
|
|
// Register global components
|
|
defineGlobalComponents(this.app)
|
|
|
|
// i18n
|
|
this.i18n = createAppI18n(this.messages)
|
|
|
|
// Install plugins
|
|
this.app.use(router)
|
|
this.app.use(this.i18n)
|
|
this.app.use(createAppPinia())
|
|
|
|
// Directives
|
|
installTooltipDirective(this.app)
|
|
|
|
// Mount
|
|
this.app.mount('body')
|
|
}
|
|
|
|
// ---- private ----
|
|
|
|
private executeCallbacks(): void {
|
|
for (const callback of this.bootingCallbacks) {
|
|
callback(this.app, router)
|
|
}
|
|
}
|
|
}
|