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

add formats `route(path) & object[path]` AND `route(symbol) & object[symbol]` exporting everything
11 changes: 9 additions & 2 deletions packages/vite-plugin-kit-routes/src/lib/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ type ExtendTypes = {
}

type LogKind = 'update' | 'post_update_run' | 'errors' | 'stats'
type FormatKind = 'route(path)' | 'route(symbol)' | 'variables' | 'object[path]' | 'object[symbol]'
type FormatKind =
| 'route(path)'
| 'route(symbol)'
| 'variables'
| 'object[path]'
| 'object[symbol]'
| 'route(path) & object[path]'
| 'route(symbol) & object[symbol]'

export type Options<T extends ExtendTypes = ExtendTypes> = {
/**
Expand Down Expand Up @@ -810,7 +817,7 @@ ${c.files
.map(c => {
return (
`/**\n * ${c.type}\n */
${options?.format?.includes('route') ? `` : `export `}` +
${options?.format?.includes('object') ? `export ` : ``}` +
`const ${c.type} = {
${c.files
.map(key => {
Expand Down
112 changes: 92 additions & 20 deletions packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ describe('run()', async () => {
},
}

const commonConfig_symbol: Options<KIT_ROUTES_ObjectSymbol> = {
const commonConfig_variables: Options<KIT_ROUTES_ObjectSymbol> = {
PAGES: {
subGroup2: {
explicit_search_params: {
Expand Down Expand Up @@ -367,36 +367,37 @@ describe('run()', async () => {

const commonConfig_Path: Options<KIT_ROUTES_ObjectPath> = {
PAGES: {
'/subGroup2': commonConfig_symbol.PAGES?.subGroup2,
'/contract': commonConfig_symbol.PAGES?.contract,
'/site': commonConfig_symbol.PAGES?.site,
'/site/[id]': commonConfig_symbol.PAGES?.site_id,
'/match/[id=int]': commonConfig_symbol.PAGES?.match_id_int,
'/subGroup2': commonConfig_variables.PAGES?.subGroup2,
'/contract': commonConfig_variables.PAGES?.contract,
'/site': commonConfig_variables.PAGES?.site,
'/site/[id]': commonConfig_variables.PAGES?.site_id,
'/match/[id=int]': commonConfig_variables.PAGES?.match_id_int,
'/site_contract/[siteId]-[contractId]':
commonConfig_symbol.PAGES?.site_contract_siteId_contractId,
commonConfig_variables.PAGES?.site_contract_siteId_contractId,
},
SERVERS: {},
ACTIONS: {
'default /contract/[id]': commonConfig_symbol.ACTIONS?.default_contract_id,
'default /contract/[id]': commonConfig_variables.ACTIONS?.default_contract_id,
'send /site_contract/[siteId]-[contractId]':
commonConfig_symbol.ACTIONS?.send_site_contract_siteId_contractId,
commonConfig_variables.ACTIONS?.send_site_contract_siteId_contractId,
},
}

const commonConfig_symbol_space: Options<KIT_ROUTES_RouteSymbol> = {
const commonConfig_symbol: Options<KIT_ROUTES_RouteSymbol> = {
PAGES: {
subGroup2: commonConfig_symbol.PAGES?.subGroup2,
contract: commonConfig_symbol.PAGES?.contract,
site: commonConfig_symbol.PAGES?.site,
site_id: commonConfig_symbol.PAGES?.site_id,
match_id_int: commonConfig_symbol.PAGES?.match_id_int,
site_contract_siteId_contractId: commonConfig_symbol.PAGES?.site_contract_siteId_contractId,
subGroup2: commonConfig_variables.PAGES?.subGroup2,
contract: commonConfig_variables.PAGES?.contract,
site: commonConfig_variables.PAGES?.site,
site_id: commonConfig_variables.PAGES?.site_id,
match_id_int: commonConfig_variables.PAGES?.match_id_int,
site_contract_siteId_contractId:
commonConfig_variables.PAGES?.site_contract_siteId_contractId,
},
SERVERS: {},
ACTIONS: {
'default contract_id': commonConfig_symbol.ACTIONS?.default_contract_id,
'default contract_id': commonConfig_variables.ACTIONS?.default_contract_id,
'send site_contract_siteId_contractId':
commonConfig_symbol.ACTIONS?.send_site_contract_siteId_contractId,
commonConfig_variables.ACTIONS?.send_site_contract_siteId_contractId,
},
}

Expand All @@ -420,7 +421,7 @@ describe('run()', async () => {
{
pathFile: 'format-object-symbol',
format: 'object[symbol]',
extra: { ...commonConfig, ...commonConfig_symbol },
extra: { ...commonConfig, ...commonConfig_variables },
},
{
pathFile: 'format-route-path',
Expand All @@ -430,11 +431,21 @@ describe('run()', async () => {
{
pathFile: 'format-route-symbol',
format: 'route(symbol)',
extra: { ...commonConfig, ...commonConfig_symbol_space },
extra: { ...commonConfig, ...commonConfig_symbol },
},
{
pathFile: 'format-variables',
format: 'variables',
extra: { ...commonConfig, ...commonConfig_variables },
},
{
pathFile: 'format-route-and-object-path',
format: 'route(path) & object[path]',
extra: { ...commonConfig, ...commonConfig_Path },
},
{
pathFile: 'format-route-and-object-symbol',
format: 'route(symbol) & object[symbol]',
extra: { ...commonConfig, ...commonConfig_symbol },
},
] as const
Expand Down Expand Up @@ -631,6 +642,67 @@ describe('run()', async () => {
)
})

//
it('format route(path) & object[path]', async () => {
let { route, PAGES, SERVERS, ACTIONS, LINKS } = await import(
getPathROUTES(runs[5].pathFile)
)
// route
expect(route(element.key_path, ...element.params), element.name).toBe(element.results)
const obj = findObj(element.kind, PAGES, SERVERS, ACTIONS, LINKS)

// object
expect(fnOrNot(obj, element.key_path, ...element.params), element.name).toBe(
element.results,
)
})
// SHORTENED
it('format route(path) & object[path] shortened', async () => {
let { route, PAGES, SERVERS, ACTIONS, LINKS } = await import(
getPathROUTES(getToRunShortened(runs[5]).pathFile)
)
// route
expect(route(element.key_path, ...element.params_shortened), element.name).toBe(
element.results,
)
// object
const obj = findObj(element.kind, PAGES, SERVERS, ACTIONS, LINKS)
expect(fnOrNot(obj, element.key_path, ...element.params_shortened), element.name).toBe(
element.results,
)
})

//
it('format route(symbol) & object[symbol]', async () => {
let { route, PAGES, SERVERS, ACTIONS, LINKS } = await import(
getPathROUTES(runs[6].pathFile)
)
// route
expect(route(element.key_symbol, ...element.params), element.name).toBe(element.results)
const obj = findObj(element.kind, PAGES, SERVERS, ACTIONS, LINKS)

// object
expect(fnOrNot(obj, element.key_symbol, ...element.params), element.name).toBe(
element.results,
)
})
// SHORTENED
it('format route(symbol) & object[symbol] shortened', async () => {
let { route, PAGES, SERVERS, ACTIONS, LINKS } = await import(
getPathROUTES(getToRunShortened(runs[6]).pathFile)
)
// route
expect(route(element.key_symbol, ...element.params_shortened), element.name).toBe(
element.results,
)

// object
const obj = findObj(element.kind, PAGES, SERVERS, ACTIONS, LINKS)
expect(fnOrNot(obj, element.key_symbol, ...element.params_shortened), element.name).toBe(
element.results,
)
})

// VARIABLES && SHORTENED
it('format variables', async () => {
let vars___not = await import(getPathROUTES(runs[4].pathFile))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/**
* This file was generated by 'vite-plugin-kit-routes'
*
* >> DO NOT EDIT THIS FILE MANUALLY <<
*/

/**
* PAGES
*/
export const PAGES = {
"/": `/`,
"/subGroup": `/subGroup`,
"/subGroup/user": `/subGroup/user`,
"/subGroup2": (params: { first: (string | number) }) => {
return `/subGroup2${appendSp({ first: params.first })}`
},
"/contract": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }, sp?: Record<string, string | number>) => {
return `${params?.lang ? `/${params?.lang}`: ''}/contract${appendSp(sp)}`
},
"/contract/[id]": (params: { id: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/contract/${params.id}`
},
"/gp/one": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/gp/one`
},
"/gp/two": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/gp/two`
},
"/main": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/main`
},
"/match/[id=ab]": (params: { id: (Parameters<typeof import('../params/ab.ts').match>[0]), lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/match/${params.id}`
},
"/match/[id=int]": (params: { id: (number), lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/match/${params.id}`
},
"/site": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string), limit?: (number) }, sp?: Record<string, string | number>) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site${appendSp({ ...sp, limit: params?.limit })}`
},
"/site/[id]": (params?: { lang?: ('fr' | 'hu' | undefined), id?: (string), limit?: (number), demo?: (string) }) => {
params = params ?? {}
params.lang = params.lang ?? "fr";
params.id = params.id ?? "Vienna";
return `${params?.lang ? `/${params?.lang}`: ''}/site/${params.id}${appendSp({ limit: params?.limit, demo: params?.demo })}`
},
"/site_contract/[siteId]-[contractId]": (params: { siteId: (string | number), contractId: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string), limit?: (number) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site_contract/${params.siteId}-${params.contractId}${appendSp({ limit: params?.limit })}`
},
"/a/[...rest]/z": (params: { rest: (string | number)[] }) => {
return `/a/${params.rest?.join('/')}/z`
},
"/lay/normal": `/lay/normal`,
"/lay/root-layout": `/lay/root-layout`,
"/lay/skip": `/lay/skip`,
"/sp": `/sp`
}

/**
* SERVERS
*/
export const SERVERS = {
"GET /contract": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/contract`
},
"POST /contract": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/contract`
},
"GET /site": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site`
},
"GET /api/graphql": `/api/graphql`,
"POST /api/graphql": `/api/graphql`,
"GET /data/errors/[locale].json": (params: { locale: (string | number) }) => {
return `/data/errors/${params.locale}.json`
}
}

/**
* ACTIONS
*/
export const ACTIONS = {
"default /contract/[id]": (params: { id: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string), limit?: (number) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/contract/${params.id}${appendSp({ limit: params?.limit })}`
},
"create /site": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site?/create`
},
"update /site/[id]": (params: { id: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site/${params.id}?/update`
},
"delete /site/[id]": (params: { id: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site/${params.id}?/delete`
},
"noSatisfies /site_contract": (params?: { lang?: ('fr' | 'en' | 'hu' | 'at' | string) }) => {
return `${params?.lang ? `/${params?.lang}`: ''}/site_contract?/noSatisfies`
},
"send /site_contract/[siteId]-[contractId]": (params: { siteId: (string | number), contractId: (string | number), lang?: ('fr' | 'en' | 'hu' | 'at' | string), extra?: ('A' | 'B') }) => {
params.extra = params.extra ?? "A";
return `${params?.lang ? `/${params?.lang}`: ''}/site_contract/${params.siteId}-${params.contractId}?/send${appendSp({ extra: params?.extra }, '&')}`
}
}

/**
* LINKS
*/
export const LINKS = {
"twitter": `https://twitter.com/jycouet`,
"twitter_post": (params: { name: (string | number), id: (string | number) }) => {
return `https://twitter.com/${params.name}/status/${params.id}`
},
"gravatar": (params: { str: (string | number), s?: (number), d?: ("retro" | "identicon") }) => {
params.s = params.s ?? 75;
params.d = params.d ?? "identicon";
return `https://www.gravatar.com/avatar/${params.str}${appendSp({ s: params?.s, d: params?.d })}`
}
}

/**
* Append search params to a string
*/
const appendSp = (sp?: Record<string, string | number | undefined>, prefix: '?' | '&' = '?') => {
if (sp === undefined) return ''
const mapping = Object.entries(sp)
.filter(c => c[1] !== undefined)
.map(c => [c[0], String(c[1])])

const formated = new URLSearchParams(mapping).toString()
if (formated) {
return `${prefix}${formated}`
}
return ''
}

/**
* get the current search params
*
* Could be use like this:
* ```
* route("/cities", { page: 2 }, { ...currentSP() })
* ```
*/
export const currentSp = () => {
const params = new URLSearchParams(window.location.search)
const record: Record<string, string> = {}
for (const [key, value] of params.entries()) {
record[key] = value
}
return record
}

// route function helpers
type NonFunctionKeys<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]
type FunctionKeys<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]
type FunctionParams<T> = T extends (...args: infer P) => any ? P : never

const AllObjs = { ...PAGES, ...ACTIONS, ...SERVERS, ...LINKS }
type AllTypes = typeof AllObjs

/**
* To be used like this:
* ```ts
* import { route } from '$lib/ROUTES'
*
* route('site_id', { id: 1 })
* ```
*/
export function route<T extends FunctionKeys<AllTypes>>(key: T, ...params: FunctionParams<AllTypes[T]>): string
export function route<T extends NonFunctionKeys<AllTypes>>(key: T): string
export function route<T extends keyof AllTypes>(key: T, ...params: any[]): string {
if (AllObjs[key] as any instanceof Function) {
const element = (AllObjs as any)[key] as (...args: any[]) => string
return element(...params)
} else {
return AllObjs[key] as string
}
}

/**
* Add this type as a generic of the vite plugin `kitRoutes<KIT_ROUTES>`.
*
* Full example:
* ```ts
* import type { KIT_ROUTES } from '$lib/ROUTES'
* import { kitRoutes } from 'vite-plugin-kit-routes'
*
* kitRoutes<KIT_ROUTES>({
* PAGES: {
* // here, key of object will be typed!
* }
* })
* ```
*/
export type KIT_ROUTES = {
PAGES: { '/': never, '/subGroup': never, '/subGroup/user': never, '/subGroup2': never, '/contract': 'lang', '/contract/[id]': 'id' | 'lang', '/gp/one': 'lang', '/gp/two': 'lang', '/main': 'lang', '/match/[id=ab]': 'id' | 'lang', '/match/[id=int]': 'id' | 'lang', '/site': 'lang', '/site/[id]': 'lang' | 'id', '/site_contract/[siteId]-[contractId]': 'siteId' | 'contractId' | 'lang', '/a/[...rest]/z': 'rest', '/lay/normal': never, '/lay/root-layout': never, '/lay/skip': never, '/sp': never }
SERVERS: { 'GET /contract': 'lang', 'POST /contract': 'lang', 'GET /site': 'lang', 'GET /api/graphql': never, 'POST /api/graphql': never, 'GET /data/errors/[locale].json': 'locale' }
ACTIONS: { 'default /contract/[id]': 'id' | 'lang', 'create /site': 'lang', 'update /site/[id]': 'id' | 'lang', 'delete /site/[id]': 'id' | 'lang', 'noSatisfies /site_contract': 'lang', 'send /site_contract/[siteId]-[contractId]': 'siteId' | 'contractId' | 'lang' }
LINKS: { 'twitter': never, 'twitter_post': 'name' | 'id', 'gravatar': 'str' }
Params: { first: never, lang: never, id: never, limit: never, demo: never, siteId: never, contractId: never, rest: never, locale: never, extra: never, name: never, str: never, s: never, d: never }
}
Loading