Skip to content

Commit

Permalink
Merge pull request #3 from IdoPesok/improvements
Browse files Browse the repository at this point in the history
fixed no params bug
  • Loading branch information
IdoPesok authored May 18, 2024
2 parents 76e6f9f + 395ce6e commit 61b9ac2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/good-poets-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"type-safe-paths": patch
---

Fix bug that required params object when there were no params
48 changes: 36 additions & 12 deletions packages/type-safe-paths/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import z from "zod"

type Length<T extends any[]> = T extends { length: infer L } ? L : never

type IsEmptyObject<T> = keyof T extends never ? true : false

type BuildTuple<L extends number, T extends any[] = []> = T extends {
length: L
}
Expand Down Expand Up @@ -30,6 +32,7 @@ type Path<
? never
:
| (TDepth extends 0 ? `/` : ``)
| "(.*)"
| `/${":" | ""}${Segment<TSegmentValue>}${Path<TSegmentValue, TDepth extends number ? Add<TDepth, 1> : never>}`

type TExtractPathFromString<T extends string> =
Expand Down Expand Up @@ -121,42 +124,63 @@ export const createPathHelpers = <
>(
registry: TRegistry
) => {
type TSearchParams<TKey extends keyof TRegistry["$registry"]> =
TRegistry["$registry"][TKey]["searchParams"]

type TParams<TKey extends keyof TRegistry["$registry"]> =
TRegistry["$registry"][TKey]["params"]

type TOpts<TKey extends keyof TRegistry["$registry"]> =
(TParams<TKey> extends never
? {}
: {
params: {
[k in TRegistry["$registry"][TKey]["params"]]: string
}
}) &
(TSearchParams<TKey> extends z.AnyZodObject
? {
searchParams: z.input<TSearchParams<TKey>>
}
: {}) & {}

const buildPath = <TKey extends keyof TRegistry["$registry"]>(
k: TKey,
opts: {
params: {
[k in TRegistry["$registry"][TKey]["params"]]: string
}
} & (TRegistry["$registry"][TKey]["searchParams"] extends z.AnyZodObject
? {
searchParams: z.input<TRegistry["$registry"][TKey]["searchParams"]>
}
: {})
...optsArr: IsEmptyObject<TOpts<TKey>> extends true ? [] : [TOpts<TKey>]
): string => {
let mutatedPath = k.toString()

const opts = optsArr[0]

// replace params in path
if (opts.params) {
if (opts && "params" in opts && opts.params) {
for (const [key, value] of Object.entries(opts.params)) {
mutatedPath = mutatedPath.replace(`:${key}`, value as string)
}
}

const dummyBase = "http://localhost"

// remove regex from path
if (mutatedPath.includes("(.*)")) {
mutatedPath = mutatedPath.replace("(.*)", "")
}

const url = new URL(mutatedPath, dummyBase)

if (!("searchParams" in opts)) {
if (opts && !("searchParams" in opts)) {
return url.pathname
}

let parsed = opts.searchParams
let parsed = opts && "searchParams" in opts ? opts.searchParams : undefined

const schema = registry.$dataMap[k].searchParamsSchema || undefined
if (schema) {
parsed = schema.parse(parsed)
}

if (!parsed) return url.pathname

// add search params
for (const [key, value] of Object.entries(parsed)) {
url.searchParams.set(key, JSON.stringify(value))
Expand Down
17 changes: 17 additions & 0 deletions packages/type-safe-paths/src/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ const paths = new TypeSafePaths({
optional: z.string().default(" the parsing worked"),
}),
})
.add("/posts", {
metadata: {
allowedPermissions: ["user"],
testing: "hello world",
},
searchParams: z.object({
query: z.string().optional(),
}),
})
.add("/api(.*)", {
metadata: {
allowedPermissions: ["user"],
testing: "hello world",
},
})

const {
buildPath,
Expand Down Expand Up @@ -63,3 +78,5 @@ console.log(
"/posts/details/:postId/:commentId"
)
)

console.log(buildPath("/api(.*)"))

0 comments on commit 61b9ac2

Please sign in to comment.