chore: split frontend building into legacy Vue 2 and Vue 3
- Built the frontend in separate packages until we migrated everything to Vue 3. - Separate logic into two packages controlled by main package.json Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/55432/head
parent
ab551c4c8a
commit
f3383f9f90
@ -0,0 +1,50 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
# This is a simple helper to execute npm COMMANDs in two directories
|
||||||
|
# we need this as we cannot use npm workspaces as they break with 2 versions of vue.
|
||||||
|
|
||||||
|
COMMAND=""
|
||||||
|
FRONTEND="$(dirname $0)/frontend"
|
||||||
|
FRONTEND_LEGACY="$(dirname $0)/frontend-legacy"
|
||||||
|
|
||||||
|
build_command() {
|
||||||
|
if [ "install" = "$1" ] || [ "ci" = "$1" ]; then
|
||||||
|
COMMAND=$@
|
||||||
|
elif [ "run" = "$1" ]; then
|
||||||
|
COMMAND="run --if-present ${@:2}"
|
||||||
|
else
|
||||||
|
COMMAND="run --if-present $@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_parallel() {
|
||||||
|
npx concurrently \
|
||||||
|
"cd \"$FRONTEND\" && npm $COMMAND" \
|
||||||
|
"cd \"$FRONTEND_LEGACY\" && npm $COMMAND"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_sequentially() {
|
||||||
|
echo -e "\e[1;34m>> Running 'npm $COMMAND' for Vue 3 based frontend\e[0m"
|
||||||
|
echo
|
||||||
|
pushd "$FRONTEND"
|
||||||
|
npm $COMMAND
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo -e "\e[1;34m>> Running 'npm $COMMAND' for Vue 2 based frontend\e[0m"
|
||||||
|
echo
|
||||||
|
pushd "$FRONTEND_LEGACY"
|
||||||
|
npm $COMMAND
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [ "--parallel" = "$1" ]; then
|
||||||
|
build_command ${@:2}
|
||||||
|
run_parallel
|
||||||
|
else
|
||||||
|
build_command $@
|
||||||
|
run_sequentially
|
||||||
|
fi
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
version = 1
|
||||||
|
SPDX-PackageName = "nextcloud"
|
||||||
|
SPDX-PackageSupplier = "Nextcloud <info@nextcloud.com>"
|
||||||
|
SPDX-PackageDownloadLocation = "https://github.com/nextcloud/server"
|
||||||
|
|
||||||
|
[[annotations]]
|
||||||
|
path = ["package.json", "package-lock.json", "tsconfig.json"]
|
||||||
|
precedence = "aggregate"
|
||||||
|
SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors"
|
||||||
|
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function getCurrentUser() {
|
||||||
|
return {
|
||||||
|
uid: 'test',
|
||||||
|
displayName: 'Test',
|
||||||
|
isAdmin: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRequestToken() {
|
||||||
|
return 'test-token-1234'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onRequestTokenUpdate() {}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
interceptors: {
|
||||||
|
response: {
|
||||||
|
use: () => {},
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
use: () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get: async () => ({ status: 200, data: {} }),
|
||||||
|
delete: async () => ({ status: 200, data: {} }),
|
||||||
|
post: async () => ({ status: 200, data: {} }),
|
||||||
|
head: async () => ({ status: 200, data: {} }),
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Capabilities } from '../../apps/files/src/types.ts'
|
||||||
|
|
||||||
|
export function getCapabilities(): Capabilities {
|
||||||
|
return {
|
||||||
|
files: {
|
||||||
|
bigfilechunking: true,
|
||||||
|
blacklisted_files: [],
|
||||||
|
forbidden_filename_basenames: [],
|
||||||
|
forbidden_filename_characters: [],
|
||||||
|
forbidden_filename_extensions: [],
|
||||||
|
forbidden_filenames: [],
|
||||||
|
undelete: true,
|
||||||
|
version_deletion: true,
|
||||||
|
version_labeling: true,
|
||||||
|
versioning: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { vi } from 'vitest'
|
||||||
|
|
||||||
|
export const showMessage = vi.fn()
|
||||||
|
export const showSuccess = vi.fn()
|
||||||
|
export const showWarning = vi.fn()
|
||||||
|
export const showInfo = vi.fn()
|
||||||
|
export const showError = vi.fn()
|
||||||
|
export const showUndo = vi.fn()
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function loadState(app: string, key: string, fallback?: any) {
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
export default {}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
export default '<svg>SvgMock</svg>'
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function createClient() {}
|
||||||
|
export function getPatcher() {
|
||||||
|
return {
|
||||||
|
patch: () => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import mime from 'mime'
|
||||||
|
import { basename } from 'node:path'
|
||||||
|
|
||||||
|
class FileSystemEntry {
|
||||||
|
private _isFile: boolean
|
||||||
|
private _fullPath: string
|
||||||
|
|
||||||
|
constructor(isFile: boolean, fullPath: string) {
|
||||||
|
this._isFile = isFile
|
||||||
|
this._fullPath = fullPath
|
||||||
|
}
|
||||||
|
|
||||||
|
get isFile() {
|
||||||
|
return !!this._isFile
|
||||||
|
}
|
||||||
|
|
||||||
|
get isDirectory() {
|
||||||
|
return !this.isFile
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return basename(this._fullPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FileSystemFileEntry extends FileSystemEntry {
|
||||||
|
private _contents: string
|
||||||
|
private _lastModified: number
|
||||||
|
|
||||||
|
constructor(fullPath: string, contents: string, lastModified = Date.now()) {
|
||||||
|
super(true, fullPath)
|
||||||
|
this._contents = contents
|
||||||
|
this._lastModified = lastModified
|
||||||
|
}
|
||||||
|
|
||||||
|
file(success: (file: File) => void) {
|
||||||
|
const lastModified = this._lastModified
|
||||||
|
// Faking the mime by using the file extension
|
||||||
|
const type = mime.getType(this.name) || ''
|
||||||
|
success(new File([this._contents], this.name, { lastModified, type }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FileSystemDirectoryEntry extends FileSystemEntry {
|
||||||
|
private _entries: FileSystemEntry[]
|
||||||
|
|
||||||
|
constructor(fullPath: string, entries: FileSystemEntry[]) {
|
||||||
|
super(false, fullPath)
|
||||||
|
this._entries = entries || []
|
||||||
|
}
|
||||||
|
|
||||||
|
createReader() {
|
||||||
|
let read = false
|
||||||
|
return {
|
||||||
|
readEntries: (success: (entries: FileSystemEntry[]) => void) => {
|
||||||
|
if (read) {
|
||||||
|
return success([])
|
||||||
|
}
|
||||||
|
read = true
|
||||||
|
success(this._entries)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mocks the File API's File class
|
||||||
|
* It will allow us to test the Filesystem API as well as the
|
||||||
|
* File API in the same test suite.
|
||||||
|
*/
|
||||||
|
export class DataTransferItem {
|
||||||
|
private _type: string
|
||||||
|
private _entry: FileSystemEntry
|
||||||
|
|
||||||
|
getAsEntry?: () => FileSystemEntry
|
||||||
|
|
||||||
|
constructor(type = '', entry: FileSystemEntry, isFileSystemAPIAvailable = true) {
|
||||||
|
this._type = type
|
||||||
|
this._entry = entry
|
||||||
|
|
||||||
|
// Only when the Files API is available we are
|
||||||
|
// able to get the entry
|
||||||
|
if (isFileSystemAPIAvailable) {
|
||||||
|
this.getAsEntry = () => this._entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get kind() {
|
||||||
|
return 'file'
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return this._type
|
||||||
|
}
|
||||||
|
|
||||||
|
getAsFile(): File | null {
|
||||||
|
if (this._entry.isFile && this._entry instanceof FileSystemFileEntry) {
|
||||||
|
let file: File | null = null
|
||||||
|
this._entry.file((f) => {
|
||||||
|
file = f
|
||||||
|
})
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
// The browser will return an empty File object if the entry is a directory
|
||||||
|
return new File([], this._entry.name, { type: '' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fileSystemEntryToDataTransferItem(entry: FileSystemEntry, isFileSystemAPIAvailable = true): DataTransferItem {
|
||||||
|
return new DataTransferItem(
|
||||||
|
entry.isFile ? 'text/plain' : 'httpd/unix-directory',
|
||||||
|
entry,
|
||||||
|
isFileSystemAPIAvailable,
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
window.OC = {
|
||||||
|
...window.OC,
|
||||||
|
config: {
|
||||||
|
version: '32.0.0',
|
||||||
|
...(window.OC?.config ?? {}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
window.OCA = { ...window.OCA }
|
||||||
|
window.OCP = { ...window.OCP }
|
||||||
|
|
||||||
|
window._oc_webroot = ''
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
export function setup() {
|
||||||
|
process.env.TZ = 'UTC'
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
import '@testing-library/jest-dom/vitest'
|
||||||
|
import 'core-js/stable/index.js'
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/comments
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/dashboard
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/dav
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/federatedfilesharing
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files_external
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files_reminders
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files_sharing
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files_trashbin
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/files_versions
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/oauth2
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/profile
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/settings
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/sharebymail
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/systemtags
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/theming
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/twofactor_backupcodes
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/updatenotification
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/user_ldap
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/user_status
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/weather_status
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../../apps/workflowengine
|
||||||
@ -0,0 +1 @@
|
|||||||
|
../../core
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { recommendedVue2 } from '@nextcloud/eslint-config'
|
||||||
|
import CypressEslint from 'eslint-plugin-cypress'
|
||||||
|
import { defineConfig } from 'eslint/config'
|
||||||
|
import * as globals from 'globals'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
linterOptions: {
|
||||||
|
reportUnusedDisableDirectives: 'error',
|
||||||
|
reportUnusedInlineConfigs: 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
...recommendedVue2,
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'server/custom-webpack-globals',
|
||||||
|
files: ['**/*.js', '**/*.ts', '**/*.vue'],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
PRODUCTION: 'readonly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'server/scripts-are-cjs',
|
||||||
|
files: [
|
||||||
|
'*.js',
|
||||||
|
'build/**/*.js',
|
||||||
|
'**/core/src/icons.cjs',
|
||||||
|
],
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.es2023,
|
||||||
|
...globals.node,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off',
|
||||||
|
'jsdoc/require-jsdoc': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Cypress setup
|
||||||
|
CypressEslint.configs.recommended,
|
||||||
|
{
|
||||||
|
name: 'server/cypress',
|
||||||
|
files: ['cypress/**', '**/*.cy.*'],
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off',
|
||||||
|
'jsdoc/require-jsdoc': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-unused-expressions': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// customer server ignore files
|
||||||
|
{
|
||||||
|
name: 'server/ignored-files',
|
||||||
|
ignores: [
|
||||||
|
'.devcontainer/',
|
||||||
|
'composer.json',
|
||||||
|
'**/*.php',
|
||||||
|
'3rdparty/',
|
||||||
|
'tests/', // PHP tests
|
||||||
|
'**/js/',
|
||||||
|
'**/l10n/', // all translations (config only ignored in root)
|
||||||
|
'**/vendor/', // different vendors
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,151 @@
|
|||||||
|
{
|
||||||
|
"name": "nextcloud-ui-legacy",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "Nextcloud Server",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"author": "Nextcloud GmbH and Nextcloud contributors",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --node-env production --progress",
|
||||||
|
"dev": "webpack --node-env development --progress",
|
||||||
|
"lint": "eslint --suppressions-location ../eslint-baseline.json --no-error-on-unmatched-pattern ./apps/*/ ./core/",
|
||||||
|
"lint:fix": "eslint --suppressions-location ../eslint-baseline.json --fix --no-error-on-unmatched-pattern ./apps/*/ ./core/",
|
||||||
|
"test": "vitest run",
|
||||||
|
"test:coverage": "vitest run --coverage --reporter=default",
|
||||||
|
"test:update-snapshots": "vitest run --update",
|
||||||
|
"test:watch": "vitest watch",
|
||||||
|
"watch": "webpack --node-env development --progress --watch"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"extends @nextcloud/browserslist-config"
|
||||||
|
],
|
||||||
|
"overrides": {
|
||||||
|
"@vitejs/plugin-vue2": {
|
||||||
|
"vite": "^7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||||
|
"@mdi/js": "^7.4.47",
|
||||||
|
"@mdi/svg": "^7.4.47",
|
||||||
|
"@nextcloud/auth": "^2.5.3",
|
||||||
|
"@nextcloud/axios": "^2.5.2",
|
||||||
|
"@nextcloud/browser-storage": "^0.5.0",
|
||||||
|
"@nextcloud/calendar-availability-vue": "^2.2.10",
|
||||||
|
"@nextcloud/capabilities": "^1.2.0",
|
||||||
|
"@nextcloud/dialogs": "^7.1.0",
|
||||||
|
"@nextcloud/event-bus": "^3.3.2",
|
||||||
|
"@nextcloud/files": "^3.12.0",
|
||||||
|
"@nextcloud/initial-state": "^3.0.0",
|
||||||
|
"@nextcloud/l10n": "^3.4.0",
|
||||||
|
"@nextcloud/logger": "^3.0.2",
|
||||||
|
"@nextcloud/moment": "^1.3.5",
|
||||||
|
"@nextcloud/password-confirmation": "^6.0.1",
|
||||||
|
"@nextcloud/paths": "^2.2.1",
|
||||||
|
"@nextcloud/router": "^3.0.1",
|
||||||
|
"@nextcloud/sharing": "^0.3.0",
|
||||||
|
"@nextcloud/upload": "^1.11.0",
|
||||||
|
"@nextcloud/vue": "^8.31.0",
|
||||||
|
"@simplewebauthn/browser": "^13.2.2",
|
||||||
|
"@vue/web-component-wrapper": "^1.3.0",
|
||||||
|
"@vueuse/components": "^11.3.0",
|
||||||
|
"@vueuse/core": "^11.3.0",
|
||||||
|
"@vueuse/integrations": "^11.3.0",
|
||||||
|
"backbone": "^1.6.1",
|
||||||
|
"blurhash": "^2.0.5",
|
||||||
|
"browserslist-useragent-regexp": "^4.1.3",
|
||||||
|
"camelcase": "^8.0.0",
|
||||||
|
"cancelable-promise": "^4.3.1",
|
||||||
|
"clipboard": "^2.0.11",
|
||||||
|
"color": "^5.0.2",
|
||||||
|
"core-js": "^3.45.0",
|
||||||
|
"crypto-browserify": "^3.12.1",
|
||||||
|
"davclient.js": "nextcloud-deps/davclient.js#59d7777d7fe290c5f1fd74a58e7eb529b63e153d",
|
||||||
|
"debounce": "^2.2.0",
|
||||||
|
"dompurify": "^3.2.7",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"focus-trap": "^7.6.5",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"is-svg": "^6.1.0",
|
||||||
|
"jquery": "~3.7",
|
||||||
|
"jquery-ui": "1.14.1",
|
||||||
|
"jquery-ui-dist": "^1.13.3",
|
||||||
|
"libphonenumber-js": "^1.12.23",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"marked": "^16.3.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
|
"moment-timezone": "^0.6.0",
|
||||||
|
"p-limit": "^7.1.1",
|
||||||
|
"p-queue": "^8.1.0",
|
||||||
|
"path": "^0.12.7",
|
||||||
|
"pinia": "^2.3.1",
|
||||||
|
"query-string": "^9.3.1",
|
||||||
|
"regenerator-runtime": "^0.14.1",
|
||||||
|
"select2": "3.5.1",
|
||||||
|
"snap.js": "^2.0.9",
|
||||||
|
"strengthify": "github:nextcloud/strengthify#0.5.9",
|
||||||
|
"throttle-debounce": "^5.0.2",
|
||||||
|
"underscore": "1.13.7",
|
||||||
|
"url-search-params-polyfill": "^8.2.5",
|
||||||
|
"v-click-outside": "^3.2.0",
|
||||||
|
"v-tooltip": "^2.1.3",
|
||||||
|
"vue": "^2.7.16",
|
||||||
|
"vue-click-outside": "^1.1.0",
|
||||||
|
"vue-cropperjs": "^4.2.0",
|
||||||
|
"vue-frag": "^1.4.3",
|
||||||
|
"vue-infinite-loading": "^2.4.5",
|
||||||
|
"vue-localstorage": "^0.6.2",
|
||||||
|
"vue-material-design-icons": "^5.3.1",
|
||||||
|
"vue-router": "^3.6.5",
|
||||||
|
"vuedraggable": "^2.24.3",
|
||||||
|
"vuex": "^3.6.2",
|
||||||
|
"vuex-router-sync": "^5.0.0",
|
||||||
|
"webdav": "^5.8.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/node": "^7.28.0",
|
||||||
|
"@babel/plugin-transform-private-methods": "^7.27.1",
|
||||||
|
"@babel/preset-typescript": "^7.27.1",
|
||||||
|
"@codecov/webpack-plugin": "^1.9.1",
|
||||||
|
"@nextcloud/babel-config": "^1.2.0",
|
||||||
|
"@nextcloud/typings": "^1.9.1",
|
||||||
|
"@nextcloud/webpack-vue-config": "^6.3.0",
|
||||||
|
"@pinia/testing": "^0.1.7",
|
||||||
|
"@testing-library/jest-dom": "^6.6.4",
|
||||||
|
"@testing-library/user-event": "^14.6.1",
|
||||||
|
"@testing-library/vue": "^5.8.3",
|
||||||
|
"@types/dockerode": "^3.3.44",
|
||||||
|
"@types/wait-on": "^5.3.4",
|
||||||
|
"@vitejs/plugin-vue2": "^2.3.3",
|
||||||
|
"@vitest/coverage-v8": "^3.2.4",
|
||||||
|
"@vue/test-utils": "^1.3.5",
|
||||||
|
"@vue/tsconfig": "~0.5.1",
|
||||||
|
"@zip.js/zip.js": "^2.8.2",
|
||||||
|
"babel-loader-exclude-node-modules-except": "^1.2.1",
|
||||||
|
"babel-plugin-module-resolver": "^5.0.2",
|
||||||
|
"colord": "^2.9.3",
|
||||||
|
"exports-loader": "^5.0.0",
|
||||||
|
"file-loader": "^6.2.0",
|
||||||
|
"handlebars-loader": "^1.7.3",
|
||||||
|
"mime": "^4.1.0",
|
||||||
|
"msw": "^2.11.3",
|
||||||
|
"raw-loader": "^4.0.2",
|
||||||
|
"regextras": "^0.8.0",
|
||||||
|
"sass": "^1.93.2",
|
||||||
|
"sinon": "<= 5.0.7",
|
||||||
|
"typescript": "^5.9.2",
|
||||||
|
"vite": "^7.1.8",
|
||||||
|
"vitest": "^3.2.4",
|
||||||
|
"vue-loader": "^15.11.1",
|
||||||
|
"vue-template-compiler": "^2.7.16",
|
||||||
|
"wait-on": "^8.0.4",
|
||||||
|
"webpack": "^5.102.0",
|
||||||
|
"webpack-cli": "^6.0.1",
|
||||||
|
"webpack-merge": "^6.0.1",
|
||||||
|
"workbox-webpack-plugin": "^7.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^22.0.0",
|
||||||
|
"npm": "^10.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.json",
|
||||||
|
"include": ["./apps/**/*.ts", "./apps/**/*.vue", "./core/**/*.ts", "./core/**/*.vue", "./*.d.ts"],
|
||||||
|
"exclude": ["./**/*.cy.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["DOM", "ESNext"],
|
||||||
|
"types": ["node", "vue", "vue-router"],
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
// Set module resolution to bundler and `noEmit` to be able to set `allowImportingTsExtensions`, so we can import Typescript with .ts extension
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true,
|
||||||
|
// Allow ts to import js files
|
||||||
|
"allowJs": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"declaration": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"strict": true,
|
||||||
|
},
|
||||||
|
"vueCompilerOptions": {
|
||||||
|
"target": 2.7
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
// these options are overrides used only by ts-node
|
||||||
|
// same as our --compilerOptions flag and our TS_NODE_COMPILER_OPTIONS environment variable
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "commonjs",
|
||||||
|
"verbatimModuleSyntax": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import vue from '@vitejs/plugin-vue2'
|
||||||
|
import { exec } from 'node:child_process'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { promisify } from 'node:util'
|
||||||
|
import { defaultExclude, defineConfig } from 'vitest/config'
|
||||||
|
|
||||||
|
const gitIgnore: string[] = []
|
||||||
|
// get all files ignored in the apps directory (e.g. if putting `view` app there).
|
||||||
|
try {
|
||||||
|
const execAsync = promisify(exec)
|
||||||
|
const { stdout } = await execAsync('git check-ignore apps/*', { cwd: __dirname })
|
||||||
|
gitIgnore.push(...stdout.split('\n').filter(Boolean))
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Git ignored files excluded from tests: ', gitIgnore)
|
||||||
|
} catch (error) {
|
||||||
|
// we can ignore error code 1 as this just means there are no ignored files
|
||||||
|
if (error && (typeof error !== 'object' || !('code' in error && error.code === 1))) {
|
||||||
|
// but otherwise something bad is happening and we should re-throw
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
root: import.meta.dirname,
|
||||||
|
resolve: {
|
||||||
|
preserveSymlinks: true,
|
||||||
|
alias: {
|
||||||
|
vue$: resolve(__dirname, './node_modules/vue/dist/vue.js'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
include: ['./{apps,core}/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
||||||
|
environment: 'jsdom',
|
||||||
|
environmentOptions: {
|
||||||
|
jsdom: {
|
||||||
|
url: 'http://nextcloud.local',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
coverage: {
|
||||||
|
include: ['./apps/*/src/**', 'core/src/**'],
|
||||||
|
exclude: ['**.spec.*', '**.test.*', '**.cy.*', 'core/src/tests/**'],
|
||||||
|
provider: 'v8',
|
||||||
|
reporter: ['lcov', 'text'],
|
||||||
|
},
|
||||||
|
setupFiles: [
|
||||||
|
'./__tests__/mock-window.js',
|
||||||
|
'./__tests__/setup-testing-library.js',
|
||||||
|
],
|
||||||
|
exclude: [
|
||||||
|
...defaultExclude,
|
||||||
|
...gitIgnore,
|
||||||
|
],
|
||||||
|
globalSetup: './__tests__/setup-global.js',
|
||||||
|
server: {
|
||||||
|
deps: {
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
version = 1
|
||||||
|
SPDX-PackageName = "nextcloud"
|
||||||
|
SPDX-PackageSupplier = "Nextcloud <info@nextcloud.com>"
|
||||||
|
SPDX-PackageDownloadLocation = "https://github.com/nextcloud/server"
|
||||||
|
|
||||||
|
[[annotations]]
|
||||||
|
path = ["package.json", "package-lock.json", "tsconfig.json"]
|
||||||
|
precedence = "aggregate"
|
||||||
|
SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors"
|
||||||
|
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "nextcloud-ui",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "Nextcloud Server Vue 3 UI",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"author": "Nextcloud GmbH and Nextcloud contributors",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "vite build",
|
||||||
|
"dev": "NODE_ENV=development vite build --mode development",
|
||||||
|
"lint": "eslint --suppressions-location ../eslint-baseline.json --no-error-on-unmatched-pattern ./apps/*/ ./core/",
|
||||||
|
"lint:fix": "eslint --suppressions-location ../eslint-baseline.json --fix --no-error-on-unmatched-pattern ./apps/*/ ./core/",
|
||||||
|
"test": "vitest run --passWithNoTests",
|
||||||
|
"test:coverage": "vitest run --passWithNoTests --coverage --reporter=default",
|
||||||
|
"test:update-snapshots": "vitest run --update",
|
||||||
|
"test:watch": "vitest watch",
|
||||||
|
"watch": "NODE_ENV=development vite build --mode development --watch"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"extends @nextcloud/browserslist-config"
|
||||||
|
],
|
||||||
|
"devDependencies": {
|
||||||
|
"@nextcloud/vite-config": "^2.5.2",
|
||||||
|
"vite": "npm:rolldown-vite@^7.1.19"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^22.0.0",
|
||||||
|
"npm": "^10.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"include": ["./apps", "./core"]
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*!
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { createAppConfig } from '@nextcloud/vite-config'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
|
||||||
|
export default createAppConfig({
|
||||||
|
}, {
|
||||||
|
emptyOutputDirectory: {
|
||||||
|
additionalDirectories: [resolve(import.meta.dirname, '../..', 'dist')],
|
||||||
|
},
|
||||||
|
extractLicenseInformation: {
|
||||||
|
includeSourceMaps: true,
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
root: resolve(import.meta.dirname, '../..'),
|
||||||
|
resolve: {
|
||||||
|
preserveSymlinks: true,
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'dist',
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames({ facadeModuleId }) {
|
||||||
|
const [, appId] = facadeModuleId!.match(/apps\/([^/]+)\//)!
|
||||||
|
return `${appId}-[name].mjs`
|
||||||
|
},
|
||||||
|
chunkFileNames: '[name]-[hash].chunk.mjs',
|
||||||
|
assetFileNames({ originalFileNames }) {
|
||||||
|
const [name] = originalFileNames
|
||||||
|
if (name) {
|
||||||
|
const [, appId] = name.match(/apps\/([^/]+)\//)!
|
||||||
|
return `${appId}-[name]-[hash][extname]`
|
||||||
|
}
|
||||||
|
return '[name]-[hash][extname]'
|
||||||
|
},
|
||||||
|
/* advancedChunks: {
|
||||||
|
groups: [{ name: 'common', test: /[\\/]node_modules[\\/]/ }],
|
||||||
|
// only include modules in the groups if they are used at least by 3 different chunks
|
||||||
|
minShareCount: 3,
|
||||||
|
// only include modules in the groups if they are smaller than 200kb on its own
|
||||||
|
maxModuleSize: 200 * 1024,
|
||||||
|
// define the groups output size (not too small but also not too big!)
|
||||||
|
minSize: 50 * 1024,
|
||||||
|
maxSize: 500 * 1024,
|
||||||
|
}, */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// stub - for the moment see build/frontend/vite.config.ts
|
||||||
|
export default {}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// temporary see build/frontend/vitest.config.mts
|
||||||
Loading…
Reference in New Issue