diff --git a/src/address.ts b/src/address.ts index 7e6b0fdcc4e..c510b46c040 100644 --- a/src/address.ts +++ b/src/address.ts @@ -235,6 +235,7 @@ export class Address { */ secondaryAddress(): string { return this.Helpers.replaceSymbolWithNumber( + // TODO ST-DDT 2022-01-30: this.faker.definitions.address.secondary_address this.faker.random.arrayElement(['Apt. ###', 'Suite ###']) ); } diff --git a/src/definitions.ts b/src/definitions.ts deleted file mode 100644 index db142429ba3..00000000000 --- a/src/definitions.ts +++ /dev/null @@ -1,131 +0,0 @@ -export interface Definitions { - address: { - city_name; - city_prefix; - city_suffix; - country_code_alpha_3; - country_code; - country; - county; - direction_abbr; - direction; - postcode_by_state; - postcode: string | string[]; - state_abbr; - state; - street_prefix; - street_suffix; - time_zone; - }; - animal: { - bear; - bird; - cat; - cetacean; - cow; - crocodilia; - dog; - fish; - horse; - insect; - lion; - rabbit; - snake; - type; - }; - commerce: { - color; - department; - product_description; - product_name; - }; - company: { - adjective; - bs_adjective; - bs_noun; - bs_verb; - descriptor; - noun; - suffix; - }; - database: { - collation; - column; - engine; - type; - }; - date: { - month; - weekday; - }; - finance: { - account_type; - credit_card; - currency: Record; - transaction_type; - }; - hacker: { - abbreviation; - adjective; - ingverb; - noun; - phrase; - verb; - }; - internet: { - domain_suffix; - example_email; - free_email; - }; - lorem: { - words; - }; - music: { - genre; - }; - name: { - binary_gender; - female_first_name; - female_last_name; - female_middle_name; - female_prefix; - first_name; - gender; - last_name; - male_first_name; - male_last_name; - male_middle_name; - male_prefix; - middle_name; - prefix; - suffix; - title: { - descriptor; - level; - job; - }; - }; - phone_number: { - formats; - }; - system: { - directoryPaths; - mimeTypes; - }; - vehicle: { - bicycle_type; - fuel; - manufacturer; - model; - type; - }; - word: { - adjective: string[]; - adverb: string[]; - conjunction: string[]; - interjection: string[]; - noun: string[]; - preposition: string[]; - verb: string[]; - }; -} diff --git a/src/definitions/address.ts b/src/definitions/address.ts new file mode 100644 index 00000000000..a5bf2d1c861 --- /dev/null +++ b/src/definitions/address.ts @@ -0,0 +1,115 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to addresses. + */ +export interface AddressDefinitions { + /** + * Postcodes patterns by state + */ + // TODO ST-DDT 2022-01-31: address.zipCodeByState() expects only { [state: string]: { min: number; max: number } } + postcode_by_state: + | string[] + | { [state: string]: { min: number; max: number } }; + /** + * Postcodes patterns (Fake-Pattern | Fake-Pattern[]). + */ + postcode: string | string[]; + + /** + * Names of actual cities + */ + city_name?: string[]; + /** + * Common city prefixes + */ + city_prefix: string[]; + /** + * Common city suffixes + */ + city_suffix: string[]; + + /** + * The names of all countries + */ + country: string[]; + /** + * The names of this country's states + */ + state: string[]; + /** + * The abbreviated names of this country's states + */ + state_abbr: string[]; + /** + * The names of counties inside the country or state + */ + county: string[]; + + /** + * The names of the compass directions. + * First the 4 cardinal directions, then the 4 ordinal directions + */ + direction: string[]; + /** + * The abbreviated names of the compass directions. + * First the 4 cardinal directions, then the 4 ordinal directions + */ + direction_abbr: string[]; + + /** + * Common street prefixes + */ + street_prefix: string[]; + /** + * Common street suffixes + */ + street_suffix: string[]; + + /** + * The address "inside" an address/e.g. an apartment or office. + */ + secondary_address: string[]; + + /** + * The ISO-3166-1 ALPHA-2 country codes + */ + country_code: string[]; + /** + * The ISO-3166-1 ALPHA-3 country codes + */ + country_code_alpha_3: string[]; + + // A list of timezones names. + time_zone: string[]; +} + +/** + * Internal: A list of all keys for the AddressDefinitions. + */ +export const ADDRESS = allOf()( + 'postcode_by_state', + 'postcode', + + 'city_name', + 'city_prefix', + 'city_suffix', + + 'country', + 'state', + 'state_abbr', + 'county', + + 'direction_abbr', + 'direction', + + 'street_prefix', + 'street_suffix', + + 'secondary_address', + + 'country_code', + 'country_code_alpha_3', + + 'time_zone' +); diff --git a/src/definitions/animal.ts b/src/definitions/animal.ts new file mode 100644 index 00000000000..68fe0db24ae --- /dev/null +++ b/src/definitions/animal.ts @@ -0,0 +1,41 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to animals. + */ +export interface AnimalDefinitions { + bear: string[]; + bird: string[]; + cat: string[]; + cetacean: string[]; + cow: string[]; + crocodilia: string[]; + dog: string[]; + fish: string[]; + horse: string[]; + insect: string[]; + lion: string[]; + rabbit: string[]; + snake: string[]; + type: string[]; +} + +/** + * Internal: A list of all keys for the AnimalDefinitions. + */ +export const ANIMAL = allOf()( + 'dog', + 'cat', + 'snake', + 'bear', + 'lion', + 'cetacean', + 'insect', + 'crocodilia', + 'cow', + 'bird', + 'fish', + 'rabbit', + 'horse', + 'type' +); diff --git a/src/definitions/commerce.ts b/src/definitions/commerce.ts new file mode 100644 index 00000000000..dbe22f69949 --- /dev/null +++ b/src/definitions/commerce.ts @@ -0,0 +1,51 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to commerce. + */ +export interface CommerceDefinitions { + /** + * Human readable color names + */ + color: string[]; + /** + * Department names inside a shop. + */ + department: string[]; + /** + * Product name generation definitions. + */ + product_name: CommerceProductNameDefinitions; + /** + * Descriptions for products. + */ + product_description: string[]; +} + +/** + * The possible definitions related to product name generation. + */ +export interface CommerceProductNameDefinitions { + /** + * Adjectives describing a product (e.g. tasty). + */ + adjective: string[]; + /** + * Materials describing a product (e.g. wood). + */ + material: string[]; + /** + * Types of products (e.g. chair). + */ + product: string[]; +} + +/** + * Internal: A list of all keys for the CommerceDefinitions. + */ +export const COMMERCE = allOf()( + 'color', + 'department', + 'product_name', + 'product_description' +); diff --git a/src/definitions/company.ts b/src/definitions/company.ts new file mode 100644 index 00000000000..35947bde9f7 --- /dev/null +++ b/src/definitions/company.ts @@ -0,0 +1,50 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to companies. + */ +export interface CompanyDefinitions { + /** + * Business/products related adjectives. + */ + bs_adjective: string[]; + /** + * Business/products related nouns. + */ + bs_noun: string[]; + /** + * Business/products related verbs. + */ + bs_verb: string[]; + /** + * Catch phrase adjectives. + */ + adjective: string[]; + /** + * Catch phrase adjectives. + */ + descriptor: string[]; + /** + * Catch phrase adjectives. + */ + noun: string[]; + /** + * Company suffixes + */ + suffix: string[]; +} + +/** + * Internal: A list of all keys for the CompanyDefinitions. + */ +export const COMPANY = allOf()( + 'bs_adjective', + 'bs_noun', + 'bs_verb', + + 'adjective', + 'descriptor', + 'noun', + + 'suffix' +); diff --git a/src/definitions/database.ts b/src/definitions/database.ts new file mode 100644 index 00000000000..935f35fcd98 --- /dev/null +++ b/src/definitions/database.ts @@ -0,0 +1,33 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to databases. + */ +export interface DatabaseDefinitions { + /** + * Database Engine + */ + engine: string[]; + /** + * Database Collation + */ + collation: string[]; + /** + * Column names + */ + column: string[]; + /** + * Column types + */ + type: string[]; +} + +/** + * Internal: A list of all keys for the DatabaseDefinitions. + */ +export const DATABASE = allOf()( + 'collation', + 'column', + 'engine', + 'type' +); diff --git a/src/definitions/date.ts b/src/definitions/date.ts new file mode 100644 index 00000000000..2738bdb5e84 --- /dev/null +++ b/src/definitions/date.ts @@ -0,0 +1,44 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to dates. + */ +export interface DateDefinitions { + /** + * The translations for months (January - December). + */ + month: DateEntryDefinition; + /** + * The translations for weekdays (Sunday - Saturday). + */ + weekday: DateEntryDefinition; +} + +/** + * The possible definitions related to date entries. + */ +export interface DateEntryDefinition { + /** + * The long name of the entry. + */ + wide: string[]; + /** + * The short name/abbreviation of the entry. + */ + abbr: string[]; + /** + * The wide name of the entry when used in context. If absent wide will be used instead. + * It is used to specify a word in context, which may differ from a stand-alone word. + */ + wide_context?: string[]; + /** + * The short name/abbreviation name of the entry when used in context. If absent abbr will be used instead. + * It is used to specify a word in context, which may differ from a stand-alone word. + */ + abbr_context?: string[]; +} + +/** + * Internal: A list of all keys for the DateDefinitions. + */ +export const DATE = allOf()('month', 'weekday'); diff --git a/src/definitions/definitions.ts b/src/definitions/definitions.ts new file mode 100644 index 00000000000..d59f84fc859 --- /dev/null +++ b/src/definitions/definitions.ts @@ -0,0 +1,111 @@ +import type { AddressDefinitions } from './address'; +import { ADDRESS } from './address'; +import type { AnimalDefinitions } from './animal'; +import { ANIMAL } from './animal'; +import type { CommerceDefinitions } from './commerce'; +import { COMMERCE } from './commerce'; +import type { CompanyDefinitions } from './company'; +import { COMPANY } from './company'; +import type { DatabaseDefinitions } from './database'; +import { DATABASE } from './database'; +import type { DateDefinitions } from './date'; +import { DATE } from './date'; +import type { FinanceDefinitions } from './finance'; +import { FINANCE } from './finance'; +import type { HackerDefinitions } from './hacker'; +import { HACKER } from './hacker'; +import type { InternetDefinitions } from './internet'; +import { INTERNET } from './internet'; +import type { LoremDefinitions } from './lorem'; +import { LOREM } from './lorem'; +import type { MusicDefinitions } from './music'; +import { MUSIC } from './music'; +import type { NameDefinitions } from './name'; +import { NAME } from './name'; +import type { PhoneNumberDefinitions } from './phone_number'; +import { PHONE_NUMBER } from './phone_number'; +import type { SystemDefinitions } from './system'; +import { SYSTEM } from './system'; +import type { VehicleDefinitions } from './vehicle'; +import { VEHICLE } from './vehicle'; +import type { WordDefinitions } from './word'; +import { WORD } from './word'; + +/** + * The definitions as used by the Faker modules. + */ +interface Definitions { + address: AddressDefinitions; + animal: AnimalDefinitions; + commerce: CommerceDefinitions; + company: CompanyDefinitions; + database: DatabaseDefinitions; + date: DateDefinitions; + finance: FinanceDefinitions; + hacker: HackerDefinitions; + internet: InternetDefinitions; + lorem: LoremDefinitions; + music: MusicDefinitions; + name: NameDefinitions; + phone_number: PhoneNumberDefinitions; + system: SystemDefinitions; + vehicle: VehicleDefinitions; + word: WordDefinitions; +} + +/** + * The definitions as used by the translations/locales. + * This is basically the same as Definitions with the exception, + * that most properties are optional and extra properties are allowed. + */ +export type LocaleDefinition = { + /** + * The name of the language. + */ + title: string; + separator?: string; +} & { + // Known modules + [module in keyof Definitions]?: Partial; +} & { + // Unsupported & custom modules + [group: string]: Record | string; +}; + +/** + * Internal: Compatibility type to ensure all modules have access to fallback locales. + * This should be replaced with a Proxy based property access + * that don't require prior getter generation in the future. + */ +export type DefinitionTypes = { + readonly title: string; + readonly separator: string; +} & { + readonly [module in keyof Definitions]: Array; +}; + +/** + * Internal: List off all modules and their properties, + * that needs to have a fallback generated in Faker.loadDefinitions(). + */ +export const DEFINITIONS: DefinitionTypes = { + title: '', + separator: '', + + address: ADDRESS, + animal: ANIMAL, + company: COMPANY, + commerce: COMMERCE, + database: DATABASE, + date: DATE, + finance: FINANCE, + hacker: HACKER, + internet: INTERNET, + lorem: LOREM, + music: MUSIC, + name: NAME, + phone_number: PHONE_NUMBER, + system: SYSTEM, + vehicle: VEHICLE, + word: WORD, +}; diff --git a/src/definitions/finance.ts b/src/definitions/finance.ts new file mode 100644 index 00000000000..afe3639b5b4 --- /dev/null +++ b/src/definitions/finance.ts @@ -0,0 +1,50 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to finances. + */ +export interface FinanceDefinitions { + /** + * The types of accounts/purposes of an account (e.g. `Savings` account). + */ + account_type: string[]; + /** + * The pattern by provider used to generate credit card codes. + * `L` will be replaced by the check bit. + * + * @see Helpers.replaceCreditCardSymbols() + */ + credit_card: { [provider: string]: string[] }; + /** + * Currencies by their full name and their symbols (e.g. `US Dollar` -> `USD` / `$`). + */ + currency: { [currencyName: string]: FinanceCurrencyEntryDefinitions }; + /** + * Types of transactions (e.g. `deposit`). + */ + transaction_type: string[]; +} + +/** + * The possible definitions related to currency entries. + */ +export interface FinanceCurrencyEntryDefinitions { + /** + * The code/short text/abbreviation for the currency (e.g. `USD`). + */ + code: string; + /** + * The symbol for the currency (e.g. `$`). + */ + symbol: string; +} + +/** + * Internal: A list of all keys for the FinanceDefinitions. + */ +export const FINANCE = allOf()( + 'account_type', + 'credit_card', + 'currency', + 'transaction_type' +); diff --git a/src/definitions/hacker.ts b/src/definitions/hacker.ts new file mode 100644 index 00000000000..00aa3a40875 --- /dev/null +++ b/src/definitions/hacker.ts @@ -0,0 +1,47 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to computers. + */ +export interface HackerDefinitions { + /** + * Generic computer related abbreviations (e.g. `RAM`, `EXE`). + */ + abbreviation: string[]; + /** + * Some computer related adjectives or descriptors (e.g. `digital`, `bluetooth`) + */ + adjective: string[]; + /** + * Some computer related verbs for continuous actions (en: `ing` suffix; e.g. `hacking`). + */ + ingverb: string[]; + /** + * Some computer related nouns (e.g. `protocol`, `sensor`) + */ + noun: string[]; + /** + * Some phrases that will be injected with random hacker words. + * May use any of the HackerDefinition keys wrapped in double braces. + * (e.g. `I'm {{ingverb}} {{adjective}} {{noun}}` ) + * + * @see Helpers.mustache() + */ + phrase: string[]; + /** + * Some computer related verbs (e.g. `hack`). + */ + verb: string[]; +} + +/** + * Internal: A list of all keys for the HackerDefinitions. + */ +export const HACKER = allOf()( + 'abbreviation', + 'adjective', + 'ingverb', + 'noun', + 'phrase', + 'verb' +); diff --git a/src/definitions/index.ts b/src/definitions/index.ts new file mode 100644 index 00000000000..e4659e0afe6 --- /dev/null +++ b/src/definitions/index.ts @@ -0,0 +1,27 @@ +export type { AddressDefinitions } from './address'; +export type { AnimalDefinitions } from './animal'; +export type { + CommerceDefinitions, + CommerceProductNameDefinitions, +} from './commerce'; +export type { CompanyDefinitions } from './company'; +export type { DatabaseDefinitions } from './database'; +export type { DateDefinitions, DateEntryDefinition } from './date'; +export type { DefinitionTypes, LocaleDefinition } from './definitions'; +export { DEFINITIONS } from './definitions'; +export type { + FinanceCurrencyEntryDefinitions, + FinanceDefinitions, +} from './finance'; +export type { HackerDefinitions } from './hacker'; +export type { InternetDefinitions } from './internet'; +export type { LoremDefinitions } from './lorem'; +export type { MusicDefinitions } from './music'; +export type { NameDefinitions, NameTitleDefinitions } from './name'; +export type { PhoneNumberDefinitions } from './phone_number'; +export type { + SystemDefinitions, + SystemMimeTypeEntryDefinitions, +} from './system'; +export type { VehicleDefinitions } from './vehicle'; +export type { WordDefinitions } from './word'; diff --git a/src/definitions/internet.ts b/src/definitions/internet.ts new file mode 100644 index 00000000000..55448841d8c --- /dev/null +++ b/src/definitions/internet.ts @@ -0,0 +1,28 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to internet stuff. + */ +export interface InternetDefinitions { + /** + * Common top level and similar domains (e.g `de`, `co.uk`). + */ + domain_suffix: string[]; + /** + * Some email domains containing `example` (e.g. `example.com`). + */ + example_email: string[]; + /** + * Some free-mail domains used in that country (e.g. `gmail.de`). + */ + free_email: string[]; +} + +/** + * Internal: A list of all keys for the InternetDefinitions. + */ +export const INTERNET = allOf()( + 'domain_suffix', + 'example_email', + 'free_email' +); diff --git a/src/definitions/lorem.ts b/src/definitions/lorem.ts new file mode 100644 index 00000000000..eb548e46fd4 --- /dev/null +++ b/src/definitions/lorem.ts @@ -0,0 +1,16 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to lorem texts. + */ +export interface LoremDefinitions { + /** + * Lorem words used to generate dummy texts. + */ + words: string[]; +} + +/** + * Internal: A list of all keys for the LoremDefinitions. + */ +export const LOREM = allOf()('words'); diff --git a/src/definitions/music.ts b/src/definitions/music.ts new file mode 100644 index 00000000000..1f2ffdd80bd --- /dev/null +++ b/src/definitions/music.ts @@ -0,0 +1,16 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to music. + */ +export interface MusicDefinitions { + /** + * The names of some music genres. + */ + genre: string[]; +} + +/** + * Internal: A list of all keys for the MusicDefinitions. + */ +export const MUSIC = allOf()('genre'); diff --git a/src/definitions/name.ts b/src/definitions/name.ts new file mode 100644 index 00000000000..57926649b09 --- /dev/null +++ b/src/definitions/name.ts @@ -0,0 +1,73 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to people's names. + */ +export interface NameDefinitions { + gender: string[]; + binary_gender: string[]; + + prefix?: string[]; + female_prefix?: string[]; + male_prefix?: string[]; + + first_name?: string[]; + female_first_name?: string[]; + male_first_name?: string[]; + + middle_name?: string[]; + female_middle_name?: string[]; + male_middle_name?: string[]; + + last_name?: string[]; + female_last_name?: string[]; + male_last_name?: string[]; + + suffix: string[]; + + /** + * A list of patterns used to generate names (Fake-Pattern[]). + */ + name: string[]; + + title: NameTitleDefinitions; +} + +/** + * The possible definitions related to people's titles. + */ +export interface NameTitleDefinitions { + descriptor?: string[]; + job: string[]; + level?: string[]; +} + +/** + * Internal: A list of all keys for the NameDefinitions. + */ +export const NAME = allOf()( + 'gender', + 'binary_gender', + + 'prefix', + 'female_prefix', + 'male_prefix', + + 'first_name', + 'female_first_name', + 'male_first_name', + + 'middle_name', + 'female_middle_name', + 'male_middle_name', + + 'last_name', + 'female_last_name', + 'male_last_name', + + 'suffix', + + 'name', + + 'title' +); diff --git a/src/definitions/phone_number.ts b/src/definitions/phone_number.ts new file mode 100644 index 00000000000..ed7353b552d --- /dev/null +++ b/src/definitions/phone_number.ts @@ -0,0 +1,21 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to phone numbers. + */ +export interface PhoneNumberDefinitions { + /** + * Some patterns used to generate phone numbers. + * `#` will be replaced by a random digit (0-9). + * `!` will be replaced by a random digit (2-9). + * (e.g. `!##-!##-####` -> 272-285-0453) + * + * @see Helpers.replaceSymbolWithNumber(format) + */ + formats: string[]; +} + +/** + * Internal: A list of all keys for the PhoneNumberDefinitions. + */ +export const PHONE_NUMBER = allOf()('formats'); diff --git a/src/definitions/system.ts b/src/definitions/system.ts new file mode 100644 index 00000000000..5c9039b43d1 --- /dev/null +++ b/src/definitions/system.ts @@ -0,0 +1,33 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to files and the system. + */ +export interface SystemDefinitions { + /** + * Returns some common file paths. + */ + directoryPaths: string[]; + /** + * The mime type definitions with some additional information. + */ + mimeTypes: { [mimeType: string]: SystemMimeTypeEntryDefinitions }; +} + +/** + * The mime type entry details. + */ +export interface SystemMimeTypeEntryDefinitions { + source?: string; + extensions?: string[]; + compressible?: boolean; + charset?: string; +} + +/** + * Internal: A list of all keys for the SystemDefinitions. + */ +export const SYSTEM = allOf()( + 'directoryPaths', + 'mimeTypes' +); diff --git a/src/definitions/utils.ts b/src/definitions/utils.ts new file mode 100644 index 00000000000..b7b826a1657 --- /dev/null +++ b/src/definitions/utils.ts @@ -0,0 +1,8 @@ +// https://stackoverflow.com/a/53395649/4573065 +export type AllOf = ['Needs to be all of', T]; + +export function allOf(): ( + ...array: U & ([T] extends [U[number]] ? unknown : AllOf[]) +) => U & ([T] extends [U[number]] ? unknown : AllOf[]) { + return (...array) => array; +} diff --git a/src/definitions/vehicle.ts b/src/definitions/vehicle.ts new file mode 100644 index 00000000000..7fdc11f1de1 --- /dev/null +++ b/src/definitions/vehicle.ts @@ -0,0 +1,38 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to vehicles. + */ +export interface VehicleDefinitions { + /** + * Some types of bicycles. + */ + bicycle_type: string[]; + /** + * Some types of fuel (e.g. `Gasoline`). + */ + fuel: string[]; + /** + * Some brands of manufactures (e.g. `Tesla`). + */ + manufacturer: string[]; + /** + * Some names of models (e.g. `Fiesta`). + */ + model: string[]; + /** + * Some types of vehicles (e.g. `Minivan`). + */ + type: string[]; +} + +/** + * Internal: A list of all keys for the VehicleDefinitions. + */ +export const VEHICLE = allOf()( + 'bicycle_type', + 'fuel', + 'manufacturer', + 'model', + 'type' +); diff --git a/src/definitions/word.ts b/src/definitions/word.ts new file mode 100644 index 00000000000..dcbe47dd508 --- /dev/null +++ b/src/definitions/word.ts @@ -0,0 +1,27 @@ +import { allOf } from './utils'; + +/** + * The possible definitions related to words. + */ +export interface WordDefinitions { + adjective: string[]; + adverb: string[]; + conjunction: string[]; + interjection: string[]; + noun: string[]; + preposition: string[]; + verb: string[]; +} + +/** + * Internal: A list of all keys for the WordDefinitions. + */ +export const WORD = allOf()( + 'adjective', + 'adverb', + 'conjunction', + 'interjection', + 'noun', + 'preposition', + 'verb' +); diff --git a/src/finance.ts b/src/finance.ts index 719d1198e95..9a7592518b5 100644 --- a/src/finance.ts +++ b/src/finance.ts @@ -244,6 +244,7 @@ export class Finance { format = provider; } else { // Choose a random provider + // TODO ST-DDT 2022-01-30: #375 This is impossible to access if (typeof localeFormat === 'string') { format = localeFormat; } else if (typeof localeFormat === 'object') { diff --git a/src/index.ts b/src/index.ts index d740faea929..4d9e8438cae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,8 @@ import { Company } from './company'; import { Database } from './database'; import { Datatype } from './datatype'; import { _Date } from './date'; -import type { Definitions } from './definitions'; +import type { LocaleDefinition } from './definitions'; +import { DEFINITIONS } from './definitions'; import { Fake } from './fake'; import { Finance } from './finance'; import { Git } from './git'; @@ -30,171 +31,10 @@ import { Word } from './word'; // https://github.com/microsoft/TypeScript/issues/29729#issuecomment-471566609 type LiteralUnion = T | (U & { zz_IGNORE_ME?: never }); -export interface LocaleDefinition { - title: string; - separator?: string; - - address?: Partial<{ - building_number: any[]; - city_name: any[]; - city_prefix: any[]; - city_suffix: any[]; - city: any[]; - country_code_alpha_3: any[]; - country_code: any[]; - country: any[]; - county: any[]; - default_country: any[]; - direction_abbr: any[]; - direction: any[]; - postcode_by_state: any[]; - postcode: any[]; - secondary_address: any[]; - state_abbr: any[]; - state: any[]; - street_address: any[]; - street_name: any[]; - street_suffix: any[]; - time_zone: any[]; - }>; - animal?: Partial<{ - bear: any[]; - bird: any[]; - cat: any[]; - cetacean: any[]; - cow: any[]; - crocodilia: any[]; - dog: any[]; - fish: any[]; - horse: any[]; - insect: any[]; - lion: any[]; - rabbit: any[]; - snake: any[]; - type: any[]; - }>; - app?: Partial<{ - author: any[]; - name: any[]; - version: any[]; - }>; - business?: Partial<{ - credit_card_expiry_dates: any[]; - credit_card_numbers: any[]; - credit_card_types: any[]; - }>; - cell_phone?: Partial<{ - formats: any[]; - }>; - commerce?: Partial<{ - color: any[]; - department: any[]; - product_description: any[]; - product_name: any[]; - }>; - company?: Partial<{ - adjective: any[]; - bs_adjective: any[]; - bs_noun: any[]; - bs_verb: any[]; - descriptor: any[]; - name: any[]; - noun: any[]; - suffix: any[]; - }>; - database?: Partial<{ - collation: any[]; - column: any[]; - engine: any[]; - type: any[]; - }>; - date?: Partial<{ - month: any[]; - weekday: any[]; - }>; - finance?: Partial<{ - account_type: any[]; - credit_card: any[]; - currency: any[]; - transaction_type: any[]; - }>; - hacker?: Partial<{ - abbreviation: any[]; - adjective: any[]; - ingverb: any[]; - noun: any[]; - phrase: any[]; - verb: any[]; - }>; - internet?: Partial<{ - avatar_uri: any[]; - domain_suffix: any[]; - example_email: any[]; - free_email: any[]; - }>; - lorem?: Partial<{ - supplemental: any[]; - words: any[]; - }>; - music?: Partial<{ - genre: any[]; - }>; - name?: Partial<{ - binary_gender: string[]; - female_first_name: string[]; - female_last_name: string[]; - female_middle_name: string[]; - female_prefix: string[]; - first_name: string[]; - gender: string[]; - last_name: string[]; - male_first_name: string[]; - male_last_name: string[]; - male_middle_name: string[]; - male_prefix: string[]; - name: string[]; - prefix: string[]; - suffix: string[]; - title: { - descriptor?: string[]; - job: string[]; - level?: string[]; - }; - }>; - phone_number?: Partial<{ - formats: any[]; - }>; - system?: Partial<{ - directoryPaths: any[]; - mimeTypes: any[]; - }>; - team?: Partial<{ - creature: any[]; - name: any[]; - }>; - vehicle?: Partial<{ - bicycle: any[]; - fuel: any[]; - manufacturer: any[]; - model: any[]; - type: any[]; - }>; - word?: Partial<{ - adjective: any[]; - adverb: any[]; - conjunction: any[]; - interjection: any[]; - noun: any[]; - preposition: any[]; - verb: any[]; - }>; - [group: string]: any; -} - export type UsableLocale = LiteralUnion; export type UsedLocales = Partial>; -export type { Definitions }; +export type { LocaleDefinition }; export interface FakerOptions { locales?: UsedLocales; @@ -202,145 +42,13 @@ export interface FakerOptions { localeFallback?: UsableLocale; } -export interface DefinitionTypes { - readonly name: string[]; - readonly address: string[]; - readonly animal: string[]; - readonly company: string[]; - readonly lorem: string[]; - readonly hacker: string[]; - readonly phone_number: string[]; - readonly finance: string[]; - readonly internet: string[]; - readonly commerce: string[]; - readonly database: string[]; - readonly system: string[]; - readonly date: string[]; - readonly vehicle: string[]; - readonly music: string[]; - readonly word: string[]; - readonly title: string | string[]; - readonly separator: string | string[]; -} - export class Faker { locales: UsedLocales; locale: UsableLocale; localeFallback: UsableLocale; - // @ts-expect-error: will be lazy filled by constructor - readonly definitions: Definitions = {}; - private readonly definitionTypes: DefinitionTypes = { - name: [ - 'first_name', - 'last_name', - 'prefix', - 'suffix', - 'binary_gender', - 'gender', - 'title', - 'male_prefix', - 'female_prefix', - 'male_first_name', - 'female_first_name', - 'male_middle_name', - 'female_middle_name', - 'male_last_name', - 'female_last_name', - ], - address: [ - 'city_name', - 'city_prefix', - 'city_suffix', - 'street_suffix', - 'county', - 'country', - 'country_code', - 'country_code_alpha_3', - 'state', - 'state_abbr', - 'street_prefix', - 'postcode', - 'postcode_by_state', - 'direction', - 'direction_abbr', - 'time_zone', - ], - animal: [ - 'dog', - 'cat', - 'snake', - 'bear', - 'lion', - 'cetacean', - 'insect', - 'crocodilia', - 'cow', - 'bird', - 'fish', - 'rabbit', - 'horse', - 'type', - ], - company: [ - 'adjective', - 'noun', - 'descriptor', - 'bs_adjective', - 'bs_noun', - 'bs_verb', - 'suffix', - ], - lorem: ['words'], - hacker: ['abbreviation', 'adjective', 'noun', 'verb', 'ingverb', 'phrase'], - phone_number: ['formats'], - finance: [ - 'account_type', - 'transaction_type', - 'currency', - 'iban', - 'credit_card', - ], - internet: [ - 'avatar_uri', - 'domain_suffix', - 'free_email', - 'example_email', - 'password', - ], - commerce: [ - 'color', - 'department', - 'product_name', - 'price', - 'categories', - 'product_description', - ], - database: ['collation', 'column', 'engine', 'type'], - system: ['mimeTypes', 'directoryPaths'], - date: ['month', 'weekday'], - vehicle: [ - 'vehicle', - 'manufacturer', - 'model', - 'type', - 'fuel', - 'vin', - 'color', - ], - music: ['genre'], - word: [ - 'adjective', - 'adverb', - 'conjunction', - 'interjection', - 'noun', - 'preposition', - 'verb', - ], - title: '', - separator: '', - }; + // Will be lazy init + readonly definitions: LocaleDefinition = {} as LocaleDefinition; seedValue?: any[] | any; @@ -381,30 +89,26 @@ export class Faker { this.locale = this.locale || opts.locale || 'en'; this.localeFallback = this.localeFallback || opts.localeFallback || 'en'; - this.loadDefinitions(this.definitionTypes); + this.loadDefinitions(); } /** * Load the definitions contained in the locales file for the given types - * - * @param types */ - private loadDefinitions(types: DefinitionTypes): void { + private loadDefinitions(): void { // TODO @Shinigami92 2022-01-11: Find a way to load this even more dynamically // In a way so that we don't accidentally miss a definition - Object.keys(types).forEach((t: keyof DefinitionTypes) => { + Object.entries(DEFINITIONS).forEach(([t, v]) => { if (typeof this.definitions[t] === 'undefined') { this.definitions[t] = {}; } - if (typeof types[t] === 'string') { - this.definitions[t] = types[t]; + if (typeof v === 'string') { + this.definitions[t] = v; return; } - // TODO @Shinigami92 2022-01-11: We may have a bug here for the keys 'title' and 'separator' - // @ts-expect-error - types[t].forEach((p) => { + v.forEach((p) => { Object.defineProperty(this.definitions[t], p, { get: () => { if ( diff --git a/src/locales/el/credit_card/index.ts b/src/locales/el/credit_card/index.ts index 3ed856dc133..92cf1e689f1 100644 --- a/src/locales/el/credit_card/index.ts +++ b/src/locales/el/credit_card/index.ts @@ -1,10 +1,11 @@ +import type { FinanceDefinitions } from '../../../definitions'; import american_express from './american_express'; import discover from './discover'; import maestro from './maestro'; import mastercard from './mastercard'; import visa from './visa'; -const credit_card: any = { +const credit_card: FinanceDefinitions['credit_card'] = { american_express, discover, maestro, diff --git a/src/locales/el/finance/index.ts b/src/locales/el/finance/index.ts index d899702fd31..76e0fa8d062 100644 --- a/src/locales/el/finance/index.ts +++ b/src/locales/el/finance/index.ts @@ -1,8 +1,9 @@ +import type { FinanceDefinitions } from '../../../definitions'; import account_type from './account_type'; import currency from './currency'; import transaction_type from './transaction_type'; -const finance: any = { +const finance: Partial = { account_type, currency, transaction_type, diff --git a/src/locales/el/hacker/index.ts b/src/locales/el/hacker/index.ts index 35032f5227c..28143c2bd80 100644 --- a/src/locales/el/hacker/index.ts +++ b/src/locales/el/hacker/index.ts @@ -1,9 +1,10 @@ +import type { HackerDefinitions } from '../../../definitions'; import abbreviation from './abbreviation'; import adjective from './adjective'; import noun from './noun'; import verb from './verb'; -const hacker: any = { +const hacker: Partial = { abbreviation, adjective, noun, diff --git a/src/locales/en/address/index.ts b/src/locales/en/address/index.ts index d0677de66cc..27c071aa886 100644 --- a/src/locales/en/address/index.ts +++ b/src/locales/en/address/index.ts @@ -1,3 +1,4 @@ +import type { AddressDefinitions } from '../../../definitions'; import building_number from './building_number'; import city from './city'; import city_name from './city_name'; @@ -20,28 +21,38 @@ import street_name from './street_name'; import street_suffix from './street_suffix'; import time_zone from './time_zone'; -const address: any = { - building_number, +const address = { + postcode, + postcode_by_state, + city, city_name, city_prefix, city_suffix, + country, - country_code, - country_code_alpha_3, + state, + state_abbr, county, - default_country, + direction, direction_abbr, - postcode, - postcode_by_state, + + // street_prefix + street_suffix, + secondary_address, - state, - state_abbr, + + country_code, + country_code_alpha_3, + + time_zone, + + // Extra street_address, street_name, - street_suffix, - time_zone, -}; + default_country, + building_number, +} as Partial; export default address; diff --git a/src/locales/en/animal/index.ts b/src/locales/en/animal/index.ts index f576b998579..33625a81f44 100644 --- a/src/locales/en/animal/index.ts +++ b/src/locales/en/animal/index.ts @@ -1,3 +1,4 @@ +import type { AnimalDefinitions } from '../../../definitions'; import bear from './bear'; import bird from './bird'; import cat from './cat'; @@ -13,7 +14,7 @@ import rabbit from './rabbit'; import snake from './snake'; import type from './type'; -const animal: any = { +const animal: AnimalDefinitions = { bear, bird, cat, diff --git a/src/locales/en/commerce/index.ts b/src/locales/en/commerce/index.ts index 74ccad9a532..30ab7e1ee56 100644 --- a/src/locales/en/commerce/index.ts +++ b/src/locales/en/commerce/index.ts @@ -1,9 +1,10 @@ +import type { CommerceDefinitions } from '../../../definitions'; import color from './color'; import department from './department'; import product_description from './product_description'; import product_name from './product_name'; -const commerce: any = { +const commerce: CommerceDefinitions = { color, department, product_description, diff --git a/src/locales/en/company/index.ts b/src/locales/en/company/index.ts index 9c2343931ad..82326134396 100644 --- a/src/locales/en/company/index.ts +++ b/src/locales/en/company/index.ts @@ -1,3 +1,4 @@ +import type { CompanyDefinitions } from '../../../definitions'; import adjective from './adjective'; import bs_adjective from './bs_adjective'; import bs_noun from './bs_noun'; @@ -7,15 +8,18 @@ import name from './name'; import noun from './noun'; import suffix from './suffix'; -const company: any = { - adjective, +const company = { bs_adjective, bs_noun, bs_verb, + + adjective, descriptor, - name, noun, + suffix, -}; + + name, +} as CompanyDefinitions; export default company; diff --git a/src/locales/en/database/index.ts b/src/locales/en/database/index.ts index 8be270761e9..44774db2121 100644 --- a/src/locales/en/database/index.ts +++ b/src/locales/en/database/index.ts @@ -1,9 +1,10 @@ +import type { DatabaseDefinitions } from '../../../definitions'; import collation from './collation'; import column from './column'; import engine from './engine'; import type from './type'; -const database: any = { +const database: DatabaseDefinitions = { collation, column, engine, diff --git a/src/locales/en/date/index.ts b/src/locales/en/date/index.ts index 35b1df67c7d..e722b683f7b 100644 --- a/src/locales/en/date/index.ts +++ b/src/locales/en/date/index.ts @@ -1,7 +1,8 @@ +import type { DateDefinitions } from '../../../definitions'; import month from './month'; import weekday from './weekday'; -const date: any = { +const date: DateDefinitions = { month, weekday, }; diff --git a/src/locales/en/finance/credit_card/index.ts b/src/locales/en/finance/credit_card/index.ts index 47b74b5a06c..08f33e9cbc9 100644 --- a/src/locales/en/finance/credit_card/index.ts +++ b/src/locales/en/finance/credit_card/index.ts @@ -1,3 +1,4 @@ +import type { FinanceDefinitions } from '../../../../definitions'; import american_express from './american_express'; import diners_club from './diners_club'; import discover from './discover'; @@ -10,7 +11,7 @@ import solo from './solo'; import switch_ from './switch'; import visa from './visa'; -const credit_card: any = { +const credit_card: FinanceDefinitions['credit_card'] = { american_express, diners_club, discover, diff --git a/src/locales/en/finance/index.ts b/src/locales/en/finance/index.ts index 969746b0687..004d53143cb 100644 --- a/src/locales/en/finance/index.ts +++ b/src/locales/en/finance/index.ts @@ -1,9 +1,10 @@ +import type { FinanceDefinitions } from '../../../definitions'; import account_type from './account_type'; import credit_card from './credit_card'; import currency from './currency'; import transaction_type from './transaction_type'; -const finance: any = { +const finance: FinanceDefinitions = { account_type, credit_card, currency, diff --git a/src/locales/en/hacker/index.ts b/src/locales/en/hacker/index.ts index 959b7e0a14c..196657a8320 100644 --- a/src/locales/en/hacker/index.ts +++ b/src/locales/en/hacker/index.ts @@ -1,3 +1,4 @@ +import type { HackerDefinitions } from '../../../definitions'; import abbreviation from './abbreviation'; import adjective from './adjective'; import ingverb from './ingverb'; @@ -5,7 +6,7 @@ import noun from './noun'; import phrase from './phrase'; import verb from './verb'; -const hacker: any = { +const hacker: HackerDefinitions = { abbreviation, adjective, ingverb, diff --git a/src/locales/en/internet/index.ts b/src/locales/en/internet/index.ts index 028fd227691..a1788c66178 100644 --- a/src/locales/en/internet/index.ts +++ b/src/locales/en/internet/index.ts @@ -1,13 +1,14 @@ +import type { InternetDefinitions } from '../../../definitions'; import avatar_uri from './avatar_uri'; import domain_suffix from './domain_suffix'; import example_email from './example_email'; import free_email from './free_email'; -const internet: any = { +const internet = { avatar_uri, domain_suffix, example_email, free_email, -}; +} as InternetDefinitions; export default internet; diff --git a/src/locales/en/lorem/index.ts b/src/locales/en/lorem/index.ts index 62962376cd4..9f1838e169e 100644 --- a/src/locales/en/lorem/index.ts +++ b/src/locales/en/lorem/index.ts @@ -1,9 +1,10 @@ +import type { LoremDefinitions } from '../../../definitions'; import supplemental from './supplemental'; import words from './words'; -const lorem: any = { +const lorem = { supplemental, words, -}; +} as LoremDefinitions; export default lorem; diff --git a/src/locales/en/music/index.ts b/src/locales/en/music/index.ts index 54b9163ea41..3347664de77 100644 --- a/src/locales/en/music/index.ts +++ b/src/locales/en/music/index.ts @@ -1,6 +1,7 @@ +import type { MusicDefinitions } from '../../../definitions'; import genre from './genre'; -const music: any = { +const music: MusicDefinitions = { genre, }; diff --git a/src/locales/en/name/index.ts b/src/locales/en/name/index.ts index 6e21934a33d..8241b4ad716 100644 --- a/src/locales/en/name/index.ts +++ b/src/locales/en/name/index.ts @@ -1,3 +1,4 @@ +import type { NameDefinitions } from '../../../definitions'; import binary_gender from './binary_gender'; import female_first_name from './female_first_name'; import first_name from './first_name'; @@ -9,16 +10,22 @@ import prefix from './prefix'; import suffix from './suffix'; import title from './title'; -const name: any = { +const name: NameDefinitions = { binary_gender, - female_first_name, - first_name, gender, - last_name, - male_first_name, - name: name_, + prefix, + + first_name, + female_first_name, + male_first_name, + + last_name, + suffix, + + name: name_, + title, }; diff --git a/src/locales/en/name/title.ts b/src/locales/en/name/title.ts index b18b6004c1b..ec599841aa0 100644 --- a/src/locales/en/name/title.ts +++ b/src/locales/en/name/title.ts @@ -1,4 +1,6 @@ -export default { +import type { NameTitleDefinitions } from '../../../definitions'; + +const title: NameTitleDefinitions = { descriptor: [ 'Lead', 'Senior', @@ -90,3 +92,5 @@ export default { 'Strategist', ], }; + +export default title; diff --git a/src/locales/en/phone_number/index.ts b/src/locales/en/phone_number/index.ts index f760b9e1550..6b8f73b0266 100644 --- a/src/locales/en/phone_number/index.ts +++ b/src/locales/en/phone_number/index.ts @@ -1,6 +1,7 @@ +import type { PhoneNumberDefinitions } from '../../../definitions'; import formats from './formats'; -const phone_number: any = { +const phone_number: PhoneNumberDefinitions = { formats, }; diff --git a/src/locales/en/system/index.ts b/src/locales/en/system/index.ts index 3fde96086c0..c873d9d702a 100644 --- a/src/locales/en/system/index.ts +++ b/src/locales/en/system/index.ts @@ -1,7 +1,8 @@ +import type { SystemDefinitions } from '../../../definitions'; import directoryPaths from './directoryPaths'; import mimeTypes from './mimeTypes'; -const system: any = { +const system: SystemDefinitions = { directoryPaths, mimeTypes, }; diff --git a/src/locales/en/vehicle/index.ts b/src/locales/en/vehicle/index.ts index f48d68b37d1..01ecc1c034f 100644 --- a/src/locales/en/vehicle/index.ts +++ b/src/locales/en/vehicle/index.ts @@ -1,15 +1,16 @@ +import type { VehicleDefinitions } from '../../../definitions'; import bicycle from './bicycle'; import fuel from './fuel'; import manufacturer from './manufacturer'; import model from './model'; import type_ from './type'; -const vehicle: any = { +const vehicle = { bicycle, fuel, manufacturer, model, type: type_, -}; +} as Partial; export default vehicle; diff --git a/src/locales/en/word/index.ts b/src/locales/en/word/index.ts index 7fed2b4375c..8f76f579b7b 100644 --- a/src/locales/en/word/index.ts +++ b/src/locales/en/word/index.ts @@ -1,3 +1,4 @@ +import type { WordDefinitions } from '../../../definitions'; import adjective from './adjective'; import adverb from './adverb'; import conjunction from './conjunction'; @@ -6,7 +7,7 @@ import noun from './noun'; import preposition from './preposition'; import verb from './verb'; -const word: any = { +const word: WordDefinitions = { adjective, adverb, conjunction, diff --git a/src/locales/fa/finance/credit_card/index.ts b/src/locales/fa/finance/credit_card/index.ts index a05f43510f4..7a1430a4ac3 100644 --- a/src/locales/fa/finance/credit_card/index.ts +++ b/src/locales/fa/finance/credit_card/index.ts @@ -1,7 +1,8 @@ +import type { FinanceDefinitions } from '../../../../definitions'; import mastercard from './mastercard'; import visa from './visa'; -const credit_card: any = { +const credit_card: FinanceDefinitions['credit_card'] = { mastercard, visa, }; diff --git a/src/locales/fa/finance/index.ts b/src/locales/fa/finance/index.ts index 969746b0687..004d53143cb 100644 --- a/src/locales/fa/finance/index.ts +++ b/src/locales/fa/finance/index.ts @@ -1,9 +1,10 @@ +import type { FinanceDefinitions } from '../../../definitions'; import account_type from './account_type'; import credit_card from './credit_card'; import currency from './currency'; import transaction_type from './transaction_type'; -const finance: any = { +const finance: FinanceDefinitions = { account_type, credit_card, currency, diff --git a/src/locales/nl/hacker/index.ts b/src/locales/nl/hacker/index.ts index 34dc68f20d0..12c95cf77dc 100644 --- a/src/locales/nl/hacker/index.ts +++ b/src/locales/nl/hacker/index.ts @@ -1,9 +1,10 @@ +import type { HackerDefinitions } from '../../../definitions'; import adjective from './adjective'; import noun from './noun'; import phrase from './phrase'; import verb from './verb'; -const hacker: any = { +const hacker: Partial = { adjective, noun, phrase, diff --git a/src/locales/ru/hacker/index.ts b/src/locales/ru/hacker/index.ts index 959b7e0a14c..d19ca4b25d0 100644 --- a/src/locales/ru/hacker/index.ts +++ b/src/locales/ru/hacker/index.ts @@ -1,3 +1,4 @@ +import type { HackerDefinitions } from '../../../definitions'; import abbreviation from './abbreviation'; import adjective from './adjective'; import ingverb from './ingverb'; @@ -5,7 +6,7 @@ import noun from './noun'; import phrase from './phrase'; import verb from './verb'; -const hacker: any = { +const hacker: Partial = { abbreviation, adjective, ingverb, diff --git a/src/lorem.ts b/src/lorem.ts index 9368ec019fa..afbc6df36e6 100644 --- a/src/lorem.ts +++ b/src/lorem.ts @@ -24,7 +24,7 @@ export class Lorem { */ word(length?: number): string { const hasRightLength = (word: string) => word.length === length; - let properLengthWords: string[]; + let properLengthWords: readonly string[]; if (typeof length === 'undefined') { properLengthWords = this.faker.definitions.lorem.words; } else { diff --git a/src/name.ts b/src/name.ts index d00094e24b3..74c8e522e35 100644 --- a/src/name.ts +++ b/src/name.ts @@ -110,11 +110,11 @@ export class Name { } if (gender === 0) { return this.faker.random.arrayElement( - this.faker.locales[this.faker.locale].name.male_middle_name + this.faker.definitions.name.male_middle_name ); } else { return this.faker.random.arrayElement( - this.faker.locales[this.faker.locale].name.female_middle_name + this.faker.definitions.name.female_middle_name ); } }