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/hip-ways-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-kit-routes': patch
---

fix when route is starting with group
7 changes: 1 addition & 6 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,5 @@
"vite-plugin-watch-and-run": "1.4.3",
"website": "1.1.2"
},
"changesets": [
"little-crews-smell",
"poor-starfishes-complain",
"popular-trains-swim",
"tame-jars-chew"
]
"changesets": []
}
11 changes: 11 additions & 0 deletions packages/vite-plugin-kit-routes/src/lib/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

export const PAGES = {
_ROOT: `/`,
subGroup: `/subGroup`,
subGroup2: (params: { first: string | number }) => {
return `/subGroup2${appendSp({ first: params.first })}`
},
lang_contract: (params: { lang?: 'fr' | 'en' | 'hu' | 'at' | string } = {}) => {
return `${params?.lang ? `/${params?.lang}` : ''}/contract`
},
Expand All @@ -21,6 +25,9 @@ export const PAGES = {
lang_gp_two: (params: { lang?: 'fr' | 'en' | 'hu' | 'at' | string } = {}) => {
return `${params?.lang ? `/${params?.lang}` : ''}/gp/two`
},
lang_main: (params: { lang?: 'fr' | 'en' | 'hu' | 'at' | string } = {}) => {
return `${params?.lang ? `/${params?.lang}` : ''}/main`
},
lang_match_id_int: (params: {
lang?: 'fr' | 'en' | 'hu' | 'at' | string
id: string | number
Expand Down Expand Up @@ -128,10 +135,13 @@ const appendSp = (sp?: Record<string, string | number | undefined>) => {
export type KIT_ROUTES = {
PAGES: {
_ROOT: never
subGroup: never
subGroup2: 'first'
lang_contract: 'lang'
lang_contract_id: 'lang' | 'id'
lang_gp_one: 'lang'
lang_gp_two: 'lang'
lang_main: 'lang'
lang_match_id_int: 'lang' | 'id'
lang_site: 'lang' | 'limit'
lang_site_id: 'lang' | 'id' | 'limit' | 'demo'
Expand All @@ -144,6 +154,7 @@ export type KIT_ROUTES = {
lang_site_contract_siteId_contractId: 'lang' | 'siteId' | 'contractId' | 'extra'
}
Params: {
first: never
lang: never
id: never
limit: never
Expand Down
16 changes: 13 additions & 3 deletions packages/vite-plugin-kit-routes/src/lib/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,23 @@ function generated_file_path(options?: Options) {
return options?.generated_file_path ?? 'src/lib/ROUTES.ts'
}

export function rmvGroups(key: string) {
let toRet = key
// rmv (groups)
.replace(/\([^)]*\)/g, '')
.replace(/\/+/g, '/')
return toRet
}

export function formatKey(key: string, options?: Options) {
let toRet = rmvGroups(key)

if (options?.object_keys_format === undefined || options?.object_keys_format === '/') {
return key
return toRet
}

const toReplace = ['/', '[', ']', '(', ')', '-', '=']
let toRet = key
toRet = toRet
.split('')
.map(c => (toReplace.includes(c) ? '_' : c))
.join('')
Expand Down Expand Up @@ -191,7 +201,7 @@ export const fileToMetadata = (
options: Options | undefined,
useWithAppendSp: boolean | undefined,
) => {
let toRet = original
let toRet = rmvGroups(original)

const keyToUse = formatKey(original, options)

Expand Down
24 changes: 19 additions & 5 deletions packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,36 @@ describe('vite-plugin-kit-routes', () => {
`)
})

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

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

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

it('formatKey / starting with group', async () => {
expect(formatKey('/(group)/test', { object_keys_format: '/' })).toMatchInlineSnapshot('"/test"')
})

it('formatKey _ starting with group', async () => {
expect(formatKey('/(group)/test', { object_keys_format: '_' })).toMatchInlineSnapshot('"test"')
})

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

it('formatKey ROOT', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<hr />

<ul>
<li><a href={PAGES.lang({ lang: $page.params.lang })}>Home</a></li>
<li><a href={PAGES._ROOT}>Home</a></li>
<li><a href={PAGES.lang_site({ lang: $page.params.lang })}>Sites</a></li>
<li>
<a href={PAGES.lang_site({ lang: $page.params.lang, limit: 2 })}>Sites (with Search Param)</a>
Expand Down Expand Up @@ -64,7 +64,7 @@
<a href={PAGES.lang_gp_one({ lang: $page.params.lang })}>gp One</a>
</li>
<li>
<a href={PAGES.lang_gp_two({ lang: $page.params.lang })}>gp One</a>
<a href={PAGES.lang_gp_two({ lang: $page.params.lang })}>gp Two</a>
</li>
</ul>

Expand Down
22 changes: 22 additions & 0 deletions packages/vite-plugin-kit-routes/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
import { PAGES } from '$lib/ROUTES.js'

const list = [
{ lang: 'fr', caption: 'Français' },
{ lang: 'en', caption: 'English' },
{ lang: 'hu', caption: 'Magyar' },
{ lang: 'at', caption: 'Deutsch' },
].map(c => {
return { href: PAGES.lang_main({ lang: c.lang }), ...c }
})
</script>

<h2>Home</h2>

<ul>
{#each list as { href, caption }}
<li>
<a {href}>{caption}</a>
</li>
{/each}
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
import { page } from '$app/stores'
</script>

<h2>Main page from Lang</h2>

{$page.params.lang}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
const contractId = $page.params.contractId

// 🤞 before, random string
// const action = `/site_contract/${siteId}-${contractId}?/sendSomething`
// const action = `/en/site_contract/${siteId}-${contractId}?/sendSomething`

// ✅ after, all typed & make sure it exist. // 'vite-plugin-kit-routes',
const action = ACTIONS.lang_site_contract_siteId_contractId('sendSomething', {
Expand Down
7 changes: 7 additions & 0 deletions packages/vite-plugin-kit-routes/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export default defineConfig({

extend: {
PAGES: {
subGroup2: {
explicit_search_params: {
first: {
required: true,
},
},
},
lang_site: {
// extra_search_params: 'with',
explicit_search_params: { limit: { type: 'number' } },
Expand Down
89 changes: 72 additions & 17 deletions website/src/pages/docs/tools/06_vite-plugin-kit-routes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,76 @@ import { Callout } from '@theguild/components'

# ⚡How to - `vite-plugin-kit-routes`

Never be out of sync with your routes again 🥳
`vite-plugin-kit-routes` automatically updates route references in SvelteKit projects, crucial for
large applications where manual tracking of route changes is error-prone. It simplifies development
by ensuring all route links are consistent and up-to-date, saving time and preventing broken links.

<Callout>It's very early, things might change! 😉</Callout>
You will essentially have 3 objects at your disposal: `PAGES`, `SERVERS` and `ACTIONS` and instead
of hardcode strings, you will use these objects that are always up to date with your routes.

By default, no Configuration is needed, it will just infer as much as it can from your project. Then
you will be able to narrow down types & search params.
No more 🤞, now be confident ✅!

By default, no Configuration is requiered. Just [Install](#installation) the plugin, and use objects
available in your `$lib/ROUTES.ts` generated file _(always in sync)_.

## Examples

```svelte filename="+page.svelte" {2, 9}
```svelte filename="PAGES - First example" {2, 9}
<script lang="ts">
import { PAGES } from '$lib/ROUTES'
</script>

<!-- 🤞 before, random string -->
<a href="/terms-and-conditions">Terms</a>

<!-- ✅ after, make sure it exist. // 'vite-plugin-kit-routes' -->
<a href={PAGES['/terms-and-conditions']}>Terms</a>
<!--
If you change location of `/terms-and-conditions/+page.svelte`:
- the key '/terms-and-conditions' will not exist
- `PAGES` object will yield!
-->
```

```svelte filename="PAGES - With 1 route param" {2, 9}
<script lang="ts">
import { PAGES } from '$lib/ROUTES'
</script>

<!-- 🤞 before, random string -->
<a href="/site_contract/{siteId}-{contractId}?limit={3}">Go to site</a>
<a href="/site_contract/{siteId}">Go to site</a>

<!-- ✅ after, all typed & make sure it exist. // 'vite-plugin-kit-routes', -->
<a href={PAGES.site_contract_siteId_contractId({ siteId, contractId, limit: 3 })}>Go to site</a>
<!-- ✅ after, all typed & make sure it exist. // 'vite-plugin-kit-routes' -->
<a href={PAGES['/site_contract/{siteId}']({ siteId })}>Go to site</a>
```

```svelte filename="+page.svelte" {4, 13}
```svelte filename="PAGES - With 1 Search Param*" {2, 9}
<script lang="ts">
import { PAGES } from '$lib/ROUTES'
</script>

<!-- 🤞 before, random string -->
<a href="/site_contract/{siteId}?limit={3}">Go to site</a>

<!-- ✅ after, all typed & make sure it exist. // 'vite-plugin-kit-routes' -->
<a href={PAGES['/site_contract/{siteId}']({ siteId, limit: 3 })}>Go to site</a>
```

<em>* You can add a lot of configs to specify search params, types, ...</em>

```svelte filename="ACTIONS - With a named action" {4, 12}
<script lang="ts">
import { enhance } from '$app/forms'
import { page } from '$app/stores'
import { ACTIONS } from '$lib/ROUTES'

const siteId = $page.params.siteId
const contractId = $page.params.contractId

// 🤞 before, random string
const action = `/site_contract/${siteId}-${contractId}?/sendSomething`
const action = `/site_contract/${siteId}?/sendSomething`

// ✅ after, all typed & make sure it exist. // 'vite-plugin-kit-routes',
const action = ACTIONS.site_contract_siteId_contractId('sendSomething', { siteId, contractId })
const action = ACTIONS['/site_contract/${siteId}']('sendSomething', { siteId })
</script>

<form method="POST" use:enhance {action}>
Expand All @@ -54,26 +89,41 @@ npm i -D vite-plugin-kit-routes

Add the plugin like this:

```js filename="vite.config.js"
```js filename="vite.config.js" {2, 9}
import { sveltekit } from '@sveltejs/kit/vite'
import { kitRoutes } from 'vite-plugin-kit-routes'

/** @type {import('vite').UserConfig} */
const config = {
plugins: [
// This is the plugin to add
sveltekit(),
// ✅ Add the plugin
kitRoutes()
]
}

export default config
```

It will create a file `./src/lib/ROUTES.ts` at the start of your dev server & any update of any of
It will generate a file `./src/lib/ROUTES.ts` at the start of your dev server & any update of any of
your `+page.svelte` | `+server.ts` | `+page.server.ts`.

## Side Notes

- You can run prettier at the end of the process with something like:
<Callout>You can make use of `ctrl + space` to discover config options. 🎉</Callout>

- What kind of person are you: `PAGES['/terms']` or `PAGES.terms` ?

_You can choose anyway 😜_

```ts filename="vite.config.ts"
kitRoutes({
// object_keys_format: '/' (default)
object_keys_format: '_'
})
```

- You like nice and formated files? You can add **any** cmd after the generation

```ts filename="vite.config.ts"
kitRoutes({
Expand Down Expand Up @@ -114,7 +164,7 @@ kitRoutes({
})
```

- Then, you can add the `KIT_ROUTES` type... It will be crazy good!
- Then, you can add the `KIT_ROUTES` type... It will be crazy good! I'm not sure you are ready!

```ts filename="vite.config.ts"
import type { KIT_ROUTES } from '$lib/ROUTES'
Expand All @@ -124,3 +174,8 @@ kitRoutes<KIT_ROUTES>({
// Conf
})
```

---

Let me know what I forgot to add on [TwiX](https://twitter.com/jycouet), or what you would like to
see in the future. 🙏