New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

nuxt-typed-router

Package Overview
Dependencies
Maintainers
1
Versions
216
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nuxt-typed-router - npm Package Compare versions

Comparing version 0.1.14 to 0.2.0

lib/index.js

232

lib/module.js

@@ -1,117 +0,125 @@

// @ts-check
import fs from 'fs';
import * as prettier from 'prettier';
import { camelCase } from 'lodash';
import chalk from 'chalk';
const path = require('path');
const logSymbols = require('log-symbols');
function typedRouterModule(moduleOptions) {
const options = { ...this.options.typedRouter, ...moduleOptions };
this.addPlugin({
src: path.resolve(__dirname, './templates/nuxt-typed-router.js'),
});
this.nuxt.hook('build:extendRoutes', async routes => {
try {
// Redirect with @
this.extendRoutes(async existingRoutes => {
let formatedRoutes;
const recursiveMatch = (route, parent) => {
if (route.path && route.path.startsWith('@') && !!parent) {
route.path = route.path.split('@')[1];
const parentsChildren = parent.children;
if (parentsChildren) {
let defaultName = null;
if (route.name) {
defaultName = route.name;
} else if (route.children) {
const child = route.children.find(f => f.path === '');
if (child) {
defaultName = child.name;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const prettier = __importStar(require("prettier"));
const lodash_1 = require("lodash");
const chalk_1 = __importDefault(require("chalk"));
const path_1 = __importDefault(require("path"));
const log_symbols_1 = __importDefault(require("log-symbols"));
require("./templates/nuxt-typed-router");
const typedRouterModule = function (moduleOptions) {
const { filePath = `${this.options.srcDir}/__routes.js`, routesObjectName = 'routerPagesNames', stripAtFromName = false, } = { ...this.options.typedRouter, ...moduleOptions };
this.nuxt.hook('build:extendRoutes', async (routes) => {
try {
this.extendRoutes(async (existingRoutes) => {
let formatedRoutes;
const recursiveMatch = (route, parent) => {
var _a;
if (route.path && route.path.startsWith('@') && !!parent) {
route.path = route.path.split('@')[1];
if (stripAtFromName && route.name) {
const [left, right] = (_a = route.name) === null || _a === void 0 ? void 0 : _a.split('@');
route.name = `${left}${right}`;
}
const parentsChildren = parent.children;
if (parentsChildren) {
let defaultName = null;
if (route.name) {
defaultName = route.name;
}
else if (route.children) {
const child = route.children.find((f) => f.path === '');
if (child) {
defaultName = child.name;
}
}
else {
defaultName = null;
}
parentsChildren.push({
path: '',
name: `${parent.name}-index`,
redirect: {
...(defaultName && { name: defaultName }),
...(!defaultName && { path: route.path }),
},
});
}
}
if (route.children) {
route.children.forEach((child) => recursiveMatch(child, route));
}
};
existingRoutes.map((route) => recursiveMatch(route));
formatedRoutes = existingRoutes;
let routesObject = '{';
const recursiveTypedRoutes = (route, level) => {
const routeName = route.name;
if (route.children) {
const [parentName, parentName2] = route.path.split('/');
routesObject += `${lodash_1.camelCase(parentName || parentName2 || 'index')}:{`;
route.children.map((r) => recursiveTypedRoutes(r, level + 1));
routesObject += '},';
}
else if (routeName) {
let splitted = routeName.split('-');
splitted = splitted.slice(level, splitted.length);
routesObject += `'${lodash_1.camelCase(splitted.join('-')) || 'index'}': '${routeName}',`;
}
};
formatedRoutes.map((r) => recursiveTypedRoutes(r, 0));
routesObject += '}';
const template = `export const ${routesObjectName} = ${routesObject};`;
const templateForLocal = `export default ${routesObject};`;
try {
let prettierFoundOptions = await prettier.resolveConfig(process.cwd());
if (!prettierFoundOptions) {
prettierFoundOptions = require('../.prettierrc');
}
const formatedModelsFile = prettier.format(template, {
...prettierFoundOptions,
parser: 'typescript',
});
const savePath = path_1.default.resolve(process.cwd(), filePath);
await fs_1.default.writeFileSync(savePath, formatedModelsFile);
await fs_1.default.writeFileSync(path_1.default.resolve(__dirname, './generated.js'), templateForLocal);
console.log(log_symbols_1.default.success, `Route definition file generated at ${chalk_1.default.blue(savePath)}`);
this.addPlugin({
src: path_1.default.resolve(__dirname, './templates/nuxt-typed-router.js'),
});
}
} else {
defaultName = null;
}
parentsChildren.push({
path: '',
name: `${parent.name}-index`,
redirect: {
...(defaultName && { name: defaultName }),
...(!defaultName && { path: route.path }),
},
});
}
}
if (route.children) {
route.children.forEach(child => recursiveMatch(child, route));
}
};
existingRoutes.map(route => recursiveMatch(route));
formatedRoutes = existingRoutes;
// Typed router
let routesInterfaces = '{';
let routesEnum = [];
const recursiveTypedRoutes = (route, level) => {
const routeName = route.name;
if (route.children) {
const [parentName, parentName2] = route.path.split('/');
routesInterfaces += `${camelCase(parentName || parentName2 || 'index')}:{`;
route.children.map(r => recursiveTypedRoutes(r, level + 1));
routesInterfaces += '},';
} else if (routeName) {
let splitted = routeName.split('-');
splitted = splitted.slice(level, splitted.length);
routesInterfaces += `'${camelCase(splitted.join('-')) || 'index'}': '${routeName}',`;
routesEnum.push(`'${route.name}'`);
}
};
formatedRoutes.map(r => recursiveTypedRoutes(r, 0));
routesInterfaces += '}';
const template = `
export const ${options.routesObjectName || 'routerPagesNames'} = ${routesInterfaces};`;
const routesEnumsTemplate = `export type RouteNames = ${routesEnum.join('|')};`;
try {
if (options.filePath) {
let prettierFoundOptions = await prettier.resolveConfig(process.cwd());
if (!prettierFoundOptions) {
prettierFoundOptions = require('../.prettierrc');
}
const formatedModelsFile = prettier.format(template, {
...prettierFoundOptions,
parser: 'typescript',
catch (e) {
console.error(chalk_1.default.red('Error while saving route definitions file'), '\n' + e);
}
return formatedRoutes;
});
const savePath = path.resolve(process.cwd(), options.filePath);
await fs.writeFileSync(savePath, formatedModelsFile);
console.log(
logSymbols.success,
`Route definition file generated at ${chalk.blue(savePath)}`
);
}
await fs.writeFileSync(
path.resolve(__dirname, '../types/__generated.ts'),
routesEnumsTemplate
);
} catch (e) {
console.error(chalk.red('Error while saving route definitions file'), '\n' + e);
}
return formatedRoutes;
});
} catch (e) {
console.error(chalk.red('Error while generating routes definitions model'), '\n' + e);
}
});
}
catch (e) {
console.error(chalk_1.default.red('Error while generating routes definitions model'), '\n' + e);
}
});
};
module.exports = typedRouterModule;
module.exports.meta = require('../package.json');

@@ -1,6 +0,9 @@

import Vue from 'vue';
export default (ctx, inject) => {
inject('typedRouter', ctx.app.router);
inject('typedRoute', ctx.route);
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const generated_js_1 = __importDefault(require("../generated.js"));
exports.default = (ctx, inject) => {
inject('$routeNames', generated_js_1.default);
};
{
"name": "nuxt-typed-router",
"version": "0.1.14",
"version": "0.2.0",
"description": "Provide autocompletion for pages route names generated by Nuxt router",

@@ -16,2 +16,7 @@ "main": "lib/module.js",

],
"scripts": {
"dev": "tsc -p ./tsconfig.json --pretty --watch",
"build": "tsc -p ./tsconfig.json --pretty",
"prepublish": "yarn build"
},
"publishConfig": {

@@ -30,5 +35,12 @@ "access": "public"

"log-symbols": "^4.0.0",
"prettier": "^2.1.2",
"prettier": "^2.2.0"
},
"devDependencies": {
"@nuxt/types": "^2.14.7",
"@types/lodash": "^4.14.165",
"@types/node": "^14.14.10",
"@types/prettier": "^2.1.5",
"typescript": "^4.1.2",
"vue-router": "^3.4.9"
}
}

@@ -5,3 +5,11 @@ # 🚦Typed Router Module

[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![npm downloads][npm-total-downloads-src]][npm-downloads-href]
<img src='https://img.shields.io/npm/l/simple-graphql-to-typescript.svg'>
[npm-version-src]: https://img.shields.io/npm/v/nuxt-typed-router.svg
[npm-version-href]: https://www.npmjs.com/package/nuxt-typed-router
[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-typed-router.svg
[npm-total-downloads-src]: https://img.shields.io/npm/dt/nuxt-typed-router.svg
[npm-downloads-href]: https://www.npmjs.com/package/nuxt-typed-router
> Provide a safe typed router to nuxt with auto-generated typed definitions for route names

@@ -58,5 +66,11 @@

filePath?: string;
// Name of the routesNames object (ex: "routesTree")
// Default: "routerPagesNames"
routesObjectName?: string;
// Strip `@` sign from declared routes (ex: `admin/@home.vue` will be accessed like this `routerPagesNames.admin.home`
// and the route name will be `admin-home` instead of `admin-@home`)
// Default: true
stripAtFromNames?: boolean;
};

@@ -69,2 +83,14 @@ ```

# For Typescript users
Add `nuxt-typed-router/types` to your `tsconfig.json` types
```js
{
"types": ["@nuxt/types", "nuxt-typed-router/types"],
}
```
# Javascript Users
## - `routerPagesNames` global object

@@ -134,10 +160,8 @@

You can just import it now
You can use it from the injected `$routeNames` option on your components
```javascript
import { routerPagesNames } from '~/models/__routes.js';
export default {
mounted() {
this.$router.push({ name: routerPagesNames.index.content });
this.$router.push({ name: this.$routeNames.index.content });
},

@@ -147,37 +171,14 @@ };

## - `$typedRouter`
Or you can just import it
A global `$typedRouter` method is added to the Nuxt context and is accessible in your components and context. It's an alias of Vue `$router`, but the typings are modified so the `name` options is typed with the routes names generated from the pages directory
```javascript
import { routerPagesNames } from '~/models/__routes.js';
### _Why not directly modifying the types of `$router` and `$route` ?_
That was the idea when I builded this module initially, but I got confronted with Typescript limitations for modifying already defined third-party lib typings.
If I wanted to modify vue-router types, i could have just written this:
```typescript
declare module 'vue-router/types' {
export interface Location {
name: 'login' | 'home';
}
}
export default {
mounted() {
this.$router.push({ name: routerPagesNames.index.content });
},
};
```
Unfortunately that's not possible, Typescript throws this errors:
- `Subsequent property declarations must have the same type. Property 'name' must be of type 'string', but here has type '"login" | "home"`
- `All declarations of 'name' must have identical modifiers`
So the only way for now is to have an alternative `$typedRouter`, or a global enum-like object.
### _Requirements_
For your IDE to augment the Vue types, you need to explicitly import the module in your Nuxt config
```javascript
// nuxt.config.js
import 'nuxt-typed-router';
```
### _Usage_

@@ -184,0 +185,0 @@

@@ -1,45 +0,2 @@

import Vue from 'vue';
import * as TypedRouter from './vue';
export default TypedRouter;
interface NuxtTypedRouterOptions {
filePath?: string;
routesObjectName?: string;
}
declare module '@nuxt/vue-app' {
interface Context {
$typedRouter: TypedRouter.TypedVueRouter;
}
interface NuxtAppOptions {
$typedRouter: TypedRouter.TypedVueRouter;
}
interface Configuration {
typedRouter?: NuxtTypedRouterOptions;
}
}
// Nuxt 2.9+
declare module '@nuxt/types' {
interface Configuration {
typedRouter?: NuxtTypedRouterOptions;
}
interface Context {
$typedRouter: TypedRouter.TypedVueRouter;
}
interface NuxtAppOptions {
$typedRouter: TypedRouter.TypedVueRouter;
}
}
declare module 'vue/types/vue' {
interface Vue {
$typedRouter: TypedRouter.TypedVueRouter;
$typedRoute: TypedRouter.TypedRoute;
}
}
declare module 'vuex/types/index' {
interface Store<S> {
$typedRouter: TypedRouter.TypedVueRouter;
}
}
export { NuxtTypedRouterOptions } from './types';
//# sourceMappingURL=index.d.ts.map

@@ -1,42 +0,7 @@

import VueRouter, { Location, Route, RouteRecord } from 'vue-router';
import { RouteNames } from './__generated';
import { ErrorHandler } from 'vue-router/types/router';
import Vue, { AsyncComponent, ComponentOptions } from 'vue';
export { RouteNames };
export interface NuxtTypedRouterOptions {
filePath?: string;
import pagesNamesModel from './generated.ts';
declare module 'vue/types/vue' {
interface Vue {
$routesNames: typeof pagesNamesModel;
}
}
export type Component = ComponentOptions<Vue> | typeof Vue | AsyncComponent;
export interface TypedVueRouter extends VueRouter {
push(location: TypedRawLocation): Promise<TypedRoute>;
replace(location: TypedRawLocation): Promise<TypedRoute>;
push(location: TypedRawLocation, onComplete?: Function, onAbort?: ErrorHandler): void;
replace(location: TypedRawLocation, onComplete?: Function, onAbort?: ErrorHandler): void;
getMatchedComponents(to?: TypedRawLocation | TypedRoute): Component[];
resolve(
to: TypedRawLocation,
current?: TypedRoute,
append?: boolean
): {
location: TypedLocation;
route: TypedRoute;
href: string;
normalizedTo: TypedLocation;
resolved: TypedRoute;
};
}
export type TypedRawLocation = string | TypedLocation;
export interface TypedLocation extends Location {
name?: RouteNames;
}
export interface TypedRoute extends Route {
name?: RouteNames;
}
export interface TypedRouteRecord extends RouteRecord {
name?: RouteNames;
}
//# sourceMappingURL=vue.d.ts.map
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc