nuxt-typed-router 1.0.5 โ 1.1.1
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.
- package/README.md +14 -10
- package/dist/module.json +1 -1
- package/dist/module.mjs +57 -48
- package/package.json +7 -24
- package/dist/runtime/typed-router.d.ts +0 -12
- package/dist/runtime/typed-router.mjs +0 -12
- package/dist/runtime/useTypedRouter.d.ts +0 -13
- package/dist/runtime/useTypedRouter.mjs +0 -13
- package/hook.d.ts +0 -4
- package/hook.mjs +0 -1
package/README.md
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
- ๐ฆ Provides auto-completion and errors for route params in `push` and `replace` methods
|
|
19
19
|
|
|
20
20
|
<br/>
|
|
21
|
+
|
|
22
|
+
Demo ๐งช : [nuxt-typed-router-demo](https://github.com/victorgarciaesgi/nuxt-typed-router-demo)
|
|
23
|
+
|
|
21
24
|
<br/>
|
|
22
25
|
<p align="center">
|
|
23
26
|
<img src="https://github.com/victorgarciaesgi/nuxt-typed-router/blob/master/medias/in-action.gif?raw=true"/>
|
|
@@ -46,7 +49,7 @@ npm install -D nuxt-typed-router@legacy
|
|
|
46
49
|
|
|
47
50
|
# Configuration
|
|
48
51
|
|
|
49
|
-
First, register the module in the `nuxt.config.
|
|
52
|
+
First, register the module in the `nuxt.config.ts`
|
|
50
53
|
|
|
51
54
|
```ts
|
|
52
55
|
import TypedRouter from 'nuxt-typed-router';
|
|
@@ -77,15 +80,15 @@ interface ModuleOptions {
|
|
|
77
80
|
|
|
78
81
|
# Generated files
|
|
79
82
|
|
|
80
|
-
The module will
|
|
83
|
+
The module will generate 4 files each time you modify the `pages` folder :
|
|
81
84
|
|
|
82
|
-
-
|
|
83
|
-
-
|
|
85
|
+
- `~/<outDir>/__routes.ts` with the global object of the route names inside.
|
|
86
|
+
- `~/<outDir>/__useTypedRouter.ts` Composable tu simply access your typed routes
|
|
87
|
+
- `~/<outDir>/typed-router.d.ts` containing the global typecript definitions and exports
|
|
88
|
+
- `~/plugins/__typed_router.ts` Plugin that will inject `$typedRouter` and `$routesList` (`@nuxt/kit` has problems registering plugin templates so this is a workaround)
|
|
84
89
|
|
|
85
90
|
# Usage in Vue/Nuxt
|
|
86
91
|
|
|
87
|
-
## Check out this demo and clone it! [nuxt-typed-router-demo](https://github.com/victorgarciaesgi/nuxt-typed-router-demo)
|
|
88
|
-
|
|
89
92
|
<br/>
|
|
90
93
|
|
|
91
94
|
### **_Requirements_**
|
|
@@ -122,7 +125,7 @@ Given this structure
|
|
|
122
125
|
โ โโโ login.vue
|
|
123
126
|
โโโ ...
|
|
124
127
|
|
|
125
|
-
The generated
|
|
128
|
+
The generated route list will look like this
|
|
126
129
|
|
|
127
130
|
```ts
|
|
128
131
|
export const routerPagesNames = {
|
|
@@ -154,11 +157,12 @@ export type TypedRouteList =
|
|
|
154
157
|
|
|
155
158
|
# Usage with `useTypedRouter` hook
|
|
156
159
|
|
|
157
|
-
`useTypedRouter` is an exported composable from nuxt-typed-router. It contains a clone of `vue-router` but with
|
|
160
|
+
`useTypedRouter` is an exported composable from nuxt-typed-router. It contains a clone of `vue-router` but with strictly typed route names and params type-check
|
|
158
161
|
|
|
159
162
|
```vue
|
|
160
163
|
<script lang="ts">
|
|
161
|
-
|
|
164
|
+
// The path here is `~/generated` because I set `outDir: './generated'` in my module options
|
|
165
|
+
import { useTypedRouter } from '~/generated';
|
|
162
166
|
|
|
163
167
|
export default defineComponent({
|
|
164
168
|
setup() {
|
|
@@ -210,7 +214,7 @@ Exemple with `pinia` store here
|
|
|
210
214
|
|
|
211
215
|
```ts
|
|
212
216
|
import pinia from 'pinia';
|
|
213
|
-
import { useTypedRouter } from '
|
|
217
|
+
import { useTypedRouter } from '~/generated';
|
|
214
218
|
|
|
215
219
|
export const useFooStore = defineStore('foo', {
|
|
216
220
|
actions: {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { extendPages, defineNuxtModule } from '@nuxt/kit';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
2
|
import chalk from 'chalk';
|
|
4
3
|
import logSymbols from 'log-symbols';
|
|
5
|
-
import { resolve, dirname } from 'pathe';
|
|
6
4
|
import prettier from 'prettier';
|
|
7
5
|
import fs from 'fs';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, resolve } from 'pathe';
|
|
8
8
|
import mkdirp from 'mkdirp';
|
|
9
9
|
import { camelCase } from 'lodash-es';
|
|
10
10
|
|
|
@@ -35,9 +35,11 @@ async function formatOutputWithPrettier(template) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
dirname(fileURLToPath(import.meta.url));
|
|
39
|
+
async function saveRouteFiles(outDir, srcDir, fileName, content) {
|
|
39
40
|
try {
|
|
40
|
-
const
|
|
41
|
+
const processedOutDir = resolve(srcDir, outDir);
|
|
42
|
+
const outputFile = resolve(process.cwd(), `${processedOutDir}/${fileName}`);
|
|
41
43
|
const formatedContent = await formatOutputWithPrettier(content);
|
|
42
44
|
if (fs.existsSync(outputFile)) {
|
|
43
45
|
await writeFile(outputFile, formatedContent);
|
|
@@ -128,14 +130,16 @@ function startGeneratorProcedure({
|
|
|
128
130
|
output,
|
|
129
131
|
routesConfig
|
|
130
132
|
}) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
routesConfig.forEach((route, index) => {
|
|
134
|
+
const rootSiblingsRoutes = routesConfig.filter((rt) => rt.chunkName !== route.chunkName);
|
|
135
|
+
walkThoughRoutes({
|
|
136
|
+
route,
|
|
137
|
+
level: 0,
|
|
138
|
+
output,
|
|
139
|
+
siblings: rootSiblingsRoutes,
|
|
140
|
+
isLast: isItemLast(routesConfig, index)
|
|
141
|
+
});
|
|
142
|
+
});
|
|
139
143
|
output.routesObjectTemplate += "}";
|
|
140
144
|
output.routesDeclTemplate += "}";
|
|
141
145
|
}
|
|
@@ -192,8 +196,12 @@ function walkThoughRoutes({
|
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
const signatureTemplate = `/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
199
|
+
* ---------------------
|
|
200
|
+
* \u{1F697}\u{1F6A6} Generated by nuxt-typed-router. Do not modify !
|
|
201
|
+
* ---------------------
|
|
202
|
+
* */
|
|
203
|
+
|
|
204
|
+
`;
|
|
197
205
|
const staticDeclImports = `
|
|
198
206
|
import type {
|
|
199
207
|
NavigationFailure,
|
|
@@ -203,15 +211,6 @@ import type {
|
|
|
203
211
|
RouteQueryAndHash,
|
|
204
212
|
} from 'vue-router';
|
|
205
213
|
import type { TypedRouteList } from './__routes'
|
|
206
|
-
|
|
207
|
-
// -- Unbuild CommonJS Shims --
|
|
208
|
-
import __cjs_url__ from 'url';
|
|
209
|
-
import __cjs_path__ from 'path';
|
|
210
|
-
import __cjs_mod__ from 'module';
|
|
211
|
-
const __filename = __cjs_url__.fileURLToPath(import.meta.url);
|
|
212
|
-
const __dirname = __cjs_path__.dirname(__filename);
|
|
213
|
-
const require = __cjs_mod__.createRequire(import.meta.url);
|
|
214
|
-
|
|
215
214
|
`;
|
|
216
215
|
const staticDeclarations = `
|
|
217
216
|
type TypedRouteParamsStructure = {
|
|
@@ -227,7 +226,7 @@ const staticDeclarations = `
|
|
|
227
226
|
TypedLocationAsRelativeRaw<T> &
|
|
228
227
|
RouteLocationOptions;
|
|
229
228
|
|
|
230
|
-
interface TypedRouter {
|
|
229
|
+
export interface TypedRouter {
|
|
231
230
|
/**
|
|
232
231
|
* Remove an existing route by its name.
|
|
233
232
|
*
|
|
@@ -288,18 +287,11 @@ const staticDeclarations = `
|
|
|
288
287
|
$routesList: RouteListDecl;
|
|
289
288
|
}
|
|
290
289
|
}
|
|
291
|
-
declare module 'nuxt-typed-router/hook' {
|
|
292
|
-
declare const useTypedRouter: () => {
|
|
293
|
-
/** Export of $router with type check */
|
|
294
|
-
router: TypedRouter,
|
|
295
|
-
/** Contains a typed dictionnary of all your route names (for syntax sugar) */
|
|
296
|
-
routes: RouteListDecl
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
290
|
`;
|
|
300
291
|
|
|
301
292
|
function createRuntimePluginFile(routesDeclTemplate) {
|
|
302
293
|
return `
|
|
294
|
+
${signatureTemplate}
|
|
303
295
|
import { defineNuxtPlugin } from '#app';
|
|
304
296
|
|
|
305
297
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
@@ -316,10 +308,24 @@ function createRuntimePluginFile(routesDeclTemplate) {
|
|
|
316
308
|
}
|
|
317
309
|
function createRuntimeHookFile(routesDeclTemplate) {
|
|
318
310
|
return `
|
|
319
|
-
|
|
320
|
-
import { useNuxtApp } from '
|
|
311
|
+
${signatureTemplate}
|
|
312
|
+
import { useNuxtApp } from '#app';
|
|
313
|
+
import { TypedRouter, RouteListDecl } from './typed-router';
|
|
321
314
|
|
|
322
|
-
|
|
315
|
+
/** Returns instances of $typedRouter and $routesList fully typed to use in your components or your Vuex/Pinia store
|
|
316
|
+
*
|
|
317
|
+
* @exemple
|
|
318
|
+
*
|
|
319
|
+
* \`\`\`ts
|
|
320
|
+
* const { router, routes } = useTypedRouter();
|
|
321
|
+
* \`\`\`
|
|
322
|
+
*/
|
|
323
|
+
export const useTypedRouter = (): {
|
|
324
|
+
/** Export of $router with type check */
|
|
325
|
+
router: TypedRouter,
|
|
326
|
+
/** Contains a typed dictionnary of all your route names (for syntax sugar) */
|
|
327
|
+
routes: RouteListDecl
|
|
328
|
+
} => {
|
|
323
329
|
const { $router } = useNuxtApp();
|
|
324
330
|
|
|
325
331
|
const routesList = ${routesDeclTemplate};
|
|
@@ -327,11 +333,18 @@ function createRuntimeHookFile(routesDeclTemplate) {
|
|
|
327
333
|
return {
|
|
328
334
|
router: $router,
|
|
329
335
|
routes: routesList,
|
|
330
|
-
};
|
|
336
|
+
} as any;
|
|
331
337
|
};
|
|
332
338
|
|
|
333
339
|
`;
|
|
334
340
|
}
|
|
341
|
+
function createRuntimeIndexFile() {
|
|
342
|
+
return `
|
|
343
|
+
${signatureTemplate}
|
|
344
|
+
export * from './__routes';
|
|
345
|
+
export * from './__useTypedRouter';
|
|
346
|
+
`;
|
|
347
|
+
}
|
|
335
348
|
function createRuntimeRoutesFile({
|
|
336
349
|
routesList,
|
|
337
350
|
routesObjectTemplate,
|
|
@@ -372,22 +385,22 @@ function createTypedRouteParamsExport(routesParams) {
|
|
|
372
385
|
}`;
|
|
373
386
|
}
|
|
374
387
|
|
|
375
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
376
388
|
function routeHook(outDir, routesObjectName, srcDir, nuxt) {
|
|
377
389
|
try {
|
|
378
390
|
extendPages(async (routes) => {
|
|
379
391
|
if (routes.length) {
|
|
380
392
|
const { routesDeclTemplate, routesList, routesObjectTemplate, routesParams } = constructRouteMap(routes);
|
|
381
393
|
const pluginName = "__typed-router.ts";
|
|
382
|
-
const runtimeDir = resolve(__dirname, process.env.NUXT_BUILD_TYPE === "stub" ? "../../dist/runtime" : "./runtime");
|
|
383
|
-
const pluginPath = resolve(runtimeDir, pluginName);
|
|
384
394
|
nuxt.hook("build:done", async () => {
|
|
385
395
|
const pluginFolder = `${srcDir}/plugins`;
|
|
386
|
-
await saveRouteFiles(pluginFolder, pluginName, createRuntimePluginFile(routesDeclTemplate));
|
|
396
|
+
await saveRouteFiles(pluginFolder, srcDir, pluginName, createRuntimePluginFile(routesDeclTemplate));
|
|
387
397
|
});
|
|
388
|
-
await
|
|
389
|
-
|
|
390
|
-
|
|
398
|
+
await Promise.all([
|
|
399
|
+
saveRouteFiles(outDir, srcDir, "__useTypedRouter.ts", createRuntimeHookFile(routesDeclTemplate)),
|
|
400
|
+
saveRouteFiles(outDir, srcDir, `__routes.ts`, createRuntimeRoutesFile({ routesList, routesObjectTemplate, routesObjectName })),
|
|
401
|
+
saveRouteFiles(outDir, srcDir, `typed-router.d.ts`, createDeclarationRoutesFile({ routesDeclTemplate, routesList, routesParams })),
|
|
402
|
+
saveRouteFiles(outDir, srcDir, "index.ts", createRuntimeIndexFile())
|
|
403
|
+
]);
|
|
391
404
|
console.log(logSymbols.success, `[typed-router] Routes definitions generated`);
|
|
392
405
|
} else {
|
|
393
406
|
console.log(logSymbols.warning, chalk.yellow(`[typed-router] No routes defined. Check if your ${chalk.underline(chalk.bold("pages"))} folder exists and remove ${chalk.underline(chalk.bold("app.vue"))}`));
|
|
@@ -404,13 +417,9 @@ const module = defineNuxtModule({
|
|
|
404
417
|
configKey: "nuxtTypedRouter",
|
|
405
418
|
compatibility: { nuxt: "^3.0.0", bridge: false }
|
|
406
419
|
},
|
|
407
|
-
defaults: {
|
|
408
|
-
routesObjectName: "routerPagesNames",
|
|
409
|
-
stripAtFromName: false
|
|
410
|
-
},
|
|
411
420
|
setup(moduleOptions, nuxt) {
|
|
412
421
|
const srcDir = nuxt.options.srcDir;
|
|
413
|
-
const { outDir =
|
|
422
|
+
const { outDir = `./generated`, routesObjectName = "routerPagesNames" } = moduleOptions;
|
|
414
423
|
nuxt.hook("pages:extend", () => routeHook(outDir, routesObjectName, srcDir, nuxt));
|
|
415
424
|
routeHook(outDir, routesObjectName, srcDir, nuxt);
|
|
416
425
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-typed-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Provide autocompletion for pages route names generated by Nuxt router",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -9,26 +9,21 @@
|
|
|
9
9
|
"prepack": "nuxt-module-build",
|
|
10
10
|
"build:local": "nuxt-module-build --stub && cross-env NUXT_BUILD_TYPE=stub nuxi dev playground",
|
|
11
11
|
"init:build": "nuxt-module-build --stub && nuxi prepare playground",
|
|
12
|
-
"build:test": "cross-env NUXT_BUILD_TYPE=stub yarn
|
|
13
|
-
"test": "yarn build:test &&
|
|
14
|
-
"test:
|
|
12
|
+
"build:test": "cross-env NUXT_BUILD_TYPE=stub yarn prepack && yarn play:build",
|
|
13
|
+
"test": "yarn build:test && vitest run",
|
|
14
|
+
"test:watch": "yarn build:test && vitest"
|
|
15
15
|
},
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
18
|
"import": "./dist/module.mjs",
|
|
19
19
|
"require": "./dist/module.cjs"
|
|
20
|
-
},
|
|
21
|
-
"./hook": {
|
|
22
|
-
"import": "./hook.mjs"
|
|
23
20
|
}
|
|
24
21
|
},
|
|
25
22
|
"main": "./dist/module.cjs",
|
|
26
23
|
"types": "./main.d.ts",
|
|
27
24
|
"files": [
|
|
28
25
|
"dist",
|
|
29
|
-
"main.d.ts"
|
|
30
|
-
"hook.mjs",
|
|
31
|
-
"hook.d.ts"
|
|
26
|
+
"main.d.ts"
|
|
32
27
|
],
|
|
33
28
|
"publishConfig": {
|
|
34
29
|
"access": "public"
|
|
@@ -65,31 +60,19 @@
|
|
|
65
60
|
"prettier": "^2.5.1"
|
|
66
61
|
},
|
|
67
62
|
"devDependencies": {
|
|
68
|
-
"@babel/plugin-transform-runtime": "^7.16.10",
|
|
69
|
-
"@babel/preset-env": "^7.16.11",
|
|
70
63
|
"@nuxt/module-builder": "latest",
|
|
71
|
-
"@nuxt/test-utils": "^0.2.2",
|
|
72
64
|
"@nuxt/types": "^2.15.8",
|
|
73
65
|
"@nuxtjs/eslint-config-typescript": "latest",
|
|
74
|
-
"@types/
|
|
75
|
-
"@types/lodash": "^4.14.178",
|
|
66
|
+
"@types/lodash-es": "^4.14.178",
|
|
76
67
|
"@types/mkdirp": "^1.0.2",
|
|
77
68
|
"@types/node": "^16.11.12",
|
|
78
69
|
"@types/prettier": "^2.4.3",
|
|
79
|
-
"babel-jest": "^27.4.6",
|
|
80
|
-
"copyfiles": "^2.4.0",
|
|
81
|
-
"core-js": "^3.20.3",
|
|
82
70
|
"cross-env": "^7.0.3",
|
|
83
71
|
"eslint": "8.8.0",
|
|
84
72
|
"eslint-config-prettier": "^8.3.0",
|
|
85
|
-
"jest": "^27.4.7",
|
|
86
73
|
"nuxt3": "latest",
|
|
87
|
-
"path": "^0.12.7",
|
|
88
|
-
"playwright": "^1.18.1",
|
|
89
|
-
"rimraf": "^3.0.2",
|
|
90
|
-
"ts-jest": "^27.1.3",
|
|
91
74
|
"typescript": "^4.5.1",
|
|
92
|
-
"
|
|
75
|
+
"vitest": "^0.2.5",
|
|
93
76
|
"vue-router": "^4.0.12"
|
|
94
77
|
}
|
|
95
78
|
}
|
package/hook.d.ts
DELETED
package/hook.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { useTypedRouter } from './dist/runtime/useTypedRouter.mjs';
|