aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2023-11-14 17:11:26 +0100
committerGitHub <[email protected]>2023-11-14 16:11:26 +0000
commit7e3c92e802614ae5e9f621d9e679dfd6f6d63cf1 (patch)
treebb6813a857c0c42ba1049be5035fce7f45b99c46 /src
parent36fc517d17591c8ea1d5135d9a93c7591e3d1f74 (diff)
downloadfaker-7e3c92e802614ae5e9f621d9e679dfd6f6d63cf1.tar.xz
faker-7e3c92e802614ae5e9f621d9e679dfd6f6d63cf1.zip
infra: enable strictNullChecks in tsconfig (#2435)
Diffstat (limited to 'src')
-rw-r--r--src/definitions/date.ts3
-rw-r--r--src/definitions/definitions.ts2
-rw-r--r--src/locale-proxy.ts40
-rw-r--r--src/modules/airline/index.ts2
-rw-r--r--src/modules/color/index.ts37
-rw-r--r--src/modules/commerce/index.ts10
-rw-r--r--src/modules/date/index.ts51
-rw-r--r--src/modules/finance/index.ts22
-rw-r--r--src/modules/helpers/index.ts2
-rw-r--r--src/modules/helpers/unique.ts4
-rw-r--r--src/modules/internet/index.ts2
-rw-r--r--src/modules/person/index.ts112
-rw-r--r--src/modules/random/index.ts2
13 files changed, 191 insertions, 98 deletions
diff --git a/src/definitions/date.ts b/src/definitions/date.ts
index 16cfb28a..2265a025 100644
--- a/src/definitions/date.ts
+++ b/src/definitions/date.ts
@@ -26,8 +26,9 @@ export interface DateEntryDefinition {
/**
* The short name/abbreviation of the entry.
+ * If null, the locale does not support a short name/abbreviation for the entry.
*/
- abbr: string[];
+ abbr: string[] | null;
/**
* The wide name of the entry when used in context. If absent wide will be used instead.
diff --git a/src/definitions/definitions.ts b/src/definitions/definitions.ts
index ca495e34..c2a3b560 100644
--- a/src/definitions/definitions.ts
+++ b/src/definitions/definitions.ts
@@ -50,4 +50,4 @@ export type LocaleDefinition = {
system?: SystemDefinition;
vehicle?: VehicleDefinition;
word?: WordDefinition;
-} & Record<string, Record<string, unknown> | undefined>;
+} & Record<string, Record<string, unknown>>;
diff --git a/src/locale-proxy.ts b/src/locale-proxy.ts
index 67b29d47..e99ba655 100644
--- a/src/locale-proxy.ts
+++ b/src/locale-proxy.ts
@@ -55,6 +55,30 @@ export function createLocaleProxy(locale: LocaleDefinition): LocaleProxy {
}
/**
+ * Checks that the value is not null or undefined and throws an error if it is.
+ *
+ * @param value The value to check.
+ * @param path The path to the locale data.
+ */
+export function assertLocaleData<T>(
+ value: T,
+ ...path: string[]
+): asserts value is NonNullable<T> {
+ if (value === null) {
+ throw new FakerError(
+ `The locale data for '${path.join('.')}' aren't applicable to this locale.
+ If you think this is a bug, please report it at: https://github.com/faker-js/faker`
+ );
+ } else if (value === undefined) {
+ throw new FakerError(
+ `The locale data for '${path.join('.')}' are missing in this locale.
+ Please contribute the missing data to the project or use a locale/Faker instance that has these data.
+ For more information see https://fakerjs.dev/guide/localization.html`
+ );
+ }
+}
+
+/**
* Creates a proxy for a category that throws an error when accessing an undefined property.
*
* @param categoryName The name of the category.
@@ -79,20 +103,10 @@ function createCategoryProxy<
const value = target[entryName];
if (typeof entryName === 'symbol' || entryName === 'nodeType') {
return value;
- } else if (value === null) {
- throw new FakerError(
- `The locale data for '${categoryName}.${entryName.toString()}' aren't applicable to this locale.
- If you think this is a bug, please report it at: https://github.com/faker-js/faker`
- );
- } else if (value === undefined) {
- throw new FakerError(
- `The locale data for '${categoryName}.${entryName.toString()}' are missing in this locale.
- Please contribute the missing data to the project or use a locale/Faker instance that has these data.
- For more information see https://fakerjs.dev/guide/localization.html`
- );
- } else {
- return value;
}
+
+ assertLocaleData(value, categoryName, entryName.toString());
+ return value;
},
set: throwReadOnlyError,
diff --git a/src/modules/airline/index.ts b/src/modules/airline/index.ts
index 4c1ec318..e8ac47c5 100644
--- a/src/modules/airline/index.ts
+++ b/src/modules/airline/index.ts
@@ -155,7 +155,7 @@ export class AirlineModule extends ModuleBase {
): string {
const { allowNumerics = false, allowVisuallySimilarCharacters = false } =
options;
- const excludedChars = [];
+ const excludedChars: string[] = [];
if (!allowNumerics) {
excludedChars.push(...numerics);
}
diff --git a/src/modules/color/index.ts b/src/modules/color/index.ts
index 5962ef71..57b906a3 100644
--- a/src/modules/color/index.ts
+++ b/src/modules/color/index.ts
@@ -47,17 +47,19 @@ export type Casing = 'lower' | 'upper' | 'mixed';
*
* @param hexColor Hex color string to be formatted.
* @param options Options object.
- * @param options.prefix Prefix of the generated hex color. Defaults to `'0x'`.
- * @param options.casing Letter type case of the generated hex color. Defaults to `'mixed'`.
+ * @param options.prefix Prefix of the generated hex color.
+ * @param options.casing Letter type case of the generated hex color.
*/
function formatHexColor(
hexColor: string,
- options?: {
- prefix?: string;
- casing?: Casing;
+ options: {
+ prefix: string;
+ casing: Casing;
}
): string {
- switch (options?.casing) {
+ const { prefix, casing } = options;
+
+ switch (casing) {
case 'upper':
hexColor = hexColor.toUpperCase();
break;
@@ -68,8 +70,8 @@ function formatHexColor(
// Do nothing
}
- if (options?.prefix) {
- hexColor = options.prefix + hexColor;
+ if (prefix) {
+ hexColor = prefix + hexColor;
}
return hexColor;
@@ -360,19 +362,20 @@ export class ColorModule extends ModuleBase {
*/
includeAlpha?: boolean;
}): string | number[];
- rgb(options?: {
- prefix?: string;
- casing?: Casing;
- format?: 'hex' | ColorFormat;
- includeAlpha?: boolean;
- }): string | number[] {
+ rgb(
+ options: {
+ prefix?: string;
+ casing?: Casing;
+ format?: 'hex' | ColorFormat;
+ includeAlpha?: boolean;
+ } = {}
+ ): string | number[] {
const {
format = 'hex',
includeAlpha = false,
prefix = '#',
casing = 'lower',
- } = options || {};
- options = { format, includeAlpha, prefix, casing };
+ } = options;
let color: string | number[];
let cssFunction: CssFunctionType = 'rgb';
if (format === 'hex') {
@@ -380,7 +383,7 @@ export class ColorModule extends ModuleBase {
length: includeAlpha ? 8 : 6,
prefix: '',
});
- color = formatHexColor(color, options);
+ color = formatHexColor(color, { prefix, casing });
return color;
}
diff --git a/src/modules/commerce/index.ts b/src/modules/commerce/index.ts
index 1be3fcb2..425bc848 100644
--- a/src/modules/commerce/index.ts
+++ b/src/modules/commerce/index.ts
@@ -1,3 +1,4 @@
+import { FakerError } from '../../errors/faker-error';
import { deprecated } from '../../internal/deprecated';
import { ModuleBase } from '../../internal/module-base';
@@ -401,7 +402,14 @@ export class CommerceModule extends ModuleBase {
const registrantLength = groupRules.find(
([rangeMaximum]) => elementValue <= rangeMaximum
- )[1];
+ )?.[1];
+
+ if (!registrantLength) {
+ // This can only happen if the ISBN_LENGTH_RULES are corrupted
+ throw new FakerError(
+ `Unable to find a registrant length for the group ${group}`
+ );
+ }
const registrant = element.slice(0, registrantLength);
const publication = element.slice(registrantLength);
diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts
index a40b4772..39c85735 100644
--- a/src/modules/date/index.ts
+++ b/src/modules/date/index.ts
@@ -3,6 +3,7 @@ import type { DateEntryDefinition } from '../../definitions';
import { FakerError } from '../../errors/faker-error';
import { deprecated } from '../../internal/deprecated';
import { SimpleModuleBase } from '../../internal/module-base';
+import { assertLocaleData } from '../../locale-proxy';
/**
* Converts date passed as a string, number or Date to a Date object.
@@ -15,6 +16,10 @@ function toDate(
date: string | Date | number | undefined,
fallback: () => Date
): Date {
+ if (date == null) {
+ return fallback();
+ }
+
date = new Date(date);
if (Number.isNaN(date.valueOf())) {
date = fallback();
@@ -383,14 +388,15 @@ export class SimpleDateModule extends SimpleModuleBase {
},
legacyTo?: string | Date | number
): Date {
- if (typeof options !== 'object' || options instanceof Date) {
+ if (options instanceof Date || typeof options !== 'object') {
deprecated({
deprecated: 'faker.date.between(from, to)',
proposed: 'faker.date.between({ from, to })',
since: '8.0',
until: '9.0',
});
- options = { from: options, to: legacyTo };
+ // We use options as fallback for legacyTo avoid TS errors for unintended usage.
+ options = { from: options, to: legacyTo ?? options };
}
const { from, to } = options;
@@ -559,14 +565,15 @@ export class SimpleDateModule extends SimpleModuleBase {
legacyTo?: string | Date | number,
legacyCount: number = 3
): Date[] {
- if (typeof options !== 'object' || options instanceof Date) {
+ if (options instanceof Date || typeof options !== 'object') {
deprecated({
deprecated: 'faker.date.betweens(from, to, count)',
proposed: 'faker.date.betweens({ from, to, count })',
since: '8.0',
until: '9.0',
});
- options = { from: options, to: legacyTo, count: legacyCount };
+ // We use options as fallback for legacyTo avoid TS errors for unintended usage.
+ options = { from: options, to: legacyTo ?? options, count: legacyCount };
}
const { from, to, count = 3 } = options;
@@ -864,12 +871,6 @@ export class SimpleDateModule extends SimpleModuleBase {
refDate?: string | Date | number;
} = {}
): Date {
- if (options.max < options.min) {
- throw new FakerError(
- `Max ${options.max} should be larger than or equal to min ${options.min}.`
- );
- }
-
const mode = options.mode === 'age' ? 'age' : 'year';
const refDate = toDate(options.refDate, this.faker.defaultRefDate);
const refYear = refDate.getUTCFullYear();
@@ -894,6 +895,12 @@ export class SimpleDateModule extends SimpleModuleBase {
);
}
+ if (max < min) {
+ throw new FakerError(
+ `Max ${options.max} should be larger than or equal to min ${options.min}.`
+ );
+ }
+
return new Date(this.faker.number.int({ min, max }));
}
}
@@ -1074,12 +1081,8 @@ export class DateModule extends SimpleDateModule {
context?: boolean;
} = {}
): string {
- const {
- // eslint-disable-next-line deprecation/deprecation
- abbr,
- abbreviated = abbr ?? false,
- context = false,
- } = options;
+ // eslint-disable-next-line deprecation/deprecation
+ const { abbr, abbreviated = abbr ?? false, context = false } = options;
if (abbr != null) {
deprecated({
@@ -1100,7 +1103,9 @@ export class DateModule extends SimpleDateModule {
type = useContext ? 'wide_context' : 'wide';
}
- return this.faker.helpers.arrayElement(source[type]);
+ const values = source[type];
+ assertLocaleData(values, 'date.month', type);
+ return this.faker.helpers.arrayElement(values);
}
/**
@@ -1260,12 +1265,8 @@ export class DateModule extends SimpleDateModule {
context?: boolean;
} = {}
): string {
- const {
- // eslint-disable-next-line deprecation/deprecation
- abbr,
- abbreviated = abbr ?? false,
- context = false,
- } = options;
+ // eslint-disable-next-line deprecation/deprecation
+ const { abbr, abbreviated = abbr ?? false, context = false } = options;
if (abbr != null) {
deprecated({
@@ -1286,6 +1287,8 @@ export class DateModule extends SimpleDateModule {
type = useContext ? 'wide_context' : 'wide';
}
- return this.faker.helpers.arrayElement(source[type]);
+ const values = source[type];
+ assertLocaleData(values, 'date.weekday', type);
+ return this.faker.helpers.arrayElement(values);
}
}
diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts
index c443b605..33db26f0 100644
--- a/src/modules/finance/index.ts
+++ b/src/modules/finance/index.ts
@@ -24,6 +24,22 @@ export interface Currency {
}
/**
+ * Puts a space after every 4 characters.
+ *
+ * @internal
+ *
+ * @param iban The iban to pretty print.
+ */
+export function prettyPrintIban(iban: string): string {
+ let pretty = '';
+ for (let i = 0; i < iban.length; i += 4) {
+ pretty += `${iban.substring(i, i + 4)} `;
+ }
+
+ return pretty.trimEnd();
+}
+
+/**
* Module to generate finance and money related entries.
*
* ### Overview
@@ -663,9 +679,9 @@ export class FinanceModule extends ModuleBase {
*/
currencySymbol(): string {
let symbol: string;
- while (!symbol) {
+ do {
symbol = this.currency().symbol;
- }
+ } while (symbol.length === 0);
return symbol;
}
@@ -1147,7 +1163,7 @@ export class FinanceModule extends ModuleBase {
const result = `${ibanFormat.country}${checksum}${s}`;
- return formatted ? result.match(/.{1,4}/g).join(' ') : result;
+ return formatted ? prettyPrintIban(result) : result;
}
/**
diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts
index 59eeadba..667f3a51 100644
--- a/src/modules/helpers/index.ts
+++ b/src/modules/helpers/index.ts
@@ -1120,7 +1120,7 @@ export class SimpleHelpersModule extends SimpleModuleBase {
) => RecordKey,
>(
method: TMethod,
- args: Parameters<TMethod> = [] as Parameters<TMethod>,
+ args: Parameters<TMethod> = [] as unknown as Parameters<TMethod>,
options: {
/**
* This parameter does nothing.
diff --git a/src/modules/helpers/unique.ts b/src/modules/helpers/unique.ts
index 44b3a71d..20805530 100644
--- a/src/modules/helpers/unique.ts
+++ b/src/modules/helpers/unique.ts
@@ -97,9 +97,9 @@ export function exec<
maxRetries = 50,
currentIterations = 0,
compare = defaultCompare,
- store,
+ store = {},
} = options;
- let { exclude } = options;
+ let { exclude = [] } = options;
options.currentIterations = currentIterations;
// Support single exclude argument as string
diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts
index 5eb9b4bc..8cc651a3 100644
--- a/src/modules/internet/index.ts
+++ b/src/modules/internet/index.ts
@@ -620,6 +620,7 @@ export class InternetModule extends ModuleBase {
firstName + this.faker.helpers.arrayElement(['.', '_']) + lastName;
break;
case 2:
+ default:
result = `${firstName}${this.faker.helpers.arrayElement([
'.',
'_',
@@ -804,6 +805,7 @@ export class InternetModule extends ModuleBase {
firstName + this.faker.helpers.arrayElement(['.', '_']) + lastName;
break;
case 2:
+ default:
result = `${firstName}${this.faker.helpers.arrayElement([
'.',
'_',
diff --git a/src/modules/person/index.ts b/src/modules/person/index.ts
index e0f4b6b0..0c5f79c3 100644
--- a/src/modules/person/index.ts
+++ b/src/modules/person/index.ts
@@ -1,5 +1,7 @@
import type { Faker } from '../..';
+import { FakerError } from '../../errors/faker-error';
import { ModuleBase } from '../../internal/module-base';
+import { assertLocaleData } from '../../locale-proxy';
export enum Sex {
Female = 'female',
@@ -18,6 +20,7 @@ export type SexType = `${Sex}`;
* @param param2.generic Non-sex definitions.
* @param param2.female Female definitions.
* @param param2.male Male definitions.
+ * @param type Type of the definition.
*
* @returns Definition based on given sex.
*/
@@ -25,10 +28,14 @@ function selectDefinition<T>(
faker: Faker,
elementSelectorFn: (values: T[]) => string,
sex: SexType | undefined,
- // TODO @Shinigami92 2022-03-21: Remove fallback empty object when `strict: true`
- { generic, female, male }: { generic?: T[]; female?: T[]; male?: T[] } = {}
+ {
+ generic,
+ female,
+ male,
+ }: { generic?: T[] | null; female?: T[] | null; male?: T[] | null },
+ type: string
): string {
- let values: T[] | undefined;
+ let values: T[] | undefined | null;
switch (sex) {
case Sex.Female:
@@ -50,6 +57,8 @@ function selectDefinition<T>(
} else {
values = generic;
}
+
+ assertLocaleData(values, `person.{${type}, female_${type}, male_${type}}`);
}
return elementSelectorFn(values);
@@ -92,11 +101,17 @@ export class PersonModule extends ModuleBase {
const { first_name, female_first_name, male_first_name } =
this.faker.rawDefinitions.person ?? {};
- return selectDefinition(this.faker, this.faker.helpers.arrayElement, sex, {
- generic: first_name,
- female: female_first_name,
- male: male_first_name,
- });
+ return selectDefinition(
+ this.faker,
+ this.faker.helpers.arrayElement,
+ sex,
+ {
+ generic: first_name,
+ female: female_first_name,
+ male: male_first_name,
+ },
+ 'first_name'
+ );
}
/**
@@ -135,16 +150,23 @@ export class PersonModule extends ModuleBase {
generic: last_name_pattern,
female: female_last_name_pattern,
male: male_last_name_pattern,
- }
+ },
+ 'last_name_pattern'
);
return this.faker.helpers.fake(pattern);
}
- return selectDefinition(this.faker, this.faker.helpers.arrayElement, sex, {
- generic: last_name,
- female: female_last_name,
- male: male_last_name,
- });
+ return selectDefinition(
+ this.faker,
+ this.faker.helpers.arrayElement,
+ sex,
+ {
+ generic: last_name,
+ female: female_last_name,
+ male: male_last_name,
+ },
+ 'last_name'
+ );
}
/**
@@ -164,11 +186,17 @@ export class PersonModule extends ModuleBase {
const { middle_name, female_middle_name, male_middle_name } =
this.faker.rawDefinitions.person ?? {};
- return selectDefinition(this.faker, this.faker.helpers.arrayElement, sex, {
- generic: middle_name,
- female: female_middle_name,
- male: male_middle_name,
- });
+ return selectDefinition(
+ this.faker,
+ this.faker.helpers.arrayElement,
+ sex,
+ {
+ generic: middle_name,
+ female: female_middle_name,
+ male: male_middle_name,
+ },
+ 'middle_name'
+ );
}
/**
@@ -305,11 +333,17 @@ export class PersonModule extends ModuleBase {
const { prefix, female_prefix, male_prefix } =
this.faker.rawDefinitions.person ?? {};
- return selectDefinition(this.faker, this.faker.helpers.arrayElement, sex, {
- generic: prefix,
- female: female_prefix,
- male: male_prefix,
- });
+ return selectDefinition(
+ this.faker,
+ this.faker.helpers.arrayElement,
+ sex,
+ {
+ generic: prefix,
+ female: female_prefix,
+ male: male_prefix,
+ },
+ 'prefix'
+ );
}
/**
@@ -350,9 +384,13 @@ export class PersonModule extends ModuleBase {
* @since 8.0.0
*/
jobDescriptor(): string {
- return this.faker.helpers.arrayElement(
- this.faker.definitions.person.title.descriptor
- );
+ const values = this.faker.definitions.person.title.descriptor;
+
+ if (values == null) {
+ throw new FakerError('No person.title.descriptor definitions available.');
+ }
+
+ return this.faker.helpers.arrayElement(values);
}
/**
@@ -364,9 +402,13 @@ export class PersonModule extends ModuleBase {
* @since 8.0.0
*/
jobArea(): string {
- return this.faker.helpers.arrayElement(
- this.faker.definitions.person.title.level
- );
+ const values = this.faker.definitions.person.title.level;
+
+ if (values == null) {
+ throw new FakerError('No person.title.area definitions available.');
+ }
+
+ return this.faker.helpers.arrayElement(values);
}
/**
@@ -378,9 +420,13 @@ export class PersonModule extends ModuleBase {
* @since 8.0.0
*/
jobType(): string {
- return this.faker.helpers.arrayElement(
- this.faker.definitions.person.title.job
- );
+ const values = this.faker.definitions.person.title.job;
+
+ if (values == null) {
+ throw new FakerError('No person.title.job definitions available.');
+ }
+
+ return this.faker.helpers.arrayElement(values);
}
/**
diff --git a/src/modules/random/index.ts b/src/modules/random/index.ts
index 997583c1..474e8ca6 100644
--- a/src/modules/random/index.ts
+++ b/src/modules/random/index.ts
@@ -123,7 +123,7 @@ export class RandomModule extends ModuleBase {
'_',
'-',
];
- let result: string;
+ let result = '';
let iteration = 0;