@wavelengthusaf/client-router 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/src/elements/RouteElement.d.ts +11 -0
  2. package/dist/src/elements/RouteElement.d.ts.map +1 -0
  3. package/dist/src/elements/RouterElement.d.ts +12 -0
  4. package/dist/src/elements/RouterElement.d.ts.map +1 -0
  5. package/dist/src/index.d.ts +6 -0
  6. package/dist/src/index.d.ts.map +1 -0
  7. package/dist/src/models/CompiledRoute.d.ts +7 -0
  8. package/dist/src/models/CompiledRoute.d.ts.map +1 -0
  9. package/dist/src/models/MatchedRoute.d.ts +7 -0
  10. package/dist/src/models/MatchedRoute.d.ts.map +1 -0
  11. package/dist/src/models/RouteComponent.d.ts +6 -0
  12. package/dist/src/models/RouteComponent.d.ts.map +1 -0
  13. package/dist/src/models/RouteContext.d.ts +7 -0
  14. package/dist/src/models/RouteContext.d.ts.map +1 -0
  15. package/dist/src/models/RouteDefinition.d.ts +6 -0
  16. package/dist/src/models/RouteDefinition.d.ts.map +1 -0
  17. package/dist/src/models/RouteGuard.d.ts +3 -0
  18. package/dist/src/models/RouteGuard.d.ts.map +1 -0
  19. package/dist/src/models/RouteParams.d.ts +4 -0
  20. package/dist/src/models/RouteParams.d.ts.map +1 -0
  21. package/dist/src/models/index.d.ts +9 -0
  22. package/dist/src/models/index.d.ts.map +1 -0
  23. package/dist/src/router/Router.d.ts +20 -0
  24. package/dist/src/router/Router.d.ts.map +1 -0
  25. package/dist/src/utils/compileRoute.d.ts +3 -0
  26. package/dist/src/utils/compileRoute.d.ts.map +1 -0
  27. package/dist/src/utils/index.d.ts +4 -0
  28. package/dist/src/utils/index.d.ts.map +1 -0
  29. package/dist/src/utils/matchRoute.d.ts +3 -0
  30. package/dist/src/utils/matchRoute.d.ts.map +1 -0
  31. package/package.json +7 -1
  32. package/.gitlab-ci.yml +0 -84
  33. package/.husky/pre-commit +0 -38
  34. package/.storybook/main.ts +0 -16
  35. package/.storybook/manager.ts +0 -7
  36. package/.storybook/preview.ts +0 -23
  37. package/.storybook/theme.ts +0 -30
  38. package/.storybook/vitest.setup.ts +0 -7
  39. package/eslint.config.mjs +0 -89
  40. package/index.ts +0 -15
  41. package/prettier.config.ts +0 -30
  42. package/src/elements/RouteElement.ts +0 -67
  43. package/src/elements/RouterElement.ts +0 -97
  44. package/src/elements/__tests__/RouteElement.test.ts +0 -89
  45. package/src/elements/__tests__/RouterElement.test.ts +0 -253
  46. package/src/index.ts +0 -15
  47. package/src/models/CompiledRoute.ts +0 -7
  48. package/src/models/MatchedRoute.ts +0 -7
  49. package/src/models/RouteComponent.ts +0 -6
  50. package/src/models/RouteContext.ts +0 -7
  51. package/src/models/RouteDefinition.ts +0 -6
  52. package/src/models/RouteGuard.ts +0 -6
  53. package/src/models/RouteParams.ts +0 -3
  54. package/src/models/index.ts +0 -17
  55. package/src/router/Router.ts +0 -225
  56. package/src/router/__tests__/Router.test.ts +0 -464
  57. package/src/stories/RouterElement.stories.test.ts +0 -310
  58. package/src/stories/RouterElement.stories.ts +0 -208
  59. package/src/utils/__tests__/compileRoute.test.ts +0 -97
  60. package/src/utils/__tests__/matchRoute.test.ts +0 -180
  61. package/src/utils/compileRoute.ts +0 -37
  62. package/src/utils/index.ts +0 -4
  63. package/src/utils/matchRoute.ts +0 -37
  64. package/tsconfig.build.json +0 -20
  65. package/tsconfig.json +0 -55
  66. package/vitest.config.ts +0 -34
  67. package/vitest.setup.ts +0 -3
  68. package/vitest.shims.d.ts +0 -1
@@ -1,180 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { matchRoute } from '../matchRoute.ts';
3
-
4
- function route(path: string, paramNames: string[] = []) {
5
- return {
6
- routeDefinition: { path },
7
- pattern: new RegExp(`^${path.replace(':id', '([^/]+)')}$`),
8
- paramNames,
9
- };
10
- }
11
-
12
- describe('matchRoute', () => {
13
- describe('basic matching', () => {
14
- it.each([
15
- {
16
- routes: [route('/home')],
17
- path: '/home',
18
- expected: '/home',
19
- },
20
- {
21
- routes: [route('/about')],
22
- path: '/about',
23
- expected: '/about',
24
- },
25
- ])('matches static route %#', ({ routes, path, expected }) => {
26
- // @ts-expect-error (passing wrong parameters)
27
- const result = matchRoute(routes, path);
28
-
29
- expect(result?.routeDefinition.path).toBe(expected);
30
- });
31
- });
32
-
33
- describe('params', () => {
34
- it('extracts single param', () => {
35
- const routes = [
36
- {
37
- routeDefinition: { path: '/users/:id' },
38
- pattern: /^\/users\/([^/]+)$/,
39
- paramNames: ['id'],
40
- },
41
- ];
42
-
43
- // @ts-expect-error (passing wrong parameters)
44
- const result = matchRoute(routes, '/users/123');
45
-
46
- expect(result?.routeParams).toEqual({
47
- id: '123',
48
- });
49
- });
50
-
51
- it('extracts multiple params', () => {
52
- const routes = [
53
- {
54
- routeDefinition: { path: '/a/:x/b/:y' },
55
- pattern: /^\/a\/([^/]+)\/b\/([^/]+)$/,
56
- paramNames: ['x', 'y'],
57
- },
58
- ];
59
-
60
- // @ts-expect-error (passing wrong parameters)
61
- const result = matchRoute(routes, '/a/1/b/2');
62
-
63
- expect(result?.routeParams).toEqual({
64
- x: '1',
65
- y: '2',
66
- });
67
- });
68
- });
69
-
70
- describe('priority', () => {
71
- it('returns first matching route', () => {
72
- const routes = [
73
- {
74
- routeDefinition: { path: '/users' },
75
- pattern: /^\/users$/,
76
- paramNames: [],
77
- },
78
- {
79
- routeDefinition: { path: '/users/:id' },
80
- pattern: /^\/users\/([^/]+)$/,
81
- paramNames: ['id'],
82
- },
83
- ];
84
-
85
- // @ts-expect-error (passing wrong parameters)
86
- const result = matchRoute(routes, '/users');
87
-
88
- expect(result?.routeDefinition.path).toBe('/users');
89
- });
90
- });
91
-
92
- describe('no match', () => {
93
- it('returns null when no routes match', () => {
94
- const routes = [
95
- {
96
- routeDefinition: { path: '/a' },
97
- pattern: /^\/a$/,
98
- paramNames: [],
99
- },
100
- ];
101
-
102
- // @ts-expect-error (passing wrong parameters)
103
- const result = matchRoute(routes, '/b');
104
-
105
- expect(result).toBeNull();
106
- });
107
- });
108
-
109
- describe('decodeURIComponent', () => {
110
- it('decodes encoded values', () => {
111
- const routes = [
112
- {
113
- routeDefinition: { path: '/search/:query' },
114
- pattern: /^\/search\/([^/]+)$/,
115
- paramNames: ['query'],
116
- },
117
- ];
118
-
119
- // @ts-expect-error (passing wrong parameters)
120
- const result = matchRoute(routes, '/search/hello%20world');
121
-
122
- expect(result?.routeParams.query).toBe('hello world');
123
- });
124
- });
125
-
126
- describe('undefined capture safety', () => {
127
- it('skips param assignment when capture group is undefined', () => {
128
- const routes = [
129
- {
130
- routeDefinition: { path: '/test/:id/:missing' },
131
- pattern: /^\/test\/([^/]+)$/,
132
- paramNames: ['id', 'missing'],
133
- },
134
- ];
135
-
136
- // @ts-expect-error (passing wrong parameters)
137
- const result = matchRoute(routes, '/test/123');
138
-
139
- expect(result).not.toBeNull();
140
- expect(result!.routeParams).toEqual({
141
- id: '123',
142
- // missing should NOT exist
143
- });
144
- });
145
- });
146
-
147
- describe('malformed encoding', () => {
148
- it('does not throw on bad encoding', () => {
149
- const routes = [
150
- {
151
- routeDefinition: { path: '/test/:id' },
152
- pattern: /^\/test\/([^/]+)$/,
153
- paramNames: ['id'],
154
- },
155
- ];
156
-
157
- // @ts-expect-error (passing wrong parameters)
158
- const bad = () => matchRoute(routes, '/test/%E0%A4%A');
159
-
160
- expect(bad).not.toThrow();
161
- });
162
- });
163
-
164
- describe('strict matching', () => {
165
- it('does not match partial paths', () => {
166
- const routes = [
167
- {
168
- routeDefinition: { path: '/users/:id' },
169
- pattern: /^\/users\/([^/]+)$/,
170
- paramNames: ['id'],
171
- },
172
- ];
173
-
174
- // @ts-expect-error (passing wrong parameters)
175
- expect(matchRoute(routes, '/users/123/extra')).toBeNull();
176
- // @ts-expect-error (passing wrong parameters)
177
- expect(matchRoute(routes, '/users')).toBeNull();
178
- });
179
- });
180
- });
@@ -1,37 +0,0 @@
1
- import type { CompiledRoute, RouteDefinition } from '../models/index.ts';
2
-
3
- function escapeRegex(str: string): string {
4
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
5
- }
6
-
7
- export function compileRoute(routeDefinition: RouteDefinition): CompiledRoute {
8
- const paramNames: string[] = [];
9
-
10
- if (routeDefinition.path === '*') {
11
- return {
12
- routeDefinition,
13
- pattern: /^.*$/,
14
- paramNames,
15
- };
16
- }
17
-
18
- const pattern = routeDefinition.path
19
- .split('/')
20
- .map((segment) => {
21
- const match = /^:([a-zA-Z_]\w*)$/.exec(segment);
22
-
23
- if (match) {
24
- paramNames.push(match[1]!);
25
- return '([^/]+)';
26
- }
27
-
28
- return escapeRegex(segment);
29
- })
30
- .join('\\/');
31
-
32
- return {
33
- routeDefinition,
34
- pattern: new RegExp(`^${pattern}$`),
35
- paramNames,
36
- };
37
- }
@@ -1,4 +0,0 @@
1
- import { compileRoute } from './compileRoute.ts';
2
- import { matchRoute } from './matchRoute.ts';
3
-
4
- export { compileRoute, matchRoute };
@@ -1,37 +0,0 @@
1
- import type {
2
- CompiledRoute,
3
- MatchedRoute,
4
- RouteParams,
5
- } from '../models/index.ts';
6
-
7
- export function matchRoute(
8
- compiledRoutes: CompiledRoute[],
9
- pathname: string,
10
- ): MatchedRoute | null {
11
- for (const compiledRoute of compiledRoutes) {
12
- const match: RegExpMatchArray | null = compiledRoute.pattern.exec(pathname);
13
-
14
- if (!match) continue;
15
-
16
- const routeParams: RouteParams = {};
17
-
18
- compiledRoute.paramNames.forEach((name, i) => {
19
- const value: string | undefined = match[i + 1];
20
-
21
- if (value === undefined) return;
22
-
23
- try {
24
- routeParams[name] = decodeURIComponent(value);
25
- } catch {
26
- routeParams[name] = value;
27
- }
28
- });
29
-
30
- return {
31
- routeDefinition: compiledRoute.routeDefinition,
32
- routeParams,
33
- };
34
- }
35
-
36
- return null;
37
- }
@@ -1,20 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "declarationMap": true,
6
- "emitDeclarationOnly": true
7
- },
8
- "include": ["src/**/*.ts"],
9
- "exclude": [
10
- "node_modules",
11
- "dist",
12
- "coverage",
13
- "vitest.config.ts",
14
- "vitest.setup.ts",
15
- "vitest.shims.d.ts",
16
- ".storybook",
17
- "**/*.test.ts",
18
- "src/**/*.stories.ts"
19
- ]
20
- }
package/tsconfig.json DELETED
@@ -1,55 +0,0 @@
1
- {
2
- // Visit https://aka.ms/tsconfig to read more about this file
3
- "compilerOptions": {
4
- // File Layout
5
- "rootDir": ".",
6
- "outDir": "./dist",
7
-
8
- // Environment Settings
9
- // See also https://aka.ms/tsconfig/module
10
- "module": "nodenext",
11
- "target": "esnext",
12
- "types": [],
13
- // For nodejs:
14
- // "lib": ["esnext"],
15
- // "types": ["node"],
16
- // and npm install -D @types/node
17
-
18
- // Other Outputs
19
- "sourceMap": true,
20
- "declaration": true,
21
- "declarationMap": true,
22
- "emitDeclarationOnly": true,
23
-
24
- // Stricter Typechecking Options
25
- "noUncheckedIndexedAccess": true,
26
- "exactOptionalPropertyTypes": true,
27
- "allowImportingTsExtensions": true,
28
-
29
- // Style Options
30
- // "noImplicitReturns": true,
31
- // "noImplicitOverride": true,
32
- // "noUnusedLocals": true,
33
- // "noUnusedParameters": true,
34
- // "noFallthroughCasesInSwitch": true,
35
- // "noPropertyAccessFromIndexSignature": true,
36
-
37
- // Recommended Options
38
- "strict": true,
39
- // "jsx": "react-jsx",
40
- "verbatimModuleSyntax": true,
41
- "isolatedModules": true,
42
- "noUncheckedSideEffectImports": true,
43
- "moduleDetection": "force",
44
- "skipLibCheck": true
45
- },
46
- "exclude": [
47
- "node_modules",
48
- "dist",
49
- "coverage",
50
- "vitest.config.ts",
51
- "vitest.setup.ts",
52
- "vitest.shims.d.ts",
53
- ".storybook"
54
- ]
55
- }
package/vitest.config.ts DELETED
@@ -1,34 +0,0 @@
1
- import path from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import { defineConfig } from 'vitest/config';
4
-
5
- const dirname =
6
- typeof __dirname !== 'undefined'
7
- ? __dirname
8
- : path.dirname(fileURLToPath(import.meta.url));
9
-
10
- export default defineConfig({
11
- resolve: {
12
- alias: {
13
- '@': path.resolve(dirname, './src'),
14
- },
15
- },
16
- test: {
17
- environment: 'jsdom',
18
- globals: true,
19
- setupFiles: ['./vitest.setup.ts'],
20
- include: ['src/**/*.test.ts'],
21
- browser: {
22
- enabled: false,
23
- },
24
- coverage: {
25
- provider: 'v8',
26
- thresholds: {
27
- lines: 90,
28
- functions: 90,
29
- branches: 90,
30
- statements: 90,
31
- },
32
- }
33
- },
34
- });
package/vitest.setup.ts DELETED
@@ -1,3 +0,0 @@
1
- import { GlobalRegistrator } from '@happy-dom/global-registrator';
2
-
3
- GlobalRegistrator.register();
package/vitest.shims.d.ts DELETED
@@ -1 +0,0 @@
1
- /// <reference types="@vitest/browser-playwright" />