Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: typescript typings and example #486

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/guide/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,24 @@ auth: {
::: warning IMPORTANT
When adding `auth-module` to a new Nuxt project ensure you have activated the Vuex store. More information on how to do that can be found on the [Nuxt Getting Started Guide](https://nuxtjs.org/guide/vuex-store).
:::


### Typescript setup

Add the types to your "types" array in tsconfig.json after the `@nuxt/types` entry

**tsconfig.json**

```json
{
"compilerOptions": {
"types": [
"@nuxt/types",
"@nuxtjs/auth"
]
}
}
```
> **Why?**
>
> Because of the way nuxt works the `$auth` property on the context has to be merged into the nuxt `Context` interface via [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html). Adding `@nuxtjs/auth` to your types will import the types from the package and make typescript aware of the additions to the `Context` interface.
29 changes: 16 additions & 13 deletions examples/demo/pages/login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,34 @@ export default {
async login() {
this.error = null

return this.$auth
.loginWith('local', {
data: {
username: this.username,
password: this.password
}
})
.catch(e => {
this.error = e + ''
})
try {
await this.$auth
.loginWith('local', {
data: {
username: this.username,
password: this.password
}
})

} catch(e) {
this.error = e + ''
}
},

async localRefresh() {
this.error = null

return this.$auth
try {
await this.$auth
.loginWith('localRefresh', {
data: {
username: this.username,
password: this.password
}
})
.catch(e => {
} catch(e) {
this.error = e + ''
})
}
}
}
}
Expand Down
37 changes: 14 additions & 23 deletions examples/with-class-component/mixins/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,12 @@ export default class AuthMixin extends Vue {
async logout () {

this.$toast.show('Logging out...')
await this.$auth.logout().then(() => {
try {
await this.$auth.logout()
this.$toast.success('Successfully disconnected')
}).catch(err => {
} catch(err) {
this.$toast.error('Error while disconnecting: ' + err.message)
})

// If you are not fond of using axios promises on async calls
// You can still use Javascript try and catch block
//
// try {
// this.$toast.show('Logging out...')
// await this.$auth.logout()
// this.$toast.success('Successfully disconnected')
// } catch (err) {
// this.$toast.error('Error while disconnecting: ' + err.message)
// }
}
}

/**
Expand All @@ -47,16 +37,17 @@ export default class AuthMixin extends Vue {
*/
async login() {
this.$toast.show('Log in...')
await this.$auth.login({
data: {
username: this.username,
password: this.password
}
}).then(() => {
try {
await this.$auth.login({
data: {
username: this.username,
password: this.password
}
})
this.$toast.success('Successfully connected')
}).catch(err => {
this.$toast.error('Error while disconnecting: ' + err.message)
} catch(err) {
this.$toast.error('Error while connecting: ' + err.message)
this.loginHasError = true
})
}
}
}
2 changes: 1 addition & 1 deletion examples/with-class-component/pages/secure.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Admin: <b-badge>{{ $auth.hasScope('admin') }}</b-badge>
</b-card>
<b-card title="token">
{{ $auth.token || '-' }}
{{ $auth.token.get() || '-' }}
</b-card>
</b-col>
</b-row>
Expand Down
46 changes: 46 additions & 0 deletions examples/with-typescript/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<template>
<div>
<b-navbar toggleable="md" variant="light">
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
<b-navbar-brand to="/">Nuxt.js</b-navbar-brand>

<b-collapse is-nav id="nav_collapse">
<b-navbar-nav>
<b-nav-item to="/" exact>Home</b-nav-item>
<b-nav-item to="/public">Public</b-nav-item>
<b-nav-item to="/secure">Secure</b-nav-item>
</b-navbar-nav>
<b-navbar-nav class="ml-auto">
<template v-if="$auth.$state.loggedIn">
<b-nav-item-dropdown :text="$auth.$state.user.username" right>
<b-dropdown-item @click="this.logout">Logout</b-dropdown-item>
</b-nav-item-dropdown>
</template>
<template v-else>
<b-dropdown-item to="/login">Login</b-dropdown-item>
</template>
</b-navbar-nav>
</b-collapse>
</b-navbar>
<b-container class="mt-4">
<nuxt />
</b-container>
</div>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "nuxt-class-component";
import AuthMixin from "../mixins/auth";

// Utilize declaration merging to type the Default class with the mixin types
export interface Default extends AuthMixin {}

@Component({
mixins: [AuthMixin]
})
export class Default extends Vue {}

// Can't declaration merge a default export, so export it seperately
export default Default;
</script>
59 changes: 59 additions & 0 deletions examples/with-typescript/mixins/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Vue from 'vue'
import Component from 'nuxt-class-component'

export default interface AuthMixin {
username: string;
password: string;
}

@Component
export default class AuthMixin extends Vue {

/**
* This define if login got an error
* @type {boolean}
*/
loginHasError = false

/**
* Logout method using auth-module with custom post-request
* logic, using toast module to show information, success
* and error messages.
*
* @returns {Promise<void>}
*/
async logout () {

this.$toast.show('Logging out...')
try {
await this.$auth.logout()
this.$toast.success('Successfully disconnected')
} catch(err) {
this.$toast.error('Error while disconnecting: ' + err.message)
}

}

/**
* Login method using auth-module with custom post-request
* logic, using toast module to show information, success
* and error messages.
*
* @returns {Promise<T>}
*/
async login() {
this.$toast.show('Log in...')
try {
await this.$auth.login({
data: {
username: this.username,
password: this.password
}
})
this.$toast.success('Successfully connected')
} catch(err) {
this.$toast.error('Error while connecting: ' + err.message)
this.loginHasError = true
}
}
}
39 changes: 39 additions & 0 deletions examples/with-typescript/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Configuration } from "@nuxt/types";
import { resolve } from "path";

const config: Configuration = {
server: {
host: "0.0.0.0"
},
srcDir: __dirname,
buildDir: resolve(__dirname, ".nuxt"),
dev: false,
render: {
resourceHints: false
},
serverMiddleware: ["../api/auth"],
auth: {
strategies: {
local: {
endpoints: {
login: { propertyName: "token.accessToken" }
}
}
}
},
buildModules: ["@nuxt/typescript-build"],
modules: [
"bootstrap-vue/nuxt", // https://bootstrap-vue.js.org/docs/#nuxt-js
"@nuxtjs/axios",
"@nuxtjs/auth",
"@nuxtjs/toast",
],
axios: {
proxy: true
},
proxy: {
"/api": "http://localhost:3000"
}
};

export default config;
23 changes: 23 additions & 0 deletions examples/with-typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "with-typescript",
"version": "1.0.0",
"description": "",
"scripts": {
"dev": "nuxt-ts",
"build": "nuxt-ts build",
"generate": "nuxt-ts generate",
"start": "nuxt-ts start"
},
"author": "",
"license": "ISC",
"devDependencies": {
NickBolles marked this conversation as resolved.
Show resolved Hide resolved
"@nuxt/types": "^0.6.1",
"@nuxt/typescript-build": "^0.5.6",
"@nuxt/typescript-runtime": "^0.3.8",
"@nuxtjs/auth": "^4.8.4",
"@nuxtjs/axios": "^5.8.0",
"@nuxtjs/toast": "^3.3.0",
"@types/node": "^12.12.11",
"bootstrap-vue": "^2.1.0"
}
}
48 changes: 48 additions & 0 deletions examples/with-typescript/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div>
<b-jumbotron class="text-center">
<h3>Welcome to Nuxt.js auth example</h3>
<div class="mt-1">
<template v-if="$auth.$state.loggedIn">
<b-btn class="ml-3" variant="info" to="/secure">Secure</b-btn>
<b-btn class="ml-3" variant="danger" @click="this.logout">Logout</b-btn>
</template>
<b-btn variant="success" v-else to="/login">Login</b-btn>
</div>
</b-jumbotron>

<div>
User status:
<b-badge>{{ this.loggedInStatus }}</b-badge>
</div>
</div>
</template>

<script lang="ts">
// While you are using nuxt-class-component you should always
// import Vue and its class decorator Component
import Vue from "vue";
import Component from "nuxt-class-component";
import AuthMixin from "~/mixins/auth";

// Utilize declaration merging to type the Default class with the mixin types
export interface Default extends AuthMixin {}

@Component({
mixins: [AuthMixin]
})
export class Index extends Vue {
/**
* Computed string returning login status depending on current
* authentication state from auth-module.
*
* @returns {string}
*/
get loggedInStatus() {
return this.$auth.$state.loggedIn ? "Logged In" : "Guest";
}
}

// Can't declaration merge a default export, so export it seperately
export default Index;
</script>
Loading