Generating dynamic composables from a module

Hello, I'm trying to create a module for internal company use that will automatically generate server/api routes and corresponding custom useFetch composables to integrate with our internal API's. This is a rough sketch of what I want to accomplish but I'm kinda stuck on how to dynamically generate my composables. The module creation documentation is very sparse and without much experience in building modules I'm at a roadblock right now. Anyone who has done something similar before and can provide some guidance?
import { defineNuxtModule, createResolver, addServerHandler, addTemplate } from '@nuxt/kit'
import { pascalCase } from 'scule'

export interface ApiEndpoint {
url: string
headers?: Record<string, string>
}

export interface ModuleOptions {
endpoints: Record<string, ApiEndpoint>
}

export default defineNuxtModule<ModuleOptions>({
meta: {},
setup(_options, _nuxt) {
const { resolve } = createResolver(import.meta.url)

const getDataComposableName = (endpoint: string) => `use${pascalCase(endpoint)}Fetch`

const endpointKeys = Object.keys(_options.endpoints)

endpointKeys.forEach((key) => {
addServerHandler({
route: `/api/${key}/**`,
handler: resolve('runtime/server/handler'),
})

// Rough idea of what I want to accomplish
addTemplate({
filename: `${getDataComposableName(key)}.ts`,
getContents: () => {
return `
import { useFetch, type UseFetchOptions } from '#app'

export const ${getDataComposableName(key)} = <T>(
url: string | (() => string),
options?: UseFetchOptions<T>,
) => {
const baseURL = '/api/${key}'
return useFetch(url, {
baseURL,
...options,
})
}
`
},
})
})
},
})
import { defineNuxtModule, createResolver, addServerHandler, addTemplate } from '@nuxt/kit'
import { pascalCase } from 'scule'

export interface ApiEndpoint {
url: string
headers?: Record<string, string>
}

export interface ModuleOptions {
endpoints: Record<string, ApiEndpoint>
}

export default defineNuxtModule<ModuleOptions>({
meta: {},
setup(_options, _nuxt) {
const { resolve } = createResolver(import.meta.url)

const getDataComposableName = (endpoint: string) => `use${pascalCase(endpoint)}Fetch`

const endpointKeys = Object.keys(_options.endpoints)

endpointKeys.forEach((key) => {
addServerHandler({
route: `/api/${key}/**`,
handler: resolve('runtime/server/handler'),
})

// Rough idea of what I want to accomplish
addTemplate({
filename: `${getDataComposableName(key)}.ts`,
getContents: () => {
return `
import { useFetch, type UseFetchOptions } from '#app'

export const ${getDataComposableName(key)} = <T>(
url: string | (() => string),
options?: UseFetchOptions<T>,
) => {
const baseURL = '/api/${key}'
return useFetch(url, {
baseURL,
...options,
})
}
`
},
})
})
},
})
0 Replies
No replies yetBe the first to reply to this messageJoin
Want results from more Discord servers?
Add your server