fakexy-to-json 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 +148 -0
- package/dist/index.d.mts +175 -0
- package/dist/index.d.ts +175 -0
- package/dist/index.js +365 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +315 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
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,148 @@
|
|
|
1
|
+
# fakexy-to-json
|
|
2
|
+
|
|
3
|
+
Fetch and parse [fakexy.com](https://www.fakexy.com/) data to JSON. Get fake addresses, profiles, and credit cards by country.
|
|
4
|
+
|
|
5
|
+
**Important:** fakexy.com is protected by Cloudflare. You **must** pass a valid `cf_clearance` cookie to get real data. Without it, requests will return 403. See [Cloudflare cookie](#cloudflare-cookie) below for how to obtain it.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install fakexy-to-json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { getAddress, getProfile, getCreditCard } from 'fakexy-to-json';
|
|
17
|
+
|
|
18
|
+
// Pass the cf_clearance cookie (required - see Cloudflare section below)
|
|
19
|
+
const address = await getAddress({
|
|
20
|
+
countryCode: 'us',
|
|
21
|
+
headers: {
|
|
22
|
+
Cookie: 'cf_clearance=YOUR_COOKIE_VALUE',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
console.log(address);
|
|
26
|
+
// { street, city, region, zipcode, phone, country, latitude?, longitude?, person?, creditcard? }
|
|
27
|
+
|
|
28
|
+
// Get a fake profile (US with state)
|
|
29
|
+
const profile = await getProfile({
|
|
30
|
+
countryCode: 'us',
|
|
31
|
+
stateCode: 'ca',
|
|
32
|
+
headers: { Cookie: 'cf_clearance=YOUR_COOKIE_VALUE' },
|
|
33
|
+
});
|
|
34
|
+
console.log(profile);
|
|
35
|
+
// { name, gender, birthday, ssn }
|
|
36
|
+
|
|
37
|
+
// Get a fake credit card
|
|
38
|
+
const card = await getCreditCard({
|
|
39
|
+
brand: 'visa',
|
|
40
|
+
headers: { Cookie: 'cf_clearance=YOUR_COOKIE_VALUE' },
|
|
41
|
+
});
|
|
42
|
+
console.log(card);
|
|
43
|
+
// { brand, number, expire, cvv }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Cloudflare cookie
|
|
47
|
+
|
|
48
|
+
fakexy.com is behind Cloudflare. To get the `cf_clearance` cookie:
|
|
49
|
+
|
|
50
|
+
1. Open [fakexy.com](https://www.fakexy.com/) in your browser
|
|
51
|
+
2. Pass the "Just a moment..." challenge (wait for the page to load)
|
|
52
|
+
3. Open DevTools → Application → Cookies → `https://www.fakexy.com`
|
|
53
|
+
4. Copy the `cf_clearance` value
|
|
54
|
+
5. Pass it in the `headers` option: `headers: { Cookie: 'cf_clearance=YOUR_VALUE' }`
|
|
55
|
+
|
|
56
|
+
The cookie expires after some time; you'll need to refresh it when requests start failing again.
|
|
57
|
+
|
|
58
|
+
## API
|
|
59
|
+
|
|
60
|
+
### `getAddress(options?)`
|
|
61
|
+
|
|
62
|
+
Fetches a fake address. Options:
|
|
63
|
+
|
|
64
|
+
- `countryCode` – Two-letter country code (e.g. `'us'`, `'uk'`, `'de'`). Default: `'us'`
|
|
65
|
+
- `stateCode` – State/region for countries that support it (e.g. `'ca'`, `'mi'` for US)
|
|
66
|
+
- `headers` – Custom HTTP headers. **Required:** include `Cookie: cf_clearance=...` (see [Cloudflare cookie](#cloudflare-cookie))
|
|
67
|
+
- `timeout` – Request timeout in ms (default: 10000)
|
|
68
|
+
|
|
69
|
+
### `getProfile(options?)`
|
|
70
|
+
|
|
71
|
+
Fetches a fake person profile. Options: same as `getAddress`.
|
|
72
|
+
|
|
73
|
+
### `getCreditCard(options?)`
|
|
74
|
+
|
|
75
|
+
Fetches a fake credit card. Options:
|
|
76
|
+
|
|
77
|
+
- `brand` – `'visa'`, `'mastercard'`, `'amex'`, `'discover'`. Default: `'visa'`
|
|
78
|
+
- `headers`, `timeout` – Same as above
|
|
79
|
+
|
|
80
|
+
## Error Handling
|
|
81
|
+
|
|
82
|
+
The package throws typed errors you can catch and handle:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import {
|
|
86
|
+
getAddress,
|
|
87
|
+
FakexyNetworkError,
|
|
88
|
+
FakexyHttpError,
|
|
89
|
+
FakexyParseError,
|
|
90
|
+
} from 'fakexy-to-json';
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const address = await getAddress({
|
|
94
|
+
countryCode: 'us',
|
|
95
|
+
headers: { Cookie: 'cf_clearance=YOUR_VALUE' },
|
|
96
|
+
});
|
|
97
|
+
} catch (err) {
|
|
98
|
+
if (err instanceof FakexyNetworkError) {
|
|
99
|
+
console.error('Network failed:', err.url, err.cause);
|
|
100
|
+
} else if (err instanceof FakexyHttpError) {
|
|
101
|
+
console.error('HTTP error:', err.status, err.url);
|
|
102
|
+
} else if (err instanceof FakexyParseError) {
|
|
103
|
+
console.error('Parse failed - site structure may have changed');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Chrome Extension
|
|
109
|
+
|
|
110
|
+
The package works in Chrome extension **background scripts** or **service workers**. Add `host_permissions` to your `manifest.json`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"manifest_version": 3,
|
|
115
|
+
"host_permissions": ["https://www.fakexy.com/*"]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Note:** Content scripts run in page context and are subject to CORS. Call the package from the background script and use `chrome.runtime.sendMessage` to pass results to content scripts or popup. Use the `chrome.cookies` API to read `cf_clearance` for fakexy.com and pass it in headers.
|
|
120
|
+
|
|
121
|
+
## Types
|
|
122
|
+
|
|
123
|
+
All types are exported for use in your code:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import type {
|
|
127
|
+
AddressResult,
|
|
128
|
+
PersonResult,
|
|
129
|
+
CreditCardResult,
|
|
130
|
+
} from 'fakexy-to-json';
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Supported Countries
|
|
134
|
+
|
|
135
|
+
Use `SUPPORTED_COUNTRIES` for the full list:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { SUPPORTED_COUNTRIES } from 'fakexy-to-json';
|
|
139
|
+
// ['ar', 'au', 'bd', 'be', 'br', 'ca', 'cn', ...]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Disclaimer
|
|
143
|
+
|
|
144
|
+
This package is unofficial and not affiliated with, endorsed by, or sponsored by [fakexy.com](https://www.fakexy.com/). You are responsible for complying with fakexy.com's terms of service and acceptable use policies when using this library, and for using any data only in lawful ways.
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base options shared by all generators.
|
|
3
|
+
*/
|
|
4
|
+
interface BaseOptions {
|
|
5
|
+
/** Custom HTTP headers (e.g. User-Agent, Cookie for Cloudflare workarounds) */
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
/** Request timeout in milliseconds */
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Options for address generator.
|
|
12
|
+
*/
|
|
13
|
+
interface AddressOptions extends BaseOptions {
|
|
14
|
+
/** Two-letter country code (e.g. 'us', 'uk', 'de') */
|
|
15
|
+
countryCode?: string;
|
|
16
|
+
/** State/region code for countries that support it (e.g. 'ca', 'mi' for US) */
|
|
17
|
+
stateCode?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for profile/name generator.
|
|
21
|
+
*/
|
|
22
|
+
interface ProfileOptions extends BaseOptions {
|
|
23
|
+
/** Two-letter country code (e.g. 'us', 'uk') */
|
|
24
|
+
countryCode?: string;
|
|
25
|
+
/** State code for US (e.g. 'ca', 'mi') */
|
|
26
|
+
stateCode?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Options for credit card generator.
|
|
30
|
+
*/
|
|
31
|
+
interface CreditCardOptions extends BaseOptions {
|
|
32
|
+
/** Card brand: 'visa', 'mastercard', etc. */
|
|
33
|
+
brand?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Person/profile result from fakexy.com.
|
|
37
|
+
*/
|
|
38
|
+
interface PersonResult {
|
|
39
|
+
name: string;
|
|
40
|
+
gender: string;
|
|
41
|
+
birthday: string;
|
|
42
|
+
ssn: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Credit card result from fakexy.com.
|
|
46
|
+
*/
|
|
47
|
+
interface CreditCardResult {
|
|
48
|
+
brand: string;
|
|
49
|
+
number: string;
|
|
50
|
+
expire: string;
|
|
51
|
+
cvv: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Address result from fakexy.com.
|
|
55
|
+
*/
|
|
56
|
+
interface AddressResult {
|
|
57
|
+
street: string;
|
|
58
|
+
city: string;
|
|
59
|
+
region: string;
|
|
60
|
+
zipcode: string;
|
|
61
|
+
phone: string;
|
|
62
|
+
country: string;
|
|
63
|
+
latitude?: string;
|
|
64
|
+
longitude?: string;
|
|
65
|
+
person?: PersonResult;
|
|
66
|
+
creditcard?: CreditCardResult;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parses address HTML from fakexy.com into AddressResult.
|
|
71
|
+
* Use when you have HTML from a fetch (e.g. from page context).
|
|
72
|
+
*/
|
|
73
|
+
declare function parseAddressFromHtml(html: string, url?: string): AddressResult;
|
|
74
|
+
/**
|
|
75
|
+
* Fetches a fake address from fakexy.com for the given country.
|
|
76
|
+
*
|
|
77
|
+
* @param options - Country code and optional state/region
|
|
78
|
+
* @returns Parsed address with street, city, zip, phone, and optionally person/creditcard
|
|
79
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
80
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
81
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
82
|
+
*/
|
|
83
|
+
declare function getAddress(options?: AddressOptions): Promise<AddressResult>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Fetches a fake person profile from fakexy.com.
|
|
87
|
+
*
|
|
88
|
+
* @param options - Country code and optional state (for US)
|
|
89
|
+
* @returns Parsed profile with name, gender, birthday, SSN
|
|
90
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
91
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
92
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
93
|
+
*/
|
|
94
|
+
declare function getProfile(options?: ProfileOptions): Promise<PersonResult>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Fetches a fake credit card from fakexy.com.
|
|
98
|
+
*
|
|
99
|
+
* @param options - Card brand (visa, mastercard, etc.)
|
|
100
|
+
* @returns Parsed credit card with brand, number, expire, cvv
|
|
101
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
102
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
103
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
104
|
+
*/
|
|
105
|
+
declare function getCreditCard(options?: CreditCardOptions): Promise<CreditCardResult>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Base error class for all fakexy-to-json errors.
|
|
109
|
+
*/
|
|
110
|
+
declare class FakexyError extends Error {
|
|
111
|
+
name: string;
|
|
112
|
+
constructor(message: string);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Thrown when a network request fails (fetch error, timeout).
|
|
116
|
+
*/
|
|
117
|
+
declare class FakexyNetworkError extends FakexyError {
|
|
118
|
+
readonly url: string;
|
|
119
|
+
readonly cause?: Error | undefined;
|
|
120
|
+
name: string;
|
|
121
|
+
constructor(message: string, url: string, cause?: Error | undefined);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Thrown when the server returns an error status (403, 404, 5xx).
|
|
125
|
+
*/
|
|
126
|
+
declare class FakexyHttpError extends FakexyError {
|
|
127
|
+
readonly status: number;
|
|
128
|
+
readonly statusText: string;
|
|
129
|
+
readonly url: string;
|
|
130
|
+
name: string;
|
|
131
|
+
constructor(message: string, status: number, statusText: string, url: string);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Thrown when the HTML structure has changed and cannot be parsed.
|
|
135
|
+
*/
|
|
136
|
+
declare class FakexyParseError extends FakexyError {
|
|
137
|
+
readonly url?: string | undefined;
|
|
138
|
+
name: string;
|
|
139
|
+
constructor(message: string, url?: string | undefined);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Thrown when options are invalid (e.g. invalid countryCode, brand).
|
|
143
|
+
*/
|
|
144
|
+
declare class FakexyValidationError extends FakexyError {
|
|
145
|
+
readonly field: string;
|
|
146
|
+
readonly value: unknown;
|
|
147
|
+
name: string;
|
|
148
|
+
constructor(message: string, field: string, value: unknown);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Supported country codes for fakexy.com generators.
|
|
153
|
+
* Based on the site's URL structure.
|
|
154
|
+
*/
|
|
155
|
+
declare const SUPPORTED_COUNTRIES: readonly ["ar", "au", "bd", "be", "br", "ca", "cn", "cz", "fr", "de", "gr", "hu", "in", "id", "ir", "it", "jp", "my", "mx", "np", "nl", "ng", "pe", "ph", "pl", "pt", "ro", "ru", "sa", "sg", "kr", "es", "se", "th", "tr", "ug", "ua", "uk", "us", "vn"];
|
|
156
|
+
type SupportedCountryCode = (typeof SUPPORTED_COUNTRIES)[number];
|
|
157
|
+
/**
|
|
158
|
+
* Supported credit card brands.
|
|
159
|
+
*/
|
|
160
|
+
declare const SUPPORTED_CREDIT_CARD_BRANDS: readonly ["visa", "mastercard", "amex", "discover"];
|
|
161
|
+
type SupportedCreditCardBrand = (typeof SUPPORTED_CREDIT_CARD_BRANDS)[number];
|
|
162
|
+
/**
|
|
163
|
+
* Build URL for address generator.
|
|
164
|
+
*/
|
|
165
|
+
declare function buildAddressUrl(countryCode?: string, stateCode?: string): string;
|
|
166
|
+
/**
|
|
167
|
+
* Build URL for profile/name generator.
|
|
168
|
+
*/
|
|
169
|
+
declare function buildProfileUrl(countryCode?: string, stateCode?: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* Build URL for credit card generator.
|
|
172
|
+
*/
|
|
173
|
+
declare function buildCreditCardUrl(brand?: string): string;
|
|
174
|
+
|
|
175
|
+
export { type AddressOptions, type AddressResult, type BaseOptions, type CreditCardOptions, type CreditCardResult, FakexyError, FakexyHttpError, FakexyNetworkError, FakexyParseError, FakexyValidationError, type PersonResult, type ProfileOptions, SUPPORTED_COUNTRIES, SUPPORTED_CREDIT_CARD_BRANDS, type SupportedCountryCode, type SupportedCreditCardBrand, buildAddressUrl, buildCreditCardUrl, buildProfileUrl, getAddress, getCreditCard, getProfile, parseAddressFromHtml };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base options shared by all generators.
|
|
3
|
+
*/
|
|
4
|
+
interface BaseOptions {
|
|
5
|
+
/** Custom HTTP headers (e.g. User-Agent, Cookie for Cloudflare workarounds) */
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
/** Request timeout in milliseconds */
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Options for address generator.
|
|
12
|
+
*/
|
|
13
|
+
interface AddressOptions extends BaseOptions {
|
|
14
|
+
/** Two-letter country code (e.g. 'us', 'uk', 'de') */
|
|
15
|
+
countryCode?: string;
|
|
16
|
+
/** State/region code for countries that support it (e.g. 'ca', 'mi' for US) */
|
|
17
|
+
stateCode?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for profile/name generator.
|
|
21
|
+
*/
|
|
22
|
+
interface ProfileOptions extends BaseOptions {
|
|
23
|
+
/** Two-letter country code (e.g. 'us', 'uk') */
|
|
24
|
+
countryCode?: string;
|
|
25
|
+
/** State code for US (e.g. 'ca', 'mi') */
|
|
26
|
+
stateCode?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Options for credit card generator.
|
|
30
|
+
*/
|
|
31
|
+
interface CreditCardOptions extends BaseOptions {
|
|
32
|
+
/** Card brand: 'visa', 'mastercard', etc. */
|
|
33
|
+
brand?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Person/profile result from fakexy.com.
|
|
37
|
+
*/
|
|
38
|
+
interface PersonResult {
|
|
39
|
+
name: string;
|
|
40
|
+
gender: string;
|
|
41
|
+
birthday: string;
|
|
42
|
+
ssn: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Credit card result from fakexy.com.
|
|
46
|
+
*/
|
|
47
|
+
interface CreditCardResult {
|
|
48
|
+
brand: string;
|
|
49
|
+
number: string;
|
|
50
|
+
expire: string;
|
|
51
|
+
cvv: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Address result from fakexy.com.
|
|
55
|
+
*/
|
|
56
|
+
interface AddressResult {
|
|
57
|
+
street: string;
|
|
58
|
+
city: string;
|
|
59
|
+
region: string;
|
|
60
|
+
zipcode: string;
|
|
61
|
+
phone: string;
|
|
62
|
+
country: string;
|
|
63
|
+
latitude?: string;
|
|
64
|
+
longitude?: string;
|
|
65
|
+
person?: PersonResult;
|
|
66
|
+
creditcard?: CreditCardResult;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parses address HTML from fakexy.com into AddressResult.
|
|
71
|
+
* Use when you have HTML from a fetch (e.g. from page context).
|
|
72
|
+
*/
|
|
73
|
+
declare function parseAddressFromHtml(html: string, url?: string): AddressResult;
|
|
74
|
+
/**
|
|
75
|
+
* Fetches a fake address from fakexy.com for the given country.
|
|
76
|
+
*
|
|
77
|
+
* @param options - Country code and optional state/region
|
|
78
|
+
* @returns Parsed address with street, city, zip, phone, and optionally person/creditcard
|
|
79
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
80
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
81
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
82
|
+
*/
|
|
83
|
+
declare function getAddress(options?: AddressOptions): Promise<AddressResult>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Fetches a fake person profile from fakexy.com.
|
|
87
|
+
*
|
|
88
|
+
* @param options - Country code and optional state (for US)
|
|
89
|
+
* @returns Parsed profile with name, gender, birthday, SSN
|
|
90
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
91
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
92
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
93
|
+
*/
|
|
94
|
+
declare function getProfile(options?: ProfileOptions): Promise<PersonResult>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Fetches a fake credit card from fakexy.com.
|
|
98
|
+
*
|
|
99
|
+
* @param options - Card brand (visa, mastercard, etc.)
|
|
100
|
+
* @returns Parsed credit card with brand, number, expire, cvv
|
|
101
|
+
* @throws {FakexyNetworkError} When the request fails
|
|
102
|
+
* @throws {FakexyHttpError} When the server returns an error status
|
|
103
|
+
* @throws {FakexyParseError} When the page structure has changed
|
|
104
|
+
*/
|
|
105
|
+
declare function getCreditCard(options?: CreditCardOptions): Promise<CreditCardResult>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Base error class for all fakexy-to-json errors.
|
|
109
|
+
*/
|
|
110
|
+
declare class FakexyError extends Error {
|
|
111
|
+
name: string;
|
|
112
|
+
constructor(message: string);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Thrown when a network request fails (fetch error, timeout).
|
|
116
|
+
*/
|
|
117
|
+
declare class FakexyNetworkError extends FakexyError {
|
|
118
|
+
readonly url: string;
|
|
119
|
+
readonly cause?: Error | undefined;
|
|
120
|
+
name: string;
|
|
121
|
+
constructor(message: string, url: string, cause?: Error | undefined);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Thrown when the server returns an error status (403, 404, 5xx).
|
|
125
|
+
*/
|
|
126
|
+
declare class FakexyHttpError extends FakexyError {
|
|
127
|
+
readonly status: number;
|
|
128
|
+
readonly statusText: string;
|
|
129
|
+
readonly url: string;
|
|
130
|
+
name: string;
|
|
131
|
+
constructor(message: string, status: number, statusText: string, url: string);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Thrown when the HTML structure has changed and cannot be parsed.
|
|
135
|
+
*/
|
|
136
|
+
declare class FakexyParseError extends FakexyError {
|
|
137
|
+
readonly url?: string | undefined;
|
|
138
|
+
name: string;
|
|
139
|
+
constructor(message: string, url?: string | undefined);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Thrown when options are invalid (e.g. invalid countryCode, brand).
|
|
143
|
+
*/
|
|
144
|
+
declare class FakexyValidationError extends FakexyError {
|
|
145
|
+
readonly field: string;
|
|
146
|
+
readonly value: unknown;
|
|
147
|
+
name: string;
|
|
148
|
+
constructor(message: string, field: string, value: unknown);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Supported country codes for fakexy.com generators.
|
|
153
|
+
* Based on the site's URL structure.
|
|
154
|
+
*/
|
|
155
|
+
declare const SUPPORTED_COUNTRIES: readonly ["ar", "au", "bd", "be", "br", "ca", "cn", "cz", "fr", "de", "gr", "hu", "in", "id", "ir", "it", "jp", "my", "mx", "np", "nl", "ng", "pe", "ph", "pl", "pt", "ro", "ru", "sa", "sg", "kr", "es", "se", "th", "tr", "ug", "ua", "uk", "us", "vn"];
|
|
156
|
+
type SupportedCountryCode = (typeof SUPPORTED_COUNTRIES)[number];
|
|
157
|
+
/**
|
|
158
|
+
* Supported credit card brands.
|
|
159
|
+
*/
|
|
160
|
+
declare const SUPPORTED_CREDIT_CARD_BRANDS: readonly ["visa", "mastercard", "amex", "discover"];
|
|
161
|
+
type SupportedCreditCardBrand = (typeof SUPPORTED_CREDIT_CARD_BRANDS)[number];
|
|
162
|
+
/**
|
|
163
|
+
* Build URL for address generator.
|
|
164
|
+
*/
|
|
165
|
+
declare function buildAddressUrl(countryCode?: string, stateCode?: string): string;
|
|
166
|
+
/**
|
|
167
|
+
* Build URL for profile/name generator.
|
|
168
|
+
*/
|
|
169
|
+
declare function buildProfileUrl(countryCode?: string, stateCode?: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* Build URL for credit card generator.
|
|
172
|
+
*/
|
|
173
|
+
declare function buildCreditCardUrl(brand?: string): string;
|
|
174
|
+
|
|
175
|
+
export { type AddressOptions, type AddressResult, type BaseOptions, type CreditCardOptions, type CreditCardResult, FakexyError, FakexyHttpError, FakexyNetworkError, FakexyParseError, FakexyValidationError, type PersonResult, type ProfileOptions, SUPPORTED_COUNTRIES, SUPPORTED_CREDIT_CARD_BRANDS, type SupportedCountryCode, type SupportedCreditCardBrand, buildAddressUrl, buildCreditCardUrl, buildProfileUrl, getAddress, getCreditCard, getProfile, parseAddressFromHtml };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
FakexyError: () => FakexyError,
|
|
34
|
+
FakexyHttpError: () => FakexyHttpError,
|
|
35
|
+
FakexyNetworkError: () => FakexyNetworkError,
|
|
36
|
+
FakexyParseError: () => FakexyParseError,
|
|
37
|
+
FakexyValidationError: () => FakexyValidationError,
|
|
38
|
+
SUPPORTED_COUNTRIES: () => SUPPORTED_COUNTRIES,
|
|
39
|
+
SUPPORTED_CREDIT_CARD_BRANDS: () => SUPPORTED_CREDIT_CARD_BRANDS,
|
|
40
|
+
buildAddressUrl: () => buildAddressUrl,
|
|
41
|
+
buildCreditCardUrl: () => buildCreditCardUrl,
|
|
42
|
+
buildProfileUrl: () => buildProfileUrl,
|
|
43
|
+
getAddress: () => getAddress,
|
|
44
|
+
getCreditCard: () => getCreditCard,
|
|
45
|
+
getProfile: () => getProfile,
|
|
46
|
+
parseAddressFromHtml: () => parseAddressFromHtml
|
|
47
|
+
});
|
|
48
|
+
module.exports = __toCommonJS(index_exports);
|
|
49
|
+
|
|
50
|
+
// src/errors.ts
|
|
51
|
+
var FakexyError = class _FakexyError extends Error {
|
|
52
|
+
constructor(message) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.name = "FakexyError";
|
|
55
|
+
Object.setPrototypeOf(this, _FakexyError.prototype);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var FakexyNetworkError = class _FakexyNetworkError extends FakexyError {
|
|
59
|
+
constructor(message, url, cause) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.url = url;
|
|
62
|
+
this.cause = cause;
|
|
63
|
+
this.name = "FakexyNetworkError";
|
|
64
|
+
Object.setPrototypeOf(this, _FakexyNetworkError.prototype);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var FakexyHttpError = class _FakexyHttpError extends FakexyError {
|
|
68
|
+
constructor(message, status, statusText, url) {
|
|
69
|
+
super(message);
|
|
70
|
+
this.status = status;
|
|
71
|
+
this.statusText = statusText;
|
|
72
|
+
this.url = url;
|
|
73
|
+
this.name = "FakexyHttpError";
|
|
74
|
+
Object.setPrototypeOf(this, _FakexyHttpError.prototype);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var FakexyParseError = class _FakexyParseError extends FakexyError {
|
|
78
|
+
constructor(message, url) {
|
|
79
|
+
super(message);
|
|
80
|
+
this.url = url;
|
|
81
|
+
this.name = "FakexyParseError";
|
|
82
|
+
Object.setPrototypeOf(this, _FakexyParseError.prototype);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var FakexyValidationError = class _FakexyValidationError extends FakexyError {
|
|
86
|
+
constructor(message, field, value) {
|
|
87
|
+
super(message);
|
|
88
|
+
this.field = field;
|
|
89
|
+
this.value = value;
|
|
90
|
+
this.name = "FakexyValidationError";
|
|
91
|
+
Object.setPrototypeOf(this, _FakexyValidationError.prototype);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/fetch.ts
|
|
96
|
+
var DEFAULT_TIMEOUT = 1e4;
|
|
97
|
+
var DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; fakexy-to-json/1.0; +https://github.com/MaxioN03/fakexy-to-json)";
|
|
98
|
+
async function fetchHtml(url, options = {}) {
|
|
99
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
100
|
+
const headers = {
|
|
101
|
+
"User-Agent": DEFAULT_USER_AGENT,
|
|
102
|
+
Accept: "text/html,application/xhtml+xml",
|
|
103
|
+
...options.headers
|
|
104
|
+
};
|
|
105
|
+
const controller = new AbortController();
|
|
106
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch(url, {
|
|
109
|
+
headers,
|
|
110
|
+
signal: controller.signal
|
|
111
|
+
});
|
|
112
|
+
clearTimeout(timeoutId);
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
throw new FakexyHttpError(
|
|
115
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
116
|
+
response.status,
|
|
117
|
+
response.statusText,
|
|
118
|
+
url
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return await response.text();
|
|
122
|
+
} catch (err) {
|
|
123
|
+
clearTimeout(timeoutId);
|
|
124
|
+
if (err instanceof FakexyHttpError) {
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
const cause = err instanceof Error ? err : new Error(String(err));
|
|
128
|
+
const message = cause.name === "AbortError" ? `Request timed out after ${timeout}ms` : `Network request failed: ${cause.message}`;
|
|
129
|
+
throw new FakexyNetworkError(message, url, cause);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/parse.ts
|
|
134
|
+
var cheerio = __toESM(require("cheerio"));
|
|
135
|
+
function normalizeKey(label) {
|
|
136
|
+
return label.trim().toLowerCase().replace(/\s+/g, "_").replace(/[\/\-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
137
|
+
}
|
|
138
|
+
var LABEL_MAP = {
|
|
139
|
+
street: "street",
|
|
140
|
+
street_address: "street",
|
|
141
|
+
address: "street",
|
|
142
|
+
city: "city",
|
|
143
|
+
city_town: "city",
|
|
144
|
+
"city/town": "city",
|
|
145
|
+
state: "region",
|
|
146
|
+
state_province_region: "region",
|
|
147
|
+
"state/province/region": "region",
|
|
148
|
+
region: "region",
|
|
149
|
+
zip: "zipcode",
|
|
150
|
+
zip_postal_code: "zipcode",
|
|
151
|
+
"zip/postal_code": "zipcode",
|
|
152
|
+
zipcode: "zipcode",
|
|
153
|
+
postal_code: "zipcode",
|
|
154
|
+
phone: "phone",
|
|
155
|
+
phone_number: "phone",
|
|
156
|
+
country: "country",
|
|
157
|
+
latitude: "latitude",
|
|
158
|
+
longitude: "longitude",
|
|
159
|
+
full_name: "name",
|
|
160
|
+
name: "name",
|
|
161
|
+
gender: "gender",
|
|
162
|
+
birthday: "birthday",
|
|
163
|
+
birth_date: "birthday",
|
|
164
|
+
social_security_number: "ssn",
|
|
165
|
+
ssn: "ssn",
|
|
166
|
+
credit_card_brand: "brand",
|
|
167
|
+
brand: "brand",
|
|
168
|
+
credit_card_number: "number",
|
|
169
|
+
number: "number",
|
|
170
|
+
expire: "expire",
|
|
171
|
+
expiration: "expire",
|
|
172
|
+
cvv: "cvv"
|
|
173
|
+
};
|
|
174
|
+
function parseTablesToObject(html, url) {
|
|
175
|
+
const $ = cheerio.load(html);
|
|
176
|
+
const result = {};
|
|
177
|
+
$("table tr").each((_, row) => {
|
|
178
|
+
const cells = $(row).find("td, th").map((__, el) => $(el).text().trim()).get();
|
|
179
|
+
if (cells.length >= 2) {
|
|
180
|
+
const label = cells[0];
|
|
181
|
+
const value = cells[1];
|
|
182
|
+
if (label && value) {
|
|
183
|
+
const key = normalizeKey(label);
|
|
184
|
+
const canonicalKey = LABEL_MAP[key] ?? key;
|
|
185
|
+
result[canonicalKey] = value;
|
|
186
|
+
}
|
|
187
|
+
} else if (cells.length === 1) {
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
if (Object.keys(result).length === 0) {
|
|
191
|
+
throw new FakexyParseError(
|
|
192
|
+
"Could not parse any data from the page. The site structure may have changed.",
|
|
193
|
+
url
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/url.ts
|
|
200
|
+
var BASE_URL = "https://www.fakexy.com/";
|
|
201
|
+
var SUPPORTED_COUNTRIES = [
|
|
202
|
+
"ar",
|
|
203
|
+
"au",
|
|
204
|
+
"bd",
|
|
205
|
+
"be",
|
|
206
|
+
"br",
|
|
207
|
+
"ca",
|
|
208
|
+
"cn",
|
|
209
|
+
"cz",
|
|
210
|
+
"fr",
|
|
211
|
+
"de",
|
|
212
|
+
"gr",
|
|
213
|
+
"hu",
|
|
214
|
+
"in",
|
|
215
|
+
"id",
|
|
216
|
+
"ir",
|
|
217
|
+
"it",
|
|
218
|
+
"jp",
|
|
219
|
+
"my",
|
|
220
|
+
"mx",
|
|
221
|
+
"np",
|
|
222
|
+
"nl",
|
|
223
|
+
"ng",
|
|
224
|
+
"pe",
|
|
225
|
+
"ph",
|
|
226
|
+
"pl",
|
|
227
|
+
"pt",
|
|
228
|
+
"ro",
|
|
229
|
+
"ru",
|
|
230
|
+
"sa",
|
|
231
|
+
"sg",
|
|
232
|
+
"kr",
|
|
233
|
+
"es",
|
|
234
|
+
"se",
|
|
235
|
+
"th",
|
|
236
|
+
"tr",
|
|
237
|
+
"ug",
|
|
238
|
+
"ua",
|
|
239
|
+
"uk",
|
|
240
|
+
"us",
|
|
241
|
+
"vn"
|
|
242
|
+
];
|
|
243
|
+
var SUPPORTED_CREDIT_CARD_BRANDS = [
|
|
244
|
+
"visa",
|
|
245
|
+
"mastercard",
|
|
246
|
+
"amex",
|
|
247
|
+
"discover"
|
|
248
|
+
];
|
|
249
|
+
function buildAddressUrl(countryCode, stateCode) {
|
|
250
|
+
const code = (countryCode ?? "us").toLowerCase();
|
|
251
|
+
if (stateCode) {
|
|
252
|
+
return `${BASE_URL}${code}-fake-address-generator-${stateCode.toLowerCase()}`;
|
|
253
|
+
}
|
|
254
|
+
return `${BASE_URL}fake-address-generator-${code}`;
|
|
255
|
+
}
|
|
256
|
+
function buildProfileUrl(countryCode, stateCode) {
|
|
257
|
+
const code = (countryCode ?? "us").toLowerCase();
|
|
258
|
+
if (stateCode) {
|
|
259
|
+
return `${BASE_URL}${code}-fake-name-generator-${stateCode.toLowerCase()}`;
|
|
260
|
+
}
|
|
261
|
+
return `${BASE_URL}fake-name-generator-${code}`;
|
|
262
|
+
}
|
|
263
|
+
function buildCreditCardUrl(brand) {
|
|
264
|
+
const b = (brand ?? "visa").toLowerCase();
|
|
265
|
+
return `${BASE_URL}fake-creditcard-generator-${b}`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/generators/address.ts
|
|
269
|
+
function mapRawToAddress(raw) {
|
|
270
|
+
const result = {
|
|
271
|
+
street: raw.street ?? raw.address ?? "",
|
|
272
|
+
city: raw.city ?? "",
|
|
273
|
+
region: raw.region ?? raw.state ?? "",
|
|
274
|
+
zipcode: raw.zipcode ?? raw.zip ?? raw.postal_code ?? "",
|
|
275
|
+
phone: raw.phone ?? raw.phone_number ?? "",
|
|
276
|
+
country: raw.country ?? ""
|
|
277
|
+
};
|
|
278
|
+
if (raw.latitude) result.latitude = raw.latitude;
|
|
279
|
+
if (raw.longitude) result.longitude = raw.longitude;
|
|
280
|
+
if (raw.name || raw.full_name) {
|
|
281
|
+
result.person = {
|
|
282
|
+
name: raw.name ?? raw.full_name ?? "",
|
|
283
|
+
gender: raw.gender ?? "",
|
|
284
|
+
birthday: raw.birthday ?? raw.birth_date ?? "",
|
|
285
|
+
ssn: raw.ssn ?? raw.social_security_number ?? ""
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
if (raw.brand || raw.number) {
|
|
289
|
+
result.creditcard = {
|
|
290
|
+
brand: raw.brand ?? raw.credit_card_brand ?? "",
|
|
291
|
+
number: raw.number ?? raw.credit_card_number ?? "",
|
|
292
|
+
expire: raw.expire ?? raw.expiration ?? "",
|
|
293
|
+
cvv: raw.cvv ?? ""
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
function parseAddressFromHtml(html, url) {
|
|
299
|
+
const raw = parseTablesToObject(html, url);
|
|
300
|
+
return mapRawToAddress(raw);
|
|
301
|
+
}
|
|
302
|
+
async function getAddress(options) {
|
|
303
|
+
const url = buildAddressUrl(options?.countryCode, options?.stateCode);
|
|
304
|
+
const html = await fetchHtml(url, {
|
|
305
|
+
headers: options?.headers,
|
|
306
|
+
timeout: options?.timeout
|
|
307
|
+
});
|
|
308
|
+
return parseAddressFromHtml(html, url);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/generators/profile.ts
|
|
312
|
+
function mapRawToPerson(raw) {
|
|
313
|
+
return {
|
|
314
|
+
name: raw.name ?? raw.full_name ?? "",
|
|
315
|
+
gender: raw.gender ?? "",
|
|
316
|
+
birthday: raw.birthday ?? raw.birth_date ?? "",
|
|
317
|
+
ssn: raw.ssn ?? raw.social_security_number ?? ""
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async function getProfile(options) {
|
|
321
|
+
const url = buildProfileUrl(options?.countryCode, options?.stateCode);
|
|
322
|
+
const html = await fetchHtml(url, {
|
|
323
|
+
headers: options?.headers,
|
|
324
|
+
timeout: options?.timeout
|
|
325
|
+
});
|
|
326
|
+
const raw = parseTablesToObject(html, url);
|
|
327
|
+
return mapRawToPerson(raw);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/generators/creditcard.ts
|
|
331
|
+
function mapRawToCreditCard(raw) {
|
|
332
|
+
return {
|
|
333
|
+
brand: raw.brand ?? raw.credit_card_brand ?? "",
|
|
334
|
+
number: raw.number ?? raw.credit_card_number ?? "",
|
|
335
|
+
expire: raw.expire ?? raw.expiration ?? "",
|
|
336
|
+
cvv: raw.cvv ?? ""
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async function getCreditCard(options) {
|
|
340
|
+
const url = buildCreditCardUrl(options?.brand);
|
|
341
|
+
const html = await fetchHtml(url, {
|
|
342
|
+
headers: options?.headers,
|
|
343
|
+
timeout: options?.timeout
|
|
344
|
+
});
|
|
345
|
+
const raw = parseTablesToObject(html, url);
|
|
346
|
+
return mapRawToCreditCard(raw);
|
|
347
|
+
}
|
|
348
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
349
|
+
0 && (module.exports = {
|
|
350
|
+
FakexyError,
|
|
351
|
+
FakexyHttpError,
|
|
352
|
+
FakexyNetworkError,
|
|
353
|
+
FakexyParseError,
|
|
354
|
+
FakexyValidationError,
|
|
355
|
+
SUPPORTED_COUNTRIES,
|
|
356
|
+
SUPPORTED_CREDIT_CARD_BRANDS,
|
|
357
|
+
buildAddressUrl,
|
|
358
|
+
buildCreditCardUrl,
|
|
359
|
+
buildProfileUrl,
|
|
360
|
+
getAddress,
|
|
361
|
+
getCreditCard,
|
|
362
|
+
getProfile,
|
|
363
|
+
parseAddressFromHtml
|
|
364
|
+
});
|
|
365
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/fetch.ts","../src/parse.ts","../src/url.ts","../src/generators/address.ts","../src/generators/profile.ts","../src/generators/creditcard.ts"],"sourcesContent":["/**\n * fakexy-to-json\n *\n * Fetch and parse fakexy.com data to JSON.\n * Supports fake addresses, profiles, and credit cards by country.\n *\n * @packageDocumentation\n */\n\nexport { getAddress, parseAddressFromHtml } from './generators/address.js';\nexport { getProfile } from './generators/profile.js';\nexport { getCreditCard } from './generators/creditcard.js';\n\nexport {\n FakexyError,\n FakexyNetworkError,\n FakexyHttpError,\n FakexyParseError,\n FakexyValidationError,\n} from './errors.js';\n\nexport {\n buildAddressUrl,\n buildProfileUrl,\n buildCreditCardUrl,\n SUPPORTED_COUNTRIES,\n SUPPORTED_CREDIT_CARD_BRANDS,\n} from './url.js';\n\nexport type {\n AddressResult,\n PersonResult,\n CreditCardResult,\n AddressOptions,\n ProfileOptions,\n CreditCardOptions,\n BaseOptions,\n} from './types.js';\n\nexport type { SupportedCountryCode, SupportedCreditCardBrand } from './url.js';\n","/**\n * Base error class for all fakexy-to-json errors.\n */\nexport class FakexyError extends Error {\n override name = 'FakexyError';\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, FakexyError.prototype);\n }\n}\n\n/**\n * Thrown when a network request fails (fetch error, timeout).\n */\nexport class FakexyNetworkError extends FakexyError {\n override name = 'FakexyNetworkError';\n\n constructor(\n message: string,\n public readonly url: string,\n public readonly cause?: Error,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyNetworkError.prototype);\n }\n}\n\n/**\n * Thrown when the server returns an error status (403, 404, 5xx).\n */\nexport class FakexyHttpError extends FakexyError {\n override name = 'FakexyHttpError';\n\n constructor(\n message: string,\n public readonly status: number,\n public readonly statusText: string,\n public readonly url: string,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyHttpError.prototype);\n }\n}\n\n/**\n * Thrown when the HTML structure has changed and cannot be parsed.\n */\nexport class FakexyParseError extends FakexyError {\n override name = 'FakexyParseError';\n\n constructor(\n message: string,\n public readonly url?: string,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyParseError.prototype);\n }\n}\n\n/**\n * Thrown when options are invalid (e.g. invalid countryCode, brand).\n */\nexport class FakexyValidationError extends FakexyError {\n override name = 'FakexyValidationError';\n\n constructor(\n message: string,\n public readonly field: string,\n public readonly value: unknown,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyValidationError.prototype);\n }\n}\n","import { FakexyHttpError, FakexyNetworkError } from './errors.js';\n\nconst DEFAULT_TIMEOUT = 10000;\nconst DEFAULT_USER_AGENT =\n 'Mozilla/5.0 (compatible; fakexy-to-json/1.0; +https://github.com/MaxioN03/fakexy-to-json)';\n\nexport interface FetchOptions {\n headers?: Record<string, string>;\n timeout?: number;\n}\n\n/**\n * Fetch HTML from a URL with timeout and custom headers.\n * @throws {FakexyNetworkError} When fetch fails or times out\n * @throws {FakexyHttpError} When response status is not ok (4xx, 5xx)\n */\nexport async function fetchHtml(\n url: string,\n options: FetchOptions = {},\n): Promise<string> {\n const timeout = options.timeout ?? DEFAULT_TIMEOUT;\n const headers: Record<string, string> = {\n 'User-Agent': DEFAULT_USER_AGENT,\n Accept: 'text/html,application/xhtml+xml',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n headers,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new FakexyHttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url,\n );\n }\n\n return await response.text();\n } catch (err) {\n clearTimeout(timeoutId);\n\n if (err instanceof FakexyHttpError) {\n throw err;\n }\n\n const cause = err instanceof Error ? err : new Error(String(err));\n const message =\n cause.name === 'AbortError'\n ? `Request timed out after ${timeout}ms`\n : `Network request failed: ${cause.message}`;\n\n throw new FakexyNetworkError(message, url, cause);\n }\n}\n","import * as cheerio from 'cheerio';\nimport { FakexyParseError } from './errors.js';\n\n/**\n * Normalize a label to a consistent key format.\n */\nfunction normalizeKey(label: string): string {\n return label\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, '_')\n .replace(/[\\/\\-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '');\n}\n\n/**\n * Map common fakexy.com label variations to our canonical keys.\n */\nconst LABEL_MAP: Record<string, string> = {\n street: 'street',\n street_address: 'street',\n address: 'street',\n city: 'city',\n city_town: 'city',\n 'city/town': 'city',\n state: 'region',\n state_province_region: 'region',\n 'state/province/region': 'region',\n region: 'region',\n zip: 'zipcode',\n zip_postal_code: 'zipcode',\n 'zip/postal_code': 'zipcode',\n zipcode: 'zipcode',\n postal_code: 'zipcode',\n phone: 'phone',\n phone_number: 'phone',\n country: 'country',\n latitude: 'latitude',\n longitude: 'longitude',\n full_name: 'name',\n name: 'name',\n gender: 'gender',\n birthday: 'birthday',\n birth_date: 'birthday',\n social_security_number: 'ssn',\n ssn: 'ssn',\n credit_card_brand: 'brand',\n brand: 'brand',\n credit_card_number: 'number',\n number: 'number',\n expire: 'expire',\n expiration: 'expire',\n cvv: 'cvv',\n};\n\n/**\n * Extract key-value pairs from HTML tables.\n * fakexy.com uses tables with label (th/td) and value (td) cells.\n */\nexport function parseTablesToObject(\n html: string,\n url?: string,\n): Record<string, string> {\n const $ = cheerio.load(html);\n const result: Record<string, string> = {};\n\n $('table tr').each((_, row) => {\n const cells = $(row)\n .find('td, th')\n .map((__, el) => $(el).text().trim())\n .get();\n\n if (cells.length >= 2) {\n const label = cells[0];\n const value = cells[1];\n if (label && value) {\n const key = normalizeKey(label);\n const canonicalKey = LABEL_MAP[key] ?? key;\n result[canonicalKey] = value;\n }\n } else if (cells.length === 1) {\n // Some rows might have single cell - skip or use as key for next row\n // For now we skip\n }\n });\n\n if (Object.keys(result).length === 0) {\n throw new FakexyParseError(\n 'Could not parse any data from the page. The site structure may have changed.',\n url,\n );\n }\n\n return result;\n}\n","const BASE_URL = 'https://www.fakexy.com/';\n\n/**\n * Supported country codes for fakexy.com generators.\n * Based on the site's URL structure.\n */\nexport const SUPPORTED_COUNTRIES = [\n 'ar',\n 'au',\n 'bd',\n 'be',\n 'br',\n 'ca',\n 'cn',\n 'cz',\n 'fr',\n 'de',\n 'gr',\n 'hu',\n 'in',\n 'id',\n 'ir',\n 'it',\n 'jp',\n 'my',\n 'mx',\n 'np',\n 'nl',\n 'ng',\n 'pe',\n 'ph',\n 'pl',\n 'pt',\n 'ro',\n 'ru',\n 'sa',\n 'sg',\n 'kr',\n 'es',\n 'se',\n 'th',\n 'tr',\n 'ug',\n 'ua',\n 'uk',\n 'us',\n 'vn',\n] as const;\n\nexport type SupportedCountryCode = (typeof SUPPORTED_COUNTRIES)[number];\n\n/**\n * Supported credit card brands.\n */\nexport const SUPPORTED_CREDIT_CARD_BRANDS = [\n 'visa',\n 'mastercard',\n 'amex',\n 'discover',\n] as const;\n\nexport type SupportedCreditCardBrand =\n (typeof SUPPORTED_CREDIT_CARD_BRANDS)[number];\n\n/**\n * Build URL for address generator.\n */\nexport function buildAddressUrl(\n countryCode?: string,\n stateCode?: string,\n): string {\n const code = (countryCode ?? 'us').toLowerCase();\n if (stateCode) {\n // US and UK use regional URLs: us-fake-address-generator-ca, uk-fake-address-generator-south-humberside\n return `${BASE_URL}${code}-fake-address-generator-${stateCode.toLowerCase()}`;\n }\n return `${BASE_URL}fake-address-generator-${code}`;\n}\n\n/**\n * Build URL for profile/name generator.\n */\nexport function buildProfileUrl(\n countryCode?: string,\n stateCode?: string,\n): string {\n const code = (countryCode ?? 'us').toLowerCase();\n if (stateCode) {\n return `${BASE_URL}${code}-fake-name-generator-${stateCode.toLowerCase()}`;\n }\n return `${BASE_URL}fake-name-generator-${code}`;\n}\n\n/**\n * Build URL for credit card generator.\n */\nexport function buildCreditCardUrl(brand?: string): string {\n const b = (brand ?? 'visa').toLowerCase();\n return `${BASE_URL}fake-creditcard-generator-${b}`;\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildAddressUrl } from '../url.js';\nimport type { AddressOptions, AddressResult } from '../types.js';\n\nfunction mapRawToAddress(raw: Record<string, string>): AddressResult {\n const result: AddressResult = {\n street: raw.street ?? raw.address ?? '',\n city: raw.city ?? '',\n region: raw.region ?? raw.state ?? '',\n zipcode: raw.zipcode ?? raw.zip ?? raw.postal_code ?? '',\n phone: raw.phone ?? raw.phone_number ?? '',\n country: raw.country ?? '',\n };\n\n if (raw.latitude) result.latitude = raw.latitude;\n if (raw.longitude) result.longitude = raw.longitude;\n\n if (raw.name || raw.full_name) {\n result.person = {\n name: raw.name ?? raw.full_name ?? '',\n gender: raw.gender ?? '',\n birthday: raw.birthday ?? raw.birth_date ?? '',\n ssn: raw.ssn ?? raw.social_security_number ?? '',\n };\n }\n\n if (raw.brand || raw.number) {\n result.creditcard = {\n brand: raw.brand ?? raw.credit_card_brand ?? '',\n number: raw.number ?? raw.credit_card_number ?? '',\n expire: raw.expire ?? raw.expiration ?? '',\n cvv: raw.cvv ?? '',\n };\n }\n\n return result;\n}\n\n/**\n * Parses address HTML from fakexy.com into AddressResult.\n * Use when you have HTML from a fetch (e.g. from page context).\n */\nexport function parseAddressFromHtml(\n html: string,\n url?: string,\n): AddressResult {\n const raw = parseTablesToObject(html, url);\n return mapRawToAddress(raw);\n}\n\n/**\n * Fetches a fake address from fakexy.com for the given country.\n *\n * @param options - Country code and optional state/region\n * @returns Parsed address with street, city, zip, phone, and optionally person/creditcard\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getAddress(\n options?: AddressOptions,\n): Promise<AddressResult> {\n const url = buildAddressUrl(options?.countryCode, options?.stateCode);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n return parseAddressFromHtml(html, url);\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildProfileUrl } from '../url.js';\nimport type { PersonResult, ProfileOptions } from '../types.js';\n\nfunction mapRawToPerson(raw: Record<string, string>): PersonResult {\n return {\n name: raw.name ?? raw.full_name ?? '',\n gender: raw.gender ?? '',\n birthday: raw.birthday ?? raw.birth_date ?? '',\n ssn: raw.ssn ?? raw.social_security_number ?? '',\n };\n}\n\n/**\n * Fetches a fake person profile from fakexy.com.\n *\n * @param options - Country code and optional state (for US)\n * @returns Parsed profile with name, gender, birthday, SSN\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getProfile(\n options?: ProfileOptions,\n): Promise<PersonResult> {\n const url = buildProfileUrl(options?.countryCode, options?.stateCode);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n const raw = parseTablesToObject(html, url);\n return mapRawToPerson(raw);\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildCreditCardUrl } from '../url.js';\nimport type { CreditCardOptions, CreditCardResult } from '../types.js';\n\nfunction mapRawToCreditCard(raw: Record<string, string>): CreditCardResult {\n return {\n brand: raw.brand ?? raw.credit_card_brand ?? '',\n number: raw.number ?? raw.credit_card_number ?? '',\n expire: raw.expire ?? raw.expiration ?? '',\n cvv: raw.cvv ?? '',\n };\n}\n\n/**\n * Fetches a fake credit card from fakexy.com.\n *\n * @param options - Card brand (visa, mastercard, etc.)\n * @returns Parsed credit card with brand, number, expire, cvv\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getCreditCard(\n options?: CreditCardOptions,\n): Promise<CreditCardResult> {\n const url = buildCreditCardUrl(options?.brand);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n const raw = parseTablesToObject(html, url);\n return mapRawToCreditCard(raw);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,cAAN,MAAM,qBAAoB,MAAM;AAAA,EAGrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AAHf,SAAS,OAAO;AAId,WAAO,eAAe,MAAM,aAAY,SAAS;AAAA,EACnD;AACF;AAKO,IAAM,qBAAN,MAAM,4BAA2B,YAAY;AAAA,EAGlD,YACE,SACgB,KACA,OAChB;AACA,UAAM,OAAO;AAHG;AACA;AALlB,SAAS,OAAO;AAQd,WAAO,eAAe,MAAM,oBAAmB,SAAS;AAAA,EAC1D;AACF;AAKO,IAAM,kBAAN,MAAM,yBAAwB,YAAY;AAAA,EAG/C,YACE,SACgB,QACA,YACA,KAChB;AACA,UAAM,OAAO;AAJG;AACA;AACA;AANlB,SAAS,OAAO;AASd,WAAO,eAAe,MAAM,iBAAgB,SAAS;AAAA,EACvD;AACF;AAKO,IAAM,mBAAN,MAAM,0BAAyB,YAAY;AAAA,EAGhD,YACE,SACgB,KAChB;AACA,UAAM,OAAO;AAFG;AAJlB,SAAS,OAAO;AAOd,WAAO,eAAe,MAAM,kBAAiB,SAAS;AAAA,EACxD;AACF;AAKO,IAAM,wBAAN,MAAM,+BAA8B,YAAY;AAAA,EAGrD,YACE,SACgB,OACA,OAChB;AACA,UAAM,OAAO;AAHG;AACA;AALlB,SAAS,OAAO;AAQd,WAAO,eAAe,MAAM,uBAAsB,SAAS;AAAA,EAC7D;AACF;;;ACxEA,IAAM,kBAAkB;AACxB,IAAM,qBACJ;AAYF,eAAsB,UACpB,KACA,UAAwB,CAAC,GACR;AACjB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,UAAkC;AAAA,IACtC,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,GAAG,QAAQ;AAAA,EACb;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAE9D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC;AAAA,MACA,QAAQ,WAAW;AAAA,IACrB,CAAC;AACD,iBAAa,SAAS;AAEtB,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,QAC/C,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,SAAS,KAAK;AACZ,iBAAa,SAAS;AAEtB,QAAI,eAAe,iBAAiB;AAClC,YAAM;AAAA,IACR;AAEA,UAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,UAAM,UACJ,MAAM,SAAS,eACX,2BAA2B,OAAO,OAClC,2BAA2B,MAAM,OAAO;AAE9C,UAAM,IAAI,mBAAmB,SAAS,KAAK,KAAK;AAAA,EAClD;AACF;;;AC9DA,cAAyB;AAMzB,SAAS,aAAa,OAAuB;AAC3C,SAAO,MACJ,KAAK,EACL,YAAY,EACZ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,WAAW,GAAG,EACtB,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE;AACzB;AAKA,IAAM,YAAoC;AAAA,EACxC,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,MAAM;AAAA,EACN,WAAW;AAAA,EACX,aAAa;AAAA,EACb,OAAO;AAAA,EACP,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,aAAa;AAAA,EACb,OAAO;AAAA,EACP,cAAc;AAAA,EACd,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,wBAAwB;AAAA,EACxB,KAAK;AAAA,EACL,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,oBAAoB;AAAA,EACpB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,KAAK;AACP;AAMO,SAAS,oBACd,MACA,KACwB;AACxB,QAAM,IAAY,aAAK,IAAI;AAC3B,QAAM,SAAiC,CAAC;AAExC,IAAE,UAAU,EAAE,KAAK,CAAC,GAAG,QAAQ;AAC7B,UAAM,QAAQ,EAAE,GAAG,EAChB,KAAK,QAAQ,EACb,IAAI,CAAC,IAAI,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,EACnC,IAAI;AAEP,QAAI,MAAM,UAAU,GAAG;AACrB,YAAM,QAAQ,MAAM,CAAC;AACrB,YAAM,QAAQ,MAAM,CAAC;AACrB,UAAI,SAAS,OAAO;AAClB,cAAM,MAAM,aAAa,KAAK;AAC9B,cAAM,eAAe,UAAU,GAAG,KAAK;AACvC,eAAO,YAAY,IAAI;AAAA,MACzB;AAAA,IACF,WAAW,MAAM,WAAW,GAAG;AAAA,IAG/B;AAAA,EACF,CAAC;AAED,MAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC/FA,IAAM,WAAW;AAMV,IAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,IAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,gBACd,aACA,WACQ;AACR,QAAM,QAAQ,eAAe,MAAM,YAAY;AAC/C,MAAI,WAAW;AAEb,WAAO,GAAG,QAAQ,GAAG,IAAI,2BAA2B,UAAU,YAAY,CAAC;AAAA,EAC7E;AACA,SAAO,GAAG,QAAQ,0BAA0B,IAAI;AAClD;AAKO,SAAS,gBACd,aACA,WACQ;AACR,QAAM,QAAQ,eAAe,MAAM,YAAY;AAC/C,MAAI,WAAW;AACb,WAAO,GAAG,QAAQ,GAAG,IAAI,wBAAwB,UAAU,YAAY,CAAC;AAAA,EAC1E;AACA,SAAO,GAAG,QAAQ,uBAAuB,IAAI;AAC/C;AAKO,SAAS,mBAAmB,OAAwB;AACzD,QAAM,KAAK,SAAS,QAAQ,YAAY;AACxC,SAAO,GAAG,QAAQ,6BAA6B,CAAC;AAClD;;;AC9FA,SAAS,gBAAgB,KAA4C;AACnE,QAAM,SAAwB;AAAA,IAC5B,QAAQ,IAAI,UAAU,IAAI,WAAW;AAAA,IACrC,MAAM,IAAI,QAAQ;AAAA,IAClB,QAAQ,IAAI,UAAU,IAAI,SAAS;AAAA,IACnC,SAAS,IAAI,WAAW,IAAI,OAAO,IAAI,eAAe;AAAA,IACtD,OAAO,IAAI,SAAS,IAAI,gBAAgB;AAAA,IACxC,SAAS,IAAI,WAAW;AAAA,EAC1B;AAEA,MAAI,IAAI,SAAU,QAAO,WAAW,IAAI;AACxC,MAAI,IAAI,UAAW,QAAO,YAAY,IAAI;AAE1C,MAAI,IAAI,QAAQ,IAAI,WAAW;AAC7B,WAAO,SAAS;AAAA,MACd,MAAM,IAAI,QAAQ,IAAI,aAAa;AAAA,MACnC,QAAQ,IAAI,UAAU;AAAA,MACtB,UAAU,IAAI,YAAY,IAAI,cAAc;AAAA,MAC5C,KAAK,IAAI,OAAO,IAAI,0BAA0B;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,IAAI,SAAS,IAAI,QAAQ;AAC3B,WAAO,aAAa;AAAA,MAClB,OAAO,IAAI,SAAS,IAAI,qBAAqB;AAAA,MAC7C,QAAQ,IAAI,UAAU,IAAI,sBAAsB;AAAA,MAChD,QAAQ,IAAI,UAAU,IAAI,cAAc;AAAA,MACxC,KAAK,IAAI,OAAO;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,qBACd,MACA,KACe;AACf,QAAM,MAAM,oBAAoB,MAAM,GAAG;AACzC,SAAO,gBAAgB,GAAG;AAC5B;AAWA,eAAsB,WACpB,SACwB;AACxB,QAAM,MAAM,gBAAgB,SAAS,aAAa,SAAS,SAAS;AACpE,QAAM,OAAO,MAAM,UAAU,KAAK;AAAA,IAChC,SAAS,SAAS;AAAA,IAClB,SAAS,SAAS;AAAA,EACpB,CAAC;AACD,SAAO,qBAAqB,MAAM,GAAG;AACvC;;;AChEA,SAAS,eAAe,KAA2C;AACjE,SAAO;AAAA,IACL,MAAM,IAAI,QAAQ,IAAI,aAAa;AAAA,IACnC,QAAQ,IAAI,UAAU;AAAA,IACtB,UAAU,IAAI,YAAY,IAAI,cAAc;AAAA,IAC5C,KAAK,IAAI,OAAO,IAAI,0BAA0B;AAAA,EAChD;AACF;AAWA,eAAsB,WACpB,SACuB;AACvB,QAAM,MAAM,gBAAgB,SAAS,aAAa,SAAS,SAAS;AACpE,QAAM,OAAO,MAAM,UAAU,KAAK;AAAA,IAChC,SAAS,SAAS;AAAA,IAClB,SAAS,SAAS;AAAA,EACpB,CAAC;AACD,QAAM,MAAM,oBAAoB,MAAM,GAAG;AACzC,SAAO,eAAe,GAAG;AAC3B;;;AC5BA,SAAS,mBAAmB,KAA+C;AACzE,SAAO;AAAA,IACL,OAAO,IAAI,SAAS,IAAI,qBAAqB;AAAA,IAC7C,QAAQ,IAAI,UAAU,IAAI,sBAAsB;AAAA,IAChD,QAAQ,IAAI,UAAU,IAAI,cAAc;AAAA,IACxC,KAAK,IAAI,OAAO;AAAA,EAClB;AACF;AAWA,eAAsB,cACpB,SAC2B;AAC3B,QAAM,MAAM,mBAAmB,SAAS,KAAK;AAC7C,QAAM,OAAO,MAAM,UAAU,KAAK;AAAA,IAChC,SAAS,SAAS;AAAA,IAClB,SAAS,SAAS;AAAA,EACpB,CAAC;AACD,QAAM,MAAM,oBAAoB,MAAM,GAAG;AACzC,SAAO,mBAAmB,GAAG;AAC/B;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var FakexyError = class _FakexyError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "FakexyError";
|
|
6
|
+
Object.setPrototypeOf(this, _FakexyError.prototype);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
var FakexyNetworkError = class _FakexyNetworkError extends FakexyError {
|
|
10
|
+
constructor(message, url, cause) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.url = url;
|
|
13
|
+
this.cause = cause;
|
|
14
|
+
this.name = "FakexyNetworkError";
|
|
15
|
+
Object.setPrototypeOf(this, _FakexyNetworkError.prototype);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var FakexyHttpError = class _FakexyHttpError extends FakexyError {
|
|
19
|
+
constructor(message, status, statusText, url) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.status = status;
|
|
22
|
+
this.statusText = statusText;
|
|
23
|
+
this.url = url;
|
|
24
|
+
this.name = "FakexyHttpError";
|
|
25
|
+
Object.setPrototypeOf(this, _FakexyHttpError.prototype);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var FakexyParseError = class _FakexyParseError extends FakexyError {
|
|
29
|
+
constructor(message, url) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.url = url;
|
|
32
|
+
this.name = "FakexyParseError";
|
|
33
|
+
Object.setPrototypeOf(this, _FakexyParseError.prototype);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var FakexyValidationError = class _FakexyValidationError extends FakexyError {
|
|
37
|
+
constructor(message, field, value) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.field = field;
|
|
40
|
+
this.value = value;
|
|
41
|
+
this.name = "FakexyValidationError";
|
|
42
|
+
Object.setPrototypeOf(this, _FakexyValidationError.prototype);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/fetch.ts
|
|
47
|
+
var DEFAULT_TIMEOUT = 1e4;
|
|
48
|
+
var DEFAULT_USER_AGENT = "Mozilla/5.0 (compatible; fakexy-to-json/1.0; +https://github.com/MaxioN03/fakexy-to-json)";
|
|
49
|
+
async function fetchHtml(url, options = {}) {
|
|
50
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
51
|
+
const headers = {
|
|
52
|
+
"User-Agent": DEFAULT_USER_AGENT,
|
|
53
|
+
Accept: "text/html,application/xhtml+xml",
|
|
54
|
+
...options.headers
|
|
55
|
+
};
|
|
56
|
+
const controller = new AbortController();
|
|
57
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
headers,
|
|
61
|
+
signal: controller.signal
|
|
62
|
+
});
|
|
63
|
+
clearTimeout(timeoutId);
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new FakexyHttpError(
|
|
66
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
67
|
+
response.status,
|
|
68
|
+
response.statusText,
|
|
69
|
+
url
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return await response.text();
|
|
73
|
+
} catch (err) {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
if (err instanceof FakexyHttpError) {
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
const cause = err instanceof Error ? err : new Error(String(err));
|
|
79
|
+
const message = cause.name === "AbortError" ? `Request timed out after ${timeout}ms` : `Network request failed: ${cause.message}`;
|
|
80
|
+
throw new FakexyNetworkError(message, url, cause);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/parse.ts
|
|
85
|
+
import * as cheerio from "cheerio";
|
|
86
|
+
function normalizeKey(label) {
|
|
87
|
+
return label.trim().toLowerCase().replace(/\s+/g, "_").replace(/[\/\-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
88
|
+
}
|
|
89
|
+
var LABEL_MAP = {
|
|
90
|
+
street: "street",
|
|
91
|
+
street_address: "street",
|
|
92
|
+
address: "street",
|
|
93
|
+
city: "city",
|
|
94
|
+
city_town: "city",
|
|
95
|
+
"city/town": "city",
|
|
96
|
+
state: "region",
|
|
97
|
+
state_province_region: "region",
|
|
98
|
+
"state/province/region": "region",
|
|
99
|
+
region: "region",
|
|
100
|
+
zip: "zipcode",
|
|
101
|
+
zip_postal_code: "zipcode",
|
|
102
|
+
"zip/postal_code": "zipcode",
|
|
103
|
+
zipcode: "zipcode",
|
|
104
|
+
postal_code: "zipcode",
|
|
105
|
+
phone: "phone",
|
|
106
|
+
phone_number: "phone",
|
|
107
|
+
country: "country",
|
|
108
|
+
latitude: "latitude",
|
|
109
|
+
longitude: "longitude",
|
|
110
|
+
full_name: "name",
|
|
111
|
+
name: "name",
|
|
112
|
+
gender: "gender",
|
|
113
|
+
birthday: "birthday",
|
|
114
|
+
birth_date: "birthday",
|
|
115
|
+
social_security_number: "ssn",
|
|
116
|
+
ssn: "ssn",
|
|
117
|
+
credit_card_brand: "brand",
|
|
118
|
+
brand: "brand",
|
|
119
|
+
credit_card_number: "number",
|
|
120
|
+
number: "number",
|
|
121
|
+
expire: "expire",
|
|
122
|
+
expiration: "expire",
|
|
123
|
+
cvv: "cvv"
|
|
124
|
+
};
|
|
125
|
+
function parseTablesToObject(html, url) {
|
|
126
|
+
const $ = cheerio.load(html);
|
|
127
|
+
const result = {};
|
|
128
|
+
$("table tr").each((_, row) => {
|
|
129
|
+
const cells = $(row).find("td, th").map((__, el) => $(el).text().trim()).get();
|
|
130
|
+
if (cells.length >= 2) {
|
|
131
|
+
const label = cells[0];
|
|
132
|
+
const value = cells[1];
|
|
133
|
+
if (label && value) {
|
|
134
|
+
const key = normalizeKey(label);
|
|
135
|
+
const canonicalKey = LABEL_MAP[key] ?? key;
|
|
136
|
+
result[canonicalKey] = value;
|
|
137
|
+
}
|
|
138
|
+
} else if (cells.length === 1) {
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
if (Object.keys(result).length === 0) {
|
|
142
|
+
throw new FakexyParseError(
|
|
143
|
+
"Could not parse any data from the page. The site structure may have changed.",
|
|
144
|
+
url
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/url.ts
|
|
151
|
+
var BASE_URL = "https://www.fakexy.com/";
|
|
152
|
+
var SUPPORTED_COUNTRIES = [
|
|
153
|
+
"ar",
|
|
154
|
+
"au",
|
|
155
|
+
"bd",
|
|
156
|
+
"be",
|
|
157
|
+
"br",
|
|
158
|
+
"ca",
|
|
159
|
+
"cn",
|
|
160
|
+
"cz",
|
|
161
|
+
"fr",
|
|
162
|
+
"de",
|
|
163
|
+
"gr",
|
|
164
|
+
"hu",
|
|
165
|
+
"in",
|
|
166
|
+
"id",
|
|
167
|
+
"ir",
|
|
168
|
+
"it",
|
|
169
|
+
"jp",
|
|
170
|
+
"my",
|
|
171
|
+
"mx",
|
|
172
|
+
"np",
|
|
173
|
+
"nl",
|
|
174
|
+
"ng",
|
|
175
|
+
"pe",
|
|
176
|
+
"ph",
|
|
177
|
+
"pl",
|
|
178
|
+
"pt",
|
|
179
|
+
"ro",
|
|
180
|
+
"ru",
|
|
181
|
+
"sa",
|
|
182
|
+
"sg",
|
|
183
|
+
"kr",
|
|
184
|
+
"es",
|
|
185
|
+
"se",
|
|
186
|
+
"th",
|
|
187
|
+
"tr",
|
|
188
|
+
"ug",
|
|
189
|
+
"ua",
|
|
190
|
+
"uk",
|
|
191
|
+
"us",
|
|
192
|
+
"vn"
|
|
193
|
+
];
|
|
194
|
+
var SUPPORTED_CREDIT_CARD_BRANDS = [
|
|
195
|
+
"visa",
|
|
196
|
+
"mastercard",
|
|
197
|
+
"amex",
|
|
198
|
+
"discover"
|
|
199
|
+
];
|
|
200
|
+
function buildAddressUrl(countryCode, stateCode) {
|
|
201
|
+
const code = (countryCode ?? "us").toLowerCase();
|
|
202
|
+
if (stateCode) {
|
|
203
|
+
return `${BASE_URL}${code}-fake-address-generator-${stateCode.toLowerCase()}`;
|
|
204
|
+
}
|
|
205
|
+
return `${BASE_URL}fake-address-generator-${code}`;
|
|
206
|
+
}
|
|
207
|
+
function buildProfileUrl(countryCode, stateCode) {
|
|
208
|
+
const code = (countryCode ?? "us").toLowerCase();
|
|
209
|
+
if (stateCode) {
|
|
210
|
+
return `${BASE_URL}${code}-fake-name-generator-${stateCode.toLowerCase()}`;
|
|
211
|
+
}
|
|
212
|
+
return `${BASE_URL}fake-name-generator-${code}`;
|
|
213
|
+
}
|
|
214
|
+
function buildCreditCardUrl(brand) {
|
|
215
|
+
const b = (brand ?? "visa").toLowerCase();
|
|
216
|
+
return `${BASE_URL}fake-creditcard-generator-${b}`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/generators/address.ts
|
|
220
|
+
function mapRawToAddress(raw) {
|
|
221
|
+
const result = {
|
|
222
|
+
street: raw.street ?? raw.address ?? "",
|
|
223
|
+
city: raw.city ?? "",
|
|
224
|
+
region: raw.region ?? raw.state ?? "",
|
|
225
|
+
zipcode: raw.zipcode ?? raw.zip ?? raw.postal_code ?? "",
|
|
226
|
+
phone: raw.phone ?? raw.phone_number ?? "",
|
|
227
|
+
country: raw.country ?? ""
|
|
228
|
+
};
|
|
229
|
+
if (raw.latitude) result.latitude = raw.latitude;
|
|
230
|
+
if (raw.longitude) result.longitude = raw.longitude;
|
|
231
|
+
if (raw.name || raw.full_name) {
|
|
232
|
+
result.person = {
|
|
233
|
+
name: raw.name ?? raw.full_name ?? "",
|
|
234
|
+
gender: raw.gender ?? "",
|
|
235
|
+
birthday: raw.birthday ?? raw.birth_date ?? "",
|
|
236
|
+
ssn: raw.ssn ?? raw.social_security_number ?? ""
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (raw.brand || raw.number) {
|
|
240
|
+
result.creditcard = {
|
|
241
|
+
brand: raw.brand ?? raw.credit_card_brand ?? "",
|
|
242
|
+
number: raw.number ?? raw.credit_card_number ?? "",
|
|
243
|
+
expire: raw.expire ?? raw.expiration ?? "",
|
|
244
|
+
cvv: raw.cvv ?? ""
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
function parseAddressFromHtml(html, url) {
|
|
250
|
+
const raw = parseTablesToObject(html, url);
|
|
251
|
+
return mapRawToAddress(raw);
|
|
252
|
+
}
|
|
253
|
+
async function getAddress(options) {
|
|
254
|
+
const url = buildAddressUrl(options?.countryCode, options?.stateCode);
|
|
255
|
+
const html = await fetchHtml(url, {
|
|
256
|
+
headers: options?.headers,
|
|
257
|
+
timeout: options?.timeout
|
|
258
|
+
});
|
|
259
|
+
return parseAddressFromHtml(html, url);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/generators/profile.ts
|
|
263
|
+
function mapRawToPerson(raw) {
|
|
264
|
+
return {
|
|
265
|
+
name: raw.name ?? raw.full_name ?? "",
|
|
266
|
+
gender: raw.gender ?? "",
|
|
267
|
+
birthday: raw.birthday ?? raw.birth_date ?? "",
|
|
268
|
+
ssn: raw.ssn ?? raw.social_security_number ?? ""
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
async function getProfile(options) {
|
|
272
|
+
const url = buildProfileUrl(options?.countryCode, options?.stateCode);
|
|
273
|
+
const html = await fetchHtml(url, {
|
|
274
|
+
headers: options?.headers,
|
|
275
|
+
timeout: options?.timeout
|
|
276
|
+
});
|
|
277
|
+
const raw = parseTablesToObject(html, url);
|
|
278
|
+
return mapRawToPerson(raw);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/generators/creditcard.ts
|
|
282
|
+
function mapRawToCreditCard(raw) {
|
|
283
|
+
return {
|
|
284
|
+
brand: raw.brand ?? raw.credit_card_brand ?? "",
|
|
285
|
+
number: raw.number ?? raw.credit_card_number ?? "",
|
|
286
|
+
expire: raw.expire ?? raw.expiration ?? "",
|
|
287
|
+
cvv: raw.cvv ?? ""
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
async function getCreditCard(options) {
|
|
291
|
+
const url = buildCreditCardUrl(options?.brand);
|
|
292
|
+
const html = await fetchHtml(url, {
|
|
293
|
+
headers: options?.headers,
|
|
294
|
+
timeout: options?.timeout
|
|
295
|
+
});
|
|
296
|
+
const raw = parseTablesToObject(html, url);
|
|
297
|
+
return mapRawToCreditCard(raw);
|
|
298
|
+
}
|
|
299
|
+
export {
|
|
300
|
+
FakexyError,
|
|
301
|
+
FakexyHttpError,
|
|
302
|
+
FakexyNetworkError,
|
|
303
|
+
FakexyParseError,
|
|
304
|
+
FakexyValidationError,
|
|
305
|
+
SUPPORTED_COUNTRIES,
|
|
306
|
+
SUPPORTED_CREDIT_CARD_BRANDS,
|
|
307
|
+
buildAddressUrl,
|
|
308
|
+
buildCreditCardUrl,
|
|
309
|
+
buildProfileUrl,
|
|
310
|
+
getAddress,
|
|
311
|
+
getCreditCard,
|
|
312
|
+
getProfile,
|
|
313
|
+
parseAddressFromHtml
|
|
314
|
+
};
|
|
315
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/fetch.ts","../src/parse.ts","../src/url.ts","../src/generators/address.ts","../src/generators/profile.ts","../src/generators/creditcard.ts"],"sourcesContent":["/**\n * Base error class for all fakexy-to-json errors.\n */\nexport class FakexyError extends Error {\n override name = 'FakexyError';\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, FakexyError.prototype);\n }\n}\n\n/**\n * Thrown when a network request fails (fetch error, timeout).\n */\nexport class FakexyNetworkError extends FakexyError {\n override name = 'FakexyNetworkError';\n\n constructor(\n message: string,\n public readonly url: string,\n public readonly cause?: Error,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyNetworkError.prototype);\n }\n}\n\n/**\n * Thrown when the server returns an error status (403, 404, 5xx).\n */\nexport class FakexyHttpError extends FakexyError {\n override name = 'FakexyHttpError';\n\n constructor(\n message: string,\n public readonly status: number,\n public readonly statusText: string,\n public readonly url: string,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyHttpError.prototype);\n }\n}\n\n/**\n * Thrown when the HTML structure has changed and cannot be parsed.\n */\nexport class FakexyParseError extends FakexyError {\n override name = 'FakexyParseError';\n\n constructor(\n message: string,\n public readonly url?: string,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyParseError.prototype);\n }\n}\n\n/**\n * Thrown when options are invalid (e.g. invalid countryCode, brand).\n */\nexport class FakexyValidationError extends FakexyError {\n override name = 'FakexyValidationError';\n\n constructor(\n message: string,\n public readonly field: string,\n public readonly value: unknown,\n ) {\n super(message);\n Object.setPrototypeOf(this, FakexyValidationError.prototype);\n }\n}\n","import { FakexyHttpError, FakexyNetworkError } from './errors.js';\n\nconst DEFAULT_TIMEOUT = 10000;\nconst DEFAULT_USER_AGENT =\n 'Mozilla/5.0 (compatible; fakexy-to-json/1.0; +https://github.com/MaxioN03/fakexy-to-json)';\n\nexport interface FetchOptions {\n headers?: Record<string, string>;\n timeout?: number;\n}\n\n/**\n * Fetch HTML from a URL with timeout and custom headers.\n * @throws {FakexyNetworkError} When fetch fails or times out\n * @throws {FakexyHttpError} When response status is not ok (4xx, 5xx)\n */\nexport async function fetchHtml(\n url: string,\n options: FetchOptions = {},\n): Promise<string> {\n const timeout = options.timeout ?? DEFAULT_TIMEOUT;\n const headers: Record<string, string> = {\n 'User-Agent': DEFAULT_USER_AGENT,\n Accept: 'text/html,application/xhtml+xml',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n headers,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new FakexyHttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n url,\n );\n }\n\n return await response.text();\n } catch (err) {\n clearTimeout(timeoutId);\n\n if (err instanceof FakexyHttpError) {\n throw err;\n }\n\n const cause = err instanceof Error ? err : new Error(String(err));\n const message =\n cause.name === 'AbortError'\n ? `Request timed out after ${timeout}ms`\n : `Network request failed: ${cause.message}`;\n\n throw new FakexyNetworkError(message, url, cause);\n }\n}\n","import * as cheerio from 'cheerio';\nimport { FakexyParseError } from './errors.js';\n\n/**\n * Normalize a label to a consistent key format.\n */\nfunction normalizeKey(label: string): string {\n return label\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, '_')\n .replace(/[\\/\\-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '');\n}\n\n/**\n * Map common fakexy.com label variations to our canonical keys.\n */\nconst LABEL_MAP: Record<string, string> = {\n street: 'street',\n street_address: 'street',\n address: 'street',\n city: 'city',\n city_town: 'city',\n 'city/town': 'city',\n state: 'region',\n state_province_region: 'region',\n 'state/province/region': 'region',\n region: 'region',\n zip: 'zipcode',\n zip_postal_code: 'zipcode',\n 'zip/postal_code': 'zipcode',\n zipcode: 'zipcode',\n postal_code: 'zipcode',\n phone: 'phone',\n phone_number: 'phone',\n country: 'country',\n latitude: 'latitude',\n longitude: 'longitude',\n full_name: 'name',\n name: 'name',\n gender: 'gender',\n birthday: 'birthday',\n birth_date: 'birthday',\n social_security_number: 'ssn',\n ssn: 'ssn',\n credit_card_brand: 'brand',\n brand: 'brand',\n credit_card_number: 'number',\n number: 'number',\n expire: 'expire',\n expiration: 'expire',\n cvv: 'cvv',\n};\n\n/**\n * Extract key-value pairs from HTML tables.\n * fakexy.com uses tables with label (th/td) and value (td) cells.\n */\nexport function parseTablesToObject(\n html: string,\n url?: string,\n): Record<string, string> {\n const $ = cheerio.load(html);\n const result: Record<string, string> = {};\n\n $('table tr').each((_, row) => {\n const cells = $(row)\n .find('td, th')\n .map((__, el) => $(el).text().trim())\n .get();\n\n if (cells.length >= 2) {\n const label = cells[0];\n const value = cells[1];\n if (label && value) {\n const key = normalizeKey(label);\n const canonicalKey = LABEL_MAP[key] ?? key;\n result[canonicalKey] = value;\n }\n } else if (cells.length === 1) {\n // Some rows might have single cell - skip or use as key for next row\n // For now we skip\n }\n });\n\n if (Object.keys(result).length === 0) {\n throw new FakexyParseError(\n 'Could not parse any data from the page. The site structure may have changed.',\n url,\n );\n }\n\n return result;\n}\n","const BASE_URL = 'https://www.fakexy.com/';\n\n/**\n * Supported country codes for fakexy.com generators.\n * Based on the site's URL structure.\n */\nexport const SUPPORTED_COUNTRIES = [\n 'ar',\n 'au',\n 'bd',\n 'be',\n 'br',\n 'ca',\n 'cn',\n 'cz',\n 'fr',\n 'de',\n 'gr',\n 'hu',\n 'in',\n 'id',\n 'ir',\n 'it',\n 'jp',\n 'my',\n 'mx',\n 'np',\n 'nl',\n 'ng',\n 'pe',\n 'ph',\n 'pl',\n 'pt',\n 'ro',\n 'ru',\n 'sa',\n 'sg',\n 'kr',\n 'es',\n 'se',\n 'th',\n 'tr',\n 'ug',\n 'ua',\n 'uk',\n 'us',\n 'vn',\n] as const;\n\nexport type SupportedCountryCode = (typeof SUPPORTED_COUNTRIES)[number];\n\n/**\n * Supported credit card brands.\n */\nexport const SUPPORTED_CREDIT_CARD_BRANDS = [\n 'visa',\n 'mastercard',\n 'amex',\n 'discover',\n] as const;\n\nexport type SupportedCreditCardBrand =\n (typeof SUPPORTED_CREDIT_CARD_BRANDS)[number];\n\n/**\n * Build URL for address generator.\n */\nexport function buildAddressUrl(\n countryCode?: string,\n stateCode?: string,\n): string {\n const code = (countryCode ?? 'us').toLowerCase();\n if (stateCode) {\n // US and UK use regional URLs: us-fake-address-generator-ca, uk-fake-address-generator-south-humberside\n return `${BASE_URL}${code}-fake-address-generator-${stateCode.toLowerCase()}`;\n }\n return `${BASE_URL}fake-address-generator-${code}`;\n}\n\n/**\n * Build URL for profile/name generator.\n */\nexport function buildProfileUrl(\n countryCode?: string,\n stateCode?: string,\n): string {\n const code = (countryCode ?? 'us').toLowerCase();\n if (stateCode) {\n return `${BASE_URL}${code}-fake-name-generator-${stateCode.toLowerCase()}`;\n }\n return `${BASE_URL}fake-name-generator-${code}`;\n}\n\n/**\n * Build URL for credit card generator.\n */\nexport function buildCreditCardUrl(brand?: string): string {\n const b = (brand ?? 'visa').toLowerCase();\n return `${BASE_URL}fake-creditcard-generator-${b}`;\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildAddressUrl } from '../url.js';\nimport type { AddressOptions, AddressResult } from '../types.js';\n\nfunction mapRawToAddress(raw: Record<string, string>): AddressResult {\n const result: AddressResult = {\n street: raw.street ?? raw.address ?? '',\n city: raw.city ?? '',\n region: raw.region ?? raw.state ?? '',\n zipcode: raw.zipcode ?? raw.zip ?? raw.postal_code ?? '',\n phone: raw.phone ?? raw.phone_number ?? '',\n country: raw.country ?? '',\n };\n\n if (raw.latitude) result.latitude = raw.latitude;\n if (raw.longitude) result.longitude = raw.longitude;\n\n if (raw.name || raw.full_name) {\n result.person = {\n name: raw.name ?? raw.full_name ?? '',\n gender: raw.gender ?? '',\n birthday: raw.birthday ?? raw.birth_date ?? '',\n ssn: raw.ssn ?? raw.social_security_number ?? '',\n };\n }\n\n if (raw.brand || raw.number) {\n result.creditcard = {\n brand: raw.brand ?? raw.credit_card_brand ?? '',\n number: raw.number ?? raw.credit_card_number ?? '',\n expire: raw.expire ?? raw.expiration ?? '',\n cvv: raw.cvv ?? '',\n };\n }\n\n return result;\n}\n\n/**\n * Parses address HTML from fakexy.com into AddressResult.\n * Use when you have HTML from a fetch (e.g. from page context).\n */\nexport function parseAddressFromHtml(\n html: string,\n url?: string,\n): AddressResult {\n const raw = parseTablesToObject(html, url);\n return mapRawToAddress(raw);\n}\n\n/**\n * Fetches a fake address from fakexy.com for the given country.\n *\n * @param options - Country code and optional state/region\n * @returns Parsed address with street, city, zip, phone, and optionally person/creditcard\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getAddress(\n options?: AddressOptions,\n): Promise<AddressResult> {\n const url = buildAddressUrl(options?.countryCode, options?.stateCode);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n return parseAddressFromHtml(html, url);\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildProfileUrl } from '../url.js';\nimport type { PersonResult, ProfileOptions } from '../types.js';\n\nfunction mapRawToPerson(raw: Record<string, string>): PersonResult {\n return {\n name: raw.name ?? raw.full_name ?? '',\n gender: raw.gender ?? '',\n birthday: raw.birthday ?? raw.birth_date ?? '',\n ssn: raw.ssn ?? raw.social_security_number ?? '',\n };\n}\n\n/**\n * Fetches a fake person profile from fakexy.com.\n *\n * @param options - Country code and optional state (for US)\n * @returns Parsed profile with name, gender, birthday, SSN\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getProfile(\n options?: ProfileOptions,\n): Promise<PersonResult> {\n const url = buildProfileUrl(options?.countryCode, options?.stateCode);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n const raw = parseTablesToObject(html, url);\n return mapRawToPerson(raw);\n}\n","import { fetchHtml } from '../fetch.js';\nimport { parseTablesToObject } from '../parse.js';\nimport { buildCreditCardUrl } from '../url.js';\nimport type { CreditCardOptions, CreditCardResult } from '../types.js';\n\nfunction mapRawToCreditCard(raw: Record<string, string>): CreditCardResult {\n return {\n brand: raw.brand ?? raw.credit_card_brand ?? '',\n number: raw.number ?? raw.credit_card_number ?? '',\n expire: raw.expire ?? raw.expiration ?? '',\n cvv: raw.cvv ?? '',\n };\n}\n\n/**\n * Fetches a fake credit card from fakexy.com.\n *\n * @param options - Card brand (visa, mastercard, etc.)\n * @returns Parsed credit card with brand, number, expire, cvv\n * @throws {FakexyNetworkError} When the request fails\n * @throws {FakexyHttpError} When the server returns an error status\n * @throws {FakexyParseError} When the page structure has changed\n */\nexport async function getCreditCard(\n options?: CreditCardOptions,\n): Promise<CreditCardResult> {\n const url = buildCreditCardUrl(options?.brand);\n const html = await fetchHtml(url, {\n headers: options?.headers,\n timeout: options?.timeout,\n });\n const raw = parseTablesToObject(html, url);\n return mapRawToCreditCard(raw);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fakexy-to-json",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fetch and parse fakexy.com data to JSON. Fake addresses, profiles, credit cards by country.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fakexy",
|
|
7
|
+
"fake-address",
|
|
8
|
+
"fake-address-generator",
|
|
9
|
+
"fake-data",
|
|
10
|
+
"fake-names",
|
|
11
|
+
"fake-creditcard",
|
|
12
|
+
"faker",
|
|
13
|
+
"mock",
|
|
14
|
+
"mocked"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/MaxioN03/fakexy-to-json.git"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "",
|
|
22
|
+
"homepage": "https://github.com/MaxioN03/fakexy-to-json#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/MaxioN03/fakexy-to-json/issues"
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.mjs",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.mjs",
|
|
33
|
+
"require": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"dev": "tsup --watch",
|
|
44
|
+
"prepublishOnly": "npm run build"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"cheerio": "^1.2.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^25.5.0",
|
|
51
|
+
"tsup": "^8.5.1",
|
|
52
|
+
"typescript": "^6.0.2"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18"
|
|
56
|
+
}
|
|
57
|
+
}
|