Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sixty-dots-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-kit-routes': patch
---

fix optional param not set
6 changes: 3 additions & 3 deletions packages/vite-plugin-kit-routes/src/lib/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const PAGES = {
return `/gp/two`
},
lang_lang: (params?: { lang?: string | number }) => {
return `/lang/${params?.lang ?? ''}`
return `/lang${params?.lang ? `/${params?.lang}` : ''}`
},
match_id_int: (params: { id: string | number }) => {
return `/match/${params.id}`
Expand All @@ -30,7 +30,7 @@ export const PAGES = {
siteId: string | number
contractId: string | number
}) => {
return `/site_contract/${params.siteId}-${params.contractId}`
return `/site_contract/${params.siteId}-[contractId]`
},
}

Expand All @@ -54,7 +54,7 @@ export const ACTIONS = {
action: 'sendSomething',
params: { siteId: string | number; contractId: string | number },
) => {
return `/site_contract/${params.siteId}-${params.contractId}?/${action}`
return `/site_contract/${params.siteId}-[contractId]?/${action}`
},
}

Expand Down
183 changes: 97 additions & 86 deletions packages/vite-plugin-kit-routes/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,106 +123,117 @@ const getFileKeys = (
.map(file => `/` + file.replace(`/${lookFor}`, '').replace(lookFor, ''))
// Keep the sorting at this level, it will make more sense
.sort()
.map(original => {
const href = original.replace(/\([^)]*\)/g, '').replace(/\/+/g, '/')
let toRet = href
.map(original => fileToMetadata(original, type, options, useWithAppendSp))
)
}

const keyToUse = formatKey(original, options)
type Param = { name: string; optional: boolean; matcher?: string; type?: string }

// custom conf
const viteCustomPathConfig = options?.extend?.[type]
let customConf: CustomPath = {
extra_search_params: 'default',
}
if (viteCustomPathConfig && viteCustomPathConfig[keyToUse]) {
customConf = viteCustomPathConfig[keyToUse]
}
export const fileToMetadata = (
original: string,
type: 'PAGES' | 'SERVERS' | 'ACTIONS',
options: Options | undefined,
useWithAppendSp: boolean | undefined,
) => {
const href = original.replace(/\([^)]*\)/g, '').replace(/\/+/g, '/')
let toRet = href

const paramsFromPath = extractParamsFromPath(original)
paramsFromPath.params.forEach(c => {
const sMatcher = `${c.matcher ? `=${c.matcher}` : ''}`
if (c.optional) {
toRet = toRet.replaceAll(`[[${c.name + sMatcher}]]`, `\${params?.${c.name} ?? ''}`)
} else {
toRet = toRet.replaceAll(`[${c.name + sMatcher}]`, `\${params.${c.name}}`)
}
})
const keyToUse = formatKey(original, options)

const params = []
// custom conf
const viteCustomPathConfig = options?.extend?.[type]
let customConf: CustomPath = {
extra_search_params: 'default',
}
if (viteCustomPathConfig && viteCustomPathConfig[keyToUse]) {
customConf = viteCustomPathConfig[keyToUse]
}

let actionsFormat = ''
if (lookFor === '+server.ts') {
const methods = getMethodsOfServerFiles(original)
if (methods.length > 0) {
params.push(`method: ${methods.map(c => `'${c}'`).join(' | ')}`)
}
} else if (lookFor === '+page.server.ts') {
const actions = getActionsOfServerPages(original)

if (actions.length === 0) {
} else if (actions.length === 1 && actions[0] === 'default') {
} else {
params.push(`action: ${actions.map(c => `'${c}'`).join(' | ')}`)
actionsFormat = `?/\${action}`
}
}
const paramsFromPath = extractParamsFromPath(original)
paramsFromPath.params.forEach(c => {
const sMatcher = `${c.matcher ? `=${c.matcher}` : ''}`
if (c.optional) {
toRet = toRet.replaceAll(
`/[[${c.name + sMatcher}]]`,
`\${params?.${c.name} ? \`/\${params?.${c.name}}\`: ''}`,
)
} else {
toRet = toRet.replaceAll(`/[${c.name + sMatcher}]`, `/\${params.${c.name}}`)
}
})

// custom search Param?
let explicit_search_params_to_function = ''
if (customConf.explicit_search_params) {
Object.entries(customConf.explicit_search_params).forEach(sp => {
paramsFromPath.params.push({ name: sp[0], optional: !sp[1].required, type: sp[1].type })
explicit_search_params_to_function += `${sp[0]}: params?.${sp[0]}`
})
}
const params = []

// custom Param?
if (customConf.params) {
Object.entries(customConf.params).forEach(sp => {
for (let i = 0; i < paramsFromPath.params.length; i++) {
if (paramsFromPath.params[i].name === sp[0]) {
if (sp[1].type) {
paramsFromPath.params[i].type = sp[1].type
}
}
}
})
}
let actionsFormat = ''
if (type === 'SERVERS') {
const methods = getMethodsOfServerFiles(original)
if (methods.length > 0) {
params.push(`method: ${methods.map(c => `'${c}'`).join(' | ')}`)
}
} else if (type === 'ACTIONS') {
const actions = getActionsOfServerPages(original)

if (paramsFromPath.params.length > 0) {
params.push(
`params${paramsFromPath.isAllOptional ? '?' : ''}: ` +
`{${formatArgs(paramsFromPath.params, options)}}`,
)
}
if (actions.length === 0) {
} else if (actions.length === 1 && actions[0] === 'default') {
} else {
params.push(`action: ${actions.map(c => `'${c}'`).join(' | ')}`)
actionsFormat = `?/\${action}`
}
}

let fullSP = ''
const wExtraSP =
(customConf.extra_search_params === 'default' && useWithAppendSp) ||
customConf.extra_search_params === 'with'

if (wExtraSP && !customConf.explicit_search_params) {
params.push(`sp?: Record<string, string | number>`)
fullSP = `\${appendSp(sp)}`
} else if (wExtraSP && customConf.explicit_search_params) {
params.push(`sp?: Record<string, string | number>`)
fullSP = `\${appendSp({...sp, ${explicit_search_params_to_function} })}`
} else if (!wExtraSP && customConf.explicit_search_params) {
fullSP = `\${appendSp({ ${explicit_search_params_to_function} })}`
// custom search Param?
let explicit_search_params_to_function = ''
if (customConf.explicit_search_params) {
Object.entries(customConf.explicit_search_params).forEach(sp => {
paramsFromPath.params.push({ name: sp[0], optional: !sp[1].required, type: sp[1].type })
explicit_search_params_to_function += `${sp[0]}: params?.${sp[0]}`
})
}

// custom Param?
if (customConf.params) {
Object.entries(customConf.params).forEach(sp => {
for (let i = 0; i < paramsFromPath.params.length; i++) {
if (paramsFromPath.params[i].name === sp[0]) {
if (sp[1].type) {
paramsFromPath.params[i].type = sp[1].type
}
}
}
})
}

const prop =
`"${keyToUse}": (${params.join(', ')}) => ` +
` { return \`${toRet}${actionsFormat}` +
`${fullSP}` +
`\` }`
if (paramsFromPath.params.length > 0) {
params.push(
`params${paramsFromPath.isAllOptional ? '?' : ''}: ` +
`{${formatArgs(paramsFromPath.params, options)}}`,
)
}

return { keyToUse, prop, paramsFromPath }
})
)
let fullSP = ''
const wExtraSP =
(customConf.extra_search_params === 'default' && useWithAppendSp) ||
customConf.extra_search_params === 'with'

if (wExtraSP && !customConf.explicit_search_params) {
params.push(`sp?: Record<string, string | number>`)
fullSP = `\${appendSp(sp)}`
} else if (wExtraSP && customConf.explicit_search_params) {
params.push(`sp?: Record<string, string | number>`)
fullSP = `\${appendSp({...sp, ${explicit_search_params_to_function} })}`
} else if (!wExtraSP && customConf.explicit_search_params) {
fullSP = `\${appendSp({ ${explicit_search_params_to_function} })}`
}

const prop =
`"${keyToUse}": (${params.join(', ')}) => ` +
` { return \`${toRet}${actionsFormat}` +
`${fullSP}` +
`\` }`

return { keyToUse, prop, paramsFromPath }
}

type Param = { name: string; optional: boolean; matcher?: string; type?: string }
export function extractParamsFromPath(path: string): {
params: Param[]
isAllOptional: boolean
Expand Down
10 changes: 9 additions & 1 deletion packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { extractParamsFromPath, formatKey } from './index.js'
import { extractParamsFromPath, fileToMetadata, formatKey } from './index.js'

describe('vite-plugin-kit-routes', () => {
it('get id', async () => {
Expand Down Expand Up @@ -85,4 +85,12 @@ describe('vite-plugin-kit-routes', () => {
it('formatKey', async () => {
expect(formatKey('/')).toMatchInlineSnapshot('"_ROOT"')
})

it('fileToMetadata', async () => {
expect(
fileToMetadata('/[[lang]]/about', 'PAGES', undefined, undefined).prop,
).toMatchInlineSnapshot(
'"\\"lang_about\\": (params?: {lang?: string | number}) => { return `${params?.lang ? `/${params?.lang}`: \'\'}/about` }"',
)
})
})