Skip to content

Commit c9552a5

Browse files
committed
refactor: revert renaming pad util, add and use TreeNode.isNamed() method, minor optimizations
1 parent 59c3a23 commit c9552a5

File tree

7 files changed

+61
-24
lines changed

7 files changed

+61
-24
lines changed

src/codegen/generateDTS.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ts, indent } from '../utils'
1+
import { ts, pad } from '../utils'
22

33
/**
44
* Removes empty lines and indent by two spaces to match the rest of the file.
@@ -10,7 +10,7 @@ function normalizeLines(code: string) {
1010
// FIXME: the code should be cleaned up by the codegen functions. Removing empty lines here
1111
// reduces readability of the route file info map.
1212
.filter((line) => line.length !== 0)
13-
.map((line) => indent(2, line))
13+
.map((line) => pad(2, line))
1414
.join('\n')
1515
)
1616
}

src/codegen/generateRouteFileInfoMap.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,12 @@ function generateRouteFileInfoLines(
7979

8080
const routeNames = [node, ...node.getChildrenDeepSorted()]
8181
// an unnamed route cannot be accessed in types
82-
.filter((node): node is TreeNode & { name: string } => !!node.name)
83-
.map((node) => node.name)
82+
.reduce<string[]>((acc, node) => {
83+
if (node.isNamed()) {
84+
acc.push(node.name)
85+
}
86+
return acc
87+
}, [])
8488

8589
// Most of the time we only have one view, but with named views we can have multiple.
8690
const currentRouteInfo =

src/codegen/generateRouteMap.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { TreeNode } from '../core/tree'
1+
import type { TreeNode, TreeNodeNamed } from '../core/tree'
22
import { generateRouteParams } from './generateRouteParams'
3-
import { indent, formatMultilineUnion, stringToStringType } from '../utils'
3+
import { pad, formatMultilineUnion, stringToStringType } from '../utils'
44

55
export function generateRouteNamedMap(node: TreeNode): string {
66
if (node.isRoot()) {
@@ -11,19 +11,22 @@ ${node.getChildrenSorted().map(generateRouteNamedMap).join('')}}`
1111
return (
1212
// if the node has a filePath, it's a component, it has a routeName and it should be referenced in the RouteNamedMap
1313
// otherwise it should be skipped to avoid navigating to a route that doesn't render anything
14-
(node.value.components.size > 0 && node.name
15-
? indent(2, `'${node.name}': ${generateRouteRecordInfo(node)},\n`)
14+
(node.value.components.size && node.isNamed()
15+
? pad(
16+
2,
17+
`${stringToStringType(node.name)}: ${generateRouteRecordInfo(node)},\n`
18+
)
1619
: '') +
1720
(node.children.size > 0
1821
? node.getChildrenSorted().map(generateRouteNamedMap).join('\n')
1922
: '')
2023
)
2124
}
2225

23-
export function generateRouteRecordInfo(node: TreeNode) {
26+
export function generateRouteRecordInfo(node: TreeNodeNamed): string {
2427
const typeParams = [
25-
`'${node.name}'`,
26-
`'${node.fullPath}'`,
28+
stringToStringType(node.name),
29+
stringToStringType(node.fullPath),
2730
generateRouteParams(node, true),
2831
generateRouteParams(node, false),
2932
]
@@ -33,11 +36,12 @@ export function generateRouteRecordInfo(node: TreeNode) {
3336
? // TODO: remove Array.from() once Node 20 support is dropped
3437
Array.from(node.getChildrenDeep())
3538
// skip routes that are not added to the types
36-
.filter(
37-
(childRoute): childRoute is TreeNode & { name: string } =>
38-
childRoute.value.components.size > 0 && !!childRoute.name
39-
)
40-
.map((childRoute) => childRoute.name)
39+
.reduce<string[]>((acc, childRoute) => {
40+
if (childRoute.value.components.size && childRoute.isNamed()) {
41+
acc.push(childRoute.name)
42+
}
43+
return acc
44+
}, [])
4145
.sort()
4246
: []
4347

@@ -46,6 +50,6 @@ export function generateRouteRecordInfo(node: TreeNode) {
4650
)
4751

4852
return `RouteRecordInfo<
49-
${typeParams.map((line) => indent(4, line)).join(',\n')}
53+
${typeParams.map((line) => pad(4, line)).join(',\n')}
5054
>`
5155
}

src/codegen/generateRouteRecords.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getLang } from '@vue-macros/common'
22
import type { TreeNode } from '../core/tree'
33
import { ImportsMap } from '../core/utils'
44
import { type ResolvedOptions } from '../options'
5+
import { pad, stringToStringType } from '../utils'
56

67
/**
78
* Generate the route records for the given node.
@@ -48,8 +49,8 @@ ${node
4849
}
4950
}
5051

51-
const startIndent = ' '.repeat(indent * 2)
52-
const indentStr = ' '.repeat((indent + 1) * 2)
52+
const startIndent = pad(indent * 2)
53+
const indentStr = pad((indent + 1) * 2)
5354

5455
// TODO: should meta be defined a different way to allow preserving imports?
5556
// const meta = node.value.overrides.meta
@@ -62,10 +63,11 @@ ${node
6263
${indentStr}path: '${node.path}',
6364
${indentStr}${
6465
node.value.components.size
65-
? node.name
66-
? `name: '${node.name}',`
66+
? node.isNamed()
67+
? `name: ${stringToStringType(node.name)},`
6768
: `/* no name */`
68-
: `/* internal name: '${node.name}' */`
69+
: // node.name can still be false and we don't want that to result in string literal 'false'
70+
`/* internal name: ${typeof node.name === 'string' ? stringToStringType(node.name) : node.name} */`
6971
}
7072
${
7173
// component

src/core/tree.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,14 @@ describe('Tree', () => {
394394
name: 'custom',
395395
})
396396
expect(node.name).toBe('custom')
397+
expect(node.isNamed()).toBe(true)
397398

398399
node = tree.insert('auth/login', 'auth/login.vue')
399400
node.value.setOverride('', {
400401
name: 'custom-child',
401402
})
402403
expect(node.name).toBe('custom-child')
404+
expect(node.isNamed()).toBe(true)
403405
})
404406

405407
it('allows empty name to remove route from route map', () => {
@@ -408,21 +410,38 @@ describe('Tree', () => {
408410

409411
// Before setting empty name, it should use the default name
410412
expect(node.name).toBe('/some-route')
413+
expect(node.isNamed()).toBe(true)
411414

412415
// Set empty name
413416
node.value.setOverride('', {
414417
name: '',
415418
})
416419
expect(node.name).toBe('')
420+
expect(node.isNamed()).toBe(false)
421+
422+
// Set false name
423+
node.value.setOverride('', {
424+
name: false,
425+
})
426+
expect(node.name).toBe(false)
427+
expect(node.isNamed()).toBe(false)
417428

418429
// Test with nested route
419430
node = tree.insert('nested/child', 'nested/child.vue')
420431
expect(node.name).toBe('/nested/child')
432+
expect(node.isNamed()).toBe(true)
421433

422434
node.value.setOverride('', {
423435
name: '',
424436
})
425437
expect(node.name).toBe('')
438+
expect(node.isNamed()).toBe(false)
439+
440+
node.value.setOverride('', {
441+
name: false,
442+
})
443+
expect(node.name).toBe(false)
444+
expect(node.isNamed()).toBe(false)
426445
})
427446

428447
it('allows a custom path', () => {

src/core/tree.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export interface TreeNodeOptions extends ResolvedOptions {
1212
treeNodeOptions?: TreeNodeValueOptions
1313
}
1414

15+
export type TreeNodeNamed = TreeNode & {
16+
name: Extract<TreeNode['name'], string>
17+
}
18+
1519
export class TreeNode {
1620
/**
1721
* value of the node
@@ -290,6 +294,10 @@ export class TreeNode {
290294
)
291295
}
292296

297+
isNamed(): this is TreeNodeNamed {
298+
return !!this.name
299+
}
300+
293301
toString(): string {
294302
return `${this.value}${
295303
// either we have multiple names

src/utils/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const ts = String.raw
2121
* @param str The string to pad, none if omitted.
2222
* @returns The padded string.
2323
*/
24-
export function indent(spaces: number, str = ''): string {
24+
export function pad(spaces: number, str = ''): string {
2525
return `${' '.repeat(spaces)}${str}`
2626
}
2727

@@ -34,7 +34,7 @@ export function indent(spaces: number, str = ''): string {
3434
export function formatMultilineUnion(items: string[], spaces: number): string {
3535
return (items.length ? items : ['never'])
3636
.map((s) => `| ${s}`)
37-
.join(`\n${indent(spaces)}`)
37+
.join(`\n${pad(spaces)}`)
3838
}
3939

4040
/**

0 commit comments

Comments
 (0)