diff --git a/README.md b/README.md
index 4ae41314474..9ff5153c784 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,7 @@ const { faker } = require('@faker-js/faker');
export function createRandomUser() {
return {
userId: faker.string.uuid(),
- username: faker.internet.userName(),
+ username: faker.internet.username(), // before version 9.1.0, use userName()
email: faker.internet.email(),
avatar: faker.image.avatar(),
password: faker.internet.password(),
diff --git a/docs/api/ApiIndex.vue b/docs/api/ApiIndex.vue
index 7b1be7bf174..94085371ad1 100644
--- a/docs/api/ApiIndex.vue
+++ b/docs/api/ApiIndex.vue
@@ -69,8 +69,13 @@ const filtered = computed(() => {
-
+
{{ h.text }}
diff --git a/docs/guide/frameworks.md b/docs/guide/frameworks.md
index 3b0cd6f39c1..1733b4e1f70 100644
--- a/docs/guide/frameworks.md
+++ b/docs/guide/frameworks.md
@@ -71,7 +71,7 @@ import { faker } from '@faker-js/faker/locale/en';
describe('Testing the application', () => {
it('should create an account with username and password', () => {
- let username = faker.internet.userName();
+ let username = faker.internet.username(); // before version 9.1.0, use userName()
let password = faker.internet.password();
let email = faker.internet.exampleEmail();
@@ -111,7 +111,7 @@ test.describe('Testing the application', () => {
test('should create an account with username and password', async ({
page,
}) => {
- const username = faker.internet.userName();
+ const username = faker.internet.username(); // before version 9.1.0, use userName()
const password = faker.internet.password();
const email = faker.internet.exampleEmail();
diff --git a/src/modules/git/index.ts b/src/modules/git/index.ts
index 8f33f0c5484..22c848b8828 100644
--- a/src/modules/git/index.ts
+++ b/src/modules/git/index.ts
@@ -88,7 +88,7 @@ export class GitModule extends ModuleBase {
const firstName = this.faker.person.firstName();
const lastName = this.faker.person.lastName();
const fullName = this.faker.person.fullName({ firstName, lastName });
- const username = this.faker.internet.userName({ firstName, lastName });
+ const username = this.faker.internet.username({ firstName, lastName });
let user = this.faker.helpers.arrayElement([fullName, username]);
const email = this.faker.internet.email({ firstName, lastName });
diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts
index a455135b00d..3e7759f29ff 100644
--- a/src/modules/internet/index.ts
+++ b/src/modules/internet/index.ts
@@ -1,4 +1,5 @@
import { FakerError } from '../../errors/faker-error';
+import { deprecated } from '../../internal/deprecated';
import { ModuleBase } from '../../internal/module-base';
import { charMapping } from './char-mappings';
import * as random_ua from './user-agent';
@@ -105,7 +106,7 @@ const ipv4Networks: Record = {
*
* ### Overview
*
- * For user accounts, you may need an [`email()`](https://fakerjs.dev/api/internet.html#email) and a [`password()`](https://fakerjs.dev/api/internet.html#password), as well as a ASCII [`userName()`](https://fakerjs.dev/api/internet.html#username) or Unicode [`displayName()`](https://fakerjs.dev/api/internet.html#displayname). Since the emails generated could coincidentally be real email addresses, you should not use these for sending real email addresses. If this is a concern, use [`exampleEmail()`](https://fakerjs.dev/api/internet.html#exampleemail) instead.
+ * For user accounts, you may need an [`email()`](https://fakerjs.dev/api/internet.html#email) and a [`password()`](https://fakerjs.dev/api/internet.html#password), as well as a ASCII [`username()`](https://fakerjs.dev/api/internet.html#username) or Unicode [`displayName()`](https://fakerjs.dev/api/internet.html#displayname). Since the emails generated could coincidentally be real email addresses, you should not use these for sending real email addresses. If this is a concern, use [`exampleEmail()`](https://fakerjs.dev/api/internet.html#exampleemail) instead.
*
* For websites, you can generate a [`domainName()`](https://fakerjs.dev/api/internet.html#domainname) or a full [`url()`](https://fakerjs.dev/api/internet.html#url).
*
@@ -169,7 +170,7 @@ export class InternetModule extends ModuleBase {
allowSpecialCharacters = false,
} = options;
- let localPart: string = this.userName({ firstName, lastName });
+ let localPart: string = this.username({ firstName, lastName });
// Strip any special characters from the local part of the email address
// This could happen if invalid chars are passed in manually in the firstName/lastName
localPart = localPart.replaceAll(/[^A-Za-z0-9._+-]+/g, '');
@@ -273,6 +274,8 @@ export class InternetModule extends ModuleBase {
* faker.internet.userName({ firstName: '大羽', lastName: '陳' }) // 'hlzp8d.tpv45' - note neither name is used
*
* @since 2.0.1
+ *
+ * @deprecated Use `faker.internet.username()` instead.
*/
userName(
options: {
@@ -289,6 +292,56 @@ export class InternetModule extends ModuleBase {
*/
lastName?: string;
} = {}
+ ): string {
+ deprecated({
+ deprecated: 'faker.internet.userName()',
+ proposed: 'faker.internet.username()',
+ since: '9.1.0',
+ until: '10.0.0',
+ });
+
+ return this.username(options);
+ }
+
+ /**
+ * Generates a username using the given person's name as base.
+ * The resulting username may use neither, one or both of the names provided.
+ * This will always return a plain ASCII string.
+ * Some basic stripping of accents and transliteration of characters will be done.
+ *
+ * @param options An options object.
+ * @param options.firstName The optional first name to use. If not specified, a random one will be chosen.
+ * @param options.lastName The optional last name to use. If not specified, a random one will be chosen.
+ *
+ * @see faker.internet.displayName(): For generating an Unicode display name.
+ *
+ * @example
+ * faker.internet.username() // 'Nettie_Zboncak40'
+ * faker.internet.username({ firstName: 'Jeanne' }) // 'Jeanne98'
+ * faker.internet.username({ firstName: 'Jeanne' }) // 'Jeanne.Smith98'
+ * faker.internet.username({ firstName: 'Jeanne', lastName: 'Doe'}) // 'Jeanne_Doe98'
+ * faker.internet.username({ firstName: 'John', lastName: 'Doe' }) // 'John.Doe'
+ * faker.internet.username({ firstName: 'Hélene', lastName: 'Müller' }) // 'Helene_Muller11'
+ * faker.internet.username({ firstName: 'Фёдор', lastName: 'Достоевский' }) // 'Fedor.Dostoevskii50'
+ * faker.internet.username({ firstName: '大羽', lastName: '陳' }) // 'hlzp8d.tpv45' - note neither name is used
+ *
+ * @since 9.1.0
+ */
+ username(
+ options: {
+ /**
+ * The optional first name to use.
+ *
+ * @default faker.person.firstName()
+ */
+ firstName?: string;
+ /**
+ * The optional last name to use.
+ *
+ * @default faker.person.lastName()
+ */
+ lastName?: string;
+ } = {}
): string {
const {
firstName = this.faker.person.firstName(),
@@ -348,7 +401,7 @@ export class InternetModule extends ModuleBase {
* @param options.firstName The optional first name to use. If not specified, a random one will be chosen.
* @param options.lastName The optional last name to use. If not specified, a random one will be chosen.
*
- * @see faker.internet.userName(): For generating a plain ASCII username.
+ * @see faker.internet.username(): For generating a plain ASCII username.
*
* @example
* faker.internet.displayName() // 'Nettie_Zboncak40'
diff --git a/test/modules/__snapshots__/internet.spec.ts.snap b/test/modules/__snapshots__/internet.spec.ts.snap
index 9ec2d26525f..a70d9afe80e 100644
--- a/test/modules/__snapshots__/internet.spec.ts.snap
+++ b/test/modules/__snapshots__/internet.spec.ts.snap
@@ -120,6 +120,22 @@ exports[`internet > 42 > userName > with firstName option 1`] = `"Jane_Wiegand59
exports[`internet > 42 > userName > with lastName option 1`] = `"Garnet_Doe"`;
+exports[`internet > 42 > username > noArgs 1`] = `"Garnet.Reynolds-Miller15"`;
+
+exports[`internet > 42 > username > with Chinese names 1`] = `"hlzp8d.tpv"`;
+
+exports[`internet > 42 > username > with Cyrillic names 1`] = `"Fedor.Dostoevskii"`;
+
+exports[`internet > 42 > username > with Latin names 1`] = `"Jane.Doe"`;
+
+exports[`internet > 42 > username > with accented names 1`] = `"Helene.Muller"`;
+
+exports[`internet > 42 > username > with all option 1`] = `"Jane.Doe"`;
+
+exports[`internet > 42 > username > with firstName option 1`] = `"Jane_Wiegand59"`;
+
+exports[`internet > 42 > username > with lastName option 1`] = `"Garnet_Doe"`;
+
exports[`internet > 1211 > color > noArgs 1`] = `"#77721c"`;
exports[`internet > 1211 > color > with all options 1`] = `"#a9a44e"`;
@@ -240,6 +256,22 @@ exports[`internet > 1211 > userName > with firstName option 1`] = `"Jane99"`;
exports[`internet > 1211 > userName > with lastName option 1`] = `"Tito_Doe"`;
+exports[`internet > 1211 > username > noArgs 1`] = `"Tito67"`;
+
+exports[`internet > 1211 > username > with Chinese names 1`] = `"hlzp8d_tpv89"`;
+
+exports[`internet > 1211 > username > with Cyrillic names 1`] = `"Fedor_Dostoevskii89"`;
+
+exports[`internet > 1211 > username > with Latin names 1`] = `"Jane_Doe89"`;
+
+exports[`internet > 1211 > username > with accented names 1`] = `"Helene_Muller89"`;
+
+exports[`internet > 1211 > username > with all option 1`] = `"Jane_Doe89"`;
+
+exports[`internet > 1211 > username > with firstName option 1`] = `"Jane99"`;
+
+exports[`internet > 1211 > username > with lastName option 1`] = `"Tito_Doe"`;
+
exports[`internet > 1337 > color > noArgs 1`] = `"#211423"`;
exports[`internet > 1337 > color > with all options 1`] = `"#534655"`;
@@ -359,3 +391,19 @@ exports[`internet > 1337 > userName > with all option 1`] = `"Jane.Doe15"`;
exports[`internet > 1337 > userName > with firstName option 1`] = `"Jane.Cronin45"`;
exports[`internet > 1337 > userName > with lastName option 1`] = `"Devyn.Doe27"`;
+
+exports[`internet > 1337 > username > noArgs 1`] = `"Devyn.Gottlieb"`;
+
+exports[`internet > 1337 > username > with Chinese names 1`] = `"hlzp8d.tpv15"`;
+
+exports[`internet > 1337 > username > with Cyrillic names 1`] = `"Fedor.Dostoevskii15"`;
+
+exports[`internet > 1337 > username > with Latin names 1`] = `"Jane.Doe15"`;
+
+exports[`internet > 1337 > username > with accented names 1`] = `"Helene.Muller15"`;
+
+exports[`internet > 1337 > username > with all option 1`] = `"Jane.Doe15"`;
+
+exports[`internet > 1337 > username > with firstName option 1`] = `"Jane.Cronin45"`;
+
+exports[`internet > 1337 > username > with lastName option 1`] = `"Devyn.Doe27"`;
diff --git a/test/modules/internet.spec.ts b/test/modules/internet.spec.ts
index 04b255fd48f..f96671eb661 100644
--- a/test/modules/internet.spec.ts
+++ b/test/modules/internet.spec.ts
@@ -66,6 +66,20 @@ describe('internet', () => {
.it('with Chinese names', { firstName: '大羽', lastName: '陳' });
});
+ t.describe('username', (t) => {
+ t.it('noArgs')
+ .it('with firstName option', { firstName: 'Jane' })
+ .it('with lastName option', { lastName: 'Doe' })
+ .it('with all option', { firstName: 'Jane', lastName: 'Doe' })
+ .it('with Latin names', { firstName: 'Jane', lastName: 'Doe' })
+ .it('with accented names', { firstName: 'Hélene', lastName: 'Müller' })
+ .it('with Cyrillic names', {
+ firstName: 'Фёдор',
+ lastName: 'Достоевский',
+ })
+ .it('with Chinese names', { firstName: '大羽', lastName: '陳' });
+ });
+
t.describe('displayName', (t) => {
t.it('noArgs')
.it('with firstName option', { firstName: 'Jane' })
@@ -347,8 +361,80 @@ describe('internet', () => {
});
describe('userName()', () => {
+ it('should return a random userName', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName();
+
+ expect(userName).toBeTruthy();
+ expect(userName).toBeTypeOf('string');
+ expect(userName).toMatch(/\w/);
+ });
+
+ it('should return a random userName with given firstName', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({ firstName: 'Aiden' });
+
+ expect(userName).toBeTruthy();
+ expect(userName).toBeTypeOf('string');
+ expect(userName).toMatch(/\w/);
+ expect(userName).includes('Aiden');
+ });
+
+ it('should return a random userName with given firstName and lastName', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({
+ firstName: 'Aiden',
+ lastName: 'Harann',
+ });
+
+ expect(userName).toBeTruthy();
+ expect(userName).toBeTypeOf('string');
+ expect(userName).includes('Aiden');
+ expect(userName).includes('Harann');
+ expect(userName).toMatch(/^Aiden[._]Harann\d*/);
+ });
+
+ it('should strip accents', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({
+ firstName: 'Adèle',
+ lastName: 'Smith',
+ });
+ expect(userName).includes('Adele');
+ expect(userName).includes('Smith');
+ });
+
+ it('should transliterate Cyrillic', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({
+ firstName: 'Амос',
+ lastName: 'Васильев',
+ });
+ expect(userName).includes('Amos');
+ });
+
+ it('should provide a fallback for Chinese etc', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({
+ firstName: '大羽',
+ lastName: '陳',
+ });
+ expect(userName).includes('hlzp8d');
+ });
+
+ it('should provide a fallback special unicode characters', () => {
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
+ const userName = faker.internet.userName({
+ firstName: '🐼',
+ lastName: '❤️',
+ });
+ expect(userName).includes('2qt8');
+ });
+ });
+
+ describe('username()', () => {
it('should return a random username', () => {
- const username = faker.internet.userName();
+ const username = faker.internet.username();
expect(username).toBeTruthy();
expect(username).toBeTypeOf('string');
@@ -356,7 +442,7 @@ describe('internet', () => {
});
it('should return a random username with given firstName', () => {
- const username = faker.internet.userName({ firstName: 'Aiden' });
+ const username = faker.internet.username({ firstName: 'Aiden' });
expect(username).toBeTruthy();
expect(username).toBeTypeOf('string');
@@ -365,7 +451,7 @@ describe('internet', () => {
});
it('should return a random username with given firstName and lastName', () => {
- const username = faker.internet.userName({
+ const username = faker.internet.username({
firstName: 'Aiden',
lastName: 'Harann',
});
@@ -378,7 +464,7 @@ describe('internet', () => {
});
it('should strip accents', () => {
- const username = faker.internet.userName({
+ const username = faker.internet.username({
firstName: 'Adèle',
lastName: 'Smith',
});
@@ -387,7 +473,7 @@ describe('internet', () => {
});
it('should transliterate Cyrillic', () => {
- const username = faker.internet.userName({
+ const username = faker.internet.username({
firstName: 'Амос',
lastName: 'Васильев',
});
@@ -395,7 +481,7 @@ describe('internet', () => {
});
it('should provide a fallback for Chinese etc', () => {
- const username = faker.internet.userName({
+ const username = faker.internet.username({
firstName: '大羽',
lastName: '陳',
});
@@ -403,7 +489,7 @@ describe('internet', () => {
});
it('should provide a fallback special unicode characters', () => {
- const username = faker.internet.userName({
+ const username = faker.internet.username({
firstName: '🐼',
lastName: '❤️',
});
diff --git a/test/scripts/apidocs/verify-jsdoc-tags.spec.ts b/test/scripts/apidocs/verify-jsdoc-tags.spec.ts
index 753ef9b3ce9..0456d8ee477 100644
--- a/test/scripts/apidocs/verify-jsdoc-tags.spec.ts
+++ b/test/scripts/apidocs/verify-jsdoc-tags.spec.ts
@@ -36,6 +36,11 @@ function resolvePathToMethodFile(
signature: number
): string {
const dir = resolveDirToModule(moduleName);
+ // TODO @ST-DDT 2024-09-23: Remove this in v10
+ if (methodName === 'userName') {
+ methodName = 'userNameDeprecated';
+ }
+
return resolve(dir, `${methodName}_${signature}.ts`);
}