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 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.[js|ts]`
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 create 2 files:
83
+ The module will generate 4 files each time you modify the `pages` folder :
81
84
 
82
- - `__routes.ts` with the global object of the route names inside.
83
- - `typed-router.d.ts` containing the global typecript definitions and exports
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 file will look like this
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 stritly typed route names and params type-check
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
- import { useTypedRouter } from 'nuxt-typed-router/hook';
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 'nuxt-typed-router/hook';
217
+ import { useTypedRouter } from '~/generated';
214
218
 
215
219
  export const useFooStore = defineStore('foo', {
216
220
  actions: {
package/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "nuxt": "^3.0.0",
6
6
  "bridge": false
7
7
  },
8
- "version": "1.0.5"
8
+ "version": "1.1.1"
9
9
  }
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
- async function saveRouteFiles(outDir, fileName, content) {
38
+ dirname(fileURLToPath(import.meta.url));
39
+ async function saveRouteFiles(outDir, srcDir, fileName, content) {
39
40
  try {
40
- const outputFile = resolve(process.cwd(), `${outDir}/${fileName}`);
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
- const rootSiblingsRoutes = routesConfig.map((route) => route.path);
132
- routesConfig.forEach((route, index) => walkThoughRoutes({
133
- route,
134
- level: 0,
135
- output,
136
- siblings: rootSiblingsRoutes,
137
- isLast: isItemLast(routesConfig, index)
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
- * Generated by nuxt-typed-router. Do not modify
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
- import { getCurrentInstance } from 'vue';
320
- import { useNuxtApp } from 'nuxt3';
311
+ ${signatureTemplate}
312
+ import { useNuxtApp } from '#app';
313
+ import { TypedRouter, RouteListDecl } from './typed-router';
321
314
 
322
- export const useTypedRouter = () => {
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 saveRouteFiles(runtimeDir, "useTypedRouter.mjs", createRuntimeHookFile(routesDeclTemplate));
389
- await saveRouteFiles(outDir, `__routes.ts`, createRuntimeRoutesFile({ routesList, routesObjectTemplate, routesObjectName }));
390
- await saveRouteFiles(outDir, `typed-router.d.ts`, createDeclarationRoutesFile({ routesDeclTemplate, routesList, routesParams }));
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 = `${srcDir}/generated`, routesObjectName } = moduleOptions;
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.0.5",
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 init:build && yarn prepack && yarn play:build",
13
- "test": "yarn build:test && jest",
14
- "test:reset": "yarn test --updateSnapshot"
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/jest": "^27.4.0",
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
- "unbuild": "^0.6.9",
75
+ "vitest": "^0.2.5",
93
76
  "vue-router": "^4.0.12"
94
77
  }
95
78
  }
@@ -1,12 +0,0 @@
1
- import { defineNuxtPlugin } from '#app';
2
-
3
- export default defineNuxtPlugin((nuxtApp) => {
4
- const routesList = {};
5
-
6
- return {
7
- provide: {
8
- typedRouter: nuxtApp.$router,
9
- routesList,
10
- },
11
- };
12
- });
@@ -1,12 +0,0 @@
1
- import { defineNuxtPlugin } from '#app';
2
-
3
- export default defineNuxtPlugin((nuxtApp) => {
4
- const routesList = {};
5
-
6
- return {
7
- provide: {
8
- typedRouter: nuxtApp.$router,
9
- routesList,
10
- },
11
- };
12
- });
@@ -1,13 +0,0 @@
1
- import { getCurrentInstance } from 'vue';
2
- import { useNuxtApp } from 'nuxt3';
3
-
4
- export const useTypedRouter = () => {
5
- const { $router } = useNuxtApp();
6
-
7
- const routesList = {};
8
-
9
- return {
10
- router: $router,
11
- routes: routesList,
12
- };
13
- };
@@ -1,13 +0,0 @@
1
- import { getCurrentInstance } from 'vue';
2
- import { useNuxtApp } from 'nuxt3';
3
-
4
- export const useTypedRouter = () => {
5
- const { $router } = useNuxtApp();
6
-
7
- const routesList = {};
8
-
9
- return {
10
- router: $router,
11
- routes: routesList,
12
- };
13
- };
package/hook.d.ts DELETED
@@ -1,4 +0,0 @@
1
- /** @deprecated Do not import or use. Dummy export to fool Typescript into thinking it's a module */
2
- declare const doNotImportItsToFoolTypescript = 'foo';
3
-
4
- export { doNotImportItsToFoolTypescript };
package/hook.mjs DELETED
@@ -1 +0,0 @@
1
- export { useTypedRouter } from './dist/runtime/useTypedRouter.mjs';