nuxt-typed-router 3.3.3 → 3.5.0-beta.0

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
@@ -60,8 +60,6 @@ Demo repo 🧪 : [nuxt-typed-router-demo](https://github.com/victorgarciaesgi/nu
60
60
  # Compatibility:
61
61
 
62
62
  - Nuxt 3
63
- - Nuxt 2 (via [`nuxt2` branch](https://github.com/victorgarciaesgi/nuxt-typed-router/tree/nuxt2))
64
-
65
63
 
66
64
 
67
65
  # Quick start
@@ -76,16 +74,6 @@ npm install -D nuxt-typed-router
76
74
  pnpm install -D nuxt-typed-router
77
75
  ```
78
76
 
79
- ### Nuxt 2 legacy (not maintained)
80
-
81
- Nuxt 2 version is no longer maintained, but still available in [`nuxt2` branch](https://github.com/victorgarciaesgi/nuxt-typed-router/tree/nuxt2)
82
- It only has route name autocomplete functionnality
83
-
84
- ```bash
85
- yarn add -D nuxt-typed-router@legacy
86
- # or
87
- npm install -D nuxt-typed-router@legacy
88
- ```
89
77
 
90
78
  # Configuration
91
79
  Register the module in the `nuxt.config.ts`, done!
package/dist/module.d.mts CHANGED
@@ -27,14 +27,14 @@ interface ModuleOptions {
27
27
  * Remove Nuxt definitions to avoid conflicts
28
28
  * @default true
29
29
  */
30
- experimentalRemoveNuxtDefs?: boolean;
30
+ removeNuxtDefs?: boolean;
31
31
  /**
32
32
  * ⚠️ Experimental
33
33
  *
34
34
  * Exclude certain routes from being included into the generated types
35
35
  * Ex: 404 routes or catchAll routes
36
36
  */
37
- experimentalIgnoreRoutes?: string[];
37
+ ignoreRoutes?: string[];
38
38
  }
39
39
  interface StrictOptions {
40
40
  NuxtLink?: StrictParamsOptions;
package/dist/module.d.ts CHANGED
@@ -27,14 +27,14 @@ interface ModuleOptions {
27
27
  * Remove Nuxt definitions to avoid conflicts
28
28
  * @default true
29
29
  */
30
- experimentalRemoveNuxtDefs?: boolean;
30
+ removeNuxtDefs?: boolean;
31
31
  /**
32
32
  * ⚠️ Experimental
33
33
  *
34
34
  * Exclude certain routes from being included into the generated types
35
35
  * Ex: 404 routes or catchAll routes
36
36
  */
37
- experimentalIgnoreRoutes?: string[];
37
+ ignoreRoutes?: string[];
38
38
  }
39
39
  interface StrictOptions {
40
40
  NuxtLink?: StrictParamsOptions;
package/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "nuxt": "^3.0.0",
6
6
  "bridge": false
7
7
  },
8
- "version": "3.3.3"
8
+ "version": "3.5.0-beta.0"
9
9
  }
package/dist/module.mjs CHANGED
@@ -3,13 +3,13 @@ import chalk from 'chalk';
3
3
  import logSymbols from 'log-symbols';
4
4
  import path from 'path';
5
5
  import { defu } from 'defu';
6
- import { customAlphabet } from 'nanoid/non-secure';
7
- import { nanoid as nanoid$1 } from 'nanoid';
6
+ import { startCase, camelCase } from 'lodash-es';
7
+ import { nanoid } from 'nanoid/non-secure';
8
+ import prettier from 'prettier';
8
9
  import fs, { existsSync } from 'fs';
9
10
  import { fileURLToPath } from 'url';
10
11
  import { dirname, resolve } from 'pathe';
11
12
  import { mkdirp } from 'mkdirp';
12
- import { camelCase } from 'lodash-es';
13
13
  import { readFile } from 'fs/promises';
14
14
 
15
15
  class ModuleOptionsStore {
@@ -24,7 +24,7 @@ class ModuleOptionsStore {
24
24
  i18n = false;
25
25
  i18nOptions = null;
26
26
  i18nLocales = [];
27
- experimentalIgnoreRoutes = [];
27
+ ignoreRoutes = [];
28
28
  updateOptions(options) {
29
29
  if (options.plugin != null)
30
30
  this.plugin = options.plugin;
@@ -45,6 +45,12 @@ class ModuleOptionsStore {
45
45
  this.i18nOptions = defu(options.i18nOptions, {
46
46
  strategy: "prefix_except_default"
47
47
  });
48
+ if (this.i18nOptions.strategy === "prefix_except_default" && !options.i18nOptions.defaultLocale) {
49
+ console.error(
50
+ logSymbols.error,
51
+ "You have not set 'i18n.defaultLocale', it's required when using 'prefix_except_default' mode (default one)"
52
+ );
53
+ }
48
54
  if (options.i18nOptions.locales) {
49
55
  this.i18nLocales = options.i18nOptions.locales.map((l) => {
50
56
  if (typeof l === "string") {
@@ -58,12 +64,15 @@ class ModuleOptionsStore {
58
64
  if (options.pathCheck != null) {
59
65
  this.pathCheck = options.pathCheck;
60
66
  }
61
- if (options.experimentalIgnoreRoutes) {
62
- this.experimentalIgnoreRoutes = options.experimentalIgnoreRoutes;
67
+ if (options.ignoreRoutes) {
68
+ this.ignoreRoutes = options.ignoreRoutes;
69
+ }
70
+ if (options.isDocumentDriven) {
71
+ this.ignoreRoutes.push("[...slug].vue");
63
72
  }
64
73
  }
65
74
  get resolvedIgnoredRoutes() {
66
- return this.experimentalIgnoreRoutes.map((file) => path.join(this.pagesDir, file));
75
+ return this.ignoreRoutes.map((file) => path.join(this.pagesDir, file));
67
76
  }
68
77
  getResolvedStrictOptions() {
69
78
  let resolved;
@@ -113,7 +122,7 @@ function createRoutesNamesListExport(routesList) {
113
122
  /**
114
123
  * Exhaustive list of all the available route names in the app
115
124
  * */
116
- export type RoutesNamesList = ${routesList.map((m) => `'${m}'`).join("|\n")}`;
125
+ export type RoutesNamesList = ${routesList.length ? routesList.map((m) => `'${m}'`).join("|\n") : '""'}`;
117
126
  }
118
127
 
119
128
  function createRoutesParamsRecordExport(routesParams) {
@@ -142,13 +151,13 @@ function createRoutesNamedLocationsExport(routesParams) {
142
151
  * It's used for programmatic navigation like router.push or <NuxtLink/>
143
152
  * */
144
153
  export type RoutesNamedLocations =
145
- ${routesParams.map(
154
+ ${routesParams.length ? routesParams.map(
146
155
  ({ name, params }) => `{name: "${name}" ${params.length ? `, params${params.some((s) => s.required) ? "" : "?"}: {
147
156
  ${params.map(
148
157
  ({ key, required, catchAll }) => `"${key}"${required ? "" : "?"}: (string | number)${catchAll ? "[]" : ""}`
149
158
  ).join(",\n")}
150
159
  }` : ""}}`
151
- ).join("|\n")}
160
+ ).join("|\n") : "''"}
152
161
  `;
153
162
  }
154
163
 
@@ -162,7 +171,7 @@ function createRoutesNamedLocationsResolvedExport(routesParams) {
162
171
  {
163
172
  name: RoutesNamesList;
164
173
  params: unknown;
165
- } & (
174
+ } ${routesParams.length ? `& (
166
175
  ${routesParams.map(
167
176
  ({ name, params }) => `{name: "${name}" ${params.length ? `, params: {
168
177
  ${params.map(
@@ -170,7 +179,7 @@ function createRoutesNamedLocationsResolvedExport(routesParams) {
170
179
  ).join(",\n")}
171
180
  }` : ""}}`
172
181
  ).join("|\n")}
173
- )
182
+ )` : ""}
174
183
  `;
175
184
  }
176
185
 
@@ -201,7 +210,9 @@ function returnIfTrue(condition, template, otherwise) {
201
210
  return otherwise ?? "";
202
211
  }
203
212
 
204
- const nanoid = customAlphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10);
213
+ function pascalCase(str) {
214
+ return startCase(camelCase(str)).replace(/ /g, "");
215
+ }
205
216
  function createRoutePathSchema(routePaths) {
206
217
  return `export type RoutePathSchema =
207
218
  ${routePaths.filter((f) => !!f.path).map((route) => `"${route.path}"`).join("|")}
@@ -213,7 +224,7 @@ function createLocaleRoutePathSchema(routePaths) {
213
224
  `;
214
225
  }
215
226
  function createValidatePathTypes(pathElements, routesList, withLocale = false) {
216
- let pathConditions = pathElements.map(createTypeValidatePathCondition).filter((f) => {
227
+ let pathConditions = pathElements.map((m) => createTypeValidatePathCondition(m, withLocale)).filter((f) => {
217
228
  if (withLocale) {
218
229
  return !f.isLocale;
219
230
  }
@@ -247,8 +258,9 @@ function createValidatePathTypes(pathElements, routesList, withLocale = false) {
247
258
 
248
259
  `;
249
260
  }
250
- function createTypeValidatePathCondition(elements) {
251
- const typeName = `Validate${nanoid(7)}`;
261
+ function createTypeValidatePathCondition(elements, withLocale) {
262
+ const seedName = pascalCase(elements[0][0].fullPath);
263
+ const typeName = `Validate${returnIfTrue(withLocale, "Locale")}${seedName}`;
252
264
  const params = /* @__PURE__ */ new Map();
253
265
  const routeName = elements.flat()[0]?.routeName ?? "index";
254
266
  elements.flat().every((elem) => elem.type === "name");
@@ -257,13 +269,13 @@ function createTypeValidatePathCondition(elements) {
257
269
  return elementArray.map((elem) => {
258
270
  const isLast = index === elements.flat().length - 1;
259
271
  if (elem.type === "name" && isLast) {
260
- const id = nanoid(6);
272
+ const id = pascalCase(elem.content);
261
273
  params.set(elem.id, id);
262
274
  return `${elem.content}\${infer ${id}}`;
263
275
  } else if (elem.type === "name") {
264
276
  return elem.content;
265
277
  } else if (elem.type === "param" || elem.type === "optionalParam") {
266
- const id = nanoid(6);
278
+ const id = pascalCase(elem.content);
267
279
  params.set(elem.id, id);
268
280
  return `\${infer ${id}}`;
269
281
  } else if (elem.type === "catchAll") {
@@ -358,6 +370,19 @@ function createTypedRouterFile() {
358
370
 
359
371
  // - Routes location for navigation types (ex: router.push or navigateTo)
360
372
 
373
+
374
+ export type NuxtRoute<T extends RoutesNamesList, P extends string, E extends boolean = false> =
375
+ | TypedRouteLocationRawFromName<T, P>
376
+ ${returnIfTrue(!pathCheck && !strictOptions.NuxtLink.strictToArgument, ` | string`)}
377
+ ${returnIfTrue(
378
+ pathCheck && strictOptions.NuxtLink.strictToArgument,
379
+ ` | (E extends true ? string : never)`
380
+ )}
381
+ ${returnIfTrue(
382
+ pathCheck && !strictOptions.NuxtLink.strictToArgument,
383
+ ` | (E extends true ? string : TypedPathParameter<P>)`
384
+ )}
385
+
361
386
  /**
362
387
  * RouteLocationRaw with discrimanated name and params properties
363
388
  * {@link RouteLocationRaw}
@@ -460,22 +485,14 @@ function createTypedRouterFile() {
460
485
  *
461
486
  * @param to - Route location to navigate to
462
487
  */
463
- push<T extends RoutesNamesList, P extends string>(to: TypedRouteLocationRawFromName<T, P>): Promise<NavigationFailure | void | undefined>;
464
- ${returnIfTrue(
465
- pathCheck && !strictOptions.router.strictToArgument,
466
- `push<T extends string>(to: TypedPathParameter<T>): Promise<NavigationFailure | void | undefined>;`
467
- )}
488
+ push<T extends RoutesNamesList, P extends string>(to: NuxtRoute<T, P>): Promise<NavigationFailure | void | undefined>;
468
489
  /**
469
490
  * Programmatically navigate to a new URL by replacing the current entry in
470
491
  * the history stack.
471
492
  *
472
493
  * @param to - Route location to navigate to
473
494
  */
474
- replace<T extends RoutesNamesList, P extends string>(to: TypedRouteLocationRawFromName<T, P>): Promise<NavigationFailure | void | undefined>;
475
- ${returnIfTrue(
476
- pathCheck && !strictOptions.router.strictToArgument,
477
- `replace<T extends string>(to: TypedPathParameter<T>): Promise<NavigationFailure | void | undefined>;`
478
- )}
495
+ replace<T extends RoutesNamesList, P extends string>(to: NuxtRoute<T, P>): Promise<NavigationFailure | void | undefined>;
479
496
  }
480
497
 
481
498
 
@@ -520,24 +537,25 @@ function createTypedRouterFile() {
520
537
  }
521
538
 
522
539
  function createTypedRouterDefinitionFile() {
523
- const strictOptions = moduleOptionStore.getResolvedStrictOptions();
540
+ moduleOptionStore.getResolvedStrictOptions();
524
541
  const { plugin, autoImport, i18n, pathCheck } = moduleOptionStore;
525
542
  return (
526
543
  /* typescript */
527
544
  `
528
545
 
529
- import type { NuxtLinkProps, PageMeta } from '#app';
546
+ import type { NuxtLinkProps, PageMeta } from 'nuxt/app';
530
547
  import NuxtLink from 'nuxt/dist/app/components/nuxt-link';
531
548
  import type { RouteLocationRaw, RouteLocationPathRaw } from 'vue-router';
532
549
  import type { RoutesNamedLocations, RoutesNamesListRecord, RoutesNamesList } from './__routes';
533
- import type {TypedRouter, TypedRoute, TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw} from './__router';
550
+ import type {TypedRouter, TypedRoute, TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw, NuxtRoute} from './__router';
534
551
  import { useRoute as _useRoute } from './__useTypedRoute';
535
552
  import { useRouter as _useRouter } from './__useTypedRouter';
536
553
  import { useLink as _useLink } from './__useTypedLink';
537
554
  import { navigateTo as _navigateTo } from './__navigateTo';
538
555
  ${returnIfTrue(
539
556
  i18n,
540
- `import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from './__i18n-router';`
557
+ `import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from './__i18n-router';
558
+ import type {TypedNuxtLinkLocale} from './__NuxtLinkLocale'`
541
559
  )}
542
560
 
543
561
  import {definePageMeta as _definePageMeta} from './__definePageMeta';
@@ -569,40 +587,28 @@ function createTypedRouterDefinitionFile() {
569
587
  )}
570
588
  }
571
589
 
572
- type TypedNuxtLinkProps<T extends string, E extends boolean = false> = Omit<NuxtLinkProps, 'to' | 'external'> &
590
+ type TypedNuxtLinkProps<
591
+ T extends RoutesNamesList,
592
+ P extends string,
593
+ E extends boolean = false> = Omit<NuxtLinkProps, 'to' | 'external'> &
573
594
  {
574
- to:
575
- | Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'> & RoutesNamedLocations
576
- | Omit<RouteLocationPathRaw, 'path'>
577
- ${returnIfTrue(
578
- pathCheck && !strictOptions.NuxtLink.strictRouteLocation,
579
- `& {path?: (E extends true ? string : TypedPathParameter<T>)}`
580
- )}
581
- ${returnIfTrue(!pathCheck && !strictOptions.NuxtLink.strictToArgument, ` | string`)}
582
- ${returnIfTrue(
583
- pathCheck && strictOptions.NuxtLink.strictToArgument,
584
- ` | (E extends true ? string : void)`
585
- )}
586
- ${returnIfTrue(
587
- pathCheck && !strictOptions.NuxtLink.strictToArgument,
588
- ` | (E extends true ? string : TypedPathParameter<T>)`
589
- )},
595
+ to: NuxtRoute<T, P, E>,
590
596
  external?: E
591
597
  }
592
598
 
593
599
 
594
600
 
595
- export type TypedNuxtLink = new <P extends string, E extends boolean = false>(props: TypedNuxtLinkProps<P, E>) => Omit<
601
+ export type TypedNuxtLink = new <T extends RoutesNamesList, P extends string, E extends boolean = false>(props: TypedNuxtLinkProps<T, P, E>) => Omit<
596
602
  typeof NuxtLink,
597
603
  '$props'
598
604
  > & {
599
- $props: TypedNuxtLinkProps<P, E>;
605
+ $props: TypedNuxtLinkProps<T, P, E>;
600
606
  };
601
607
 
602
- // Declare runtime-core instead of vue for compatibility issues with pnpm
603
608
  declare module 'vue' {
604
609
  interface GlobalComponents {
605
610
  NuxtLink: TypedNuxtLink;
611
+ ${returnIfTrue(i18n, ` NuxtLinkLocale: TypedNuxtLinkLocale;`)}
606
612
  }
607
613
  }
608
614
 
@@ -644,6 +650,7 @@ function createIndexFile() {
644
650
  TypedRouteLocationRaw,
645
651
  TypedRouteLocationRawFromName,
646
652
  TypedRouter,
653
+ NuxtRoute
647
654
  } from './__router';
648
655
  export { routesNames } from './__routes';
649
656
  export type {
@@ -908,7 +915,7 @@ function createTypeUtilsRuntimeFile() {
908
915
  }
909
916
 
910
917
  function createi18nRouterFile() {
911
- const { router } = moduleOptionStore.getResolvedStrictOptions();
918
+ const { router, NuxtLink } = moduleOptionStore.getResolvedStrictOptions();
912
919
  const { i18nOptions, pathCheck, i18nLocales } = moduleOptionStore;
913
920
  const LocalePathType = i18nOptions?.strategy === "no_prefix" ? "TypedPathParameter" : "TypedLocalePathParameter";
914
921
  return (
@@ -916,6 +923,7 @@ function createi18nRouterFile() {
916
923
  `
917
924
  import type { RouteLocationRaw } from 'vue-router';
918
925
  import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from 'vue-i18n-routing';
926
+ import type {I18nCommonRoutingOptionsWithComposable} from 'vue-i18n-routing';
919
927
  import type {TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw, TypedRouteFromName} from './__router';
920
928
  import type {RoutesNamesList} from './__routes';
921
929
  ${returnIfTrue(
@@ -925,6 +933,16 @@ function createi18nRouterFile() {
925
933
 
926
934
  export type I18nLocales = ${i18nLocales?.length ? i18nLocales.map((loc) => `"${loc}"`).join("|") : "string"};
927
935
 
936
+
937
+ export type NuxtLocaleRoute<T extends RoutesNamesList, P extends string, E extends boolean = false> =
938
+ | TypedRouteLocationRawFromName<T, P>
939
+ ${returnIfTrue(!pathCheck && !NuxtLink.strictToArgument, ` | string`)}
940
+ ${returnIfTrue(pathCheck && NuxtLink.strictToArgument, ` | (E extends true ? string : never)`)}
941
+ ${returnIfTrue(
942
+ pathCheck && !NuxtLink.strictToArgument,
943
+ ` | (E extends true ? string : ${LocalePathType}<P>)`
944
+ )}
945
+
928
946
  export interface TypedToLocalePath {
929
947
  <T extends RoutesNamesList, P extends string>(
930
948
  to: TypedRouteLocationRawFromName<T, P>,
@@ -941,7 +959,7 @@ function createi18nRouterFile() {
941
959
  )}
942
960
  }
943
961
 
944
- export function useLocalePath(options?: Pick<NonNullable<Parameters<typeof _useLocalePath>[0]>, 'i18n'>): TypedToLocalePath {
962
+ export function useLocalePath(options?: I18nCommonRoutingOptionsWithComposable): TypedToLocalePath {
945
963
  return _useLocalePath(options) as any;
946
964
  }
947
965
 
@@ -954,7 +972,7 @@ function createi18nRouterFile() {
954
972
  }
955
973
 
956
974
 
957
- export function useLocaleRoute(options?: Pick<NonNullable<Parameters<typeof _useLocaleRoute>[0]>, 'i18n'>): TypedLocaleRoute {
975
+ export function useLocaleRoute(options?: I18nCommonRoutingOptionsWithComposable): TypedLocaleRoute {
958
976
  return _useLocaleRoute(options) as any;
959
977
  }
960
978
 
@@ -1034,7 +1052,7 @@ function extractPathElements(partOfPath, route) {
1034
1052
  pathElements.push({
1035
1053
  type: "name",
1036
1054
  content: path1,
1037
- id: nanoid$1(6),
1055
+ id: nanoid(6),
1038
1056
  ...sharedProperties
1039
1057
  });
1040
1058
  }
@@ -1042,7 +1060,7 @@ function extractPathElements(partOfPath, route) {
1042
1060
  pathElements.push({
1043
1061
  type: catchAll && parentheseContent ? "catchAll" : optional ? "optionalParam" : "param",
1044
1062
  content: key,
1045
- id: nanoid$1(6),
1063
+ id: nanoid(6),
1046
1064
  ...sharedProperties
1047
1065
  });
1048
1066
  }
@@ -1050,7 +1068,7 @@ function extractPathElements(partOfPath, route) {
1050
1068
  pathElements.push({
1051
1069
  type: "name",
1052
1070
  content: path2,
1053
- id: nanoid$1(6),
1071
+ id: nanoid(6),
1054
1072
  ...sharedProperties
1055
1073
  });
1056
1074
  }
@@ -1181,7 +1199,7 @@ function createDefinePageMetaFile() {
1181
1199
  `
1182
1200
 
1183
1201
  import { definePageMeta as defaultDefinePageMeta } from '#imports';
1184
- import type {PageMeta, NuxtError} from '#app'
1202
+ import type {PageMeta, NuxtError} from 'nuxt/app'
1185
1203
  import type {TypedRouteFromName, TypedRoute, TypedRouteLocationRawFromName, TypedRouteLocationRaw} from './__router';
1186
1204
  import type {RoutesNamesList} from './__routes';
1187
1205
  ${returnIfTrue(pathCheck, `import type {TypedPathParameter} from './__paths';`)}
@@ -1301,6 +1319,40 @@ export const helpers = {
1301
1319
  );
1302
1320
  }
1303
1321
 
1322
+ function createNuxtLinkLocaleDefinitionFile() {
1323
+ moduleOptionStore.getResolvedStrictOptions();
1324
+ return (
1325
+ /* typescript */
1326
+ `
1327
+
1328
+ import type { NuxtLinkProps, PageMeta } from 'nuxt/app';
1329
+ import NuxtLink from 'nuxt/dist/app/components/nuxt-link';
1330
+ import type { RoutesNamedLocations, RoutesNamesListRecord, RoutesNamesList } from './__routes';
1331
+ import type {TypedRouter, TypedRoute, TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw} from './__router';
1332
+ import type {NuxtLocaleRoute, I18nLocales} from './__i18n-router';
1333
+
1334
+
1335
+ type TypedNuxtLinkLocaleProps<
1336
+ T extends RoutesNamesList,
1337
+ P extends string,
1338
+ E extends boolean = false> = Omit<NuxtLinkProps, 'to' | 'external'> &
1339
+ {
1340
+ to: NuxtLocaleRoute<T, P, E>,
1341
+ external?: E,
1342
+ locale?: E extends true ? never : I18nLocales
1343
+ }
1344
+
1345
+ export type TypedNuxtLinkLocale = new <T extends RoutesNamesList, P extends string, E extends boolean = false>(props: TypedNuxtLinkLocaleProps<T, P, E>) => Omit<
1346
+ typeof NuxtLink,
1347
+ '$props'
1348
+ > & {
1349
+ $props: TypedNuxtLinkLocaleProps<T, P, E>;
1350
+ };
1351
+
1352
+ `
1353
+ );
1354
+ }
1355
+
1304
1356
  async function handleAddPlugin() {
1305
1357
  const pluginName = "__typed-router.plugin.ts";
1306
1358
  addPluginTemplate({
@@ -1310,6 +1362,32 @@ async function handleAddPlugin() {
1310
1362
  });
1311
1363
  }
1312
1364
 
1365
+ const defaultPrettierOptions = {
1366
+ printWidth: 100,
1367
+ tabWidth: 2,
1368
+ trailingComma: "es5",
1369
+ singleQuote: true,
1370
+ semi: true,
1371
+ bracketSpacing: true,
1372
+ htmlWhitespaceSensitivity: "strict"
1373
+ };
1374
+ async function formatOutputWithPrettier(template) {
1375
+ try {
1376
+ let prettierFoundOptions = await prettier.resolveConfig(process.cwd());
1377
+ if (!prettierFoundOptions) {
1378
+ prettierFoundOptions = defaultPrettierOptions;
1379
+ }
1380
+ const formatedTemplate = prettier.format(template, {
1381
+ ...prettierFoundOptions,
1382
+ parser: "typescript"
1383
+ });
1384
+ return formatedTemplate;
1385
+ } catch (e) {
1386
+ console.error(logSymbols.error, chalk.red("Error while formatting the output"), "\n" + e);
1387
+ return Promise.reject(e);
1388
+ }
1389
+ }
1390
+
1313
1391
  dirname(fileURLToPath(import.meta.url));
1314
1392
  async function processPathAndWriteFile({
1315
1393
  content,
@@ -1321,14 +1399,15 @@ async function processPathAndWriteFile({
1321
1399
  const finalOutDir = outDir ?? `.nuxt/typed-router`;
1322
1400
  const processedOutDir = resolve(rootDir, finalOutDir);
1323
1401
  const outputFile = resolve(process.cwd(), `${processedOutDir}/${fileName}`);
1402
+ const formatedContent = await formatOutputWithPrettier(content);
1324
1403
  if (fs.existsSync(outputFile)) {
1325
- await writeFile(outputFile, content);
1404
+ await writeFile(outputFile, formatedContent);
1326
1405
  } else {
1327
1406
  let dirList = outputFile.split("/");
1328
1407
  dirList.pop();
1329
1408
  const dirPath = dirList.join("/");
1330
1409
  await mkdirp(dirPath);
1331
- await writeFile(outputFile, content);
1410
+ await writeFile(outputFile, formatedContent);
1332
1411
  }
1333
1412
  } catch (e) {
1334
1413
  return Promise.reject(e);
@@ -1346,11 +1425,11 @@ async function writeFile(path, content) {
1346
1425
  const watermarkTemplate = `
1347
1426
  // @ts-nocheck
1348
1427
  // eslint-disable
1349
- /**
1350
- * ---------------------------------------------------
1351
- * \u{1F697}\u{1F6A6} Generated by nuxt-typed-router. Do not modify !
1352
- * ---------------------------------------------------
1353
- * */
1428
+ // ---------------------------------------------------
1429
+ // \u{1F697}\u{1F6A6} Generated by nuxt-typed-router. Do not modify !
1430
+ // ---------------------------------------------------
1431
+
1432
+
1354
1433
 
1355
1434
  `;
1356
1435
 
@@ -1412,6 +1491,10 @@ async function saveGeneratedFiles({ outputData }) {
1412
1491
  fileName: "__i18n-router.ts",
1413
1492
  content: createi18nRouterFile()
1414
1493
  });
1494
+ filesMap.push({
1495
+ fileName: "__NuxtLinkLocale.ts",
1496
+ content: createNuxtLinkLocaleDefinitionFile()
1497
+ });
1415
1498
  }
1416
1499
  await Promise.all(
1417
1500
  filesMap.map(({ content, fileName }) => {
@@ -1464,7 +1547,7 @@ function modifyRoutePrefixDefaultIfI18n(route) {
1464
1547
  };
1465
1548
  }
1466
1549
  } else if (i18nOptions?.strategy === "prefix_except_default") {
1467
- let defaultLocale = i18nLocales.find((f) => f === i18nOptions.defaultLocale) ? i18nOptions.defaultLocale?.replace(specialCharacterRegxp, "\\$&") : "";
1550
+ let defaultLocale = i18nLocales.find((f) => f === i18nOptions.defaultLocale) ? i18nOptions.defaultLocale?.replace(specialCharacterRegxp, "\\$&") : void 0;
1468
1551
  const routeDefaultNameRegXp = new RegExp(`^([a-zA-Z0-9-]+)${separator}${defaultLocale}`, "g");
1469
1552
  const match = routeDefaultNameRegXp.exec(route.name);
1470
1553
  if (match) {
@@ -1667,7 +1750,7 @@ async function removeNuxtDefinitions({
1667
1750
  encoding: "utf8"
1668
1751
  });
1669
1752
  const replacedNuxtLink = componentDefinitions.replace(
1670
- /'NuxtLink': typeof import\(".*"\)\['default'\]/gm,
1753
+ /'NuxtLink': typeof import\(".*"\)\['default'\]|'NuxtLinkLocale': typeof import\(".*"\)\['default'\]/gm,
1671
1754
  ""
1672
1755
  );
1673
1756
  processPathAndWriteFile({
@@ -1712,8 +1795,8 @@ const module = defineNuxtModule({
1712
1795
  plugin: false,
1713
1796
  strict: false,
1714
1797
  pathCheck: true,
1715
- experimentalRemoveNuxtDefs: true,
1716
- experimentalIgnoreRoutes: []
1798
+ removeNuxtDefs: true,
1799
+ ignoreRoutes: []
1717
1800
  },
1718
1801
  setup(moduleOptions, nuxt) {
1719
1802
  const { resolve } = createResolver(import.meta.url);
@@ -1735,10 +1818,18 @@ const module = defineNuxtModule({
1735
1818
  return isRegistered;
1736
1819
  }
1737
1820
  });
1821
+ const isDocumentDriven = !!nuxt.options.modules.find((mod) => {
1822
+ if (Array.isArray(mod)) {
1823
+ return mod[0] === "@nuxt/content";
1824
+ } else {
1825
+ return mod === "@nuxt/content";
1826
+ }
1827
+ }) && "content" in nuxt.options && "documentDriven" in nuxt.options.content;
1738
1828
  moduleOptionStore.updateOptions({
1739
1829
  ...moduleOptions,
1740
1830
  i18n: hasi18nModuleRegistered,
1741
- i18nOptions
1831
+ i18nOptions,
1832
+ isDocumentDriven
1742
1833
  });
1743
1834
  nuxt.options.alias = {
1744
1835
  ...nuxt.options.alias,
@@ -1752,7 +1843,7 @@ const module = defineNuxtModule({
1752
1843
  experimentalRfc436: true
1753
1844
  };
1754
1845
  }
1755
- if (moduleOptions.experimentalRemoveNuxtDefs) {
1846
+ if (moduleOptions.removeNuxtDefs) {
1756
1847
  removeNuxtDefinitions({
1757
1848
  autoImport: nuxt.options.imports.autoImport ?? true,
1758
1849
  buildDir: nuxt.options.buildDir
@@ -1760,7 +1851,7 @@ const module = defineNuxtModule({
1760
1851
  }
1761
1852
  });
1762
1853
  nuxt.hook("build:done", () => {
1763
- if (moduleOptions.experimentalRemoveNuxtDefs) {
1854
+ if (moduleOptions.removeNuxtDefs) {
1764
1855
  removeNuxtDefinitions({
1765
1856
  autoImport: nuxt.options.imports.autoImport ?? true,
1766
1857
  buildDir: nuxt.options.buildDir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-typed-router",
3
- "version": "3.3.3",
3
+ "version": "3.5.0-beta.0",
4
4
  "description": "Provide autocompletion for routes paths, names and params in Nuxt apps",
5
5
  "type": "module",
6
6
  "main": "./dist/module.cjs",
@@ -59,42 +59,46 @@
59
59
  "bugs": {
60
60
  "url": "https://github.com/victorgarciaesgi/nuxt-typed-router/issues"
61
61
  },
62
+ "peerDependencies": {
63
+ "prettier": "^2.8.5 || 3.x"
64
+ },
62
65
  "dependencies": {
63
- "@nuxt/kit": "3.8.1",
66
+ "@nuxt/kit": "3.8.2",
64
67
  "chalk": "5.3.0",
65
68
  "defu": "6.1.3",
66
69
  "lodash-es": "4.17.21",
67
- "log-symbols": "5.1.0",
70
+ "log-symbols": "6.0.0",
68
71
  "mkdirp": "3.0.1",
69
72
  "nanoid": "5.0.3",
70
73
  "pathe": "1.1.1"
71
74
  },
72
75
  "devDependencies": {
73
- "@nuxt/devtools": "1.0.0",
76
+ "@nuxt/devtools": "1.0.3",
74
77
  "@nuxt/module-builder": "0.5.4",
75
78
  "@nuxt/test-utils": "3.8.1",
76
79
  "@nuxt/types": "2.17.2",
77
80
  "@nuxtjs/eslint-config-typescript": "12.1.0",
78
- "@nuxtjs/i18n": "8.0.0-beta.10",
81
+ "@nuxt/content": "2.9.0",
82
+ "@nuxtjs/i18n": "8.0.0-rc.5",
79
83
  "@nuxtjs/web-vitals": "0.2.6",
80
- "@types/lodash-es": "4.17.11",
81
- "@types/node": "20.9.0",
84
+ "@types/lodash-es": "4.17.12",
85
+ "@types/node": "20.10.0",
82
86
  "@types/prettier": "3.0.0",
83
- "@typescript-eslint/eslint-plugin": "6.10.0",
84
- "@typescript-eslint/parser": "6.10.0",
85
- "@vue/test-utils": "2.4.1",
87
+ "@typescript-eslint/eslint-plugin": "6.12.0",
88
+ "@typescript-eslint/parser": "6.12.0",
89
+ "@vue/test-utils": "2.4.2",
86
90
  "bumpp": "9.2.0",
87
91
  "changelogithub": "0.13.2",
88
92
  "cross-env": "7.0.3",
89
- "eslint": "8.53.0",
93
+ "eslint": "8.54.0",
90
94
  "eslint-config-prettier": "9.0.0",
91
95
  "eslint-plugin-vue": "9.18.1",
92
- "nuxt": "3.8.1",
96
+ "nuxt": "3.8.2",
93
97
  "nuxt-seo-kit": "1.3.13",
94
98
  "playwright": "1.37.0",
95
- "prettier": "3.0.3",
99
+ "prettier": "3.1.0",
96
100
  "tsd": "0.29.0",
97
- "typescript": "5.2.2",
101
+ "typescript": "5.3.2",
98
102
  "vitest": "0.34.6",
99
103
  "vue-eslint-parser": "9.3.2",
100
104
  "vue-router": "4.2.5",