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