Skip to content

Commit

Permalink
Feat/kit routes readability (#408)
Browse files Browse the repository at this point in the history
* 🎉 NEW: when we have only 1 method, let's not add the arg

* ♻️ NEW: cleaning with nicer keys
  • Loading branch information
jycouet authored Nov 1, 2023
1 parent 48a23b2 commit 3b3c4eb
Show file tree
Hide file tree
Showing 18 changed files with 205 additions and 94 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-squids-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-kit-routes': patch
---

when we have only 1 method, let's not add the arg
5 changes: 5 additions & 0 deletions .changeset/warm-melons-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-kit-routes': patch
---

using nicer keys by default
48 changes: 30 additions & 18 deletions packages/vite-plugin-kit-routes/src/lib/ROUTES.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
export const PAGES = {
'/': (sp?: Record<string, string>) => {
_ROOT: (sp?: Record<string, string>) => {
return `/${appendSp(sp)}`
},
'/site/[id]': (params: { id: string }, sp?: Record<string, string>) => {
contract: (sp?: Record<string, string>) => {
return `/contract${appendSp(sp)}`
},
contract_id: (params: { id: string }, sp?: Record<string, string>) => {
return `/contract/${params.id}${appendSp(sp)}`
},
site: (sp?: Record<string, string>) => {
return `/site${appendSp(sp)}`
},
site_id: (params: { id: string }, sp?: Record<string, string>) => {
return `/site/${params.id}${appendSp(sp)}`
},
'/site/[param]/[yop]': (params: { param: string; yop: string }, sp?: Record<string, string>) => {
return `/site/${params.param}/${params.yop}${appendSp(sp)}`
site_contract_siteId_contractId: (
params: { siteId: string; contractId: string },
sp?: Record<string, string>,
) => {
return `/site_contract/${params.siteId}-${params.contractId}${appendSp(sp)}`
},
}

export const SERVERS = {
'/site/[id]/one': (
method: 'GET' | 'POST',
params: { id: string },
sp?: Record<string, string>,
) => {
return `/site/${params.id}/one${appendSp(sp)}`
contract: (method: 'GET' | 'POST', sp?: Record<string, string>) => {
return `/contract${appendSp(sp)}`
},
site: (method: 'GET', sp?: Record<string, string>) => {
return `/site${appendSp(sp)}`
},
}

export const ACTIONS = {
'/site/[id]/two': (params: { id: string }) => {
return `/site/${params.id}/two`
contract_id: (params: { id: string }) => {
return `/contract/${params.id}`
},
site: (action: 'action1' | 'action2') => {
return `/site?/${action}`
},
'/site/[id]/two/[hello]': (
action: 'default' | 'login' | 'register',
params: { id: string; hello: string },
site_contract_siteId_contractId: (
action: 'sendSomething',
params: { siteId: string; contractId: string },
) => {
return `/site/${params.id}/two/${params.hello}${
String(action) === 'default' ? '' : `?/${action}`
}`
return `/site_contract/${params.siteId}-${params.contractId}?/${action}`
},
}

Expand Down
132 changes: 88 additions & 44 deletions packages/vite-plugin-kit-routes/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,44 @@ export type Options = {
* @default 'src/lib/ROUTES.ts'
*/
generated_file_path?: string

/**
* when `false` _(default)_, object keys look like this: `site_id_two_hello`
*
* when `true`, object keys look like this: `/site/[id]/two/[hello]`
*/
keep_path_param_format?: boolean
}

function generated_file_path(params?: Options) {
return params?.generated_file_path ?? 'src/lib/ROUTES.ts'
function generated_file_path(options?: Options) {
return options?.generated_file_path ?? 'src/lib/ROUTES.ts'
}

export function formatKey(key: string, options?: Options) {
if (options?.keep_path_param_format) {
return key
}

const toReplace = ['/', '[', ']', '(', ')', '-']
let toRet = key
.split('')
.map(c => (toReplace.includes(c) ? '_' : c))
.join('')
.replaceAll('__', '_')
.replaceAll('__', '_')
.replaceAll('__', '_')
if (toRet.startsWith('_')) {
toRet = toRet.slice(1)
}
if (toRet.endsWith('_')) {
toRet = toRet.slice(0, -1)
}

if (toRet === '') {
toRet = '_ROOT'
}

return toRet
}

function routes_path() {
Expand All @@ -37,11 +71,21 @@ function routes_path() {
// const routes_path = 'src/lib/ROUTES.ts'
const log = new Log('Kit Routes')

const getFiles = (lookFor: '+page.svelte' | '+page.server.ts' | '+server.ts') => {
const getFileKeys = (
lookFor: '+page.svelte' | '+page.server.ts' | '+server.ts',
options?: Options,
) => {
const files = readdirSync(routes_path(), { recursive: true }) as string[]
return files
.filter(file => file.endsWith(lookFor))
.map(file => `/` + file.replace(`/${lookFor}`, '').replace(lookFor, ''))
return (
files
.filter(file => file.endsWith(lookFor))
.map(file => `/` + file.replace(`/${lookFor}`, '').replace(lookFor, ''))
// Keep the sorting at this level, it will make more sense
.sort()
.map(file => {
return { toUse: formatKey(file, options), original: file }
})
)
}

function formatExtractParamsFromPath(file_path: string) {
Expand Down Expand Up @@ -119,24 +163,24 @@ const getActionsOfServerPages = (path: string) => {
return exportedNames
}

const run = (params?: Options) => {
const files_pages = getFiles('+page.svelte')
const files_server_pages = getFiles('+page.server.ts')
const files_server = getFiles('+server.ts')
const run = (options?: Options) => {
const pages = getFileKeys('+page.svelte', options)
const server = getFileKeys('+page.server.ts', options)
const files_server = getFileKeys('+server.ts', options)

const result = write(generated_file_path(params), [
const result = write(generated_file_path(options), [
`export const PAGES = {
${files_pages
.map(file_path => {
${pages
.map(key => {
const params = []
const pFormPath = formatExtractParamsFromPath(file_path)
const pFormPath = formatExtractParamsFromPath(key.original)
if (pFormPath.length > 0) {
params.push(`params: {${pFormPath}}`)
}
params.push(`sp?: Record<string, string>`)
return (
`"${file_path}": (${params.join(', ')}) => ` +
`{ return \`${file_path
`"${key.toUse}": (${params.join(', ')}) => ` +
`{ return \`${key.original
.replaceAll('[', '${params.')
.replaceAll(']', '}')}\${appendSp(sp)}\` }`
)
Expand All @@ -146,21 +190,20 @@ const run = (params?: Options) => {
export const SERVERS = {
${files_server
.map(file_path => {
.map(key => {
const params = []
params.push(
`method: ${getMethodsOfServerFiles(file_path)
.map(c => `'${c}'`)
.join(' | ')}`,
)
const pFormPath = formatExtractParamsFromPath(file_path)
const methods = getMethodsOfServerFiles(key.original)
if (methods.length > 0) {
params.push(`method: ${methods.map(c => `'${c}'`).join(' | ')}`)
}
const pFormPath = formatExtractParamsFromPath(key.original)
if (pFormPath.length > 0) {
params.push(`params: {${pFormPath}}`)
}
params.push(`sp?: Record<string, string>`)
return (
`"${file_path}": (${params.join(', ')}) => ` +
`{ return \`${file_path
`"${key.toUse}": (${params.join(', ')}) => ` +
`{ return \`${key.original
.replaceAll('[', '${params.')
.replaceAll(']', '}')}\${appendSp(sp)}\` }`
)
Expand All @@ -169,27 +212,28 @@ export const SERVERS = {
}
export const ACTIONS = {
${files_server_pages
.map(file_path => {
${server
.map(key => {
const params = []
const actions = getActionsOfServerPages(file_path)
let actionsSpecified = false
const actions = getActionsOfServerPages(key.original)
let actionsFormat = ''
if (actions.length === 0) {
// Don't do anything...
} else if (actions.length === 1 && actions[0] === 'default') {
// Don't do anything...
} else {
params.push(`action: ${actions.map(c => `'${c}'`).join(' | ')}`)
actionsSpecified = true
actionsFormat = `?/\${action}`
// actionsFormat = `coucou`
}
const pFormPath = formatExtractParamsFromPath(file_path)
const pFormPath = formatExtractParamsFromPath(key.original)
if (pFormPath.length > 0) {
params.push(`params: {${pFormPath}}`)
}
return (
`"${file_path}": (${params.join(', ')}) => ` +
`{ return \`${file_path.replaceAll('[', '${params.').replaceAll(']', '}')}` +
`${actionsSpecified ? `\${String(action) === 'default' ? '' : \`?/\${action}\`}` : ``}\` }`
`"${key.toUse}": (${params.join(', ')}) => ` +
`{ return \`` +
`${key.original.replaceAll('[', '${params.').replaceAll(']', '}')}` +
`${actionsFormat}` +
`\`}`
)
})
.join(',\n ')}
Expand All @@ -203,9 +247,9 @@ const appendSp = (sp?: Record<string, string>) => {
])

// TODO: optimize this later. We want to write the new file only if different after prettier?! (having a tmp file somewhere?)
if (params?.post_update_run) {
log.info(`${yellow(`post_update_run`)} "${green(params?.post_update_run)}" running...`)
const child = spawn(params.post_update_run, { shell: true })
if (options?.post_update_run) {
log.info(`${yellow(`post_update_run`)} "${green(options?.post_update_run)}" running...`)
const child = spawn(options.post_update_run, { shell: true })
child.stdout.on('data', data => {
if (data.toString()) {
log.info(data.toString())
Expand All @@ -216,23 +260,23 @@ const appendSp = (sp?: Record<string, string>) => {
})
child.on('close', code => {
if (result) {
log.success(`${yellow(generated_file_path(params))} updated`)
log.success(`${yellow(generated_file_path(options))} updated`)
}
})
} else {
if (result) {
log.success(`${yellow(generated_file_path(params))} updated`)
log.success(`${yellow(generated_file_path(options))} updated`)
}
}
}

export function kitRoutes(params?: Options): Plugin[] {
export function kitRoutes(options?: Options): Plugin[] {
return [
// Run the thing at startup
{
name: 'kit-routes',
configureServer() {
run(params)
run(options)
},
},

Expand All @@ -242,7 +286,7 @@ export function kitRoutes(params?: Options): Plugin[] {
name: 'kit-routes-watch',
logs: [],
watch: ['**/+page.svelte', '**/+page.server.ts', '**/+server.ts'],
run: () => run(params),
run: () => run(options),
},
]),
]
Expand Down
18 changes: 17 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 } from './index.js'
import { extractParamsFromPath, formatKey } from './index.js'

describe('vite-plugin-kit-routes', () => {
it('get id', async () => {
Expand Down Expand Up @@ -28,4 +28,20 @@ describe('vite-plugin-kit-routes', () => {
]
`)
})

it('formatKey', async () => {
expect(formatKey('/[param]site/[yop](group)/[id]')).toMatchInlineSnapshot(
'"param_site_yop_group_id"',
)
})

it('formatKey', async () => {
expect(
formatKey('/[param]site/[yop](group)/[id]', { keep_path_param_format: true }),
).toMatchInlineSnapshot('"/[param]site/[yop](group)/[id]"')
})

it('formatKey', async () => {
expect(formatKey('/')).toMatchInlineSnapshot('"_ROOT"')
})
})
17 changes: 9 additions & 8 deletions packages/vite-plugin-kit-routes/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<script lang="ts">
import { ACTIONS, PAGES } from '$lib/ROUTES.js'
const val = ACTIONS['/site/[id]/two/[hello]']('login', { hello: 'you', id: '1' })
console.log(`val`, val)
import { PAGES } from '$lib/ROUTES.js'
</script>

<svelte:head>
Expand All @@ -14,10 +11,14 @@
<hr />

<ul>
<a href={PAGES['/']()}>Home</a>
<a href={PAGES['/site/[param]/[yop]']({ param: 'param', yop: 'yop' }, { limit: '2' })}
>Another route</a
>
<li><a href={PAGES._ROOT()}>Home</a></li>
<li><a href={PAGES.site()}>Sites</a></li>
<li><a href={PAGES.site_id({ id: 'Paris' })}>Site Paris</a></li>
<li>
<a href={PAGES.site_contract_siteId_contractId({ siteId: 'Paris', contractId: 'First' })}>
Site Paris & Contract First
</a>
</li>
</ul>

<hr />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>Contracts</h2>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { RequestHandler } from './$types'
import type { RequestHandler } from './$types.d.ts'

export const GET: RequestHandler = async () => {
return new Response()
}

export const POST: RequestHandler = () => {
// do something
return new Response()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { Actions } from './$types.d.ts'

export const actions = {
default: async () => {},
} satisfies Actions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>Contract [id]</h2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Actions } from './$types.d.ts'

export const actions = {
action1: async () => {},
action2: async () => {},
} satisfies Actions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>Sites</h2>
Loading

1 comment on commit 3b3c4eb

@vercel
Copy link

@vercel vercel bot commented on 3b3c4eb Nov 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kitql – ./

kitql.vercel.app
kitql-git-main-jycouet.vercel.app
kitql-jycouet.vercel.app
kitql.dev
www.kitql.dev

Please sign in to comment.