{"_id":"@anthwal/nestjs-url-generator","_rev":"5-c9276304873302d12671c6ca9ef11f3b","name":"@anthwal/nestjs-url-generator","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.1":{"name":"@anthwal/nestjs-url-generator","version":"1.0.1","keywords":["nestjs","nest","generate-url","signed-url","sign-url"],"author":{"name":"Arun Anthwal"},"license":"MIT","_id":"@anthwal/nestjs-url-generator@1.0.1","maintainers":[{"name":"anthwal","email":"anthwalarun003@gmail.com"}],"homepage":"https://github.com/anthwal/nestjs-url-generator#readme","bugs":{"url":"https://github.com/anthwal/nestjs-url-generator/issues"},"dist":{"shasum":"2bbdd69f470125416b0e83ba24b4c4b28ff7742a","tarball":"https://registry.npmjs.org/@anthwal/nestjs-url-generator/-/nestjs-url-generator-1.0.1.tgz","fileCount":44,"integrity":"sha512-piHbKKhJp2YHuEmk4PvyW3ZGJuBc918D7NTT3cf0iEECeGrIt7DMQbAYhqANwdfujoBscZ6IcU6oYbeUaYXRbg==","signatures":[{"sig":"MEUCIDyRLzWLtOkO4Upm/f9fi5TWzzPIuJQ0cXkqnh9LVPH3AiEAuP5iiU+G9Rf/Wrn4G5GCvO7P1OYsdZIzv34eD2o2WE0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":57561},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"9cbdae0edc71d915fa5bc7933594f2ead3b0a12c","scripts":{"lint":"eslint \"{lib,apps,libs,test}/**/*.ts\" --fix","test":"jest","build":"tsc -p tsconfig.json","format":"prettier --write \"lib/**/*.ts\" \"test/**/*.ts\"","update":"npx npm-check-updates -u && cd sample && npx npm-check-updates -u","prebuild":"rimraf dist","postbuild":"cd sample && npm install $(npm pack ../ | tail -1)"},"_npmUser":{"name":"anthwal","email":"anthwalarun003@gmail.com"},"repository":{"url":"git+https://github.com/anthwal/nestjs-url-generator.git","type":"git"},"_npmVersion":"10.8.2","description":"NestJs library for generating & signing url","directories":{"lib":"lib"},"_nodeVersion":"20.14.0","dependencies":{"qs":"^6.11.0"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.1","eslint":"^8.28.0","rimraf":"^3.0.2","prettier":"^2.8.0","@types/qs":"^6.9.7","typescript":"^5.6.3","@types/node":"^20.17.5","@nestjs/core":"^10.4.6","@nestjs/common":"^10.4.6","@types/express":"^5.0.0","reflect-metadata":"^0.1.13","eslint-config-prettier":"^8.5.0","@typescript-eslint/parser":"^5.44.0","@typescript-eslint/eslint-plugin":"^5.44.0"},"peerDependencies":{"@nestjs/core":"^9.2.0 || ^10.0.0","@nestjs/common":"^9.2.0 || ^10.0.0","reflect-metadata":"^0.1.13"},"_npmOperationalInternal":{"tmp":"tmp/nestjs-url-generator_1.0.1_1730551690571_0.40698096924322","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"@anthwal/nestjs-url-generator","version":"2.0.0","description":"NestJs library for generating & signing url","keywords":["nestjs","nest","generate-url","signed-url","sign-url"],"main":"dist/index.js","types":"dist/index.d.ts","directories":{"lib":"lib"},"scripts":{"prebuild":"rimraf dist","build":"tsc -p tsconfig.json","postbuild":"cd sample && npm install $(npm pack ../ | tail -1)","update":"npx npm-check-updates -u && cd sample && npx npm-check-updates -u","format":"prettier --write \"lib/**/*.ts\" \"test/**/*.ts\"","lint":"eslint \"{lib,apps,libs,test}/**/*.ts\" --fix","test":"jest"},"repository":{"type":"git","url":"git+https://github.com/anthwal/nestjs-url-generator.git"},"author":{"name":"Arun Anthwal"},"license":"MIT","bugs":{"url":"https://github.com/anthwal/nestjs-url-generator/issues"},"homepage":"https://github.com/anthwal/nestjs-url-generator#readme","devDependencies":{"@nestjs/common":"^11.1.17","@nestjs/core":"^11.1.17","@types/express":"^5.0.6","@types/node":"^24.0.0","@types/qs":"^6.15.0","eslint":"^9.39.2","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5","globals":"^17.2.0","prettier":"^3.8.1","reflect-metadata":"^0.2.2","rimraf":"^6.1.2","rxjs":"^7.8.2","typescript":"^5.9.3","typescript-eslint":"^8.54.0"},"peerDependencies":{"@nestjs/common":"^11.0.0","@nestjs/core":"^11.0.0","reflect-metadata":"^0.2.2"},"dependencies":{"qs":"^6.15.0"},"gitHead":"0383697550082b914be6e8251515ea917c06b6ac","_id":"@anthwal/nestjs-url-generator@2.0.0","_nodeVersion":"24.12.0","_npmVersion":"11.12.0","dist":{"integrity":"sha512-260TqDXgJiJV0Y8VYTLqWZG5bkwZrZ2P9GphLJEVLxgQV0IVISar1LXw82WDy6g+qP5k5VyxTlz7yn4SXNP2Og==","shasum":"0d81e0cbfef9efdfe4263899905e78936ad0aa2a","tarball":"https://registry.npmjs.org/@anthwal/nestjs-url-generator/-/nestjs-url-generator-2.0.0.tgz","fileCount":44,"unpackedSize":57686,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD3+POUyeWHvcOVSVRjj1xESTWsb+WN5xYAQKWbVoNCVgIgUWCUmXh3wKUO0rk09Jrw1NWmFReop7iMYo9JVe3/As0="}]},"_npmUser":{"name":"anthwal","email":"anthwalarun003@gmail.com"},"maintainers":[{"name":"anthwal","email":"anthwalarun003@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nestjs-url-generator_2.0.0_1774258234708_0.3244217437406933"},"_hasShrinkwrap":false}},"time":{"created":"2024-11-02T12:48:10.480Z","modified":"2026-03-23T09:30:34.970Z","1.0.0":"2024-11-01T15:19:56.609Z","1.0.1":"2024-11-02T12:48:10.782Z","2.0.0":"2026-03-23T09:30:34.850Z"},"bugs":{"url":"https://github.com/anthwal/nestjs-url-generator/issues"},"author":{"name":"Arun Anthwal"},"license":"MIT","homepage":"https://github.com/anthwal/nestjs-url-generator#readme","keywords":["nestjs","nest","generate-url","signed-url","sign-url"],"repository":{"type":"git","url":"git+https://github.com/anthwal/nestjs-url-generator.git"},"description":"NestJs library for generating & signing url","maintainers":[{"name":"anthwal","email":"anthwalarun003@gmail.com"}],"readme":"<p align=\"center\">\n  <img width=\"40%\" src=\"https://user-images.githubusercontent.com/17086745/97110220-8bf2f780-170a-11eb-9bf4-ca38b8d41be9.png\" />\n</p>\n\n<h2 align=\"center\">NestJS module for generating & signing URL</h2>\n\n<p align=\"center\">\n    <a href=\"https://www.codefactor.io/repository/github/anthwal/nestjs-url-generator\">\n        <img src=\"https://www.codefactor.io/repository/github/anthwal/nestjs-url-generator/badge\" alt=\"CodeFactor\" />\n    </a>\n    <a href=\"https://www.npmjs.com/package/@anthwal/nestjs-url-generator\">\n        <img src=\"https://img.shields.io/npm/v/@anthwal/nestjs-url-generator.svg?style=flat-square&sanitize=true\" alt=\"NPM Version\" />\n    </a>\n    <a href=\"https://www.npmjs.com/package/@anthwal/nestjs-url-generator\">\n        <img src=\"https://img.shields.io/npm/dm/@anthwal/nestjs-url-generator.svg?style=flat-square&sanitize=true\" alt=\"NPM Downloads\" />\n    </a>\n    <a href=\"#\">\n        <img src=\"https://img.shields.io/npm/l/@anthwal/nestjs-url-generator.svg?colorB=black&label=LICENSE&style=flat-square&sanitize=true\" alt=\"License\"/>\n    </a>\n</p>\n\n# Description\n\nURL Generation is used to dynamically generate URL that point to NestJS controller method (Route).\n\n@anthwal/nestjs-url-generator can generate plain and signed URLs\n\n# Installation\n\n```bash\nnpm i --save @anthwal/nestjs-url-generator\n```\n\nOr if you use Yarn:\n\n```bash\nyarn add @anthwal/nestjs-url-generator\n```\n\n# Requirements\n\n`@anthwal/nestjs-url-generator` is built to work with Nest 7 and newer versions.\n\n# Basic Usage\n\n### Include Module\n\nFirst you need to import [UrlGeneratorModule]:\n\n> app.module.ts\n\n```ts\nimport { UrlGeneratorModule } from '@anthwal/nestjs-url-generator';\n\n@Module({\n  imports: [\n    UrlGeneratorModule.forRoot({\n      secret: 'secret', // optional, required only for signed URL\n      appUrl: 'https://localhost:3000',\n    }),\n  ],\n})\nexport class ApplicationModule {}\n```\n\nOr Async Import With .ENV usage\n\n> .ENV\n\n```.env\nAPP_KEY=secret\nAPP_URL=https://localhost:3000\n```\n\n> signed-url.config.ts\n\n```ts\nimport { UrlGeneratorModuleOptions } from '@anthwal/nestjs-url-generator';\n\nexport function urlGeneratorModuleConfig(): UrlGeneratorModuleOptions {\n  return {\n    secret: process.env.APP_KEY,\n    appUrl: process.env.APP_URL,\n  };\n}\n```\n\n> app.module.ts\n\n```ts\nimport { UrlGeneratorModule } from '@anthwal/nestjs-url-generator';\n\n@Module({\n  imports: [\n    ConfigModule.forRoot(),\n    UrlGeneratorModule.forRootAsync({\n      useFactory: () => urlGeneratorModuleConfig(),\n    }),\n  ],\n})\nexport class ApplicationModule {}\n```\n\n## Using Service\n\nNow you need to register the service, by injecting it to the constructor.\nThere are two methods for generating url:\n\n```typescript\ngenerateUrlFromController({\n  controller,\n  controllerMethod,\n  /*?*/ query,\n  /*?*/ params,\n});\n\ngenerateUrlFromPath({\n  relativePath,\n  /*?*/ query,\n  /*?*/ params,\n});\n```\n\n> app.controller.ts\n\n```ts\nimport { UrlGeneratorService } from '@anthwal/nestjs-url-generator';\n\n@Controller()\nexport class AppController {\n  constructor(private readonly urlGeneratorService: UrlGeneratorService) {}\n\n  @Get('makeUrl')\n  async makeUrl(): Promise<string> {\n    const params = {\n      version: '1.0',\n      userId: 12,\n    };\n\n    const query = {\n      email: 'email@email',\n    };\n\n    // This will generate:\n    // https://localhost:3000/emailVerification/1.0/12?email=email%40email\n    return this.urlGeneratorService.generateUrlFromController({\n      controller: AppController,\n      controllerMethod: AppController.prototype.emailVerification,\n      query: query,\n      params: params,\n    });\n  }\n}\n```\n\n### Generate Signed URL\n\nThere are two methods for generating url:\n\n```typescript\nSignControllerUrl({\n  controller,\n  controllerMethod,\n  /*?*/ expirationDate,\n  /*?*/ query,\n  /*?*/ params,\n});\n\nSignUrl({\n  relativePath,\n  /*?*/ expirationDate,\n  /*?*/ query,\n  /*?*/ params,\n});\n```\n\n> app.controller.ts\n\n```ts\nimport { UrlGeneratorService } from '@anthwal/nestjs-url-generator';\n\n@Controller()\nexport class AppController {\n  constructor(private readonly urlGeneratorService: UrlGeneratorService) {}\n\n  @Get('makeSignUrl')\n  async makeSignUrl(): Promise<string> {\n    // This will generate:\n    // https://localhost:3000/emailVerification?\n    // expirationDate=2021-12-12T00%3A00%3A00.000Z&\n    // signed=84b5a021c433d0ee961932ac0ec04d5dd5ffd6f7fdb60b46083cfe474dfae3c0\n    return this.urlGeneratorService.SignControllerUrl({\n      controller: AppController,\n      controllerMethod: AppController.prototype.emailVerification,\n      expirationDate: new Date('2021-12-12'),\n      // or using DateTime library of your choice\n      // will be expired 30 minutes after it was created\n      expirationDate: dayjs().add(30, 'minute').toDate(),\n    });\n  }\n}\n```\n\n- [expirationDate] and [signed] query keys are used for signed URL.\n\n- By default, the signed URLs lives forever.\n  You can add expiration date to them at the time of generating one.\n\n### Reminder\n\nThe difference between params & query in ExpressJS\n\n<img width=\"50%\" src=\"https://user-images.githubusercontent.com/17086745/97456127-22bdef00-196b-11eb-89d2-d64d4324498d.png\" />\n<br>\n\n## Using Guard\n\nYou can use SignUrlGuard to verify the signed url in controller.\n\nIf the url has been tampered or when the expiration date is due, then a Forbidden exception will be thrown.\n\n> app.controller.ts\n\n```ts\nimport { SignedUrlGuard } from '@anthwal/nestjs-url-generator';\n\n@Controller()\nexport class AppController {\n  constructor(private readonly urlGeneratorService: UrlGeneratorService) {}\n\n  @Get('emailVerification')\n  @UseGuards(SignedUrlGuard)\n  async emailVerification(): Promise<string> {\n    return 'You emailed has been verified.';\n  }\n}\n```\n\n## Note\n\n- Changing the secret key will invalidate all signed urls\n- Signed URL is typically used for unsubscribe email, email verification, sign file permission, and more.\n\n- If you are using https with reverse proxy please make sure to enable trust proxy in express\n\n```typescript\nconst app = await NestFactory.create<NestExpressApplication>(AppModule);\n\napp.set('trust proxy', true);\n// or\nexpressSession({ proxy: true });\n```\n\n## Generating Keys using node REPL\n\n```javascript\nrequire('crypto').randomBytes(64, (err, buf) => {\n  if (err) throw err;\n  console.log(`${buf.length} bytes of random data: ${buf.toString('base64')}`);\n  process.exit();\n});\n```\n\n### TODO\n\n- [ ] Create unit test (expiration, tampered, with or without globalPrefix, request with or without query & param, if target for signerUrl doesn't have guard)\n\n- [ ] Automate CI, npm run build, push, npm publish\n","readmeFilename":"README.md"}