Skip to content

Commit 5439caf

Browse files
authored
Merge pull request #51 from snaplet/feat/add-options-to-phone-number
feat: add options to phone number
2 parents 8043c3d + 536e8f4 commit 5439caf

File tree

3 files changed

+106
-3
lines changed

3 files changed

+106
-3
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,19 @@ Takes in an [input](#input) and returns a string value resembling a [phone numbe
352352
copycat.phoneNumber('foo')
353353
// => '+208438699696662'
354354
```
355+
```js
356+
copycat.phoneNumber('foo', { prefixes: ['+3319900', '+3363998'], min: 1000, max: 9999 })
357+
// => '+33639983457'
358+
```
355359

356360
**note** The strings _resemble_ phone numbers, but will not always be valid. For example, the country dialing code may not exist, or for a particular country, the number of digits may be incorrect. Please let us know if you need valid
357361
phone numbers, and feel free to contribute :)
358362

363+
#### `options`
364+
- **`min=10000000000`:** Constrain generated values to be greater than or equal to `min` allow to control the minimum number of digits in the phone number
365+
- **`max=999999999999999`:** Constrain generated values to be less than or equal to `max` allow to control the maximum number of digits in the phone number
366+
- **`prefixes`:** An array of strings that should be used as prefixes for the generated phone numbers. Allowing to control the country dialing code.
367+
359368
### `copycat.username(input)`
360369

361370
Takes in an [input](#input) and returns a string value resembling a username.

scripts/collisionsBasic.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const { v4: uuid } = require('uuid')
2+
const {copycat, fictional} = require('../dist/index')
3+
4+
const TRANSFORMATIONS = {
5+
...fictional,
6+
...copycat,
7+
}
8+
9+
const METHOD = process.env.METHOD ? process.env.METHOD : 'phoneNumber'
10+
const MAX_N = +(process.env.MAX_N ?? 999999)
11+
12+
function main() {
13+
let firstColision = null
14+
let colisions = 0
15+
const colide = new Set()
16+
for (let i = 0; i < MAX_N; i++) {
17+
const result = TRANSFORMATIONS[METHOD](uuid())
18+
if (colide.has(result)) {
19+
colisions++
20+
if (firstColision == null) {
21+
firstColision = i
22+
}
23+
} else {
24+
colide.add(result)
25+
}
26+
}
27+
console.log(`firstColision: ${firstColision} colided ${colisions} times`)
28+
}
29+
30+
main()

src/phoneNumber.ts

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,68 @@
1-
import { int } from 'fictional'
1+
import { int, oneOf } from 'fictional'
2+
import { Input } from './types'
23

3-
export const phoneNumber = (input: string) =>
4-
`+${int(input, { min: 10000000000, max: 999999999999999 })}`
4+
type PhoneNumberOptions = {
5+
/**
6+
* An array of prefixes to use when generating a phone number.
7+
* Can be used to generate a fictional phone number instead of a random one.
8+
* Using fictional phone numbers might make the generation slower. And might increase likelihood of collisions.
9+
* @example
10+
* ```ts
11+
* phoneNumber(seed, {
12+
* // Generate a French phone number within fictional phone number delimited range (cf: https://en.wikipedia.org/wiki/Fictitious_telephone_number)
13+
* prefixes: ['+3319900', '+3326191', '+3335301'],
14+
* // A french phone number is 11 digits long (including the prefix) so there is no need to generate a number longer than 4 digits
15+
* min: 1000, max: 9999
16+
* })
17+
* ```
18+
* @example
19+
*
20+
* ```ts
21+
* phoneNumber(seed, {
22+
* // Generate a New Jersey fictional phone number
23+
* prefixes: ['+201555'],
24+
* min: 1000, max: 9999
25+
* })
26+
* ```
27+
* @default undefined
28+
*/
29+
prefixes?: Array<string>
30+
/**
31+
* The minimum number to generate.
32+
* @default 10000000000
33+
*/
34+
min?: number
35+
/**
36+
* The maximum number to generate.
37+
* @default 999999999999999
38+
*/
39+
max?: number
40+
}
41+
42+
export const phoneNumber = (
43+
input: Input,
44+
options: PhoneNumberOptions = { min: 10000000000, max: 999999999999999 }
45+
) => {
46+
// Use provided min and max, or default values if not provided
47+
const min = options.min ?? 10000000000
48+
const max = options.max ?? 999999999999999
49+
50+
if (options.prefixes) {
51+
const prefix =
52+
options.prefixes.length > 1
53+
? // If multiple prefixes are provided, pick one deterministically
54+
oneOf(input, options.prefixes)
55+
: options.prefixes[0]
56+
const prefixLength = prefix.length
57+
58+
// Adjust min and max based on prefix length to keep a valid number of digits in the phone number
59+
const adjustedMin = Math.max(min, 10 ** (10 - prefixLength))
60+
const adjustedMax = Math.min(max, 10 ** (15 - prefixLength) - 1)
61+
return `${prefix}${int(input, {
62+
min: adjustedMin,
63+
max: adjustedMax,
64+
})}`
65+
}
66+
67+
return `+${int(input, { min, max })}`
68+
}

0 commit comments

Comments
 (0)