nuxt-typed-router 1.0.0 → 1.0.4

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
@@ -1,4 +1,4 @@
1
- # 🚗🚦 Nuxt typed router
1
+ # 🚗🚦 Typed Router for Nuxt 3
2
2
 
3
3
  [npm-version-src]: https://img.shields.io/npm/v/nuxt-typed-router.svg
4
4
  [npm-version-href]: https://www.npmjs.com/package/nuxt-typed-router
@@ -17,6 +17,13 @@
17
17
  - 🚚 Expose a global method `$typedRouter` (clone of vue-router), but typed with the routes defined in `pages` directory
18
18
  - 🚦 Provides auto-completion and errors for route params in `push` and `replace` methods
19
19
 
20
+ <br/>
21
+ <br/>
22
+ <p align="center">
23
+ <img src="https://github.com/victorgarciaesgi/nuxt-typed-router/blob/master/medias/in-action.gif?raw=true"/>
24
+ </p>
25
+ <br/>
26
+
20
27
  # Installation
21
28
 
22
29
  ### For Nuxt 3
@@ -77,9 +84,13 @@ The module will create 2 files:
77
84
 
78
85
  # Usage in Vue/Nuxt
79
86
 
87
+ ## Check out this demo and clone it! [nuxt-typed-router-demo](https://github.com/victorgarciaesgi/nuxt-typed-router-demo)
88
+
89
+ <br/>
90
+
80
91
  ### **_Requirements_**
81
92
 
82
- You have to specify the output dir of the generated files in your configuration
93
+ You can specify the output dir of the generated files in your configuration. It defaults to `<srcDir>/generated`
83
94
 
84
95
  ```ts
85
96
  import TypedRouter from 'nuxt-typed-router';
@@ -139,6 +150,8 @@ export type TypedRouteList =
139
150
  | 'index-user';
140
151
  ```
141
152
 
153
+ > nuxt-typed-router will also create a plugin in your `<srcDir>/plugins` folder with the injected `$typedRouter` and `$routesList` helpers
154
+
142
155
  # Usage with `useTypedRouter` hook
143
156
 
144
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
@@ -164,7 +177,7 @@ export default defineComponent({
164
177
  </script>
165
178
  ```
166
179
 
167
- # Usage with `$typedRouter` injected method
180
+ # Usage with `$typedRouter` and `$routesList` injected helpers
168
181
 
169
182
  `$typedRouter` is an injected clone of vue-router `$router`, but fully typed with all your routes.
170
183
  It's available anywhere you have access to Nuxt context
@@ -176,10 +189,10 @@ import { defineComponent } from 'vue';
176
189
  export default defineComponent({
177
190
  name: 'Index',
178
191
  setup() {
179
- const { $typedRouter } = useNuxtApp();
192
+ const { $typedRouter, $routesList } = useNuxtApp();
180
193
 
181
194
  function navigate() {
182
- $typedRouter.push({ name: 'activate' });
195
+ $typedRouter.push({ name: $routesList.activate });
183
196
  }
184
197
 
185
198
  return {
@@ -190,6 +203,25 @@ export default defineComponent({
190
203
  </script>
191
204
  ```
192
205
 
206
+ # Usage outside Vue component
207
+
208
+ You can import the `useTypedRouter` composable from where it's generated.
209
+ Exemple with `pinia` store here
210
+
211
+ ```ts
212
+ import pinia from 'pinia';
213
+ import { useTypedRouter } from 'nuxt-typed-router/hook';
214
+
215
+ export const useFooStore = defineStore('foo', {
216
+ actions: {
217
+ bar() {
218
+ const { router, routes } = useTypedRouter();
219
+ router.push({ name: routes.index.user, params: { user: 2 } });
220
+ },
221
+ },
222
+ });
223
+ ```
224
+
193
225
  ## Development
194
226
 
195
227
  1. Clone this repository
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.0"
8
+ "version": "1.0.4"
9
9
  }
package/dist/module.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { extendPages, addPluginTemplate, defineNuxtModule } from '@nuxt/kit';
1
+ import { extendPages, defineNuxtModule } from '@nuxt/kit';
2
2
  import { fileURLToPath } from 'url';
3
3
  import chalk from 'chalk';
4
4
  import logSymbols from 'log-symbols';
@@ -298,17 +298,26 @@ const staticDeclarations = `
298
298
  }
299
299
  `;
300
300
 
301
+ function createRuntimePluginFile(routesDeclTemplate) {
302
+ return `
303
+ import { defineNuxtPlugin } from '#app';
304
+
305
+ export default defineNuxtPlugin((nuxtApp) => {
306
+ const routesList = ${routesDeclTemplate};
307
+
308
+ return {
309
+ provide: {
310
+ typedRouter: nuxtApp.$router,
311
+ routesList,
312
+ },
313
+ };
314
+ });
315
+ `;
316
+ }
301
317
  function createRuntimeHookFile(routesDeclTemplate) {
302
318
  return `
303
319
  import { getCurrentInstance } from 'vue';
304
-
305
- function useNuxtApp() {
306
- const vm = getCurrentInstance();
307
- if (!vm) {
308
- throw new Error('nuxt instance unavailable');
309
- }
310
- return vm.appContext.app.$nuxt;
311
- }
320
+ import { useNuxtApp } from '#app';
312
321
 
313
322
  export const useTypedRouter = () => {
314
323
  const { $router } = useNuxtApp();
@@ -364,27 +373,25 @@ function createTypedRouteParamsExport(routesParams) {
364
373
  }
365
374
 
366
375
  const __dirname = dirname(fileURLToPath(import.meta.url));
367
- function routeHook(outDir, routesObjectName) {
376
+ function routeHook(outDir, routesObjectName, srcDir, nuxt) {
368
377
  try {
369
378
  extendPages(async (routes) => {
370
- const { routesDeclTemplate, routesList, routesObjectTemplate, routesParams } = constructRouteMap(routes);
371
- const pluginName = "typed-router.mjs";
372
- const runtimeDir = resolve(__dirname, process.env.NUXT_BUILD_TYPE === "stub" ? "../../dist/runtime" : "./runtime");
373
- const pluginPath = resolve(runtimeDir, pluginName);
374
- await Promise.all([
375
- saveRouteFiles(runtimeDir, "useTypedRouter.mjs", createRuntimeHookFile(routesDeclTemplate)),
376
- saveRouteFiles(runtimeDir, pluginName, createRuntimeHookFile(routesDeclTemplate))
377
- ]);
378
- addPluginTemplate({
379
- src: pluginPath,
380
- filename: pluginName,
381
- options: {
382
- routesList: "test"
383
- }
384
- });
385
- await saveRouteFiles(outDir, `__routes.ts`, createRuntimeRoutesFile({ routesList, routesObjectTemplate, routesObjectName }));
386
- await saveRouteFiles(outDir, `typed-router.d.ts`, createDeclarationRoutesFile({ routesDeclTemplate, routesList, routesParams }));
387
- console.log(logSymbols.success, `[typed-router] Routes definitions generated`);
379
+ if (routes.length) {
380
+ const { routesDeclTemplate, routesList, routesObjectTemplate, routesParams } = constructRouteMap(routes);
381
+ 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
+ nuxt.hook("build:done", async () => {
385
+ const pluginFolder = `${srcDir}/plugins`;
386
+ await saveRouteFiles(pluginFolder, pluginName, createRuntimePluginFile(routesDeclTemplate));
387
+ });
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 }));
391
+ console.log(logSymbols.success, `[typed-router] Routes definitions generated`);
392
+ } else {
393
+ 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"))}`));
394
+ }
388
395
  });
389
396
  } catch (e) {
390
397
  console.error(chalk.red("Error while generating routes definitions model"), "\n" + e);
@@ -402,10 +409,10 @@ const module = defineNuxtModule({
402
409
  stripAtFromName: false
403
410
  },
404
411
  setup(moduleOptions, nuxt) {
405
- const { outDir = `${nuxt.options.srcDir}/generated`, routesObjectName } = moduleOptions;
406
- nuxt.hook("pages:extend", () => routeHook(outDir, routesObjectName));
407
- nuxt.hook("build:extendRoutes", () => routeHook(outDir, routesObjectName));
408
- routeHook(outDir, routesObjectName);
412
+ const srcDir = nuxt.options.srcDir;
413
+ const { outDir = `${srcDir}/generated`, routesObjectName } = moduleOptions;
414
+ nuxt.hook("pages:extend", () => routeHook(outDir, routesObjectName, srcDir, nuxt));
415
+ routeHook(outDir, routesObjectName, srcDir, nuxt);
409
416
  }
410
417
  });
411
418
 
@@ -1,20 +1,12 @@
1
- import { getCurrentInstance } from 'vue';
2
-
3
- function useNuxtApp() {
4
- const vm = getCurrentInstance();
5
- if (!vm) {
6
- throw new Error('nuxt instance unavailable');
7
- }
8
- return vm.appContext.app.$nuxt;
9
- }
10
-
11
- export const useTypedRouter = () => {
12
- const { $router } = useNuxtApp();
1
+ import { defineNuxtPlugin } from '#app';
13
2
 
3
+ export default defineNuxtPlugin((nuxtApp) => {
14
4
  const routesList = {};
15
5
 
16
6
  return {
17
- router: $router,
18
- routes: routesList,
7
+ provide: {
8
+ typedRouter: nuxtApp.$router,
9
+ routesList,
10
+ },
19
11
  };
20
- };
12
+ });
@@ -1,20 +1,12 @@
1
- import { getCurrentInstance } from 'vue';
2
-
3
- function useNuxtApp() {
4
- const vm = getCurrentInstance();
5
- if (!vm) {
6
- throw new Error('nuxt instance unavailable');
7
- }
8
- return vm.appContext.app.$nuxt;
9
- }
10
-
11
- export const useTypedRouter = () => {
12
- const { $router } = useNuxtApp();
1
+ import { defineNuxtPlugin } from '#app';
13
2
 
3
+ export default defineNuxtPlugin((nuxtApp) => {
14
4
  const routesList = {};
15
5
 
16
6
  return {
17
- router: $router,
18
- routes: routesList,
7
+ provide: {
8
+ typedRouter: nuxtApp.$router,
9
+ routesList,
10
+ },
19
11
  };
20
- };
12
+ });
@@ -1,17 +1,32 @@
1
1
  import { getCurrentInstance } from 'vue';
2
-
3
- function useNuxtApp() {
4
- const vm = getCurrentInstance();
5
- if (!vm) {
6
- throw new Error('nuxt instance unavailable');
7
- }
8
- return vm.appContext.app.$nuxt;
9
- }
2
+ import { useNuxtApp } from '#app';
10
3
 
11
4
  export const useTypedRouter = () => {
12
5
  const { $router } = useNuxtApp();
13
6
 
14
- const routesList = {};
7
+ const routesList = {
8
+ activate: 'activate',
9
+ index: 'index',
10
+ childOne: {
11
+ childOneChildOneSubOne: 'parent-child-one-child-one-sub-one',
12
+ user: { index: 'parent-child-one-child-one-sub-one-user' },
13
+ childOneChildOneSubTwo: 'parent-child-one-child-one-sub-two',
14
+ index: 'parent-child-one',
15
+ },
16
+ childTwo: {
17
+ childTwoId: 'parent-child-two-id',
18
+ childTwoChildOneSubOne: 'parent-child-two-child-one-sub-one',
19
+ index: 'parent-child-two',
20
+ profile: {
21
+ id: {
22
+ slug: { index: 'parent-child-two-profile-id-slug' },
23
+ index: 'parent-child-two-profile-id',
24
+ },
25
+ index: 'parent-child-two-profile',
26
+ },
27
+ },
28
+ rootPage: 'rootPage',
29
+ };
15
30
 
16
31
  return {
17
32
  router: $router,
@@ -1,17 +1,32 @@
1
1
  import { getCurrentInstance } from 'vue';
2
-
3
- function useNuxtApp() {
4
- const vm = getCurrentInstance();
5
- if (!vm) {
6
- throw new Error('nuxt instance unavailable');
7
- }
8
- return vm.appContext.app.$nuxt;
9
- }
2
+ import { useNuxtApp } from '#app';
10
3
 
11
4
  export const useTypedRouter = () => {
12
5
  const { $router } = useNuxtApp();
13
6
 
14
- const routesList = {};
7
+ const routesList = {
8
+ activate: 'activate',
9
+ index: 'index',
10
+ childOne: {
11
+ childOneChildOneSubOne: 'parent-child-one-child-one-sub-one',
12
+ user: { index: 'parent-child-one-child-one-sub-one-user' },
13
+ childOneChildOneSubTwo: 'parent-child-one-child-one-sub-two',
14
+ index: 'parent-child-one',
15
+ },
16
+ childTwo: {
17
+ childTwoId: 'parent-child-two-id',
18
+ childTwoChildOneSubOne: 'parent-child-two-child-one-sub-one',
19
+ index: 'parent-child-two',
20
+ profile: {
21
+ id: {
22
+ slug: { index: 'parent-child-two-profile-id-slug' },
23
+ index: 'parent-child-two-profile-id',
24
+ },
25
+ index: 'parent-child-two-profile',
26
+ },
27
+ },
28
+ rootPage: 'rootPage',
29
+ };
15
30
 
16
31
  return {
17
32
  router: $router,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-typed-router",
3
- "version": "1.0.0",
3
+ "version": "1.0.4",
4
4
  "description": "Provide autocompletion for pages route names generated by Nuxt router",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -8,7 +8,9 @@
8
8
  "play:build": "nuxi build playground",
9
9
  "prepack": "nuxt-module-build",
10
10
  "build:local": "nuxt-module-build --stub && cross-env NUXT_BUILD_TYPE=stub nuxi dev playground",
11
- "test": "jest",
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",
12
14
  "test:reset": "yarn test --updateSnapshot"
13
15
  },
14
16
  "exports": {
@@ -1 +0,0 @@
1
- export { useTypedRouter } from './useTypedRouter';
@@ -1 +0,0 @@
1
- export { useTypedRouter } from "./useTypedRouter.mjs";