Skip to content

Commit

Permalink
feat(useStrapi): improve types for v5 and v4 (#445)
Browse files Browse the repository at this point in the history
Co-authored-by: Benjamin Canac <[email protected]>
  • Loading branch information
ChristopheCVB and benjamincanac authored Dec 19, 2024
1 parent 9572f7b commit 8838d55
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 25 deletions.
2 changes: 1 addition & 1 deletion playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineNuxtConfig({
// },

strapi: {
version: 'v3',
version: 'v5',
url: 'http://localhost:1337'
// To enable the devtools, read https://strapi.nuxtjs.org/devtools
// devtools: true
Expand Down
42 changes: 42 additions & 0 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
<h2>Version</h2>
<pre>{{ version }}</pre>

<h2>API</h2>
<button
type="button"
@click="getCollections"
>
Get collections
</button>
<button
type="button"
@click="getUntyped"
>
Get untyped
</button>

<div v-if="user">
<h2>User</h2>
<button
Expand Down Expand Up @@ -52,6 +66,7 @@
</template>

<script lang="ts" setup>
const strapi = useStrapi()
const user = useStrapiUser()
const url = useStrapiUrl()
const version = useStrapiVersion()
Expand All @@ -60,6 +75,33 @@ const { login, logout, getProviderAuthenticationUrl } = useStrapiAuth()
const loading = ref(false)
const form = reactive({ identifier: '', password: '' })
type Collection = {
firstname: string
lastname: string
relation: {
name: string
nestedRelation: {
name: string
arr: Array<{ name: string }>
}
}
}
const getCollections = () => {
return strapi.find<Collection>('collection', {
fields: ['firstname'],
sort: ['lastname:asc', 'firstname'],
populate: 'relation.nestedRelation.arr'
})
}
const getUntyped = () => {
return strapi.find('untyped', {
sort: ['random'],
populate: 'relationRandom'
})
}
const onSubmit = async () => {
loading.value = true
Expand Down
8 changes: 4 additions & 4 deletions src/runtime/composables-v4/useStrapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { Strapi4ResponseSingle, Strapi4RequestParams, Strapi4ResponseMany }
import { useStrapiClient } from '#imports'

interface StrapiV4Client<T> {
find<F = T>(contentType: string, params?: Strapi4RequestParams): Promise<Strapi4ResponseMany<F>>
findOne<F = T>(contentType: string, id?: string | number | Strapi4RequestParams, params?: Strapi4RequestParams): Promise<Strapi4ResponseSingle<F>>
find<F = T>(contentType: string, params?: Strapi4RequestParams<F>): Promise<Strapi4ResponseMany<F>>
findOne<F = T>(contentType: string, id?: string | number | Strapi4RequestParams<F>, params?: Strapi4RequestParams<F>): Promise<Strapi4ResponseSingle<F>>
create<F = T>(contentType: string, data: Partial<F>): Promise<Strapi4ResponseSingle<F>>
update<F = T>(contentType: string, id: string | number | Partial<F>, data?: Partial<F>): Promise<Strapi4ResponseSingle<F>>
delete<F = T>(contentType: string, id?: string | number): Promise<Strapi4ResponseSingle<F>>
Expand All @@ -20,7 +20,7 @@ export const useStrapi = <T>(): StrapiV4Client<T> => {
* @param {Strapi4RequestParams} [params] - Query parameters
* @returns Promise<T>
*/
const find = <T>(contentType: string, params?: Strapi4RequestParams, fetchOptions?: FetchOptions): Promise<Strapi4ResponseMany<T>> => {
const find = <T>(contentType: string, params?: Strapi4RequestParams<T>, fetchOptions?: FetchOptions): Promise<Strapi4ResponseMany<T>> => {
return client(`/${contentType}`, { method: 'GET', params, ...fetchOptions })
}

Expand All @@ -32,7 +32,7 @@ export const useStrapi = <T>(): StrapiV4Client<T> => {
* @param {Strapi4RequestParams} [params] - Query parameters
* @returns Promise<T>
*/
const findOne = <T>(contentType: string, id?: string | number | Strapi4RequestParams, params?: Strapi4RequestParams, fetchOptions?: FetchOptions): Promise<Strapi4ResponseSingle<T>> => {
const findOne = <T>(contentType: string, id?: string | number | Strapi4RequestParams<T>, params?: Strapi4RequestParams<T>, fetchOptions?: FetchOptions): Promise<Strapi4ResponseSingle<T>> => {
if (typeof id === 'object') {
params = id
id = undefined
Expand Down
20 changes: 10 additions & 10 deletions src/runtime/composables-v5/useStrapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { Strapi5ResponseSingle, Strapi5RequestParams, Strapi5ResponseMany }
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>>
find<F = T>(contentType: string, params?: Strapi5RequestParams<F>): Promise<Strapi5ResponseMany<F>>
findOne<F = T>(contentType: string, documentId?: string | Strapi5RequestParams<F>, params?: Strapi5RequestParams<F>): 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>>
Expand All @@ -17,10 +17,10 @@ export const useStrapi = <T>(): StrapiV5Client<T> => {
* Get a list of {content-type} entries
*
* @param {string} contentType - Content type's name pluralized
* @param {Strapi5RequestParams} [params] - Query parameters
* @param {Strapi5RequestParams<T>} [params] - Query parameters
* @returns Promise<T>
*/
const find = <T>(contentType: string, params?: Strapi5RequestParams, fetchOptions?: FetchOptions): Promise<Strapi5ResponseMany<T>> => {
const find = <T>(contentType: string, params?: Strapi5RequestParams<T>, fetchOptions?: FetchOptions): Promise<Strapi5ResponseMany<T>> => {
return client(`/${contentType}`, { method: 'GET', params, ...fetchOptions })
}

Expand All @@ -29,10 +29,10 @@ export const useStrapi = <T>(): StrapiV5Client<T> => {
*
* @param {string} contentType - Content type's name pluralized
* @param {string} documentId - ID of entry
* @param {Strapi5RequestParams} [params] - Query parameters
* @param {Strapi5RequestParams<T>} [params] - Query parameters
* @returns Promise<T>
*/
const findOne = <T>(contentType: string, documentId?: string | Strapi5RequestParams, params?: Strapi5RequestParams, fetchOptions?: FetchOptions): Promise<Strapi5ResponseSingle<T>> => {
const findOne = <T>(contentType: string, documentId?: string | Strapi5RequestParams<T>, params?: Strapi5RequestParams<T>, fetchOptions?: FetchOptions): Promise<Strapi5ResponseSingle<T>> => {
if (typeof documentId === 'object') {
params = documentId
documentId = undefined
Expand All @@ -48,10 +48,10 @@ export const useStrapi = <T>(): StrapiV5Client<T> => {
*
* @param {string} contentType - Content type's name pluralized
* @param {Record<string, any>} data - Form data
* @param {Strapi5RequestParams} [params] - Query parameters
* @param {Strapi5RequestParams<T>} [params] - Query parameters
* @returns Promise<T>
*/
const create = <T>(contentType: string, data: Partial<T>, params: Strapi5RequestParams = {}): Promise<Strapi5ResponseSingle<T>> => {
const create = <T>(contentType: string, data: Partial<T>, params: Strapi5RequestParams<T> = {}): Promise<Strapi5ResponseSingle<T>> => {
return client(`/${contentType}`, { method: 'POST', body: { data }, params })
}

Expand All @@ -61,10 +61,10 @@ export const useStrapi = <T>(): StrapiV5Client<T> => {
* @param {string} contentType - Content type's name pluralized
* @param {string} documentId - ID of entry to be updated
* @param {Record<string, any>} data - Form data
* @param {Strapi5RequestParams} [params] - Query parameters
* @param {Strapi5RequestParams<T>} [params] - Query parameters
* @returns Promise<T>
*/
const update = <T>(contentType: string, documentId: string | Partial<T>, data?: Partial<T>, params: Strapi5RequestParams = {}): Promise<Strapi5ResponseSingle<T>> => {
const update = <T>(contentType: string, documentId: string | Partial<T>, data?: Partial<T>, params: Strapi5RequestParams<T> = {}): Promise<Strapi5ResponseSingle<T>> => {
if (typeof documentId === 'object') {
data = documentId
documentId = undefined
Expand Down
16 changes: 16 additions & 0 deletions src/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,22 @@ export interface StrapiGraphqlVariables {
[variable: string]: unknown
}

export type StrapiRequestParamField<T> = {
[K in keyof T]: T[K] extends object
? never
: K;
}[keyof T]

export type StrapiRequestParamSort<T> = `${Exclude<keyof T, symbol>}${':asc' | ':desc' | ''}`

export type StrapiRequestParamPopulate<T> = {
[K in keyof T]: T[K] extends object
? T[K] extends Array<infer I>
? `${Exclude<K, symbol>}` | `${Exclude<K, symbol>}.${StrapiRequestParamPopulate<I>}`
: `${Exclude<K, symbol>}` | `${Exclude<K, symbol>}.${StrapiRequestParamPopulate<T[K]>}`
: never;
}[keyof T]

export * from './v3'
export * from './v4'
export * from './v5'
10 changes: 5 additions & 5 deletions src/runtime/types/v4.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { StrapiLocale } from '.'
import type { StrapiLocale, StrapiRequestParamField, StrapiRequestParamPopulate, StrapiRequestParamSort } from '.'

export interface Strapi4Error {
error: {
Expand All @@ -21,10 +21,10 @@ export interface PaginationByOffset {
withCount?: boolean
}

export interface Strapi4RequestParams {
fields?: Array<string>
populate?: string | Array<string> | object
sort?: string | Array<string>
export interface Strapi4RequestParams<T> {
fields?: Array<StrapiRequestParamField<T>>
populate?: '*' | StrapiRequestParamPopulate<T> | Array<StrapiRequestParamPopulate<T>>
sort?: StrapiRequestParamSort<T> | Array<StrapiRequestParamSort<T>>
pagination?: PaginationByOffset | PaginationByPage
filters?: Record<string, unknown>
publicationState?: 'live' | 'preview'
Expand Down
10 changes: 5 additions & 5 deletions src/runtime/types/v5.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { MetaResponsePaginationByOffset, MetaResponsePaginationByPage, PaginationByOffset, PaginationByPage, StrapiLocale } from '.'
import type { MetaResponsePaginationByOffset, MetaResponsePaginationByPage, PaginationByOffset, PaginationByPage, StrapiLocale, StrapiRequestParamField, StrapiRequestParamPopulate, StrapiRequestParamSort } from '.'

export interface Strapi5Error {
error: {
Expand All @@ -9,10 +9,10 @@ export interface Strapi5Error {
}
}

export interface Strapi5RequestParams {
fields?: Array<string>
populate?: string | Array<string> | object
sort?: string | Array<string>
export interface Strapi5RequestParams<T> {
fields?: Array<StrapiRequestParamField<T>>
populate?: '*' | StrapiRequestParamPopulate<T> | Array<StrapiRequestParamPopulate<T>>
sort?: StrapiRequestParamSort<T> | Array<StrapiRequestParamSort<T>>
pagination?: PaginationByOffset | PaginationByPage
filters?: Record<string, unknown>
status?: 'published' | 'draft'
Expand Down

0 comments on commit 8838d55

Please sign in to comment.