Socket
Socket
Sign inDemoInstall

randexp

Package Overview
Dependencies
1
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.6 to 0.4.7

410

lib/randexp.js

@@ -1,245 +0,259 @@

var ret = require('ret');
var DRange = require('discontinuous-range');
var types = ret.types;
'use strict';
const ret = require('ret');
const DRange = require('discontinuous-range');
const types = ret.types;
/**
* If code is alphabetic, converts to other case.
* If not alphabetic, returns back code.
*
* @param {Number} code
* @return {Number}
*/
function toOtherCase(code) {
return code + (97 <= code && code <= 122 ? -32 :
65 <= code && code <= 90 ? 32 : 0);
}
module.exports = class RandExp {
/**
* @constructor
* @param {RegExp|String} regexp
* @param {String} m
*/
constructor(regexp, m) {
this._setDefaults(regexp);
if (regexp instanceof RegExp) {
this.ignoreCase = regexp.ignoreCase;
this.multiline = regexp.multiline;
regexp = regexp.source;
/**
* Randomly returns a true or false value.
*
* @return {Boolean}
*/
function randBool() {
return !this.randInt(0, 1);
}
} else if (typeof regexp === 'string') {
this.ignoreCase = m && m.indexOf('i') !== -1;
this.multiline = m && m.indexOf('m') !== -1;
} else {
throw new Error('Expected a regexp or string');
}
/**
* Randomly selects and returns a value from the array.
*
* @param {Array.<Object>} arr
* @return {Object}
*/
function randSelect(arr) {
if (arr instanceof DRange) {
return arr.index(this.randInt(0, arr.length - 1));
this.tokens = ret(regexp);
}
return arr[this.randInt(0, arr.length - 1)];
}
/**
* expands a token to a DiscontinuousRange of characters which has a
* length and an index function (for random selecting)
*
* @param {Object} token
* @return {DiscontinuousRange}
*/
function expand(token) {
if (token.type === ret.types.CHAR) {
return new DRange(token.value);
} else if (token.type === ret.types.RANGE) {
return new DRange(token.from, token.to);
} else {
var drange = new DRange();
for (var i = 0; i < token.set.length; i++) {
var subrange = expand.call(this, token.set[i]);
drange.add(subrange);
if (this.ignoreCase) {
for (var j = 0; j < subrange.length; j++) {
var code = subrange.index(j);
var otherCaseCode = toOtherCase(code);
if (code !== otherCaseCode) {
drange.add(otherCaseCode);
}
}
}
/**
* Checks if some custom properties have been set for this regexp.
*
* @param {RandExp} randexp
* @param {RegExp} regexp
*/
_setDefaults(regexp) {
// When a repetitional token has its max set to Infinite,
// randexp won't actually generate a random amount between min and Infinite
// instead it will see Infinite as min + 100.
this.max = regexp.max != null ? regexp.max :
RandExp.prototype.max != null ? RandExp.prototype.max : 100;
// This allows expanding to include additional characters
// for instance: RandExp.defaultRange.add(0, 65535);
this.defaultRange = regexp.defaultRange ?
regexp.defaultRange : this.defaultRange.clone();
if (regexp.randInt) {
this.randInt = regexp.randInt;
}
if (token.not) {
return this.defaultRange.clone().subtract(drange);
} else {
return drange;
}
}
}
/**
* Checks if some custom properties have been set for this regexp.
*
* @param {RandExp} randexp
* @param {RegExp} regexp
*/
function checkCustom(randexp, regexp) {
if (typeof regexp.max === 'number') {
randexp.max = regexp.max;
/**
* Generates the random string.
*
* @return {String}
*/
gen() {
return this._gen(this.tokens, []);
}
if (regexp.defaultRange instanceof DRange) {
randexp.defaultRange = regexp.defaultRange;
}
if (typeof regexp.randInt === 'function') {
randexp.randInt = regexp.randInt;
}
}
/**
* @constructor
* @param {RegExp|String} regexp
* @param {String} m
*/
var RandExp = module.exports = function(regexp, m) {
this.defaultRange = this.defaultRange.clone();
if (regexp instanceof RegExp) {
this.ignoreCase = regexp.ignoreCase;
this.multiline = regexp.multiline;
checkCustom(this, regexp);
regexp = regexp.source;
/**
* Generate random string modeled after given tokens.
*
* @param {Object} token
* @param {Array.<String>} groups
* @return {String}
*/
_gen(token, groups) {
var stack, str, n, i, l;
} else if (typeof regexp === 'string') {
this.ignoreCase = m && m.indexOf('i') !== -1;
this.multiline = m && m.indexOf('m') !== -1;
} else {
throw new Error('Expected a regexp or string');
}
switch (token.type) {
case types.ROOT:
case types.GROUP:
// Ignore lookaheads for now.
if (token.followedBy || token.notFollowedBy) { return ''; }
this.tokens = ret(regexp);
};
// Insert placeholder until group string is generated.
if (token.remember && token.groupNumber === undefined) {
token.groupNumber = groups.push(null) - 1;
}
stack = token.options ?
this._randSelect(token.options) : token.stack;
// When a repetitional token has its max set to Infinite,
// randexp won't actually generate a random amount between min and Infinite
// instead it will see Infinite as min + 100.
RandExp.prototype.max = 100;
str = '';
for (i = 0, l = stack.length; i < l; i++) {
str += this._gen(stack[i], groups);
}
if (token.remember) {
groups[token.groupNumber] = str;
}
return str;
// Generates the random string.
RandExp.prototype.gen = function() {
return gen.call(this, this.tokens, []);
};
case types.POSITION:
// Do nothing for now.
return '';
case types.SET:
var expandedSet = this._expand(token);
if (!expandedSet.length) { return ''; }
return String.fromCharCode(this._randSelect(expandedSet));
// Enables use of randexp with a shorter call.
RandExp.randexp = function(regexp, m) {
var randexp;
if (regexp._randexp === undefined) {
randexp = new RandExp(regexp, m);
regexp._randexp = randexp;
} else {
randexp = regexp._randexp;
}
checkCustom(randexp, regexp);
return randexp.gen();
};
case types.REPETITION:
// Randomly generate number between min and max.
n = this.randInt(token.min,
token.max === Infinity ? token.min + this.max : token.max);
str = '';
for (i = 0; i < n; i++) {
str += this._gen(token.value, groups);
}
// This enables sugary /regexp/.gen syntax.
RandExp.sugar = function() {
/* jshint freeze:false */
RegExp.prototype.gen = function() {
return RandExp.randexp(this);
};
};
return str;
// This allows expanding to include additional characters
// for instance: RandExp.defaultRange.add(0, 65535);
RandExp.prototype.defaultRange = new DRange(32, 126);
case types.REFERENCE:
return groups[token.value - 1] || '';
case types.CHAR:
var code = this.ignoreCase && this._randBool() ?
this._toOtherCase(token.value) : token.value;
return String.fromCharCode(code);
}
}
/**
* Randomly generates and returns a number between a and b (inclusive).
*
* @param {Number} a
* @param {Number} b
* @return {Number}
*/
RandExp.prototype.randInt = function(a, b) {
return a + Math.floor(Math.random() * (1 + b - a));
};
/**
* If code is alphabetic, converts to other case.
* If not alphabetic, returns back code.
*
* @param {Number} code
* @return {Number}
*/
_toOtherCase(code) {
return code + (97 <= code && code <= 122 ? -32 :
65 <= code && code <= 90 ? 32 : 0);
}
/**
* Generate random string modeled after given tokens.
*
* @param {Object} token
* @param {Array.<String>} groups
* @return {String}
*/
function gen(token, groups) {
var stack, str, n, i, l;
switch (token.type) {
/**
* Randomly returns a true or false value.
*
* @return {Boolean}
*/
_randBool() {
return !this.randInt(0, 1);
}
case types.ROOT:
case types.GROUP:
// Ignore lookaheads for now.
if (token.followedBy || token.notFollowedBy) { return ''; }
/**
* Randomly selects and returns a value from the array.
*
* @param {Array.<Object>} arr
* @return {Object}
*/
_randSelect(arr) {
if (arr instanceof DRange) {
return arr.index(this.randInt(0, arr.length - 1));
}
return arr[this.randInt(0, arr.length - 1)];
}
// Insert placeholder until group string is generated.
if (token.remember && token.groupNumber === undefined) {
token.groupNumber = groups.push(null) - 1;
}
stack = token.options ?
randSelect.call(this, token.options) : token.stack;
str = '';
for (i = 0, l = stack.length; i < l; i++) {
str += gen.call(this, stack[i], groups);
/**
* expands a token to a DiscontinuousRange of characters which has a
* length and an index function (for random selecting)
*
* @param {Object} token
* @return {DiscontinuousRange}
*/
_expand(token) {
if (token.type === ret.types.CHAR) {
return new DRange(token.value);
} else if (token.type === ret.types.RANGE) {
return new DRange(token.from, token.to);
} else {
let drange = new DRange();
for (let i = 0; i < token.set.length; i++) {
let subrange = this._expand(token.set[i]);
drange.add(subrange);
if (this.ignoreCase) {
for (let j = 0; j < subrange.length; j++) {
let code = subrange.index(j);
let otherCaseCode = this._toOtherCase(code);
if (code !== otherCaseCode) {
drange.add(otherCaseCode);
}
}
}
}
if (token.remember) {
groups[token.groupNumber] = str;
if (token.not) {
return this.defaultRange.clone().subtract(drange);
} else {
return this.defaultRange.clone().intersect(drange);
}
return str;
}
}
case types.POSITION:
// Do nothing for now.
return '';
/**
* Randomly generates and returns a number between a and b (inclusive).
*
* @param {Number} a
* @param {Number} b
* @return {Number}
*/
randInt(a, b) {
return a + Math.floor(Math.random() * (1 + b - a));
}
case types.SET:
var expandedSet = expand.call(this, token);
if (!expandedSet.length) { return ''; }
return String.fromCharCode(randSelect.call(this, expandedSet));
/**
* Default range of characters to generate from.
*/
get defaultRange() {
return this._range = this._range || new DRange(32, 126);
}
set defaultRange(range) {
this._range = range;
}
case types.REPETITION:
// Randomly generate number between min and max.
n = this.randInt(token.min,
token.max === Infinity ? token.min + this.max : token.max);
str = '';
for (i = 0; i < n; i++) {
str += gen.call(this, token.value, groups);
}
/**
*
* Enables use of randexp with a shorter call.
*
* @param {RegExp|String| regexp}
* @param {String} m
* @return {String}
*/
static randexp(regexp, m) {
var randexp;
if (regexp._randexp === undefined) {
randexp = new RandExp(regexp, m);
regexp._randexp = randexp;
} else {
randexp = regexp._randexp;
randexp._setDefaults(regexp);
}
return randexp.gen();
}
return str;
case types.REFERENCE:
return groups[token.value - 1] || '';
case types.CHAR:
var code = this.ignoreCase && randBool.call(this) ?
toOtherCase(token.value) : token.value;
return String.fromCharCode(code);
/**
* Enables sugary /regexp/.gen syntax.
*/
static sugar() {
/* eshint freeze:false */
RegExp.prototype.gen = function() {
return RandExp.randexp(this);
};
}
}
};

@@ -11,3 +11,3 @@ {

],
"version": "0.4.6",
"version": "0.4.7",
"homepage": "http://fent.github.io/randexp.js/",

@@ -18,3 +18,3 @@ "repository": {

},
"author": "Roly Fentanes (https://github.com/fent)",
"author": "fent (https://github.com/fent)",
"main": "./lib/randexp.js",

@@ -32,20 +32,20 @@ "files": [

"dependencies": {
"discontinuous-range": "1.0.0",
"ret": "~0.1.10"
"discontinuous-range": "github:fent/discontinuous-range#feature/intersect",
"ret": "^0.2.0"
},
"devDependencies": {
"browserify": "^14.0.0",
"browserify": "^15.2.0",
"gulp": "^3.9.0",
"gulp-header": "^1.7.1",
"gulp-header": "^2.0.1",
"gulp-insert": "^0.5.0",
"gulp-uglify": "^3.0.0",
"istanbul": "*",
"mocha": "*",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
"mocha": "^5.0.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^1.1.2"
},
"engines": {
"node": ">=0.12"
"node": ">=4"
},
"license": "MIT"
}

@@ -12,3 +12,3 @@ # randexp.js

```js
var RandExp = require('randexp');
const RandExp = require('randexp');

@@ -40,3 +40,3 @@ // supports grouping and piping

```js
var randexp = require('randexp').randexp;
const randexp = require('randexp').randexp;

@@ -63,6 +63,6 @@ randexp(/[1-6]/); // 4

The default generated character range includes printable ASCII. In order to add or remove characters,
The default generated character range includes printable ASCII. In order to add or remove characters,
a `defaultRange` attribute is exposed. you can `subtract(from, to)` and `add(from, to)`
```js
var randexp = new RandExp(/random stuff: .+/);
const randexp = new RandExp(/random stuff: .+/);
randexp.defaultRange.subtract(32, 126);

@@ -74,7 +74,8 @@ randexp.defaultRange.add(0, 65535);

You can also change the default range by changing `RandExp.prototype.defaultRange`.
# Custom PRNG
The default randomness is provided by `Math.random()`. If you need to use a seedable or cryptographic PRNG, you
can override `RandExp.prototype.randInt` or `randexp.randInt` (where `randexp` is an instance of `RandExp`). `randInt(from, to)` accepts an inclusive range and returns a randomly selected
number within that range.
can override `RandExp.prottoype.randInt` or `randexp.randInt` (where `randexp` is an instance of `RandExp`). `randInt(from, to)` accepts an inclusive range and returns a randomly selected number within that range.

@@ -86,3 +87,3 @@ # Infinite Repetitionals

```js
var randexp = new RandExp(/no{1,}/);
const randexp = new RandExp(/no{1,}/);
randexp.max = 1000000;

@@ -94,3 +95,3 @@ ```

```js
var regexp = /(hi)*/;
const regexp = /(hi)*/;
regexp.max = 1000000;

@@ -136,6 +137,1 @@ ```

```
# License
MIT

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc