-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
115 lines (92 loc) · 2.99 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"use strict";
(function () {
const root = this;
const randomInt = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
const randomElem = (arr) => arr[randomInt(0, arr.length - 1)];
const sequenceElem = (config, sequenceOffset, charIndex) => {
const base = config.uniqueCharset.length;
return config.uniqueCharset[
Math.floor(
sequenceOffset / Math.pow(base, config.length - charIndex - 1),
) % base
];
};
const charset = (name) => {
const charsets = {
numbers: "0123456789",
alphabetic: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
alphanumeric:
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
};
return charsets[name];
};
const repeat = (str, count) => str.repeat(count);
class Config {
constructor(config = {}) {
this.count = config.count || 1;
this.length = config.length || 8;
this.charset = config.charset || charset("alphanumeric");
this.uniqueCharset = uniqueCharset(this.charset);
this.prefix = config.prefix || "";
this.postfix = config.postfix || "";
this.pattern = config.pattern || repeat("#", this.length);
if (config.pattern) {
this.length = (config.pattern.match(/#/g) || []).length;
}
}
}
const uniqueCharset = (charset) => {
const uniqueChars = new Set(charset);
return Array.from(uniqueChars).join("");
};
const generateOne = (config, sequenceOffset) => {
let generateIndex = 0;
const code = [...config.pattern]
.map((char) => {
if (char === "#") {
return isNaN(sequenceOffset)
? randomElem(config.charset)
: sequenceElem(config, sequenceOffset, generateIndex++);
}
return char;
})
.join("");
return `${config.prefix}${code}${config.postfix}`;
};
const maxCombinationsCount = (config) =>
Math.pow(config.uniqueCharset.length, config.length);
const isFeasible = (config) => maxCombinationsCount(config) >= config.count;
const generate = (config, sequenceOffset) => {
config = new Config(config);
let { count } = config;
if (!isFeasible(config)) {
throw new Error("Not possible to generate requested number of codes.");
}
sequenceOffset = Number(sequenceOffset);
if (!isNaN(sequenceOffset)) {
const maxCount = maxCombinationsCount(config);
sequenceOffset = Math.max(0, Math.min(sequenceOffset, maxCount - 1));
}
const codes = new Set();
while (codes.size < count) {
const code = generateOne(config, sequenceOffset);
codes.add(code);
sequenceOffset++;
}
return Array.from(codes);
};
const coupon_crafter = {
generate,
charset,
};
if (typeof exports !== "undefined") {
if (typeof module !== "undefined" && module.exports) {
module.exports = coupon_crafter;
} else {
exports.coupon_crafter = coupon_crafter;
}
} else {
root.coupon_crafter = coupon_crafter;
}
}).call(this);