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

Typescript support #61

Closed
ampirzadeh opened this issue Oct 16, 2020 · 5 comments · Fixed by #94
Closed

Typescript support #61

ampirzadeh opened this issue Oct 16, 2020 · 5 comments · Fixed by #94
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@ampirzadeh
Copy link

What is Expected: No Error

What is happening

I wanted to use this module with nuxt, typescript and vue composition api but there are no type declarations for it, so I started writing my own, But still there is an error telling me that there is no $strapi on context when I want to use $strapi in a middleware.
The exact error:
{
"resource": "/project/middleware/auth.ts",
"owner": "typescript",
"code": "2339",
"severity": 8,
"message": "Property '$strapi' does not exist on type 'Context'.",
"source": "ts",
"startLineNumber": 4,
"startColumn": 29,
"endLineNumber": 4,
"endColumn": 36
}

I want to be able to use this module in a nuxt-typescript project without errors.

What I think would fix the error

I think rewriting the module in typescript or just providing @types folder would fix the issue.
I myself would be interested in helping.

My code

import { Middleware } from '@nuxt/types'

const auth: Middleware = ({ $strapi, redirect, route }) => {
  if (!$strapi.user) {
    return redirect(`/login?next=${route.path}`)
  }
}

export default auth
@ampirzadeh ampirzadeh added the enhancement New feature or request label Oct 16, 2020
@ampirzadeh ampirzadeh reopened this Oct 16, 2020
@benjamincanac
Copy link
Member

@ampirzadeh A PR with the types would be more than welcome!

@benjamincanac benjamincanac added the help wanted Extra attention is needed label Oct 20, 2020
@austinbakker
Copy link

austinbakker commented Oct 24, 2020

You can add typescript support manually,
You still need to add strapi to modules in nuxt.config.js but this is a solution that works without to much work. Hope this helps.

// ~/plugins/strapi.ts
// not used directly but needed for typescript support
import { Plugin } from '@nuxt/types'


interface Strapi  {
  find(collection:string, params?:object) : Promise<any>;
  findone(collection:string, id:number) : Promise<any>;
  create(collection:string, data:object) : Promise<any>;
  count(collection:string, params?:object) : Promise<any>;
  update(collection:string, id:number, data:object) : Promise<any>;
  delete(collection:string, id:number) : Promise<any>;
}

declare module 'vue/types/vue' {
  // this.$myInjectedFunction inside Vue components
  interface Vue {
    $strapi: Strapi
  }
}

declare module '@nuxt/types' {
  // nuxtContext.app.$myInjectedFunction inside asyncData, fetch, plugins, middleware, nuxtServerInit
  interface NuxtAppOptions {
    $strapi: Strapi
  }
  // nuxtContext.$myInjectedFunction
  interface Context {
    $strapi: Strapi
  }
}

declare module 'vuex/types/index' {
  // this.$myInjectedFunction inside Vuex stores
  interface Store<S> {
    $strapi: Strapi
  }
}

@luixal
Copy link

luixal commented Nov 1, 2020

Tried @austinbakker solution, but I keep getting the Property '$stripe' does not exists on type 'CombinedVueInstance.... :(

@austinbakker
Copy link

@ luxial did you try restarting you editor (mind need to wait a minute for everything to load) || Have you added the plugin to the nuxt.config.js file? And what does your tsconfig.json looklike.

@luixal
Copy link

luixal commented Nov 2, 2020

Hi @austinbakker , yesterday I made a quick tryout and notice that I was using this.$strapi.centers.find(), when looking at your code (I only copy&paste directly) it's obsvious that's not going to work. When I changed it to this.$strapi.find('centers') it work straight forward.

Another thing missing was the login function. I added it to your code like this:

login(params?:object) : Promise<any>;

Login works great when added that.

Right now, I'm only getting this error (maybe related to using SSR tried with a new SPA nuxt app and the error keeps popping up, same happens when using a javascript nuxt app):

 ERROR  [Vue warn]: Error in created hook (Promise/async): "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client"                                                   10:27:48

found in

---> <Pages/index.vue> at pages/index.vue
       <Nuxt>
         <Layouts/default.vue> at layouts/default.vue
           <Root>


 ERROR  Cannot set headers after they are sent to the client                                                                                                                                       10:27:48

  at ServerResponse.setHeader (_http_outgoing.js:518:11)
  at p (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1399)
  at Object.set (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1836)
  at Strapi.setToken (server.js:2497:19)
  at Strapi.login (server.js:2389:10)
  at runMicrotasks (<anonymous>)
  at processTicksAndRejections (internal/process/task_queues.js:97:5)
  at VueComponent.created (pages/index.js:90:18)

Any idea about this error?

If someone needs the plugin file with the login function, mine looks like this (only adding that line):

// ~/plugins/strapi.ts
// not used directly but needed for typescript support
import { Plugin } from '@nuxt/types'


interface Strapi  {
  login(params?:object) : Promise<any>;
  find(collection:string, params?:object) : Promise<any>;
  findone(collection:string, id:number) : Promise<any>;
  create(collection:string, data:object) : Promise<any>;
  count(collection:string, params?:object) : Promise<any>;
  update(collection:string, id:number, data:object) : Promise<any>;
  delete(collection:string, id:number) : Promise<any>;
}

declare module 'vue/types/vue' {
  // this.$myInjectedFunction inside Vue components
  interface Vue {
    $strapi: Strapi
  }
}

declare module '@nuxt/types' {
  // nuxtContext.app.$myInjectedFunction inside asyncData, fetch, plugins, middleware, nuxtServerInit
  interface NuxtAppOptions {
    $strapi: Strapi
  }
  // nuxtContext.$myInjectedFunction
  interface Context {
    $strapi: Strapi
  }
}

declare module 'vuex/types/index' {
  // this.$myInjectedFunction inside Vuex stores
  interface Store<S> {
    $strapi: Strapi
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants