nuxt-typed-router 2.2.2-beta.1 → 2.3.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/dist/module.json +2 -2
- package/dist/module.mjs +138 -53
- package/package.json +10 -8
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -15,6 +15,8 @@ class ModuleOptionsStore {
|
|
|
15
15
|
this.strict = false;
|
|
16
16
|
this.autoImport = false;
|
|
17
17
|
this.rootDir = "";
|
|
18
|
+
this.i18n = false;
|
|
19
|
+
this.i18nLocales = [];
|
|
18
20
|
}
|
|
19
21
|
updateOptions(options) {
|
|
20
22
|
if (options.plugin != null)
|
|
@@ -25,6 +27,10 @@ class ModuleOptionsStore {
|
|
|
25
27
|
this.autoImport = options.autoImport;
|
|
26
28
|
if (options.rootDir != null)
|
|
27
29
|
this.rootDir = options.rootDir;
|
|
30
|
+
if (options.i18n != null)
|
|
31
|
+
this.i18n = options.i18n;
|
|
32
|
+
if (options.i18nLocales != null)
|
|
33
|
+
this.i18nLocales = options.i18nLocales;
|
|
28
34
|
}
|
|
29
35
|
getResolvedStrictOptions() {
|
|
30
36
|
let resolved;
|
|
@@ -171,8 +177,6 @@ function createRoutesTypesFile({
|
|
|
171
177
|
|
|
172
178
|
${createRoutesNamedLocationsResolvedExport(routesParams)}
|
|
173
179
|
|
|
174
|
-
|
|
175
|
-
|
|
176
180
|
export type RoutesNamesListRecord = ${routesDeclTemplate};
|
|
177
181
|
|
|
178
182
|
export const routesNames = ${routesObjectTemplate};
|
|
@@ -209,6 +213,7 @@ function createTypedRouterFile() {
|
|
|
209
213
|
RouteLocationNormalizedLoaded,
|
|
210
214
|
RouteLocationRaw,
|
|
211
215
|
Router,
|
|
216
|
+
RouteLocationPathRaw
|
|
212
217
|
} from 'vue-router';
|
|
213
218
|
import type {
|
|
214
219
|
RoutesNamedLocations,
|
|
@@ -227,22 +232,26 @@ function createTypedRouterFile() {
|
|
|
227
232
|
* {@link RouteLocationRaw}
|
|
228
233
|
* */
|
|
229
234
|
export type TypedRouteLocationRaw =
|
|
230
|
-
| (Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'
|
|
235
|
+
| (Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'> & RoutesNamedLocations)
|
|
236
|
+
${returnIfFalse(strictOptions.router.strictToArgument, "| string")}
|
|
237
|
+
${returnIfTrue(
|
|
231
238
|
strictOptions.router.strictRouteLocation,
|
|
232
|
-
`| 'path'
|
|
233
|
-
|
|
234
|
-
|
|
239
|
+
`| Omit<RouteLocationPathRaw, 'path'>`,
|
|
240
|
+
"| RouteLocationPathRaw"
|
|
241
|
+
)};
|
|
235
242
|
|
|
236
243
|
|
|
237
244
|
/**
|
|
238
245
|
* Alternative version of {@link TypedRouteLocationRaw} but with a name generic
|
|
239
246
|
*/
|
|
240
247
|
export type TypedRouteLocationRawFromName<T extends RoutesNamesList> =
|
|
241
|
-
| (Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'
|
|
248
|
+
| (Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'> & TypedLocationAsRelativeRaw<T>)
|
|
249
|
+
${returnIfFalse(strictOptions.router.strictToArgument, "| string")}
|
|
250
|
+
${returnIfTrue(
|
|
242
251
|
strictOptions.router.strictRouteLocation,
|
|
243
|
-
`| 'path'
|
|
244
|
-
|
|
245
|
-
|
|
252
|
+
`| Omit<RouteLocationPathRaw, 'path'>`,
|
|
253
|
+
"| RouteLocationPathRaw"
|
|
254
|
+
)}
|
|
246
255
|
|
|
247
256
|
/**
|
|
248
257
|
* Generic providing inference and dynamic inclusion of \`params\` property
|
|
@@ -344,7 +353,7 @@ function createTypedRouterFile() {
|
|
|
344
353
|
}
|
|
345
354
|
|
|
346
355
|
function createTypedRouterDefinitionFile() {
|
|
347
|
-
const { plugin, autoImport } = moduleOptionStore;
|
|
356
|
+
const { plugin, autoImport, i18n } = moduleOptionStore;
|
|
348
357
|
const strictOptions = moduleOptionStore.getResolvedStrictOptions();
|
|
349
358
|
return (
|
|
350
359
|
/* typescript */
|
|
@@ -352,12 +361,13 @@ function createTypedRouterDefinitionFile() {
|
|
|
352
361
|
|
|
353
362
|
import type { NuxtLinkProps } from '#app';
|
|
354
363
|
import type { DefineComponent } from 'vue';
|
|
355
|
-
import type { RouteLocationRaw } from 'vue-router';
|
|
364
|
+
import type { RouteLocationRaw, RouteLocationPathRaw } from 'vue-router';
|
|
356
365
|
import type { RoutesNamedLocations, RoutesNamesListRecord } from './__routes';
|
|
357
366
|
import type {TypedRouter, TypedRoute} from './__router';
|
|
358
367
|
import { useRoute as _useRoute } from './__useTypedRoute';
|
|
359
368
|
import { useRouter as _useRouter } from './__useTypedRouter';
|
|
360
369
|
import { navigateTo as _navigateTo } from './__navigateTo';
|
|
370
|
+
import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from './__i18n-router';
|
|
361
371
|
|
|
362
372
|
declare global {
|
|
363
373
|
|
|
@@ -367,18 +377,28 @@ function createTypedRouterDefinitionFile() {
|
|
|
367
377
|
`
|
|
368
378
|
const useRoute: typeof _useRoute;
|
|
369
379
|
const useRouter: typeof _useRouter;
|
|
370
|
-
const navigateTo: typeof _navigateTo
|
|
380
|
+
const navigateTo: typeof _navigateTo;
|
|
381
|
+
${returnIfTrue(
|
|
382
|
+
i18n,
|
|
383
|
+
/* typescript */
|
|
384
|
+
`
|
|
385
|
+
const useLocalePath: typeof _useLocalePath;
|
|
386
|
+
const useLocaleRoute: typeof _useLocaleRoute;
|
|
387
|
+
`
|
|
388
|
+
)}
|
|
389
|
+
`
|
|
371
390
|
)}
|
|
372
391
|
}
|
|
373
392
|
|
|
374
393
|
type TypedNuxtLinkProps = Omit<NuxtLinkProps, 'to'> & {
|
|
375
|
-
to:
|
|
376
|
-
|
|
377
|
-
"string
|
|
378
|
-
|
|
394
|
+
to:
|
|
395
|
+
Omit<Exclude<RouteLocationRaw, string>, 'name' | 'params'> & RoutesNamedLocations
|
|
396
|
+
${returnIfFalse(strictOptions.NuxtLink.strictToArgument, "| string")}
|
|
397
|
+
${returnIfTrue(
|
|
379
398
|
strictOptions.NuxtLink.strictRouteLocation,
|
|
380
|
-
`| 'path'
|
|
381
|
-
|
|
399
|
+
`| Omit<RouteLocationPathRaw, 'path'>`,
|
|
400
|
+
"| RouteLocationPathRaw"
|
|
401
|
+
)}
|
|
382
402
|
};
|
|
383
403
|
|
|
384
404
|
export type TypedNuxtLink = DefineComponent<
|
|
@@ -426,31 +446,33 @@ function createTypedRouterDefinitionFile() {
|
|
|
426
446
|
}
|
|
427
447
|
|
|
428
448
|
function createIndexFile() {
|
|
449
|
+
const { i18n } = moduleOptionStore;
|
|
429
450
|
return (
|
|
430
451
|
/* typescript */
|
|
431
452
|
`
|
|
432
453
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
+
export type {
|
|
455
|
+
TypedLocationAsRelativeRaw,
|
|
456
|
+
TypedResolvedMatcherLocation,
|
|
457
|
+
TypedRoute,
|
|
458
|
+
TypedRouteFromName,
|
|
459
|
+
TypedRouteLocationFromName,
|
|
460
|
+
TypedRouteLocationRaw,
|
|
461
|
+
TypedRouteLocationRawFromName,
|
|
462
|
+
TypedRouter,
|
|
463
|
+
} from './__router';
|
|
464
|
+
export { routesNames } from './__routes';
|
|
465
|
+
export type {
|
|
466
|
+
RoutesNamedLocations,
|
|
467
|
+
RoutesNamedLocationsResolved,
|
|
468
|
+
RoutesNamesList,
|
|
469
|
+
RoutesNamesListRecord,
|
|
470
|
+
RoutesParamsRecord,
|
|
471
|
+
} from './__routes';
|
|
472
|
+
export { useRoute } from './__useTypedRoute';
|
|
473
|
+
export { useRouter } from './__useTypedRouter';
|
|
474
|
+
export { navigateTo } from './__navigateTo';
|
|
475
|
+
${returnIfTrue(i18n, `export {useLocalePath, useLocaleRoute} from './__i18n-router.ts';`)}
|
|
454
476
|
`
|
|
455
477
|
);
|
|
456
478
|
}
|
|
@@ -598,6 +620,35 @@ function createTypeUtilsRuntimeFile() {
|
|
|
598
620
|
);
|
|
599
621
|
}
|
|
600
622
|
|
|
623
|
+
function createi18nRouterFile() {
|
|
624
|
+
const { i18nLocales } = moduleOptionStore;
|
|
625
|
+
return (
|
|
626
|
+
/* typescript */
|
|
627
|
+
`
|
|
628
|
+
|
|
629
|
+
import { useLocalePath as _useLocalePath, useLocaleRoute as _useLocaleRoute} from 'vue-i18n-routing';
|
|
630
|
+
import type {TypedRouteLocationRawFromName, TypedRouteFromName} from './__router';
|
|
631
|
+
import type {RoutesNamesList} from './__routes';
|
|
632
|
+
|
|
633
|
+
export type I18nLocales = ${i18nLocales.map((loc) => `"${loc}"`).join("|")};
|
|
634
|
+
|
|
635
|
+
export type TypedToLocalePath = <T extends RoutesNamesList>(to: TypedRouteLocationRawFromName<T>, locale?: I18nLocales | undefined) => TypedRouteLocationRawFromName<T>;
|
|
636
|
+
|
|
637
|
+
export function useLocalePath(options?: Pick<NonNullable<Parameters<typeof _useLocalePath>[0]>, 'i18n'>): TypedToLocalePath {
|
|
638
|
+
return _useLocalePath(options) as any;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
export type TypedLocaleRoute = <T extends RoutesNamesList>(to: TypedRouteLocationRawFromName<T>, locale?: I18nLocales | undefined) => TypedRouteFromName<T>;
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
export function useLocaleRoute(options?: Pick<NonNullable<Parameters<typeof _useLocaleRoute>[0]>, 'i18n'>): TypedLocaleRoute {
|
|
645
|
+
return _useLocaleRoute(options) as any;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
`
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
|
|
601
652
|
async function handleAddPlugin() {
|
|
602
653
|
const pluginName = "__typed-router.plugin.ts";
|
|
603
654
|
addPluginTemplate({
|
|
@@ -683,6 +734,7 @@ let previousGeneratedRoutes = "";
|
|
|
683
734
|
async function saveGeneratedFiles({
|
|
684
735
|
outputData: { routesDeclTemplate, routesList, routesObjectTemplate, routesParams }
|
|
685
736
|
}) {
|
|
737
|
+
const { i18n } = moduleOptionStore;
|
|
686
738
|
const filesMap = [
|
|
687
739
|
{
|
|
688
740
|
fileName: "__useTypedRouter.ts",
|
|
@@ -722,6 +774,12 @@ async function saveGeneratedFiles({
|
|
|
722
774
|
content: createIndexFile()
|
|
723
775
|
}
|
|
724
776
|
];
|
|
777
|
+
if (i18n) {
|
|
778
|
+
filesMap.push({
|
|
779
|
+
fileName: "__i18n-router.ts",
|
|
780
|
+
content: createi18nRouterFile()
|
|
781
|
+
});
|
|
782
|
+
}
|
|
725
783
|
await Promise.all(
|
|
726
784
|
filesMap.map(({ content, fileName }) => {
|
|
727
785
|
const waterMakeredContent = `
|
|
@@ -800,6 +858,22 @@ function extractChunkMain(chunkName) {
|
|
|
800
858
|
return chunkArray?.join("/");
|
|
801
859
|
}
|
|
802
860
|
|
|
861
|
+
function createKeyedName(route) {
|
|
862
|
+
const splittedPaths = route.path.split("/");
|
|
863
|
+
const parentPath = splittedPaths[splittedPaths.length - 1];
|
|
864
|
+
const nameKey = camelCase(parentPath || "index");
|
|
865
|
+
return nameKey;
|
|
866
|
+
}
|
|
867
|
+
function createNameKeyFromFullName(route, level, parentName) {
|
|
868
|
+
let splitted = [];
|
|
869
|
+
splitted = route.name?.split("-") ?? [];
|
|
870
|
+
splitted = splitted.slice(level, splitted.length);
|
|
871
|
+
if (splitted[0] === parentName) {
|
|
872
|
+
splitted.splice(0, 1);
|
|
873
|
+
}
|
|
874
|
+
const keyName = route.path === "" ? "index" : camelCase(splitted.join("-")) || "index";
|
|
875
|
+
return keyName;
|
|
876
|
+
}
|
|
803
877
|
function walkThoughRoutes({
|
|
804
878
|
route,
|
|
805
879
|
level,
|
|
@@ -816,9 +890,14 @@ function walkThoughRoutes({
|
|
|
816
890
|
const isRootSibling = lastChunkArray === "index";
|
|
817
891
|
if (route.children?.length && !haveMatchingSiblings || !route.children?.length && haveMatchingSiblings && isRootSibling) {
|
|
818
892
|
let childrenChunks = haveMatchingSiblings ? matchingSiblings : route.children;
|
|
819
|
-
|
|
820
|
-
const
|
|
821
|
-
|
|
893
|
+
let nameKey = createKeyedName(route);
|
|
894
|
+
const hasSamePathI18nSibling = siblings?.some((sibling) => {
|
|
895
|
+
const _name = createKeyedName(sibling);
|
|
896
|
+
return _name === nameKey;
|
|
897
|
+
});
|
|
898
|
+
if (hasSamePathI18nSibling) {
|
|
899
|
+
nameKey = camelCase(route.path.split("/").join("-"));
|
|
900
|
+
}
|
|
822
901
|
output.routesObjectTemplate += `${nameKey}:{`;
|
|
823
902
|
output.routesDeclTemplate += `"${nameKey}":{`;
|
|
824
903
|
const allRouteParams = extractRouteParamsFromPath(route.path, false, previousParams);
|
|
@@ -836,13 +915,14 @@ function walkThoughRoutes({
|
|
|
836
915
|
output.routesObjectTemplate += "},";
|
|
837
916
|
output.routesDeclTemplate += `}${isLast ? "" : ","}`;
|
|
838
917
|
} else if (route.name) {
|
|
839
|
-
let
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
918
|
+
let keyName = createNameKeyFromFullName(route, level, parentName);
|
|
919
|
+
const hasSameNameI18nSibling = siblings?.some((sibling) => {
|
|
920
|
+
const _name = createNameKeyFromFullName(sibling, level, parentName);
|
|
921
|
+
return _name === keyName;
|
|
922
|
+
});
|
|
923
|
+
if (hasSameNameI18nSibling) {
|
|
924
|
+
keyName = camelCase(route.name);
|
|
844
925
|
}
|
|
845
|
-
const keyName = route.path === "" ? "index" : camelCase(splitted.join("-")) || "index";
|
|
846
926
|
output.routesObjectTemplate += `'${keyName}': '${route.name}' as const,`;
|
|
847
927
|
output.routesDeclTemplate += `"${keyName}": "${route.name}"${isLast ? "" : ","}`;
|
|
848
928
|
output.routesList.push(route.name);
|
|
@@ -877,7 +957,7 @@ function constructRouteMap(routesConfig) {
|
|
|
877
957
|
}
|
|
878
958
|
function startGenerator({ output, routesConfig }) {
|
|
879
959
|
routesConfig.forEach((route, index) => {
|
|
880
|
-
const rootSiblingsRoutes = routesConfig.filter((rt) => rt.
|
|
960
|
+
const rootSiblingsRoutes = routesConfig.filter((rt) => rt.path !== route.path);
|
|
881
961
|
walkThoughRoutes({
|
|
882
962
|
route,
|
|
883
963
|
level: 0,
|
|
@@ -946,16 +1026,21 @@ const module = defineNuxtModule({
|
|
|
946
1026
|
meta: {
|
|
947
1027
|
name: "nuxt-typed-router",
|
|
948
1028
|
configKey: "nuxtTypedRouter",
|
|
949
|
-
compatibility: { nuxt: "^3.0.0
|
|
1029
|
+
compatibility: { nuxt: "^3.0.0", bridge: false }
|
|
950
1030
|
},
|
|
951
1031
|
defaults: {
|
|
952
1032
|
plugin: false,
|
|
953
1033
|
strict: false
|
|
954
1034
|
},
|
|
955
1035
|
setup(moduleOptions, nuxt) {
|
|
956
|
-
const rootDir = nuxt.options.rootDir;
|
|
957
|
-
moduleOptionStore.updateOptions(moduleOptions);
|
|
958
1036
|
const { resolve } = createResolver(import.meta.url);
|
|
1037
|
+
const rootDir = nuxt.options.rootDir;
|
|
1038
|
+
const hasi18nModuleRegistered = !!nuxt.options.modules.find((mod) => mod === "@nuxtjs/i18n");
|
|
1039
|
+
moduleOptionStore.updateOptions({
|
|
1040
|
+
...moduleOptions,
|
|
1041
|
+
i18n: hasi18nModuleRegistered,
|
|
1042
|
+
i18nLocales: nuxt.options?.i18n?.locales ?? []
|
|
1043
|
+
});
|
|
959
1044
|
nuxt.options.alias = {
|
|
960
1045
|
...nuxt.options.alias,
|
|
961
1046
|
"@typed-router": resolve(`${rootDir}/.nuxt/typed-router`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-typed-router",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0-beta.0",
|
|
4
4
|
"description": "Provide autocompletion for pages route names generated by Nuxt router",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/module.cjs",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"dev:build": "nuxi build playground",
|
|
22
22
|
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground && pnpm run test:prepare-fixtures",
|
|
23
23
|
"build:test": "cross-env NUXT_BUILD_TYPE=stub pnpm run prepack && pnpm run dev:build",
|
|
24
|
-
"test:prepare-fixtures": "nuxi prepare test/fixtures/simple && nuxi
|
|
24
|
+
"test:prepare-fixtures": "nuxi prepare test/fixtures/simple && nuxi prepare test/fixtures/withOptions && nuxi prepare test/fixtures/complex",
|
|
25
25
|
"test:fixtures": " vitest run --dir test",
|
|
26
26
|
"test:types": "pnpm run typecheck && pnpm run test:vue && vitest typecheck --run --dir test",
|
|
27
|
-
"test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit",
|
|
27
|
+
"test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit && vue-tsc -p test/fixtures/withOptions/tsconfig.json --noEmit",
|
|
28
28
|
"test": "pnpm run dev:prepare && pnpm run test:fixtures && pnpm run test:types",
|
|
29
29
|
"docs:dev": "cd docs && pnpm run dev",
|
|
30
30
|
"docs:build": "npm run dev:prepare && cd docs && nuxi generate",
|
|
@@ -59,31 +59,33 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@nuxt/kit": "3.1.1",
|
|
61
61
|
"chalk": "^5.2.0",
|
|
62
|
+
"defu": "^6.1.2",
|
|
62
63
|
"lodash-es": "^4.17.21",
|
|
63
64
|
"log-symbols": "^5.1.0",
|
|
64
65
|
"mkdirp": "^1.0.4",
|
|
65
66
|
"pathe": "1.1.0",
|
|
66
|
-
"prettier": "2.8.3"
|
|
67
|
-
"defu": "^6.1.2"
|
|
67
|
+
"prettier": "2.8.3"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@nuxt/module-builder": "^0.2.1",
|
|
71
71
|
"@nuxt/test-utils": "^3.1.1",
|
|
72
72
|
"@nuxt/types": "^2.15.8",
|
|
73
73
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
|
74
|
+
"@nuxtjs/i18n": "8.0.0-beta.9",
|
|
74
75
|
"@types/lodash-es": "^4.17.6",
|
|
75
76
|
"@types/mkdirp": "^1.0.2",
|
|
76
77
|
"@types/node": "^17.0.23",
|
|
77
78
|
"@types/prettier": "^2.7.2",
|
|
78
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
79
|
-
"@typescript-eslint/parser": "^5.
|
|
79
|
+
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
|
80
|
+
"@typescript-eslint/parser": "^5.50.0",
|
|
81
|
+
"@vue/test-utils": "^2.2.8",
|
|
80
82
|
"cross-env": "^7.0.3",
|
|
81
83
|
"eslint": "8.33.0",
|
|
82
84
|
"eslint-config-prettier": "^8.6.0",
|
|
83
85
|
"eslint-plugin-vue": "^9.9.0",
|
|
84
86
|
"nuxt": "3.1.1",
|
|
85
87
|
"playwright": "1.30.0",
|
|
86
|
-
"typescript": "^4.9.
|
|
88
|
+
"typescript": "^4.9.5",
|
|
87
89
|
"vitest": "^0.28.3",
|
|
88
90
|
"vue-eslint-parser": "^9.1.0",
|
|
89
91
|
"vue-router": "^4.1.6",
|