Skip to content

Commit

Permalink
enh: get rid of computed property and introduce a new `resolveApiUrlP…
Browse files Browse the repository at this point in the history
…ath` helper
  • Loading branch information
phoenix-ru committed Oct 24, 2024
1 parent d3e8050 commit 013fcc2
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 55 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"dev:prepare": "nuxt-module-build build --stub",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
"docs:preview": "vitepress preview docs",
"test:unit": "vitest"
},
"dependencies": {
"@nuxt/kit": "^3.12.4",
Expand Down Expand Up @@ -61,6 +62,7 @@
"ts-essentials": "^9.4.2",
"typescript": "^5.5.4",
"vitepress": "^1.3.1",
"vitest": "^1.6.0",
"vue-tsc": "^2.0.29"
},
"packageManager": "[email protected]+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e"
Expand Down
117 changes: 111 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 6 additions & 24 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import {
useLogger
} from '@nuxt/kit'
import { defu } from 'defu'
import { joinURL } from 'ufo'
import { genInterface } from 'knitwork'
import type { DeepRequired } from 'ts-essentials'
import type { NuxtModule } from 'nuxt/schema'
import { getOriginAndPathnameFromURL, isProduction } from './runtime/helpers'
import { extractFromRuntimeConfig } from './runtime/utils/extractFromRuntimeConfig'
import { isProduction } from './runtime/helpers'
import type {
AuthProviders,
ModuleOptions,
Expand All @@ -27,6 +25,7 @@ import type {

const topLevelDefaults = {
isEnabled: true,
baseURL: '/api/auth',
disableServerSideAuth: false,
originEnvKey: 'AUTH_ORIGIN',
sessionRefresh: {
Expand Down Expand Up @@ -108,32 +107,16 @@ export default defineNuxtModule<ModuleOptions>({
const logger = useLogger(PACKAGE_NAME)

// 0. Assemble all options
let baseURL = userOptions.baseURL ?? '/api/auth'
if (userOptions.originEnvKey) {
const envFromRuntimeConfig = extractFromRuntimeConfig(nuxt.options.runtimeConfig, userOptions.originEnvKey)
const envOrigin = envFromRuntimeConfig ?? process.env[userOptions.originEnvKey]
if (envOrigin) {
baseURL = envOrigin
}
}

const { origin, pathname } = getOriginAndPathnameFromURL(baseURL)

const selectedProvider = userOptions.provider?.type ?? 'authjs'

const options = {
...defu(userOptions, topLevelDefaults, {
computed: {
origin,
pathname,
}
}),
const options = defu({
// We use `as` to infer backend types correctly for runtime-usage (everything is set, although for user everything was optional)
provider: defu(
userOptions.provider,
defaultsByBackend[selectedProvider]
) as DeepRequired<AuthProviders>
}
}, userOptions, topLevelDefaults)

// 1. Check if module should be enabled at all
if (!options.isEnabled) {
Expand All @@ -145,11 +128,10 @@ export default defineNuxtModule<ModuleOptions>({

// 2. Set up runtime configuration
if (!isProduction) {
const fullBaseUrl = joinURL(options.computed.origin ?? '', options.computed.pathname)

const loggerMessages = [
`Selected provider: ${selectedProvider}.`,
`Auth API location is \`${fullBaseUrl}\`.`
// TODO Before merging PR: write the docs how `baseURL` can be changed in runtime (env `NUXT_PUBLIC_AUTH_BASE_URL`, `runtimeConfig.public.auth.baseURL`, etc.).
`Auth API location is \`${options.baseURL}\`, it can be changed using TODO.`
]
if (selectedProvider === 'authjs') {
loggerMessages.push('Ensure that the `NuxtAuthHandler({ ... })` is there, see https://auth.sidebase.io/guide/authjs/nuxt-auth-handler')
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/composables/local/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { jsonPointerGet, objectFromJsonPointer, useTypedBackendConfig } from '..
import { _fetch } from '../../utils/fetch'
import { getRequestURLWN } from '../../utils/callWithNuxt'
import { determineCallbackUrl } from '../../utils/url'
import { formatToken } from '../../utils/local'
import { formatToken } from './utils/token'
import { type UseAuthStateReturn, useAuthState } from './useAuthState'
import { callWithNuxt } from '#app/nuxt'
// @ts-expect-error - #auth not defined
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/composables/local/useAuthState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type ComputedRef, computed, getCurrentInstance, watch } from 'vue'
import type { CommonUseAuthStateReturn } from '../../types'
import { makeCommonAuthState } from '../commonAuthState'
import { useTypedBackendConfig } from '../../helpers'
import { formatToken } from '../../utils/local'
import { formatToken } from './utils/token'
import type { CookieRef } from '#app'
import { onMounted, useCookie, useRuntimeConfig, useState } from '#imports'
// @ts-expect-error - #auth not defined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ProviderLocalResolvedConfig } from '../helpers'
import type { ProviderLocalResolvedConfig } from '../../../helpers'

export function formatToken(token: string | null | undefined, config: ProviderLocalResolvedConfig): string | null {
if (token === null || token === undefined) {
Expand Down
41 changes: 41 additions & 0 deletions src/runtime/composables/local/utils/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { joinURL } from 'ufo'

// Slimmed down type to allow easy unit testing
interface RuntimeConfig {
public: {
auth: {
baseURL: string
originEnvKey: string
}
}
}

// TODO Comment below: remove/rewrite/add to docs
// Prios in runtime (baseURL):
// - env variable (using `originEnvKey`);
// - static runtime config (`baseURL` captured during build);
// - defaults;
export function resolveApiUrlPath(
endpointPath: string,
runtimeConfig: RuntimeConfig
): string {
// Fully-specified endpoint path - do not join with `baseURL`
if (endpointPath.startsWith('http://') || endpointPath.startsWith('https://')) {
return endpointPath
}

const authRuntimeConfig = runtimeConfig.public.auth

// Default to static runtime config (still overridable using `NUXT_PUBLIC_AUTH_BASE_URL`)
let baseURL = authRuntimeConfig.baseURL

// Override base URL using environment variable specified in `originEnvKey` if any
if (authRuntimeConfig.originEnvKey) {
const envBaseURL = process.env[authRuntimeConfig.originEnvKey]
if (envBaseURL) {
baseURL = envBaseURL
}
}

return joinURL(baseURL, endpointPath)
}
12 changes: 0 additions & 12 deletions src/runtime/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
// TODO: This should be merged into `./utils`
import { parseURL } from 'ufo'
import type { DeepRequired } from 'ts-essentials'
import type { ProviderAuthjs, ProviderLocal, SupportedAuthProviders } from './types'
import type { useRuntimeConfig } from '#imports'

export const isProduction = process.env.NODE_ENV === 'production'

export function getOriginAndPathnameFromURL(url: string) {
const { protocol, host, pathname } = parseURL(url)

let origin
if (host && protocol) {
origin = `${protocol}//${host}`
}

return { origin, pathname }
}

// We use `DeepRequired` here because options are actually enriched using `defu`
// but due to a build error we can't use `DeepRequired` inside runtime config definition.
type RuntimeConfig = ReturnType<typeof useRuntimeConfig>
Expand Down
Loading

0 comments on commit 013fcc2

Please sign in to comment.