Page MenuHomePhorge

No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None
diff --git a/.gitignore b/.gitignore
index c4a96ee1ed..043938f601 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,18 @@
.DS_Store
node_modules/
dist/
npm-debug.log
test/unit/coverage
test/e2e/reports
test/e2e-playwright/test-results
test/e2e-playwright/playwright-report
selenium-debug.log
.idea/
.gitlab-ci-local/
config/local.json
src/assets/emoji.json
logs/
__screenshots__/
+.vitest-attachments/
+html/
+coverage/
diff --git a/package.json b/package.json
index d0a1419ab6..f8bacaf154 100644
--- a/package.json
+++ b/package.json
@@ -1,131 +1,131 @@
{
"name": "pleroma_fe",
"version": "2.11.1",
"description": "Pleroma frontend, the default frontend of Pleroma social network server",
"author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/src/CONTRIBUTORS.md>",
"private": false,
"scripts": {
"dev": "node build/update-emoji.js && vite dev",
"build": "node build/update-emoji.js && vite build",
"unit": "node build/update-emoji.js && vitest --run --coverage",
"unit-ci": "node build/update-emoji.js && vitest --run --coverage --browser.headless",
- "unit:watch": "node build/update-emoji.js && vitest",
+ "unit:watch": "node build/update-emoji.js && vitest --coverage",
"e2e:pw": "playwright test --config test/e2e-playwright/playwright.config.mjs",
"e2e": "sh ./tools/e2e/run.sh",
"test": "yarn run unit && yarn run e2e",
"ci-biome": "yarn exec biome check",
"ci-eslint": "yarn exec eslint",
"ci-stylelint": "yarn exec stylelint '**/*.scss' '**/*.vue'",
"lint": "yarn ci-biome; yarn ci-eslint; yarn ci-stylelint",
"lint-fix": "yarn exec eslint -- --fix; yarn exec stylelint '**/*.scss' '**/*.vue' --fix; biome check --write"
},
"dependencies": {
"@babel/runtime": "7.28.4",
"@chenfengyuan/vue-qrcode": "2.0.0",
"@fortawesome/fontawesome-svg-core": "7.1.0",
"@fortawesome/free-regular-svg-icons": "7.1.0",
"@fortawesome/free-solid-svg-icons": "7.1.0",
"@fortawesome/vue-fontawesome": "3.1.2",
"@kazvmoe-infra/pinch-zoom-element": "1.3.0",
"@kazvmoe-infra/unicode-emoji-json": "0.4.0",
"@ruffle-rs/ruffle": "0.1.0-nightly.2025.6.22",
"@vuelidate/core": "2.0.3",
"@vuelidate/validators": "2.0.4",
"@web3-storage/parse-link-header": "^3.1.0",
"body-scroll-lock": "3.1.5",
"chromatism": "3.0.0",
"click-outside-vue3": "4.0.1",
"cropperjs": "2.0.1",
"escape-html": "1.0.3",
"globals": "^16.0.0",
"hash-sum": "^2.0.0",
"js-cookie": "3.0.5",
"localforage": "1.10.0",
"parse-link-header": "2.0.0",
"phoenix": "1.8.1",
"pinia": "^3.0.4",
"punycode.js": "2.3.1",
"qrcode": "1.5.4",
"querystring-es3": "0.2.1",
"url": "0.11.4",
"utf8": "3.0.0",
"uuid": "11.1.0",
"vue": "3.5.22",
"vue-i18n": "11",
"vue-router": "4.6.4",
"vue-virtual-scroller": "^2.0.0-beta.7",
"vuex": "4.1.0"
},
"devDependencies": {
"@babel/core": "7.28.5",
"@babel/eslint-parser": "7.28.5",
"@babel/plugin-transform-runtime": "7.28.5",
"@babel/preset-env": "7.28.5",
"@babel/register": "7.28.3",
"@biomejs/biome": "2.3.11",
"@pinia/testing": "1.0.3",
"@ungap/event-target": "0.2.4",
"@vitejs/devtools": "^0.3.1",
"@vitejs/plugin-vue": "^6.0.7",
"@vitejs/plugin-vue-jsx": "^5.1.5",
"@vitest/browser": "^4.1.7",
"@vitest/browser-playwright": "^4.1.7",
"@vitest/coverage-v8": "^4.1.10",
"@vitest/ui": "^4.1.7",
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
"@vue/babel-plugin-jsx": "1.5.0",
"@vue/compiler-sfc": "3.5.22",
"@vue/test-utils": "2.4.6",
"autoprefixer": "10.4.21",
"babel-plugin-lodash": "3.3.4",
"chai": "5.3.3",
"chalk": "5.6.2",
"chromedriver": "135.0.4",
"connect-history-api-fallback": "2.0.0",
"cross-spawn": "7.0.6",
"custom-event-polyfill": "1.0.7",
"eslint": "9.39.2",
"eslint-config-standard": "17.1.0",
"eslint-formatter-friendly": "7.0.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-n": "17.23.1",
"eslint-plugin-promise": "7.2.1",
"eslint-plugin-vue": "10.6.2",
"eventsource-polyfill": "0.9.6",
"express": "5.1.0",
"function-bind": "1.1.2",
"http-proxy-middleware": "3.0.5",
"iso-639-1": "3.1.5",
"lodash": "4.17.21",
"msw": "2.14.6",
"nightwatch": "3.12.2",
"oxc": "^1.0.1",
"playwright": "1.61.0",
"postcss": "8.5.6",
"postcss-html": "^1.5.0",
"postcss-scss": "^4.0.6",
"sass-embedded": "^1.100.0",
"selenium-server": "3.141.59",
"semver": "7.7.3",
"serve-static": "2.2.0",
"shelljs": "0.10.0",
"sinon": "20.0.0",
"sinon-chai": "4.0.1",
"stylelint": "16.25.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^16.0.0",
"stylelint-config-recommended-scss": "^14.0.0",
"stylelint-config-recommended-vue": "^1.6.0",
"stylelint-config-standard": "38.0.0",
"vite": "^8.0.0",
"vite-plugin-eslint2": "^5.1.0",
"vite-plugin-stylelint": "^6.1.0",
"vitest": "^4.1.7",
"vue-eslint-parser": "10.2.0"
},
"type": "module",
"engines": {
"node": ">= 16.0.0"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
diff --git a/vite.config.js b/vite.config.js
index 445faeb240..0ba2c7d315 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,257 +1,257 @@
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { playwright } from '@vitest/browser-playwright'
import { defineConfig } from 'vite'
import eslint from 'vite-plugin-eslint2'
import stylelint from 'vite-plugin-stylelint'
import { configDefaults } from 'vitest/config'
import { getCommitHash } from './build/commit_hash.js'
import copyPlugin from './build/copy_plugin.js'
import emojisPlugin from './build/emojis_plugin.js'
import mswPlugin from './build/msw_plugin.js'
import { buildSwPlugin, swMessagesPlugin } from './build/sw_plugin.js'
const localConfigPath = '<projectRoot>/config/local.json'
const normalizeTarget = (target) => {
if (!target || typeof target !== 'string') return target
return target.endsWith('/') ? target.replace(/\/$/, '') : target
}
const getLocalDevSettings = async () => {
const envTarget = normalizeTarget(process.env.VITE_PROXY_TARGET)
const envOrigin = normalizeTarget(process.env.VITE_PROXY_ORIGIN)
try {
const settings = (await import('./config/local.json')).default
settings.target = normalizeTarget(settings.target)
settings.origin = normalizeTarget(settings.origin)
if (envTarget) settings.target = envTarget
if (envOrigin) settings.origin = envOrigin
console.info(`Using local dev server settings (${localConfigPath}):`)
console.info(JSON.stringify(settings, null, 2))
return settings
} catch (e) {
if (!envTarget && !envOrigin) {
console.info(
`Local dev server settings not found (${localConfigPath}), using default`,
e,
)
return {}
}
const settings = { target: envTarget, origin: envOrigin }
console.info(
'Using dev server settings from VITE_PROXY_TARGET/VITE_PROXY_ORIGIN:',
)
console.info(JSON.stringify(settings, null, 2))
return settings
}
}
const projectRoot = dirname(fileURLToPath(import.meta.url))
const getTransformSWSettings = (settings) => {
if ('transformSW' in settings) {
return settings.transformSW
} else {
console.info(
'`transformSW` is not present in your local settings.\n' +
'This option controls whether the service worker should be bundled and transformed into iife (immediately-invoked function expression) during development.\n' +
'If set to false, the service worker will be served as-is, as an ES Module.\n' +
'Some browsers (e.g. Firefox) does not support ESM service workers.\n' +
'To avoid surprises, it is defaulted to true, but this can be slow.\n' +
'If you are using a browser that supports ESM service workers, you can set this option to false.\n' +
`No matter your choice, you can set the transformSW option in ${localConfigPath} in to disable this message.`,
)
return true
}
}
export default defineConfig(async ({ mode, command }) => {
const settings = await getLocalDevSettings()
const target = settings.target || 'http://localhost:4000/'
const origin = settings.origin || target
const targetSW = target.replace(/^http/, 'ws')
const transformSW = getTransformSWSettings(settings)
const proxy = {
'/api': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true,
rewriteWsOrigin: true,
},
'/auth': {
// Mastodon password reset lives here
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true,
},
'/nodeinfo': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
'/instance': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
'/oauth': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
'/socket': {
target: targetSW,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
rewriteWsOrigin: true,
ws: true,
headers: {
Origin: origin,
},
},
}
const swSrc = 'src/sw.js'
const swDest = 'sw-pleroma.js'
const alias = {
src: '/src',
components: '/src/components',
...(mode === 'test' ? { vue: 'vue/dist/vue.esm-bundler.js' } : {}),
}
return {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement(tag) {
if (tag === 'pinch-zoom') {
return true
}
if (tag.startsWith('cropper-')) {
return true
}
return false
},
},
},
}),
vueJsx(),
buildSwPlugin({ swSrc, swDest }),
swMessagesPlugin(),
emojisPlugin(),
copyPlugin({
inUrl: '/static/ruffle',
inFs: resolve(projectRoot, 'node_modules/@ruffle-rs/ruffle'),
}),
eslint({
lintInWorker: true,
lintOnStart: true,
cacheLocation: resolve(projectRoot, 'node_modules/.cache/eslintcache'),
}),
stylelint({
lintInWorker: true,
lintOnStart: true,
cacheLocation: resolve(
projectRoot,
'node_modules/.cache/stylelintcache',
),
}),
...(mode === 'test' ? [mswPlugin()] : []),
],
css: {
devSourcemap: true,
},
resolve: {
alias,
},
define: {
'process.env': JSON.stringify({
NODE_ENV:
mode === 'test'
? 'testing'
: command === 'serve'
? 'development'
: 'production',
HAS_MODULE_SERVICE_WORKER: command === 'serve' && !transformSW,
}),
COMMIT_HASH: JSON.stringify(
command === 'serve' ? 'DEV' : getCommitHash(),
),
DEV_OVERRIDES: JSON.stringify(command === 'serve' ? settings : undefined),
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
},
// devtools: { enabled: true },
build: {
sourcemap: true,
rolldownOptions: {
input: {
main: 'index.html',
},
output: {
entryFileNames(chunkInfo) {
const id = chunkInfo.facadeModuleId
if (id.endsWith(swSrc)) {
return swDest
} else {
return 'static/js/[name].[hash].js'
}
},
chunkFileNames(chunkInfo) {
if (chunkInfo.facadeModuleId) {
if (
chunkInfo.facadeModuleId.includes(
'node_modules/@kazvmoe-infra/unicode-emoji-json/annotations/',
)
) {
return 'static/js/emoji-annotations/[name].[hash].js'
} else if (chunkInfo.facadeModuleId.includes('src/i18n/')) {
return 'static/js/i18n/[name].[hash].js'
}
}
return 'static/js/[name].[hash].js'
},
assetFileNames(assetInfo) {
const name = assetInfo.names?.[0] || ''
if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(name)) {
return 'static/img/[name].[hash][extname]'
} else if (/\.css$/.test(name)) {
return 'static/css/[name].[hash][extname]'
} else {
return 'static/misc/[name].[hash][extname]'
}
},
},
},
},
server: {
...(mode === 'test' ? {} : { proxy }),
port: Number(process.env.PORT) || 8080,
},
preview: {
proxy,
},
test: {
globals: true,
exclude: [...configDefaults.exclude, 'test/e2e-playwright/**'],
coverage: {
provider: 'v8',
exclude: ['**/*.style.js', 'public/**'],
},
browser: {
enabled: true,
- headless: true,
+ headless: false,
provider: playwright(),
// https://github.com/mswjs/msw/issues/2757
instances: [{ browser: 'chromium' }],
},
},
}
})

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 10, 5:31 PM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785374
Default Alt Text
(13 KB)

Event Timeline