@wipsquare/vies-vat-check 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 +21 -0
- package/README.md +310 -0
- package/dist/src/client.d.ts +32 -0
- package/dist/src/client.js +106 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/errors.d.ts +16 -0
- package/dist/src/errors.js +35 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +51 -0
- package/dist/src/index.js +114 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/retry.d.ts +5 -0
- package/dist/src/retry.js +32 -0
- package/dist/src/retry.js.map +1 -0
- package/dist/src/status.d.ts +10 -0
- package/dist/src/status.js +87 -0
- package/dist/src/status.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wipsquare
|
|
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,310 @@
|
|
|
1
|
+
# @wipsquare/vies-vat-check
|
|
2
|
+
|
|
3
|
+
TypeScript client for validating EU VAT numbers with the VIES API.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 20 or later
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @wipsquare/vies-vat-check
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Validate EU VAT numbers with VIES
|
|
18
|
+
- Pass VAT input either as separate country/code values or as a full VAT string
|
|
19
|
+
- Switch between production and test mode with a configured client
|
|
20
|
+
- Automatic retries with exponential backoff
|
|
21
|
+
- Check VIES service status
|
|
22
|
+
- Typed errors
|
|
23
|
+
- TypeScript support included
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Validate a VAT number with separate country code and number
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { checkVat } from '@wipsquare/vies-vat-check';
|
|
31
|
+
|
|
32
|
+
const result = await checkVat({
|
|
33
|
+
countryCode: 'RO',
|
|
34
|
+
vatNumber: '47366939'
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
console.log(result);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Validate a full VAT number
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { checkVat } from '@wipsquare/vies-vat-check';
|
|
44
|
+
|
|
45
|
+
const result = await checkVat({
|
|
46
|
+
vatNumber: 'RO47366939'
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log(result);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Example response:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
{
|
|
56
|
+
countryCode: 'RO',
|
|
57
|
+
vatNumber: '47366939',
|
|
58
|
+
valid: true,
|
|
59
|
+
requestDate: '2026-04-03T18:37:16.613Z',
|
|
60
|
+
requestIdentifier: '',
|
|
61
|
+
name: 'WIPSQUARE S.R.L.',
|
|
62
|
+
address: 'ORŞ. CISNĂDIE 555300 STR. MARCEL IANCU Nr. 3 Sc. A Et. PARTER Ap. 3',
|
|
63
|
+
traderName: '---',
|
|
64
|
+
traderStreet: '---',
|
|
65
|
+
traderPostalCode: '---',
|
|
66
|
+
traderCity: '---',
|
|
67
|
+
traderCompanyType: '---',
|
|
68
|
+
traderNameMatch: 'NOT_PROCESSED',
|
|
69
|
+
traderStreetMatch: 'NOT_PROCESSED',
|
|
70
|
+
traderPostalCodeMatch: 'NOT_PROCESSED',
|
|
71
|
+
traderCityMatch: 'NOT_PROCESSED',
|
|
72
|
+
traderCompanyTypeMatch: 'NOT_PROCESSED'
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Use a configured client
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { createViesClient } from '@wipsquare/vies-vat-check';
|
|
80
|
+
|
|
81
|
+
const vies = createViesClient({
|
|
82
|
+
mode: 'test',
|
|
83
|
+
timeoutMs: 10000
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const result = await vies.checkVat({
|
|
87
|
+
vatNumber: 'DE100'
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log(result);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Retry on failure
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { createViesClient } from '@wipsquare/vies-vat-check';
|
|
97
|
+
|
|
98
|
+
const vies = createViesClient({
|
|
99
|
+
retries: 2,
|
|
100
|
+
retryDelayMs: 500
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const result = await vies.checkVat({
|
|
104
|
+
vatNumber: 'RO47366939'
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
console.log(result);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This retries up to 2 times with exponential backoff: 500ms after the first failure, 1000ms after the second. Retries apply to timeouts, network errors, and 5xx responses. Client errors (4xx) and malformed responses are not retried.
|
|
111
|
+
|
|
112
|
+
### Check VIES service status
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { checkStatus } from '@wipsquare/vies-vat-check';
|
|
116
|
+
|
|
117
|
+
const result = await checkStatus();
|
|
118
|
+
|
|
119
|
+
console.log(result);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Check VIES service status with a configured client
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { createViesClient } from '@wipsquare/vies-vat-check';
|
|
126
|
+
|
|
127
|
+
const vies = createViesClient({
|
|
128
|
+
mode: 'prod',
|
|
129
|
+
timeoutMs: 10000
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const result = await vies.checkStatus();
|
|
133
|
+
|
|
134
|
+
console.log(result);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Example response:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
{
|
|
141
|
+
available: true,
|
|
142
|
+
countries: [
|
|
143
|
+
{ countryCode: 'RO', availability: 'Available' },
|
|
144
|
+
{ countryCode: 'DE', availability: 'Unavailable' }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## API
|
|
150
|
+
|
|
151
|
+
### `checkVat(input)`
|
|
152
|
+
|
|
153
|
+
Validates a VAT number through the VIES API using the default client.
|
|
154
|
+
|
|
155
|
+
Supported input forms:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
checkVat({
|
|
159
|
+
countryCode: 'RO',
|
|
160
|
+
vatNumber: '47366939'
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
checkVat({
|
|
166
|
+
vatNumber: 'RO47366939'
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Returns
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
{
|
|
174
|
+
countryCode: string;
|
|
175
|
+
vatNumber: string;
|
|
176
|
+
valid: boolean;
|
|
177
|
+
requestDate?: string;
|
|
178
|
+
requestIdentifier?: string;
|
|
179
|
+
name?: string;
|
|
180
|
+
address?: string;
|
|
181
|
+
traderName?: string;
|
|
182
|
+
traderStreet?: string;
|
|
183
|
+
traderPostalCode?: string;
|
|
184
|
+
traderCity?: string;
|
|
185
|
+
traderCompanyType?: string;
|
|
186
|
+
traderNameMatch?: 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
187
|
+
traderStreetMatch?: 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
188
|
+
traderPostalCodeMatch?: 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
189
|
+
traderCityMatch?: 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
190
|
+
traderCompanyTypeMatch?: 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### `checkStatus()`
|
|
195
|
+
|
|
196
|
+
Checks VIES system availability using the default client.
|
|
197
|
+
|
|
198
|
+
#### Returns
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
{
|
|
202
|
+
available: boolean;
|
|
203
|
+
countries: Array<{
|
|
204
|
+
countryCode: string;
|
|
205
|
+
availability: 'Available' | 'Unavailable' | 'Monitoring Disabled';
|
|
206
|
+
}>;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### `createViesClient(config?)`
|
|
211
|
+
|
|
212
|
+
Creates a configured VIES client.
|
|
213
|
+
|
|
214
|
+
#### Config
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
{
|
|
218
|
+
mode?: 'prod' | 'test'; // default: 'prod'
|
|
219
|
+
timeoutMs?: number; // default: 10000
|
|
220
|
+
retries?: number; // default: 0 (no retries)
|
|
221
|
+
retryDelayMs?: number; // default: 500
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Client methods
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
{
|
|
229
|
+
checkVat(input: { countryCode: string; vatNumber: string } | { vatNumber: string }): Promise<CheckVatResult>;
|
|
230
|
+
checkStatus(): Promise<CheckStatusResult>;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Notes
|
|
235
|
+
|
|
236
|
+
- `countryCode` is normalized to uppercase
|
|
237
|
+
- spaces are removed from `vatNumber` before the request is sent
|
|
238
|
+
- when using the full VAT format, the first two characters are treated as the country code
|
|
239
|
+
- some fields such as `name`, `address`, and trader details depend on what VIES returns for that VAT number and country
|
|
240
|
+
- the package returns the country code, not a full country name
|
|
241
|
+
- retries use exponential backoff: `retryDelayMs * 2^attempt` (e.g. 500ms, 1000ms, 2000ms)
|
|
242
|
+
- retries apply to timeouts, network errors, and 5xx HTTP responses
|
|
243
|
+
- 4xx responses and malformed responses are not retried
|
|
244
|
+
|
|
245
|
+
## Errors
|
|
246
|
+
|
|
247
|
+
The package can throw these error types:
|
|
248
|
+
|
|
249
|
+
- `ViesError` — base class for all errors
|
|
250
|
+
- `ViesHttpError` — non-2xx response from VIES (exposes `.status`)
|
|
251
|
+
- `ViesNetworkError` — fetch failed (exposes `.cause`)
|
|
252
|
+
- `ViesResponseError` — response body could not be parsed
|
|
253
|
+
- `ViesTimeoutError` — request exceeded `timeoutMs`
|
|
254
|
+
|
|
255
|
+
All errors extend `ViesError`, so you can catch broadly or narrowly:
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
import {
|
|
259
|
+
checkVat,
|
|
260
|
+
ViesError,
|
|
261
|
+
ViesHttpError,
|
|
262
|
+
ViesTimeoutError
|
|
263
|
+
} from '@wipsquare/vies-vat-check';
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
await checkVat({
|
|
267
|
+
vatNumber: 'RO47366939'
|
|
268
|
+
});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
if (error instanceof ViesTimeoutError) {
|
|
271
|
+
console.error('Request timed out');
|
|
272
|
+
} else if (error instanceof ViesHttpError) {
|
|
273
|
+
console.error(`HTTP error: ${error.status}`);
|
|
274
|
+
} else if (error instanceof ViesError) {
|
|
275
|
+
console.error('VIES error:', error.message);
|
|
276
|
+
} else {
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Development
|
|
283
|
+
|
|
284
|
+
Install dependencies:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
npm install
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Run type checking:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm run check
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Run tests:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
npm test
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Build:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
npm run build
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## License
|
|
309
|
+
|
|
310
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type ViesMode = 'prod' | 'test';
|
|
2
|
+
export interface ViesClientConfig {
|
|
3
|
+
mode?: ViesMode;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
retries?: number;
|
|
6
|
+
retryDelayMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ViesApiRequest {
|
|
9
|
+
countryCode: string;
|
|
10
|
+
vatNumber: string;
|
|
11
|
+
}
|
|
12
|
+
export type ViesMatch = 'VALID' | 'INVALID' | 'NOT_PROCESSED';
|
|
13
|
+
export interface ViesApiResponse {
|
|
14
|
+
valid: boolean;
|
|
15
|
+
countryCode?: string;
|
|
16
|
+
vatNumber?: string;
|
|
17
|
+
requestDate?: string;
|
|
18
|
+
requestIdentifier?: string;
|
|
19
|
+
name?: string;
|
|
20
|
+
address?: string;
|
|
21
|
+
traderName?: string;
|
|
22
|
+
traderStreet?: string;
|
|
23
|
+
traderPostalCode?: string;
|
|
24
|
+
traderCity?: string;
|
|
25
|
+
traderCompanyType?: string;
|
|
26
|
+
traderNameMatch?: ViesMatch;
|
|
27
|
+
traderStreetMatch?: ViesMatch;
|
|
28
|
+
traderPostalCodeMatch?: ViesMatch;
|
|
29
|
+
traderCityMatch?: ViesMatch;
|
|
30
|
+
traderCompanyTypeMatch?: ViesMatch;
|
|
31
|
+
}
|
|
32
|
+
export declare function postCheckVat(input: ViesApiRequest, config?: ViesClientConfig): Promise<ViesApiResponse>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { ViesHttpError, ViesNetworkError, ViesResponseError, ViesTimeoutError } from './errors.js';
|
|
3
|
+
import { withRetry } from './retry.js';
|
|
4
|
+
const ENDPOINTS = {
|
|
5
|
+
prod: 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number',
|
|
6
|
+
test: 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-test-service'
|
|
7
|
+
};
|
|
8
|
+
export async function postCheckVat(input, config = {}) {
|
|
9
|
+
const retries = config.retries ?? 0;
|
|
10
|
+
const retryDelayMs = config.retryDelayMs ?? 500;
|
|
11
|
+
return withRetry(() => executeCheckVat(input, config), {
|
|
12
|
+
retries,
|
|
13
|
+
retryDelayMs
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function executeCheckVat(input, config) {
|
|
17
|
+
const mode = config.mode ?? 'prod';
|
|
18
|
+
const timeoutMs = config.timeoutMs ?? 10_000;
|
|
19
|
+
const controller = new AbortController();
|
|
20
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(ENDPOINTS[mode], {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'content-type': 'application/json',
|
|
26
|
+
accept: 'application/json'
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify(input),
|
|
29
|
+
signal: controller.signal
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new ViesHttpError(response.status);
|
|
33
|
+
}
|
|
34
|
+
const json = await response.json();
|
|
35
|
+
return parseViesApiResponse(json);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
39
|
+
throw new ViesTimeoutError(timeoutMs);
|
|
40
|
+
}
|
|
41
|
+
if (error instanceof ViesHttpError || error instanceof ViesResponseError) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
throw new ViesNetworkError('VIES network request failed', error);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
clearTimeout(timeoutId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function parseViesApiResponse(value) {
|
|
51
|
+
if (!value || typeof value !== 'object') {
|
|
52
|
+
throw new ViesResponseError();
|
|
53
|
+
}
|
|
54
|
+
const data = value;
|
|
55
|
+
if (typeof data.valid !== 'boolean') {
|
|
56
|
+
throw new ViesResponseError('VIES API response is missing a valid boolean');
|
|
57
|
+
}
|
|
58
|
+
const result = {
|
|
59
|
+
valid: data.valid
|
|
60
|
+
};
|
|
61
|
+
if (typeof data.countryCode === 'string') {
|
|
62
|
+
result.countryCode = data.countryCode;
|
|
63
|
+
}
|
|
64
|
+
if (typeof data.vatNumber === 'string') {
|
|
65
|
+
result.vatNumber = data.vatNumber;
|
|
66
|
+
}
|
|
67
|
+
if (typeof data.requestDate === 'string') {
|
|
68
|
+
result.requestDate = data.requestDate;
|
|
69
|
+
}
|
|
70
|
+
if (typeof data.requestIdentifier === 'string') {
|
|
71
|
+
result.requestIdentifier = data.requestIdentifier;
|
|
72
|
+
}
|
|
73
|
+
if (typeof data.name === 'string') {
|
|
74
|
+
result.name = data.name;
|
|
75
|
+
}
|
|
76
|
+
if (typeof data.address === 'string') {
|
|
77
|
+
result.address = data.address;
|
|
78
|
+
}
|
|
79
|
+
if (typeof data.traderName === 'string') {
|
|
80
|
+
result.traderName = data.traderName;
|
|
81
|
+
}
|
|
82
|
+
if (typeof data.traderStreet === 'string') {
|
|
83
|
+
result.traderStreet = data.traderStreet;
|
|
84
|
+
}
|
|
85
|
+
if (typeof data.traderPostalCode === 'string') {
|
|
86
|
+
result.traderPostalCode = data.traderPostalCode;
|
|
87
|
+
}
|
|
88
|
+
if (typeof data.traderCity === 'string') {
|
|
89
|
+
result.traderCity = data.traderCity;
|
|
90
|
+
}
|
|
91
|
+
if (typeof data.traderCompanyType === 'string') {
|
|
92
|
+
result.traderCompanyType = data.traderCompanyType;
|
|
93
|
+
}
|
|
94
|
+
addMatchField(result, 'traderNameMatch', data.traderNameMatch);
|
|
95
|
+
addMatchField(result, 'traderStreetMatch', data.traderStreetMatch);
|
|
96
|
+
addMatchField(result, 'traderPostalCodeMatch', data.traderPostalCodeMatch);
|
|
97
|
+
addMatchField(result, 'traderCityMatch', data.traderCityMatch);
|
|
98
|
+
addMatchField(result, 'traderCompanyTypeMatch', data.traderCompanyTypeMatch);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
function addMatchField(result, key, value) {
|
|
102
|
+
if (value === 'VALID' || value === 'INVALID' || value === 'NOT_PROCESSED') {
|
|
103
|
+
result[key] = value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class ViesError extends Error {
|
|
2
|
+
constructor(message: string, options?: ErrorOptions);
|
|
3
|
+
}
|
|
4
|
+
export declare class ViesTimeoutError extends ViesError {
|
|
5
|
+
constructor(timeoutMs: number);
|
|
6
|
+
}
|
|
7
|
+
export declare class ViesHttpError extends ViesError {
|
|
8
|
+
readonly status: number;
|
|
9
|
+
constructor(status: number);
|
|
10
|
+
}
|
|
11
|
+
export declare class ViesNetworkError extends ViesError {
|
|
12
|
+
constructor(message?: string, cause?: unknown);
|
|
13
|
+
}
|
|
14
|
+
export declare class ViesResponseError extends ViesError {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
export class ViesError extends Error {
|
|
3
|
+
constructor(message, options) {
|
|
4
|
+
super(message, options);
|
|
5
|
+
this.name = 'ViesError';
|
|
6
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class ViesTimeoutError extends ViesError {
|
|
10
|
+
constructor(timeoutMs) {
|
|
11
|
+
super(`VIES request timed out after ${timeoutMs}ms`);
|
|
12
|
+
this.name = 'ViesTimeoutError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class ViesHttpError extends ViesError {
|
|
16
|
+
status;
|
|
17
|
+
constructor(status) {
|
|
18
|
+
super(`VIES request failed with status ${status}`);
|
|
19
|
+
this.name = 'ViesHttpError';
|
|
20
|
+
this.status = status;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class ViesNetworkError extends ViesError {
|
|
24
|
+
constructor(message = 'VIES network request failed', cause) {
|
|
25
|
+
super(message, { cause });
|
|
26
|
+
this.name = 'ViesNetworkError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class ViesResponseError extends ViesError {
|
|
30
|
+
constructor(message = 'Invalid response from VIES API') {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = 'ViesResponseError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAEhB,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAAsB;QACjD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAC7C,YAAY,SAAiB;QAC3B,KAAK,CAAC,gCAAgC,SAAS,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1B,MAAM,CAAS;IAE/B,YAAY,MAAc;QACxB,KAAK,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAC7C,YAAY,OAAO,GAAG,6BAA6B,EAAE,KAAe;QAClE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IAC9C,YAAY,OAAO,GAAG,gCAAgC;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type ViesClientConfig, type ViesMode, type ViesMatch } from './client.js';
|
|
2
|
+
import { type CheckStatusResult, type CountryStatus } from './status.js';
|
|
3
|
+
export type { ViesMode, ViesClientConfig, ViesMatch };
|
|
4
|
+
export type { CheckStatusResult, CountryStatus };
|
|
5
|
+
export { ViesError, ViesHttpError, ViesNetworkError, ViesResponseError, ViesTimeoutError } from './errors.js';
|
|
6
|
+
export interface CheckVatInputSeparate {
|
|
7
|
+
countryCode: string;
|
|
8
|
+
vatNumber: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CheckVatInputCombined {
|
|
11
|
+
vatNumber: string;
|
|
12
|
+
}
|
|
13
|
+
export type CheckVatInput = CheckVatInputSeparate | CheckVatInputCombined;
|
|
14
|
+
export interface CheckVatResult {
|
|
15
|
+
countryCode: string;
|
|
16
|
+
vatNumber: string;
|
|
17
|
+
valid: boolean;
|
|
18
|
+
requestDate?: string;
|
|
19
|
+
requestIdentifier?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
address?: string;
|
|
22
|
+
traderName?: string;
|
|
23
|
+
traderStreet?: string;
|
|
24
|
+
traderPostalCode?: string;
|
|
25
|
+
traderCity?: string;
|
|
26
|
+
traderCompanyType?: string;
|
|
27
|
+
traderNameMatch?: ViesMatch;
|
|
28
|
+
traderStreetMatch?: ViesMatch;
|
|
29
|
+
traderPostalCodeMatch?: ViesMatch;
|
|
30
|
+
traderCityMatch?: ViesMatch;
|
|
31
|
+
traderCompanyTypeMatch?: ViesMatch;
|
|
32
|
+
}
|
|
33
|
+
export interface ViesClient {
|
|
34
|
+
checkVat(input: CheckVatInput): Promise<CheckVatResult>;
|
|
35
|
+
checkStatus(): Promise<CheckStatusResult>;
|
|
36
|
+
}
|
|
37
|
+
export declare function normalizeCountryCode(value: string): string;
|
|
38
|
+
export declare function normalizeVatNumber(value: string): string;
|
|
39
|
+
export declare function validateInput(input: CheckVatInput): void;
|
|
40
|
+
export declare function createViesClient(config?: ViesClientConfig): ViesClient;
|
|
41
|
+
/**
|
|
42
|
+
* Validate a VAT number by passing country code and numeric part separately.
|
|
43
|
+
* Example: { countryCode: 'RO', vatNumber: '47366939' }
|
|
44
|
+
*/
|
|
45
|
+
export declare function checkVat(input: CheckVatInputSeparate): Promise<CheckVatResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Validate a full VAT number including country prefix.
|
|
48
|
+
* Example: { vatNumber: 'RO47366939' }
|
|
49
|
+
*/
|
|
50
|
+
export declare function checkVat(input: CheckVatInputCombined): Promise<CheckVatResult>;
|
|
51
|
+
export declare function checkStatus(): Promise<CheckStatusResult>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { postCheckVat } from './client.js';
|
|
3
|
+
import { getCheckStatus } from './status.js';
|
|
4
|
+
export { ViesError, ViesHttpError, ViesNetworkError, ViesResponseError, ViesTimeoutError } from './errors.js';
|
|
5
|
+
const EU_COUNTRY_CODES = new Set([
|
|
6
|
+
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI',
|
|
7
|
+
'FR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO',
|
|
8
|
+
'SE', 'SI', 'SK', 'XI'
|
|
9
|
+
]);
|
|
10
|
+
export function normalizeCountryCode(value) {
|
|
11
|
+
return value.trim().toUpperCase();
|
|
12
|
+
}
|
|
13
|
+
export function normalizeVatNumber(value) {
|
|
14
|
+
return value.trim().replace(/\s+/g, '').toUpperCase();
|
|
15
|
+
}
|
|
16
|
+
function resolveCheckVatInput(input) {
|
|
17
|
+
if ('countryCode' in input) {
|
|
18
|
+
return {
|
|
19
|
+
countryCode: normalizeCountryCode(input.countryCode),
|
|
20
|
+
vatNumber: normalizeVatNumber(input.vatNumber)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const normalizedVat = normalizeVatNumber(input.vatNumber);
|
|
24
|
+
return {
|
|
25
|
+
countryCode: normalizedVat.slice(0, 2),
|
|
26
|
+
vatNumber: normalizedVat.slice(2)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function validateInput(input) {
|
|
30
|
+
const { countryCode, vatNumber } = resolveCheckVatInput(input);
|
|
31
|
+
if (!countryCode) {
|
|
32
|
+
throw new Error('countryCode is required');
|
|
33
|
+
}
|
|
34
|
+
if (!vatNumber) {
|
|
35
|
+
throw new Error('vatNumber is required');
|
|
36
|
+
}
|
|
37
|
+
if (!EU_COUNTRY_CODES.has(countryCode)) {
|
|
38
|
+
throw new Error(`Unsupported countryCode: ${countryCode}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function checkVatWithConfig(input, config) {
|
|
42
|
+
validateInput(input);
|
|
43
|
+
const { countryCode, vatNumber } = resolveCheckVatInput(input);
|
|
44
|
+
const data = await postCheckVat({
|
|
45
|
+
countryCode,
|
|
46
|
+
vatNumber
|
|
47
|
+
}, config);
|
|
48
|
+
const result = {
|
|
49
|
+
countryCode: data.countryCode ?? countryCode,
|
|
50
|
+
vatNumber: data.vatNumber ?? vatNumber,
|
|
51
|
+
valid: data.valid
|
|
52
|
+
};
|
|
53
|
+
if (data.requestDate !== undefined) {
|
|
54
|
+
result.requestDate = data.requestDate;
|
|
55
|
+
}
|
|
56
|
+
if (data.requestIdentifier !== undefined) {
|
|
57
|
+
result.requestIdentifier = data.requestIdentifier;
|
|
58
|
+
}
|
|
59
|
+
if (data.name !== undefined) {
|
|
60
|
+
result.name = data.name;
|
|
61
|
+
}
|
|
62
|
+
if (data.address !== undefined) {
|
|
63
|
+
result.address = data.address;
|
|
64
|
+
}
|
|
65
|
+
if (data.traderName !== undefined) {
|
|
66
|
+
result.traderName = data.traderName;
|
|
67
|
+
}
|
|
68
|
+
if (data.traderStreet !== undefined) {
|
|
69
|
+
result.traderStreet = data.traderStreet;
|
|
70
|
+
}
|
|
71
|
+
if (data.traderPostalCode !== undefined) {
|
|
72
|
+
result.traderPostalCode = data.traderPostalCode;
|
|
73
|
+
}
|
|
74
|
+
if (data.traderCity !== undefined) {
|
|
75
|
+
result.traderCity = data.traderCity;
|
|
76
|
+
}
|
|
77
|
+
if (data.traderCompanyType !== undefined) {
|
|
78
|
+
result.traderCompanyType = data.traderCompanyType;
|
|
79
|
+
}
|
|
80
|
+
if (data.traderNameMatch !== undefined) {
|
|
81
|
+
result.traderNameMatch = data.traderNameMatch;
|
|
82
|
+
}
|
|
83
|
+
if (data.traderStreetMatch !== undefined) {
|
|
84
|
+
result.traderStreetMatch = data.traderStreetMatch;
|
|
85
|
+
}
|
|
86
|
+
if (data.traderPostalCodeMatch !== undefined) {
|
|
87
|
+
result.traderPostalCodeMatch = data.traderPostalCodeMatch;
|
|
88
|
+
}
|
|
89
|
+
if (data.traderCityMatch !== undefined) {
|
|
90
|
+
result.traderCityMatch = data.traderCityMatch;
|
|
91
|
+
}
|
|
92
|
+
if (data.traderCompanyTypeMatch !== undefined) {
|
|
93
|
+
result.traderCompanyTypeMatch = data.traderCompanyTypeMatch;
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
export function createViesClient(config = {}) {
|
|
98
|
+
return {
|
|
99
|
+
checkVat(input) {
|
|
100
|
+
return checkVatWithConfig(input, config);
|
|
101
|
+
},
|
|
102
|
+
checkStatus() {
|
|
103
|
+
return getCheckStatus(config);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const defaultClient = createViesClient();
|
|
108
|
+
export async function checkVat(input) {
|
|
109
|
+
return defaultClient.checkVat(input);
|
|
110
|
+
}
|
|
111
|
+
export async function checkStatus() {
|
|
112
|
+
return defaultClient.checkStatus();
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/reetry.ts
|
|
2
|
+
import { ViesHttpError, ViesResponseError } from './errors.js';
|
|
3
|
+
function isRetryable(error) {
|
|
4
|
+
if (error instanceof ViesResponseError) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (error instanceof ViesHttpError) {
|
|
8
|
+
return error.status >= 500;
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
function delay(ms) {
|
|
13
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
14
|
+
}
|
|
15
|
+
export async function withRetry(fn, config) {
|
|
16
|
+
let lastError;
|
|
17
|
+
for (let attempt = 0; attempt <= config.retries; attempt++) {
|
|
18
|
+
try {
|
|
19
|
+
return await fn();
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
lastError = error;
|
|
23
|
+
if (attempt >= config.retries || !isRetryable(error)) {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
const backoff = config.retryDelayMs * 2 ** attempt;
|
|
27
|
+
await delay(backoff);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
throw lastError;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/retry.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAEhB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAO/D,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,MAAmB;IAEnB,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAElB,IAAI,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,OAAO,CAAC;YACnD,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ViesClientConfig } from './client.js';
|
|
2
|
+
export interface CountryStatus {
|
|
3
|
+
countryCode: string;
|
|
4
|
+
availability: 'Available' | 'Unavailable' | 'Monitoring Disabled';
|
|
5
|
+
}
|
|
6
|
+
export interface CheckStatusResult {
|
|
7
|
+
available: boolean;
|
|
8
|
+
countries: CountryStatus[];
|
|
9
|
+
}
|
|
10
|
+
export declare function getCheckStatus(config?: ViesClientConfig): Promise<CheckStatusResult>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/status.ts
|
|
2
|
+
import { ViesHttpError, ViesNetworkError, ViesResponseError, ViesTimeoutError } from './errors.js';
|
|
3
|
+
import { withRetry } from './retry.js';
|
|
4
|
+
// VIES does not provide a separate test endpoint for status checks.
|
|
5
|
+
const STATUS_ENDPOINT = 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-status';
|
|
6
|
+
const VALID_AVAILABILITIES = new Set([
|
|
7
|
+
'Available',
|
|
8
|
+
'Unavailable',
|
|
9
|
+
'Monitoring Disabled'
|
|
10
|
+
]);
|
|
11
|
+
export async function getCheckStatus(config = {}) {
|
|
12
|
+
const retries = config.retries ?? 0;
|
|
13
|
+
const retryDelayMs = config.retryDelayMs ?? 500;
|
|
14
|
+
return withRetry(() => executeCheckStatus(config), {
|
|
15
|
+
retries,
|
|
16
|
+
retryDelayMs
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function executeCheckStatus(config) {
|
|
20
|
+
const timeoutMs = config.timeoutMs ?? 10_000;
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch(STATUS_ENDPOINT, {
|
|
25
|
+
method: 'GET',
|
|
26
|
+
headers: {
|
|
27
|
+
accept: 'application/json'
|
|
28
|
+
},
|
|
29
|
+
signal: controller.signal
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new ViesHttpError(response.status);
|
|
33
|
+
}
|
|
34
|
+
const json = await response.json();
|
|
35
|
+
return parseStatusResponse(json);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
39
|
+
throw new ViesTimeoutError(timeoutMs);
|
|
40
|
+
}
|
|
41
|
+
if (error instanceof ViesHttpError || error instanceof ViesResponseError) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
throw new ViesNetworkError('VIES network request failed', error);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
clearTimeout(timeoutId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function parseStatusResponse(value) {
|
|
51
|
+
if (!value || typeof value !== 'object') {
|
|
52
|
+
throw new ViesResponseError('Invalid status response from VIES API');
|
|
53
|
+
}
|
|
54
|
+
const root = value;
|
|
55
|
+
if (!root.vow || typeof root.vow !== 'object') {
|
|
56
|
+
throw new ViesResponseError('VIES status response is missing vow');
|
|
57
|
+
}
|
|
58
|
+
if (typeof root.vow.available !== 'boolean') {
|
|
59
|
+
throw new ViesResponseError('VIES status response is missing available boolean');
|
|
60
|
+
}
|
|
61
|
+
const countriesRaw = root.vow.countries;
|
|
62
|
+
if (countriesRaw !== undefined && !Array.isArray(countriesRaw)) {
|
|
63
|
+
throw new ViesResponseError('VIES status response has invalid countries');
|
|
64
|
+
}
|
|
65
|
+
const countries = (countriesRaw ?? []).map((item) => {
|
|
66
|
+
if (!item || typeof item !== 'object') {
|
|
67
|
+
throw new ViesResponseError('Invalid country status entry');
|
|
68
|
+
}
|
|
69
|
+
const entry = item;
|
|
70
|
+
if (typeof entry.countryCode !== 'string' ||
|
|
71
|
+
typeof entry.availability !== 'string') {
|
|
72
|
+
throw new ViesResponseError('Invalid country status entry');
|
|
73
|
+
}
|
|
74
|
+
if (!VALID_AVAILABILITIES.has(entry.availability)) {
|
|
75
|
+
throw new ViesResponseError('Invalid country availability value');
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
countryCode: entry.countryCode,
|
|
79
|
+
availability: entry.availability
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
available: root.vow.available,
|
|
84
|
+
countries
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/status.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wipsquare/vies-vat-check",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript client for validating EU VAT numbers with the VIES API.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vat",
|
|
7
|
+
"vies",
|
|
8
|
+
"eu",
|
|
9
|
+
"tax",
|
|
10
|
+
"validation",
|
|
11
|
+
"typescript",
|
|
12
|
+
"node"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/wipsquare/vies-vat-check#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/wipsquare/vies-vat-check/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/wipsquare/vies-vat-check.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "wipsquare",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/src/index.js",
|
|
26
|
+
"types": "./dist/src/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/src/index.d.ts",
|
|
30
|
+
"default": "./dist/src/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist/src",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"sideEffects": false,
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=20"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"clean": "rm -rf dist",
|
|
47
|
+
"build": "tsc -p tsconfig.json",
|
|
48
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
49
|
+
"pretest": "npm run build",
|
|
50
|
+
"test": "node --test dist/test/**/*.test.js",
|
|
51
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
55
|
+
"@semantic-release/git": "^10.0.1",
|
|
56
|
+
"@types/node": "^25.5.2",
|
|
57
|
+
"semantic-release": "^25.0.3",
|
|
58
|
+
"typescript": "^6.0.2"
|
|
59
|
+
}
|
|
60
|
+
}
|