indycheck 0.2.0 → 0.2.1
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/dist/native.d.ts +122 -0
- package/dist/native.js +518 -0
- package/package.json +2 -1
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* indycheck — optional native (napi-rs) backend.
|
|
3
|
+
*
|
|
4
|
+
* Same public API as the pure-TypeScript mirror in `./index`, but the
|
|
5
|
+
* validation itself runs in the compiled Rust core through the
|
|
6
|
+
* napi-rs addon in `crates/indycheck-napi` instead of the TypeScript
|
|
7
|
+
* re-implementation. The addon is optional: when it is not built (or
|
|
8
|
+
* cannot be loaded) every function below falls back to `./index`
|
|
9
|
+
* silently, so the package works with no native code at all.
|
|
10
|
+
*
|
|
11
|
+
* How it loads: `isNativeAvailable()` tries, in order,
|
|
12
|
+
* 1. `INDYCHECK_NATIVE_PATH` — a path to the addon's `index.js` (or
|
|
13
|
+
* directly to a `.node` file), when the env var is set;
|
|
14
|
+
* 2. `crates/indycheck-napi/index.js` relative to this file (works
|
|
15
|
+
* from both `src/` under vitest and `dist/`);
|
|
16
|
+
* 3. the same path found by walking up from the current working
|
|
17
|
+
* directory to a repo checkout.
|
|
18
|
+
* The `.node` binary itself is never committed to the repo — build it
|
|
19
|
+
* with `npm run build` in `crates/indycheck-napi` (see its README).
|
|
20
|
+
*
|
|
21
|
+
* Shape note: the Rust wrappers return JSON strings (see
|
|
22
|
+
* `crates/indycheck-napi/src/lib.rs`); they are parsed here into the
|
|
23
|
+
* same `{ valid, code, reason_en, reason_hi, parsed }` objects the
|
|
24
|
+
* TypeScript implementation returns. `detect` in Rust returns only
|
|
25
|
+
* the type string ("pan" | "aadhaar" | ... | "unknown"), so the
|
|
26
|
+
* `ValidationResult<DetectParsed>` shape is rebuilt here from the
|
|
27
|
+
* native type + the matching native validator, exactly like
|
|
28
|
+
* `detect` in `./index`. `validateMany` in Rust returns a bare
|
|
29
|
+
* `ValidationResult[]` (one per input, in order); the
|
|
30
|
+
* `input` / `type` / totals wrapper is rebuilt here with the same
|
|
31
|
+
* `VALID` / `SOME_INVALID` codes and reason strings as `./index`.
|
|
32
|
+
* The `*WithOptions` variants have no native equivalent (the Rust
|
|
33
|
+
* core's options live behind different entry points), so they always
|
|
34
|
+
* use the TypeScript implementation.
|
|
35
|
+
*
|
|
36
|
+
* Every function here never throws on bad input, like `./index`.
|
|
37
|
+
*/
|
|
38
|
+
import type { AadhaarParsed, CinParsed, DetectParsed, GstinParsed, IfscParsed, LlpinParsed, MobileParsed, PincodeParsed, TanParsed, UpiParsed, ValidateManyParsed, ValidationResult, VehicleParsed, VoterParsed } from "./index";
|
|
39
|
+
import * as tsImpl from "./index";
|
|
40
|
+
import type { PanParsed } from "./index";
|
|
41
|
+
/** `true` when the native addon loaded and can be used. */
|
|
42
|
+
export declare function isNativeAvailable(): boolean;
|
|
43
|
+
/** Which backend the functions below are currently using. */
|
|
44
|
+
export declare function backend(): "native" | "typescript";
|
|
45
|
+
export declare function validatePan(input: unknown): ValidationResult<PanParsed>;
|
|
46
|
+
export declare function validateAadhaar(input: unknown): ValidationResult<AadhaarParsed>;
|
|
47
|
+
export declare function validateGstin(input: unknown): ValidationResult<GstinParsed>;
|
|
48
|
+
export declare function validateIfsc(input: unknown): ValidationResult<IfscParsed>;
|
|
49
|
+
export declare function validateUpi(input: unknown): ValidationResult<UpiParsed>;
|
|
50
|
+
export declare function validateMobile(input: unknown): ValidationResult<MobileParsed>;
|
|
51
|
+
export declare function validatePincode(input: unknown): ValidationResult<PincodeParsed>;
|
|
52
|
+
export declare function validateTan(input: unknown): ValidationResult<TanParsed>;
|
|
53
|
+
export declare function validateCin(input: unknown): ValidationResult<CinParsed>;
|
|
54
|
+
export declare function validateLlpin(input: unknown): ValidationResult<LlpinParsed>;
|
|
55
|
+
export declare function validateVoterId(input: unknown): ValidationResult<VoterParsed>;
|
|
56
|
+
/** Alias for `validateVoterId`: EPIC is the name printed on the card. */
|
|
57
|
+
export declare function validateEpic(input: unknown): ValidationResult<VoterParsed>;
|
|
58
|
+
export declare function validateVehicle(input: unknown): ValidationResult<VehicleParsed>;
|
|
59
|
+
/** Alias for `validateVehicle`. */
|
|
60
|
+
export declare function validateVehicleRegistration(input: unknown): ValidationResult<VehicleParsed>;
|
|
61
|
+
/** The Rust `detect` string for a trimmed input. */
|
|
62
|
+
export declare function detectType(input: string): string;
|
|
63
|
+
export declare function detect(input: unknown): ValidationResult<DetectParsed>;
|
|
64
|
+
export declare function validateMany(inputs: unknown): ValidationResult<ValidateManyParsed>;
|
|
65
|
+
export declare function formatMobile(input: unknown): ValidationResult<MobileParsed>;
|
|
66
|
+
export declare function formatPan(input: unknown): string | null;
|
|
67
|
+
export declare function formatGstin(input: unknown): string | null;
|
|
68
|
+
export declare function maskAadhaar(input: unknown): ValidationResult<AadhaarParsed>;
|
|
69
|
+
export declare function maskPan(input: unknown): string;
|
|
70
|
+
export declare function maskMobile(input: unknown): string;
|
|
71
|
+
export declare function generatePan(entity?: unknown): string;
|
|
72
|
+
export declare function generateAadhaar(): string;
|
|
73
|
+
export declare function generateGstin(stateCode?: unknown): string;
|
|
74
|
+
export declare function generateMobile(): string;
|
|
75
|
+
export declare const validateMobileWithOptions: typeof tsImpl.validateMobileWithOptions;
|
|
76
|
+
export declare const validatePanWithOptions: typeof tsImpl.validatePanWithOptions;
|
|
77
|
+
export declare const validateAadhaarWithOptions: typeof tsImpl.validateAadhaarWithOptions;
|
|
78
|
+
export declare const validateGstinWithOptions: typeof tsImpl.validateGstinWithOptions;
|
|
79
|
+
export declare const formatMobileWithOptions: typeof tsImpl.formatMobileWithOptions;
|
|
80
|
+
export declare const defaultOptions: typeof tsImpl.defaultOptions;
|
|
81
|
+
export declare const lenientOptions: typeof tsImpl.lenientOptions;
|
|
82
|
+
export declare const noSpacesHyphensOptions: typeof tsImpl.noSpacesHyphensOptions;
|
|
83
|
+
declare const _default: {
|
|
84
|
+
backend: typeof backend;
|
|
85
|
+
isNativeAvailable: typeof isNativeAvailable;
|
|
86
|
+
validateMobile: typeof validateMobile;
|
|
87
|
+
validatePan: typeof validatePan;
|
|
88
|
+
validateAadhaar: typeof validateAadhaar;
|
|
89
|
+
validateGstin: typeof validateGstin;
|
|
90
|
+
validateIfsc: typeof validateIfsc;
|
|
91
|
+
validateUpi: typeof validateUpi;
|
|
92
|
+
validatePincode: typeof validatePincode;
|
|
93
|
+
validateTan: typeof validateTan;
|
|
94
|
+
validateCin: typeof validateCin;
|
|
95
|
+
validateLlpin: typeof validateLlpin;
|
|
96
|
+
validateVoterId: typeof validateVoterId;
|
|
97
|
+
validateEpic: typeof validateEpic;
|
|
98
|
+
validateVehicle: typeof validateVehicle;
|
|
99
|
+
validateVehicleRegistration: typeof validateVehicleRegistration;
|
|
100
|
+
validateMobileWithOptions: typeof tsImpl.validateMobileWithOptions;
|
|
101
|
+
validatePanWithOptions: typeof tsImpl.validatePanWithOptions;
|
|
102
|
+
validateAadhaarWithOptions: typeof tsImpl.validateAadhaarWithOptions;
|
|
103
|
+
validateGstinWithOptions: typeof tsImpl.validateGstinWithOptions;
|
|
104
|
+
formatMobile: typeof formatMobile;
|
|
105
|
+
formatMobileWithOptions: typeof tsImpl.formatMobileWithOptions;
|
|
106
|
+
formatPan: typeof formatPan;
|
|
107
|
+
formatGstin: typeof formatGstin;
|
|
108
|
+
maskAadhaar: typeof maskAadhaar;
|
|
109
|
+
maskPan: typeof maskPan;
|
|
110
|
+
maskMobile: typeof maskMobile;
|
|
111
|
+
generatePan: typeof generatePan;
|
|
112
|
+
generateAadhaar: typeof generateAadhaar;
|
|
113
|
+
generateGstin: typeof generateGstin;
|
|
114
|
+
generateMobile: typeof generateMobile;
|
|
115
|
+
defaultOptions: typeof tsImpl.defaultOptions;
|
|
116
|
+
lenientOptions: typeof tsImpl.lenientOptions;
|
|
117
|
+
noSpacesHyphensOptions: typeof tsImpl.noSpacesHyphensOptions;
|
|
118
|
+
detect: typeof detect;
|
|
119
|
+
detectType: typeof detectType;
|
|
120
|
+
validateMany: typeof validateMany;
|
|
121
|
+
};
|
|
122
|
+
export default _default;
|
package/dist/native.js
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* indycheck — optional native (napi-rs) backend.
|
|
4
|
+
*
|
|
5
|
+
* Same public API as the pure-TypeScript mirror in `./index`, but the
|
|
6
|
+
* validation itself runs in the compiled Rust core through the
|
|
7
|
+
* napi-rs addon in `crates/indycheck-napi` instead of the TypeScript
|
|
8
|
+
* re-implementation. The addon is optional: when it is not built (or
|
|
9
|
+
* cannot be loaded) every function below falls back to `./index`
|
|
10
|
+
* silently, so the package works with no native code at all.
|
|
11
|
+
*
|
|
12
|
+
* How it loads: `isNativeAvailable()` tries, in order,
|
|
13
|
+
* 1. `INDYCHECK_NATIVE_PATH` — a path to the addon's `index.js` (or
|
|
14
|
+
* directly to a `.node` file), when the env var is set;
|
|
15
|
+
* 2. `crates/indycheck-napi/index.js` relative to this file (works
|
|
16
|
+
* from both `src/` under vitest and `dist/`);
|
|
17
|
+
* 3. the same path found by walking up from the current working
|
|
18
|
+
* directory to a repo checkout.
|
|
19
|
+
* The `.node` binary itself is never committed to the repo — build it
|
|
20
|
+
* with `npm run build` in `crates/indycheck-napi` (see its README).
|
|
21
|
+
*
|
|
22
|
+
* Shape note: the Rust wrappers return JSON strings (see
|
|
23
|
+
* `crates/indycheck-napi/src/lib.rs`); they are parsed here into the
|
|
24
|
+
* same `{ valid, code, reason_en, reason_hi, parsed }` objects the
|
|
25
|
+
* TypeScript implementation returns. `detect` in Rust returns only
|
|
26
|
+
* the type string ("pan" | "aadhaar" | ... | "unknown"), so the
|
|
27
|
+
* `ValidationResult<DetectParsed>` shape is rebuilt here from the
|
|
28
|
+
* native type + the matching native validator, exactly like
|
|
29
|
+
* `detect` in `./index`. `validateMany` in Rust returns a bare
|
|
30
|
+
* `ValidationResult[]` (one per input, in order); the
|
|
31
|
+
* `input` / `type` / totals wrapper is rebuilt here with the same
|
|
32
|
+
* `VALID` / `SOME_INVALID` codes and reason strings as `./index`.
|
|
33
|
+
* The `*WithOptions` variants have no native equivalent (the Rust
|
|
34
|
+
* core's options live behind different entry points), so they always
|
|
35
|
+
* use the TypeScript implementation.
|
|
36
|
+
*
|
|
37
|
+
* Every function here never throws on bad input, like `./index`.
|
|
38
|
+
*/
|
|
39
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
40
|
+
if (k2 === undefined) k2 = k;
|
|
41
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
42
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
43
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
44
|
+
}
|
|
45
|
+
Object.defineProperty(o, k2, desc);
|
|
46
|
+
}) : (function(o, m, k, k2) {
|
|
47
|
+
if (k2 === undefined) k2 = k;
|
|
48
|
+
o[k2] = m[k];
|
|
49
|
+
}));
|
|
50
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
51
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
52
|
+
}) : function(o, v) {
|
|
53
|
+
o["default"] = v;
|
|
54
|
+
});
|
|
55
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
56
|
+
var ownKeys = function(o) {
|
|
57
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
58
|
+
var ar = [];
|
|
59
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
60
|
+
return ar;
|
|
61
|
+
};
|
|
62
|
+
return ownKeys(o);
|
|
63
|
+
};
|
|
64
|
+
return function (mod) {
|
|
65
|
+
if (mod && mod.__esModule) return mod;
|
|
66
|
+
var result = {};
|
|
67
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
68
|
+
__setModuleDefault(result, mod);
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
})();
|
|
72
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
73
|
+
exports.noSpacesHyphensOptions = exports.lenientOptions = exports.defaultOptions = exports.formatMobileWithOptions = exports.validateGstinWithOptions = exports.validateAadhaarWithOptions = exports.validatePanWithOptions = exports.validateMobileWithOptions = void 0;
|
|
74
|
+
exports.isNativeAvailable = isNativeAvailable;
|
|
75
|
+
exports.backend = backend;
|
|
76
|
+
exports.validatePan = validatePan;
|
|
77
|
+
exports.validateAadhaar = validateAadhaar;
|
|
78
|
+
exports.validateGstin = validateGstin;
|
|
79
|
+
exports.validateIfsc = validateIfsc;
|
|
80
|
+
exports.validateUpi = validateUpi;
|
|
81
|
+
exports.validateMobile = validateMobile;
|
|
82
|
+
exports.validatePincode = validatePincode;
|
|
83
|
+
exports.validateTan = validateTan;
|
|
84
|
+
exports.validateCin = validateCin;
|
|
85
|
+
exports.validateLlpin = validateLlpin;
|
|
86
|
+
exports.validateVoterId = validateVoterId;
|
|
87
|
+
exports.validateEpic = validateEpic;
|
|
88
|
+
exports.validateVehicle = validateVehicle;
|
|
89
|
+
exports.validateVehicleRegistration = validateVehicleRegistration;
|
|
90
|
+
exports.detectType = detectType;
|
|
91
|
+
exports.detect = detect;
|
|
92
|
+
exports.validateMany = validateMany;
|
|
93
|
+
exports.formatMobile = formatMobile;
|
|
94
|
+
exports.formatPan = formatPan;
|
|
95
|
+
exports.formatGstin = formatGstin;
|
|
96
|
+
exports.maskAadhaar = maskAadhaar;
|
|
97
|
+
exports.maskPan = maskPan;
|
|
98
|
+
exports.maskMobile = maskMobile;
|
|
99
|
+
exports.generatePan = generatePan;
|
|
100
|
+
exports.generateAadhaar = generateAadhaar;
|
|
101
|
+
exports.generateGstin = generateGstin;
|
|
102
|
+
exports.generateMobile = generateMobile;
|
|
103
|
+
const node_module_1 = require("node:module");
|
|
104
|
+
const node_fs_1 = require("node:fs");
|
|
105
|
+
const node_path_1 = require("node:path");
|
|
106
|
+
const tsImpl = __importStar(require("./index"));
|
|
107
|
+
const nativeRequire = (0, node_module_1.createRequire)((0, node_path_1.join)(process.cwd(), "package.json"));
|
|
108
|
+
function bindingCandidates() {
|
|
109
|
+
const envPath = process.env.INDYCHECK_NATIVE_PATH;
|
|
110
|
+
// An explicit path is authoritative: if it cannot be loaded, the
|
|
111
|
+
// addon is treated as absent (TypeScript fallback) instead of
|
|
112
|
+
// silently loading a different binary.
|
|
113
|
+
if (envPath)
|
|
114
|
+
return [envPath];
|
|
115
|
+
const candidates = [];
|
|
116
|
+
// CommonJS: relative to this file (dist/ or src/ under packages/js).
|
|
117
|
+
if (typeof __dirname !== "undefined") {
|
|
118
|
+
candidates.push((0, node_path_1.join)(__dirname, "..", "..", "..", "crates", "indycheck-napi", "index.js"));
|
|
119
|
+
}
|
|
120
|
+
// Walk up from the working directory to a repo checkout (covers
|
|
121
|
+
// vitest, where __dirname is not defined, and `npm test` from anywhere).
|
|
122
|
+
let dir = process.cwd();
|
|
123
|
+
for (let i = 0; i < 6; i++) {
|
|
124
|
+
candidates.push((0, node_path_1.join)(dir, "crates", "indycheck-napi", "index.js"));
|
|
125
|
+
const parent = (0, node_path_1.dirname)(dir);
|
|
126
|
+
if (parent === dir)
|
|
127
|
+
break;
|
|
128
|
+
dir = parent;
|
|
129
|
+
}
|
|
130
|
+
return [...new Set(candidates)].filter((c) => (0, node_fs_1.existsSync)(c));
|
|
131
|
+
}
|
|
132
|
+
let binding = null;
|
|
133
|
+
let attempted = false;
|
|
134
|
+
function loadBinding() {
|
|
135
|
+
if (attempted)
|
|
136
|
+
return binding;
|
|
137
|
+
attempted = true;
|
|
138
|
+
for (const candidate of bindingCandidates()) {
|
|
139
|
+
try {
|
|
140
|
+
const mod = nativeRequire(candidate);
|
|
141
|
+
if (mod &&
|
|
142
|
+
typeof mod.validatePan === "function" &&
|
|
143
|
+
typeof mod.validateVehicle === "function" &&
|
|
144
|
+
typeof mod.detect === "function" &&
|
|
145
|
+
typeof mod.validateMany === "function") {
|
|
146
|
+
binding = mod;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Not built / not loadable here — try the next candidate.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return binding;
|
|
155
|
+
}
|
|
156
|
+
/** `true` when the native addon loaded and can be used. */
|
|
157
|
+
function isNativeAvailable() {
|
|
158
|
+
return loadBinding() !== null;
|
|
159
|
+
}
|
|
160
|
+
/** Which backend the functions below are currently using. */
|
|
161
|
+
function backend() {
|
|
162
|
+
return loadBinding() !== null ? "native" : "typescript";
|
|
163
|
+
}
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Call helpers
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
/** Rust `ValidationResult::err` omits `parsed` from the JSON entirely
|
|
168
|
+
* (serde `skip_serializing_if`), while the TS mirror sets it to
|
|
169
|
+
* `null` — normalise so both backends return identical shapes. */
|
|
170
|
+
function normalizeResult(r) {
|
|
171
|
+
if (r.parsed === undefined)
|
|
172
|
+
r.parsed = null;
|
|
173
|
+
return r;
|
|
174
|
+
}
|
|
175
|
+
/** Run a native call that returns a JSON `ValidationResult`; on any
|
|
176
|
+
* failure (missing addon, bad JSON) use the TypeScript fallback. */
|
|
177
|
+
function callJson(fn, fallback) {
|
|
178
|
+
const b = loadBinding();
|
|
179
|
+
if (b === null)
|
|
180
|
+
return fallback();
|
|
181
|
+
try {
|
|
182
|
+
return normalizeResult(JSON.parse(fn(b)));
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return fallback();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Run a native call returning a plain value; fall back on any failure. */
|
|
189
|
+
function callPlain(fn, fallback) {
|
|
190
|
+
const b = loadBinding();
|
|
191
|
+
if (b === null)
|
|
192
|
+
return fallback();
|
|
193
|
+
try {
|
|
194
|
+
return fn(b);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return fallback();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** Native validator for a `detect` type string, or null for "unknown". */
|
|
201
|
+
function validateByNativeType(b, type, input) {
|
|
202
|
+
let json;
|
|
203
|
+
switch (type) {
|
|
204
|
+
case "pan":
|
|
205
|
+
json = b.validatePan(input);
|
|
206
|
+
break;
|
|
207
|
+
case "aadhaar":
|
|
208
|
+
json = b.validateAadhaar(input);
|
|
209
|
+
break;
|
|
210
|
+
case "gstin":
|
|
211
|
+
json = b.validateGstin(input);
|
|
212
|
+
break;
|
|
213
|
+
case "ifsc":
|
|
214
|
+
json = b.validateIfsc(input);
|
|
215
|
+
break;
|
|
216
|
+
case "upi":
|
|
217
|
+
json = b.validateUpi(input);
|
|
218
|
+
break;
|
|
219
|
+
case "mobile":
|
|
220
|
+
json = b.validateMobile(input);
|
|
221
|
+
break;
|
|
222
|
+
case "pincode":
|
|
223
|
+
json = b.validatePincode(input);
|
|
224
|
+
break;
|
|
225
|
+
case "tan":
|
|
226
|
+
json = b.validateTan(input);
|
|
227
|
+
break;
|
|
228
|
+
case "cin":
|
|
229
|
+
json = b.validateCin(input);
|
|
230
|
+
break;
|
|
231
|
+
case "llpin":
|
|
232
|
+
json = b.validateLlpin(input);
|
|
233
|
+
break;
|
|
234
|
+
case "voter":
|
|
235
|
+
json = b.validateVoterId(input);
|
|
236
|
+
break;
|
|
237
|
+
case "vehicle":
|
|
238
|
+
json = b.validateVehicle(input);
|
|
239
|
+
break;
|
|
240
|
+
default:
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
return normalizeResult(JSON.parse(json));
|
|
244
|
+
}
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
// Validators — native when available, TypeScript otherwise
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
function validatePan(input) {
|
|
249
|
+
if (typeof input !== "string")
|
|
250
|
+
return tsImpl.validatePan(input);
|
|
251
|
+
return callJson((b) => b.validatePan(input), () => tsImpl.validatePan(input));
|
|
252
|
+
}
|
|
253
|
+
function validateAadhaar(input) {
|
|
254
|
+
if (typeof input !== "string")
|
|
255
|
+
return tsImpl.validateAadhaar(input);
|
|
256
|
+
return callJson((b) => b.validateAadhaar(input), () => tsImpl.validateAadhaar(input));
|
|
257
|
+
}
|
|
258
|
+
function validateGstin(input) {
|
|
259
|
+
if (typeof input !== "string")
|
|
260
|
+
return tsImpl.validateGstin(input);
|
|
261
|
+
return callJson((b) => b.validateGstin(input), () => tsImpl.validateGstin(input));
|
|
262
|
+
}
|
|
263
|
+
function validateIfsc(input) {
|
|
264
|
+
if (typeof input !== "string")
|
|
265
|
+
return tsImpl.validateIfsc(input);
|
|
266
|
+
return callJson((b) => b.validateIfsc(input), () => tsImpl.validateIfsc(input));
|
|
267
|
+
}
|
|
268
|
+
function validateUpi(input) {
|
|
269
|
+
if (typeof input !== "string")
|
|
270
|
+
return tsImpl.validateUpi(input);
|
|
271
|
+
return callJson((b) => b.validateUpi(input), () => tsImpl.validateUpi(input));
|
|
272
|
+
}
|
|
273
|
+
function validateMobile(input) {
|
|
274
|
+
if (typeof input !== "string")
|
|
275
|
+
return tsImpl.validateMobile(input);
|
|
276
|
+
return callJson((b) => b.validateMobile(input), () => tsImpl.validateMobile(input));
|
|
277
|
+
}
|
|
278
|
+
function validatePincode(input) {
|
|
279
|
+
if (typeof input !== "string")
|
|
280
|
+
return tsImpl.validatePincode(input);
|
|
281
|
+
return callJson((b) => b.validatePincode(input), () => tsImpl.validatePincode(input));
|
|
282
|
+
}
|
|
283
|
+
function validateTan(input) {
|
|
284
|
+
if (typeof input !== "string")
|
|
285
|
+
return tsImpl.validateTan(input);
|
|
286
|
+
return callJson((b) => b.validateTan(input), () => tsImpl.validateTan(input));
|
|
287
|
+
}
|
|
288
|
+
function validateCin(input) {
|
|
289
|
+
if (typeof input !== "string")
|
|
290
|
+
return tsImpl.validateCin(input);
|
|
291
|
+
return callJson((b) => b.validateCin(input), () => tsImpl.validateCin(input));
|
|
292
|
+
}
|
|
293
|
+
function validateLlpin(input) {
|
|
294
|
+
if (typeof input !== "string")
|
|
295
|
+
return tsImpl.validateLlpin(input);
|
|
296
|
+
return callJson((b) => b.validateLlpin(input), () => tsImpl.validateLlpin(input));
|
|
297
|
+
}
|
|
298
|
+
function validateVoterId(input) {
|
|
299
|
+
if (typeof input !== "string")
|
|
300
|
+
return tsImpl.validateVoterId(input);
|
|
301
|
+
return callJson((b) => b.validateVoterId(input), () => tsImpl.validateVoterId(input));
|
|
302
|
+
}
|
|
303
|
+
/** Alias for `validateVoterId`: EPIC is the name printed on the card. */
|
|
304
|
+
function validateEpic(input) {
|
|
305
|
+
return validateVoterId(input);
|
|
306
|
+
}
|
|
307
|
+
function validateVehicle(input) {
|
|
308
|
+
if (typeof input !== "string")
|
|
309
|
+
return tsImpl.validateVehicle(input);
|
|
310
|
+
return callJson((b) => b.validateVehicle(input), () => tsImpl.validateVehicle(input));
|
|
311
|
+
}
|
|
312
|
+
/** Alias for `validateVehicle`. */
|
|
313
|
+
function validateVehicleRegistration(input) {
|
|
314
|
+
return validateVehicle(input);
|
|
315
|
+
}
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// detect / validateMany — shapes rebuilt from the native primitives
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
/** The Rust `detect` string for a trimmed input. */
|
|
320
|
+
function detectType(input) {
|
|
321
|
+
const b = loadBinding();
|
|
322
|
+
if (b === null)
|
|
323
|
+
return tsImpl.detectType(input);
|
|
324
|
+
try {
|
|
325
|
+
return b.detect(input);
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
return tsImpl.detectType(input);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function detect(input) {
|
|
332
|
+
if (typeof input !== "string")
|
|
333
|
+
return tsImpl.detect(input);
|
|
334
|
+
const b = loadBinding();
|
|
335
|
+
if (b === null)
|
|
336
|
+
return tsImpl.detect(input);
|
|
337
|
+
try {
|
|
338
|
+
const type = b.detect(input);
|
|
339
|
+
const trimmed = input.trim();
|
|
340
|
+
if (type === "unknown") {
|
|
341
|
+
return {
|
|
342
|
+
valid: false,
|
|
343
|
+
code: "UNKNOWN_TYPE",
|
|
344
|
+
reason_en: "Could not detect the type of this input",
|
|
345
|
+
reason_hi: "Is input ka type pehchana nahi ja saka",
|
|
346
|
+
parsed: { type: "unknown", value: trimmed, result: null },
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
const result = validateByNativeType(b, type, input);
|
|
350
|
+
if (result === null)
|
|
351
|
+
return tsImpl.detect(input);
|
|
352
|
+
return {
|
|
353
|
+
valid: result.valid,
|
|
354
|
+
code: result.code,
|
|
355
|
+
reason_en: result.reason_en,
|
|
356
|
+
reason_hi: result.reason_hi,
|
|
357
|
+
parsed: { type, value: trimmed, result },
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return tsImpl.detect(input);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
function validateMany(inputs) {
|
|
365
|
+
if (!Array.isArray(inputs) || inputs.length === 0) {
|
|
366
|
+
return tsImpl.validateMany(inputs);
|
|
367
|
+
}
|
|
368
|
+
if (!inputs.every((item) => typeof item === "string")) {
|
|
369
|
+
// Typed `{ value, type }` entries and non-strings are a
|
|
370
|
+
// TypeScript-wrapper feature — the native batch takes strings only.
|
|
371
|
+
return tsImpl.validateMany(inputs);
|
|
372
|
+
}
|
|
373
|
+
const b = loadBinding();
|
|
374
|
+
if (b === null)
|
|
375
|
+
return tsImpl.validateMany(inputs);
|
|
376
|
+
try {
|
|
377
|
+
const results = JSON.parse(b.validateMany(inputs));
|
|
378
|
+
const items = inputs.map((item, i) => {
|
|
379
|
+
const result = normalizeResult(results[i]);
|
|
380
|
+
const type = b.detect(item);
|
|
381
|
+
return {
|
|
382
|
+
input: item,
|
|
383
|
+
type: type === "unknown" ? null : type,
|
|
384
|
+
valid: result.valid,
|
|
385
|
+
code: result.code,
|
|
386
|
+
reason_en: result.reason_en,
|
|
387
|
+
reason_hi: result.reason_hi,
|
|
388
|
+
parsed: result.parsed,
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
const validCount = items.filter((r) => r.valid).length;
|
|
392
|
+
const invalidCount = items.length - validCount;
|
|
393
|
+
const parsed = {
|
|
394
|
+
results: items,
|
|
395
|
+
total: items.length,
|
|
396
|
+
validCount,
|
|
397
|
+
invalidCount,
|
|
398
|
+
};
|
|
399
|
+
if (invalidCount === 0) {
|
|
400
|
+
return {
|
|
401
|
+
valid: true,
|
|
402
|
+
code: "VALID",
|
|
403
|
+
reason_en: "All inputs are valid.",
|
|
404
|
+
reason_hi: "Saare input sahi hain.",
|
|
405
|
+
parsed,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
valid: false,
|
|
410
|
+
code: "SOME_INVALID",
|
|
411
|
+
reason_en: "Some inputs are invalid.",
|
|
412
|
+
reason_hi: "Kuch input galat hain.",
|
|
413
|
+
parsed,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return tsImpl.validateMany(inputs);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
// Format / mask — same contracts as ./index
|
|
422
|
+
// ---------------------------------------------------------------------------
|
|
423
|
+
function formatMobile(input) {
|
|
424
|
+
// Same contract as validateMobile (see ./index).
|
|
425
|
+
return validateMobile(input);
|
|
426
|
+
}
|
|
427
|
+
function formatPan(input) {
|
|
428
|
+
if (typeof input !== "string")
|
|
429
|
+
return tsImpl.formatPan(input);
|
|
430
|
+
return callPlain((b) => b.formatPan(input), () => tsImpl.formatPan(input));
|
|
431
|
+
}
|
|
432
|
+
function formatGstin(input) {
|
|
433
|
+
if (typeof input !== "string")
|
|
434
|
+
return tsImpl.formatGstin(input);
|
|
435
|
+
return callPlain((b) => b.formatGstin(input), () => tsImpl.formatGstin(input));
|
|
436
|
+
}
|
|
437
|
+
function maskAadhaar(input) {
|
|
438
|
+
// Same contract as validateAadhaar (see ./index) — NOT the Rust
|
|
439
|
+
// `mask_aadhaar` string function, which masks any 12-digit string.
|
|
440
|
+
return validateAadhaar(input);
|
|
441
|
+
}
|
|
442
|
+
function maskPan(input) {
|
|
443
|
+
if (typeof input !== "string")
|
|
444
|
+
return tsImpl.maskPan(input);
|
|
445
|
+
return callPlain((b) => b.maskPan(input), () => tsImpl.maskPan(input));
|
|
446
|
+
}
|
|
447
|
+
function maskMobile(input) {
|
|
448
|
+
if (typeof input !== "string")
|
|
449
|
+
return tsImpl.maskMobile(input);
|
|
450
|
+
return callPlain((b) => b.maskMobile(input), () => tsImpl.maskMobile(input));
|
|
451
|
+
}
|
|
452
|
+
// ---------------------------------------------------------------------------
|
|
453
|
+
// Mock test-data generators — TEST DATA ONLY, never real issued IDs
|
|
454
|
+
// ---------------------------------------------------------------------------
|
|
455
|
+
function generatePan(entity) {
|
|
456
|
+
const code = typeof entity === "string" && entity.length > 0 ? entity : "P";
|
|
457
|
+
return callPlain((b) => b.generatePan(code), () => tsImpl.generatePan(entity));
|
|
458
|
+
}
|
|
459
|
+
function generateAadhaar() {
|
|
460
|
+
return callPlain((b) => b.generateAadhaar(), () => tsImpl.generateAadhaar());
|
|
461
|
+
}
|
|
462
|
+
function generateGstin(stateCode) {
|
|
463
|
+
const code = typeof stateCode === "string" ? stateCode : "18";
|
|
464
|
+
return callPlain((b) => b.generateGstin(code), () => tsImpl.generateGstin(stateCode));
|
|
465
|
+
}
|
|
466
|
+
function generateMobile() {
|
|
467
|
+
return callPlain((b) => b.generateMobile(), () => tsImpl.generateMobile());
|
|
468
|
+
}
|
|
469
|
+
// ---------------------------------------------------------------------------
|
|
470
|
+
// Options variants — no native equivalent; always TypeScript
|
|
471
|
+
// ---------------------------------------------------------------------------
|
|
472
|
+
exports.validateMobileWithOptions = tsImpl.validateMobileWithOptions;
|
|
473
|
+
exports.validatePanWithOptions = tsImpl.validatePanWithOptions;
|
|
474
|
+
exports.validateAadhaarWithOptions = tsImpl.validateAadhaarWithOptions;
|
|
475
|
+
exports.validateGstinWithOptions = tsImpl.validateGstinWithOptions;
|
|
476
|
+
exports.formatMobileWithOptions = tsImpl.formatMobileWithOptions;
|
|
477
|
+
exports.defaultOptions = tsImpl.defaultOptions;
|
|
478
|
+
exports.lenientOptions = tsImpl.lenientOptions;
|
|
479
|
+
exports.noSpacesHyphensOptions = tsImpl.noSpacesHyphensOptions;
|
|
480
|
+
exports.default = {
|
|
481
|
+
backend,
|
|
482
|
+
isNativeAvailable,
|
|
483
|
+
validateMobile,
|
|
484
|
+
validatePan,
|
|
485
|
+
validateAadhaar,
|
|
486
|
+
validateGstin,
|
|
487
|
+
validateIfsc,
|
|
488
|
+
validateUpi,
|
|
489
|
+
validatePincode,
|
|
490
|
+
validateTan,
|
|
491
|
+
validateCin,
|
|
492
|
+
validateLlpin,
|
|
493
|
+
validateVoterId,
|
|
494
|
+
validateEpic,
|
|
495
|
+
validateVehicle,
|
|
496
|
+
validateVehicleRegistration,
|
|
497
|
+
validateMobileWithOptions: exports.validateMobileWithOptions,
|
|
498
|
+
validatePanWithOptions: exports.validatePanWithOptions,
|
|
499
|
+
validateAadhaarWithOptions: exports.validateAadhaarWithOptions,
|
|
500
|
+
validateGstinWithOptions: exports.validateGstinWithOptions,
|
|
501
|
+
formatMobile,
|
|
502
|
+
formatMobileWithOptions: exports.formatMobileWithOptions,
|
|
503
|
+
formatPan,
|
|
504
|
+
formatGstin,
|
|
505
|
+
maskAadhaar,
|
|
506
|
+
maskPan,
|
|
507
|
+
maskMobile,
|
|
508
|
+
generatePan,
|
|
509
|
+
generateAadhaar,
|
|
510
|
+
generateGstin,
|
|
511
|
+
generateMobile,
|
|
512
|
+
defaultOptions: exports.defaultOptions,
|
|
513
|
+
lenientOptions: exports.lenientOptions,
|
|
514
|
+
noSpacesHyphensOptions: exports.noSpacesHyphensOptions,
|
|
515
|
+
detect,
|
|
516
|
+
detectType,
|
|
517
|
+
validateMany,
|
|
518
|
+
};
|
package/package.json
CHANGED
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsc -p tsconfig.build.json",
|
|
36
|
+
"native:build": "npm --prefix ../../crates/indycheck-napi run build",
|
|
36
37
|
"test": "vitest run",
|
|
37
38
|
"typecheck": "tsc --noEmit"
|
|
38
39
|
},
|
|
39
40
|
"types": "dist/index.d.ts",
|
|
40
|
-
"version": "0.2.
|
|
41
|
+
"version": "0.2.1"
|
|
41
42
|
}
|