Skip to content

Commit

Permalink
Use AuthTokenSection in App (fails with two kinds of TS errors)
Browse files Browse the repository at this point in the history
* package.json: add Nextcloud dependencies (from Nextcloud)
* main.ts: register pinia

  Otherwise the following error would be thrown:

     TypeError: Cannot read properties of undefined (reading '_s')
         at i (pinia.mjs:1714:20)
         at setup (AuthTokenList.vue:11:32)
         at mn (vue.runtime.esm.js:3033:30)
         at vue.runtime.esm.js:2457:27
         ...

* remove .ts suffix from import paths (causes build error otherwise)
* add declare global to define Nextcloud types. This should be changed
  to @nextcloud/typings.
* annotated import of Nextcloud components (JS) with @ts-expect-error
  to solve tsc errors. This is most likely due to missing type
  definitions. Unclear how Nextcloud core made this working.
* the eslint rule set @nextcloud/eslint-config/typescript was added to
  prevent import path errors

The build fails with errors like

   ERROR in /app/src/components/AuthTokenSetup.vue.ts
   47:9-14
   [tsl] ERROR in /app/src/components/AuthTokenSetup.vue.ts(47,10)
         TS2339: Property 'reset' does not exist on type 'CreateComponentPublicInstance<{}, { authTokenStore: Store<"auth-token", { tokens: IToken[]; }, {}, { updateToken(token: IToken): Promise<any>; addToken(name: string): Promise<ITokenResponse | null>; deleteToken(token: IToken): Promise<...>; wipeToken(token: IToken): Promise<...>; renameToken(token: IToken, newName: ...'.

This hints at Typescript not being able to infer types from the
component definition.

Related issues:

* vuejs/vue#9873
* vuejs/vue#12628
* vuejs/vue#8721

Unsuccessfully attempted proposed solutions:

* Declaring return types on methods like:

  reset(): void {
  async submit(): Promise<void> {

* Using arrow functions

  Did not work and would introduce new errors anyway

* Defining interfaces for the returned component

  Caused another rabbit hole of more and more required type
  definitions, that should be infered by the Vue typings anyway
  • Loading branch information
tholewebgods committed Jul 5, 2024
1 parent 2c5dee9 commit aa4524e
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 12 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
extends: [
'@nextcloud',
'@nextcloud/eslint-config/typescript',
],
rules: {
'jsdoc/require-jsdoc': 'off',
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@nextcloud/browserslist-config": "^3.0.1",
"@nextcloud/eslint-config": "^8.3.0",
"@nextcloud/eslint-plugin": "^2.2.1",
"@nextcloud/typings": "^1.8.0",
"@nextcloud/webpack-vue-config": "^6.0.1",
"@typescript-eslint/parser": "^6.18.0",
"@vue/eslint-config-typescript": "^12.0.0",
Expand Down
34 changes: 24 additions & 10 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
<!--
SPDX-FileLicenseText: 2024 Thomas Lehmann <t.lehmann@strato.de>
SPDX-License-Identifier: AGPL-3.0-or-later

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<template>
<NcAppContent>
<div id="simplesettings">
<h1>Hello world!</h1>
</div>
</NcAppContent>
<AuthTokenSection />
</template>

<script lang="ts">
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
import AuthTokenSection from './components/AuthTokenSection.vue'
import { defineComponent } from 'vue'

export default {
export default defineComponent({
name: 'App',
components: {
NcAppContent,
AuthTokenSection,
},
}
})
</script>

<style scoped lang="scss">
Expand Down
27 changes: 26 additions & 1 deletion src/components/AuthToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,41 @@ import type { IToken } from '../store/authtoken'
import { mdiCheck, mdiCellphone, mdiTablet, mdiMonitor, mdiWeb, mdiKey, mdiMicrosoftEdge, mdiFirefox, mdiGoogleChrome, mdiAppleSafari, mdiAndroid, mdiAppleIos } from '@mdi/js'
import { translate as t } from '@nextcloud/l10n'
import { defineComponent } from 'vue'
import { TokenType, useAuthTokenStore } from '../store/authtoken.ts'
import { TokenType, useAuthTokenStore } from '../store/authtoken'

// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcActionCheckbox from '@nextcloud/vue/dist/Components/NcActionCheckbox.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'

declare global {
interface Window {
oc_defaults: {
baseUrl: string;
docBaseUrl: string;
docPlaceholderUrl: string;
entity: string;
folder: string;
logoClaim: string;
name: string;
productName: string;
slogan: string;
syncClientUrl: string;
title: string;
};
}
}

// When using capture groups the following parts are extracted the first is used as the version number, the second as the OS
const userAgentMap = {
ie: /(?:MSIE|Trident|Trident\/7.0; rv)[ :](\d+)/,
Expand Down
2 changes: 2 additions & 0 deletions src/components/AuthTokenSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ import { translate as t } from '@nextcloud/l10n'
import { defineComponent } from 'vue'
import { useAuthTokenStore, type ITokenResponse } from '../store/authtoken'

// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'

import AuthTokenSetupDialog from './AuthTokenSetupDialog.vue'
Expand Down
4 changes: 4 additions & 0 deletions src/components/AuthTokenSetupDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,13 @@ import { getRootUrl } from '@nextcloud/router'
import { defineComponent, type PropType } from 'vue'

import QR from '@chenfengyuan/vue-qrcode'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
// @ts-expect-error: Cannot find module or its corresponding type declarations.
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'

import logger from '../logger'
Expand Down
25 changes: 24 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
/*
* SPDX-FileLicenseText: 2024 Thomas Lehmann <t.lehmann@strato.de>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Vue from 'vue'
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import { PiniaVuePlugin, createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()

Vue.use(PiniaVuePlugin)

Vue.mixin({ methods: { t, n } })

const View = Vue.extend(App)
new View().$mount('#simplesettings')
new View({ pinia }).$mount('#simplesettings')
6 changes: 6 additions & 0 deletions src/store/authtoken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ import { defineStore } from 'pinia'
import axios from '@nextcloud/axios'
import logger from '../logger'

declare global {
// TODO find matching typedef in the @nextcloud/dialogs package
// eslint-disable-next-line @typescript-eslint/no-explicit-any
interface Window { OC: any; }
}

const BASE_URL = generateUrl('/simplesettings/authtokens')

const confirm = () => {
Expand Down

0 comments on commit aa4524e

Please sign in to comment.