gender-api.com-client 1.0.12 → 2.0.2

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/README.md CHANGED
@@ -1,248 +1,107 @@
1
- Official Gender-API.com JavaScript And TypeScript Client
2
- =========================
1
+ # Gender-API.com Client for JavaScript and TypeScript
3
2
 
4
- This library is still beta. If you experience some problems or if you have some questions feel free to contact us.
3
+ Official Node.js client for [Gender-API.com](https://gender-api.com).
4
+ Determine the gender of a first name, full name, or email address with ease using our V2 API.
5
5
 
6
- About
7
- ------------
8
- Gender-API.com JavaScript and TypeScript client.
6
+ [![npm version](https://badge.fury.io/js/gender-api.com-client.svg)](https://badge.fury.io/js/gender-api.com-client)
9
7
 
10
- Homepage: <https://gender-api.com>
8
+ ## Features
11
9
 
12
- FAQ: <https://gender-api.com/en/frequently-asked-questions>
10
+ - **Full V2 API Support**: Access all latest endpoints.
11
+ - **TypeScript Support**: First-class type definitions included.
12
+ - **Modern Promise-based API**: Uses async/await and `fetch` (Node 20+).
13
+ - **Batch Processing**: Resolve up to 100 names in a single request.
13
14
 
14
- API Docs: <https://gender-api.com/en/api-docs>
15
+ ## Installation
15
16
 
16
- Contact: <https://gender-api.com/en/contact>
17
-
18
- Installation
19
- ------------
20
-
21
- ```
22
- my-project$ npm i gender-api.com-client --save
17
+ ```bash
18
+ npm install gender-api.com-client --save
23
19
  ```
24
20
 
25
- Usage
26
- ------------
27
- #### [TypeScript Examples](#typescript)
28
- #### [JavaScript Example](#javascript)
21
+ *Requires Node.js 20 or higher.*
29
22
 
30
- API-Key
31
- -----------
32
- Get a free API key here: <https://gender-api.com/en/account>
23
+ ## Usage
33
24
 
34
- ## TypeScript
35
- can also be used with Angular 2+.
25
+ First, get your free API Key from [Gender-API.com Account](https://gender-api.com/en/account).
36
26
 
37
- ### Simple Usage
27
+ ### Basic Example (TypeScript / ES Modules)
38
28
 
39
29
  ```typescript
40
- import {Client as GenderApiClient, ResultSingleName} from "gender-api.com-client";
41
-
42
- const genderApiClient = new GenderApiClient("your API key");
43
-
44
- try {
45
- genderApiClient.getByFirstName('theresa', (response: ResultSingleName) => {
46
- console.log(response.gender); //female
47
- console.log(response.accuracy); //98
48
- });
49
-
50
- genderApiClient.getByFirstNameAndCountry('john', 'US', (response: ResultSingleName) => {
51
- console.log(response.gender); //male
52
- console.log(response.accuracy); //99
53
- });
54
- }
55
- catch(e) {
56
- console.log('Error:', e);
57
- }
58
- ```
30
+ import { Client } from 'gender-api.com-client';
59
31
 
60
- ### Split First and Last Name
32
+ const client = new Client('YOUR_API_KEY');
61
33
 
62
- ```typescript
63
- import {Client as GenderApiClient, ResultSplit} from "gender-api.com-client";
64
-
65
- const genderApiClient = new GenderApiClient("your API key");
66
-
67
- try {
68
- genderApiClient.getByFirstNameAndLastName('theresa miller', (response: ResultSplit) => {
69
- console.log(response.gender); //female
70
- console.log(response.accuracy); //98
71
- console.log(response.first_name); //Theresa
72
- console.log(response.last_name); //Miller
73
- });
74
-
75
- genderApiClient.getByFirstNameAndLastNameAndCountry('john johnson', 'US', (response: ResultSplit) => {
76
- console.log(response.gender); //male
77
- console.log(response.accuracy); //99
78
- console.log(response.first_name); //John
79
- console.log(response.last_name); //Johnson
80
- });
81
- }
82
- catch(e) {
83
- console.log('Error:', e);
84
- }
85
- ```
86
-
87
- ### Email Address
34
+ async function checkGender() {
35
+ try {
36
+ // By First Name
37
+ const result = await client.getByFirstName('Theresa');
38
+ console.log(`${result.first_name} is ${result.gender} (Probability: ${result.probability})`);
88
39
 
89
- ```typescript
90
- import {Client as GenderApiClient, ResultEmailAddress} from "gender-api.com-client";
91
-
92
- const genderApiClient = new GenderApiClient("your API key");
93
-
94
- try {
95
- genderApiClient.getByEmailAddress('theresa.miller@gmail.com', (response: ResultEmailAddress) => {
96
- console.log(response.gender); //female
97
- console.log(response.accuracy); //98
98
- console.log(response.first_name); //Theresa
99
- console.log(response.last_name); //Miller
100
- });
101
-
102
- genderApiClient.getByEmailAddressAndCountry('john.johnson44@hotmail.com', 'US', (response: ResultEmailAddress) => {
103
- console.log(response.gender); //male
104
- console.log(response.accuracy); //99
105
- console.log(response.first_name); //John
106
- console.log(response.last_name); //Johnson
107
- });
108
- }
109
- catch(e) {
110
- console.log('Error:', e);
40
+ // By Full Name
41
+ const fullResult = await client.getByFullName('John Smith');
42
+ console.log(`${fullResult.first_name} ${fullResult.last_name} is ${fullResult.gender}`);
43
+
44
+ } catch (error) {
45
+ console.error('Error:', error);
46
+ }
111
47
  }
48
+
49
+ checkGender();
112
50
  ```
113
51
 
114
- ### Statistics
52
+ ### Common Scenarios
115
53
 
54
+ #### 1. Check a First Name
116
55
  ```typescript
117
- import {Client as GenderApiClient, ResultStats} from "gender-api.com-client";
118
-
119
- const genderApiClient = new GenderApiClient("your API key");
120
-
121
- try {
122
- genderApiClient.getStats((response: ResultStats) => {
123
- console.log(response.is_limit_reached); //false
124
- console.log(response.remaining_requests); //Available Credits
125
- console.log(response.amount_month_start); //Credits at the start of the month
126
- console.log(response.amount_month_bought); //Credits bought this month
127
- });
128
-
129
- }
130
- catch(e) {
131
- console.log('Error:', e);
132
- }
56
+ const result = await client.getByFirstName('Andrea', { country: 'IT' });
57
+ // Andrea in Italy is usually male
133
58
  ```
134
59
 
135
- ## JavaScript
136
-
137
- ### Simple Usage
138
-
139
- ```javascript
140
- try {
141
- var GenderApi = require('gender-api.com-client');
142
-
143
- var genderApiClient = new GenderApi.Client('your api key');
144
-
145
- genderApiClient.getByFirstName('theresa', function (response) {
146
- console.log(response.gender); //female
147
- console.log(response.accuracy); //98
148
- });
149
-
150
- genderApiClient.getByFirstNameAndCountry('john', 'US', function (response) {
151
- console.log(response.gender); //male
152
- console.log(response.accuracy); //99
153
- });
154
-
155
- }
156
- catch(e) {
157
- console.log('Error:', e);
158
- }
60
+ #### 2. Check an Email Address
61
+ ```typescript
62
+ const result = await client.getByEmailAddress('marie.curie@example.com');
63
+ console.log(result.gender); // female
159
64
  ```
160
65
 
161
- ### Split First and Last Name
162
-
163
- ```javascript
164
- try {
165
- var GenderApi = require('gender-api.com-client');
66
+ #### 3. Batch Processing (Multiple Names)
67
+ Process lists efficiently using the batch endpoints.
166
68
 
167
- var genderApiClient = new GenderApi.Client('your api key');
69
+ ```typescript
70
+ const names = [
71
+ { id: '1', first_name: 'Theresa', country: 'US' },
72
+ { id: '2', first_name: 'John', country: 'US' }
73
+ ];
168
74
 
169
- genderApiClient.getByFirstNameAndLastName('theresa miller', function (response) {
170
- console.log(response.gender); //female
171
- console.log(response.accuracy); //98
172
- console.log(response.first_name); //Theresa
173
- console.log(response.last_name); //Miller
174
- });
75
+ const results = await client.getByFirstNameMultiple(names);
175
76
 
176
- genderApiClient.getByFirstNameAndLastNameAndCountry('john johnson', 'US', function (response) {
177
- console.log(response.gender); //male
178
- console.log(response.accuracy); //99
179
- console.log(response.first_name); //John
180
- console.log(response.last_name); //Johnson
181
- });
182
- }
183
- catch(e) {
184
- console.log('Error:', e);
185
- }
77
+ results.forEach(r => {
78
+ console.log(`ID: ${r.input.id}, Gender: ${r.gender}`);
79
+ });
186
80
  ```
187
81
 
188
- ### Email Address
189
-
190
- ```javascript
191
- try {
192
- var GenderApi = require('gender-api.com-client');
193
-
194
- var genderApiClient = new GenderApi.Client('your api key');
195
-
196
- genderApiClient.getByEmailAddress('theresa.miller@gmail.com', function (response) {
197
- console.log(response.gender); //female
198
- console.log(response.accuracy); //98
199
- console.log(response.first_name); //Theresa
200
- console.log(response.last_name); //Miller
201
- });
82
+ #### 4. Account Statistics
83
+ Check your remaining credits.
202
84
 
203
- genderApiClient.getByEmailAddressAndCountry('john.johnson44@hotmail.com', 'US', function (response) {
204
- console.log(response.gender); //male
205
- console.log(response.accuracy); //99
206
- console.log(response.first_name); //John
207
- console.log(response.last_name); //Johnson
208
- });
209
- }
210
- catch (e) {
211
- console.log('Error:', e);
212
- }
85
+ ```typescript
86
+ const stats = await client.getStatistics();
87
+ console.log(`Credits Remaining: ${stats.remaining_credits}`);
213
88
  ```
214
89
 
215
- ### Statistics
90
+ ## API Reference
216
91
 
217
- ```javascript
218
- try {
219
- var GenderApi = require('gender-api.com-client');
92
+ The `Client` class provides the following methods:
220
93
 
221
- var genderApiClient = new GenderApi.Client('your api key');
222
-
223
- genderApiClient.getStats(function (response) {
224
- console.log(response.is_limit_reached); //false
225
- console.log(response.remaining_requests); //Available Credits
226
- console.log(response.amount_month_start); //Credits at the start of the month
227
- console.log(response.amount_month_bought); //Credits bought this month
228
- });
229
- }
230
- catch (e) {
231
- console.log('Error:', e);
232
- }
233
- ```
94
+ - `getByFirstName(firstName: string, options?: RequestOptions)`
95
+ - `getByFullName(fullName: string, options?: RequestOptions)`
96
+ - `getByEmailAddress(email: string, options?: RequestOptions)`
97
+ - `getByFirstNameMultiple(items: FirstNameRequestItem[])`
98
+ - `getByFullNameMultiple(items: FullNameRequestItem[])`
99
+ - `getByEmailAddressMultiple(items: EmailRequestItem[])`
100
+ - `getCountryOfOrigin(request: CountryOfOriginRequest)`
101
+ - `getStatistics()`
234
102
 
103
+ All methods return a `Promise` that resolves to the result object or throws an error.
235
104
 
236
- Testing
237
- ------------
105
+ ## License
238
106
 
239
- ```
240
- gender-api-client-npm$ KEY=<your API key> npm run test
241
- ```
242
-
243
- Build project
244
- ------------
245
-
246
- ```
247
- gender-api-client-npm$ npm run build
248
- ```
107
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,6 +1,2 @@
1
1
  export * from './lib/client';
2
- export * from './lib/result/email-address';
3
- export * from './lib/result/multiple-names';
4
- export * from './lib/result/single-name';
5
- export * from './lib/result/split';
6
- export * from './lib/result/stats';
2
+ export * from './lib/models';
package/dist/index.js CHANGED
@@ -1,11 +1,18 @@
1
1
  "use strict";
2
- function __export(m) {
3
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4
- }
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
5
16
  Object.defineProperty(exports, "__esModule", { value: true });
6
- __export(require("./lib/client"));
7
- __export(require("./lib/result/email-address"));
8
- __export(require("./lib/result/multiple-names"));
9
- __export(require("./lib/result/single-name"));
10
- __export(require("./lib/result/split"));
11
- __export(require("./lib/result/stats"));
17
+ __exportStar(require("./lib/client"), exports);
18
+ __exportStar(require("./lib/models"), exports);
@@ -1,73 +1,15 @@
1
+ import { FirstNameRequest, FullNameRequest, EmailRequest, FirstNameRequestMultipleItem, FullNameRequestMultipleItem, EmailRequestMultipleItem, CountryOfOriginRequest, SingleNameResult, FullNameResult, EmailResult, StatisticResult, CountryOfOriginResult } from "./models";
1
2
  export declare class Client {
2
- apiKey: string;
3
- host: string;
4
- /**
5
- * @param {string} apiKey
6
- */
3
+ private apiKey;
4
+ private readonly baseUrl;
7
5
  constructor(apiKey: string);
8
- /**
9
- * @param {string} firstName
10
- * @param {Function} callback
11
- * @throws Exception
12
- * @return void
13
- */
14
- getByFirstName(firstName: string, callback: Function): void;
15
- /**
16
- * @param {string} firstName
17
- * @param {string} country
18
- * @param {Function} callback
19
- * @throws Exception
20
- * @return void
21
- */
22
- getByFirstNameAndCountry(firstName: string, country: string, callback: Function): void;
23
- /**
24
- * @param {string[]} firstNames
25
- * @param {string} country
26
- * @param {Function} callback
27
- * @throws Exception
28
- * @return void
29
- */
30
- getByMultipleNamesAndCountry(firstNames: string[], country: string, callback: Function): void;
31
- /**
32
- * @param {string} fullName
33
- * @param {Function} callback
34
- * @throws Exception
35
- * @return void
36
- */
37
- getByFirstNameAndLastName(fullName: string, callback: Function): void;
38
- /**
39
- * @param {string} fullName
40
- * @param {string} country
41
- * @param {Function} callback
42
- * @throws Exception
43
- * @return void
44
- */
45
- getByFirstNameAndLastNameAndCountry(fullName: string, country: string, callback: Function): void;
46
- /**
47
- * @param {string} emailAddress
48
- * @param {Function} callback
49
- * @throws Exception
50
- * @return void
51
- */
52
- getByEmailAddress(emailAddress: string, callback: Function): void;
53
- /**
54
- * @param {string} emailAddress
55
- * @param {string} country
56
- * @param {Function} callback
57
- * @throws Exception
58
- * @return void
59
- */
60
- getByEmailAddressAndCountry(emailAddress: string, country: string, callback: Function): void;
61
- /**
62
- * @param {Function} callback
63
- * @throws Exception
64
- * @return void
65
- */
66
- getStats(callback: Function): void;
67
- /**
68
- * @param {string} method
69
- * @param data
70
- * @param {Function} callback
71
- */
72
- private performRequest(method, data, callback);
6
+ private request;
7
+ getByFirstName(firstName: string, options?: Omit<FirstNameRequest, 'first_name'>): Promise<SingleNameResult>;
8
+ getByFullName(fullName: string, options?: Omit<FullNameRequest, 'full_name'>): Promise<FullNameResult>;
9
+ getByEmailAddress(email: string, options?: Omit<EmailRequest, 'email'>): Promise<EmailResult>;
10
+ getByFirstNameMultiple(items: FirstNameRequestMultipleItem[]): Promise<SingleNameResult[]>;
11
+ getByFullNameMultiple(items: FullNameRequestMultipleItem[]): Promise<FullNameResult[]>;
12
+ getByEmailAddressMultiple(items: EmailRequestMultipleItem[]): Promise<EmailResult[]>;
13
+ getCountryOfOrigin(request: CountryOfOriginRequest): Promise<CountryOfOriginResult>;
14
+ getStatistics(): Promise<StatisticResult>;
73
15
  }
@@ -1,146 +1,78 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var multiple_names_1 = require("./result/multiple-names");
4
- var Client = /** @class */ (function () {
5
- /**
6
- * @param {string} apiKey
7
- */
8
- function Client(apiKey) {
3
+ exports.Client = void 0;
4
+ class Client {
5
+ apiKey;
6
+ baseUrl = 'https://gender-api.com/v2';
7
+ constructor(apiKey) {
9
8
  this.apiKey = apiKey;
10
- this.host = 'https://gender-api.com';
11
9
  }
12
- /**
13
- * @param {string} firstName
14
- * @param {Function} callback
15
- * @throws Exception
16
- * @return void
17
- */
18
- Client.prototype.getByFirstName = function (firstName, callback) {
19
- return this.getByFirstNameAndCountry(firstName, '', callback);
20
- };
21
- /**
22
- * @param {string} firstName
23
- * @param {string} country
24
- * @param {Function} callback
25
- * @throws Exception
26
- * @return void
27
- */
28
- Client.prototype.getByFirstNameAndCountry = function (firstName, country, callback) {
29
- this.performRequest('get', {
30
- name: firstName,
31
- country: country
32
- }, function (json) {
33
- callback(json);
10
+ async request(endpoint, method, body) {
11
+ const headers = {
12
+ 'Authorization': `Bearer ${this.apiKey}`,
13
+ 'Content-Type': 'application/json',
14
+ 'User-Agent': 'Gender-API-Client/2.0.0 (Node.js)'
15
+ };
16
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
17
+ method,
18
+ headers,
19
+ body: body ? JSON.stringify(body) : undefined,
34
20
  });
35
- };
36
- /**
37
- * @param {string[]} firstNames
38
- * @param {string} country
39
- * @param {Function} callback
40
- * @throws Exception
41
- * @return void
42
- */
43
- Client.prototype.getByMultipleNamesAndCountry = function (firstNames, country, callback) {
44
- this.performRequest('get', {
45
- name: firstNames.join(';'),
46
- country: country,
47
- multi: 'true',
48
- }, function (json) {
49
- var names = [];
50
- for (var _i = 0, _a = json.result; _i < _a.length; _i++) {
51
- var name_1 = _a[_i];
52
- names.push(name_1);
21
+ if (!response.ok) {
22
+ let errorDetail = response.statusText;
23
+ try {
24
+ const errorJson = await response.json();
25
+ if (errorJson && errorJson.detail) {
26
+ errorDetail = errorJson.detail;
27
+ }
53
28
  }
54
- callback(new multiple_names_1.ResultMultipleNames(names));
55
- });
56
- };
57
- /**
58
- * @param {string} fullName
59
- * @param {Function} callback
60
- * @throws Exception
61
- * @return void
62
- */
63
- Client.prototype.getByFirstNameAndLastName = function (fullName, callback) {
64
- this.getByFirstNameAndLastNameAndCountry(fullName, '', callback);
65
- };
66
- /**
67
- * @param {string} fullName
68
- * @param {string} country
69
- * @param {Function} callback
70
- * @throws Exception
71
- * @return void
72
- */
73
- Client.prototype.getByFirstNameAndLastNameAndCountry = function (fullName, country, callback) {
74
- this.performRequest('get', {
75
- split: fullName,
76
- country: country
77
- }, function (json) {
78
- callback(json);
79
- });
80
- };
81
- /**
82
- * @param {string} emailAddress
83
- * @param {Function} callback
84
- * @throws Exception
85
- * @return void
86
- */
87
- Client.prototype.getByEmailAddress = function (emailAddress, callback) {
88
- this.getByEmailAddressAndCountry(emailAddress, '', callback);
89
- };
90
- /**
91
- * @param {string} emailAddress
92
- * @param {string} country
93
- * @param {Function} callback
94
- * @throws Exception
95
- * @return void
96
- */
97
- Client.prototype.getByEmailAddressAndCountry = function (emailAddress, country, callback) {
98
- this.performRequest('get', {
99
- email: emailAddress,
100
- country: country
101
- }, function (json) {
102
- callback(json);
103
- });
104
- };
105
- /**
106
- * @param {Function} callback
107
- * @throws Exception
108
- * @return void
109
- */
110
- Client.prototype.getStats = function (callback) {
111
- this.performRequest('get-stats', {}, function (json) {
112
- callback(json);
113
- });
114
- };
115
- /**
116
- * @param {string} method
117
- * @param data
118
- * @param {Function} callback
119
- */
120
- Client.prototype.performRequest = function (method, data, callback) {
121
- var formData = '';
122
- var dataKeys = Object.keys(data);
123
- for (var i = 0; i < dataKeys.length; i++) {
124
- formData += '&' + dataKeys[i] + '=' + encodeURI(data[dataKeys[i]]);
29
+ catch (e) {
30
+ // Ignore json parse error
31
+ }
32
+ throw new Error(`API Error ${response.status}: ${errorDetail}`);
125
33
  }
126
- var endpoint = '/' + method + '?key=' + this.apiKey + formData;
127
- var https = require('https');
128
- https.get(this.host + endpoint, function (resp) {
129
- var data = '';
130
- resp.on('data', function (chunk) {
131
- data += chunk;
132
- });
133
- resp.on('end', function () {
134
- var json = JSON.parse(data);
135
- if (json.errmsg) {
136
- throw new Error(json.errno + ': ' + json.errmsg);
137
- }
138
- callback(json);
139
- });
140
- }).on("error", function (err) {
141
- throw new Error(err.message);
142
- });
143
- };
144
- return Client;
145
- }());
34
+ const data = await response.json();
35
+ // Handle cases where API returns 200 but body is an error
36
+ if (data && data.status && data.detail && typeof data.status === 'number' && data.status >= 400) {
37
+ throw new Error(`API Error ${data.status}: ${data.detail}`);
38
+ }
39
+ return data;
40
+ }
41
+ async getByFirstName(firstName, options) {
42
+ const body = {
43
+ first_name: firstName,
44
+ ...options
45
+ };
46
+ return this.request('/gender/by-first-name', 'POST', body);
47
+ }
48
+ async getByFullName(fullName, options) {
49
+ const body = {
50
+ full_name: fullName,
51
+ ...options
52
+ };
53
+ return this.request('/gender/by-full-name', 'POST', body);
54
+ }
55
+ async getByEmailAddress(email, options) {
56
+ const body = {
57
+ email: email,
58
+ ...options
59
+ };
60
+ return this.request('/gender/by-email-address', 'POST', body);
61
+ }
62
+ async getByFirstNameMultiple(items) {
63
+ return this.request('/gender/by-first-name-multiple', 'POST', items);
64
+ }
65
+ async getByFullNameMultiple(items) {
66
+ return this.request('/gender/by-full-name-multiple', 'POST', items);
67
+ }
68
+ async getByEmailAddressMultiple(items) {
69
+ return this.request('/gender/by-email-address-multiple', 'POST', items);
70
+ }
71
+ async getCountryOfOrigin(request) {
72
+ return this.request('/country-of-origin', 'POST', request);
73
+ }
74
+ async getStatistics() {
75
+ return this.request('/statistic', 'GET');
76
+ }
77
+ }
146
78
  exports.Client = Client;
@@ -0,0 +1,89 @@
1
+ export interface NameRequest {
2
+ country?: string;
3
+ locale?: string;
4
+ ip?: string;
5
+ }
6
+ export interface FirstNameRequest extends NameRequest {
7
+ first_name: string;
8
+ }
9
+ export interface FullNameRequest extends NameRequest {
10
+ full_name: string;
11
+ }
12
+ export interface EmailRequest extends NameRequest {
13
+ email: string;
14
+ }
15
+ export interface MultipleNameRequestItem {
16
+ id: string;
17
+ country?: string;
18
+ locale?: string;
19
+ ip?: string;
20
+ }
21
+ export interface FirstNameRequestMultipleItem extends MultipleNameRequestItem {
22
+ first_name: string;
23
+ }
24
+ export interface FullNameRequestMultipleItem extends MultipleNameRequestItem {
25
+ full_name: string;
26
+ }
27
+ export interface EmailRequestMultipleItem extends MultipleNameRequestItem {
28
+ email: string;
29
+ }
30
+ export interface CountryOfOriginRequest {
31
+ first_name: string;
32
+ full_name?: string;
33
+ email?: string;
34
+ }
35
+ export interface ResultDetails {
36
+ credits_used: number;
37
+ samples: number;
38
+ country: string | null;
39
+ first_name_sanitized: string;
40
+ duration: string;
41
+ }
42
+ export interface Result {
43
+ input: any;
44
+ details: ResultDetails;
45
+ result_found: boolean;
46
+ probability: number;
47
+ gender: 'male' | 'female' | 'unknown';
48
+ }
49
+ export interface SingleNameResult extends Result {
50
+ first_name: string;
51
+ }
52
+ export interface FullNameResult extends Result {
53
+ first_name: string;
54
+ last_name?: string;
55
+ }
56
+ export interface EmailResult extends Result {
57
+ first_name: string;
58
+ last_name?: string;
59
+ }
60
+ export interface CountryOfOriginItem {
61
+ country_name: string;
62
+ country: string;
63
+ probability: number;
64
+ continental_region: string;
65
+ statistical_region: string;
66
+ }
67
+ export interface CountryOfOriginResult {
68
+ input: CountryOfOriginRequest;
69
+ details: ResultDetails;
70
+ result_found: boolean;
71
+ country_of_origin: CountryOfOriginItem[];
72
+ country_of_origin_map_url: string;
73
+ first_name: string;
74
+ probability: number;
75
+ gender: 'male' | 'female' | 'unknown';
76
+ }
77
+ export interface UsageLastMonth {
78
+ date: string;
79
+ credits_used: number;
80
+ }
81
+ export interface StatisticResult {
82
+ is_limit_reached: boolean;
83
+ remaining_credits: number;
84
+ details: {
85
+ credits_used: number;
86
+ duration: string;
87
+ };
88
+ usage_last_month: UsageLastMonth;
89
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_test_1 = require("node:test");
4
+ const chai_1 = require("chai");
5
+ const client_1 = require("../lib/client");
6
+ require("dotenv/config");
7
+ const apiKey = process.env.GENDER_API_KEY || '';
8
+ (0, node_test_1.describe)('Integration Tests', { skip: !apiKey ? 'No GENDER_API_KEY provided' : false }, () => {
9
+ let client;
10
+ (0, node_test_1.before)(() => {
11
+ client = new client_1.Client(apiKey);
12
+ });
13
+ (0, node_test_1.it)('should get gender by first name', async () => {
14
+ const result = await client.getByFirstName('Theresa', { country: 'US' });
15
+ (0, chai_1.expect)(result.gender).to.equal('female');
16
+ (0, chai_1.expect)(result.first_name).to.equal('Theresa');
17
+ (0, chai_1.expect)(result.result_found).to.be.true;
18
+ });
19
+ (0, node_test_1.it)('should get gender by full name', async () => {
20
+ const result = await client.getByFullName('John Smith', { country: 'US' });
21
+ (0, chai_1.expect)(result.gender).to.equal('male');
22
+ (0, chai_1.expect)(result.first_name).to.equal('John');
23
+ (0, chai_1.expect)(result.last_name).to.equal('Smith');
24
+ (0, chai_1.expect)(result.result_found).to.be.true;
25
+ });
26
+ (0, node_test_1.it)('should get gender by email address', async () => {
27
+ const result = await client.getByEmailAddress('theresa.miller@gmail.com');
28
+ (0, chai_1.expect)(result.gender).to.equal('female');
29
+ (0, chai_1.expect)(result.first_name).to.equal('Theresa');
30
+ (0, chai_1.expect)(result.last_name).to.equal('Miller');
31
+ });
32
+ (0, node_test_1.it)('should get multiple names (first name)', async () => {
33
+ const items = [
34
+ { id: '1', first_name: 'Theresa', country: 'US' },
35
+ { id: '2', first_name: 'John', country: 'US' }
36
+ ];
37
+ const results = await client.getByFirstNameMultiple(items);
38
+ (0, chai_1.expect)(results).to.have.lengthOf(2);
39
+ const theresa = results.find(r => r.input.id === '1');
40
+ const john = results.find(r => r.input.id === '2');
41
+ (0, chai_1.expect)(theresa?.gender).to.equal('female');
42
+ (0, chai_1.expect)(john?.gender).to.equal('male');
43
+ });
44
+ (0, node_test_1.it)('should get multiple names (full name)', async () => {
45
+ const items = [
46
+ { id: '1', full_name: 'Theresa Miller', country: 'US' },
47
+ { id: '2', full_name: 'John Smith', country: 'US' }
48
+ ];
49
+ const results = await client.getByFullNameMultiple(items);
50
+ (0, chai_1.expect)(results).to.have.lengthOf(2);
51
+ const theresa = results.find(r => r.input.id === '1');
52
+ (0, chai_1.expect)(theresa?.gender).to.equal('female');
53
+ });
54
+ (0, node_test_1.it)('should get multiple names (email)', async () => {
55
+ const items = [
56
+ { id: '1', email: 'theresa.miller@gmail.com' },
57
+ { id: '2', email: 'john.smith@gmail.com' }
58
+ ];
59
+ const results = await client.getByEmailAddressMultiple(items);
60
+ (0, chai_1.expect)(results).to.have.lengthOf(2);
61
+ (0, chai_1.expect)(results[0].result_found).to.be.true;
62
+ });
63
+ (0, node_test_1.it)('should get statistics', async () => {
64
+ const stats = await client.getStatistics();
65
+ (0, chai_1.expect)(stats).to.have.property('remaining_credits');
66
+ (0, chai_1.expect)(stats.is_limit_reached).to.be.a('boolean');
67
+ });
68
+ (0, node_test_1.it)('should get country of origin', async (t) => {
69
+ try {
70
+ const result = await client.getCountryOfOrigin({ first_name: 'Sven' });
71
+ (0, chai_1.expect)(result.country_of_origin).to.be.an('array');
72
+ if (result.country_of_origin.length > 0) {
73
+ (0, chai_1.expect)(result.country_of_origin[0]).to.have.property('country');
74
+ }
75
+ }
76
+ catch (e) {
77
+ // Some keys do not support this endpoint, verify if error is 402/403 or similar
78
+ // For now, if it fails, we can skip manually or log.
79
+ // node:test context allowed t.skip()
80
+ t.skip(`Skipping Country of Origin test: ${e.message}`);
81
+ }
82
+ });
83
+ (0, node_test_1.it)('should throw error for invalid request', async () => {
84
+ let error;
85
+ try {
86
+ await client.getByFirstName('');
87
+ }
88
+ catch (e) {
89
+ error = e;
90
+ }
91
+ (0, chai_1.expect)(error).to.exist;
92
+ (0, chai_1.expect)(error.message).to.contain('Error');
93
+ });
94
+ });
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "gender-api.com-client",
3
- "version": "1.0.12",
4
- "description": "JavaScript and TypeScript client for Gender-API.com",
3
+ "version": "2.0.2",
4
+ "description": "Modern JavaScript and TypeScript client for Gender-API.com",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "engines": {
11
+ "node": ">=20"
12
+ },
7
13
  "scripts": {
8
14
  "build": "tsc",
9
- "test": "mocha --reporter spec"
15
+ "test": "tsx --test test/**/*.ts",
16
+ "prepublishOnly": "npm run build"
10
17
  },
11
18
  "readme": "README.md",
12
19
  "repository": {
@@ -17,7 +24,8 @@
17
24
  "gender",
18
25
  "genderize",
19
26
  "api",
20
- "gender-api.com"
27
+ "gender-api.com",
28
+ "typescript"
21
29
  ],
22
30
  "author": "Gender-API.com",
23
31
  "license": "MIT",
@@ -25,9 +33,12 @@
25
33
  "url": "https://github.com/markus-perl/gender-api-client-npm/issues"
26
34
  },
27
35
  "homepage": "https://github.com/markus-perl/gender-api-client-npm#readme",
28
- "dependencies": {},
29
36
  "devDependencies": {
30
- "@types/node": "^9.6.0",
31
- "mocha": "^5.0.5"
37
+ "@types/chai": "^5.0.0",
38
+ "@types/node": "^20.0.0",
39
+ "chai": "^5.0.0",
40
+ "dotenv": "^16.0.0",
41
+ "tsx": "^4.21.0",
42
+ "typescript": "^5.0.0"
32
43
  }
33
44
  }
@@ -1,2 +0,0 @@
1
- export declare abstract class ResultAbstract {
2
- }
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var ResultAbstract = /** @class */ (function () {
4
- function ResultAbstract() {
5
- }
6
- return ResultAbstract;
7
- }());
8
- exports.ResultAbstract = ResultAbstract;
@@ -1,15 +0,0 @@
1
- import { ResultAbstract } from "./abstract";
2
- export declare class ResultEmailAddress extends ResultAbstract {
3
- name_sanitized: string;
4
- first_name: string;
5
- last_name: string;
6
- email: string;
7
- mail_provider: string;
8
- country: string;
9
- gender: string;
10
- samples: number;
11
- accuracy: number;
12
- duration: string;
13
- credits_used: number;
14
- constructor(name_sanitized: string, first_name: string, last_name: string, email: string, mail_provider: string, country: string, gender: string, samples: number, accuracy: number, duration: string, credits_used: number);
15
- }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
- return function (d, b) {
7
- extendStatics(d, b);
8
- function __() { this.constructor = d; }
9
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10
- };
11
- })();
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var abstract_1 = require("./abstract");
14
- var ResultEmailAddress = /** @class */ (function (_super) {
15
- __extends(ResultEmailAddress, _super);
16
- function ResultEmailAddress(name_sanitized, first_name, last_name, email, mail_provider, country, gender, samples, accuracy, duration, credits_used) {
17
- var _this = _super.call(this) || this;
18
- _this.name_sanitized = name_sanitized;
19
- _this.first_name = first_name;
20
- _this.last_name = last_name;
21
- _this.email = email;
22
- _this.mail_provider = mail_provider;
23
- _this.country = country;
24
- _this.gender = gender;
25
- _this.samples = samples;
26
- _this.accuracy = accuracy;
27
- _this.duration = duration;
28
- _this.credits_used = credits_used;
29
- return _this;
30
- }
31
- return ResultEmailAddress;
32
- }(abstract_1.ResultAbstract));
33
- exports.ResultEmailAddress = ResultEmailAddress;
@@ -1,10 +0,0 @@
1
- import { ResultAbstract } from "./abstract";
2
- import { ResultSingleName } from "./single-name";
3
- export declare class ResultMultipleNames extends ResultAbstract {
4
- names: ResultSingleName[];
5
- constructor(names: ResultSingleName[]);
6
- /**
7
- * @returns {ResultSingleName[]}
8
- */
9
- getNames(): ResultSingleName[];
10
- }
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
- return function (d, b) {
7
- extendStatics(d, b);
8
- function __() { this.constructor = d; }
9
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10
- };
11
- })();
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var abstract_1 = require("./abstract");
14
- var ResultMultipleNames = /** @class */ (function (_super) {
15
- __extends(ResultMultipleNames, _super);
16
- function ResultMultipleNames(names) {
17
- var _this = _super.call(this) || this;
18
- _this.names = names;
19
- return _this;
20
- }
21
- /**
22
- * @returns {ResultSingleName[]}
23
- */
24
- ResultMultipleNames.prototype.getNames = function () {
25
- return this.names;
26
- };
27
- return ResultMultipleNames;
28
- }(abstract_1.ResultAbstract));
29
- exports.ResultMultipleNames = ResultMultipleNames;
@@ -1,11 +0,0 @@
1
- import { ResultAbstract } from "./abstract";
2
- export declare class ResultSingleName extends ResultAbstract {
3
- name_sanitized: string;
4
- country: string;
5
- gender: string;
6
- samples: number;
7
- accuracy: number;
8
- duration: string;
9
- credits_used: number;
10
- constructor(name_sanitized: string, country: string, gender: string, samples: number, accuracy: number, duration: string, credits_used: number);
11
- }
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
- return function (d, b) {
7
- extendStatics(d, b);
8
- function __() { this.constructor = d; }
9
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10
- };
11
- })();
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var abstract_1 = require("./abstract");
14
- var ResultSingleName = /** @class */ (function (_super) {
15
- __extends(ResultSingleName, _super);
16
- function ResultSingleName(name_sanitized, country, gender, samples, accuracy, duration, credits_used) {
17
- var _this = _super.call(this) || this;
18
- _this.name_sanitized = name_sanitized;
19
- _this.country = country;
20
- _this.gender = gender;
21
- _this.samples = samples;
22
- _this.accuracy = accuracy;
23
- _this.duration = duration;
24
- _this.credits_used = credits_used;
25
- return _this;
26
- }
27
- return ResultSingleName;
28
- }(abstract_1.ResultAbstract));
29
- exports.ResultSingleName = ResultSingleName;
@@ -1,12 +0,0 @@
1
- import { ResultAbstract } from "./abstract";
2
- export declare class ResultSplit extends ResultAbstract {
3
- last_name: string;
4
- first_name: string;
5
- name: string;
6
- gender: string;
7
- samples: number;
8
- accuracy: number;
9
- duration: string;
10
- credits_used: number;
11
- constructor(last_name: string, first_name: string, name: string, gender: string, samples: number, accuracy: number, duration: string, credits_used: number);
12
- }
@@ -1,30 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
- return function (d, b) {
7
- extendStatics(d, b);
8
- function __() { this.constructor = d; }
9
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10
- };
11
- })();
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var abstract_1 = require("./abstract");
14
- var ResultSplit = /** @class */ (function (_super) {
15
- __extends(ResultSplit, _super);
16
- function ResultSplit(last_name, first_name, name, gender, samples, accuracy, duration, credits_used) {
17
- var _this = _super.call(this) || this;
18
- _this.last_name = last_name;
19
- _this.first_name = first_name;
20
- _this.name = name;
21
- _this.gender = gender;
22
- _this.samples = samples;
23
- _this.accuracy = accuracy;
24
- _this.duration = duration;
25
- _this.credits_used = credits_used;
26
- return _this;
27
- }
28
- return ResultSplit;
29
- }(abstract_1.ResultAbstract));
30
- exports.ResultSplit = ResultSplit;
@@ -1,10 +0,0 @@
1
- import { ResultAbstract } from "./abstract";
2
- export declare class ResultStats extends ResultAbstract {
3
- key: string;
4
- is_limit_reached: boolean;
5
- remaining_requests: Number;
6
- amount_month_start: Number;
7
- amount_month_bought: Number;
8
- duration: string;
9
- constructor(key: string, is_limit_reached: boolean, remaining_requests: Number, amount_month_start: Number, amount_month_bought: Number, duration: string);
10
- }
@@ -1,28 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
- return function (d, b) {
7
- extendStatics(d, b);
8
- function __() { this.constructor = d; }
9
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10
- };
11
- })();
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- var abstract_1 = require("./abstract");
14
- var ResultStats = /** @class */ (function (_super) {
15
- __extends(ResultStats, _super);
16
- function ResultStats(key, is_limit_reached, remaining_requests, amount_month_start, amount_month_bought, duration) {
17
- var _this = _super.call(this) || this;
18
- _this.key = key;
19
- _this.is_limit_reached = is_limit_reached;
20
- _this.remaining_requests = remaining_requests;
21
- _this.amount_month_start = amount_month_start;
22
- _this.amount_month_bought = amount_month_bought;
23
- _this.duration = duration;
24
- return _this;
25
- }
26
- return ResultStats;
27
- }(abstract_1.ResultAbstract));
28
- exports.ResultStats = ResultStats;