diff --git a/.eslintrc.js b/.eslintrc.js index 07b9f932..3d146345 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,6 @@ module.exports = { root: true, env: { - browser: true, node: true }, extends: [ @@ -9,11 +8,9 @@ module.exports = { 'plugin:jsdoc/recommended', 'plugin:json/recommended', 'plugin:@typescript-eslint/recommended', - '@nuxtjs/eslint-config-typescript', 'prettier', 'plugin:prettier/recommended', 'plugin:promise/recommended', - 'plugin:nuxt/recommended', 'plugin:import/errors', 'plugin:import/warnings', 'plugin:import/typescript' @@ -31,28 +28,6 @@ module.exports = { '@typescript-eslint/prefer-ts-expect-error': 'error', 'prefer-arrow-callback': 'error', curly: 'error', - // Force some component order stuff, formatting and such, for consistency - 'vue/component-name-in-template-casing': [ - 'error', - 'kebab-case', - { - ignores: [] - } - ], - 'vue/order-in-components': 'error', - 'vue/v-bind-style': 'error', - 'vue/v-on-style': 'error', - 'vue/v-slot-style': 'error', - 'vue/attributes-order': 'error', - 'vue/html-self-closing': [ - 'error', - { - html: { - void: 'always' - } - } - ], - 'vue/multiline-html-element-content-newline': 'error', 'padding-line-between-statements': [ 'error', // Always require blank lines after directives (like 'use-strict'), except between directives @@ -93,14 +68,60 @@ module.exports = { ], 'lodash/import-scope': ['error', 'method'] }, - settings: { - 'import/resolver': { - nuxt: { - extensions: ['.js', '.ts', '.vue', '.json'] - } - } - }, overrides: [ + { + files: ['client/**/*'], + env: { + browser: true, + node: true + }, + extends: [ + 'eslint:recommended', + 'plugin:jsdoc/recommended', + 'plugin:json/recommended', + 'plugin:@typescript-eslint/recommended', + '@nuxtjs/eslint-config-typescript', + 'prettier', + 'plugin:prettier/recommended', + 'plugin:promise/recommended', + 'plugin:nuxt/recommended', + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript' + ], + rules: { + // Force some component order stuff, formatting and such, for consistency + 'vue/component-name-in-template-casing': [ + 'error', + 'kebab-case', + { + ignores: [] + } + ], + 'vue/order-in-components': 'error', + 'vue/v-bind-style': 'error', + 'vue/v-on-style': 'error', + 'vue/v-slot-style': 'error', + 'vue/attributes-order': 'error', + 'vue/html-self-closing': [ + 'error', + { + html: { + void: 'always' + } + } + ], + 'vue/multiline-html-element-content-newline': 'error' + }, + settings: { + 'import/resolver': { + nuxt: { + extensions: ['.js', '.ts', '.vue', '.json'], + nuxtSrcDir: 'client/' + } + } + } + }, { files: ['**/*.spec.ts'], plugins: ['jest', 'jest-formatting'], diff --git a/.github/labeler.yml b/.github/labeler.yml index 1de495b8..df7dfac6 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,20 +1,25 @@ tests: - - "**/*.spec.js" + - '**/*.spec.js' github_actions: - - ".github/workflows/*" + - '.github/workflows/*' vuex: - - "store/**/*.ts" + - 'client/store/**/*.ts' plugins: - - "plugins/**/*.ts" + - 'client/plugins/**/*.ts' vue: - - "**/*.vue" + - '**/*.vue' docker: - - "Dockerfile*" + - 'Dockerfile*' ui: - - any: ["components/**/*.vue", "layouts/**/*.vue", "pages/**/*.vue"] + - any: + [ + 'client/components/**/*.vue', + 'client/layouts/**/*.vue', + 'client/pages/**/*.vue' + ] diff --git a/.github/workflows/Dockerfile.nginx b/.github/workflows/Dockerfile.nginx index 1f474a7a..51734734 100644 --- a/.github/workflows/Dockerfile.nginx +++ b/.github/workflows/Dockerfile.nginx @@ -6,6 +6,6 @@ FROM nginx:alpine LABEL maintainer="Jellyfin Packaging Team - packaging@jellyfin.org" LABEL org.opencontainers.image.source="https://github.com/jellyfin/jellyfin-vue" -COPY dist/ /usr/share/nginx/html/ +COPY client/dist/ /usr/share/nginx/html/ COPY .docker/nginx.conf /etc/nginx/conf.d/default.conf COPY .docker/mime.types /etc/nginx/mime.types diff --git a/.github/workflows/Dockerfile.ssr b/.github/workflows/Dockerfile.ssr index 44d30d48..e0505c82 100644 --- a/.github/workflows/Dockerfile.ssr +++ b/.github/workflows/Dockerfile.ssr @@ -7,8 +7,8 @@ LABEL maintainer="Jellyfin Packaging Team - packaging@jellyfin.org" LABEL org.opencontainers.image.source="https://github.com/jellyfin/jellyfin-vue" COPY .docker/package.json .docker/package-lock.json ./.docker/nuxt.config.js ./ -COPY .nuxt ./.nuxt -COPY static ./static +COPY client/.nuxt ./.nuxt +COPY client/static ./static # Install runtime dependencies RUN npm ci --production --no-audit diff --git a/.vscode/settings.json b/.vscode/settings.json index 5d0b55fa..fea56447 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,11 @@ { "editor.formatOnSave": true, "i18n-ally.keystyle": "nested", - "i18n-ally.localesPaths": "locales", "i18n-ally.sortKeys": true, "vetur.format.defaultFormatter.html": "prettier", "i18n-ally.sourceLanguage": "en-US", - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode", + "i18n-ally.localesPaths": [ + "client/locales" + ] } diff --git a/Dockerfile b/Dockerfile index ccd698b0..a17c882f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,8 +23,8 @@ WORKDIR /app COPY .docker/package.json .docker/package-lock.json .docker/nuxt.config.js ./ # Copy client files from the build image -COPY --from=build /app/.nuxt ./.nuxt -COPY --from=build /app/static ./static +COPY --from=build /app/client/.nuxt ./.nuxt +COPY --from=build /app/client/static ./static # Install runtime dependencies RUN npm ci --production --no-audit diff --git a/Dockerfile.static b/Dockerfile.static index 7566b0ec..0f84cfe7 100644 --- a/Dockerfile.static +++ b/Dockerfile.static @@ -19,6 +19,6 @@ RUN npm run build:static # Deploy built distribution to nginx FROM nginx:alpine -COPY --from=build /app/dist/ /usr/share/nginx/html/ +COPY --from=build /app/client/dist/ /usr/share/nginx/html/ COPY .docker/nginx.conf /etc/nginx/conf.d/default.conf COPY .docker/mime.types /etc/nginx/mime.types diff --git a/jest-helpers.d.ts b/client/jest-helpers.d.ts similarity index 100% rename from jest-helpers.d.ts rename to client/jest-helpers.d.ts diff --git a/client/jest.config.js b/client/jest.config.js new file mode 100644 index 00000000..85cac95b --- /dev/null +++ b/client/jest.config.js @@ -0,0 +1,26 @@ +module.exports = { + moduleNameMapper: { + '^@/(.*)$': '/$1', + '^~/(.*)$': '/$1' + }, + moduleFileExtensions: ['ts', 'js', 'vue', 'json'], + transform: { + '^.+\\.ts$': 'ts-jest', + '^.+\\.js$': 'babel-jest', + '.*\\.(vue)$': 'vue-jest' + }, + collectCoverageFrom: [ + '/components/**/*.vue', + '/layouts/**/*.vue', + '/middleware/**/*.vue', + '/middleware/**/*.ts', + '/mixins/**/*.vue', + '/mixins/**/*.ts', + '/pages/**/*.vue', + '/plugins/**/*.ts', + '/schemes/**/*.ts', + '/store/**/*.ts', + '/utils/**/*.ts' + ], + setupFiles: ['jest-canvas-mock', './jest.setup.ts'] +}; diff --git a/jest.setup.ts b/client/jest.setup.ts similarity index 100% rename from jest.setup.ts rename to client/jest.setup.ts diff --git a/nuxt-i18n.d.ts b/client/nuxt-i18n.d.ts similarity index 100% rename from nuxt-i18n.d.ts rename to client/nuxt-i18n.d.ts diff --git a/nuxt.config.ts b/client/nuxt.config.ts similarity index 98% rename from nuxt.config.ts rename to client/nuxt.config.ts index 7d8bf7e1..fbd83a68 100644 --- a/nuxt.config.ts +++ b/client/nuxt.config.ts @@ -23,11 +23,6 @@ const config: NuxtConfig = { ** See https://nuxtjs.org/api/configuration-modern */ modern: 'client', - /** - * Source directory - * See https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-srcdir/ - */ - srcDir: 'client/', /* ** Progress bar between routes ** See https://nuxtjs.org/api/configuration-loading diff --git a/client/pages/settings/index.vue b/client/pages/settings/index.vue index 0f1ab54e..651fad6c 100644 --- a/client/pages/settings/index.vue +++ b/client/pages/settings/index.vue @@ -128,7 +128,7 @@ import Vue from 'vue'; import { mapActions } from 'vuex'; import isEmpty from 'lodash/isEmpty'; import { SystemInfo } from '@jellyfin/client-axios'; -import { version } from '~/package.json'; +import { version } from '../../../package.json'; import htmlHelper from '~/mixins/htmlHelper'; export default Vue.extend({ diff --git a/client/store/deviceProfile.ts b/client/store/deviceProfile.ts index be07443d..8ca94b4b 100644 --- a/client/store/deviceProfile.ts +++ b/client/store/deviceProfile.ts @@ -1,7 +1,7 @@ import { ActionTree, MutationTree } from 'vuex'; import { v4 as uuidv4 } from 'uuid'; +import { version } from '../../package.json'; import { browserDetector } from '~/plugins/browserDetection'; -import { version } from '~/package.json'; export interface DeviceState { deviceId: string; diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 00000000..7eac7509 --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "ESNext", + "moduleResolution": "Node", + "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"], + "esModuleInterop": true, + "resolveJsonModule": true, + "allowJs": true, + "sourceMap": true, + "strict": true, + "noEmit": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "~/*": ["./*"], + "@/*": ["./*"] + }, + "types": [ + "@types/node", + "@nuxt/types", + "@types/nuxtjs__auth", + "@nuxtjs/axios", + "@nuxtjs/vuetify", + "@nuxtjs/date-fns", + "nuxt-i18n", + "@types/wicg-mediasession", + "jest" + ] + } +} diff --git a/client/utils/__tests__/items.spec.ts b/client/utils/__tests__/items.spec.ts index c451dd33..04f3bc39 100644 --- a/client/utils/__tests__/items.spec.ts +++ b/client/utils/__tests__/items.spec.ts @@ -2,7 +2,7 @@ import { getShapeFromCollectionType, getShapeFromItemType, getLibraryIcon -} from '../items'; +} from '~/utils/items'; describe('getLibraryIcon', () => { it('returns the correct library icon based on library type', () => { diff --git a/vue-shims.d.ts b/client/vue-shims.d.ts similarity index 100% rename from vue-shims.d.ts rename to client/vue-shims.d.ts diff --git a/jest.config.js b/jest.config.js index c3a8ea0b..bd07781c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,29 +1,6 @@ module.exports = { - moduleNameMapper: { - '^@/(.*)$': '/$1', - '^~/(.*)$': '/$1' - }, - moduleFileExtensions: ['ts', 'js', 'vue', 'json'], - transform: { - '^.+\\.ts$': 'ts-jest', - '^.+\\.js$': 'babel-jest', - '.*\\.(vue)$': 'vue-jest' - }, collectCoverage: true, - collectCoverageFrom: [ - '/components/**/*.vue', - '/layouts/**/*.vue', - '/middleware/**/*.vue', - '/middleware/**/*.ts', - '/mixins/**/*.vue', - '/mixins/**/*.ts', - '/pages/**/*.vue', - '/plugins/**/*.ts', - '/schemes/**/*.ts', - '/store/**/*.ts', - '/utils/**/*.ts' - ], - testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', - setupFiles: ['jest-canvas-mock', './jest.setup.ts'], - coverageReporters: ['text', 'cobertura', 'html', 'lcov'] + coverageReporters: ['text', 'cobertura', 'html', 'lcov'], + projects: ['/client/jest.config.js'], + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$' }; diff --git a/package.json b/package.json index 323097e9..c8831ce6 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,16 @@ "version": "0.0.0", "private": true, "scripts": { - "dev": "NUXT_SSR=1 nuxt", - "dev:static": "nuxt", - "build": "NUXT_SSR=1 nuxt build", - "build:standalone": "NUXT_SSR=1 nuxt build --standalone", - "build:static": "nuxt build", - "prod": "npm run build && npm run start", - "prod:static": "npm run build:static && npm run start:static", - "start": "NUXT_SSR=1 nuxt start", - "start:static": "nuxt start", - "generate": "nuxt generate", + "dev": "NUXT_SSR=1 nuxt client", + "dev:static": "nuxt client", + "build": "NUXT_SSR=1 nuxt build client", + "build:standalone": "NUXT_SSR=1 nuxt build --standalone client", + "build:static": "nuxt build client", + "prod": "npm run build client && npm run start client", + "prod:static": "npm run build:static client && npm run start:static client", + "start": "NUXT_SSR=1 nuxt start client", + "start:static": "nuxt start client", + "generate": "nuxt generate client", "lint:js": "eslint --ext .ts,.js,.json,.vue .", "lint:style": "stylelint **/*.{vue,css} --ignore-path .gitignore", "lint": "npm run lint:js && npm run lint:style", diff --git a/tsconfig.json b/tsconfig.json index e49b6fbe..622ea1a4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,30 +3,11 @@ "target": "ES2018", "module": "ESNext", "moduleResolution": "Node", - "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"], - "esModuleInterop": true, - "resolveJsonModule": true, - "allowJs": true, - "sourceMap": true, + "lib": ["ESNext", "ESNext.AsyncIterable"], "strict": true, "noEmit": true, - "experimentalDecorators": true, "baseUrl": ".", - "paths": { - "~/*": ["./*"], - "@/*": ["./*"] - }, - "types": [ - "@types/node", - "@nuxt/types", - "@types/nuxtjs__auth", - "@nuxtjs/axios", - "@nuxtjs/vuetify", - "@nuxtjs/date-fns", - "nuxt-i18n", - "@types/wicg-mediasession", - "jest" - ] + "types": ["@types/node"] }, - "exclude": ["node_modules", ".nuxt", "dist"] + "exclude": ["node_modules"] } diff --git a/vetur.config.js b/vetur.config.js new file mode 100644 index 00000000..7c474684 --- /dev/null +++ b/vetur.config.js @@ -0,0 +1,10 @@ +// vetur.config.js +/** @type {import('vls').VeturConfig} */ +module.exports = { + projects: [ + { + root: './client', + package: '../package.json' + } + ] +};