aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShinigami <[email protected]>2022-01-14 16:59:17 +0100
committerDamien Retzinger <[email protected]>2022-01-14 18:37:49 -0500
commit8fa14c698c25ee23ffc5168d7c69dc37fd7f8c4b (patch)
treead66bb4c91e32525021c92f6e524aac1418111f6 /src
parent6122d3c9b0e6c352514bf35707187da56e379359 (diff)
downloadfaker-8fa14c698c25ee23ffc5168d7c69dc37fd7f8c4b.tar.xz
faker-8fa14c698c25ee23ffc5168d7c69dc37fd7f8c4b.zip
feat: migrate fake (#79)
Co-authored-by: Honza Machala <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/fake.ts110
-rw-r--r--src/index.ts3
2 files changed, 112 insertions, 1 deletions
diff --git a/src/fake.ts b/src/fake.ts
new file mode 100644
index 00000000..e435ce89
--- /dev/null
+++ b/src/fake.ts
@@ -0,0 +1,110 @@
+import type { Faker } from '.';
+
+/**
+ * Generator method for combining faker methods based on string input
+ */
+export class Fake {
+ constructor(private readonly faker: Faker) {
+ // Bind `this` so namespaced is working correctly
+ for (const name of Object.getOwnPropertyNames(Fake.prototype)) {
+ if (name === 'constructor' || typeof this[name] !== 'function') {
+ continue;
+ }
+ this[name] = this[name].bind(this);
+ }
+ }
+
+ /**
+ * Generator method for combining faker methods based on string input
+ *
+ * __Example:__
+ *
+ * ```
+ * console.log(faker.fake('{{name.lastName}}, {{name.firstName}} {{name.suffix}}'));
+ * // outputs: "Marks, Dean Sr."
+ * ```
+ *
+ * This will interpolate the format string with the value of methods
+ * [name.lastName]{@link faker.name.lastName}, [name.firstName]{@link faker.name.firstName},
+ * and [name.suffix]{@link faker.name.suffix}
+ *
+ * @method faker.fake
+ * @param str
+ */
+ fake(str: string): string {
+ // setup default response as empty string
+ let res = '';
+
+ // if incoming str parameter is not provided, return error message
+ if (typeof str !== 'string' || str.length === 0) {
+ throw new Error('string parameter is required!');
+ }
+
+ // find first matching {{ and }}
+ const start = str.search('{{');
+ const end = str.search('}}');
+
+ // if no {{ and }} is found, we are done
+ if (start === -1 || end === -1) {
+ return str;
+ }
+
+ // console.log('attempting to parse', str);
+
+ // extract method name from between the {{ }} that we found
+ // for example: {{name.firstName}}
+ const token = str.substr(start + 2, end - start - 2);
+ let method = token.replace('}}', '').replace('{{', '');
+
+ // console.log('method', method)
+
+ // extract method parameters
+ const regExp = /\(([^)]+)\)/;
+ const matches = regExp.exec(method);
+ let parameters = '';
+ if (matches) {
+ method = method.replace(regExp, '');
+ parameters = matches[1];
+ }
+
+ // split the method into module and function
+ const parts = method.split('.');
+
+ if (typeof this.faker[parts[0]] === 'undefined') {
+ throw new Error('Invalid module: ' + parts[0]);
+ }
+
+ if (typeof this.faker[parts[0]][parts[1]] === 'undefined') {
+ throw new Error('Invalid method: ' + parts[0] + '.' + parts[1]);
+ }
+
+ // assign the function from the module.function namespace
+ const fn = this.faker[parts[0]][parts[1]];
+
+ // If parameters are populated here, they are always going to be of string type
+ // since we might actually be dealing with an object or array,
+ // we always attempt to the parse the incoming parameters into JSON
+ let params: any;
+ // Note: we experience a small performance hit here due to JSON.parse try / catch
+ // If anyone actually needs to optimize this specific code path, please open a support issue on github
+ try {
+ params = JSON.parse(parameters);
+ } catch (err) {
+ // since JSON.parse threw an error, assume parameters was actually a string
+ params = parameters;
+ }
+
+ let result: string;
+ if (typeof params === 'string' && params.length === 0) {
+ result = fn.call(this);
+ } else {
+ result = fn.call(this, params);
+ }
+
+ // replace the found tag with the returned fake value
+ res = str.replace('{{' + token + '}}', result);
+
+ // return the response recursively until we are done finding all tags
+ return this.fake(res);
+ }
+}
diff --git a/src/index.ts b/src/index.ts
index 768ea2ef..b8fef5e8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,6 @@
import { Datatype } from './datatype';
import { _Date } from './date';
+import { Fake } from './fake';
import { Git } from './git';
import { Hacker } from './hacker';
import { Helpers } from './helpers';
@@ -155,7 +156,7 @@ export class Faker {
seedValue?: any[] | any;
- readonly fake = new (require('./fake'))(this).fake;
+ readonly fake: Fake['fake'] = new Fake(this).fake;
readonly unique = new (require('./unique'))(this).unique;
readonly mersenne: Mersenne = new Mersenne();