gstin-utils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ujjwal Pratap
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,340 @@
1
+ # gstin-utils
2
+
3
+ > A lightweight, zero-dependency utility package for Indian GSTIN validation, parsing, normalization, masking, and metadata extraction.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/gstin-utils.svg)](https://www.npmjs.com/package/gstin-utils)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
+
9
+ ---
10
+
11
+ ## Why gstin-utils?
12
+
13
+ Working with Indian GST (Goods and Services Tax) data is a common requirement in fintech, invoicing, ERP, e-commerce, and tax-compliance applications. GSTIN numbers have a strict 15-character format with embedded state codes, PAN, entity identifiers, and a checksum β€” yet most codebases validate them with ad-hoc regexes that miss important checks.
14
+
15
+ **gstin-utils** gives you production-grade utilities to:
16
+
17
+ - βœ… **Validate** GSTINs with full checksum verification (Luhn mod-36)
18
+ - πŸ” **Parse** a GSTIN into state code, PAN, entity code, and more
19
+ - 🏷️ **Extract** state names, PAN numbers, and metadata
20
+ - πŸ”’ **Mask** GSTINs for safe display in logs or UI
21
+ - πŸ“ **Normalize** raw user input (trim + uppercase)
22
+ - πŸ—ΊοΈ **Map** all 37+ Indian state/UT codes to their names
23
+ - πŸ›‘οΈ **Zero dependencies** β€” lightweight and secure
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install gstin-utils
31
+ ```
32
+
33
+ ```bash
34
+ yarn add gstin-utils
35
+ ```
36
+
37
+ ```bash
38
+ pnpm add gstin-utils
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Quick Start
44
+
45
+ ```ts
46
+ import { isValidGSTIN, parseGSTIN, maskGSTIN } from 'gstin-utils';
47
+
48
+ // Validate
49
+ isValidGSTIN('27AAPFU0939F1ZV'); // true
50
+ isValidGSTIN('INVALIDGSTIN123'); // false
51
+
52
+ // Parse
53
+ parseGSTIN('27AAPFU0939F1ZV');
54
+ // {
55
+ // gstin: '27AAPFU0939F1ZV',
56
+ // stateCode: '27',
57
+ // stateName: 'Maharashtra',
58
+ // pan: 'AAPFU0939F',
59
+ // entityCode: '1',
60
+ // checksum: 'V',
61
+ // isValid: true,
62
+ // ...
63
+ // }
64
+
65
+ // Mask for display
66
+ maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
67
+ ```
68
+
69
+ ---
70
+
71
+ ## GSTIN Format Reference
72
+
73
+ A GSTIN is a **15-character alphanumeric** string with the following structure:
74
+
75
+ | Position | Characters | Meaning | Example |
76
+ | -------- | ---------- | ------------------------------------ | ------- |
77
+ | 1–2 | `27` | State/UT code | `27` |
78
+ | 3–7 | `AAPFU` | First 5 characters of PAN (letters) | `AAPFU` |
79
+ | 8–11 | `0939` | Next 4 characters of PAN (digits) | `0939` |
80
+ | 12 | `F` | Last character of PAN (letter) | `F` |
81
+ | 13 | `1` | Entity code (1–9 or A–Z) | `1` |
82
+ | 14 | `Z` | Default/reserved character | `Z` |
83
+ | 15 | `V` | Checksum (computed via Luhn mod-36) | `V` |
84
+
85
+ ---
86
+
87
+ ## API Reference
88
+
89
+ ### `normalizeGSTIN(gstin: unknown): string`
90
+
91
+ Trims whitespace and converts to uppercase.
92
+
93
+ ```ts
94
+ normalizeGSTIN(' 27aapfu0939f1zv '); // "27AAPFU0939F1ZV"
95
+ normalizeGSTIN(null); // ""
96
+ ```
97
+
98
+ ---
99
+
100
+ ### `isValidGSTIN(gstin: unknown): boolean`
101
+
102
+ Quick boolean check β€” validates format, state code, and checksum.
103
+
104
+ ```ts
105
+ isValidGSTIN('27AAPFU0939F1ZV'); // true
106
+ isValidGSTIN('00AAPFU0939F1ZV'); // false (invalid state code)
107
+ isValidGSTIN(undefined); // false
108
+ ```
109
+
110
+ ---
111
+
112
+ ### `validateGSTIN(gstin: unknown): GSTINValidationResult`
113
+
114
+ Returns a detailed validation object with individual check results and error messages.
115
+
116
+ ```ts
117
+ validateGSTIN('27AAPFU0939F1ZV');
118
+ // {
119
+ // isValid: true,
120
+ // formatValid: true,
121
+ // lengthValid: true,
122
+ // stateCodeValid: true,
123
+ // panSegmentValid: true,
124
+ // entityCodeValid: true,
125
+ // defaultZValid: true,
126
+ // checksumValid: true,
127
+ // errors: []
128
+ // }
129
+
130
+ validateGSTIN('00AAPFU0939F1ZV');
131
+ // {
132
+ // isValid: false,
133
+ // stateCodeValid: false,
134
+ // errors: ['"00" is not a recognized GST state/UT code.', ...]
135
+ // }
136
+ ```
137
+
138
+ ---
139
+
140
+ ### `parseGSTIN(gstin: unknown): GSTINParsedResult | null`
141
+
142
+ Breaks down a GSTIN into its constituent parts. Returns `null` for unusable input.
143
+
144
+ ```ts
145
+ parseGSTIN('27AAPFU0939F1ZV');
146
+ // {
147
+ // gstin: '27AAPFU0939F1ZV',
148
+ // normalized: '27AAPFU0939F1ZV',
149
+ // stateCode: '27',
150
+ // stateName: 'Maharashtra',
151
+ // pan: 'AAPFU0939F',
152
+ // entityCode: '1',
153
+ // defaultChar: 'Z',
154
+ // checksum: 'V',
155
+ // isValid: true
156
+ // }
157
+ ```
158
+
159
+ ---
160
+
161
+ ### `getStateCodeFromGSTIN(gstin: unknown): string | null`
162
+
163
+ Extracts the 2-digit state code.
164
+
165
+ ```ts
166
+ getStateCodeFromGSTIN('27AAPFU0939F1ZV'); // "27"
167
+ getStateCodeFromGSTIN(''); // null
168
+ ```
169
+
170
+ ---
171
+
172
+ ### `getStateNameFromGSTIN(gstin: unknown): string | null`
173
+
174
+ Returns the human-readable state/UT name.
175
+
176
+ ```ts
177
+ getStateNameFromGSTIN('27AAPFU0939F1ZV'); // "Maharashtra"
178
+ getStateNameFromGSTIN('07AAPFU0939F1ZV'); // "Delhi"
179
+ ```
180
+
181
+ ---
182
+
183
+ ### `getPANFromGSTIN(gstin: unknown): string | null`
184
+
185
+ Extracts the 10-character PAN segment.
186
+
187
+ ```ts
188
+ getPANFromGSTIN('27AAPFU0939F1ZV'); // "AAPFU0939F"
189
+ ```
190
+
191
+ ---
192
+
193
+ ### `maskGSTIN(gstin: unknown): string | null`
194
+
195
+ Masks the middle portion for safe display.
196
+
197
+ ```ts
198
+ maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
199
+ ```
200
+
201
+ ---
202
+
203
+ ### `isValidStateCode(code: unknown): boolean`
204
+
205
+ Validates a 2-digit GST state/UT code against the known list.
206
+
207
+ ```ts
208
+ isValidStateCode('27'); // true (Maharashtra)
209
+ isValidStateCode('00'); // false
210
+ isValidStateCode('99'); // true (Centre Jurisdiction)
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `computeChecksum(gstin: string): string`
216
+
217
+ Computes the expected checksum character using the Luhn mod-36 algorithm.
218
+
219
+ ```ts
220
+ computeChecksum('27AAPFU0939F1ZV'); // "V"
221
+ ```
222
+
223
+ ---
224
+
225
+ ### `isChecksumValid(gstin: string): boolean`
226
+
227
+ Checks if the 15th character matches the computed checksum.
228
+
229
+ ```ts
230
+ isChecksumValid('27AAPFU0939F1ZV'); // true
231
+ isChecksumValid('27AAPFU0939F1ZA'); // false
232
+ ```
233
+
234
+ ---
235
+
236
+ ### Data Exports
237
+
238
+ ```ts
239
+ import { STATE_CODE_MAP, getAllStateCodes, getStateNameByCode } from 'gstin-utils';
240
+
241
+ STATE_CODE_MAP['27']; // "Maharashtra"
242
+ getAllStateCodes(); // ['01', '02', '03', ...]
243
+ getStateNameByCode('07'); // "Delhi"
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Edge Case Handling
249
+
250
+ All functions handle these edge cases gracefully:
251
+
252
+ | Input | Behavior |
253
+ | ------------------ | ----------------------------------------------- |
254
+ | `null` | Returns safe default (`""`, `false`, or `null`) |
255
+ | `undefined` | Returns safe default |
256
+ | `""` | Returns safe default |
257
+ | `12345` (number) | Returns safe default (non-string) |
258
+ | `" 27aapfu... "` | Auto-trimmed and uppercased |
259
+ | Short strings | Returns `null` or validation failure |
260
+ | Long strings | Returns validation failure |
261
+
262
+ ---
263
+
264
+ ## State/UT Codes Supported
265
+
266
+ The package includes a complete mapping of **37+ GST state and UT codes**, including:
267
+
268
+ - All 28 Indian states
269
+ - All 8 Union Territories
270
+ - Special codes: `96` (Foreign Country), `97` (Other Territory), `99` (Centre Jurisdiction)
271
+
272
+ ---
273
+
274
+ ## Project Structure
275
+
276
+ ```
277
+ gstin-utils/
278
+ β”œβ”€β”€ src/
279
+ β”‚ β”œβ”€β”€ index.ts # Barrel exports
280
+ β”‚ β”œβ”€β”€ validator.ts # Core validation & utility functions
281
+ β”‚ β”œβ”€β”€ checksum.ts # Luhn mod-36 checksum algorithm
282
+ β”‚ β”œβ”€β”€ state-codes.ts # State/UT code mapping
283
+ β”‚ └── types.ts # TypeScript interfaces
284
+ β”œβ”€β”€ tests/
285
+ β”‚ └── gstin-utils.test.ts
286
+ β”œβ”€β”€ examples/
287
+ β”‚ └── usage.ts
288
+ β”œβ”€β”€ package.json
289
+ β”œβ”€β”€ tsconfig.json
290
+ β”œβ”€β”€ jest.config.js
291
+ β”œβ”€β”€ LICENSE
292
+ └── README.md
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Development
298
+
299
+ ```bash
300
+ # Install dependencies
301
+ npm install
302
+
303
+ # Build
304
+ npm run build
305
+
306
+ # Run tests
307
+ npm test
308
+
309
+ # Run tests with coverage
310
+ npm run test:coverage
311
+ ```
312
+
313
+ ---
314
+
315
+ ## Use Cases
316
+
317
+ - 🏦 **Fintech** β€” Validate merchant GSTINs during onboarding
318
+ - 🧾 **Invoicing** β€” Parse and display GSTIN details on invoices
319
+ - πŸ“‹ **ERP systems** β€” Normalize and store GSTINs consistently
320
+ - πŸ“ **Form validation** β€” Client-side or server-side GSTIN validation
321
+ - πŸ“Š **Analytics** β€” Extract state-level data from GSTIN records
322
+ - πŸ”’ **Logging** β€” Mask GSTINs in logs to protect PII
323
+
324
+ ---
325
+
326
+ ## Contributing
327
+
328
+ Contributions are welcome! Please open an issue or submit a pull request.
329
+
330
+ 1. Fork the repository
331
+ 2. Create your feature branch: `git checkout -b feature/my-feature`
332
+ 3. Commit your changes: `git commit -m 'Add my feature'`
333
+ 4. Push to the branch: `git push origin feature/my-feature`
334
+ 5. Open a pull request
335
+
336
+ ---
337
+
338
+ ## License
339
+
340
+ [MIT](./LICENSE) Β© Ujjwal Pratap
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @module gstin-utils/checksum
3
+ *
4
+ * Implements the GSTIN checksum verification algorithm.
5
+ *
6
+ * GSTIN uses a **modified Luhn mod-36** algorithm for its 15th (check) character.
7
+ * The algorithm maps each character of the first 14 characters to a numeric value,
8
+ * applies a weighted computation, and derives the expected check character.
9
+ *
10
+ * Character set (base-36):
11
+ * 0-9 β†’ 0–9
12
+ * A-Z β†’ 10–35
13
+ *
14
+ * Algorithm steps:
15
+ * 1. For each of the first 14 characters, get its numeric value.
16
+ * 2. Compute: factor = value Γ— (position is odd ? 1 : 2)
17
+ * 3. Split factor into: quotient = floor(factor / 36), remainder = factor % 36
18
+ * 4. Sum all (quotient + remainder) values.
19
+ * 5. Check character value = (36 - (sum % 36)) % 36
20
+ * 6. Map check character value back to the character set.
21
+ *
22
+ * Reference: Government of India GST Portal documentation.
23
+ */
24
+ /**
25
+ * Computes the expected checksum character for a GSTIN.
26
+ *
27
+ * @param gstin - A 15-character GSTIN string (uppercase, no spaces)
28
+ * @returns The expected checksum character (the 15th character)
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * computeChecksum('27AAPFU0939F1ZV'); // 'V'
33
+ * ```
34
+ */
35
+ export declare function computeChecksum(gstin: string): string;
36
+ /**
37
+ * Validates whether the 15th character of a GSTIN matches
38
+ * the computed checksum.
39
+ *
40
+ * @param gstin - A 15-character GSTIN string (uppercase, no spaces)
41
+ * @returns `true` if checksum is valid, `false` otherwise
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * isChecksumValid('27AAPFU0939F1ZV'); // true
46
+ * isChecksumValid('27AAPFU0939F1ZA'); // false
47
+ * ```
48
+ */
49
+ export declare function isChecksumValid(gstin: string): boolean;
50
+ //# sourceMappingURL=checksum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checksum.d.ts","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAItD"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ /**
3
+ * @module gstin-utils/checksum
4
+ *
5
+ * Implements the GSTIN checksum verification algorithm.
6
+ *
7
+ * GSTIN uses a **modified Luhn mod-36** algorithm for its 15th (check) character.
8
+ * The algorithm maps each character of the first 14 characters to a numeric value,
9
+ * applies a weighted computation, and derives the expected check character.
10
+ *
11
+ * Character set (base-36):
12
+ * 0-9 β†’ 0–9
13
+ * A-Z β†’ 10–35
14
+ *
15
+ * Algorithm steps:
16
+ * 1. For each of the first 14 characters, get its numeric value.
17
+ * 2. Compute: factor = value Γ— (position is odd ? 1 : 2)
18
+ * 3. Split factor into: quotient = floor(factor / 36), remainder = factor % 36
19
+ * 4. Sum all (quotient + remainder) values.
20
+ * 5. Check character value = (36 - (sum % 36)) % 36
21
+ * 6. Map check character value back to the character set.
22
+ *
23
+ * Reference: Government of India GST Portal documentation.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.computeChecksum = computeChecksum;
27
+ exports.isChecksumValid = isChecksumValid;
28
+ /** The characters used for base-36 encoding */
29
+ const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
30
+ /**
31
+ * Computes the expected checksum character for a GSTIN.
32
+ *
33
+ * @param gstin - A 15-character GSTIN string (uppercase, no spaces)
34
+ * @returns The expected checksum character (the 15th character)
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * computeChecksum('27AAPFU0939F1ZV'); // 'V'
39
+ * ```
40
+ */
41
+ function computeChecksum(gstin) {
42
+ const input = gstin.substring(0, 14);
43
+ let sum = 0;
44
+ for (let i = 0; i < 14; i++) {
45
+ const char = input[i];
46
+ const value = CHARS.indexOf(char);
47
+ // Positions are 1-indexed: odd positions use factor 1, even use factor 2
48
+ const factor = value * (i % 2 === 0 ? 1 : 2);
49
+ const quotient = Math.floor(factor / 36);
50
+ const remainder = factor % 36;
51
+ sum += quotient + remainder;
52
+ }
53
+ const checkValue = (36 - (sum % 36)) % 36;
54
+ return CHARS[checkValue];
55
+ }
56
+ /**
57
+ * Validates whether the 15th character of a GSTIN matches
58
+ * the computed checksum.
59
+ *
60
+ * @param gstin - A 15-character GSTIN string (uppercase, no spaces)
61
+ * @returns `true` if checksum is valid, `false` otherwise
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * isChecksumValid('27AAPFU0939F1ZV'); // true
66
+ * isChecksumValid('27AAPFU0939F1ZA'); // false
67
+ * ```
68
+ */
69
+ function isChecksumValid(gstin) {
70
+ if (typeof gstin !== 'string' || gstin.length !== 15)
71
+ return false;
72
+ const expected = computeChecksum(gstin);
73
+ return gstin[14] === expected;
74
+ }
75
+ //# sourceMappingURL=checksum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checksum.js","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;AAgBH,0CAkBC;AAeD,0CAIC;AAnDD,+CAA+C;AAC/C,MAAM,KAAK,GAAG,sCAAsC,CAAC;AAErD;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,KAAa;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrC,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAElC,yEAAyE;QACzE,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,MAAM,GAAG,EAAE,CAAC;QAE9B,GAAG,IAAI,QAAQ,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1C,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,eAAe,CAAC,KAAa;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACnE,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAChC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @module gstin-utils
3
+ *
4
+ * A lightweight, zero-dependency utility package for Indian GSTIN
5
+ * validation, parsing, normalization, masking, and metadata extraction.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import {
10
+ * isValidGSTIN,
11
+ * parseGSTIN,
12
+ * maskGSTIN,
13
+ * } from 'gstin-utils';
14
+ *
15
+ * isValidGSTIN('27AAPFU0939F1ZV'); // true
16
+ * parseGSTIN('27AAPFU0939F1ZV'); // { stateCode: '27', stateName: 'Maharashtra', ... }
17
+ * maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
18
+ * ```
19
+ */
20
+ export { normalizeGSTIN, isValidGSTIN, validateGSTIN, parseGSTIN, getStateCodeFromGSTIN, getStateNameFromGSTIN, getPANFromGSTIN, maskGSTIN, isValidStateCode, } from './validator';
21
+ export { computeChecksum, isChecksumValid } from './checksum';
22
+ export { STATE_CODE_MAP, getAllStateCodes, getStateNameByCode, } from './state-codes';
23
+ export type { GSTINValidationResult, GSTINParsedResult } from './types';
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /**
3
+ * @module gstin-utils
4
+ *
5
+ * A lightweight, zero-dependency utility package for Indian GSTIN
6
+ * validation, parsing, normalization, masking, and metadata extraction.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import {
11
+ * isValidGSTIN,
12
+ * parseGSTIN,
13
+ * maskGSTIN,
14
+ * } from 'gstin-utils';
15
+ *
16
+ * isValidGSTIN('27AAPFU0939F1ZV'); // true
17
+ * parseGSTIN('27AAPFU0939F1ZV'); // { stateCode: '27', stateName: 'Maharashtra', ... }
18
+ * maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
19
+ * ```
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.getStateNameByCode = exports.getAllStateCodes = exports.STATE_CODE_MAP = exports.isChecksumValid = exports.computeChecksum = exports.isValidStateCode = exports.maskGSTIN = exports.getPANFromGSTIN = exports.getStateNameFromGSTIN = exports.getStateCodeFromGSTIN = exports.parseGSTIN = exports.validateGSTIN = exports.isValidGSTIN = exports.normalizeGSTIN = void 0;
23
+ // --- Core functions --------------------------------------------------------
24
+ var validator_1 = require("./validator");
25
+ Object.defineProperty(exports, "normalizeGSTIN", { enumerable: true, get: function () { return validator_1.normalizeGSTIN; } });
26
+ Object.defineProperty(exports, "isValidGSTIN", { enumerable: true, get: function () { return validator_1.isValidGSTIN; } });
27
+ Object.defineProperty(exports, "validateGSTIN", { enumerable: true, get: function () { return validator_1.validateGSTIN; } });
28
+ Object.defineProperty(exports, "parseGSTIN", { enumerable: true, get: function () { return validator_1.parseGSTIN; } });
29
+ Object.defineProperty(exports, "getStateCodeFromGSTIN", { enumerable: true, get: function () { return validator_1.getStateCodeFromGSTIN; } });
30
+ Object.defineProperty(exports, "getStateNameFromGSTIN", { enumerable: true, get: function () { return validator_1.getStateNameFromGSTIN; } });
31
+ Object.defineProperty(exports, "getPANFromGSTIN", { enumerable: true, get: function () { return validator_1.getPANFromGSTIN; } });
32
+ Object.defineProperty(exports, "maskGSTIN", { enumerable: true, get: function () { return validator_1.maskGSTIN; } });
33
+ Object.defineProperty(exports, "isValidStateCode", { enumerable: true, get: function () { return validator_1.isValidStateCode; } });
34
+ // --- Checksum utilities ----------------------------------------------------
35
+ var checksum_1 = require("./checksum");
36
+ Object.defineProperty(exports, "computeChecksum", { enumerable: true, get: function () { return checksum_1.computeChecksum; } });
37
+ Object.defineProperty(exports, "isChecksumValid", { enumerable: true, get: function () { return checksum_1.isChecksumValid; } });
38
+ // --- State code data & helpers ---------------------------------------------
39
+ var state_codes_1 = require("./state-codes");
40
+ Object.defineProperty(exports, "STATE_CODE_MAP", { enumerable: true, get: function () { return state_codes_1.STATE_CODE_MAP; } });
41
+ Object.defineProperty(exports, "getAllStateCodes", { enumerable: true, get: function () { return state_codes_1.getAllStateCodes; } });
42
+ Object.defineProperty(exports, "getStateNameByCode", { enumerable: true, get: function () { return state_codes_1.getStateNameByCode; } });
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,8EAA8E;AAC9E,yCAUqB;AATnB,2GAAA,cAAc,OAAA;AACd,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AACb,uGAAA,UAAU,OAAA;AACV,kHAAA,qBAAqB,OAAA;AACrB,kHAAA,qBAAqB,OAAA;AACrB,4GAAA,eAAe,OAAA;AACf,sGAAA,SAAS,OAAA;AACT,6GAAA,gBAAgB,OAAA;AAGlB,8EAA8E;AAC9E,uCAA8D;AAArD,2GAAA,eAAe,OAAA;AAAE,2GAAA,eAAe,OAAA;AAEzC,8EAA8E;AAC9E,6CAIuB;AAHrB,6GAAA,cAAc,OAAA;AACd,+GAAA,gBAAgB,OAAA;AAChB,iHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @module gstin-utils/state-codes
3
+ *
4
+ * Complete mapping of Indian GST state/UT codes to their names.
5
+ * This includes all 28 states, 8 union territories, and special codes
6
+ * used by the GST system.
7
+ *
8
+ * Reference: https://www.gst.gov.in
9
+ */
10
+ export declare const STATE_CODE_MAP: Record<string, string>;
11
+ /**
12
+ * Returns an array of all valid GST state codes.
13
+ */
14
+ export declare function getAllStateCodes(): string[];
15
+ /**
16
+ * Returns the full state/UT name for a given state code.
17
+ *
18
+ * @param code - Two-digit state code (e.g., "27")
19
+ * @returns The state/UT name, or `undefined` if the code is invalid
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * getStateNameByCode('27'); // "Maharashtra"
24
+ * getStateNameByCode('99'); // "Centre Jurisdiction"
25
+ * getStateNameByCode('00'); // undefined
26
+ * ```
27
+ */
28
+ export declare function getStateNameByCode(code: string): string | undefined;
29
+ //# sourceMappingURL=state-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-codes.d.ts","sourceRoot":"","sources":["../src/state-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2CjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGnE"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * @module gstin-utils/state-codes
4
+ *
5
+ * Complete mapping of Indian GST state/UT codes to their names.
6
+ * This includes all 28 states, 8 union territories, and special codes
7
+ * used by the GST system.
8
+ *
9
+ * Reference: https://www.gst.gov.in
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.STATE_CODE_MAP = void 0;
13
+ exports.getAllStateCodes = getAllStateCodes;
14
+ exports.getStateNameByCode = getStateNameByCode;
15
+ exports.STATE_CODE_MAP = {
16
+ '01': 'Jammu & Kashmir',
17
+ '02': 'Himachal Pradesh',
18
+ '03': 'Punjab',
19
+ '04': 'Chandigarh',
20
+ '05': 'Uttarakhand',
21
+ '06': 'Haryana',
22
+ '07': 'Delhi',
23
+ '08': 'Rajasthan',
24
+ '09': 'Uttar Pradesh',
25
+ '10': 'Bihar',
26
+ '11': 'Sikkim',
27
+ '12': 'Arunachal Pradesh',
28
+ '13': 'Nagaland',
29
+ '14': 'Manipur',
30
+ '15': 'Mizoram',
31
+ '16': 'Tripura',
32
+ '17': 'Meghalaya',
33
+ '18': 'Assam',
34
+ '19': 'West Bengal',
35
+ '20': 'Jharkhand',
36
+ '21': 'Odisha',
37
+ '22': 'Chhattisgarh',
38
+ '23': 'Madhya Pradesh',
39
+ '24': 'Gujarat',
40
+ '25': 'Daman & Diu',
41
+ '26': 'Dadra & Nagar Haveli and Daman & Diu',
42
+ '27': 'Maharashtra',
43
+ '28': 'Andhra Pradesh (Old)',
44
+ '29': 'Karnataka',
45
+ '30': 'Goa',
46
+ '31': 'Lakshadweep',
47
+ '32': 'Kerala',
48
+ '33': 'Tamil Nadu',
49
+ '34': 'Puducherry',
50
+ '35': 'Andaman & Nicobar Islands',
51
+ '36': 'Telangana',
52
+ '37': 'Andhra Pradesh',
53
+ '38': 'Ladakh',
54
+ // Special codes used by GST
55
+ '96': 'Foreign Country',
56
+ '97': 'Other Territory',
57
+ '99': 'Centre Jurisdiction',
58
+ };
59
+ /**
60
+ * Returns an array of all valid GST state codes.
61
+ */
62
+ function getAllStateCodes() {
63
+ return Object.keys(exports.STATE_CODE_MAP);
64
+ }
65
+ /**
66
+ * Returns the full state/UT name for a given state code.
67
+ *
68
+ * @param code - Two-digit state code (e.g., "27")
69
+ * @returns The state/UT name, or `undefined` if the code is invalid
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * getStateNameByCode('27'); // "Maharashtra"
74
+ * getStateNameByCode('99'); // "Centre Jurisdiction"
75
+ * getStateNameByCode('00'); // undefined
76
+ * ```
77
+ */
78
+ function getStateNameByCode(code) {
79
+ if (typeof code !== 'string')
80
+ return undefined;
81
+ return exports.STATE_CODE_MAP[code.trim()];
82
+ }
83
+ //# sourceMappingURL=state-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-codes.js","sourceRoot":"","sources":["../src/state-codes.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAkDH,4CAEC;AAeD,gDAGC;AApEY,QAAA,cAAc,GAA2B;IACpD,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,sCAAsC;IAC5C,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,sBAAsB;IAC5B,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,QAAQ;IACd,4BAA4B;IAC5B,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,qBAAqB;CAC5B,CAAC;AAEF;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,sBAAc,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC/C,OAAO,sBAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @module gstin-utils/types
3
+ *
4
+ * Type definitions for the gstin-utils package.
5
+ * All return types for validation, parsing, and utility functions.
6
+ */
7
+ /**
8
+ * Detailed validation result returned by `validateGSTIN()`.
9
+ * Each field represents one aspect of GSTIN validity.
10
+ */
11
+ export interface GSTINValidationResult {
12
+ /** Whether the GSTIN passes all validation checks */
13
+ isValid: boolean;
14
+ /** Whether the GSTIN matches the expected regex format */
15
+ formatValid: boolean;
16
+ /** Whether the GSTIN is exactly 15 characters */
17
+ lengthValid: boolean;
18
+ /** Whether the first two digits are a recognized GST state/UT code */
19
+ stateCodeValid: boolean;
20
+ /** Whether characters 3–12 form a valid PAN pattern */
21
+ panSegmentValid: boolean;
22
+ /** Whether the 13th character (entity code) is a valid alphanumeric digit */
23
+ entityCodeValid: boolean;
24
+ /** Whether the 14th character is 'Z' (default/reserved) */
25
+ defaultZValid: boolean;
26
+ /** Whether the 15th character (checksum) is valid per the Luhn-mod-36 algorithm */
27
+ checksumValid: boolean;
28
+ /** List of human-readable error messages for each failed check */
29
+ errors: string[];
30
+ }
31
+ /**
32
+ * Parsed GSTIN structure returned by `parseGSTIN()`.
33
+ * Breaks down a GSTIN into its constituent parts.
34
+ */
35
+ export interface GSTINParsedResult {
36
+ /** The original GSTIN (as provided) */
37
+ gstin: string;
38
+ /** Normalized (trimmed + uppercased) GSTIN */
39
+ normalized: string;
40
+ /** First 2 digits β€” the GST state/UT code */
41
+ stateCode: string;
42
+ /** Human-readable state/UT name, or "Unknown" if code is not recognized */
43
+ stateName: string;
44
+ /** Characters 3–12 β€” the PAN of the entity */
45
+ pan: string;
46
+ /** 13th character β€” entity/registration number within the same PAN */
47
+ entityCode: string;
48
+ /** 14th character β€” reserved character (should be 'Z') */
49
+ defaultChar: string;
50
+ /** 15th character β€” checksum digit */
51
+ checksum: string;
52
+ /** Whether the GSTIN is valid (passes all checks) */
53
+ isValid: boolean;
54
+ }
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,cAAc,EAAE,OAAO,CAAC;IACxB,uDAAuD;IACvD,eAAe,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAC;IACzB,2DAA2D;IAC3D,aAAa,EAAE,OAAO,CAAC;IACvB,mFAAmF;IACnF,aAAa,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * @module gstin-utils/types
4
+ *
5
+ * Type definitions for the gstin-utils package.
6
+ * All return types for validation, parsing, and utility functions.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @module gstin-utils/validator
3
+ *
4
+ * Core GSTIN validation and utility functions.
5
+ * All functions accept raw user input and handle edge cases gracefully.
6
+ */
7
+ import { GSTINValidationResult, GSTINParsedResult } from './types';
8
+ /**
9
+ * Normalizes a GSTIN string by trimming whitespace and converting
10
+ * to uppercase. Useful before storing or comparing GSTINs.
11
+ *
12
+ * @param gstin - Raw GSTIN input
13
+ * @returns Cleaned GSTIN string (trimmed + uppercased)
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * normalizeGSTIN(' 27aapfu0939f1zv '); // "27AAPFU0939F1ZV"
18
+ * normalizeGSTIN(null); // ""
19
+ * ```
20
+ */
21
+ export declare function normalizeGSTIN(gstin: unknown): string;
22
+ /**
23
+ * Quick boolean check: is the given GSTIN structurally valid?
24
+ *
25
+ * This checks length, format regex, state code validity, and checksum.
26
+ * For detailed diagnostics, use `validateGSTIN()` instead.
27
+ *
28
+ * @param gstin - Raw GSTIN input
29
+ * @returns `true` if valid, `false` otherwise
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * isValidGSTIN('27AAPFU0939F1ZV'); // true
34
+ * isValidGSTIN('INVALIDGSTIN'); // false
35
+ * isValidGSTIN(undefined); // false
36
+ * ```
37
+ */
38
+ export declare function isValidGSTIN(gstin: unknown): boolean;
39
+ /**
40
+ * Performs a detailed, multi-step validation of a GSTIN.
41
+ * Returns an object describing which checks passed and which failed,
42
+ * along with human-readable error messages.
43
+ *
44
+ * @param gstin - Raw GSTIN input
45
+ * @returns A `GSTINValidationResult` object
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const result = validateGSTIN('27AAPFU0939F1ZV');
50
+ * // {
51
+ * // isValid: true,
52
+ * // formatValid: true,
53
+ * // lengthValid: true,
54
+ * // stateCodeValid: true,
55
+ * // panSegmentValid: true,
56
+ * // entityCodeValid: true,
57
+ * // defaultZValid: true,
58
+ * // checksumValid: true,
59
+ * // errors: []
60
+ * // }
61
+ * ```
62
+ */
63
+ export declare function validateGSTIN(gstin: unknown): GSTINValidationResult;
64
+ /**
65
+ * Parses a GSTIN into its constituent parts.
66
+ *
67
+ * Even if the GSTIN is invalid, this function will still attempt to extract
68
+ * whatever information it can (state code, PAN, etc.). The `isValid` field
69
+ * tells you whether the GSTIN passed all validation checks.
70
+ *
71
+ * @param gstin - Raw GSTIN input
72
+ * @returns A `GSTINParsedResult` object, or `null` if input is empty/unusable
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * parseGSTIN('27AAPFU0939F1ZV');
77
+ * // {
78
+ * // gstin: '27AAPFU0939F1ZV',
79
+ * // normalized: '27AAPFU0939F1ZV',
80
+ * // stateCode: '27',
81
+ * // stateName: 'Maharashtra',
82
+ * // pan: 'AAPFU0939F',
83
+ * // entityCode: '1',
84
+ * // defaultChar: 'Z',
85
+ * // checksum: 'V',
86
+ * // isValid: true
87
+ * // }
88
+ * ```
89
+ */
90
+ export declare function parseGSTIN(gstin: unknown): GSTINParsedResult | null;
91
+ /**
92
+ * Extracts the 2-digit state code from a GSTIN.
93
+ *
94
+ * @param gstin - Raw GSTIN input
95
+ * @returns The state code string, or `null` if input is too short
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * getStateCodeFromGSTIN('27AAPFU0939F1ZV'); // "27"
100
+ * ```
101
+ */
102
+ export declare function getStateCodeFromGSTIN(gstin: unknown): string | null;
103
+ /**
104
+ * Extracts the state/UT name from a GSTIN.
105
+ *
106
+ * @param gstin - Raw GSTIN input
107
+ * @returns The state name, or `null` if the code is unrecognized or input is too short
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * getStateNameFromGSTIN('27AAPFU0939F1ZV'); // "Maharashtra"
112
+ * getStateNameFromGSTIN('99XXXXX0000X1ZA'); // "Centre Jurisdiction"
113
+ * ```
114
+ */
115
+ export declare function getStateNameFromGSTIN(gstin: unknown): string | null;
116
+ /**
117
+ * Extracts the PAN (characters 3–12) from a GSTIN.
118
+ *
119
+ * @param gstin - Raw GSTIN input
120
+ * @returns The 10-character PAN string, or `null` if input is too short
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * getPANFromGSTIN('27AAPFU0939F1ZV'); // "AAPFU0939F"
125
+ * ```
126
+ */
127
+ export declare function getPANFromGSTIN(gstin: unknown): string | null;
128
+ /**
129
+ * Masks the middle portion of a GSTIN for display or logging purposes.
130
+ * Replaces characters 6–9 (0-indexed: 5–8) with asterisks.
131
+ *
132
+ * Format: `XXAAP****39F1ZV` (first 5 + **** + last 6)
133
+ *
134
+ * @param gstin - Raw GSTIN input
135
+ * @returns The masked GSTIN string, or `null` if input is too short
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
140
+ * ```
141
+ */
142
+ export declare function maskGSTIN(gstin: unknown): string | null;
143
+ /**
144
+ * Checks whether a given 2-digit code is a valid GST state/UT code.
145
+ *
146
+ * @param code - A 2-digit state code string
147
+ * @returns `true` if the code is recognized, `false` otherwise
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * isValidStateCode('27'); // true (Maharashtra)
152
+ * isValidStateCode('00'); // false
153
+ * isValidStateCode('99'); // true (Centre Jurisdiction)
154
+ * ```
155
+ */
156
+ export declare function isValidStateCode(code: unknown): boolean;
157
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAoDnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASpD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAyFnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAyBnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAInE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAInE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAIvD"}
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ /**
3
+ * @module gstin-utils/validator
4
+ *
5
+ * Core GSTIN validation and utility functions.
6
+ * All functions accept raw user input and handle edge cases gracefully.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.normalizeGSTIN = normalizeGSTIN;
10
+ exports.isValidGSTIN = isValidGSTIN;
11
+ exports.validateGSTIN = validateGSTIN;
12
+ exports.parseGSTIN = parseGSTIN;
13
+ exports.getStateCodeFromGSTIN = getStateCodeFromGSTIN;
14
+ exports.getStateNameFromGSTIN = getStateNameFromGSTIN;
15
+ exports.getPANFromGSTIN = getPANFromGSTIN;
16
+ exports.maskGSTIN = maskGSTIN;
17
+ exports.isValidStateCode = isValidStateCode;
18
+ const state_codes_1 = require("./state-codes");
19
+ const checksum_1 = require("./checksum");
20
+ // ---------------------------------------------------------------------------
21
+ // Constants
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Regex pattern for a structurally valid GSTIN.
25
+ *
26
+ * Breakdown:
27
+ * ^ β€” start of string
28
+ * [0-9]{2} β€” 2-digit state code
29
+ * [A-Z]{5} β€” 5 letters of PAN (first 5 chars: entity type + name)
30
+ * [0-9]{4} β€” 4 digits of PAN
31
+ * [A-Z] β€” 1 letter of PAN (check letter)
32
+ * [1-9A-Z] β€” entity code (1–9 or A–Z, never 0)
33
+ * Z β€” default reserved character
34
+ * [0-9A-Z] β€” checksum character
35
+ * $ β€” end of string
36
+ */
37
+ const GSTIN_REGEX = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/;
38
+ /**
39
+ * Regex pattern for a valid PAN segment (characters 3–12 of GSTIN).
40
+ *
41
+ * PAN format: AAAAA9999A
42
+ * 5 uppercase letters + 4 digits + 1 uppercase letter
43
+ */
44
+ const PAN_REGEX = /^[A-Z]{5}[0-9]{4}[A-Z]$/;
45
+ // ---------------------------------------------------------------------------
46
+ // Helpers (internal)
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Safely coerces input to a trimmed, uppercased string.
50
+ * Returns an empty string for null, undefined, or non-string values.
51
+ *
52
+ * @internal
53
+ */
54
+ function sanitize(input) {
55
+ if (input === null || input === undefined)
56
+ return '';
57
+ if (typeof input !== 'string')
58
+ return '';
59
+ return input.trim().toUpperCase();
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Public API
63
+ // ---------------------------------------------------------------------------
64
+ /**
65
+ * Normalizes a GSTIN string by trimming whitespace and converting
66
+ * to uppercase. Useful before storing or comparing GSTINs.
67
+ *
68
+ * @param gstin - Raw GSTIN input
69
+ * @returns Cleaned GSTIN string (trimmed + uppercased)
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * normalizeGSTIN(' 27aapfu0939f1zv '); // "27AAPFU0939F1ZV"
74
+ * normalizeGSTIN(null); // ""
75
+ * ```
76
+ */
77
+ function normalizeGSTIN(gstin) {
78
+ return sanitize(gstin);
79
+ }
80
+ /**
81
+ * Quick boolean check: is the given GSTIN structurally valid?
82
+ *
83
+ * This checks length, format regex, state code validity, and checksum.
84
+ * For detailed diagnostics, use `validateGSTIN()` instead.
85
+ *
86
+ * @param gstin - Raw GSTIN input
87
+ * @returns `true` if valid, `false` otherwise
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * isValidGSTIN('27AAPFU0939F1ZV'); // true
92
+ * isValidGSTIN('INVALIDGSTIN'); // false
93
+ * isValidGSTIN(undefined); // false
94
+ * ```
95
+ */
96
+ function isValidGSTIN(gstin) {
97
+ const normalized = sanitize(gstin);
98
+ if (normalized.length !== 15)
99
+ return false;
100
+ if (!GSTIN_REGEX.test(normalized))
101
+ return false;
102
+ const stateCode = normalized.substring(0, 2);
103
+ if (!(stateCode in state_codes_1.STATE_CODE_MAP))
104
+ return false;
105
+ return (0, checksum_1.isChecksumValid)(normalized);
106
+ }
107
+ /**
108
+ * Performs a detailed, multi-step validation of a GSTIN.
109
+ * Returns an object describing which checks passed and which failed,
110
+ * along with human-readable error messages.
111
+ *
112
+ * @param gstin - Raw GSTIN input
113
+ * @returns A `GSTINValidationResult` object
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const result = validateGSTIN('27AAPFU0939F1ZV');
118
+ * // {
119
+ * // isValid: true,
120
+ * // formatValid: true,
121
+ * // lengthValid: true,
122
+ * // stateCodeValid: true,
123
+ * // panSegmentValid: true,
124
+ * // entityCodeValid: true,
125
+ * // defaultZValid: true,
126
+ * // checksumValid: true,
127
+ * // errors: []
128
+ * // }
129
+ * ```
130
+ */
131
+ function validateGSTIN(gstin) {
132
+ const normalized = sanitize(gstin);
133
+ const errors = [];
134
+ // 1. Length check
135
+ const lengthValid = normalized.length === 15;
136
+ if (!lengthValid) {
137
+ errors.push(`GSTIN must be exactly 15 characters, received ${normalized.length}.`);
138
+ }
139
+ // 2. Overall format check
140
+ const formatValid = GSTIN_REGEX.test(normalized);
141
+ if (!formatValid && lengthValid) {
142
+ errors.push('GSTIN does not match the expected format.');
143
+ }
144
+ // For the remaining checks we need at least 15 characters
145
+ let stateCodeValid = false;
146
+ let panSegmentValid = false;
147
+ let entityCodeValid = false;
148
+ let defaultZValid = false;
149
+ let checksumValid = false;
150
+ if (lengthValid) {
151
+ // 3. State code check
152
+ const stateCode = normalized.substring(0, 2);
153
+ stateCodeValid = stateCode in state_codes_1.STATE_CODE_MAP;
154
+ if (!stateCodeValid) {
155
+ errors.push(`"${stateCode}" is not a recognized GST state/UT code.`);
156
+ }
157
+ // 4. PAN segment check (characters 3–12, i.e. index 2–11)
158
+ const panSegment = normalized.substring(2, 12);
159
+ panSegmentValid = PAN_REGEX.test(panSegment);
160
+ if (!panSegmentValid) {
161
+ errors.push(`PAN segment "${panSegment}" does not match the expected PAN format (AAAAA9999A).`);
162
+ }
163
+ // 5. Entity code check (13th character, index 12)
164
+ const entityCode = normalized[12];
165
+ entityCodeValid = /^[1-9A-Z]$/.test(entityCode);
166
+ if (!entityCodeValid) {
167
+ errors.push(`Entity code "${entityCode}" is invalid. Must be 1–9 or A–Z.`);
168
+ }
169
+ // 6. Default 'Z' check (14th character, index 13)
170
+ defaultZValid = normalized[13] === 'Z';
171
+ if (!defaultZValid) {
172
+ errors.push(`14th character must be "Z" (reserved), found "${normalized[13]}".`);
173
+ }
174
+ // 7. Checksum check (15th character, index 14)
175
+ checksumValid = (0, checksum_1.isChecksumValid)(normalized);
176
+ if (!checksumValid) {
177
+ const expected = (0, checksum_1.computeChecksum)(normalized);
178
+ errors.push(`Checksum character "${normalized[14]}" is invalid. Expected "${expected}".`);
179
+ }
180
+ }
181
+ const isValid = lengthValid &&
182
+ formatValid &&
183
+ stateCodeValid &&
184
+ panSegmentValid &&
185
+ entityCodeValid &&
186
+ defaultZValid &&
187
+ checksumValid;
188
+ return {
189
+ isValid,
190
+ formatValid,
191
+ lengthValid,
192
+ stateCodeValid,
193
+ panSegmentValid,
194
+ entityCodeValid,
195
+ defaultZValid,
196
+ checksumValid,
197
+ errors,
198
+ };
199
+ }
200
+ /**
201
+ * Parses a GSTIN into its constituent parts.
202
+ *
203
+ * Even if the GSTIN is invalid, this function will still attempt to extract
204
+ * whatever information it can (state code, PAN, etc.). The `isValid` field
205
+ * tells you whether the GSTIN passed all validation checks.
206
+ *
207
+ * @param gstin - Raw GSTIN input
208
+ * @returns A `GSTINParsedResult` object, or `null` if input is empty/unusable
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * parseGSTIN('27AAPFU0939F1ZV');
213
+ * // {
214
+ * // gstin: '27AAPFU0939F1ZV',
215
+ * // normalized: '27AAPFU0939F1ZV',
216
+ * // stateCode: '27',
217
+ * // stateName: 'Maharashtra',
218
+ * // pan: 'AAPFU0939F',
219
+ * // entityCode: '1',
220
+ * // defaultChar: 'Z',
221
+ * // checksum: 'V',
222
+ * // isValid: true
223
+ * // }
224
+ * ```
225
+ */
226
+ function parseGSTIN(gstin) {
227
+ var _a;
228
+ const raw = typeof gstin === 'string' ? gstin : '';
229
+ const normalized = sanitize(gstin);
230
+ if (normalized.length < 15)
231
+ return null;
232
+ const stateCode = normalized.substring(0, 2);
233
+ const stateName = (_a = (0, state_codes_1.getStateNameByCode)(stateCode)) !== null && _a !== void 0 ? _a : 'Unknown';
234
+ const pan = normalized.substring(2, 12);
235
+ const entityCode = normalized[12];
236
+ const defaultChar = normalized[13];
237
+ const checksum = normalized[14];
238
+ const valid = isValidGSTIN(normalized);
239
+ return {
240
+ gstin: raw.trim(),
241
+ normalized,
242
+ stateCode,
243
+ stateName,
244
+ pan,
245
+ entityCode,
246
+ defaultChar,
247
+ checksum,
248
+ isValid: valid,
249
+ };
250
+ }
251
+ /**
252
+ * Extracts the 2-digit state code from a GSTIN.
253
+ *
254
+ * @param gstin - Raw GSTIN input
255
+ * @returns The state code string, or `null` if input is too short
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * getStateCodeFromGSTIN('27AAPFU0939F1ZV'); // "27"
260
+ * ```
261
+ */
262
+ function getStateCodeFromGSTIN(gstin) {
263
+ const normalized = sanitize(gstin);
264
+ if (normalized.length < 2)
265
+ return null;
266
+ return normalized.substring(0, 2);
267
+ }
268
+ /**
269
+ * Extracts the state/UT name from a GSTIN.
270
+ *
271
+ * @param gstin - Raw GSTIN input
272
+ * @returns The state name, or `null` if the code is unrecognized or input is too short
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * getStateNameFromGSTIN('27AAPFU0939F1ZV'); // "Maharashtra"
277
+ * getStateNameFromGSTIN('99XXXXX0000X1ZA'); // "Centre Jurisdiction"
278
+ * ```
279
+ */
280
+ function getStateNameFromGSTIN(gstin) {
281
+ var _a;
282
+ const code = getStateCodeFromGSTIN(gstin);
283
+ if (!code)
284
+ return null;
285
+ return (_a = (0, state_codes_1.getStateNameByCode)(code)) !== null && _a !== void 0 ? _a : null;
286
+ }
287
+ /**
288
+ * Extracts the PAN (characters 3–12) from a GSTIN.
289
+ *
290
+ * @param gstin - Raw GSTIN input
291
+ * @returns The 10-character PAN string, or `null` if input is too short
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * getPANFromGSTIN('27AAPFU0939F1ZV'); // "AAPFU0939F"
296
+ * ```
297
+ */
298
+ function getPANFromGSTIN(gstin) {
299
+ const normalized = sanitize(gstin);
300
+ if (normalized.length < 12)
301
+ return null;
302
+ return normalized.substring(2, 12);
303
+ }
304
+ /**
305
+ * Masks the middle portion of a GSTIN for display or logging purposes.
306
+ * Replaces characters 6–9 (0-indexed: 5–8) with asterisks.
307
+ *
308
+ * Format: `XXAAP****39F1ZV` (first 5 + **** + last 6)
309
+ *
310
+ * @param gstin - Raw GSTIN input
311
+ * @returns The masked GSTIN string, or `null` if input is too short
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * maskGSTIN('27AAPFU0939F1ZV'); // "27AAP****39F1ZV"
316
+ * ```
317
+ */
318
+ function maskGSTIN(gstin) {
319
+ const normalized = sanitize(gstin);
320
+ if (normalized.length < 15)
321
+ return null;
322
+ const prefix = normalized.substring(0, 5); // "27AAP"
323
+ const suffix = normalized.substring(9, 15); // "39F1ZV"
324
+ return `${prefix}****${suffix}`;
325
+ }
326
+ /**
327
+ * Checks whether a given 2-digit code is a valid GST state/UT code.
328
+ *
329
+ * @param code - A 2-digit state code string
330
+ * @returns `true` if the code is recognized, `false` otherwise
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * isValidStateCode('27'); // true (Maharashtra)
335
+ * isValidStateCode('00'); // false
336
+ * isValidStateCode('99'); // true (Centre Jurisdiction)
337
+ * ```
338
+ */
339
+ function isValidStateCode(code) {
340
+ if (typeof code !== 'string')
341
+ return false;
342
+ const trimmed = code.trim();
343
+ return trimmed in state_codes_1.STATE_CODE_MAP;
344
+ }
345
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "gstin-utils",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight, zero-dependency utility package for Indian GSTIN validation, parsing, normalization, masking, and metadata extraction.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "test": "jest",
15
+ "test:coverage": "jest --coverage",
16
+ "prepublishOnly": "npm run build && npm test",
17
+ "lint": "tsc --noEmit"
18
+ },
19
+ "keywords": [
20
+ "gstin",
21
+ "gst",
22
+ "india",
23
+ "tax",
24
+ "validation",
25
+ "parser",
26
+ "fintech",
27
+ "invoice",
28
+ "erp",
29
+ "pan",
30
+ "state-code",
31
+ "checksum",
32
+ "masking",
33
+ "utility"
34
+ ],
35
+ "author": "Dheeraj Singh",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/dheeraj0808/gstin-validator"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/dheeraj0808/gstin-validator/issues"
43
+ },
44
+ "homepage": "https://github.com/ujjwalpratap/gstin-utils#readme",
45
+ "engines": {
46
+ "node": ">=14.0.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/jest": "^29.5.12",
50
+ "jest": "^29.7.0",
51
+ "ts-jest": "^29.1.2",
52
+ "typescript": "^5.4.5"
53
+ }
54
+ }