chore(deps): update to use docus v4 + nuxt v4 (#3388)

This commit is contained in:
Daniel Roe 2025-09-29 19:37:53 +03:00 committed by GitHub
parent 30514ac2ce
commit 1a5c3eb671
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 7204 additions and 6233 deletions

1
.gitignore vendored
View file

@ -4,6 +4,7 @@ dist
.output .output
.pnpm-store .pnpm-store
.nuxt .nuxt
.data
.env .env
.DS_Store .DS_Store
.idea/ .idea/

4
.npmrc
View file

@ -1,4 +0,0 @@
shamefully-hoist=true
shell-emulator=true
ignore-workspace-root-check=true
package-manager-strict=false

View file

@ -17,13 +17,12 @@ RUN apk add git --no-cache
# Prepare build deps ( ignore postinstall scripts for now ) # Prepare build deps ( ignore postinstall scripts for now )
COPY package.json ./ COPY package.json ./
COPY .npmrc ./
COPY pnpm-lock.yaml ./ COPY pnpm-lock.yaml ./
COPY patches ./patches
RUN pnpm i --frozen-lockfile --ignore-scripts RUN pnpm i --frozen-lockfile --ignore-scripts
# Copy all source files # Copy all source files
COPY . ./ COPY . ./
RUN pnpm nuxt prepare
# Run full install with every postinstall script ( This needs project file ) # Run full install with every postinstall script ( This needs project file )
RUN pnpm i --frozen-lockfile RUN pnpm i --frozen-lockfile

19
app/augments.d.ts vendored Normal file
View file

@ -0,0 +1,19 @@
export {}
declare module '#app' {
interface PageMeta {
wideLayout?: boolean
}
interface RuntimeNuxtHooks {
'elk-logo:click': () => void
}
}
declare global {
namespace NodeJS {
interface Process {
mock?: Record<string, any>
}
}
}

View file

@ -17,6 +17,7 @@ export const shikiParser: Parser = (options) => {
return promise ?? [] return promise ?? []
if (!parser) if (!parser)
// @ts-expect-error will be fixed when shiki upgrades
parser = createParser(highlighter) parser = createParser(highlighter)
return parser(options) return parser(options)

View file

@ -19,11 +19,11 @@ export default defineNuxtPlugin(async (nuxt) => {
if (!supportLanguages.includes(lang.value)) if (!supportLanguages.includes(lang.value))
userSettings.value.language = getDefaultLanguage(supportLanguages) userSettings.value.language = getDefaultLanguage(supportLanguages)
if (lang.value !== i18n.locale) if (lang.value !== i18n.locale.value)
await setLocale(userSettings.value.language as Locale) await setLocale(userSettings.value.language as Locale)
watch([lang, isHydrated], () => { watch([lang, isHydrated], () => {
if (isHydrated.value && lang.value !== i18n.locale) if (isHydrated.value && lang.value !== i18n.locale.value)
setLocale(lang.value) setLocale(lang.value)
}, { immediate: true }) }, { immediate: true })
} }

View file

@ -75,13 +75,11 @@ export const countryLocaleVariants: Record<string, (LocaleObjectData & { country
const locales: LocaleObjectData[] = [ const locales: LocaleObjectData[] = [
{ {
// @ts-expect-error en used as placeholder
code: 'en', code: 'en',
file: 'en.json', file: 'en.json',
name: 'English', name: 'English',
}, },
{ {
// @ts-expect-error ar used as placeholder
code: 'ar', code: 'ar',
file: 'ar.json', file: 'ar.json',
name: 'العربية', name: 'العربية',
@ -112,7 +110,6 @@ const locales: LocaleObjectData[] = [
}, },
} satisfies LocaleObjectData, } satisfies LocaleObjectData,
{ {
// @ts-expect-error ca used as placeholder
code: 'ca', code: 'ca',
file: 'ca.json', file: 'ca.json',
name: 'Català', name: 'Català',
@ -153,7 +150,6 @@ const locales: LocaleObjectData[] = [
name: 'Nederlands', name: 'Nederlands',
}, },
{ {
// @ts-expect-error es used as placeholder
code: 'es', code: 'es',
file: 'es.json', file: 'es.json',
name: 'Español', name: 'Español',
@ -207,7 +203,6 @@ const locales: LocaleObjectData[] = [
}, },
}, },
{ {
// @ts-expect-error pt used as placeholder
code: 'pt', code: 'pt',
file: 'pt.json', file: 'pt.json',
name: 'Português', name: 'Português',
@ -283,7 +278,7 @@ function buildLocales() {
acc.push(data) acc.push(data)
} }
return acc return acc
}, <LocaleObjectData[]>[]) }, [] as LocaleObjectData[])
return useLocales.sort((a, b) => a.code.localeCompare(b.code)) return useLocales.sort((a, b) => a.code.localeCompare(b.code))
} }
@ -313,7 +308,7 @@ export const datetimeFormats = Object.values(currentLocales).reduce((acc, data)
} }
return acc return acc
}, <DateTimeFormats>{}) }, {} as DateTimeFormats)
export 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
@ -345,7 +340,7 @@ export const numberFormats = Object.values(currentLocales).reduce((acc, data) =>
} }
return acc return acc
}, <NumberFormats>{}) }, {} as NumberFormats)
export 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
@ -355,4 +350,4 @@ export const pluralRules = Object.values(currentLocales).reduce((acc, data) => {
} }
return acc return acc
}, <PluralizationRules>{}) }, {} as PluralizationRules)

View file

@ -1,35 +1,41 @@
export default defineAppConfig({ export default defineAppConfig({
docus: { seo: {
title: 'Elk', title: 'Elk',
description: 'A nimble Mastodon web client.', description: 'A nimble Mastodon web client with modern features and elegant design.',
image: 'https://docs.elk.zone/elk-screenshot.png', },
socials: { header: {
// twitter: 'elk_zone', title: 'Elk',
github: 'elk-zone/elk', logo: {
mastodon: { alt: 'Elk',
label: 'Mastodon', light: '/logo.svg',
icon: 'IconMastodon', dark: '/logo.svg',
href: 'https://elk.zone/@elk@webtoo.ls',
},
}, },
aside: { },
level: 0, socials: {
exclude: [], github: 'https://github.com/elk-zone/elk',
}, mastodon: 'https://elk.zone/@elk@webtoo.ls',
header: { },
logo: true, github: {
showLinkIcon: true, url: 'https://github.com/elk-zone/elk',
exclude: [], branch: 'main',
}, rootDir: 'docs',
footer: { },
iconLinks: [ toc: {
title: 'On this page',
bottom: {
title: 'Community',
links: [
{ {
href: 'https://nuxt.com', icon: 'i-ph-shooting-star-duotone',
icon: 'IconNuxtLabs', label: 'Star on GitHub',
to: 'https://github.com/elk-zone/elk',
target: '_blank',
}, },
{ {
href: 'https://m.webtoo.ls/@elk', icon: 'i-simple-icons-mastodon',
icon: 'IconMastodon', label: 'Follow on Mastodon',
to: 'https://elk.zone/@elk@webtoo.ls',
target: '_blank',
}, },
], ],
}, },

View file

@ -1,5 +0,0 @@
<template>
<AppLayout>
<NuxtPage />
</AppLayout>
</template>

View file

@ -0,0 +1,4 @@
/* Elk brand colors for light and dark modes */
:root {
--ui-primary: #f0943c;
}

View file

@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { TranslationStatus } from '../../types' import type { TranslationStatus } from '../../../types'
const localesStatuses: TranslationStatus = await import('../../translation-status.json').then(m => m.default) const localesStatuses: TranslationStatus = await import('../../../translation-status.json').then(m => m.default)
const totalReference = localesStatuses.en.total const totalReference = localesStatuses.en!.total
type Tab = 'missing' | 'outdated' type Tab = 'missing' | 'outdated'
@ -32,7 +32,7 @@ const missingEntries = computed<string[]>(() => {
if (hidden.value || !currentLocale.value || localeTab.value !== 'missing') if (hidden.value || !currentLocale.value || localeTab.value !== 'missing')
return [] return []
return localesStatuses[locale.value].missing return localesStatuses[locale.value]!.missing
}) })
const outdatedEntries = computed<string[]>(() => { const outdatedEntries = computed<string[]>(() => {

View file

@ -1,36 +0,0 @@
---
title: Elk
navigation: false
layout: page
---
::block-hero
---
cta:
- Read more
- /guide
secondary:
- Try it out →
- https://elk.zone
---
#title
Elk
#description
An in-progress, nimble Mastodon web client
#support
![Screenshot of Elk](/screenshot.png)
#extra
::list
- markdown support
- code blocks
- reordering and connecting posts in timelines
- multi account
- GitHub HTML cards
- and more...
::
::

View file

@ -1,3 +1,8 @@
---
title: Introduction
description: Get started with Elk, the nimble Mastodon web client.
---
# Introduction # Introduction
## What is Elk? ## What is Elk?
@ -16,7 +21,7 @@ Elk provides some features not available through the standard Mastodon web app i
You can use Elk right in your browser. You can use Elk right in your browser.
On a mobile device, you can install the app to your home screen right from your browser for easy access. On a mobile device, you can install the app to your home screen right from your browser for easy access.
(This is called a Progressive Web App, or [PWA](../80.pwa.md).) (This is called a Progressive Web App, or [PWA](../pwa.md).)
Want to try it out? Want to try it out?
Visit https://elk.zone, type in your Mastodon server address, then log in. Visit https://elk.zone, type in your Mastodon server address, then log in.
@ -50,7 +55,7 @@ Using a client, you can
- View, add, or participate in polls - View, add, or participate in polls
- Follow, unfollow, mute, and block accounts - Follow, unfollow, mute, and block accounts
::alert{type="info"} ::callout{type="info"}
**Note:** Not all clients provide all features. **Note:** Not all clients provide all features.
:: ::

View file

@ -1,6 +1,11 @@
---
title: Features
description: Discover the features that make Elk a delightful Mastodon client.
---
# Features # Features
::alert{type=warning} ::callout{type=warning}
🚧 This section is a work in progress. 🚧 🚧 This section is a work in progress. 🚧
:: ::
@ -23,7 +28,7 @@ Elk renders basic Markdown-like text markup in post texts as the expected HTML.
- Use one asterisk (`*`) before and after a word or phrase to *italicize** the text. - Use one asterisk (`*`) before and after a word or phrase to *italicize** the text.
- Surround the text with two asterisks (`**word**`) to **bold** it. - Surround the text with two asterisks (`**word**`) to **bold** it.
::alert{type="warning"} ::callout{type="warning"}
Many apps do not support Markdown in posts. Many apps do not support Markdown in posts.
Mastodon itself does not support Markdown in posts. Mastodon itself does not support Markdown in posts.

View file

@ -1,3 +1,8 @@
---
title: Contributing
description: Learn how to contribute to Elk and help build the future of Mastodon clients.
---
# Contributing # Contributing
We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide. We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide.

View file

@ -1,3 +1,8 @@
---
title: Sponsoring
description: Support the development of Elk by sponsoring the team.
---
# Sponsoring # Sponsoring
If you're enjoying the app, consider sponsoring our team: If you're enjoying the app, consider sponsoring our team:

View file

@ -1,4 +1,7 @@
# Netlify and Cloudflare ---
title: Netlify and Cloudflare
description: Deploy your own Elk instance.
---
Want to host Elk for your Mastodon instance? You came to the right place! Want to host Elk for your Mastodon instance? You came to the right place!

View file

@ -1,3 +1,8 @@
---
title: Progressive Web App
description: Learn about Elk's PWA capabilities and how to install it on your device.
---
# PWA # PWA
Elk provides a PWA (Progressive Web App) that can be installed on your desktop/device. This allows you to use Elk as a native app on your device, and it will work offline. Elk provides a PWA (Progressive Web App) that can be installed on your desktop/device. This allows you to use Elk as a native app on your device, and it will work offline.

View file

@ -1,3 +1,8 @@
---
title: Privacy Policy
description: Elk's privacy policy and data handling practices.
---
# Privacy # Privacy
> Last updated January 27, 2023 > Last updated January 27, 2023
@ -8,7 +13,7 @@ This privacy notice for Elk describes how we handle your information when you:
- Download and use our mobile or desktop application (Elk) - Download and use our mobile or desktop application (Elk)
::alert{type=warning} ::callout{type="warning"}
Elk is [open source](https://github.com/elk-zone/elk) and other websites that link to this privacy notice may not be affiliated with Elk or bound by this policy. Elk is [open source](https://github.com/elk-zone/elk) and other websites that link to this privacy notice may not be affiliated with Elk or bound by this policy.
:: ::

158
docs/content/index.md Executable file
View file

@ -0,0 +1,158 @@
---
seo:
title: "Elk - A Nimble Mastodon Web Client"
description: A nimble Mastodon web client that provides a fresh and intuitive social media experience with modern features and elegant design.
ogImage: https://docs.elk.zone/elk-screenshot.png
---
::u-page-hero
---
orientation: horizontal
---
:::div{.hidden.lg:flex.items-center.justify-center}
![Elk Screenshot](/screenshot.png){.rounded-lg.shadow-lg}
:::
#title
A Nimble [Mastodon Web Client]{.text-primary}
#description
Experience Mastodon like never before. Elk brings you a fresh, intuitive interface with modern features that make social networking delightful.
#links
:::u-button
---
icon: i-ph-rocket-launch-duotone
size: xl
to: /guide
---
Read the docs
:::
:::u-button
---
icon: i-ph-arrow-square-out-duotone
size: xl
variant: outline
to: https://elk.zone
target: _blank
---
Try it live
:::
::
::u-page-section
#title
Everything you need for the perfect [Mastodon experience]{.text-primary}
#features
:::u-page-card
---
spotlight: true
icon: i-ph-markdown-logo-duotone
to: /guide/features
---
#title
Rich Content Support
#description
Full Markdown support with syntax highlighting, emoji reactions, and rich media previews that bring your posts to life.
:::
:::u-page-card
---
spotlight: true
icon: i-ic-twotone-view-timeline
to: /guide/features
---
#title
Smart Timeline Management
#description
Reorder and connect posts in your timeline with intelligent grouping and enhanced notification management.
:::
:::u-page-card
---
spotlight: true
icon: i-ph-users-duotone
to: /guide/features
---
#title
Multi-Account Support
#description
Seamlessly manage multiple Mastodon accounts with quick switching and unified notifications.
:::
:::u-page-card
---
spotlight: true
icon: i-ph-github-logo-duotone
to: /guide/features
---
#title
GitHub Integration
#description
Beautiful HTML cards for GitHub links with repository previews and rich metadata display.
:::
:::u-page-card
---
spotlight: true
icon: i-ph-device-mobile-duotone
to: /pwa
---
#title
Progressive Web App
#description
Install Elk on any device for a native-like experience with offline support and push notifications.
:::
:::u-page-card
---
spotlight: true
icon: i-ph-heart-duotone
to: /guide/contributing
---
#title
Open Source & Community Driven
#description
Built with love by the community. Contribute to the future of federated social media.
:::
::
::u-page-section
---
orientation: horizontal
---
#title
Ready to dive in?
#description
Join thousands of users who have already discovered a better way to experience Mastodon. Get started in minutes with our comprehensive documentation.
#links
:::u-button
---
icon: i-ph-book-open-duotone
size: xl
to: /guide
---
Read the docs
:::
:::u-button
---
icon: i-ph-github-logo-duotone
size: xl
variant: outline
to: https://github.com/elk-zone/elk
target: _blank
---
View on GitHub
:::
::

View file

@ -1,5 +1,17 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
extends: '@nuxt-themes/docus', extends: ['docus'],
css: ['~/assets/css/main.css'],
site: {
name: 'Elk',
url: 'https://docs.elk.zone',
},
llms: {
domain: 'https://docs.elk.zone',
},
vite: { vite: {
optimizeDeps: { optimizeDeps: {

View file

@ -3,16 +3,14 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "nuxi dev", "dev": "nuxt dev",
"build": "nuxi build", "build": "nuxt build",
"generate": "nuxi generate", "generate": "nuxt generate",
"preview": "nuxi preview" "preview": "nuxt preview"
}, },
"dependencies": { "dependencies": {
"theme-colors": "^0.1.0" "better-sqlite3": "^12.4.1",
}, "docus": "^4.0.0",
"devDependencies": { "nuxt": "^4.1.2"
"@nuxt-themes/docus": "^1.15.1",
"nuxt": "^3.18.1"
} }
} }

View file

@ -1,17 +0,0 @@
import { defineTheme } from 'pinceau'
import { getColors } from 'theme-colors'
const light = getColors('#995e1b')
const primary = Object
.entries(getColors('#d98018'))
.reduce((acc, [key, value]) => {
acc[key] = {
initial: light[key]!,
dark: value,
}
return acc
}, {} as Record<string | number, { initial: string, dark: string }>)
export default defineTheme({
color: { primary },
})

View file

@ -1,5 +1,5 @@
import type { BuildInfo } from '#shared/types' import type { BuildInfo } from '../shared/types'
import { createResolver, defineNuxtModule } from '@nuxt/kit' import { createResolver, defineNuxtModule } from 'nuxt/kit'
import { isCI } from 'std-env' import { isCI } from 'std-env'
import { getEnv, version } from '../config/env' import { getEnv, version } from '../config/env'

View file

@ -1,5 +1,5 @@
import { lstat } from 'node:fs' import { lstat } from 'node:fs'
import { createResolver, defineNuxtModule } from '@nuxt/kit' import { createResolver, defineNuxtModule } from 'nuxt/kit'
import { currentLocales } from '../config/i18n' import { currentLocales } from '../config/i18n'
const virtual = 'virtual:emoji-mart-lang-importer' const virtual = 'virtual:emoji-mart-lang-importer'

View file

@ -1,5 +1,5 @@
import { addVitePlugin, defineNuxtModule } from '@nuxt/kit'
import MagicString from 'magic-string' import MagicString from 'magic-string'
import { addVitePlugin, defineNuxtModule } from 'nuxt/kit'
export default defineNuxtModule({ export default defineNuxtModule({
meta: { meta: {

View file

@ -1,7 +1,7 @@
import type { ManifestOptions } from 'vite-plugin-pwa' import type { ManifestOptions } from 'vite-plugin-pwa'
import { Buffer } from 'node:buffer' import { Buffer } from 'node:buffer'
import { readFile } from 'node:fs/promises' import { readFile } from 'node:fs/promises'
import { createResolver } from '@nuxt/kit' import { createResolver } from 'nuxt/kit'
import { THEME_COLORS } from '../../app/constants/index' import { THEME_COLORS } from '../../app/constants/index'
import { getEnv } from '../../config/env' import { getEnv } from '../../config/env'
import { currentLocales } from '../../config/i18n' import { currentLocales } from '../../config/i18n'

View file

@ -6,7 +6,7 @@ import type { VitePWANuxtOptions } from './types'
import { mkdir, readFile, writeFile } from 'node:fs/promises' import { mkdir, readFile, writeFile } from 'node:fs/promises'
import { dirname } from 'node:path' import { dirname } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit' import { addPlugin, createResolver, defineNuxtModule } from 'nuxt/kit'
import { join, resolve } from 'pathe' import { join, resolve } from 'pathe'
import { VitePWA } from 'vite-plugin-pwa' import { VitePWA } from 'vite-plugin-pwa'
import { configurePWAOptions } from './config' import { configurePWAOptions } from './config'

View file

@ -1,6 +1,6 @@
import type { BuildInfo } from './shared/types' import type { BuildInfo } from './shared/types'
import { createResolver, useNuxt } from '@nuxt/kit'
import { resolveModulePath } from 'exsolve' import { resolveModulePath } from 'exsolve'
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 { currentLocales } from './config/i18n' import { currentLocales } from './config/i18n'
@ -11,12 +11,10 @@ const { resolve } = createResolver(import.meta.url)
const mockProxy = resolveModulePath('mocked-exports/proxy', { from: import.meta.url }) const mockProxy = resolveModulePath('mocked-exports/proxy', { from: import.meta.url })
export default defineNuxtConfig({ export default defineNuxtConfig({
compatibilityDate: '2024-09-11', compatibilityDate: '2025-07-11',
future: {
compatibilityVersion: 4,
},
typescript: { typescript: {
tsConfig: { tsConfig: {
include: ['../tests/nuxt'],
exclude: ['../service-worker'], exclude: ['../service-worker'],
compilerOptions: { compilerOptions: {
// TODO: enable this once we fix the issues // TODO: enable this once we fix the issues
@ -37,11 +35,6 @@ export default defineNuxtConfig({
'@unlazy/nuxt', '@unlazy/nuxt',
'@nuxt/test-utils/module', '@nuxt/test-utils/module',
...(isDevelopment || isWindows) ? [] : ['nuxt-security'], ...(isDevelopment || isWindows) ? [] : ['nuxt-security'],
'~~/modules/emoji-mart-translation',
'~~/modules/purge-comments',
'~~/modules/build-env',
'~~/modules/pwa/index', // change to '@vite-pwa/nuxt' once released and remove pwa module
'stale-dep/nuxt',
], ],
vue: { vue: {
propsDestructure: true, propsDestructure: true,
@ -318,48 +311,19 @@ export default defineNuxtConfig({
colorMode: { classSuffix: '' }, colorMode: { classSuffix: '' },
i18n: { i18n: {
locales: currentLocales, locales: currentLocales,
lazy: true,
strategy: 'no_prefix', strategy: 'no_prefix',
detectBrowserLanguage: false, detectBrowserLanguage: false,
// relative to i18n dir on rootDir: not yet v4 compat layout // relative to i18n dir on rootDir: not yet v4 compat layout
langDir: '../locales', langDir: '../locales',
defaultLocale: 'en-US', defaultLocale: 'en-US',
experimental: {
generatedLocaleFilePathFormat: 'relative',
},
vueI18n: '../config/i18n.config.ts', vueI18n: '../config/i18n.config.ts',
bundle: {
optimizeTranslationDirective: false,
},
}, },
pwa, pwa,
staleDep: {
packageManager: 'pnpm',
},
unlazy: { unlazy: {
ssr: false, ssr: false,
}, },
}) })
declare global {
// eslint-disable-next-line ts/no-namespace
namespace NodeJS {
interface Process {
mock?: Record<string, any>
}
}
}
declare module '#app' {
interface PageMeta {
wideLayout?: boolean
}
interface RuntimeNuxtHooks {
'elk-logo:click': () => void
}
}
declare module '@nuxt/schema' { declare module '@nuxt/schema' {
interface AppConfig { interface AppConfig {
storage: any storage: any

View file

@ -7,30 +7,30 @@
"homepage": "https://elk.zone/", "homepage": "https://elk.zone/",
"main": "./nuxt.config.ts", "main": "./nuxt.config.ts",
"scripts": { "scripts": {
"build": "nuxi build", "build": "nuxt build",
"dev": "nuxi dev --port 5314", "dev": "nuxt dev --port 5314",
"dev:pwa": "VITE_DEV_PWA=true nuxi dev --port 5314", "dev:pwa": "VITE_DEV_PWA=true nuxt dev --port 5314",
"dev:mocked": "nuxi dev --port 5314 --dotenv .env.mock", "dev:mocked": "nuxt dev --port 5314 --dotenv .env.mock",
"dev:mocked:pwa": "VITE_DEV_PWA=true nuxi dev --port 5314 --dotenv .env.mock", "dev:mocked:pwa": "VITE_DEV_PWA=true nuxt dev --port 5314 --dotenv .env.mock",
"dev:mocked:pwa:ssl": "VITE_DEV_PWA=true nuxi dev --port 5314 --https --ssl-cert ./https-dev-config/localhost.crt --ssl-key ./https-dev-config/localhost.key --dotenv .env.mock", "dev:mocked:pwa:ssl": "VITE_DEV_PWA=true nuxt dev --port 5314 --https --ssl-cert ./https-dev-config/localhost.crt --ssl-key ./https-dev-config/localhost.key --dotenv .env.mock",
"start": "PORT=5314 node .output/server/index.mjs", "start": "PORT=5314 node .output/server/index.mjs",
"start:https": "PORT=5314 node ./https-dev-config/local-https-server.mjs", "start:https": "PORT=5314 node ./https-dev-config/local-https-server.mjs",
"lint": "eslint --cache .", "lint": "eslint --cache .",
"lint:fix": "eslint --cache --fix .", "lint:fix": "eslint --cache --fix .",
"typecheck": "stale-dep && nuxi typecheck", "typecheck": "nuxt typecheck",
"prepare": "ignore-dependency-scripts \"tsx scripts/prepare.ts\"", "prepare": "node scripts/prepare-translation-status.ts && node scripts/prepare.ts",
"generate": "nuxi generate", "generate": "nuxt generate",
"test:unit": "stale-dep && vitest", "test:unit": "vitest",
"test:unit:ci": "stale-dep && vitest run", "test:unit:ci": "vitest run",
"test:typecheck": "stale-dep && vue-tsc --noEmit && vue-tsc --noEmit --project service-worker/tsconfig.json", "test:typecheck": "vue-tsc -b --noEmit",
"test": "nr test:unit", "test": "vitest",
"test:ci": "nr test:unit:ci", "test:ci": "vitest run",
"update:team:avatars": "tsx scripts/avatars.ts", "update:team:avatars": "node scripts/avatars.ts",
"cleanup-translations": "tsx scripts/cleanup-translations.ts", "cleanup-translations": "node scripts/cleanup-translations.ts",
"prepare-translation-status": "tsx scripts/prepare-translation-status.ts", "prepare-translation-status": "node scripts/prepare-translation-status.ts",
"generate-pwa-icons": "tsx scripts/generate-pwa-icons.ts", "generate-pwa-icons": "node scripts/generate-pwa-icons.ts",
"postinstall": "ignore-dependency-scripts \"stale-dep -u && simple-git-hooks && nuxi prepare && nr prepare-translation-status\"", "postinstall": "simple-git-hooks && nuxt prepare",
"release": "stale-dep && bumpp && tsx scripts/release.ts" "release": "bumpp && node scripts/release.ts"
}, },
"dependencies": { "dependencies": {
"@emoji-mart/data": "^1.1.2", "@emoji-mart/data": "^1.1.2",
@ -38,15 +38,21 @@
"@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.22", "@iconify/utils": "^2.1.22",
"@nuxt/devtools": "^2.4.1", "@intlify/core-base": "^11.1.12",
"@intlify/message-compiler": "^11.1.12",
"@intlify/shared": "^11.1.12",
"@nuxt/devtools": "^2.6.5",
"@nuxt/test-utils": "^3.19.2", "@nuxt/test-utils": "^3.19.2",
"@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/color-mode": "^3.5.2",
"@nuxtjs/i18n": "^9.5.4", "@nuxtjs/i18n": "^10.1.0",
"@pinia/nuxt": "^0.11.0", "@pinia/nuxt": "^0.11.2",
"@tiptap/core": "2.2.4", "@tiptap/core": "2.2.4",
"@tiptap/extension-bold": "2.2.4", "@tiptap/extension-bold": "2.2.4",
"@tiptap/extension-character-count": "2.2.4", "@tiptap/extension-character-count": "2.2.4",
"@tiptap/extension-code": "2.2.4",
"@tiptap/extension-code-block": "2.2.4", "@tiptap/extension-code-block": "2.2.4",
"@tiptap/extension-document": "2.2.4",
"@tiptap/extension-hard-break": "2.2.4",
"@tiptap/extension-history": "2.2.4", "@tiptap/extension-history": "2.2.4",
"@tiptap/extension-italic": "2.2.4", "@tiptap/extension-italic": "2.2.4",
"@tiptap/extension-mention": "2.2.4", "@tiptap/extension-mention": "2.2.4",
@ -57,16 +63,19 @@
"@tiptap/starter-kit": "2.2.4", "@tiptap/starter-kit": "2.2.4",
"@tiptap/suggestion": "2.2.4", "@tiptap/suggestion": "2.2.4",
"@tiptap/vue-3": "2.2.4", "@tiptap/vue-3": "2.2.4",
"@unocss/nuxt": "^66.1.2", "@unhead/schema": "^2.0.17",
"@unlazy/nuxt": "^0.12.4",
"@unocss/nuxt": "^66.5.2",
"@upstash/redis": "^1.27.1", "@upstash/redis": "^1.27.1",
"@vercel/kv": "^3.0.0", "@vercel/kv": "^3.0.0",
"@vue-macros/nuxt": "^1.11.12", "@vue-macros/nuxt": "^1.13.5",
"@vueuse/core": "^12.0.0", "@vueuse/core": "^12.0.0",
"@vueuse/gesture": "^2.0.0", "@vueuse/gesture": "^2.0.0",
"@vueuse/integrations": "^12.0.0", "@vueuse/integrations": "^12.0.0",
"@vueuse/math": "^12.0.0", "@vueuse/math": "^12.0.0",
"@vueuse/motion": "2.2.6", "@vueuse/motion": "2.2.6",
"@vueuse/nuxt": "^13.2.0", "@vueuse/nuxt": "^13.9.0",
"@vueuse/shared": "^13.9.0",
"blurhash": "^2.0.5", "blurhash": "^2.0.5",
"browser-fs-access": "^0.38.0", "browser-fs-access": "^0.38.0",
"cheerio": "^1.0.0", "cheerio": "^1.0.0",
@ -81,23 +90,25 @@
"github-reserved-names": "^2.0.4", "github-reserved-names": "^2.0.4",
"happy-dom": "^16.0.0", "happy-dom": "^16.0.0",
"idb-keyval": "^6.2.1", "idb-keyval": "^6.2.1",
"ignore-dependency-scripts": "^1.0.1",
"iso-639-1": "^3.0.0", "iso-639-1": "^3.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"lru-cache": "^11.0.0", "lru-cache": "^11.0.0",
"magic-string": "^0.30.19",
"masto": "^6.10.4", "masto": "^6.10.4",
"mocked-exports": "^0.1.1", "mocked-exports": "^0.1.1",
"node-emoji": "^2.1.3", "node-emoji": "^2.1.3",
"nuxt-security": "^2.2.0", "nuxt": "^4.1.2",
"nuxt-security": "^2.4.0",
"page-lifecycle": "^0.1.2", "page-lifecycle": "^0.1.2",
"pinia": "^3.0.2", "pathe": "^2.0.3",
"pinia": "^3.0.3",
"postcss-nested": "^7.0.0", "postcss-nested": "^7.0.0",
"prosemirror-highlight": "^0.13.0", "prosemirror-highlight": "^0.13.0",
"prosemirror-state": "^1.4.3",
"rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-node-polyfills": "^0.2.1",
"shiki": "^1.22.2", "shiki": "^1.22.2",
"simple-git": "^3.19.1", "simple-git": "^3.19.1",
"slimeform": "^0.10.0", "slimeform": "^0.10.0",
"stale-dep": "^0.8.0",
"std-env": "^3.7.0", "std-env": "^3.7.0",
"string-length": "^5.0.1", "string-length": "^5.0.1",
"theme-vitesse": "^0.8.0", "theme-vitesse": "^0.8.0",
@ -106,10 +117,19 @@
"ufo": "^1.5.3", "ufo": "^1.5.3",
"ultrahtml": "^1.5.3", "ultrahtml": "^1.5.3",
"unimport": "^3.10.0", "unimport": "^3.10.0",
"unstorage": "^1.17.1",
"vite": "^7.1.7",
"vite-plugin-pwa": "^0.21.0", "vite-plugin-pwa": "^0.21.0",
"vue": "^3.5.4",
"vue-advanced-cropper": "^2.8.9", "vue-advanced-cropper": "^2.8.9",
"vue-i18n": "^11.1.12",
"vue-virtual-scroller": "2.0.0-beta.8", "vue-virtual-scroller": "2.0.0-beta.8",
"workbox-build": "^7.1.1", "workbox-build": "^7.1.1",
"workbox-cacheable-response": "^7.1.0",
"workbox-expiration": "^7.1.0",
"workbox-precaching": "^7.1.0",
"workbox-routing": "^7.1.0",
"workbox-strategies": "^7.1.0",
"workbox-window": "^7.1.0", "workbox-window": "^7.1.0",
"ws": "^8.15.1" "ws": "^8.15.1"
}, },
@ -123,7 +143,6 @@
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/wicg-file-system-access": "^2023.10.6", "@types/wicg-file-system-access": "^2023.10.6",
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"@unlazy/nuxt": "^0.12.4",
"@unocss/eslint-config": "^66.4.2", "@unocss/eslint-config": "^66.4.2",
"@vue/test-utils": "2.4.6", "@vue/test-utils": "2.4.6",
"bumpp": "^10.2.3", "bumpp": "^10.2.3",
@ -133,21 +152,14 @@
"flat": "^6.0.1", "flat": "^6.0.1",
"fs-extra": "^11.3.1", "fs-extra": "^11.3.1",
"lint-staged": "^16.1.6", "lint-staged": "^16.1.6",
"nuxt": "^3.18.1",
"prettier": "^3.6.2", "prettier": "^3.6.2",
"sharp": "^0.34.3", "sharp": "^0.34.3",
"sharp-ico": "^0.1.5", "sharp-ico": "^0.1.5",
"simple-git-hooks": "^2.13.1", "simple-git-hooks": "^2.13.1",
"tsx": "^4.20.5",
"typescript": "^5.4.4", "typescript": "^5.4.4",
"vitest": "3.2.4", "vitest": "3.2.4",
"vue-tsc": "^2.1.6" "vue-tsc": "^2.1.6"
}, },
"pnpm": {
"patchedDependencies": {
"pinceau": "patches/pinceau.patch"
}
},
"resolutions": { "resolutions": {
"nuxt-component-meta": "0.14.0", "nuxt-component-meta": "0.14.0",
"unstorage": "^1.17.1", "unstorage": "^1.17.1",
@ -155,7 +167,7 @@
"vue": "^3.5.4" "vue": "^3.5.4"
}, },
"simple-git-hooks": { "simple-git-hooks": {
"pre-commit": "pnpm lint-staged" "pre-commit": "npx lint-staged"
}, },
"lint-staged": { "lint-staged": {
"*": "eslint --fix" "*": "eslint --fix"

View file

View file

@ -1,13 +0,0 @@
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 612f1c7908c2e973870be08c6fba1515e6e2b9ca..445a3b0574c5388b624d537fc17cbf4a08973ded 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -115,7 +115,7 @@ interface ModuleHooks {
interface ModuleOptions extends PinceauOptions {
}
-declare module '@vue/runtime-core' {
+declare module 'vue' {
interface ComponentCustomProperties {
$dt: DtFunction;
$pinceau: ComputedRef<string>;

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,21 @@
packages: packages:
- docs - docs
ignoreWorkspaceRootCheck: true
ignoredBuiltDependencies:
- '@parcel/watcher'
- '@tailwindcss/oxide'
- esbuild
- vue-demi
onlyBuiltDependencies:
- better-sqlite3
- sharp
- simple-git-hooks
packageManagerStrict: false
shellEmulator: true
verifyDepsBeforeRun: install

View file

@ -2,7 +2,7 @@ import { writeFile } from 'node:fs/promises'
import fs from 'fs-extra' import fs from 'fs-extra'
import { ofetch } from 'ofetch' import { ofetch } from 'ofetch'
import { join, resolve } from 'pathe' import { join, resolve } from 'pathe'
import { elkTeamMembers } from '../app/composables/about' import { elkTeamMembers } from '../app/composables/about.ts'
const avatarsDir = resolve('./public/avatars/') const avatarsDir = resolve('./public/avatars/')

View file

@ -1,8 +1,8 @@
import { Buffer } from 'node:buffer' import { Buffer } from 'node:buffer'
import { readFile, writeFile } from 'node:fs/promises' import { readFile, writeFile } from 'node:fs/promises'
import { createResolver } from '@nuxt/kit'
import { flatten, unflatten } from 'flat' import { flatten, unflatten } from 'flat'
import { currentLocales } from '../config/i18n' import { createResolver } from 'nuxt/kit'
import { currentLocales } from '../config/i18n.ts'
const resolver = createResolver(import.meta.url) const resolver = createResolver(import.meta.url)

View file

@ -1,4 +1,4 @@
import type { ThemeColors } from '~/composables/settings' import type { ThemeColors } from '../app/composables/settings'
import chroma from 'chroma-js' import chroma from 'chroma-js'
// #cc7d24 -> hcl(67.14,62.19,59.56) // #cc7d24 -> hcl(67.14,62.19,59.56)

View file

@ -1,10 +1,10 @@
import type { ElkTranslationStatus } from '#shared/types/translation-status'
import type { LocaleEntry } from '../docs/types' import type { LocaleEntry } from '../docs/types'
import type { ElkTranslationStatus } from '../shared/types/translation-status'
import { Buffer } from 'node:buffer' import { Buffer } from 'node:buffer'
import { readFile, writeFile } from 'node:fs/promises' import { readFile, writeFile } from 'node:fs/promises'
import { createResolver } from '@nuxt/kit'
import { flatten } from 'flat' import { flatten } from 'flat'
import { countryLocaleVariants, currentLocales } from '../config/i18n' import { createResolver } from 'nuxt/kit'
import { countryLocaleVariants, currentLocales } from '../config/i18n.ts'
export const localeData: [code: string, file: string[], title: string][] export const localeData: [code: string, file: string[], title: string][]
= currentLocales.map((l: any) => [l.code, l.files ? l.files : [l.file!], l.name ?? l.code]) = currentLocales.map((l: any) => [l.code, l.files ? l.files : [l.file!], l.name ?? l.code])

View file

@ -1,7 +1,7 @@
import process from 'node:process' import process from 'node:process'
import fs from 'fs-extra' import fs from 'fs-extra'
import { emojiPrefix, iconifyEmojiPackage } from '../config/emojis' import { emojiPrefix, iconifyEmojiPackage } from '../config/emojis.ts'
import { colorsMap } from './generate-themes' import { colorsMap } from './generate-themes.ts'
const dereference = process.platform === 'win32' ? true : undefined const dereference = process.platform === 'win32' ? true : undefined

View file

@ -1,5 +1,6 @@
{ {
"extends": "../tsconfig.json", "extends": "../.nuxt/tsconfig.app.json",
"noEmit": true,
"compilerOptions": { "compilerOptions": {
"lib": ["ESNext", "WebWorker", "DOM.Iterable"], "lib": ["ESNext", "WebWorker", "DOM.Iterable"],
"types": ["vite/client"] "types": ["vite/client"]

View file

@ -0,0 +1 @@
{"root":["./elk-sw.ts","./notification.ts","./share-target.ts","./types.ts","./web-push-notifications.ts"],"version":"5.9.2"}

View file

@ -1,6 +1,6 @@
/// <reference lib="WebWorker" /> /// <reference lib="WebWorker" />
/// <reference types="vite/client" /> /// <reference types="vite/client" />
import type { PushPayload } from '~~/service-worker/types' import type { PushPayload } from './types'
import { ELK_PAGE_LIFECYCLE_FROZEN } from '../app/constants' import { ELK_PAGE_LIFECYCLE_FROZEN } from '../app/constants'
import { import {
closeDatabaseConnections, closeDatabaseConnections,

View file

@ -1,5 +1,5 @@
import type { RouteLocationRaw } from '#vue-router'
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import type { RouteLocationRaw } from 'vue-router'
import type { MarkNonNullable, Mutable } from './utils' import type { MarkNonNullable, Mutable } from './utils'
export interface AppInfo { export interface AppInfo {
@ -43,8 +43,6 @@ export interface GroupedLikeNotifications {
export type NotificationSlot = GroupedNotifications | GroupedLikeNotifications | mastodon.v1.Notification export type NotificationSlot = GroupedNotifications | GroupedLikeNotifications | mastodon.v1.Notification
export type TranslateFn = ReturnType<typeof useI18n>['t']
export interface DraftItem { export interface DraftItem {
editingStatus?: mastodon.v1.Status editingStatus?: mastodon.v1.Status
initialText?: string initialText?: string

View file

@ -1,3 +1,20 @@
{ {
"extends": "./.nuxt/tsconfig.json" "references": [
{
"path": "./.nuxt/tsconfig.app.json"
},
{
"path": "./.nuxt/tsconfig.server.json"
},
{
"path": "./.nuxt/tsconfig.shared.json"
},
{
"path": "./.nuxt/tsconfig.node.json"
},
{
"path": "./service-worker/tsconfig.json"
}
],
"files": []
} }

View file

@ -1,22 +1,30 @@
import { defineVitestConfig } from '@nuxt/test-utils/config' import { defineVitestProject } from '@nuxt/test-utils/config'
import { isCI } from 'std-env' import { isCI } from 'std-env'
import { defineConfig } from 'vitest/config'
export default defineVitestConfig({ export default defineConfig({
define: { define: {
'process.test': 'true', 'process.test': 'true',
}, },
test: { test: {
reporters: isCI ? ['default', 'hanging-process'] : ['default'], reporters: isCI ? ['default', 'hanging-process'] : ['default'],
setupFiles: [ projects: [
'./tests/setup.ts', await defineVitestProject({
], test: {
environmentOptions: { name: 'nuxt',
nuxt: { setupFiles: [
mock: { './tests/setup.ts',
indexedDb: true, ],
intersectionObserver: true, environmentOptions: {
nuxt: {
mock: {
indexedDb: true,
intersectionObserver: true,
},
},
},
}, },
}, }),
}, ],
}, },
}) })