nuxt-typed-router 3.4.0 → 3.5.0-beta.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/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "nuxt": "^3.0.0",
6
6
  "bridge": false
7
7
  },
8
- "version": "3.4.0"
8
+ "version": "3.5.0-beta.1"
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 {
@@ -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") {
@@ -61,6 +67,9 @@ class ModuleOptionsStore {
61
67
  if (options.ignoreRoutes) {
62
68
  this.ignoreRoutes = options.ignoreRoutes;
63
69
  }
70
+ if (options.isDocumentDriven) {
71
+ this.ignoreRoutes.push("[...slug].vue");
72
+ }
64
73
  }
65
74
  get resolvedIgnoredRoutes() {
66
75
  return this.ignoreRoutes.map((file) => path.join(this.pagesDir, file));
@@ -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 = `T${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 = `T${pascalCase(elem.content)}`;
267
279
  params.set(elem.id, id);
268
280
  return `\${infer ${id}}`;
269
281
  } else if (elem.type === "catchAll") {
@@ -911,6 +923,7 @@ function createi18nRouterFile() {
911
923
  `
912
924
  import type { RouteLocationRaw } from 'vue-router';
913
925
  import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from 'vue-i18n-routing';
926
+ import type {I18nCommonRoutingOptionsWithComposable} from 'vue-i18n-routing';
914
927
  import type {TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw, TypedRouteFromName} from './__router';
915
928
  import type {RoutesNamesList} from './__routes';
916
929
  ${returnIfTrue(
@@ -946,7 +959,7 @@ function createi18nRouterFile() {
946
959
  )}
947
960
  }
948
961
 
949
- export function useLocalePath(options?: Pick<NonNullable<Parameters<typeof _useLocalePath>[0]>, 'i18n'>): TypedToLocalePath {
962
+ export function useLocalePath(options?: I18nCommonRoutingOptionsWithComposable): TypedToLocalePath {
950
963
  return _useLocalePath(options) as any;
951
964
  }
952
965
 
@@ -959,7 +972,7 @@ function createi18nRouterFile() {
959
972
  }
960
973
 
961
974
 
962
- export function useLocaleRoute(options?: Pick<NonNullable<Parameters<typeof _useLocaleRoute>[0]>, 'i18n'>): TypedLocaleRoute {
975
+ export function useLocaleRoute(options?: I18nCommonRoutingOptionsWithComposable): TypedLocaleRoute {
963
976
  return _useLocaleRoute(options) as any;
964
977
  }
965
978
 
@@ -1039,7 +1052,7 @@ function extractPathElements(partOfPath, route) {
1039
1052
  pathElements.push({
1040
1053
  type: "name",
1041
1054
  content: path1,
1042
- id: nanoid$1(6),
1055
+ id: nanoid(6),
1043
1056
  ...sharedProperties
1044
1057
  });
1045
1058
  }
@@ -1047,7 +1060,7 @@ function extractPathElements(partOfPath, route) {
1047
1060
  pathElements.push({
1048
1061
  type: catchAll && parentheseContent ? "catchAll" : optional ? "optionalParam" : "param",
1049
1062
  content: key,
1050
- id: nanoid$1(6),
1063
+ id: nanoid(6),
1051
1064
  ...sharedProperties
1052
1065
  });
1053
1066
  }
@@ -1055,7 +1068,7 @@ function extractPathElements(partOfPath, route) {
1055
1068
  pathElements.push({
1056
1069
  type: "name",
1057
1070
  content: path2,
1058
- id: nanoid$1(6),
1071
+ id: nanoid(6),
1059
1072
  ...sharedProperties
1060
1073
  });
1061
1074
  }
@@ -1349,6 +1362,32 @@ async function handleAddPlugin() {
1349
1362
  });
1350
1363
  }
1351
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
+
1352
1391
  dirname(fileURLToPath(import.meta.url));
1353
1392
  async function processPathAndWriteFile({
1354
1393
  content,
@@ -1360,14 +1399,15 @@ async function processPathAndWriteFile({
1360
1399
  const finalOutDir = outDir ?? `.nuxt/typed-router`;
1361
1400
  const processedOutDir = resolve(rootDir, finalOutDir);
1362
1401
  const outputFile = resolve(process.cwd(), `${processedOutDir}/${fileName}`);
1402
+ const formatedContent = await formatOutputWithPrettier(content);
1363
1403
  if (fs.existsSync(outputFile)) {
1364
- await writeFile(outputFile, content);
1404
+ await writeFile(outputFile, formatedContent);
1365
1405
  } else {
1366
1406
  let dirList = outputFile.split("/");
1367
1407
  dirList.pop();
1368
1408
  const dirPath = dirList.join("/");
1369
1409
  await mkdirp(dirPath);
1370
- await writeFile(outputFile, content);
1410
+ await writeFile(outputFile, formatedContent);
1371
1411
  }
1372
1412
  } catch (e) {
1373
1413
  return Promise.reject(e);
@@ -1385,11 +1425,11 @@ async function writeFile(path, content) {
1385
1425
  const watermarkTemplate = `
1386
1426
  // @ts-nocheck
1387
1427
  // eslint-disable
1388
- /**
1389
- * ---------------------------------------------------
1390
- * \u{1F697}\u{1F6A6} Generated by nuxt-typed-router. Do not modify !
1391
- * ---------------------------------------------------
1392
- * */
1428
+ // ---------------------------------------------------
1429
+ // \u{1F697}\u{1F6A6} Generated by nuxt-typed-router. Do not modify !
1430
+ // ---------------------------------------------------
1431
+
1432
+
1393
1433
 
1394
1434
  `;
1395
1435
 
@@ -1507,7 +1547,7 @@ function modifyRoutePrefixDefaultIfI18n(route) {
1507
1547
  };
1508
1548
  }
1509
1549
  } else if (i18nOptions?.strategy === "prefix_except_default") {
1510
- 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;
1511
1551
  const routeDefaultNameRegXp = new RegExp(`^([a-zA-Z0-9-]+)${separator}${defaultLocale}`, "g");
1512
1552
  const match = routeDefaultNameRegXp.exec(route.name);
1513
1553
  if (match) {
@@ -1778,10 +1818,18 @@ const module = defineNuxtModule({
1778
1818
  return isRegistered;
1779
1819
  }
1780
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;
1781
1828
  moduleOptionStore.updateOptions({
1782
1829
  ...moduleOptions,
1783
1830
  i18n: hasi18nModuleRegistered,
1784
- i18nOptions
1831
+ i18nOptions,
1832
+ isDocumentDriven
1785
1833
  });
1786
1834
  nuxt.options.alias = {
1787
1835
  ...nuxt.options.alias,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-typed-router",
3
- "version": "3.4.0",
3
+ "version": "3.5.0-beta.1",
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,6 +59,9 @@
59
59
  "bugs": {
60
60
  "url": "https://github.com/victorgarciaesgi/nuxt-typed-router/issues"
61
61
  },
62
+ "peerDependencies": {
63
+ "prettier": "^2.5.x || 3.x"
64
+ },
62
65
  "dependencies": {
63
66
  "@nuxt/kit": "3.8.2",
64
67
  "chalk": "5.3.0",
@@ -75,6 +78,7 @@
75
78
  "@nuxt/test-utils": "3.8.1",
76
79
  "@nuxt/types": "2.17.2",
77
80
  "@nuxtjs/eslint-config-typescript": "12.1.0",
81
+ "@nuxt/content": "2.9.0",
78
82
  "@nuxtjs/i18n": "8.0.0-rc.5",
79
83
  "@nuxtjs/web-vitals": "0.2.6",
80
84
  "@types/lodash-es": "4.17.12",