{"id":22982372,"url":"https://github.com/niradler/tracking-number-validation","last_synced_at":"2025-10-23T15:55:36.973Z","repository":{"id":29623608,"uuid":"121382266","full_name":"niradler/tracking-number-validation","owner":"niradler","description":"A simple way to validate tracking number for the following couriers.","archived":false,"fork":false,"pushed_at":"2025-09-23T12:39:34.000Z","size":288,"stargazers_count":33,"open_issues_count":3,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-20T14:41:18.785Z","etag":null,"topics":["fedex","javascript","nodejs","nodejs-modules","tracking-number","ups","usps"],"latest_commit_sha":null,"homepage":"https://niradler.github.io/tracking-number-validation/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/niradler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-02-13T12:52:55.000Z","updated_at":"2025-10-14T02:29:42.000Z","dependencies_parsed_at":"2023-12-23T17:16:29.492Z","dependency_job_id":null,"html_url":"https://github.com/niradler/tracking-number-validation","commit_stats":{"total_commits":43,"total_committers":3,"mean_commits":"14.333333333333334","dds":"0.34883720930232553","last_synced_commit":"79ff9b440a1f6417fdd241e29be0b619c48a623a"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/niradler/tracking-number-validation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niradler%2Ftracking-number-validation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niradler%2Ftracking-number-validation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niradler%2Ftracking-number-validation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niradler%2Ftracking-number-validation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/niradler","download_url":"https://codeload.github.com/niradler/tracking-number-validation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niradler%2Ftracking-number-validation/sbom","scorecard":{"id":688769,"data":{"date":"2025-08-11","repo":{"name":"github.com/niradler/tracking-number-validation","commit":"79ff9b440a1f6417fdd241e29be0b619c48a623a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.4,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.js.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.js.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/niradler/tracking-number-validation/build.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.js.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/niradler/tracking-number-validation/build.js.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"59 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-f9cm-qmx5-m98h","Warn: Project is vulnerable to: GHSA-7wpw-2hjm-89gp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T01:44:38.673Z","repository_id":29623608,"created_at":"2025-08-22T01:44:38.673Z","updated_at":"2025-08-22T01:44:38.673Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280647981,"owners_count":26366641,"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-10-23T02:00:06.710Z","response_time":142,"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":["fedex","javascript","nodejs","nodejs-modules","tracking-number","ups","usps"],"created_at":"2024-12-15T02:18:10.380Z","updated_at":"2025-10-23T15:55:36.968Z","avatar_url":"https://github.com/niradler.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tracking-number-validation\n\nA modern TypeScript library for validating tracking numbers from multiple shipping carriers.\n\n## 🚀 Features\n\n- **TypeScript First**: Full TypeScript support with comprehensive type definitions\n- **Modern ESM**: ES modules with CommonJS compatibility\n- **Zero Dependencies**: Lightweight with no external dependencies\n- **Comprehensive Testing**: Full test coverage with Jest\n- **Multiple Carriers**: Support for 11+ shipping carriers\n\n## 📦 Supported Carriers\n\n- **UPS** - United Parcel Service\n- **USPS** - United States Postal Service (including barcodes starting with 95)\n- **FedEx** - Federal Express\n- **DHL** - DHL Express\n- **OnTrac** - OnTrac Shipping\n- **Amazon** - Amazon Logistics\n- **LaserShip** - LaserShip Delivery\n- **Canada Post** - Canada Post Corporation\n- **China Post** - China Post Corporation\n- **Australia Post** - Australia Post Corporation\n- **Royal Mail** - Royal Mail Group\n\n## 🛠 Installation\n\n```bash\n# Using pnpm (recommended)\npnpm add tracking-number-validation\n\n# Using npm\nnpm install tracking-number-validation\n\n# Using yarn\nyarn add tracking-number-validation\n```\n\n## 📖 Usage\n\n### TypeScript/ES Modules\n\n```typescript\nimport { \n  getCourier, \n  getCourierOne, \n  isValid, \n  isCourier, \n  getTrackingUrl,\n  getAllPossibleCouriers,\n  getValidCouriersOnly,\n  getAllTrackingUrlsForNumber,\n  getDetailedCourierInfo,\n  generateTrackingNumber,\n  generateMultipleTrackingNumbers,\n  type CourierName \n} from 'tracking-number-validation';\n\n// Get all matching couriers for a tracking number\nconst couriers = getCourier('1Z9999W99999999999');\nconsole.log(couriers); // ['ups']\n\n// Get the first matching courier\nconst courier = getCourierOne('1Z9999W99999999999');\nconsole.log(courier); // 'ups'\n\n// Check if tracking number is valid\nconst isValidNumber = isValid('1Z9999W99999999999');\nconsole.log(isValidNumber); // true\n\n// Check if tracking number belongs to specific courier\nconst isUPS = isCourier('1Z9999W99999999999', 'ups');\nconsole.log(isUPS); // true\n\n// Get tracking URL\nconst trackingUrl = getTrackingUrl('1Z9999W99999999999', 'ups');\nconsole.log(trackingUrl); // 'https://www.ups.com/track?trackingNumber=1Z9999W99999999999'\n\n// Auto-detect courier and get URL\nconst autoUrl = getTrackingUrl('1Z9999W99999999999');\nconsole.log(autoUrl); // 'https://www.ups.com/track?trackingNumber=1Z9999W99999999999'\n\n// Get all possible couriers (including pattern matches that may not validate)\nconst allPossible = getAllPossibleCouriers('1Z9999W99999999999');\nconsole.log(allPossible); // ['ups']\n\n// Get only validated couriers\nconst validOnly = getValidCouriersOnly('1Z9999W99999999999');\nconsole.log(validOnly); // ['ups']\n\n// Get detailed validation info\nconst detailedInfo = getDetailedCourierInfo('1Z9999W99999999999');\nconsole.log(detailedInfo); // [{ courier: 'ups', valid: true, tracking_url: '...' }]\n\n// Generate tracking numbers\nconst generatedUPS = generateTrackingNumber('ups');\nconsole.log(generatedUPS); // '1Z12345E1512345676'\n\n// Generate multiple tracking numbers\nconst multipleUSPS = generateMultipleTrackingNumbers('usps', 3);\nconsole.log(multipleUSPS); // ['9400100000000000000000', '9400100000000000000001', ...]\n```\n\n### CommonJS\n\n```javascript\nconst { \n  getCourier, \n  isValid, \n  getTrackingUrl,\n  generateTrackingNumber,\n  CourierName \n} = require('tracking-number-validation');\n\nconst courier = getCourier('9400100000000000000000');\nconsole.log(courier); // ['usps']\n```\n\n### Browser (Global)\n\n```html\n\u003cscript src=\"https://unpkg.com/tracking-number-validation@3.0.0/dist/index.global.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const courier = TNV.getCourier('1Z9999W99999999999');\n  console.log(courier); // ['ups']\n\u003c/script\u003e\n```\n\n## 🔧 API Reference\n\n### `getCourier(trackingNumber: string): CourierName[]`\n\nReturns an array of courier names that match the tracking number pattern.\n\n```typescript\ngetCourier('1Z9999W99999999999'); // ['ups']\ngetCourier('invalid'); // []\n```\n\n### `getCourierOne(trackingNumber: string): CourierName | undefined`\n\nReturns the first matching courier name or `undefined` if no match.\n\n```typescript\ngetCourierOne('1Z9999W99999999999'); // 'ups'\ngetCourierOne('invalid'); // undefined\n```\n\n### `isValid(trackingNumber: string): boolean`\n\nChecks if the tracking number is valid for any supported courier.\n\n```typescript\nisValid('1Z9999W99999999999'); // true\nisValid('invalid'); // false\n```\n\n### `isCourier(trackingNumber: string, courier: CourierName): boolean`\n\nChecks if the tracking number belongs to a specific courier.\n\n```typescript\nisCourier('1Z9999W99999999999', 'ups'); // true\nisCourier('1Z9999W99999999999', 'fedex'); // false\n```\n\n### `getTrackingUrl(trackingNumber: string, courier?: CourierName): string | null`\n\nReturns the tracking URL for the given tracking number and courier.\n\n```typescript\ngetTrackingUrl('1Z9999W99999999999', 'ups'); \n// 'https://www.ups.com/track?trackingNumber=1Z9999W99999999999'\n\ngetTrackingUrl('1Z9999W99999999999'); // Auto-detects UPS\n// 'https://www.ups.com/track?trackingNumber=1Z9999W99999999999'\n```\n\n### `injectPatterns(courier: CourierName, pattern: string | RegExp): boolean`\n\nAdds a custom pattern for an existing courier.\n\n```typescript\ninjectPatterns('ups', /CUSTOM\\d{10}/); // true\nisValid('CUSTOM1234567890'); // true (now matches UPS)\n```\n\n### `getAllPossibleCouriers(trackingNumber: string): string[]`\n\nReturns all couriers that match the tracking number pattern (including those that may not validate).\n\n```typescript\ngetAllPossibleCouriers('1Z9999W99999999999'); // ['ups']\ngetAllPossibleCouriers('invalid'); // []\n```\n\n### `getValidCouriersOnly(trackingNumber: string): string[]`\n\nReturns only the couriers that both match the pattern and validate the tracking number.\n\n```typescript\ngetValidCouriersOnly('1Z9999W99999999999'); // ['ups']\ngetValidCouriersOnly('invalid'); // []\n```\n\n### `getAllTrackingUrlsForNumber(trackingNumber: string): object[]`\n\nReturns tracking URLs for all matching couriers with validation information.\n\n```typescript\ngetAllTrackingUrlsForNumber('1Z9999W99999999999');\n// [{ courier: 'ups', url: 'https://...', valid: true }]\n```\n\n### `getDetailedCourierInfo(trackingNumber: string): ValidationResult[]`\n\nReturns comprehensive validation information for all matching couriers.\n\n```typescript\ngetDetailedCourierInfo('1Z9999W99999999999');\n// [{ courier: 'ups', valid: true, tracking_url: 'https://...' }]\n```\n\n### `generateTrackingNumber(courier: CourierName): string`\n\nGenerates a valid-format tracking number for the specified courier.\n\n```typescript\ngenerateTrackingNumber('ups'); // '1Z12345E1512345676'\ngenerateTrackingNumber('fedex'); // '999999999999'\n```\n\n### `generateMultipleTrackingNumbers(courier: CourierName, count: number): string[]`\n\nGenerates multiple tracking numbers for the specified courier.\n\n```typescript\ngenerateMultipleTrackingNumbers('usps', 3);\n// ['9400100000000000000000', '9400100000000000000001', '9400100000000000000002']\n```\n\n### `generateTrackingNumberWithValidation(config: GeneratorConfig): string`\n\nGenerates a tracking number and validates it against the library's own validation rules.\n\n```typescript\ngenerateTrackingNumberWithValidation({ courier: 'ups' });\n// '1Z12345E1512345676' (guaranteed to pass isValid())\n```\n\n## 📝 Tracking Number Examples\n\n### UPS\n- `1Z9999W99999999999`\n- `1Z12345E1512345676`\n- `T9999999999`\n\n### USPS\n- `9400 1000 0000 0000 0000 00`\n- `9205 5000 0000 0000 0000 00` \n- `9500 1000 0000 0000 0000 00` (95 prefix supported)\n- `EC 000 000 000 US`\n- `82 000 000 00`\n\n### FedEx\n- `9999 9999 9999`\n- `9999 9999 9999 999`\n- `999999999999`\n- `61299995669352455464`\n\n### DHL\n- `125-12345678`\n- `125 12345678`\n- `SEA1234567`\n\n### OnTrac\n- `C00000000000000`\n\n### Amazon\n- `TBA502887274000`\n\n### LaserShip\n- `1LS123456789012`\n\n### Canada Post\n- `RP123456789CA`\n- `1234567890123`\n\n### China Post\n- `EE123456789CN`\n- `RR123456789CN`\n- `CP123456789CN`\n\n### Australia Post\n- `AP123456789AU`\n- `123456789012`\n- `TM123456789012345`\n\n### Royal Mail\n- `GB123456789GB`\n- `RR123456789GB`\n\n## 🎲 Tracking Number Generation\n\nGenerate valid tracking numbers for testing purposes:\n\n```typescript\nimport { generateTrackingNumber, generateMultipleTrackingNumbers, CourierName } from 'tracking-number-validation';\n\n// Generate single tracking numbers\nconst upsNumber = generateTrackingNumber(CourierName.UPS);\nconst fedexNumber = generateTrackingNumber(CourierName.FEDEX);\nconst uspsNumber = generateTrackingNumber(CourierName.USPS);\n\n// Generate multiple tracking numbers\nconst multipleNumbers = generateMultipleTrackingNumbers(CourierName.UPS, 5);\nconsole.log(multipleNumbers); // ['1Z...', '1Z...', '1Z...', '1Z...', '1Z...']\n\n// Generate with specific formats (where supported)\nconst fedexGround = generateTrackingNumber({ \n  courier: CourierName.FEDEX, \n  format: 'ground' \n});\n\n// Available formats per courier\nimport { courierFormats } from 'tracking-number-validation';\nconsole.log(courierFormats[CourierName.FEDEX]); // ['express', 'ground', 'smartpost']\nconsole.log(courierFormats[CourierName.USPS]); // ['tracking', 's10', 'certified']\n```\n\n### Supported Generation Formats\n\n- **FedEx**: `express` (12 digits), `ground` (15 digits), `smartpost` (22 digits)\n- **USPS**: `tracking` (22 digits), `s10` (13 chars), `certified` (20 digits)\n- **DHL**: `express` (10 digits), `ecommerce` (10 chars), `global` (18 chars)\n- **Australia Post**: `s10`, `domestic`, `tm`\n- **Canada Post**: `s10`, `domestic`\n- **UPS, Amazon, OnTrac, LaserShip, China Post, Royal Mail**: Default formats only\n\n## 🆕 What's New in v3.0.0\n\n### ✨ Major Updates\n- **Full TypeScript rewrite** with comprehensive type definitions\n- **Modern ESM support** with CommonJS compatibility\n- **Updated UPS tracking URLs** (removed deprecated `/mobile/` path)\n- **Enhanced USPS support** for barcodes starting with 95\n- **New carriers added**: LaserShip, Canada Post, China Post, Australia Post, and Royal Mail\n- **Tracking number generation**: Generate valid tracking numbers for testing\n- **Advanced validation functions**: Get detailed courier information and validation results\n\n### 🔧 Breaking Changes\n- Minimum Node.js version: 16+\n- Full TypeScript types required\n- ES modules by default\n- Updated build system using `tsup`\n\n### 🛠 Development Improvements\n- Modern Jest testing with TypeScript\n- ESLint configuration for TypeScript\n- Comprehensive test coverage\n- Updated documentation and examples\n\n## 🤝 Contributing\n\nWe welcome contributions! Please feel free to:\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes with tests\n4. Submit a pull request\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/niradler/tracking-number-validation.git\ncd tracking-number-validation\n\n# Install dependencies\npnpm install\n\n# Run tests\npnpm test\n\n# Build the project\npnpm build\n\n# Type checking\npnpm type-check\n\n# Linting\npnpm lint\n```\n\n## 📄 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## 🔗 Links\n\n- [GitHub Repository](https://github.com/niradler/tracking-number-validation)\n- [NPM Package](https://www.npmjs.com/package/tracking-number-validation)\n- [Issue Tracker](https://github.com/niradler/tracking-number-validation/issues)\n\n## 📊 Version History\n\n### v3.0.0 (Latest)\n\n- Complete TypeScript rewrite\n- Added 5 new carriers: LaserShip, Canada Post, China Post, Australia Post, and Royal Mail\n- Tracking number generation capabilities\n- Advanced validation and courier detection functions\n- Fixed UPS tracking URLs\n- Enhanced USPS barcode support (95 prefix)\n- Modern ESM build system\n\n### v2.0.2\n- Legacy JavaScript version\n- Basic courier support\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniradler%2Ftracking-number-validation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fniradler%2Ftracking-number-validation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniradler%2Ftracking-number-validation/lists"}