Releases: karthi-21/HSN-Code-Package
Release list
v3.0.0 — Safer GST workflows and stricter data contracts
hsn-code-package v3.0.0
Version 3.0 makes HSN/GST data safer to consume, strengthens financial input validation, secures spreadsheet exports, and replaces the ineffective GST-rate update automation.
This is a semver-major release because several previously permissive behaviors are now intentionally stricter.
Breaking changes
Immutable canonical datasets
getAllHsn() and getAllSac() now return stable, frozen arrays containing frozen records.
Clone records before modifying them:
const editableCodes = hsn.getAllHsn().map(code => ({ ...code }));TypeScript declarations now expose canonical HSN, SAC, GST-rate, and metadata values as readonly.
Strict GSTR-1 validation
generateGSTR1Summary() now rejects:
- Missing taxable values or rates
- Numeric strings
- Negative values
NaNand infinite values- Invalid
isInterStatevalues
Each item must provide a finite, non-negative taxableValue and either gstRate or igstRate.
CSV formula protection
exportToCSV() now protects spreadsheet-formula strings by default.
exportToCSV(data, { preventFormulaInjection: false });Use the opt-out only for trusted data where preserving formula-like input is intentional. Legitimate signed numeric strings such as -1234.50 remain unchanged.
CLI exit statuses
Invalid identifiers passed to these commands now return exit status 1:
hsn validate <code>
hsn gstin <gstin>Scripts that inspect the command exit status should account for this corrected behavior.
TypeScript metadata contract
HsnStats now includes these required fields:
gstRatesLastUpdated
gstRateSource
gstNotificationRefgstRateSource is one of:
'chapter-level' | 'mixed' | 'authoritative-excel'Security improvements
- Replaced vulnerable legacy spreadsheet parsers with integrity-pinned SheetJS 0.20.3.
- Added spreadsheet-formula injection protection to CSV headers and cells.
- Changed the GST-rate workflow to use read-only repository permissions.
- Removed automatic commits and pushes from the scheduled rate workflow.
- Added strict HTTPS, redirect, content-type, file-signature, size, duplicate, and workbook-overlap validation.
GST-rate workflow changes
The old weekly workflow produced metadata-only commits without materially updating any of the 12,604 bundled rates.
The replacement workflow:
- Runs only when
GST_RATE_SOURCE_URLis configured - Never modifies repository files
- Fails closed when downloading or parsing fails
- Requires at least 80% of workbook rows to match bundled HSN codes
- Opens a review issue when validated rate content differs
- Reports
mixedprovenance whenever chapter-level fallbacks remain - Reports
authoritative-excelonly when every generated rate comes from the workbook
Local updates remain an explicit reviewed operation:
node scripts/update-gst-rates.js --writeCorrectness fixes
- Invoice totals now support downward round-off adjustments.
- Signed cent rounding is symmetric and no longer exposes negative zero.
- GSTR-1 summaries reject malformed financial data instead of silently converting it to zero.
- CLI validation failures now return reliable nonzero statuses.
- GST rates and metadata are staged together before either target is replaced.
- Cached public datasets can no longer be corrupted through consumer mutation.
Tooling and quality
- Strict TypeScript checking is now required by CI.
- Publishing is blocked when tests or TypeScript checks fail.
- Expanded regression coverage to 208 passing tests.
- Verified the final npm package contains only the expected runtime files.
- Production dependency audit reports zero vulnerabilities.
Upgrade
npm install hsn-code-package@3Review the migration guidance in the README before upgrading applications that mutate returned records, accept loosely typed GSTR-1 input, depend on exact CSV output, or inspect CLI exit statuses.
v2.3.1 — Author, Live Demo & npm fix
v2.3.1
Documentation and metadata update — no API or behaviour changes.
What's new
-
Live demo — hsn-gst-demo.karthi-21.com is now
linked prominently in the README and set as the package homepage on npm. Try every feature
in the browser without installing anything. -
Author — karthi-21.com added as author URL in
package.json
and credited in the TypeScript definitions (@author+@seetags, visible in IDE tooltips).
Fixes
- Version bump from
2.3.0to2.3.1to resolve npm 403 conflict from a double-publish attempt.
No code changes. Safe to upgrade from any 2.x version.
Full API docs & live demo: hsn-gst-demo.karthi-21.com
v2.3.0 — Full GST Toolkit
What's new in v2.3.0
This release transforms hsn-code-package from an HSN lookup library into a complete, zero-runtime-dependency GST toolkit for India.
GST rate data (Issue #2)
- Bundled IGST/CGST/SGST/cess rates for all 12,604 HSN codes — derived from CBIC Notification No. 09/2025-CT(Rate) (effective 22 Sep 2025)
- New:
getGstRateByCode(code),getHsnByExactCodeWithRate(code),getHsnByRateSlabs(igstRate) - Weekly auto-update GitHub Actions workflow (
update-gst-rates.yml) — auto-opens an issue if the update fails npm run update:ratesto trigger manually
GST calculation utilities (Issue #3)
- Pure, rate-agnostic helpers — no HSN data required, pass the rate in
calculateTax,calculateGSTBreakdown(CGST/SGST or IGST + cess),reverseCalculateTaxgetApplicableTaxType(state-code based IGST vs CGST+SGST)calculateInvoiceTotals(multi-line invoice with round-off),groupItemsByTaxRate(GSTR-1 grouping)applyRoundOffRules(half-up 2-decimal rounding)
GSTIN & PAN validation (Issue #4)
- MOD-36 checksum verification, full 38-state code map
validateGSTIN,formatGSTIN,getStateFromGSTIN,isValidPAN,getGSTINComponents
SAC codes for services (Issue #4)
- 496 real Indian GST SAC codes
getAllSac,getSacByCode,searchSac(with matchType + pagination),getCodeDetails(unified HSN/SAC lookup)
Export utilities (Issue #4)
exportToCSV(RFC-compliant escaping, custom delimiter/headers)exportToJSON,generateGSTR1Summary(rate-wise CGST/SGST/IGST/cess breakdown)
Advanced HSN lookups (Issue #4)
getChapterSummary(chapter)— code count, range, full listfindCodesByDescription(keywords)— AND keyword matchbulkValidateHsnCodes(codes)— validate an array at once
CLI (hsn)
hsn search "cotton" --limit 10
hsn validate 52010011
hsn chapter 52
hsn gstin 27AAPFU0939F1ZV
hsn sac "construction"
hsn export "silk" --format csv
hsn statsTypeScript
Complete, audited type definitions bundled — no @types package needed. New npm run typecheck (tsc --strict --noEmit) ensures types stay accurate.
105 tests passing · Node.js >= 14 · Zero runtime dependencies
Full API docs: [README](https://github.com/karthi-21/HSN-Code-Package#readme)
v2.0.0 — Zero-dependency rewrite with new lookup APIs and TypeScript support
What's new in v2.0.0
🐛 Critical bug fixes
- Exports were completely broken —
module.exportsused bitwise OR on functions (evaluates to0), meaning nothing was exported and the package silently failed for all users. Fixed. - File path broke outside the package directory — the Excel file was loaded with a relative path, crashing when called from any other directory. Fixed with
__dirname. - Crashes on null/undefined input —
getCodeByTxt(null)andgetDesByCode(undefined)threw unhandled TypeErrors. Now throws a clear, descriptive error.
⚡ Zero runtime dependencies (was 41)
The package previously installed 41 transitive packages at runtime just to parse one static Excel file. The HSN data is now pre-built into data/hsn_codes.json and shipped directly — no parsing at startup, no extra installs for your users.
🆕 New API methods
| Method | Description |
|---|---|
getHsnByExactCode(code) |
Exact match — returns the single entry or undefined |
isValidHsnCode(code) |
Boolean validation, safe on null/undefined |
getHsnChapter(chapter) |
All codes under a 2-digit chapter (e.g. '52' for cotton) |
searchHsn(query, options) |
Search with matchType, limit, and offset for pagination |
getStats() |
Dataset metadata — version, date, total codes, chapters |
🔷 TypeScript support
Full index.d.ts type definitions included. No @types/ package needed.
✅ Tests
35 tests added with 98% coverage across all functions and edge cases.
📦 Dataset
12,604 HSN codes across 86 chapters (CBIC / WCO Harmonized System Nomenclature).
Migration from v1
Existing calls to getAllHsn(), getCodeByTxt(), and getDesByCode() work the same — they now validate input and won't crash on null. Destructured imports are required:
// v1 (broken — nothing was exported)
const hsn = require('hsn-code-package');
// v2 (correct)
const { getAllHsn, getCodeByTxt, getDesByCode } = require('hsn-code-package');