Skip to content

Commit

Permalink
Upgrade @snout/router-path
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Sep 4, 2021
1 parent 1951431 commit 6d1c8ed
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 23 deletions.
9 changes: 8 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
module.exports = require('@snout/jest-config')
module.exports = {
...require('@snout/jest-config'),
globals: {
'ts-jest': {
tsconfig: 'test/tsconfig.json',
},
},
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@snout/eslint-config": "^2.0.0",
"@snout/jest-config": "^1.0.2",
"@snout/rollup-config": "^1.1.2",
"@snout/router-path": "^0.3.0",
"@snout/router-path": "^0.4.0",
"@snout/tsconfig": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
Expand Down
2 changes: 1 addition & 1 deletion src/coercion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function int<Name extends string> (name: Name): Param<Name, number> {
return {
name,
exp: /(0|[1-9]\d*)/,
build: arg => `${Math.floor(arg)}`,
parse: match => parseInt(match, 10),
format: arg => `${Math.floor(arg)}`,
}
}
14 changes: 6 additions & 8 deletions src/optional.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AnyParam, NormalizeParam, Param, param, ParamArg, ParamOrString} from '@snout/router-path'
import {AnyParam, normalizeParam, NormalizeParam, Param, ParamArg, ParamOrString} from '@snout/router-path'
import {escape} from '@snout/regexp'

export function optional<InnerParam extends ParamOrString> (
Expand All @@ -10,20 +10,18 @@ export function optional<InnerParam extends ParamOrString> (

if (literals.length !== 2) throw new Error('Invalid param count')

const [start, end] = literals
const {build, exp, name, parse} = typeof inner === 'string'
? param(inner) as NormalizedParam
: inner as NormalizedParam
const [start, end] = literals as unknown as [string, string]
const {name, exp, parse, format} = normalizeParam(inner)

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
name,
exp: new RegExp(`(?:${escape(start)}${exp.source}${escape(end)})?`),
build: (arg: Arg) => arg == null ? '' : `${start}${build(arg)}${end}`,
parse: match => match === '' ? undefined : parse(match),
format: (arg: Arg) => arg == null ? '' : `${start}${format(arg)}${end}`,
} as OptionalParam<NormalizeParam<InnerParam>>
}

type OptionalParam<InnerParam extends AnyParam> = InnerParam extends Param<infer Name, infer Arg, infer Result>
? Param<Name, Arg | undefined, Result | undefined>
type OptionalParam<InnerParam extends AnyParam> = InnerParam extends Param<infer Name, infer Arg>
? Param<Name, Arg | undefined>
: AnyParam
12 changes: 6 additions & 6 deletions src/repeating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ export function any<Name extends string> (
exp: RegExp = /[^/]+/,
separator: string = '/',
prefix: string = separator,
): Param<Name, string[], Partial<string[]>> {
): Param<Name, string[]> {
return {
name,
exp: new RegExp(`${arrayParamPattern(exp, prefix, separator)}?`),
build: arg => arg.length > 0 ? `${prefix}${arg.join(separator)}` : '',
parse: match => match === '' ? [] : match.split(separator),
format: arg => arg.length > 0 ? `${prefix}${arg.join(separator)}` : '',
}
}

Expand All @@ -20,16 +20,16 @@ export function some<Name extends string> (
exp: RegExp = /[^/]+/,
separator: string = '/',
prefix: string = separator,
): Param<Name, string[], SomeParamResult> {
): Param<Name, SomeArg> {
return {
name,
exp: new RegExp(arrayParamPattern(exp, prefix, separator)),
build: arg => `${prefix}${arg.join(separator)}`,
parse: match => match.split(separator) as SomeParamResult,
parse: match => match.split(separator) as SomeArg,
format: arg => `${prefix}${arg.join(separator)}`,
}
}

type SomeParamResult = { [0]: string } & Partial<string[]>
type SomeArg = [string, ...string[]]

function arrayParamPattern (exp: RegExp, prefix: string, separator: string): string {
const segmentExp = `(?:${exp.source})`
Expand Down
2 changes: 1 addition & 1 deletion src/slash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export function createSlash<Name extends string> (name: Name): Param<Name, boole
return {
name,
exp: /(\/)?/,
build: arg => arg ? '/' : '',
parse: match => match !== '',
format: arg => arg ? '/' : '',
}
}

Expand Down
6 changes: 6 additions & 0 deletions test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "@snout/tsconfig",
"compilerOptions": {
"noUncheckedIndexedAccess": true
}
}
11 changes: 6 additions & 5 deletions test/unit/optional.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import {param, path} from '@snout/router-path'
import {normalizeParam, path} from '@snout/router-path'

import {int} from '../../src/coercion'
import {optional} from '../../src/optional'

describe('optional()', () => {
it('should allow building with or without a defined arg', () => {
const subject = path`/a/${'p1'}${optional`/b/${param('p2')}/c`}/d`
const subject = path`/a/${'p1'}${optional`/b/${'p2'}/c`}/d`

expect(subject.build({p1: 'x', p2: 'y'})).toBe('/a/x/b/y/c/d')
expect(subject.build({p1: 'x', p2: undefined})).toBe('/a/x/d')
expect(subject.build({p1: 'x'})).toBe('/a/x/d')
})

it('should allow building when the inner param is specified as a string', () => {
const subject = path`/a/${'p1'}${optional`/b/${'p2'}/c`}/d`
it('should allow building when the inner param is specified as a parameter object', () => {
const p2 = normalizeParam('p2')
const subject = path`/a/${'p1'}${optional`/b/${p2}/c`}/d`

expect(subject.build({p1: 'x', p2: 'y'})).toBe('/a/x/b/y/c/d')
expect(subject.build({p1: 'x', p2: undefined})).toBe('/a/x/d')
expect(subject.build({p1: 'x'})).toBe('/a/x/d')
})

it('should match with or without the optional section', () => {
const subject = path`/a/${'p1'}${optional`/b/${param('p2')}/c`}/d`
const subject = path`/a/${'p1'}${optional`/b/${'p2'}/c`}/d`

expect(subject.match('/a/x/b/y/c/d')).toStrictEqual({p1: 'x', p2: 'y'})
expect(subject.match('/a/x/d')).toStrictEqual({p1: 'x', p2: undefined})
Expand Down

0 comments on commit 6d1c8ed

Please sign in to comment.