chore: update nuxt to 3.10.3 (#2610)

main
Joaquín Sánchez 2024-02-24 17:46:14 +01:00 committed by GitHub
parent 1fefb6e5b6
commit 55037f04cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
53 changed files with 3584 additions and 3766 deletions

View File

@ -4,7 +4,7 @@ provideGlobalCommands()
const route = useRoute() const route = useRoute()
if (process.server && !route.path.startsWith('/settings')) { if (import.meta.server && !route.path.startsWith('/settings')) {
const url = useRequestURL() const url = useRequestURL()
useHead({ useHead({

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { LocaleObject } from '@nuxtjs/i18n'
import type { AriaAnnounceType, AriaLive } from '~/composables/aria' import type { AriaAnnounceType, AriaLive } from '~/composables/aria'
import type { LocaleObject } from '#i18n'
const router = useRouter() const router = useRouter()
const { t, locale, locales } = useI18n() const { t, locale, locales } = useI18n()

View File

@ -33,7 +33,7 @@ const previewImage = ref('')
const imageSrc = computed<string>(() => previewImage.value || defaultImage.value) const imageSrc = computed<string>(() => previewImage.value || defaultImage.value)
async function pickImage() { async function pickImage() {
if (process.server) if (import.meta.server)
return return
const image = await fileOpen({ const image = await fileOpen({
description: 'Image', description: 'Image',

View File

@ -22,7 +22,7 @@ const slider = ref()
const slide = ref() const slide = ref()
const image = ref() const image = ref()
const reduceMotion = process.server ? ref(false) : useReducedMotion() const reduceMotion = import.meta.server ? ref(false) : useReducedMotion()
const isInitialScrollDone = useTimeout(350) const isInitialScrollDone = useTimeout(350)
const canAnimate = computed(() => isInitialScrollDone.value && !reduceMotion.value) const canAnimate = computed(() => isInitialScrollDone.value && !reduceMotion.value)

View File

@ -46,7 +46,7 @@ useCommand({
@click="to ? $scrollToTop() : undefined" @click="to ? $scrollToTop() : undefined"
> >
<div <div
w-full flex w-fit px5 py3 md:gap2 gap4 items-center w-full flex px5 py3 md:gap2 gap4 items-center
transition-250 group-hover:bg-active transition-250 group-hover:bg-active
group-focus-visible:ring="2 current" group-focus-visible:ring="2 current"
> >

View File

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ComputedRef } from 'vue' import type { ComputedRef } from 'vue'
import type { LocaleObject } from '#i18n' import type { LocaleObject } from '@nuxtjs/i18n'
const userSettings = useUserSettings() const userSettings = useUserSettings()

View File

@ -88,7 +88,7 @@ async function deleteAndRedraft() {
}) !== 'confirm') }) !== 'confirm')
return return
if (process.dev) { if (import.meta.dev) {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
const result = confirm('[DEV] Are you sure you want to delete and re-draft this post?') const result = confirm('[DEV] Are you sure you want to delete and re-draft this post?')
if (!result) if (!result)

View File

@ -64,7 +64,7 @@ const meta = computed(() => {
const avatar = `https://github.com/${user}.png?size=256` const avatar = `https://github.com/${user}.png?size=256`
const author = props.card.authorName const author = props.card.authorName
const info = { return {
type, type,
user, user,
titleUrl: `https://github.com/${user}${repo ? `/${repo}` : ''}`, titleUrl: `https://github.com/${user}${repo ? `/${repo}` : ''}`,
@ -78,8 +78,7 @@ const meta = computed(() => {
user: author, user: author,
} }
: undefined, : undefined,
} } satisfies Meta
return info
}) })
</script> </script>

View File

@ -26,13 +26,12 @@ const meta = computed(() => {
const lines = meta?.[2] const lines = meta?.[2]
const code = meta?.[3].split('\n').slice(0, maxLines).join('\n') const code = meta?.[3].split('\n').slice(0, maxLines).join('\n')
const project = props.card.title?.replace(' - StackBlitz', '') const project = props.card.title?.replace(' - StackBlitz', '')
const info = { return {
file, file,
lines, lines,
code, code,
project, project,
} } satisfies Meta
return info
}) })
const vnodeCode = computed(() => { const vnodeCode = computed(() => {

View File

@ -13,7 +13,7 @@ const { items, command } = defineProps<{
}>() }>()
const emojis = computed(() => { const emojis = computed(() => {
if (process.server) if (import.meta.server)
return [] return []
return items.map((item: CustomEmoji | Emoji) => { return items.map((item: CustomEmoji | Emoji) => {

View File

@ -5,7 +5,7 @@ const cache = new LRUCache<string, any>({
max: 1000, max: 1000,
}) })
if (process.dev && process.client) if (import.meta.dev && import.meta.client)
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log({ cache }) console.log({ cache })

View File

@ -1,7 +1,7 @@
import type { ComputedRef } from 'vue' import type { ComputedRef } from 'vue'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import Fuse from 'fuse.js' import Fuse from 'fuse.js'
import type { LocaleObject } from '#i18n' import type { LocaleObject } from '@nuxtjs/i18n'
import type { SearchResult } from '~/composables/masto/search' import type { SearchResult } from '~/composables/masto/search'
// @unocss-include // @unocss-include

View File

@ -56,7 +56,7 @@ export async function openPublishDialog(draftKey = 'dialog', draft?: Draft, over
if (overwrite && !isEmptyDraft(currentUserDrafts.value[draftKey])) { if (overwrite && !isEmptyDraft(currentUserDrafts.value[draftKey])) {
// TODO overwrite warning // TODO overwrite warning
// TODO don't overwrite, have a draft list // TODO don't overwrite, have a draft list
if (process.dev) { if (import.meta.dev) {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
const result = confirm('[DEV] Are you sure you overwrite draft content?') const result = confirm('[DEV] Are you sure you overwrite draft content?')
if (!result) if (!result)
@ -89,7 +89,7 @@ function restoreMediaPreviewFromState() {
isMediaPreviewOpen.value = history.state?.mediaPreview ?? false isMediaPreviewOpen.value = history.state?.mediaPreview ?? false
} }
if (process.client) { if (import.meta.client) {
window.addEventListener('popstate', restoreMediaPreviewFromState) window.addEventListener('popstate', restoreMediaPreviewFromState)
restoreMediaPreviewFromState() restoreMediaPreviewFromState()

View File

@ -11,7 +11,7 @@ function getDefault(): CustomEmojisInfo {
} }
} }
export const currentCustomEmojis = process.server export const currentCustomEmojis = import.meta.server
? computed(getDefault) ? computed(getDefault)
: useUserLocalStorage(STORAGE_KEY_CUSTOM_EMOJIS, getDefault) : useUserLocalStorage(STORAGE_KEY_CUSTOM_EMOJIS, getDefault)

View File

@ -21,7 +21,7 @@ export async function useAsyncIDBKeyval<T>(
const data = (shallow ? shallowRef : ref)(initialValue) as Ref<T> const data = (shallow ? shallowRef : ref)(initialValue) as Ref<T>
const rawInit: T = resolveUnref(initialValue) const rawInit: T = toValue(initialValue)
async function read() { async function read() {
if (!isIDBSupported) if (!isIDBSupported)

View File

@ -13,7 +13,7 @@ export function useMask(options: UseMaskOptions = {}) {
getContainer = () => document.body, getContainer = () => document.body,
zIndex = 100, zIndex = 100,
} = options } = options
const wrapperEl = (process.server ? null : document.createElement('div')) as HTMLDivElement const wrapperEl = (import.meta.server ? null : document.createElement('div')) as HTMLDivElement
function show() { function show() {
const container = getContainer() const container = getContainer()

View File

@ -99,7 +99,7 @@ export function useStreaming(
stream.value = cb(streamingClient.value) stream.value = cb(streamingClient.value)
}) })
if (process.client && !process.test) if (import.meta.client && !process.test)
useNuxtApp().$pageLifecycle.addFrozenListener(cleanup) useNuxtApp().$pageLifecycle.addFrozenListener(cleanup)
tryOnBeforeUnmount(() => isActive.value = false) tryOnBeforeUnmount(() => isActive.value = false)

View File

@ -94,7 +94,7 @@ export function usePublish(options: {
...(isGlitchEdition.value ? { 'content-type': 'text/markdown' } : {}), ...(isGlitchEdition.value ? { 'content-type': 'text/markdown' } : {}),
} as mastodon.rest.v1.CreateStatusParams } as mastodon.rest.v1.CreateStatusParams
if (process.dev) { if (import.meta.dev) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.info({ console.info({
raw: draft.value.params.status, raw: draft.value.params.status,
@ -249,7 +249,7 @@ export function useUploadMediaAttachment(draft: Ref<Draft>) {
} }
async function pickAttachments() { async function pickAttachments() {
if (process.server) if (import.meta.server)
return return
const mimeTypes = currentInstance.value!.configuration?.mediaAttachments.supportedMimeTypes const mimeTypes = currentInstance.value!.configuration?.mediaAttachments.supportedMimeTypes
const files = await fileOpen({ const files = await fileOpen({

View File

@ -4,7 +4,7 @@ import { STORAGE_KEY_DRAFTS } from '~/constants'
import type { Draft, DraftMap } from '~/types' import type { Draft, DraftMap } from '~/types'
import type { Mutable } from '~/types/utils' import type { Mutable } from '~/types/utils'
export const currentUserDrafts = (process.server || process.test) export const currentUserDrafts = (import.meta.server || process.test)
? computed<DraftMap>(() => ({})) ? computed<DraftMap>(() => ({}))
: useUserLocalStorage<DraftMap>(STORAGE_KEY_DRAFTS, () => ({})) : useUserLocalStorage<DraftMap>(STORAGE_KEY_DRAFTS, () => ({}))

View File

@ -45,7 +45,7 @@ export const supportedTranslationCodes = [
export function getLanguageCode() { export function getLanguageCode() {
let code = 'en' let code = 'en'
const getCode = (code: string) => code.replace(/-.*$/, '') const getCode = (code: string) => code.replace(/-.*$/, '')
if (!process.server) { if (import.meta.client) {
const { locale } = useI18n() const { locale } = useI18n()
code = getCode(locale.value ? locale.value : navigator.language) code = getCode(locale.value ? locale.value : navigator.language)
} }

View File

@ -103,7 +103,7 @@ export function usePaginator<T, P, U = T>(
bound.update() bound.update()
} }
if (process.client) { if (import.meta.client) {
useIntervalFn(() => { useIntervalFn(() => {
bound.update() bound.update()
}, 1000) }, 1000)

View File

@ -56,7 +56,7 @@ export interface ThemeColors {
} }
export function getDefaultLanguage(languages: string[]) { export function getDefaultLanguage(languages: string[]) {
if (process.server) if (import.meta.server)
return 'en-US' return 'en-US'
return matchLanguages(languages, navigator.languages) || 'en-US' return matchLanguages(languages, navigator.languages) || 'en-US'
} }

View File

@ -1,14 +1,12 @@
import type { Ref } from 'vue' import type { Ref } from 'vue'
import type { VueI18n } from 'vue-i18n' import type { LocaleObject } from '@nuxtjs/i18n'
import type { LocaleObject } from 'vue-i18n-routing'
import type { FontSize, OldFontSize, PreferencesSettings, UserSettings } from './definition' import type { FontSize, OldFontSize, PreferencesSettings, UserSettings } from './definition'
import { STORAGE_KEY_SETTINGS } from '~/constants' import { STORAGE_KEY_SETTINGS } from '~/constants'
import { oldFontSizeMap } from '~~/constants/options' import { oldFontSizeMap } from '~~/constants/options'
export function useUserSettings() { export function useUserSettings() {
const i18n = useNuxtApp().vueApp.config.globalProperties.$i18n as VueI18n const { locales } = useNuxtApp().$i18n
const { locales } = i18n const supportLanguages = (unref(locales) as LocaleObject[]).map(locale => locale.code)
const supportLanguages = (locales as LocaleObject[]).map(locale => locale.code)
const settingsStorage = useUserLocalStorage<UserSettings>(STORAGE_KEY_SETTINGS, () => getDefaultUserSettings(supportLanguages)) const settingsStorage = useUserLocalStorage<UserSettings>(STORAGE_KEY_SETTINGS, () => getDefaultUserSettings(supportLanguages))
// Backward compatibility, font size was xs, sm, md, lg, xl before // Backward compatibility, font size was xs, sm, md, lg, xl before

View File

@ -1,5 +1,4 @@
import type { Directions } from 'vue-i18n-routing' import type { Directions, LocaleObject } from '@nuxtjs/i18n'
import type { LocaleObject } from '#i18n'
export function setupPageHeader() { export function setupPageHeader() {
const { locale, locales, t } = useI18n() const { locale, locales, t } = useI18n()
@ -52,7 +51,7 @@ export function setupPageHeader() {
return titleTemplate return titleTemplate
}, },
link: (process.client && useAppConfig().pwaEnabled) link: (import.meta.client && useAppConfig().pwaEnabled)
? () => [{ ? () => [{
key: 'webmanifest', key: 'webmanifest',
rel: 'manifest', rel: 'manifest',

View File

@ -28,7 +28,7 @@ export interface UseTiptapOptions {
} }
export function useTiptap(options: UseTiptapOptions) { export function useTiptap(options: UseTiptapOptions) {
if (process.server) if (import.meta.server)
return { editor: ref<Editor | undefined>() } return { editor: ref<Editor | undefined>() }
const { const {

View File

@ -18,7 +18,7 @@ export function isCustomEmoji(emoji: CustomEmoji | Emoji): emoji is CustomEmoji
return !!(emoji as CustomEmoji).custom return !!(emoji as CustomEmoji).custom
} }
export const TiptapMentionSuggestion: Partial<SuggestionOptions> = process.server export const TiptapMentionSuggestion: Partial<SuggestionOptions> = import.meta.server
? {} ? {}
: { : {
pluginKey: new PluginKey('mention'), pluginKey: new PluginKey('mention'),
@ -56,7 +56,7 @@ export const TiptapEmojiSuggestion: Partial<SuggestionOptions> = {
pluginKey: new PluginKey('emoji'), pluginKey: new PluginKey('emoji'),
char: ':', char: ':',
async items({ query }): Promise<(CustomEmoji | Emoji)[]> { async items({ query }): Promise<(CustomEmoji | Emoji)[]> {
if (process.server || query.length === 0) if (import.meta.server || query.length === 0)
return [] return []
if (currentCustomEmojis.value.emojis.length === 0) if (currentCustomEmojis.value.emojis.length === 0)

View File

@ -32,7 +32,7 @@ function initializeUsers(): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>
} }
} }
const users = process.server const users = import.meta.server
? ref<UserLogin[]>(defaultUsers) ? ref<UserLogin[]>(defaultUsers)
: useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, { deep: true }) : useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, { deep: true })
@ -42,7 +42,7 @@ function initializeUsers(): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>
return users return users
} }
const users = process.server ? initializeUsers() as Ref<UserLogin[]> | RemovableRef<UserLogin[]> : await initializeUsers() const users = import.meta.server ? initializeUsers() as Ref<UserLogin[]> | RemovableRef<UserLogin[]> : await initializeUsers()
const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true }) const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true })
const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '') const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '')
export const instanceStorage = useLocalStorage<Record<string, mastodon.v1.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true }) export const instanceStorage = useLocalStorage<Record<string, mastodon.v1.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true })
@ -81,7 +81,7 @@ export const isGotoSocial = computed(() => currentNodeInfo.value?.software?.name
export const isGlitchEdition = computed(() => currentInstance.value?.version?.includes('+glitch')) export const isGlitchEdition = computed(() => currentInstance.value?.version?.includes('+glitch'))
// when multiple tabs: we need to reload window when sign in, switch account or sign out // when multiple tabs: we need to reload window when sign in, switch account or sign out
if (process.client) { if (import.meta.client) {
const windowReload = () => { const windowReload = () => {
document.visibilityState === 'visible' && window.location.reload() document.visibilityState === 'visible' && window.location.reload()
} }
@ -184,7 +184,7 @@ export function getExpandSpoilersByDefault(account: mastodon.v1.AccountCredentia
* @returns `true` when user selected "Always show media" as Media Display preference * @returns `true` when user selected "Always show media" as Media Display preference
*/ */
export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials) { export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials) {
return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'show_all' ?? false return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'show_all'
} }
/** /**
@ -192,7 +192,7 @@ export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials)
* @returns `true` when user selected "Always hide media" as Media Display preference * @returns `true` when user selected "Always hide media" as Media Display preference
*/ */
export function getHideMediaByDefault(account: mastodon.v1.AccountCredentials) { export function getHideMediaByDefault(account: mastodon.v1.AccountCredentials) {
return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'hide_all' ?? false return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'hide_all'
} }
export async function fetchAccountInfo(client: mastodon.rest.Client, server: string) { export async function fetchAccountInfo(client: mastodon.rest.Client, server: string) {
@ -343,7 +343,7 @@ interface UseUserLocalStorageCache {
* @param initial * @param initial
*/ */
export function useUserLocalStorage<T extends object>(key: string, initial: () => T): Ref<T> { export function useUserLocalStorage<T extends object>(key: string, initial: () => T): Ref<T> {
if (process.server || process.test) if (import.meta.server || process.test)
return shallowRef(initial()) return shallowRef(initial())
// @ts-expect-error bind value to the function // @ts-expect-error bind value to the function

View File

@ -43,7 +43,7 @@ export function onReactivated(hook: () => void, target?: ComponentInternalInstan
export function useHydratedHead<T extends SchemaAugmentations>(input: UseHeadInput<T>, options?: UseHeadOptions): ActiveHeadEntry<UseHeadInput<T>> | void { export function useHydratedHead<T extends SchemaAugmentations>(input: UseHeadInput<T>, options?: UseHeadOptions): ActiveHeadEntry<UseHeadInput<T>> | void {
if (input && typeof input === 'object' && !('value' in input)) { if (input && typeof input === 'object' && !('value' in input)) {
const title = 'title' in input ? input.title : undefined const title = 'title' in input ? input.title : undefined
if (process.server && title) { if (import.meta.server && title) {
input.meta = input.meta || [] input.meta = input.meta || []
if (Array.isArray(input.meta)) { if (Array.isArray(input.meta)) {
input.meta.push( input.meta.push(

View File

@ -1,5 +1,5 @@
export function useWebShareTarget(listener?: (message: MessageEvent) => void) { export function useWebShareTarget(listener?: (message: MessageEvent) => void) {
if (process.server) if (import.meta.server)
return return
onBeforeMount(() => { onBeforeMount(() => {

20
config/i18n.config.ts Normal file
View File

@ -0,0 +1,20 @@
import {
currentLocales,
datetimeFormats,
numberFormats,
pluralRules,
} from './i18n'
export default defineI18nConfig(() => {
return {
legacy: false,
availableLocales: currentLocales.map(l => l.code),
fallbackLocale: 'en-US',
fallbackWarn: true,
missingWarn: true,
datetimeFormats,
numberFormats,
// eslint-disable-next-line @typescript-eslint/comma-dangle
pluralRules
}
})

View File

@ -1,7 +1,5 @@
import type { NuxtI18nOptions } from '@nuxtjs/i18n'
import type { DateTimeFormats, NumberFormats, PluralizationRule, PluralizationRules } from '@intlify/core-base' import type { DateTimeFormats, NumberFormats, PluralizationRule, PluralizationRules } from '@intlify/core-base'
import type { LocaleObject } from '@nuxtjs/i18n'
import type { LocaleObject } from '#i18n'
interface LocaleObjectData extends LocaleObject { interface LocaleObjectData extends LocaleObject {
numberFormats?: NumberFormats numberFormats?: NumberFormats
@ -239,7 +237,7 @@ function buildLocales() {
...data, ...data,
code: l.code, code: l.code,
name: l.name, name: l.name,
files: [data.file!, `${l.code}.json`], files: [data.file as string, `${l.code}.json`],
} }
delete entry.file delete entry.file
acc.push(entry) acc.push(entry)
@ -256,7 +254,7 @@ function buildLocales() {
export const currentLocales = buildLocales() export const currentLocales = buildLocales()
const datetimeFormats = Object.values(currentLocales).reduce((acc, data) => { export const datetimeFormats = Object.values(currentLocales).reduce((acc, data) => {
const dateTimeFormats = data.dateTimeFormats const dateTimeFormats = data.dateTimeFormats
if (dateTimeFormats) { if (dateTimeFormats) {
acc[data.code] = { ...dateTimeFormats } acc[data.code] = { ...dateTimeFormats }
@ -281,7 +279,7 @@ const datetimeFormats = Object.values(currentLocales).reduce((acc, data) => {
return acc return acc
}, <DateTimeFormats>{}) }, <DateTimeFormats>{})
const numberFormats = Object.values(currentLocales).reduce((acc, data) => { export const numberFormats = Object.values(currentLocales).reduce((acc, data) => {
const numberFormats = data.numberFormats const numberFormats = data.numberFormats
if (numberFormats) { if (numberFormats) {
acc[data.code] = { ...numberFormats } acc[data.code] = { ...numberFormats }
@ -313,7 +311,7 @@ const numberFormats = Object.values(currentLocales).reduce((acc, data) => {
return acc return acc
}, <NumberFormats>{}) }, <NumberFormats>{})
const pluralRules = Object.values(currentLocales).reduce((acc, data) => { export const pluralRules = Object.values(currentLocales).reduce((acc, data) => {
const pluralRule = data.pluralRule const pluralRule = data.pluralRule
if (pluralRule) { if (pluralRule) {
acc[data.code] = pluralRule acc[data.code] = pluralRule
@ -322,21 +320,3 @@ const pluralRules = Object.values(currentLocales).reduce((acc, data) => {
return acc return acc
}, <PluralizationRules>{}) }, <PluralizationRules>{})
export const i18n: NuxtI18nOptions = {
locales: currentLocales,
lazy: true,
strategy: 'no_prefix',
detectBrowserLanguage: false,
langDir: 'locales',
defaultLocale: 'en-US',
vueI18n: {
availableLocales: currentLocales.map(l => l.code),
fallbackLocale: 'en-US',
fallbackWarn: false,
missingWarn: false,
datetimeFormats,
numberFormats,
pluralRules,
},
}

View File

@ -9,10 +9,10 @@
"preview": "nuxi preview" "preview": "nuxi preview"
}, },
"dependencies": { "dependencies": {
"theme-colors": "^0.0.5" "theme-colors": "^0.1.0"
}, },
"devDependencies": { "devDependencies": {
"@nuxt-themes/docus": "^1.14.6", "@nuxt-themes/docus": "^1.15.0",
"nuxt": "^3.7.0" "nuxt": "^3.10.3"
} }
} }

View File

@ -1,3 +1,3 @@
declare module 'virtual:emoji-mart-lang-importer' { declare module 'virtual:emoji-mart-lang-importer' {
export default function(lang: string): Promise<any> export default function (lang: string): Promise<any>
} }

View File

@ -11,7 +11,7 @@ const errorCodes: Record<number, string> = {
404: 'Page not found', 404: 'Page not found',
} }
if (process.dev) if (import.meta.dev)
console.error(error) console.error(error)
const defaultMessage = 'Something went wrong' const defaultMessage = 'Something went wrong'

View File

@ -1,5 +1,5 @@
export default defineNuxtRouteMiddleware(async (to, from) => { export default defineNuxtRouteMiddleware(async (to, from) => {
if (process.server) if (import.meta.server)
return return
if (!('server' in to.params)) if (!('server' in to.params))

View File

@ -1,5 +1,5 @@
export default defineNuxtRouteMiddleware(async (to) => { export default defineNuxtRouteMiddleware(async (to) => {
if (process.server || !useRuntimeConfig().public.singleInstance) if (import.meta.server || !useRuntimeConfig().public.singleInstance)
return return
if (to.params.server) { if (to.params.server) {

View File

@ -1,7 +1,7 @@
import type { RouteLocationNormalized } from 'vue-router' import type { RouteLocationNormalized } from 'vue-router'
export default defineNuxtRouteMiddleware((to) => { export default defineNuxtRouteMiddleware((to) => {
if (process.server) if (import.meta.server)
return return
if (to.path === '/signin/callback') if (to.path === '/signin/callback')

View File

@ -1,7 +1,6 @@
import fs from 'fs-extra' import fs from 'fs-extra'
import { createResolver, defineNuxtModule } from '@nuxt/kit' import { createResolver, defineNuxtModule } from '@nuxt/kit'
import { i18n } from '../config/i18n' import { currentLocales } from '../config/i18n'
import type { LocaleObject } from '#i18n'
const virtual = 'virtual:emoji-mart-lang-importer' const virtual = 'virtual:emoji-mart-lang-importer'
const resolvedVirtual = `\0${virtual}.mjs` const resolvedVirtual = `\0${virtual}.mjs`
@ -25,7 +24,7 @@ export default defineNuxtModule({
if (id === resolvedVirtual) { if (id === resolvedVirtual) {
const locales = await Promise.all( const locales = await Promise.all(
Array Array
.from(new Set((i18n.locales as LocaleObject[]).map(l => l.code.split('-')[0]))) .from(new Set((currentLocales).map(l => l.code.split('-')[0])))
.map(async (l) => { .map(async (l) => {
const exists = await isFile(resolver.resolve(`../node_modules/@emoji-mart/data/i18n/${l}.json`)) const exists = await isFile(resolver.resolve(`../node_modules/@emoji-mart/data/i18n/${l}.json`))
return [l, exists] as [code: string, exists: boolean] return [l, exists] as [code: string, exists: boolean]

View File

@ -3,12 +3,11 @@ import { readFile } from 'fs-extra'
import { createResolver } from '@nuxt/kit' import { createResolver } from '@nuxt/kit'
import type { ManifestOptions } from 'vite-plugin-pwa' import type { ManifestOptions } from 'vite-plugin-pwa'
import { getEnv } from '../../config/env' import { getEnv } from '../../config/env'
import { i18n } from '../../config/i18n' import { currentLocales } from '../../config/i18n'
import type { LocaleObject } from '#i18n'
export type LocalizedWebManifest = Record<string, Partial<ManifestOptions>> export type LocalizedWebManifest = Record<string, Partial<ManifestOptions>>
export const pwaLocales = i18n.locales as LocaleObject[] export const pwaLocales = currentLocales
type WebManifestEntry = Pick<ManifestOptions, 'name' | 'short_name' | 'description' | 'screenshots' | 'shortcuts'> type WebManifestEntry = Pick<ManifestOptions, 'name' | 'short_name' | 'description' | 'screenshots' | 'shortcuts'>
type RequiredWebManifestEntry = Required<WebManifestEntry & Pick<ManifestOptions, 'dir' | 'lang' | 'screenshots' | 'shortcuts'>> type RequiredWebManifestEntry = Required<WebManifestEntry & Pick<ManifestOptions, 'dir' | 'lang' | 'screenshots' | 'shortcuts'>>
@ -141,8 +140,8 @@ export async function createI18n(): Promise<LocalizedWebManifest> {
.map(async ({ code, dir = 'ltr', file, files }) => { .map(async ({ code, dir = 'ltr', file, files }) => {
// read locale file or files // read locale file or files
const { action, app_desc_short, app_name, nav, pwa } = file const { action, app_desc_short, app_name, nav, pwa } = file
? await readI18nFile(file) ? await readI18nFile(file as string)
: await findBestWebManifestData(files, env) : await findBestWebManifestData(files as string[], env)
const entry = pwa?.webmanifest?.[env] ?? {} const entry = pwa?.webmanifest?.[env] ?? {}
if (!entry.name && app_name) if (!entry.name && app_name)

View File

@ -37,7 +37,7 @@ export default defineNuxtPlugin(async () => {
const config = useRuntimeConfig() const config = useRuntimeConfig()
const h3App = createApp({ const h3App = createApp({
debug: process.dev, debug: import.meta.dev,
// TODO: add global error handler // TODO: add global error handler
// onError: (err, event) => { // onError: (err, event) => {
// console.log({ err, event }) // console.log({ err, event })

View File

@ -1,9 +1,9 @@
import { createResolver, useNuxt } from '@nuxt/kit' import { createResolver, useNuxt } from '@nuxt/kit'
import { isCI, isDevelopment, isWindows } from 'std-env' import { isCI, isDevelopment, isWindows } from 'std-env'
import { isPreview } from './config/env' import { isPreview } from './config/env'
import { i18n } from './config/i18n'
import { pwa } from './config/pwa' import { pwa } from './config/pwa'
import type { BuildInfo } from './types' import type { BuildInfo } from './types'
import { currentLocales } from './config/i18n'
const { resolve } = createResolver(import.meta.url) const { resolve } = createResolver(import.meta.url)
@ -34,7 +34,6 @@ export default defineNuxtConfig({
'stale-dep/nuxt', 'stale-dep/nuxt',
], ],
vue: { vue: {
defineModel: true,
propsDestructure: true, propsDestructure: true,
}, },
macros: { macros: {
@ -46,9 +45,11 @@ export default defineNuxtConfig({
devtools: { devtools: {
enabled: true, enabled: true,
}, },
features: {
inlineStyles: false,
},
experimental: { experimental: {
payloadExtraction: false, payloadExtraction: false,
inlineSSRStyles: false,
renderJsonPayloads: true, renderJsonPayloads: true,
}, },
css: [ css: [
@ -277,7 +278,15 @@ export default defineNuxtConfig({
rateLimiter: false, rateLimiter: false,
}, },
colorMode: { classSuffix: '' }, colorMode: { classSuffix: '' },
i18n, i18n: {
locales: currentLocales,
lazy: true,
strategy: 'no_prefix',
detectBrowserLanguage: false,
langDir: 'locales',
defaultLocale: 'en-US',
vueI18n: './config/i18n.config.ts',
},
pwa, pwa,
staleDep: { staleDep: {
packageManager: 'pnpm', packageManager: 'pnpm',

View File

@ -36,12 +36,12 @@
"@fnando/sparkline": "^0.3.10", "@fnando/sparkline": "^0.3.10",
"@iconify-emoji/twemoji": "^1.0.2", "@iconify-emoji/twemoji": "^1.0.2",
"@iconify/json": "^2.2.170", "@iconify/json": "^2.2.170",
"@iconify/utils": "^2.1.7", "@iconify/utils": "^2.1.22",
"@nuxt/devtools": "^1.0.0-beta.1", "@nuxt/devtools": "^1.0.8",
"@nuxt/test-utils": "^3.9.0-alpha.1", "@nuxt/test-utils": "^3.11.0",
"@nuxtjs/color-mode": "^3.3.2", "@nuxtjs/color-mode": "^3.3.2",
"@nuxtjs/i18n": "8.0.0-beta.10", "@nuxtjs/i18n": "^8.1.1",
"@pinia/nuxt": "^0.4.11", "@pinia/nuxt": "^0.5.1",
"@tiptap/core": "2.1.8", "@tiptap/core": "2.1.8",
"@tiptap/extension-bold": "2.1.8", "@tiptap/extension-bold": "2.1.8",
"@tiptap/extension-character-count": "2.1.8", "@tiptap/extension-character-count": "2.1.8",
@ -56,22 +56,22 @@
"@tiptap/starter-kit": "2.1.8", "@tiptap/starter-kit": "2.1.8",
"@tiptap/suggestion": "2.1.8", "@tiptap/suggestion": "2.1.8",
"@tiptap/vue-3": "2.1.8", "@tiptap/vue-3": "2.1.8",
"@unocss/nuxt": "^0.53.4", "@unocss/nuxt": "^0.58.5",
"@upstash/redis": "^1.27.1", "@upstash/redis": "^1.27.1",
"@vercel/kv": "^1.0.1", "@vercel/kv": "^1.0.1",
"@vue-macros/nuxt": "^1.6.0", "@vue-macros/nuxt": "^1.6.0",
"@vueuse/core": "^10.2.1", "@vueuse/core": "^10.8.0",
"@vueuse/gesture": "^2.0.0", "@vueuse/gesture": "^2.0.0",
"@vueuse/integrations": "^10.2.1", "@vueuse/integrations": "^10.8.0",
"@vueuse/math": "^10.2.1", "@vueuse/math": "^10.8.0",
"@vueuse/motion": "2.0.0", "@vueuse/motion": "2.1.0",
"@vueuse/nuxt": "^10.2.1", "@vueuse/nuxt": "^10.8.0",
"blurhash": "^2.0.5", "blurhash": "^2.0.5",
"browser-fs-access": "^0.34.1", "browser-fs-access": "^0.35.0",
"chroma-js": "^2.4.2", "chroma-js": "^2.4.2",
"emoji-mart": "^5.5.2", "emoji-mart": "^5.5.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"floating-vue": "2.0.0-beta.24", "floating-vue": "^5.2.2",
"focus-trap": "^7.5.1", "focus-trap": "^7.5.1",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fuse.js": "^6.6.2", "fuse.js": "^6.6.2",
@ -86,7 +86,7 @@
"node-emoji": "^2.1.3", "node-emoji": "^2.1.3",
"nuxt-security": "^0.13.1", "nuxt-security": "^0.13.1",
"page-lifecycle": "^0.1.2", "page-lifecycle": "^0.1.2",
"pinia": "^2.1.4", "pinia": "^2.1.7",
"postcss-nested": "^6.0.1", "postcss-nested": "^6.0.1",
"prosemirror-highlight": "^0.5.0", "prosemirror-highlight": "^0.5.0",
"rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-node-polyfills": "^0.2.1",
@ -101,10 +101,10 @@
"theme-vitesse": "^0.7.2", "theme-vitesse": "^0.7.2",
"tiny-decode": "^0.1.3", "tiny-decode": "^0.1.3",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"ufo": "^1.3.0", "ufo": "^1.4.0",
"ultrahtml": "^1.2.0", "ultrahtml": "^1.5.3",
"unimport": "^3.0.12", "unimport": "^3.7.1",
"vite-plugin-pwa": "^0.16.4", "vite-plugin-pwa": "^0.19.0",
"vue-advanced-cropper": "^2.8.8", "vue-advanced-cropper": "^2.8.8",
"vue-virtual-scroller": "2.0.0-beta.8", "vue-virtual-scroller": "2.0.0-beta.8",
"workbox-build": "^7.0.0", "workbox-build": "^7.0.0",
@ -112,8 +112,8 @@
"ws": "^8.15.1" "ws": "^8.15.1"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.41.3", "@antfu/eslint-config": "^0.43.1",
"@antfu/ni": "^0.21.8", "@antfu/ni": "^0.21.12",
"@types/chroma-js": "^2.4.1", "@types/chroma-js": "^2.4.1",
"@types/file-saver": "^2.0.5", "@types/file-saver": "^2.0.5",
"@types/flat": "^5.0.2", "@types/flat": "^5.0.2",
@ -123,34 +123,34 @@
"@types/prettier": "^2.7.3", "@types/prettier": "^2.7.3",
"@types/wicg-file-system-access": "^2020.9.6", "@types/wicg-file-system-access": "^2020.9.6",
"@types/ws": "^8.5.10", "@types/ws": "^8.5.10",
"@unlazy/nuxt": "^0.9.3", "@unlazy/nuxt": "^0.11.1",
"@vue/test-utils": "^2.4.3", "@vue/test-utils": "^2.4.4",
"bumpp": "^9.2.0", "bumpp": "^9.2.0",
"consola": "^3.2.3", "consola": "^3.2.3",
"eslint": "^8.49.0", "eslint": "^8.49.0",
"flat": "^5.0.2", "flat": "^5.0.2",
"fs-extra": "^11.1.1", "fs-extra": "^11.1.1",
"lint-staged": "^14.0.1", "lint-staged": "^14.0.1",
"nuxt": "3.8.2", "nuxt": "^3.10.3",
"prettier": "^3.0.3", "prettier": "^3.0.3",
"sharp": "^0.32.5", "sharp": "^0.32.6",
"sharp-ico": "^0.1.5", "sharp-ico": "^0.1.5",
"simple-git-hooks": "^2.9.0", "simple-git-hooks": "^2.9.0",
"tsx": "^3.12.8", "tsx": "^4.7.1",
"typescript": "^5.1.6", "typescript": "^5.3.3",
"vitest": "^1.3.0", "vitest": "1.3.1",
"vue-tsc": "^1.8.8" "vue-tsc": "^1.8.27"
}, },
"pnpm": { "pnpm": {
"overrides": { "overrides": {
"@nuxt/schema": "3.8.2", "unstorage": "^1.10.1"
"unstorage": "^1.9.0"
}, },
"patchedDependencies": { "patchedDependencies": {
"nuxt-security@0.13.1": "patches/nuxt-security@0.13.1.patch" "nuxt-security@0.13.1": "patches/nuxt-security@0.13.1.patch"
} }
}, },
"resolutions": { "resolutions": {
"vitest": "1.3.1",
"vue": "^3.4.19" "vue": "^3.4.19"
}, },
"simple-git-hooks": { "simple-git-hooks": {

28
page-lifecycle.d.ts vendored
View File

@ -1,17 +1,17 @@
declare module 'page-lifecycle/dist/lifecycle.mjs' { declare module 'page-lifecycle/dist/lifecycle.mjs' {
type PageLifecycleState = 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated' type PageLifecycleState = 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated'
interface PageLifecycleEvent extends Event { interface PageLifecycleEvent extends Event {
newState: PageLifecycleState newState: PageLifecycleState
oldState: PageLifecycleState oldState: PageLifecycleState
} }
interface PageLifecycle extends EventTarget { interface PageLifecycle extends EventTarget {
get state(): PageLifecycleState get state(): PageLifecycleState
get pageWasDiscarded(): boolean get pageWasDiscarded(): boolean
addUnsavedChanges: (id: Symbol | any) => void addUnsavedChanges: (id: symbol | any) => void
removeUnsavedChanges: (id: Symbol | any) => void removeUnsavedChanges: (id: symbol | any) => void
addEventListener: (type: string, listener: (evt: PageLifecycleEvent) => void) => void addEventListener: (type: string, listener: (evt: PageLifecycleEvent) => void) => void
} }
const lifecycle: PageLifecycle const lifecycle: PageLifecycle
export default lifecycle export default lifecycle
} }

View File

@ -8,7 +8,7 @@ const accountName = computed(() => toShortHandle(params.account as string))
const { t } = useI18n() const { t } = useI18n()
const { data: account, pending, refresh } = await useAsyncData(() => fetchAccountByHandle(accountName.value).catch(() => null), { immediate: process.client, default: () => shallowRef() }) const { data: account, pending, refresh } = await useAsyncData(() => fetchAccountByHandle(accountName.value).catch(() => null), { immediate: import.meta.client, default: () => shallowRef() })
const relationship = computed(() => account ? useRelationship(account.value).value : undefined) const relationship = computed(() => account ? useRelationship(account.value).value : undefined)
const userSettings = useUserSettings() const userSettings = useUserSettings()

View File

@ -6,7 +6,7 @@ definePageMeta({
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
if (process.client && route.path === '/signin/callback') if (import.meta.client && route.path === '/signin/callback')
router.push('/home') router.push('/home')
const { t } = useI18n() const { t } = useI18n()

View File

@ -12,7 +12,7 @@ useHydratedHead({
const loggedInUsers = useUsers() const loggedInUsers = useUsers()
async function exportTokens() { async function exportTokens() {
if (process.server) if (import.meta.server)
return return
if (!confirm('Please aware that the tokens represent the **full access** to your accounts, and should be treated as sensitive information. Are you sure you want to export the tokens?')) if (!confirm('Please aware that the tokens represent the **full access** to your accounts, and should be treated as sensitive information. Are you sure you want to export the tokens?'))
@ -31,7 +31,7 @@ async function exportTokens() {
} }
async function importTokens() { async function importTokens() {
if (process.server) if (import.meta.server)
return return
const file = await fileOpen({ const file = await fileOpen({
description: 'Token File', description: 'Token File',

View File

@ -8,7 +8,7 @@ definePageMeta({
useWebShareTarget() useWebShareTarget()
const pwaIsInstalled = process.client && !!useNuxtApp().$pwa?.isInstalled const pwaIsInstalled = import.meta.client && !!useNuxtApp().$pwa?.isInstalled
</script> </script>
<template> <template>

View File

@ -16,7 +16,7 @@ export default defineNuxtPlugin(() => {
if (!settings) { return } if (!settings) { return }
const html = document.documentElement const html = document.documentElement
${process.dev ? 'console.log({ settings })' : ''} ${import.meta.dev ? 'console.log({ settings })' : ''}
if (settings.fontSize) { if (settings.fontSize) {
const oldFontSizeMap = ${JSON.stringify(oldFontSizeMap)} const oldFontSizeMap = ${JSON.stringify(oldFontSizeMap)}

View File

@ -7,13 +7,13 @@ export default defineNuxtPlugin(async (nuxt) => {
nuxt.vueApp.config.globalProperties.$d = wrapI18n(d) nuxt.vueApp.config.globalProperties.$d = wrapI18n(d)
nuxt.vueApp.config.globalProperties.$n = wrapI18n(n) nuxt.vueApp.config.globalProperties.$n = wrapI18n(n)
if (process.client) { if (import.meta.client) {
const i18n = nuxt.vueApp.config.globalProperties.$i18n as import('vue-i18n').VueI18n const i18n = useNuxtApp().$i18n
const { setLocale, locales } = i18n const { setLocale, locales } = i18n
const userSettings = useUserSettings() const userSettings = useUserSettings()
const lang = computed(() => userSettings.value.language) const lang = computed(() => userSettings.value.language)
const supportLanguages = (locales as import('vue-i18n-routing').LocaleObject[]).map(locale => locale.code) const supportLanguages = unref(locales).map(locale => locale.code)
if (!supportLanguages.includes(lang.value)) if (!supportLanguages.includes(lang.value))
userSettings.value.language = getDefaultLanguage(supportLanguages) userSettings.value.language = getDefaultLanguage(supportLanguages)

File diff suppressed because it is too large Load Diff

View File

@ -22,13 +22,12 @@ function merge(src: Record<string, any>, dst: Record<string, any>) {
} }
} }
const sourceFiles: string[] = sourceLanguageLocale.files ? sourceLanguageLocale.files : [sourceLanguageLocale.file!] const sourceFiles = sourceLanguageLocale.files ? sourceLanguageLocale.files : [sourceLanguageLocale.file!]
const sourceTranslations: Record<string, string> = {} const sourceTranslations: Record<string, string> = {}
for (const file of sourceFiles) { for (const file of sourceFiles) {
const data = JSON.parse(Buffer.from( const data = JSON.parse(Buffer.from(
await fs.readFile(resolver.resolve(`../locales/${file}`), 'utf-8'), await fs.readFile(resolver.resolve(`../locales/${file as string}`), 'utf-8'),
).toString()) as Record<string, unknown> ).toString()) as Record<string, unknown>
merge(flatten(data), sourceTranslations) merge(flatten(data), sourceTranslations)
@ -36,7 +35,7 @@ for (const file of sourceFiles) {
async function removeOutdatedTranslations() { async function removeOutdatedTranslations() {
for (const locale of currentLocales.filter(l => l.code !== 'en-US')) { for (const locale of currentLocales.filter(l => l.code !== 'en-US')) {
const files: string[] = locale.files ? locale.files : [locale.file!] const files = locale.files ? locale.files as string[] : [locale.file as string]
for (const file of files) { for (const file of files) {
const path = resolver.resolve(`../locales/${file}`) const path = resolver.resolve(`../locales/${file}`)

View File

@ -1,9 +1,9 @@
{ {
"extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"lib": ["ESNext", "WebWorker", "DOM.Iterable"], "lib": ["ESNext", "WebWorker", "DOM.Iterable"],
"types": ["vite/client"] "types": ["vite/client"]
}, },
"include": ["./"], "include": ["./"],
"exclude": [], "exclude": []
"extends": "../tsconfig.json"
} }

View File

@ -1,4 +1,4 @@
import { describe, expect, it, vi } from 'vitest' import { beforeEach, describe, expect, it, vi } from 'vitest'
import { renderToString } from 'vue/server-renderer' import { renderToString } from 'vue/server-renderer'
import { format } from 'prettier' import { format } from 'prettier'
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
@ -6,6 +6,10 @@ import { mockComponent } from '@nuxt/test-utils/runtime'
import { contentToVNode } from '~/composables/content-render' import { contentToVNode } from '~/composables/content-render'
import type { ContentParseOptions } from '~/composables/content-parse' import type { ContentParseOptions } from '~/composables/content-parse'
beforeEach(() => {
publicServer.value = useRuntimeConfig().public.defaultServer
})
describe('content-rich', () => { describe('content-rich', () => {
it('empty', async () => { it('empty', async () => {
const { formatted } = await render('') const { formatted } = await render('')