{"id":31262748,"url":"https://github.com/aceiny/nestjs-nominatim","last_synced_at":"2025-09-23T11:53:30.213Z","repository":{"id":312620722,"uuid":"1048027862","full_name":"aceiny/nestjs-nominatim","owner":"aceiny","description":"an open source nestjs library to communicate with the nominatim location and geolocation api (or self hosted) ","archived":false,"fork":false,"pushed_at":"2025-09-16T16:57:39.000Z","size":163,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T19:33:44.647Z","etag":null,"topics":["geocoding-api","lookup","nestjs","nominatim","npm","reverse"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/nestjs-nominatim","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aceiny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-31T18:53:24.000Z","updated_at":"2025-09-16T16:57:42.000Z","dependencies_parsed_at":"2025-09-01T00:33:25.308Z","dependency_job_id":"ae95538e-8aa5-4b89-88d3-6f8e38085a8e","html_url":"https://github.com/aceiny/nestjs-nominatim","commit_stats":null,"previous_names":["aceiny/nestjs-nominatim"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aceiny/nestjs-nominatim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aceiny%2Fnestjs-nominatim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aceiny%2Fnestjs-nominatim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aceiny%2Fnestjs-nominatim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aceiny%2Fnestjs-nominatim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aceiny","download_url":"https://codeload.github.com/aceiny/nestjs-nominatim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aceiny%2Fnestjs-nominatim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276570675,"owners_count":25665900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-23T02:00:09.130Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["geocoding-api","lookup","nestjs","nominatim","npm","reverse"],"created_at":"2025-09-23T11:53:28.462Z","updated_at":"2025-09-23T11:53:30.207Z","avatar_url":"https://github.com/aceiny.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Nominatim\n\n[![npm version](https://badge.fury.io/js/nestjs-nominatim.svg)](https://badge.fury.io/js/nestjs-nominatim)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA powerful and easy-to-use NestJS library for integrating with the Nominatim API (OpenStreetMap geocoding service). This library provides a clean, type-safe interface for performing geocoding, reverse geocoding, and place lookups.\n\n## 🚀 Features\n\n- **🔍 Forward Geocoding**: Search for places by name or address\n- **📍 Reverse Geocoding**: Get address information from coordinates\n- **🔎 Place Lookup**: Retrieve detailed information by OSM ID\n- **💪 TypeScript Support**: Fully typed with comprehensive interfaces\n- **⚙️ Configurable**: Flexible configuration options\n- **🏥 Health Checks**: Built-in API health monitoring\n- **🌐 Language Support**: Multi-language address formatting\n- **🔧 NestJS Integration**: Native NestJS module with dependency injection\n- **📍 Address Formatting**: Convert raw place data into structured address components\n- **⚡ Caching Support**: Built-in configurable caching for improved performance\n\n## 📦 Installation\n\n```bash\nnpm install nestjs-nominatim\n```\n\n### Peer Dependencies\n\nMake sure you have the following peer dependencies installed:\n\n```bash\nnpm install @nestjs/common @nestjs/core @nestjs/axios axios @nestjs/cache-manager cache-manager\n```\n\n## 🛠️ Quick Start\n\n### 1. Import the Module\n\n```typescript\nimport { Module } from \"@nestjs/common\";\nimport { NominatimModule } from \"nestjs-nominatim\";\n\n@Module({\n  imports: [\n    NominatimModule.forRoot({\n      baseUrl: \"https://nominatim.openstreetmap.org\",\n      language: \"en\",\n      userAgent: \"YourApp/1.0\",\n      timeout: 5000,\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### 1.1. With Caching (Recommended)\n\nFor better performance, integrate with NestJS cache manager:\n\n```typescript\nimport { Module } from \"@nestjs/common\";\nimport { NominatimModule } from \"nestjs-nominatim\";\n\n@Module({\n  imports: [\n    NominatimModule.forRoot({\n      baseUrl: \"https://nominatim.openstreetmap.org\",\n      language: \"en\",\n      userAgent: \"YourApp/1.0\",\n      timeout: 5000,\n      addressdetails: true, // Recommended for better caching efficiency\n      cache: {\n        ttl: 3600000, // 1 hour cache (in milliseconds)\n        max: 1000, // maximum number of items in cache\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### 2. Use the Service\n\n```typescript\nimport { Injectable } from \"@nestjs/common\";\nimport { NominatimService } from \"nestjs-nominatim\";\n\n@Injectable()\nexport class LocationService {\n  constructor(private readonly nominatimService: NominatimService) {}\n\n  async searchPlace(query: string) {\n    return await this.nominatimService.search(query);\n  }\n\n  async reverseGeocode(lat: number, lon: number) {\n    return await this.nominatimService.reverse({ lat, lon });\n  }\n}\n```\n\n## 📚 API Reference\n\n### Configuration Options\n\n| Option           | Type                 | Default                               | Description                        |\n| ---------------- | -------------------- | ------------------------------------- | ---------------------------------- |\n| `baseUrl`        | `string`             | `https://nominatim.openstreetmap.org` | Nominatim API base URL             |\n| `language`       | `string`             | `en`                                  | Preferred language for results     |\n| `addressdetails` | `boolean`            | `false`                               | Include detailed address breakdown |\n| `timeout`        | `number`             | `5000`                                | Request timeout in milliseconds    |\n| `userAgent`      | `string`             | `nestjs-nominatim`                    | User agent string                  |\n| `extratags`      | `boolean`            | `false`                               | Include extra OSM tags             |\n| `namedetails`    | `boolean`            | `false`                               | Include name details               |\n| `cache`          | `CacheModuleOptions` | `CashConfig`                          | Cache configuration options        |\n\n### Service Methods\n\n#### `search(query: string): Promise\u003cNominatimSearchResults\u003e`\n\nSearch for places by name or address.\n\n```typescript\nconst results = await nominatimService.search(\"Paris, France\");\nconsole.log(results[0].display_name); // \"Paris, Île-de-France, France\"\n```\n\n#### `reverse(coordinates: Coordinates): Promise\u003cNominatimPlace\u003e`\n\nPerform reverse geocoding from coordinates.\n\n```typescript\nconst place = await nominatimService.reverse({\n  lat: 48.8566,\n  lon: 2.3522,\n});\nconsole.log(place.display_name); // Address at the coordinates\n```\n\n#### `lookup(osmIds: string[]): Promise\u003cNominatimPlace[]\u003e`\n\nLook up places by OpenStreetMap IDs.\n\n```typescript\nconst places = await nominatimService.lookup([\"R146656\", \"W104393803\"]);\nconsole.log(places[0].display_name);\n```\n\n#### `healthCheck(): Promise\u003cHealthCheck\u003e`\n\nCheck the health status of the Nominatim API.\n\n```typescript\nconst health = await nominatimService.healthCheck();\nconsole.log(health.message, health.status); // 'OK' , 0\n```\n\n#### `formatLocation(place: NominatimPlace): FormattedAddress`\n\nFormat a place result into a structured address with standardized components.\n\n```typescript\nconst place = await nominatimService.reverse({\n  lat: 48.8566,\n  lon: 2.3522,\n});\nconst formatted = nominatimService.formatLocation(place);\n\nconsole.log(formatted.country); // \"France\"\nconsole.log(formatted.commune); // \"Paris\"\nconsole.log(formatted.street); // \"Rue de Rivoli\"\nconsole.log(formatted.postcode); // \"75001\"\nconsole.log(formatted.fullAddress); // Complete formatted address\n```\n\n## 🏗️ Advanced Usage\n\n### Caching Configuration\n\nThe library includes built-in caching support to improve performance and reduce API calls. Caching is automatically applied to all search, reverse geocoding, and lookup operations when configured.\n\n#### Basic Caching Setup\n\n```typescript\nimport { Module } from \"@nestjs/common\";\nimport { NominatimModule } from \"nestjs-nominatim\";\n\n@Module({\n  imports: [\n    NominatimModule.forRoot({\n      baseUrl: \"https://nominatim.openstreetmap.org\",\n      language: \"en\",\n      userAgent: \"YourApp/1.0\",\n      cache: {\n        ttl: 3600000, // Cache for 1 hour (in milliseconds)\n        max: 1000, // Store up to 1000 cached responses\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n#### Advanced Caching with Redis\n\n```typescript\nimport { Module } from \"@nestjs/common\";\nimport { NominatimModule } from \"nestjs-nominatim\";\nimport { redisStore } from \"cache-manager-redis-store\";\n\n@Module({\n  imports: [\n    NominatimModule.forRoot({\n      baseUrl: \"https://nominatim.openstreetmap.org\",\n      language: \"en\",\n      userAgent: \"YourApp/1.0\",\n      cache: {\n        store: redisStore,\n        host: \"localhost\",\n        port: 6379,\n        ttl: 3600000, // 1 hour in milliseconds\n        max: 10000,\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n#### Default Cache Configuration\n\nIf no cache configuration is provided, the library uses these defaults:\n\n```typescript\n{\n  ttl: 86400000,        // 1 day (in milliseconds)\n  namespace: \"nominatim\", // Cache key prefix\n  refreshThreshold: 60000, // Refresh if \u003c 1 min left\n  nonBlocking: false,    // Block until store writes are done\n}\n```\n\n#### Cache Keys\n\nThe library uses structured cache keys for different operations:\n\n- Search: `search:{query}`\n- Reverse: `reverse:{lat}:{lon}`\n- Lookup: `lookup:{osmId1},{osmId2},...`\n\n#### Performance Benefits\n\nWith caching enabled, you can expect:\n\n- **Faster Response Times**: Subsequent identical requests return instantly from cache\n- **Reduced API Load**: Fewer requests to the Nominatim API\n- **Cost Savings**: Lower bandwidth usage and API rate limit consumption\n- **Better User Experience**: Instant results for repeated searches\n\nExample performance improvement:\n\n```typescript\n// First call - hits the API (slower)\nconst result1 = await nominatimService.search(\"Paris, France\"); // ~200-500ms\n\n// Second call - served from cache (faster)\nconst result2 = await nominatimService.search(\"Paris, France\"); // ~1-5ms\n```\n\n### Custom Configuration\n\n```typescript\n@Module({\n  imports: [\n    NominatimModule.forRoot({\n      baseUrl: \"https://your-nominatim-instance.com\",\n      language: \"fr\",\n      addressdetails: true,\n      extratags: true,\n      namedetails: true,\n      userAgent: \"MyGeocodingApp/2.0 (contact@example.com)\",\n      timeout: 10000,\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### Error Handling\n\n```typescript\n@Injectable()\nexport class LocationService {\n  constructor(private readonly nominatimService: NominatimService) {}\n\n  async safeSearch(query: string) {\n    try {\n      const results = await this.nominatimService.search(query);\n      return { success: true, data: results };\n    } catch (error) {\n      console.error(\"Geocoding failed:\", error.message);\n      return { success: false, error: error.message };\n    }\n  }\n}\n```\n\n### Health Monitoring\n\n```typescript\n@Injectable()\nexport class HealthService {\n  constructor(private readonly nominatimService: NominatimService) {}\n\n  @Get(\"/health/nominatim\")\n  async checkNominatimHealth() {\n    const health = await this.nominatimService.healthCheck();\n    if (health.messasge === \"OK\" || health.status = 0) {\n      throw new ServiceUnavailableException(\"Nominatim API is unavailable\");\n    }\n    return health;\n  }\n}\n```\n\n## 🌍 Language Support\n\nThe library supports multiple languages for address formatting:\n\n```typescript\n// French addresses\nNominatimModule.forRoot({ language: \"fr\" });\n\n// German addresses\nNominatimModule.forRoot({ language: \"de\" });\n\n// Spanish addresses\nNominatimModule.forRoot({ language: \"es\" });\n```\n\n## 📝 Type Definitions\n\nThe library includes comprehensive TypeScript definitions:\n\n- `NominatimSearchResults`: Array of search results\n- `NominatimPlace`: Detailed place information\n- `Coordinates`: Latitude/longitude coordinates\n- `FormattedAddress`: Structured address components\n- `HealthCheck`: API health status\n- `NominatimModuleOptions`: Configuration options\n\n## 🧪 Testing\n\nTo run the included tests:\n\n```bash\nnpm test\n```\n\nThe test suite includes examples of all major functionality and can serve as additional documentation.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## 🐛 Issues\n\nIf you encounter any issues or have feature requests, please [create an issue](https://github.com/aceiny/nestjs-nominatim/issues) on GitHub.\n\n## 📞 Support\n\nFor support and questions, please:\n\n- Check the documentation above\n- Look at the [test examples](src/test.ts)\n- Create an issue on GitHub\n\n## 🙏 Acknowledgments\n\n- [OpenStreetMap](https://www.openstreetmap.org/) for providing the Nominatim service\n- [NestJS](https://nestjs.com/) for the amazing framework\n- All contributors to this project\n\n## Author\n\n```\nahmed yassine zeraibi (aceiny.dev@gmail.com)\n```\n\n**Made with ❤️ for the NestJS community**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faceiny%2Fnestjs-nominatim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faceiny%2Fnestjs-nominatim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faceiny%2Fnestjs-nominatim/lists"}