Skip to content

Commit

Permalink
feat(module): handle v5 (#424)
Browse files Browse the repository at this point in the history
* add basic v5

* update types export

* remove package-lock.json

* add package-lock.json to gitignore

* update v5 types

* add v5 option in version options

* update useStrapi for v5

* remove unneeded check in v5

* fix documentId typos

* up

---------

Co-authored-by: XanderD99 <[email protected]>
Co-authored-by: Benjamin Canac <[email protected]>
  • Loading branch information
3 people authored Sep 26, 2024
1 parent 7740f82 commit b8949e5
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ sw.js
.output
.env
.history

package-lock.json
2 changes: 1 addition & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface ModuleOptions {
* @type string
* @example 'v3'
*/
version?: 'v4' | 'v3'
version?: 'v5' | 'v4' | 'v3'

/**
* Nuxt Cookie Options
Expand Down
97 changes: 97 additions & 0 deletions src/runtime/composables-v5/useStrapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { FetchOptions } from 'ofetch'

import type { Strapi5ResponseSingle, Strapi5RequestParams, Strapi5ResponseMany } from '../types/v5'
import { useStrapiClient } from '#imports'

interface StrapiV5Client<T> {
find<F = T>(contentType: string, params?: Strapi5RequestParams): Promise<Strapi5ResponseMany<F>>
findOne<F = T>(contentType: string, documentId?: string | Strapi5RequestParams, params?: Strapi5RequestParams): Promise<Strapi5ResponseSingle<F>>
create<F = T>(contentType: string, data: Partial<F>): Promise<Strapi5ResponseSingle<F>>
update<F = T>(contentType: string, documentId: string | Partial<F>, data?: Partial<F>): Promise<Strapi5ResponseSingle<F>>
delete<F = T>(contentType: string, documentId?: string): Promise<Strapi5ResponseSingle<F>>
}

export const useStrapi = <T>(): StrapiV5Client<T> => {
const client = useStrapiClient()

/**
* Get a list of {content-type} entries
*
* @param {string} contentType - Content type's name pluralized
* @param {Strapi5RequestParams} [params] - Query parameters
* @returns Promise<T>
*/
const find = <T>(contentType: string, params?: Strapi5RequestParams, fetchOptions?: FetchOptions): Promise<Strapi5ResponseMany<T>> => {
return client(`/${contentType}`, { method: 'GET', params, ...fetchOptions })
}

/**
* Get a specific {content-type} entry
*
* @param {string} contentType - Content type's name pluralized
* @param {string} documentId - ID of entry
* @param {Strapi5RequestParams} [params] - Query parameters
* @returns Promise<T>
*/
const findOne = <T>(contentType: string, documentId?: string | Strapi5RequestParams, params?: Strapi5RequestParams, fetchOptions?: FetchOptions): Promise<Strapi5ResponseSingle<T>> => {
if (typeof documentId === 'object') {
params = documentId
documentId = undefined
}

const path = [contentType, documentId].filter(Boolean).join('/')

return client(path, { method: 'GET', params, ...fetchOptions })
}

/**
* Create a {content-type} entry
*
* @param {string} contentType - Content type's name pluralized
* @param {Record<string, any>} data - Form data
* @returns Promise<T>
*/
const create = <T>(contentType: string, data: Partial<T>): Promise<Strapi5ResponseSingle<T>> => {
return client(`/${contentType}`, { method: 'POST', body: { data } })
}

/**
* Update an entry
*
* @param {string} contentType - Content type's name pluralized
* @param {string} documentId - ID of entry to be updated
* @param {Record<string, any>} data - Form data
* @returns Promise<T>
*/
const update = <T>(contentType: string, documentId: string | Partial<T>, data?: Partial<T>): Promise<Strapi5ResponseSingle<T>> => {
if (typeof documentId === 'object') {
data = documentId
documentId = undefined
}

const path = [contentType, documentId].filter(Boolean).join('/')

return client(path, { method: 'PUT', body: { data } })
}

/**
* Delete an entry
*
* @param {string} contentType - Content type's name pluralized
* @param {string|number} id - ID of entry to be deleted
* @returns Promise<T>
*/
const _delete = <T>(contentType: string, id?: string | number): Promise<T> => {
const path = [contentType, id].filter(Boolean).join('/')

return client(path, { method: 'DELETE' })
}

return {
find,
findOne,
create,
update,
delete: _delete
}
}
1 change: 1 addition & 0 deletions src/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,4 @@ export interface StrapiGraphqlVariables {

export * from './v3'
export * from './v4'
export * from './v5'
42 changes: 42 additions & 0 deletions src/runtime/types/v5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { MetaResponsePaginationByOffset, MetaResponsePaginationByPage, PaginationByOffset, PaginationByPage, StrapiLocale } from '.'

export interface Strapi5Error {
error: {
status: number
name: string
message: string
details: Record<string, unknown>
}
}

export interface Strapi5RequestParams {
fields?: Array<string>
populate?: string | Array<string> | object
sort?: string | Array<string>
pagination?: PaginationByOffset | PaginationByPage
filters?: Record<string, unknown>
publicationState?: 'live' | 'preview'
locale?: StrapiLocale
}

export interface Strapi5SystemFields {
documentId: string
locale?: StrapiLocale
}

export type Strapi5ResponseData<T> = Strapi5SystemFields & T

export interface Strapi5ResponseSingle<T> {
data: Strapi5ResponseData<T>
meta: Strapi5ResponseMeta
}

export interface Strapi5ResponseMany<T> {
data: Strapi5ResponseData<T>[]
meta: Strapi5ResponseMeta
}

export interface Strapi5ResponseMeta {
pagination: MetaResponsePaginationByPage | MetaResponsePaginationByOffset
[key: string]: unknown
}

0 comments on commit b8949e5

Please sign in to comment.