From 1173e5c5bfec81ca1e9644a135350a618ed8711b Mon Sep 17 00:00:00 2001 From: rodrigobnogueira Date: Sat, 11 Jul 2026 20:13:17 -0300 Subject: [PATCH 1/3] feat(medical): add a medical module Adds `faker.medical` with plausible, non-clinical healthcare data for tests, demos, and fixtures: specialty, department, condition, symptom, procedure, allergen, bloodType, and a fictitious drugName. Scoped to Faker's plausible-not-real policy per the discussion in #2309: real diagnosis codes (ICD-10), real medicine names, and correlated patient records are deliberately excluded. drugName() assembles invented brand-style names from morphemes and avoids real WHO INN stems, so it can never resemble a real drug. English locale data; tests, snapshots, and JSDoc included. Ref #2309 --- scripts/generate-locales.ts | 1 + src/definitions/definitions.ts | 2 + src/definitions/index.ts | 1 + src/definitions/medical.ts | 62 ++++ src/faker.ts | 2 + src/index.ts | 1 + src/locales/en/index.ts | 2 + src/locales/en/medical/allergen.ts | 42 +++ src/locales/en/medical/blood_type.ts | 1 + src/locales/en/medical/condition.ts | 160 ++++++++++ src/locales/en/medical/department.ts | 32 ++ .../en/medical/drug_forbidden_ending.ts | 18 ++ src/locales/en/medical/drug_infix.ts | 22 ++ src/locales/en/medical/drug_prefix.ts | 52 ++++ src/locales/en/medical/drug_suffix.ts | 32 ++ src/locales/en/medical/index.ts | 31 ++ src/locales/en/medical/procedure.ts | 107 +++++++ src/locales/en/medical/specialty.ts | 28 ++ src/locales/en/medical/symptom.ts | 291 ++++++++++++++++++ src/modules/medical/index.ts | 1 + src/modules/medical/module.ts | 161 ++++++++++ .../__snapshots__/medical.spec.ts.snap | 49 +++ test/modules/medical.spec.ts | 92 ++++++ .../verify-jsdoc-tags.spec.ts.snap | 13 + 24 files changed, 1203 insertions(+) create mode 100644 src/definitions/medical.ts create mode 100644 src/locales/en/medical/allergen.ts create mode 100644 src/locales/en/medical/blood_type.ts create mode 100644 src/locales/en/medical/condition.ts create mode 100644 src/locales/en/medical/department.ts create mode 100644 src/locales/en/medical/drug_forbidden_ending.ts create mode 100644 src/locales/en/medical/drug_infix.ts create mode 100644 src/locales/en/medical/drug_prefix.ts create mode 100644 src/locales/en/medical/drug_suffix.ts create mode 100644 src/locales/en/medical/index.ts create mode 100644 src/locales/en/medical/procedure.ts create mode 100644 src/locales/en/medical/specialty.ts create mode 100644 src/locales/en/medical/symptom.ts create mode 100644 src/modules/medical/index.ts create mode 100644 src/modules/medical/module.ts create mode 100644 test/modules/__snapshots__/medical.spec.ts.snap create mode 100644 test/modules/medical.spec.ts diff --git a/scripts/generate-locales.ts b/scripts/generate-locales.ts index d51d58b83e8..491d571deef 100644 --- a/scripts/generate-locales.ts +++ b/scripts/generate-locales.ts @@ -60,6 +60,7 @@ const definitionsTypes: DefinitionType = { internet: 'InternetDefinition', location: 'LocationDefinition', lorem: 'LoremDefinition', + medical: 'MedicalDefinition', metadata: 'MetadataDefinition', music: 'MusicDefinition', person: 'PersonDefinition', diff --git a/src/definitions/definitions.ts b/src/definitions/definitions.ts index d207ec123f3..ca1ace2421d 100644 --- a/src/definitions/definitions.ts +++ b/src/definitions/definitions.ts @@ -12,6 +12,7 @@ import type { HackerDefinition } from './hacker'; import type { InternetDefinition } from './internet'; import type { LocationDefinition } from './location'; import type { LoremDefinition } from './lorem'; +import type { MedicalDefinition } from './medical'; import type { MetadataDefinition } from './metadata'; import type { MusicDefinition } from './music'; import type { PersonDefinition } from './person'; @@ -47,6 +48,7 @@ export type LocaleDefinition = { internet?: InternetDefinition; location?: LocationDefinition; lorem?: LoremDefinition; + medical?: MedicalDefinition; music?: MusicDefinition; person?: PersonDefinition; phone_number?: PhoneNumberDefinition; diff --git a/src/definitions/index.ts b/src/definitions/index.ts index 68ac04011f1..e98ccde0b32 100644 --- a/src/definitions/index.ts +++ b/src/definitions/index.ts @@ -16,6 +16,7 @@ export type { HackerDefinition } from './hacker'; export type { InternetDefinition } from './internet'; export type { LocationDefinition } from './location'; export type { LoremDefinition } from './lorem'; +export type { MedicalDefinition } from './medical'; export type { MetadataDefinition } from './metadata'; export type { MusicDefinition } from './music'; export type { PersonDefinition, PersonEntryDefinition } from './person'; diff --git a/src/definitions/medical.ts b/src/definitions/medical.ts new file mode 100644 index 00000000000..ccbdae80393 --- /dev/null +++ b/src/definitions/medical.ts @@ -0,0 +1,62 @@ +import type { LocaleEntry } from './definitions'; + +/** + * The possible definitions related to medical and healthcare data. + */ +export type MedicalDefinition = LocaleEntry<{ + /** + * Medical specialties, e.g. `'Cardiology'`. + */ + specialty: string[]; + + /** + * Hospital departments, e.g. `'Emergency Department'`. + */ + department: string[]; + + /** + * Plausible medical condition names (without diagnosis codes), e.g. `'Type 2 Diabetes'`. + */ + condition: string[]; + + /** + * Symptoms, e.g. `'Shortness of Breath'`. + */ + symptom: string[]; + + /** + * Medical procedures, e.g. `'Appendectomy'`. + */ + procedure: string[]; + + /** + * Common allergens, e.g. `'Penicillin'`. + */ + allergen: string[]; + + /** + * Blood types, e.g. `'O+'`. + */ + blood_type: string[]; + + /** + * Invented morpheme prefixes used to build fictitious drug names. + */ + drug_prefix: string[]; + + /** + * Invented morpheme infixes used to build fictitious drug names. + */ + drug_infix: string[]; + + /** + * Invented morpheme suffixes used to build fictitious drug names. + */ + drug_suffix: string[]; + + /** + * Real INN stems that a fictitious drug name must not end with, so generated + * names cannot resemble real substances. + */ + drug_forbidden_ending: string[]; +}>; diff --git a/src/faker.ts b/src/faker.ts index 16a80384eee..5615a0db8a9 100644 --- a/src/faker.ts +++ b/src/faker.ts @@ -19,6 +19,7 @@ import { ImageModule } from './modules/image'; import { InternetModule } from './modules/internet'; import { LocationModule } from './modules/location'; import { LoremModule } from './modules/lorem'; +import { MedicalModule } from './modules/medical'; import { MusicModule } from './modules/music'; import { PersonModule } from './modules/person'; import { PhoneModule } from './modules/phone'; @@ -73,6 +74,7 @@ export class Faker extends SimpleFaker { readonly internet: InternetModule = new InternetModule(this); readonly location: LocationModule = new LocationModule(this); readonly lorem: LoremModule = new LoremModule(this); + readonly medical: MedicalModule = new MedicalModule(this); readonly music: MusicModule = new MusicModule(this); readonly person: PersonModule = new PersonModule(this); readonly phone: PhoneModule = new PhoneModule(this); diff --git a/src/index.ts b/src/index.ts index d75e522ce0a..2b85647ca58 100644 --- a/src/index.ts +++ b/src/index.ts @@ -75,6 +75,7 @@ export { IPv4Network } from './modules/internet'; export type { IPv4NetworkType, InternetModule } from './modules/internet'; export type { LocationModule, SimpleLocationModule } from './modules/location'; export type { LoremModule } from './modules/lorem'; +export type { MedicalModule } from './modules/medical'; export type { MusicModule } from './modules/music'; export type { NumberModule } from './modules/number'; export { Sex } from './modules/person'; diff --git a/src/locales/en/index.ts b/src/locales/en/index.ts index 994287a82ce..e32cc7b0ff3 100644 --- a/src/locales/en/index.ts +++ b/src/locales/en/index.ts @@ -19,6 +19,7 @@ import hacker from './hacker'; import internet from './internet'; import location from './location'; import lorem from './lorem'; +import medical from './medical'; import metadata from './metadata'; import music from './music'; import person from './person'; @@ -51,6 +52,7 @@ const en: LocaleDefinition = { internet, location, lorem, + medical, metadata, music, person, diff --git a/src/locales/en/medical/allergen.ts b/src/locales/en/medical/allergen.ts new file mode 100644 index 00000000000..7c392d28be9 --- /dev/null +++ b/src/locales/en/medical/allergen.ts @@ -0,0 +1,42 @@ +export default [ + 'Adhesive', + 'Anesthesia', + 'Aspirin', + 'Bee Sting', + 'Celery', + 'Cockroaches', + 'Codeine', + 'Contrast Dye', + 'Corn', + 'Dust Mites', + 'Eggs', + 'Fish', + 'Fragrance', + 'Fructose', + 'Gluten', + 'Grass', + 'Ibuprofen', + 'Insect Bites', + 'Lactose', + 'Latex', + 'Lupin', + 'MSG', + 'Milk', + 'Mold', + 'Morphine', + 'Mustard', + 'Nickel', + 'Peanuts', + 'Penicillin', + 'Pet Dander', + 'Pollen', + 'Ragweed', + 'Red Dye', + 'Sesame', + 'Shellfish', + 'Soy', + 'Sulfa Drugs', + 'Sulfites', + 'Tree Nuts', + 'Wheat', +]; diff --git a/src/locales/en/medical/blood_type.ts b/src/locales/en/medical/blood_type.ts new file mode 100644 index 00000000000..23f769b690c --- /dev/null +++ b/src/locales/en/medical/blood_type.ts @@ -0,0 +1 @@ +export default ['A+', 'A-', 'AB+', 'AB-', 'B+', 'B-', 'O+', 'O-']; diff --git a/src/locales/en/medical/condition.ts b/src/locales/en/medical/condition.ts new file mode 100644 index 00000000000..e6925b2bade --- /dev/null +++ b/src/locales/en/medical/condition.ts @@ -0,0 +1,160 @@ +export default [ + 'Acne Vulgaris', + 'Acute Bronchitis', + 'Acute Kidney Injury', + 'Acute Sinusitis', + 'Allergic Rhinitis', + "Alzheimer's Disease", + 'Anal Fissure', + 'Anemia', + 'Angina Pectoris', + 'Anxiety Disorder', + 'Aortic Aneurysm', + 'Appendicitis', + 'Asthma', + 'Atrial Fibrillation', + 'Attention Deficit Hyperactivity Disorder', + 'Autism Spectrum Disorder', + "Barrett's Esophagus", + 'Basal Cell Carcinoma', + 'Benign Prostatic Hyperplasia', + 'Bipolar Disorder', + 'Bladder Cancer', + 'Brain Tumor', + 'Breast Cancer', + 'Bronchiolitis', + 'COVID-19', + 'Cardiomyopathy', + 'Carpal Tunnel Syndrome', + 'Cataracts', + 'Celiac Disease', + 'Cellulitis', + 'Cholecystitis', + 'Chronic Kidney Disease', + 'Chronic Liver Disease', + 'Chronic Obstructive Pulmonary Disease', + 'Chronic Pain Syndrome', + 'Chronic Sinusitis', + 'Cirrhosis', + 'Colon Cancer', + 'Congenital Heart Disease', + 'Congestive Heart Failure', + 'Coronary Artery Disease', + "Crohn's Disease", + 'Croup', + 'Cystic Fibrosis', + 'Deep Vein Thrombosis', + 'Dengue Fever', + 'Depression', + 'Diabetic Retinopathy', + 'Diverticulitis', + 'Eczema', + 'Emphysema', + 'Endocarditis', + 'Endometrial Cancer', + 'Endometriosis', + 'Epilepsy', + 'Erectile Dysfunction', + 'Esophagitis', + 'Essential Hypertension', + 'Fecal Incontinence', + 'Fibromyalgia', + 'Gastritis', + 'Gastroesophageal Reflux Disease', + 'Gestational Diabetes', + 'Glaucoma', + 'Glomerulonephritis', + 'Gout', + 'HIV/AIDS', + 'Hearing Loss', + 'Hemophilia', + 'Hemorrhoids', + 'Hepatitis C', + 'Hiatal Hernia', + 'Hyperlipidemia', + 'Hypertensive Heart Disease', + 'Hyperthyroidism', + 'Hypothyroidism', + 'Infectious Mononucleosis', + 'Influenza', + 'Interstitial Cystitis', + 'Interstitial Lung Disease', + 'Iron Deficiency Anemia', + 'Irritable Bowel Syndrome', + 'Kidney Cancer', + 'Kidney Stones', + 'Laryngitis', + 'Leukemia', + 'Leukopenia', + 'Lung Cancer', + 'Lupus', + 'Lyme Disease', + 'Lymphoma', + 'Macular Degeneration', + 'Melanoma', + "Meniere's Disease", + 'Migraine', + 'Multiple Sclerosis', + 'Myeloma', + 'Myocardial Infarction', + 'Narcolepsy', + 'Nephrotic Syndrome', + 'Nonalcoholic Fatty Liver Disease', + 'Obesity', + 'Osteoarthritis', + 'Osteoporosis', + 'Otitis Externa', + 'Otitis Media', + 'Ovarian Cancer', + 'Overactive Bladder', + 'Pancreatic Cancer', + 'Pancreatitis', + "Parkinson's Disease", + 'Peptic Ulcer Disease', + 'Pericarditis', + 'Peripheral Artery Disease', + 'Peripheral Neuropathy', + 'Pernicious Anemia', + 'Pharyngitis', + 'Pleural Effusion', + 'Pneumonia', + 'Pneumothorax', + 'Polycystic Kidney Disease', + 'Polycystic Ovary Syndrome', + 'Post-Traumatic Stress Disorder', + 'Preeclampsia', + 'Prostate Cancer', + 'Psoriasis', + 'Pulmonary Embolism', + 'Pulmonary Hypertension', + 'Pyelonephritis', + 'Restless Leg Syndrome', + 'Rheumatoid Arthritis', + 'Rosacea', + 'Sarcoidosis', + 'Schizophrenia', + 'Scleroderma', + 'Seizure Disorder', + 'Sepsis', + 'Shingles', + 'Sickle Cell Disease', + "Sj\u00F6gren's Syndrome", + 'Sleep Apnea', + 'Squamous Cell Carcinoma', + 'Stress Incontinence', + 'Stroke', + 'Substance Use Disorder', + 'Thrombocytopenia', + 'Thyroid Cancer', + 'Tonsillitis', + 'Tuberculosis', + 'Type 1 Diabetes', + 'Type 2 Diabetes', + 'Ulcerative Colitis', + 'Urge Incontinence', + 'Urinary Tract Infection', + 'Uterine Fibroids', + 'Valvular Heart Disease', + 'Viral Gastroenteritis', + 'Vitamin D Deficiency', +]; diff --git a/src/locales/en/medical/department.ts b/src/locales/en/medical/department.ts new file mode 100644 index 00000000000..93b8f618994 --- /dev/null +++ b/src/locales/en/medical/department.ts @@ -0,0 +1,32 @@ +export default [ + 'Burn Unit', + 'Cardiac Care Unit (CCU)', + 'Cardiology Unit', + 'Dialysis Unit', + 'Emergency Department', + 'Endoscopy Suite', + 'Infusion Center', + 'Inpatient Ward', + 'Intensive Care Unit (ICU)', + 'Labor and Delivery', + 'Laboratory', + 'Maternity Ward', + 'Medical Observation Unit', + 'Neonatal Intensive Care Unit (NICU)', + 'Neurology Unit', + 'Occupational Therapy', + 'Oncology', + 'Operating Room', + 'Outpatient Clinic', + 'Pediatrics', + 'Pharmacy', + 'Physical Therapy', + 'Post-Anesthesia Care Unit (PACU)', + 'Psychiatric Ward', + 'Radiology', + 'Rehabilitation Unit', + 'Respiratory Therapy', + 'Sleep Lab', + 'Surgery', + 'Wound Care Center', +]; diff --git a/src/locales/en/medical/drug_forbidden_ending.ts b/src/locales/en/medical/drug_forbidden_ending.ts new file mode 100644 index 00000000000..c68c46b54c3 --- /dev/null +++ b/src/locales/en/medical/drug_forbidden_ending.ts @@ -0,0 +1,18 @@ +export default [ + 'caine', + 'cillin', + 'dipine', + 'floxacin', + 'gliptin', + 'mab', + 'mycin', + 'nib', + 'olol', + 'parin', + 'prazole', + 'pril', + 'profen', + 'sartan', + 'statin', + 'vir', +]; diff --git a/src/locales/en/medical/drug_infix.ts b/src/locales/en/medical/drug_infix.ts new file mode 100644 index 00000000000..2328e8ea1a7 --- /dev/null +++ b/src/locales/en/medical/drug_infix.ts @@ -0,0 +1,22 @@ +export default [ + 'be', + 'co', + 'di', + 'du', + 'ga', + 'lo', + 'ly', + 'mi', + 'na', + 'no', + 'pra', + 'ra', + 'ri', + 'se', + 'sy', + 'ta', + 'va', + 'vi', + 'xa', + 'ze', +]; diff --git a/src/locales/en/medical/drug_prefix.ts b/src/locales/en/medical/drug_prefix.ts new file mode 100644 index 00000000000..908bd94ad06 --- /dev/null +++ b/src/locales/en/medical/drug_prefix.ts @@ -0,0 +1,52 @@ +export default [ + 'Adva', + 'Alda', + 'Andel', + 'Brix', + 'Cael', + 'Cavi', + 'Cetra', + 'Corva', + 'Elix', + 'Fenda', + 'Grava', + 'Hylo', + 'Ixen', + 'Juvi', + 'Kesa', + 'Klar', + 'Lume', + 'Lyra', + 'Miza', + 'Morva', + 'Neuvo', + 'Nexa', + 'Nuvi', + 'Ombra', + 'Orba', + 'Oxa', + 'Praxa', + 'Pyra', + 'Quen', + 'Quila', + 'Ravi', + 'Reva', + 'Rexa', + 'Roven', + 'Soli', + 'Solva', + 'Sona', + 'Tavo', + 'Trova', + 'Uvel', + 'Valo', + 'Venda', + 'Vyra', + 'Wraxa', + 'Xely', + 'Ynova', + 'Zenta', + 'Zeva', + 'Ziva', + 'Zol', +]; diff --git a/src/locales/en/medical/drug_suffix.ts b/src/locales/en/medical/drug_suffix.ts new file mode 100644 index 00000000000..c60dc8647f9 --- /dev/null +++ b/src/locales/en/medical/drug_suffix.ts @@ -0,0 +1,32 @@ +export default [ + 'cor', + 'dara', + 'dex', + 'don', + 'dyn', + 'en', + 'ex', + 'fen', + 'gis', + 'in', + 'lor', + 'mira', + 'mox', + 'nix', + 'ol', + 'pex', + 'pral', + 'quel', + 'ric', + 'sen', + 'tiva', + 'tor', + 'vane', + 'via', + 'vor', + 'vue', + 'xen', + 'yl', + 'zen', + 'zia', +]; diff --git a/src/locales/en/medical/index.ts b/src/locales/en/medical/index.ts new file mode 100644 index 00000000000..9d94a62d59d --- /dev/null +++ b/src/locales/en/medical/index.ts @@ -0,0 +1,31 @@ +/* + * This file is automatically generated. + * Run 'pnpm run generate:locales' to update. + */ +import allergen from './allergen'; +import blood_type from './blood_type'; +import condition from './condition'; +import department from './department'; +import drug_forbidden_ending from './drug_forbidden_ending'; +import drug_infix from './drug_infix'; +import drug_prefix from './drug_prefix'; +import drug_suffix from './drug_suffix'; +import procedure from './procedure'; +import specialty from './specialty'; +import symptom from './symptom'; + +const medical = { + allergen, + blood_type, + condition, + department, + drug_forbidden_ending, + drug_infix, + drug_prefix, + drug_suffix, + procedure, + specialty, + symptom, +}; + +export default medical; diff --git a/src/locales/en/medical/procedure.ts b/src/locales/en/medical/procedure.ts new file mode 100644 index 00000000000..90f6dbb8fb7 --- /dev/null +++ b/src/locales/en/medical/procedure.ts @@ -0,0 +1,107 @@ +export default [ + 'Ablation', + 'Adenoidectomy', + 'Adrenalectomy', + 'Angioplasty', + 'Appendectomy', + 'Biopsy', + 'Blood Test', + 'Bone Marrow Biopsy', + 'Bone Marrow Transplant', + 'Botox Injection', + 'Bronchoscopy', + 'C-Section', + 'CAR T-Cell Therapy', + 'CT Scan', + 'Cardiac Catheterization', + 'Cataract Surgery', + 'Chemical Peel', + 'Chemotherapy', + 'Cholecystectomy', + 'Cochlear Implant', + 'Colectomy', + 'Colonoscopy', + 'Colostomy', + 'Corneal Transplant', + 'Coronary Artery Bypass Graft', + 'Cryotherapy', + 'Defibrillator Implantation', + 'Dermabrasion', + 'Dialysis', + 'Echocardiogram', + 'Electrocardiogram (ECG)', + 'Electrocautery', + 'Endoscopy', + 'Epidural Injection', + 'Excision', + 'Filler Injection', + 'Flap Surgery', + 'Gallbladder Removal', + 'Gastrectomy', + 'Glaucoma Surgery', + 'Heart Transplant', + 'Hemodialysis', + 'Hernia Repair', + 'Hip Replacement', + 'Hormone Therapy', + 'Hysterectomy', + 'IVIG Infusion', + 'Ileostomy', + 'Immunotherapy', + 'Incision and Drainage', + 'Joint Aspiration', + 'Joint Injection', + 'Kidney Biopsy', + 'Kidney Transplant', + 'Knee Replacement', + 'LASIK Surgery', + 'Laser Hair Removal', + 'Liver Biopsy', + 'Liver Resection', + 'Liver Transplant', + 'Lumbar Puncture', + 'Lumpectomy', + 'Lung Transplant', + 'Lymph Node Biopsy', + 'MRI Scan', + 'Mastectomy', + 'Microdermabrasion', + 'Mole Removal', + 'Nephrectomy', + 'Nerve Block', + 'Pacemaker Insertion', + 'Pancreas Transplant', + 'Pancreatectomy', + 'Paracentesis', + 'Parathyroidectomy', + 'Peritoneal Dialysis', + 'Physical Therapy Session', + 'Plasmapheresis', + 'Prostatectomy', + 'Radiation Therapy', + 'Retinal Detachment Repair', + 'Rhinoplasty', + 'Septoplasty', + 'Sinus Surgery', + 'Skin Biopsy', + 'Skin Graft', + 'Skin Tag Removal', + 'Splenectomy', + 'Stapedectomy', + 'Stapling', + 'Stem Cell Transplant', + 'Suturing', + 'Targeted Therapy', + 'Thoracentesis', + 'Thyroidectomy', + 'Tonsillectomy', + 'Trigger Point Injection', + 'Tympanoplasty', + 'Ultrasound', + 'Vaccination', + 'Vitrectomy', + 'Wart Removal', + 'Whipple Procedure', + 'Wound Debridement', + 'X-Ray', +]; diff --git a/src/locales/en/medical/specialty.ts b/src/locales/en/medical/specialty.ts new file mode 100644 index 00000000000..164a3678a3c --- /dev/null +++ b/src/locales/en/medical/specialty.ts @@ -0,0 +1,28 @@ +export default [ + 'Allergy', + 'Cardiology', + 'Critical Care', + 'Dermatology', + 'Endocrinology', + 'Gastroenterology', + 'General Surgery', + 'Gynecology', + 'Hematology', + 'Infectious Disease', + 'Internal Medicine', + 'Nephrology', + 'Neurology', + 'Obstetrics', + 'Oncology', + 'Ophthalmology', + 'Orthopedics', + 'Otolaryngology', + 'Pain Medicine', + 'Pediatrics', + 'Psychiatry', + 'Pulmonology', + 'Rheumatology', + 'Urology', + 'Vascular Medicine', + 'Vascular Surgery', +]; diff --git a/src/locales/en/medical/symptom.ts b/src/locales/en/medical/symptom.ts new file mode 100644 index 00000000000..07f696960d8 --- /dev/null +++ b/src/locales/en/medical/symptom.ts @@ -0,0 +1,291 @@ +export default [ + 'Abdominal Bloating', + 'Abdominal Pain', + 'Abdominal Swelling', + 'Abnormal Vaginal Bleeding', + 'Acne', + 'Anemia', + 'Anxiety', + 'Asymmetrical Shape', + 'Avoidance Behaviors', + 'Back Pain', + 'Balance Issues', + 'Barking Cough', + 'Blackheads', + 'Bladder Pain', + 'Bladder Spasms', + 'Bleeding', + 'Bleeding Gums', + 'Bloating', + 'Blood in Stool', + 'Blood in Urine', + 'Bloody Diarrhea', + 'Blurred Vision', + 'Bone Loss', + 'Bone Pain', + 'Bradykinesia', + 'Breast Lump', + 'Bruising', + 'Burning Sensation', + 'Cataplexy', + 'Central Vision Loss', + 'Change in Bowel Habits', + 'Changing Mole', + 'Chest Discomfort', + 'Chest Pain', + 'Chronic Cough', + 'Cloudy Urine', + 'Cognitive Changes', + 'Cognitive Difficulties', + 'Cognitive Impairment', + 'Cold Extremities', + 'Cold Hands', + 'Color Changes', + 'Color Fading', + 'Color Variation', + 'Communication Difficulties', + 'Confusion', + 'Congestion', + 'Constipation', + 'Convulsions', + 'Cough', + 'Coughing Blood', + 'Cramping', + 'Cravings', + 'Crusted Surface', + 'Cyanosis', + 'Cysts', + 'Dark Areas', + 'Dark Spots', + 'Daytime Sleepiness', + 'Decreased Breath Sounds', + 'Decreased Urine Output', + 'Delusions', + 'Depression', + 'Diameter Increase', + 'Diarrhea', + 'Difficulty Breathing', + 'Difficulty Hearing', + 'Difficulty Speaking', + 'Difficulty Swallowing', + 'Discharge', + 'Discomfort', + 'Disorganization', + 'Disorganized Thinking', + 'Distorted Vision', + 'Dizziness', + 'Double Vision', + 'Dry Cough', + 'Dry Eyes', + 'Dry Mouth', + 'Dry Skin', + 'Dysmenorrhea', + 'Ear Fullness', + 'Ear Pain', + 'Easy Bruising', + 'Edema', + 'Excess Hair Growth', + 'Excessive Daytime Sleepiness', + 'Exercise', + 'Extreme Hunger', + 'Eye Irritation', + 'Eye Pain', + 'Facial Pain', + 'Facial Pressure', + 'Facial Redness', + 'Fading Colors', + 'Fatigue', + 'Fever', + 'Flank Pain', + 'Flashbacks', + 'Floaters', + 'Fluid Drainage', + 'Forgetfulness', + 'Fragmented Sleep', + 'Frequency', + 'Frequent Infections', + 'Frequent Urination', + 'Gas', + 'Gastrointestinal Issues', + 'Glare Sensitivity', + 'Growth with Central Depression', + 'Hair Loss', + 'Hallucinations', + 'Halos Around Lights', + 'Headache', + 'Headaches', + 'Hearing Loss', + 'Heart Murmurs', + 'Heartburn', + 'Heat Intolerance', + 'Heavy Menstrual Bleeding', + 'Heavy Periods', + 'Hemarthrosis', + 'Hematuria', + 'Hemoptysis', + 'High Blood Pressure', + 'Hoarseness', + 'Hyperactivity', + 'Hyperlipidemia', + 'Hypertension', + 'Hypervigilance', + 'Hypoalbuminemia', + 'Hypotension', + 'Impulsivity', + 'Inability to Maintain Erection', + 'Inattention', + 'Incomplete Emptying', + 'Incontinence', + 'Increased Appetite', + 'Increased Thirst', + 'Infertility', + 'Insomnia', + 'Involuntary Bowel Movements', + 'Involuntary Leakage', + 'Irregular Borders', + 'Irregular Heartbeat', + 'Irregular Periods', + 'Irritability', + 'Itching', + 'Itchy Eyes', + 'Jaundice', + 'Joint Pain', + 'Kidney Problems', + 'Laughing', + 'Leakage', + 'Leg Pain', + 'Lifting', + 'Light Sensitivity', + 'Lightheadedness', + 'Limited Mobility', + 'Loss of Appetite', + 'Loss of Consciousness', + 'Loss of Control', + 'Loss of Smell', + 'Loss of Taste', + 'Low Blood Pressure', + 'Mania', + 'Memory Loss', + 'Mood Swings', + 'Morning Headaches', + 'Mouth Ulcers', + 'Muffled Sounds', + 'Muscle Aches', + 'Muscle Weakness', + 'Nasal Congestion', + 'Nausea', + 'Neck Lump', + 'Neck Pain', + 'Negative Symptoms', + 'Neglect of Responsibilities', + 'Night Sweats', + 'Nightmares', + 'Nipple Discharge', + 'Nocturia', + 'Nosebleeds', + 'Numbness', + 'Open Sore', + 'Pain', + 'Pain Crises', + 'Pain During Bowel Movements', + 'Painful Intercourse', + 'Painful Urination', + 'Pale Skin', + 'Palpitations', + 'Pearly Bump', + 'Pelvic Pain', + 'Persistent Cough', + 'Persistent Pain', + 'Petechiae', + 'Photosensitivity', + 'Pimples', + 'Poor Growth', + 'Poor Night Vision', + 'Postnasal Drip', + 'Postural Instability', + 'Premature Ejaculation', + 'Prolonged Bleeding', + 'Proteinuria', + 'Pulsatile Mass', + 'Rapid Heart Rate', + 'Rapid Heartbeat', + 'Rapid Pulse', + 'Rash', + "Raynaud's Phenomenon", + 'Rectal Bleeding', + 'Recurrent Infections', + 'Red Eyes', + 'Red Patch', + 'Red Patches', + 'Redness', + 'Reduced Libido', + 'Reduced Mobility', + 'Regurgitation', + 'Relief with Movement', + 'Repetitive Behaviors', + 'Respiratory Distress', + 'Restricted Interests', + 'Rigidity', + 'Rough Red Patch', + 'Runny Nose', + 'Salty Skin', + 'Scaling', + 'Scar-Like Area', + 'Scarring', + 'Seizures', + 'Sensory Sensitivities', + 'Severe Anxiety', + 'Severe Pain', + 'Shortness of Breath', + 'Skin Rash', + 'Skin Thickening', + 'Sleep Disturbance', + 'Sleep Disturbances', + 'Sleep Paralysis', + 'Sneezing', + 'Snoring', + 'Social Impairment', + "Sore That Doesn't Heal", + 'Sore Throat', + 'Spasms', + 'Speech Changes', + 'Staring Spells', + 'Stress', + 'Stridor', + 'Sudden Urge to Urinate', + 'Sweating', + 'Swelling', + 'Swelling in Legs', + 'Swollen Lymph Nodes', + 'Swollen Salivary Glands', + 'Swollen Tonsils', + 'Syncope', + 'Thickened Skin', + 'Tingling', + 'Tinnitus', + 'Tolerance', + 'Tophi', + 'Tremor', + 'Uncomfortable Sensations', + 'Uncontrolled Movements', + 'Unexplained Weight Loss', + 'Urge to Move Legs', + 'Urgency', + 'Urine Leakage with Coughing', + 'Vertigo', + 'Visible Blood Vessels', + 'Vision Changes', + 'Vision Loss', + 'Vision Problems', + 'Vomiting', + 'Warmth', + 'Weak Stream', + 'Weakness', + 'Weight Gain', + 'Weight Loss', + 'Wheezing', + 'Whiteheads', + 'Widespread Pain', + 'Withdrawal Symptoms', + 'Worsening at Night', +]; diff --git a/src/modules/medical/index.ts b/src/modules/medical/index.ts new file mode 100644 index 00000000000..20a96c9a596 --- /dev/null +++ b/src/modules/medical/index.ts @@ -0,0 +1 @@ +export * from './module'; diff --git a/src/modules/medical/module.ts b/src/modules/medical/module.ts new file mode 100644 index 00000000000..7b57c28d70f --- /dev/null +++ b/src/modules/medical/module.ts @@ -0,0 +1,161 @@ +import { ModuleBase } from '../../internal/module-base'; + +/** + * Module to generate plausible medical and healthcare related entries. + * + * ### Overview + * + * Generate plausible, non-clinical healthcare data for tests, demos, and + * fixtures: a medical [`specialty()`](https://fakerjs.dev/api/medical.html#specialty), + * a hospital [`department()`](https://fakerjs.dev/api/medical.html#department), + * a [`condition()`](https://fakerjs.dev/api/medical.html#condition), + * a [`symptom()`](https://fakerjs.dev/api/medical.html#symptom), + * a [`procedure()`](https://fakerjs.dev/api/medical.html#procedure), + * an [`allergen()`](https://fakerjs.dev/api/medical.html#allergen), + * a [`bloodType()`](https://fakerjs.dev/api/medical.html#bloodtype), + * and a fictitious [`drugName()`](https://fakerjs.dev/api/medical.html#drugname). + * + * All values are intentionally generic or invented. Real diagnosis codes (e.g. + * ICD-10), real medicine names, and correlated patient records are deliberately + * out of scope — this data must never be used for clinical purposes. + */ +export class MedicalModule extends ModuleBase { + /** + * Returns a random medical specialty. + * + * @example + * faker.medical.specialty() // 'Cardiology' + * + * @since 10.6.0 + */ + specialty(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.specialty + ); + } + + /** + * Returns a random hospital department. + * + * @example + * faker.medical.department() // 'Emergency Department' + * + * @since 10.6.0 + */ + department(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.department + ); + } + + /** + * Returns a random, plausible medical condition name (without any diagnosis code). + * + * @example + * faker.medical.condition() // 'Type 2 Diabetes' + * + * @since 10.6.0 + */ + condition(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.condition + ); + } + + /** + * Returns a random symptom. + * + * @example + * faker.medical.symptom() // 'Shortness of Breath' + * + * @since 10.6.0 + */ + symptom(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.symptom + ); + } + + /** + * Returns a random medical procedure. + * + * @example + * faker.medical.procedure() // 'Appendectomy' + * + * @since 10.6.0 + */ + procedure(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.procedure + ); + } + + /** + * Returns a random allergen. + * + * @example + * faker.medical.allergen() // 'Penicillin' + * + * @since 10.6.0 + */ + allergen(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.allergen + ); + } + + /** + * Returns a random blood type. + * + * @example + * faker.medical.bloodType() // 'O+' + * + * @since 10.6.0 + */ + bloodType(): string { + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.blood_type + ); + } + + /** + * Returns a fictitious, brand-style drug name. + * + * The name is assembled from invented morphemes and deliberately avoids real + * WHO INN stems (e.g. `-statin`, `-pril`), so it never resolves to a real + * medicine or brand and cannot be mistaken for one. + * + * @example + * faker.medical.drugName() // 'Zolpraxen' + * + * @since 10.6.0 + */ + drugName(): string { + const { + drug_prefix: prefixes, + drug_infix: infixes, + drug_suffix: suffixes, + drug_forbidden_ending: forbiddenEndings, + } = this.faker.definitions.medical; + + let name = ''; + // Retry a few times so a name that happens to end in a real INN stem is + // rerolled rather than returned. + for (let attempt = 0; attempt < 12; attempt++) { + const parts = [this.faker.helpers.arrayElement(prefixes)]; + if (this.faker.datatype.boolean(0.4)) { + parts.push(this.faker.helpers.arrayElement(infixes)); + } + + parts.push(this.faker.helpers.arrayElement(suffixes)); + name = parts.join(''); + + const lower = name.toLowerCase(); + if (forbiddenEndings.every((ending) => !lower.endsWith(ending))) { + break; + } + } + + return name; + } +} diff --git a/test/modules/__snapshots__/medical.spec.ts.snap b/test/modules/__snapshots__/medical.spec.ts.snap new file mode 100644 index 00000000000..b905fd995d7 --- /dev/null +++ b/test/modules/__snapshots__/medical.spec.ts.snap @@ -0,0 +1,49 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`medical > 42 > allergen 1`] = `"Gluten"`; + +exports[`medical > 42 > bloodType 1`] = `"AB+"`; + +exports[`medical > 42 > condition 1`] = `"Fibromyalgia"`; + +exports[`medical > 42 > department 1`] = `"Maternity Ward"`; + +exports[`medical > 42 > drugName 1`] = `"Mizator"`; + +exports[`medical > 42 > procedure 1`] = `"Glaucoma Surgery"`; + +exports[`medical > 42 > specialty 1`] = `"Infectious Disease"`; + +exports[`medical > 42 > symptom 1`] = `"Glare Sensitivity"`; + +exports[`medical > 1211 > allergen 1`] = `"Sulfites"`; + +exports[`medical > 1211 > bloodType 1`] = `"O-"`; + +exports[`medical > 1211 > condition 1`] = `"Thyroid Cancer"`; + +exports[`medical > 1211 > department 1`] = `"Sleep Lab"`; + +exports[`medical > 1211 > drugName 1`] = `"Zentaex"`; + +exports[`medical > 1211 > procedure 1`] = `"Tympanoplasty"`; + +exports[`medical > 1211 > specialty 1`] = `"Vascular Medicine"`; + +exports[`medical > 1211 > symptom 1`] = `"Uncontrolled Movements"`; + +exports[`medical > 1337 > allergen 1`] = `"Eggs"`; + +exports[`medical > 1337 > bloodType 1`] = `"AB+"`; + +exports[`medical > 1337 > condition 1`] = `"Crohn's Disease"`; + +exports[`medical > 1337 > department 1`] = `"Inpatient Ward"`; + +exports[`medical > 1337 > drugName 1`] = `"Juvilonix"`; + +exports[`medical > 1337 > procedure 1`] = `"Dermabrasion"`; + +exports[`medical > 1337 > specialty 1`] = `"General Surgery"`; + +exports[`medical > 1337 > symptom 1`] = `"Double Vision"`; diff --git a/test/modules/medical.spec.ts b/test/modules/medical.spec.ts new file mode 100644 index 00000000000..d1a813a3782 --- /dev/null +++ b/test/modules/medical.spec.ts @@ -0,0 +1,92 @@ +import { describe, expect, it } from 'vitest'; +import { faker } from '../../src'; +import { seededTests } from '../support/seeded-runs'; +import { times } from '../support/times'; + +const NON_SEEDED_BASED_RUN = 5; + +describe('medical', () => { + seededTests(faker, 'medical', (t) => { + t.itEach( + 'specialty', + 'department', + 'condition', + 'symptom', + 'procedure', + 'allergen', + 'bloodType', + 'drugName' + ); + }); + + describe.each(times(NON_SEEDED_BASED_RUN).map(() => faker.seed()))( + 'random seeded tests for seed %i', + () => { + describe('specialty()', () => { + it('should return a random value from the specialty array', () => { + const actual = faker.medical.specialty(); + expect(faker.definitions.medical.specialty).toContain(actual); + }); + }); + + describe('department()', () => { + it('should return a random value from the department array', () => { + const actual = faker.medical.department(); + expect(faker.definitions.medical.department).toContain(actual); + }); + }); + + describe('condition()', () => { + it('should return a random value from the condition array', () => { + const actual = faker.medical.condition(); + expect(faker.definitions.medical.condition).toContain(actual); + }); + }); + + describe('symptom()', () => { + it('should return a random value from the symptom array', () => { + const actual = faker.medical.symptom(); + expect(faker.definitions.medical.symptom).toContain(actual); + }); + }); + + describe('procedure()', () => { + it('should return a random value from the procedure array', () => { + const actual = faker.medical.procedure(); + expect(faker.definitions.medical.procedure).toContain(actual); + }); + }); + + describe('allergen()', () => { + it('should return a random value from the allergen array', () => { + const actual = faker.medical.allergen(); + expect(faker.definitions.medical.allergen).toContain(actual); + }); + }); + + describe('bloodType()', () => { + it('should return a random value from the blood type array', () => { + const actual = faker.medical.bloodType(); + expect(faker.definitions.medical.blood_type).toContain(actual); + }); + }); + + describe('drugName()', () => { + it('should return a non-empty fictitious drug name', () => { + const actual = faker.medical.drugName(); + expect(actual).toBeTypeOf('string'); + expect(actual.length).toBeGreaterThan(0); + expect(actual).toMatch(/^[A-Za-z]+$/); + }); + + it('should not end with a real INN stem', () => { + const lower = faker.medical.drugName().toLowerCase(); + for (const ending of faker.definitions.medical + .drug_forbidden_ending) { + expect(lower.endsWith(ending)).toBe(false); + } + }); + }); + } + ); +}); diff --git a/test/scripts/apidocs/__snapshots__/verify-jsdoc-tags.spec.ts.snap b/test/scripts/apidocs/__snapshots__/verify-jsdoc-tags.spec.ts.snap index 079999de55c..715e4b6b422 100644 --- a/test/scripts/apidocs/__snapshots__/verify-jsdoc-tags.spec.ts.snap +++ b/test/scripts/apidocs/__snapshots__/verify-jsdoc-tags.spec.ts.snap @@ -323,6 +323,19 @@ exports[`check docs completeness > all modules and methods are present 1`] = ` "words", ], ], + [ + "medical", + [ + "allergen", + "bloodType", + "condition", + "department", + "drugName", + "procedure", + "specialty", + "symptom", + ], + ], [ "music", [ From afba7851c0808510f52849efe6495e210f590367 Mon Sep 17 00:00:00 2001 From: rodrigobnogueira Date: Sun, 12 Jul 2026 01:24:16 -0300 Subject: [PATCH 2/3] chore(medical): commit generated files and tighten en locale data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add generated docs/.vitepress/api-pages.ts and regenerate the typed en/medical locale index (fixes the Check Code Generation job) - symptom: drop non-symptom trigger/modifier entries (Exercise, Laughing, Lifting, Relief with Movement, Worsening at Night, Tolerance), exact plural duplicates (Headaches, Red Patches, Sleep Disturbances), and entries duplicating the condition list (Anemia, Hyperlipidemia); clarify Frequency/Urgency as Urinary Frequency/Urinary Urgency - specialty: use Allergy and Immunology; add Anesthesiology, Emergency Medicine, Family Medicine, Neurosurgery, Pathology, Plastic Surgery, Radiology - procedure: replace the trademarked Botox Injection with Botulinum Toxin Injection - condition: use a literal ö in Sjögren's Syndrome - drug morphemes: swap pex/zia/se/ga for plex/vex/so/go so no generated name can contain an unfortunate substring; the full 31,500-name space is verified free of real brand names and WHO INN generics --- docs/.vitepress/api-pages.ts | 1 + src/locales/en/medical/condition.ts | 2 +- src/locales/en/medical/drug_infix.ts | 4 ++-- src/locales/en/medical/drug_suffix.ts | 4 ++-- src/locales/en/medical/index.ts | 3 ++- src/locales/en/medical/procedure.ts | 2 +- src/locales/en/medical/specialty.ts | 9 ++++++++- src/locales/en/medical/symptom.ts | 15 ++------------- test/modules/__snapshots__/medical.spec.ts.snap | 10 +++++----- 9 files changed, 24 insertions(+), 26 deletions(-) diff --git a/docs/.vitepress/api-pages.ts b/docs/.vitepress/api-pages.ts index fcea7f72b39..6abc411ae07 100644 --- a/docs/.vitepress/api-pages.ts +++ b/docs/.vitepress/api-pages.ts @@ -28,6 +28,7 @@ export const apiPages = [ { text: 'Internet', link: '/api/internet.html' }, { text: 'Location', link: '/api/location.html' }, { text: 'Lorem', link: '/api/lorem.html' }, + { text: 'Medical', link: '/api/medical.html' }, { text: 'Music', link: '/api/music.html' }, { text: 'Number', link: '/api/number.html' }, { text: 'Person', link: '/api/person.html' }, diff --git a/src/locales/en/medical/condition.ts b/src/locales/en/medical/condition.ts index e6925b2bade..420c0e98315 100644 --- a/src/locales/en/medical/condition.ts +++ b/src/locales/en/medical/condition.ts @@ -138,7 +138,7 @@ export default [ 'Sepsis', 'Shingles', 'Sickle Cell Disease', - "Sj\u00F6gren's Syndrome", + "Sjögren's Syndrome", 'Sleep Apnea', 'Squamous Cell Carcinoma', 'Stress Incontinence', diff --git a/src/locales/en/medical/drug_infix.ts b/src/locales/en/medical/drug_infix.ts index 2328e8ea1a7..dd37923e0fc 100644 --- a/src/locales/en/medical/drug_infix.ts +++ b/src/locales/en/medical/drug_infix.ts @@ -3,7 +3,7 @@ export default [ 'co', 'di', 'du', - 'ga', + 'go', 'lo', 'ly', 'mi', @@ -12,7 +12,7 @@ export default [ 'pra', 'ra', 'ri', - 'se', + 'so', 'sy', 'ta', 'va', diff --git a/src/locales/en/medical/drug_suffix.ts b/src/locales/en/medical/drug_suffix.ts index c60dc8647f9..2403d619861 100644 --- a/src/locales/en/medical/drug_suffix.ts +++ b/src/locales/en/medical/drug_suffix.ts @@ -14,7 +14,7 @@ export default [ 'mox', 'nix', 'ol', - 'pex', + 'plex', 'pral', 'quel', 'ric', @@ -22,11 +22,11 @@ export default [ 'tiva', 'tor', 'vane', + 'vex', 'via', 'vor', 'vue', 'xen', 'yl', 'zen', - 'zia', ]; diff --git a/src/locales/en/medical/index.ts b/src/locales/en/medical/index.ts index 9d94a62d59d..021c943c31a 100644 --- a/src/locales/en/medical/index.ts +++ b/src/locales/en/medical/index.ts @@ -2,6 +2,7 @@ * This file is automatically generated. * Run 'pnpm run generate:locales' to update. */ +import type { MedicalDefinition } from '../../../definitions'; import allergen from './allergen'; import blood_type from './blood_type'; import condition from './condition'; @@ -14,7 +15,7 @@ import procedure from './procedure'; import specialty from './specialty'; import symptom from './symptom'; -const medical = { +const medical: MedicalDefinition = { allergen, blood_type, condition, diff --git a/src/locales/en/medical/procedure.ts b/src/locales/en/medical/procedure.ts index 90f6dbb8fb7..bc2736c8b2e 100644 --- a/src/locales/en/medical/procedure.ts +++ b/src/locales/en/medical/procedure.ts @@ -8,7 +8,7 @@ export default [ 'Blood Test', 'Bone Marrow Biopsy', 'Bone Marrow Transplant', - 'Botox Injection', + 'Botulinum Toxin Injection', 'Bronchoscopy', 'C-Section', 'CAR T-Cell Therapy', diff --git a/src/locales/en/medical/specialty.ts b/src/locales/en/medical/specialty.ts index 164a3678a3c..fc282e754cc 100644 --- a/src/locales/en/medical/specialty.ts +++ b/src/locales/en/medical/specialty.ts @@ -1,9 +1,12 @@ export default [ - 'Allergy', + 'Allergy and Immunology', + 'Anesthesiology', 'Cardiology', 'Critical Care', 'Dermatology', + 'Emergency Medicine', 'Endocrinology', + 'Family Medicine', 'Gastroenterology', 'General Surgery', 'Gynecology', @@ -12,15 +15,19 @@ export default [ 'Internal Medicine', 'Nephrology', 'Neurology', + 'Neurosurgery', 'Obstetrics', 'Oncology', 'Ophthalmology', 'Orthopedics', 'Otolaryngology', 'Pain Medicine', + 'Pathology', 'Pediatrics', + 'Plastic Surgery', 'Psychiatry', 'Pulmonology', + 'Radiology', 'Rheumatology', 'Urology', 'Vascular Medicine', diff --git a/src/locales/en/medical/symptom.ts b/src/locales/en/medical/symptom.ts index 07f696960d8..a4128c1dcbb 100644 --- a/src/locales/en/medical/symptom.ts +++ b/src/locales/en/medical/symptom.ts @@ -4,7 +4,6 @@ export default [ 'Abdominal Swelling', 'Abnormal Vaginal Bleeding', 'Acne', - 'Anemia', 'Anxiety', 'Asymmetrical Shape', 'Avoidance Behaviors', @@ -86,7 +85,6 @@ export default [ 'Edema', 'Excess Hair Growth', 'Excessive Daytime Sleepiness', - 'Exercise', 'Extreme Hunger', 'Eye Irritation', 'Eye Pain', @@ -102,7 +100,6 @@ export default [ 'Fluid Drainage', 'Forgetfulness', 'Fragmented Sleep', - 'Frequency', 'Frequent Infections', 'Frequent Urination', 'Gas', @@ -113,7 +110,6 @@ export default [ 'Hallucinations', 'Halos Around Lights', 'Headache', - 'Headaches', 'Hearing Loss', 'Heart Murmurs', 'Heartburn', @@ -126,7 +122,6 @@ export default [ 'High Blood Pressure', 'Hoarseness', 'Hyperactivity', - 'Hyperlipidemia', 'Hypertension', 'Hypervigilance', 'Hypoalbuminemia', @@ -151,10 +146,8 @@ export default [ 'Jaundice', 'Joint Pain', 'Kidney Problems', - 'Laughing', 'Leakage', 'Leg Pain', - 'Lifting', 'Light Sensitivity', 'Lightheadedness', 'Limited Mobility', @@ -216,12 +209,10 @@ export default [ 'Recurrent Infections', 'Red Eyes', 'Red Patch', - 'Red Patches', 'Redness', 'Reduced Libido', 'Reduced Mobility', 'Regurgitation', - 'Relief with Movement', 'Repetitive Behaviors', 'Respiratory Distress', 'Restricted Interests', @@ -240,7 +231,6 @@ export default [ 'Skin Rash', 'Skin Thickening', 'Sleep Disturbance', - 'Sleep Disturbances', 'Sleep Paralysis', 'Sneezing', 'Snoring', @@ -263,14 +253,14 @@ export default [ 'Thickened Skin', 'Tingling', 'Tinnitus', - 'Tolerance', 'Tophi', 'Tremor', 'Uncomfortable Sensations', 'Uncontrolled Movements', 'Unexplained Weight Loss', 'Urge to Move Legs', - 'Urgency', + 'Urinary Frequency', + 'Urinary Urgency', 'Urine Leakage with Coughing', 'Vertigo', 'Visible Blood Vessels', @@ -287,5 +277,4 @@ export default [ 'Whiteheads', 'Widespread Pain', 'Withdrawal Symptoms', - 'Worsening at Night', ]; diff --git a/test/modules/__snapshots__/medical.spec.ts.snap b/test/modules/__snapshots__/medical.spec.ts.snap index b905fd995d7..fd00db37b59 100644 --- a/test/modules/__snapshots__/medical.spec.ts.snap +++ b/test/modules/__snapshots__/medical.spec.ts.snap @@ -14,7 +14,7 @@ exports[`medical > 42 > procedure 1`] = `"Glaucoma Surgery"`; exports[`medical > 42 > specialty 1`] = `"Infectious Disease"`; -exports[`medical > 42 > symptom 1`] = `"Glare Sensitivity"`; +exports[`medical > 42 > symptom 1`] = `"Gastrointestinal Issues"`; exports[`medical > 1211 > allergen 1`] = `"Sulfites"`; @@ -28,9 +28,9 @@ exports[`medical > 1211 > drugName 1`] = `"Zentaex"`; exports[`medical > 1211 > procedure 1`] = `"Tympanoplasty"`; -exports[`medical > 1211 > specialty 1`] = `"Vascular Medicine"`; +exports[`medical > 1211 > specialty 1`] = `"Urology"`; -exports[`medical > 1211 > symptom 1`] = `"Uncontrolled Movements"`; +exports[`medical > 1211 > symptom 1`] = `"Unexplained Weight Loss"`; exports[`medical > 1337 > allergen 1`] = `"Eggs"`; @@ -44,6 +44,6 @@ exports[`medical > 1337 > drugName 1`] = `"Juvilonix"`; exports[`medical > 1337 > procedure 1`] = `"Dermabrasion"`; -exports[`medical > 1337 > specialty 1`] = `"General Surgery"`; +exports[`medical > 1337 > specialty 1`] = `"Gastroenterology"`; -exports[`medical > 1337 > symptom 1`] = `"Double Vision"`; +exports[`medical > 1337 > symptom 1`] = `"Distorted Vision"`; From b7a3ddf803ae9a75bb0f337024a0df7ff7c3c0f1 Mon Sep 17 00:00:00 2001 From: rodrigobnogueira Date: Sun, 12 Jul 2026 19:09:36 -0300 Subject: [PATCH 3/3] refactor(medical): replace the runtime drug-name generator with a static list Per review feedback: drugName() now draws from a pre-generated drug_name locale array (250 names built once from the morphemes and screened against real brand names, WHO INN generic names, and INN class stems), instead of assembling names at runtime with a retry loop. The four morpheme definition keys are gone and the module reads like every other array-backed method. Also trims the class-level overview to not enumerate every method. --- src/definitions/medical.ts | 20 +- .../en/medical/drug_forbidden_ending.ts | 18 -- src/locales/en/medical/drug_infix.ts | 22 -- src/locales/en/medical/drug_name.ts | 252 ++++++++++++++++++ src/locales/en/medical/drug_prefix.ts | 52 ---- src/locales/en/medical/drug_suffix.ts | 32 --- src/locales/en/medical/index.ts | 10 +- src/modules/medical/module.ts | 45 +--- .../__snapshots__/medical.spec.ts.snap | 6 +- test/modules/medical.spec.ts | 14 +- 10 files changed, 269 insertions(+), 202 deletions(-) delete mode 100644 src/locales/en/medical/drug_forbidden_ending.ts delete mode 100644 src/locales/en/medical/drug_infix.ts create mode 100644 src/locales/en/medical/drug_name.ts delete mode 100644 src/locales/en/medical/drug_prefix.ts delete mode 100644 src/locales/en/medical/drug_suffix.ts diff --git a/src/definitions/medical.ts b/src/definitions/medical.ts index ccbdae80393..b652d8eaff8 100644 --- a/src/definitions/medical.ts +++ b/src/definitions/medical.ts @@ -40,23 +40,7 @@ export type MedicalDefinition = LocaleEntry<{ blood_type: string[]; /** - * Invented morpheme prefixes used to build fictitious drug names. + * Fictitious, brand-style drug names, e.g. `'Zolpraxen'`. */ - drug_prefix: string[]; - - /** - * Invented morpheme infixes used to build fictitious drug names. - */ - drug_infix: string[]; - - /** - * Invented morpheme suffixes used to build fictitious drug names. - */ - drug_suffix: string[]; - - /** - * Real INN stems that a fictitious drug name must not end with, so generated - * names cannot resemble real substances. - */ - drug_forbidden_ending: string[]; + drug_name: string[]; }>; diff --git a/src/locales/en/medical/drug_forbidden_ending.ts b/src/locales/en/medical/drug_forbidden_ending.ts deleted file mode 100644 index c68c46b54c3..00000000000 --- a/src/locales/en/medical/drug_forbidden_ending.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default [ - 'caine', - 'cillin', - 'dipine', - 'floxacin', - 'gliptin', - 'mab', - 'mycin', - 'nib', - 'olol', - 'parin', - 'prazole', - 'pril', - 'profen', - 'sartan', - 'statin', - 'vir', -]; diff --git a/src/locales/en/medical/drug_infix.ts b/src/locales/en/medical/drug_infix.ts deleted file mode 100644 index dd37923e0fc..00000000000 --- a/src/locales/en/medical/drug_infix.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default [ - 'be', - 'co', - 'di', - 'du', - 'go', - 'lo', - 'ly', - 'mi', - 'na', - 'no', - 'pra', - 'ra', - 'ri', - 'so', - 'sy', - 'ta', - 'va', - 'vi', - 'xa', - 'ze', -]; diff --git a/src/locales/en/medical/drug_name.ts b/src/locales/en/medical/drug_name.ts new file mode 100644 index 00000000000..e2595dbf72c --- /dev/null +++ b/src/locales/en/medical/drug_name.ts @@ -0,0 +1,252 @@ +export default [ + 'Advaen', + 'Advavor', + 'Advavue', + 'Advazen', + 'Advazepral', + 'Aldadiol', + 'Aldatalor', + 'Andelcor', + 'Andelnavia', + 'Andelol', + 'Andelpradyn', + 'Andelsyyl', + 'Andeltor', + 'Andelzen', + 'Brixdara', + 'Brixgis', + 'Brixol', + 'Brixvor', + 'Caeldivex', + 'Caelduzen', + 'Caellor', + 'Caelmira', + 'Caelnix', + 'Caelpravue', + 'Caeltapral', + 'Caeltor', + 'Caelvue', + 'Cavibequel', + 'Cavidyn', + 'Cavipramira', + 'Cetracoyl', + 'Cetrapramira', + 'Cetraprasen', + 'Cetrasen', + 'Corvamira', + 'Corvaplex', + 'Corvavia', + 'Corvazetiva', + 'Elixcomox', + 'Elixdiplex', + 'Elixnopral', + 'Elixxen', + 'Elixzen', + 'Fendafen', + 'Fendamira', + 'Fendanix', + 'Fendaol', + 'Fendasoxen', + 'Gravabedon', + 'Gravadex', + 'Gravataol', + 'Gravavex', + 'Hylodon', + 'Hyloen', + 'Hylogis', + 'Hyloin', + 'Hylotor', + 'Hylozeen', + 'Hylozen', + 'Ixendara', + 'Ixendivor', + 'Ixendutiva', + 'Ixengis', + 'Ixenin', + 'Ixenmidex', + 'Ixenvafen', + 'Ixenvifen', + 'Ixenvor', + 'Juvidara', + 'Juviin', + 'Juvinool', + 'Kesacoyl', + 'Kesaex', + 'Kesagis', + 'Kesalomox', + 'Kesamox', + 'Kesasogis', + 'Kesativa', + 'Kesavadex', + 'Kesavane', + 'Kesavidyn', + 'Kesaviyl', + 'Klargoex', + 'Klarlor', + 'Klarmitor', + 'Klarmox', + 'Klartiva', + 'Klarvavane', + 'Klarxadon', + 'Lumedara', + 'Lumein', + 'Lumemox', + 'Lumevor', + 'Lumeyl', + 'Lyralopral', + 'Lyraplex', + 'Lyrasomox', + 'Lyravane', + 'Lyravex', + 'Lyrayl', + 'Mizamira', + 'Mizaquel', + 'Mizasen', + 'Mizatadex', + 'Mizator', + 'Mizavavia', + 'Morvaplex', + 'Morvavex', + 'Neuvobemox', + 'Neuvodyn', + 'Neuvonix', + 'Neuvovex', + 'Nexanovue', + 'Nexaplex', + 'Nexaric', + 'Nuvicor', + 'Nuvidex', + 'Nuvilocor', + 'Nuviridex', + 'Nuvitamira', + 'Nuvividyn', + 'Nuvizen', + 'Ombralydon', + 'Ombrapral', + 'Ombraric', + 'Ombravane', + 'Orbaex', + 'Orbamox', + 'Orbaplex', + 'Orbapral', + 'Orbatagis', + 'Oxadara', + 'Oxadien', + 'Oxaravor', + 'Oxasovue', + 'Oxavue', + 'Praxabecor', + 'Praxayl', + 'Pyraen', + 'Pyraloquel', + 'Pyramira', + 'Pyraplex', + 'Pyraramox', + 'Pyrasosen', + 'Pyravia', + 'Quendara', + 'Quennomox', + 'Quenpraex', + 'Quentor', + 'Quenvia', + 'Quenzen', + 'Quiladon', + 'Quiladumira', + 'Quilamisen', + 'Quilativa', + 'Ravidyn', + 'Raviric', + 'Ravivex', + 'Revalor', + 'Revalydon', + 'Revapral', + 'Rexacocor', + 'Rexadon', + 'Rexaen', + 'Rexanacor', + 'Rexaplex', + 'Rovendex', + 'Rovendidex', + 'Roventiva', + 'Rovenvia', + 'Rovenzecor', + 'Solitapral', + 'Solixen', + 'Solizedyn', + 'Solvadex', + 'Solvadon', + 'Solvanaol', + 'Solvaol', + 'Solvavane', + 'Solvavisen', + 'Sonadex', + 'Sonaen', + 'Sonaex', + 'Sonagoxen', + 'Sonaprafen', + 'Sonayl', + 'Tavodufen', + 'Tavopral', + 'Tavosonix', + 'Trovadex', + 'Trovamizen', + 'Trovariin', + 'Trovasyvia', + 'Uvelmox', + 'Uvelol', + 'Uvelsyvane', + 'Uvelvivex', + 'Uvelxen', + 'Uvelzen', + 'Valocor', + 'Valopral', + 'Valovia', + 'Valozevex', + 'Valozevia', + 'Vendadon', + 'Vendafen', + 'Vendavane', + 'Vendazen', + 'Vyraen', + 'Vyraex', + 'Vyragoplex', + 'Vyrapral', + 'Vyrasypral', + 'Vyrativa', + 'Wraxalydara', + 'Wraxanopral', + 'Wraxaquel', + 'Wraxavimox', + 'Wraxavue', + 'Xelydon', + 'Xelygis', + 'Xelyol', + 'Ynovanix', + 'Ynovapramira', + 'Ynovaquel', + 'Ynovasen', + 'Ynovasovex', + 'Ynovavane', + 'Zentacor', + 'Zentalygis', + 'Zentamira', + 'Zentanix', + 'Zentavor', + 'Zentavue', + 'Zevalomira', + 'Zevaritiva', + 'Zevasen', + 'Zevataquel', + 'Zevaxanix', + 'Zivadutiva', + 'Zivafen', + 'Zivalydara', + 'Zivalyvor', + 'Zivaol', + 'Zivavia', + 'Zolnodex', + 'Zolpraxen', + 'Zolraric', + 'Zolvia', + 'Zolyl', +]; diff --git a/src/locales/en/medical/drug_prefix.ts b/src/locales/en/medical/drug_prefix.ts deleted file mode 100644 index 908bd94ad06..00000000000 --- a/src/locales/en/medical/drug_prefix.ts +++ /dev/null @@ -1,52 +0,0 @@ -export default [ - 'Adva', - 'Alda', - 'Andel', - 'Brix', - 'Cael', - 'Cavi', - 'Cetra', - 'Corva', - 'Elix', - 'Fenda', - 'Grava', - 'Hylo', - 'Ixen', - 'Juvi', - 'Kesa', - 'Klar', - 'Lume', - 'Lyra', - 'Miza', - 'Morva', - 'Neuvo', - 'Nexa', - 'Nuvi', - 'Ombra', - 'Orba', - 'Oxa', - 'Praxa', - 'Pyra', - 'Quen', - 'Quila', - 'Ravi', - 'Reva', - 'Rexa', - 'Roven', - 'Soli', - 'Solva', - 'Sona', - 'Tavo', - 'Trova', - 'Uvel', - 'Valo', - 'Venda', - 'Vyra', - 'Wraxa', - 'Xely', - 'Ynova', - 'Zenta', - 'Zeva', - 'Ziva', - 'Zol', -]; diff --git a/src/locales/en/medical/drug_suffix.ts b/src/locales/en/medical/drug_suffix.ts deleted file mode 100644 index 2403d619861..00000000000 --- a/src/locales/en/medical/drug_suffix.ts +++ /dev/null @@ -1,32 +0,0 @@ -export default [ - 'cor', - 'dara', - 'dex', - 'don', - 'dyn', - 'en', - 'ex', - 'fen', - 'gis', - 'in', - 'lor', - 'mira', - 'mox', - 'nix', - 'ol', - 'plex', - 'pral', - 'quel', - 'ric', - 'sen', - 'tiva', - 'tor', - 'vane', - 'vex', - 'via', - 'vor', - 'vue', - 'xen', - 'yl', - 'zen', -]; diff --git a/src/locales/en/medical/index.ts b/src/locales/en/medical/index.ts index 021c943c31a..60700bb3626 100644 --- a/src/locales/en/medical/index.ts +++ b/src/locales/en/medical/index.ts @@ -7,10 +7,7 @@ import allergen from './allergen'; import blood_type from './blood_type'; import condition from './condition'; import department from './department'; -import drug_forbidden_ending from './drug_forbidden_ending'; -import drug_infix from './drug_infix'; -import drug_prefix from './drug_prefix'; -import drug_suffix from './drug_suffix'; +import drug_name from './drug_name'; import procedure from './procedure'; import specialty from './specialty'; import symptom from './symptom'; @@ -20,10 +17,7 @@ const medical: MedicalDefinition = { blood_type, condition, department, - drug_forbidden_ending, - drug_infix, - drug_prefix, - drug_suffix, + drug_name, procedure, specialty, symptom, diff --git a/src/modules/medical/module.ts b/src/modules/medical/module.ts index 7b57c28d70f..376ad5726c2 100644 --- a/src/modules/medical/module.ts +++ b/src/modules/medical/module.ts @@ -6,14 +6,8 @@ import { ModuleBase } from '../../internal/module-base'; * ### Overview * * Generate plausible, non-clinical healthcare data for tests, demos, and - * fixtures: a medical [`specialty()`](https://fakerjs.dev/api/medical.html#specialty), - * a hospital [`department()`](https://fakerjs.dev/api/medical.html#department), - * a [`condition()`](https://fakerjs.dev/api/medical.html#condition), - * a [`symptom()`](https://fakerjs.dev/api/medical.html#symptom), - * a [`procedure()`](https://fakerjs.dev/api/medical.html#procedure), - * an [`allergen()`](https://fakerjs.dev/api/medical.html#allergen), - * a [`bloodType()`](https://fakerjs.dev/api/medical.html#bloodtype), - * and a fictitious [`drugName()`](https://fakerjs.dev/api/medical.html#drugname). + * fixtures: specialties, hospital departments, conditions, symptoms, + * procedures, allergens, blood types, and fictitious drug names. * * All values are intentionally generic or invented. Real diagnosis codes (e.g. * ICD-10), real medicine names, and correlated patient records are deliberately @@ -121,9 +115,9 @@ export class MedicalModule extends ModuleBase { /** * Returns a fictitious, brand-style drug name. * - * The name is assembled from invented morphemes and deliberately avoids real - * WHO INN stems (e.g. `-statin`, `-pril`), so it never resolves to a real - * medicine or brand and cannot be mistaken for one. + * All values are invented: they were generated from neutral morphemes and + * screened against real brand names, WHO INN generic names, and INN class + * stems (e.g. `-statin`, `-pril`), so they do not resolve to real medicines. * * @example * faker.medical.drugName() // 'Zolpraxen' @@ -131,31 +125,8 @@ export class MedicalModule extends ModuleBase { * @since 10.6.0 */ drugName(): string { - const { - drug_prefix: prefixes, - drug_infix: infixes, - drug_suffix: suffixes, - drug_forbidden_ending: forbiddenEndings, - } = this.faker.definitions.medical; - - let name = ''; - // Retry a few times so a name that happens to end in a real INN stem is - // rerolled rather than returned. - for (let attempt = 0; attempt < 12; attempt++) { - const parts = [this.faker.helpers.arrayElement(prefixes)]; - if (this.faker.datatype.boolean(0.4)) { - parts.push(this.faker.helpers.arrayElement(infixes)); - } - - parts.push(this.faker.helpers.arrayElement(suffixes)); - name = parts.join(''); - - const lower = name.toLowerCase(); - if (forbiddenEndings.every((ending) => !lower.endsWith(ending))) { - break; - } - } - - return name; + return this.faker.helpers.arrayElement( + this.faker.definitions.medical.drug_name + ); } } diff --git a/test/modules/__snapshots__/medical.spec.ts.snap b/test/modules/__snapshots__/medical.spec.ts.snap index fd00db37b59..9c9f0a1f5f0 100644 --- a/test/modules/__snapshots__/medical.spec.ts.snap +++ b/test/modules/__snapshots__/medical.spec.ts.snap @@ -8,7 +8,7 @@ exports[`medical > 42 > condition 1`] = `"Fibromyalgia"`; exports[`medical > 42 > department 1`] = `"Maternity Ward"`; -exports[`medical > 42 > drugName 1`] = `"Mizator"`; +exports[`medical > 42 > drugName 1`] = `"Lumeyl"`; exports[`medical > 42 > procedure 1`] = `"Glaucoma Surgery"`; @@ -24,7 +24,7 @@ exports[`medical > 1211 > condition 1`] = `"Thyroid Cancer"`; exports[`medical > 1211 > department 1`] = `"Sleep Lab"`; -exports[`medical > 1211 > drugName 1`] = `"Zentaex"`; +exports[`medical > 1211 > drugName 1`] = `"Zentavor"`; exports[`medical > 1211 > procedure 1`] = `"Tympanoplasty"`; @@ -40,7 +40,7 @@ exports[`medical > 1337 > condition 1`] = `"Crohn's Disease"`; exports[`medical > 1337 > department 1`] = `"Inpatient Ward"`; -exports[`medical > 1337 > drugName 1`] = `"Juvilonix"`; +exports[`medical > 1337 > drugName 1`] = `"Ixenvafen"`; exports[`medical > 1337 > procedure 1`] = `"Dermabrasion"`; diff --git a/test/modules/medical.spec.ts b/test/modules/medical.spec.ts index d1a813a3782..9b9360c5680 100644 --- a/test/modules/medical.spec.ts +++ b/test/modules/medical.spec.ts @@ -72,19 +72,9 @@ describe('medical', () => { }); describe('drugName()', () => { - it('should return a non-empty fictitious drug name', () => { + it('should return a random value from the drug name array', () => { const actual = faker.medical.drugName(); - expect(actual).toBeTypeOf('string'); - expect(actual.length).toBeGreaterThan(0); - expect(actual).toMatch(/^[A-Za-z]+$/); - }); - - it('should not end with a real INN stem', () => { - const lower = faker.medical.drugName().toLowerCase(); - for (const ending of faker.definitions.medical - .drug_forbidden_ending) { - expect(lower.endsWith(ending)).toBe(false); - } + expect(faker.definitions.medical.drug_name).toContain(actual); }); }); }