Skip to content

Commit a8337ef

Browse files
feat: better warnings & type refactors
1 parent 83e7fc6 commit a8337ef

File tree

6 files changed

+69
-49
lines changed

6 files changed

+69
-49
lines changed

src/module.ts

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,34 @@ export default defineNuxtModule<ModuleOptions>({
5757
},
5858
},
5959
defaults: {
60-
kirbyUrl: process.env.KIRBY_BASE_URL,
60+
kirbyUrl: process.env.KIRBY_BASE_URL as string,
6161
kirbyEndpoint: 'api/query',
6262
kirbyAuth: 'basic',
63-
token: process.env.KIRBY_API_TOKEN,
63+
token: process.env.KIRBY_API_TOKEN as string,
6464
credentials: {
65-
username: process.env.KIRBY_API_USERNAME,
66-
password: process.env.KIRBY_API_PASSWORD,
65+
username: process.env.KIRBY_API_USERNAME as string,
66+
password: process.env.KIRBY_API_PASSWORD as string,
6767
},
6868
clientRequests: false,
6969
},
7070
async setup(options, nuxt) {
7171
const { resolve } = createResolver(import.meta.url)
72-
const { clientRequests } = options
7372
const apiRoute = '/api/__kql__' as const
7473

74+
// Make sure Kirby URL and KQL endpoint are set
75+
if (!options.kirbyUrl)
76+
console.warn('Missing `KIRBY_BASE_URL` in `.env`')
77+
78+
if (!options.kirbyEndpoint)
79+
console.warn('Missing `kql.kirbyEndpoint` option in Nuxt config')
80+
81+
// Make sure authentication credentials are set
82+
if (options.kirbyAuth === 'basic' && (!options.credentials || !options.credentials.username || !options.credentials.password))
83+
console.warn('Missing `KIRBY_API_USERNAME` and `KIRBY_API_PASSWORD` in `.env` for basic authentication')
84+
85+
if (options.kirbyAuth === 'bearer' && !options.token)
86+
console.warn('Missing `KIRBY_API_TOKEN` in `.env` for bearer authentication')
87+
7588
// Private runtime config
7689
nuxt.options.runtimeConfig.kql = defu(
7790
nuxt.options.runtimeConfig.kql,
@@ -83,35 +96,58 @@ export default defineNuxtModule<ModuleOptions>({
8396
nuxt.options.runtimeConfig.public.kql,
8497
// Protect authorization data if no public requests are enabled
8598
{
86-
kirbyUrl: clientRequests ? options.kirbyUrl : undefined,
87-
kirbyEndpoint: clientRequests ? options.kirbyEndpoint : undefined,
88-
kirbyAuth: clientRequests ? options.kirbyAuth : undefined,
89-
token: clientRequests ? options.token : undefined,
90-
credentials: clientRequests ? options.credentials : undefined,
91-
clientRequests,
99+
kirbyUrl: options.clientRequests ? options.kirbyUrl : undefined,
100+
kirbyEndpoint: options.clientRequests ? options.kirbyEndpoint : undefined,
101+
kirbyAuth: options.clientRequests ? options.kirbyAuth : undefined,
102+
token: options.clientRequests ? options.token : undefined,
103+
credentials: options.clientRequests ? options.credentials : undefined,
104+
clientRequests: options.clientRequests,
92105
} as ModuleOptions,
93106
)
94107

108+
// Transpile runtime
95109
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
96110
nuxt.options.build.transpile.push(runtimeDir)
97111

112+
// Add KQL proxy endpoint to fetch queries on server-side
113+
addServerHandler({
114+
route: apiRoute,
115+
handler: resolve(runtimeDir, 'server/api/kql'),
116+
})
117+
118+
// Add KQL composables
98119
nuxt.hook('autoImports:dirs', (dirs) => {
99120
dirs.push(resolve(runtimeDir, 'composables'))
100121
})
101122

102-
addServerHandler({
103-
route: apiRoute,
104-
handler: resolve(runtimeDir, 'server/api'),
123+
nuxt.hook('nitro:config', (nitroConfig) => {
124+
// Inline module runtime in Nitro bundle
125+
nitroConfig.externals = defu(typeof nitroConfig.externals === 'object' ? nitroConfig.externals : {}, {
126+
inline: [resolve('./runtime')],
127+
})
105128
})
106129

107130
addTemplate({
108-
filename: 'nuxt-kql-options.ts',
131+
filename: 'nuxt-kql/options.mjs',
109132
write: true,
110133
getContents() {
111134
return `
112135
export const apiRoute = '${apiRoute}'
113136
`.trimStart()
114137
},
115138
})
139+
140+
addTemplate({
141+
filename: 'types/nuxt-kql.d.ts',
142+
getContents: () => [
143+
'declare module \'#build/nuxt-kql/options\' {',
144+
' const apiRoute: string',
145+
'}',
146+
].join('\n'),
147+
})
148+
149+
nuxt.hook('prepare:types', (options) => {
150+
options.references.push({ path: resolve(nuxt.options.buildDir, 'types/nuxt-kql.d.ts') })
151+
})
116152
},
117153
})

src/runtime/composables/$kql.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { hash as ohash } from 'ohash'
22
import type { KqlPrivateFetchOptions, KqlQueryRequest, KqlQueryResponse } from '../types'
3-
import { apiRoute } from '#build/nuxt-kql-options'
3+
import { apiRoute } from '#build/nuxt-kql/options'
44

55
interface InternalState<T> {
66
promiseMap: Map<string, Promise<T>>

src/runtime/composables/$publicKql.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import type { KqlPublicFetchOptions, KqlQueryRequest, KqlQueryResponse } from '../types'
2-
import { assertKqlPublicConfig, getAuthHeaders, headersToObject } from '../utils'
32
import type { ModuleOptions } from '../../module'
4-
import { useRuntimeConfig } from '#app'
3+
import { getAuthHeaders, headersToObject } from '../utils'
4+
import { useRuntimeConfig } from '#imports'
55

66
export function $publicKql<T = KqlQueryResponse>(
77
query: KqlQueryRequest,
88
opts: KqlPublicFetchOptions = {},
99
): Promise<T> {
10-
const { public: { kql } } = useRuntimeConfig()
11-
assertKqlPublicConfig(kql as ModuleOptions)
10+
const { kql } = useRuntimeConfig().public
11+
if (!kql.clientRequests)
12+
throw new Error('Fetching from Kirby client-side isn\'t allowed. Enable it by setting `clientRequests` to `true`.')
1213

1314
return $fetch<T>(kql.kirbyEndpoint, {
1415
...opts,

src/runtime/composables/useKql.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import type { NitroFetchRequest } from 'nitropack'
22
import type { Ref } from 'vue'
33
import { computed, unref } from 'vue'
44
import type { KqlQueryRequest, KqlQueryResponse, UseKqlOptions } from '../types'
5-
import { assertKqlPublicConfig, getAuthHeaders } from '../utils'
65
import type { ModuleOptions } from '../../module'
6+
import { getAuthHeaders } from '../utils'
77
import type { AsyncData } from '#app'
8-
import { useFetch, useRuntimeConfig } from '#app'
9-
import { apiRoute } from '#build/nuxt-kql-options'
8+
import { useFetch, useRuntimeConfig } from '#imports'
9+
import { apiRoute } from '#build/nuxt-kql/options'
1010

1111
export function useKql<ResT = KqlQueryResponse, ReqT = KqlQueryRequest>(
1212
query: Ref<ReqT> | ReqT,
@@ -25,8 +25,9 @@ export function usePublicKql<ResT = KqlQueryResponse, ReqT = KqlQueryRequest>(
2525
query: Ref<ReqT> | ReqT,
2626
opts: UseKqlOptions<ResT> = {},
2727
) {
28-
const { public: { kql } } = useRuntimeConfig()
29-
assertKqlPublicConfig(kql as ModuleOptions)
28+
const { kql } = useRuntimeConfig().public
29+
if (!kql.clientRequests)
30+
throw new Error('Fetching from Kirby client-side isn\'t allowed. Enable it by setting `clientRequests` to `true`.')
3031

3132
const _query = computed(() => unref(query))
3233

src/runtime/server/api.ts renamed to src/runtime/server/api/kql.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import { defineEventHandler, useBody } from 'h3'
22
import { getQuery } from 'ufo'
3-
import type { ModuleOptions } from '../../module'
4-
import type { KqlQueryRequest, KqlQueryResponse } from '../types'
5-
import { getAuthHeaders } from '../utils'
3+
import type { ModuleOptions } from '../../../module'
4+
import type { KqlQueryRequest, KqlQueryResponse } from '../../types'
5+
import { getAuthHeaders } from '../../utils'
6+
import { useRuntimeConfig } from '#imports'
67

78
export default defineEventHandler(async (event): Promise<KqlQueryResponse> => {
89
const { kql } = useRuntimeConfig()
910

10-
if (!kql.kirbyUrl || !kql.kirbyEndpoint)
11-
throw new Error('Kirby base URL or KQL API route path is not configured')
12-
1311
let kqlRequest: Partial<KqlQueryRequest> = {}
1412

1513
if (event.req.method === 'POST') {

src/runtime/utils.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,12 @@ export function getAuthHeaders({ kirbyAuth, token, credentials }: ModuleOptions)
1515
const headers: Record<string, string> = {}
1616

1717
if (kirbyAuth === 'basic') {
18-
if (!credentials?.username || !credentials?.password)
19-
throw new Error('Missing KQL credentials for basic auth')
20-
21-
const { username, password } = credentials
22-
18+
const { username, password } = credentials || {}
2319
headers.Authorization = Buffer.from(`${username}:${password}`).toString('base64')
2420
}
2521

26-
if (kirbyAuth === 'bearer') {
27-
if (!token)
28-
throw new Error('Missing KQL token for bearer auth')
29-
22+
if (kirbyAuth === 'bearer')
3023
headers.Authorization = `Bearer ${token}`
31-
}
3224

3325
return headers
3426
}
35-
36-
export function assertKqlPublicConfig(config: ModuleOptions) {
37-
if (!config.clientRequests)
38-
throw new Error('Fetching from the KQL server directly on the client isn\'t allowed. Enable it by setting the nuxt-kql option "clientRequests" to "true" first.')
39-
40-
if (!config.kirbyUrl || !config.kirbyEndpoint)
41-
throw new Error('Kirby base URL or KQL API route path is not configured')
42-
}

0 commit comments

Comments
 (0)