# @isa/utils/ean-validation Lightweight Angular utility library for validating EAN (European Article Number) barcodes with reactive forms integration and standalone validation functions. ## Overview The EAN Validation library provides tools for validating 13-digit EAN barcodes in Angular applications. It includes both an Angular Forms validator for reactive form validation and a standalone utility function for programmatic validation. The library uses a simple regex-based approach for fast, efficient validation without external dependencies. ## Table of Contents - [Features](#features) - [Quick Start](#quick-start) - [Core Concepts](#core-concepts) - [API Reference](#api-reference) - [Usage Examples](#usage-examples) - [EAN Format](#ean-format) - [Architecture Notes](#architecture-notes) - [Testing](#testing) - [Dependencies](#dependencies) ## Features - **Angular Forms validator** - `eanValidator` for reactive form controls - **Standalone validation** - `isEan()` utility function for programmatic checks - **Regex-based validation** - Fast, efficient 13-digit EAN validation - **Zero dependencies** - No external libraries required - **Type-safe** - Full TypeScript support - **Null-safe** - Graceful handling of undefined/null values - **Lightweight** - Minimal bundle size impact - **Framework agnostic core** - Validation logic can be used outside Angular ## Quick Start ### 1. Reactive Form Validation ```typescript import { Component } from '@angular/core'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { eanValidator } from '@isa/utils/ean-validation'; @Component({ selector: 'app-product-form', standalone: true, imports: [ReactiveFormsModule], template: `
` }) export class ProductFormComponent { productForm = new FormGroup({ ean: new FormControl('', [eanValidator]) }); get eanControl() { return this.productForm.get('ean')!; } } ``` ### 2. Programmatic Validation ```typescript import { Component } from '@angular/core'; import { isEan } from '@isa/utils/ean-validation'; @Component({ selector: 'app-barcode-scanner', template: ` ` }) export class BarcodeScannerComponent { validateBarcode(code: string): void { if (isEan(code)) { console.log('Valid EAN:', code); // Process valid EAN } else { console.error('Invalid EAN:', code); // Handle invalid EAN } } } ``` ### 3. Combined Usage ```typescript import { Component } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { eanValidator, isEan } from '@isa/utils/ean-validation'; @Component({ selector: 'app-product-search', standalone: true, imports: [ReactiveFormsModule], template: ` ` }) export class ProductSearchComponent { searchControl = new FormControl('', [eanValidator]); canSearch(): boolean { const value = this.searchControl.value; return !!value && isEan(value); } search(): void { if (this.canSearch()) { const ean = this.searchControl.value!; console.log('Searching for:', ean); // Perform search } } } ``` ## Core Concepts ### EAN (European Article Number) EAN is a 13-digit barcode standard used internationally for product identification: ``` 1234567890123 └───┬────┘││└─ Check digit │ ││ │ │└── Product code │ └─── Manufacturer code └───────── Country/GS1 prefix ``` ### Validation Rules The library validates EANs based on these criteria: 1. **Length**: Must be exactly 13 digits 2. **Content**: Must contain only numeric characters (0-9) 3. **Format**: No spaces, dashes, or other separators allowed **Valid EANs:** ```typescript '1234567890123' ✓ (13 digits, all numeric) '0000000000000' ✓ (13 digits, all numeric) '9999999999999' ✓ (13 digits, all numeric) ``` **Invalid EANs:** ```typescript '123456789012' ✗ (12 digits - too short) '12345678901234' ✗ (14 digits - too long) '123456789012A' ✗ (contains letter) '1234-5678-9012' ✗ (contains dashes) ' 1234567890123' ✗ (contains whitespace) '' ✗ (empty string - via isEan()) undefined ✗ (undefined - via isEan()) ``` ### Regex Pattern The validation uses a simple regex pattern: ```typescript const EAN_REGEX = /^[0-9]{13}$/; ``` **Pattern breakdown:** - `^` - Start of string - `[0-9]` - Any digit from 0 to 9 - `{13}` - Exactly 13 times - `$` - End of string ## API Reference ### eanValidator Angular Forms validator function for validating EAN input. **Type:** `ValidatorFn` **Signature:** ```typescript eanValidator(control: AbstractControl): ValidationErrors | null ``` **Parameters:** - `control: AbstractControl` - The form control to validate **Returns:** - `null` - If the value is valid or empty/null - `{ invalidEan: true }` - If the value is invalid **Validation Behavior:** - **Empty values**: Returns `null` (considered valid - use `Validators.required` for required fields) - **Valid EAN**: Returns `null` - **Invalid EAN**: Returns `{ invalidEan: true }` **Example:** ```typescript import { FormControl } from '@angular/forms'; import { eanValidator } from '@isa/utils/ean-validation'; const eanControl = new FormControl('', [eanValidator]); eanControl.setValue('1234567890123'); console.log(eanControl.valid); // true eanControl.setValue('123'); console.log(eanControl.errors); // { invalidEan: true } eanControl.setValue(''); console.log(eanControl.valid); // true (empty is valid) ``` ### isEan Standalone utility function for programmatic EAN validation. **Signature:** ```typescript isEan(value: string | undefined): boolean ``` **Parameters:** - `value: string | undefined` - The value to validate **Returns:** - `true` - If the value is a valid 13-digit EAN - `false` - If the value is invalid, undefined, null, or empty **Validation Behavior:** - **undefined/null**: Returns `false` - **Empty string**: Returns `false` - **Valid EAN**: Returns `true` - **Invalid EAN**: Returns `false` **Example:** ```typescript import { isEan } from '@isa/utils/ean-validation'; isEan('1234567890123'); // true isEan('123'); // false isEan(''); // false isEan(undefined); // false isEan(null); // false (TypeScript allows via type coercion) ``` ### EAN_REGEX Regular expression constant for EAN validation. **Type:** `RegExp` **Value:** `/^[0-9]{13}$/` **Note:** This is an internal constant. Prefer using `eanValidator` or `isEan()` for validation. **Example:** ```typescript import { EAN_REGEX } from '@isa/utils/ean-validation'; // Direct regex usage (not recommended) const isValid = EAN_REGEX.test('1234567890123'); console.log(isValid); // true // Prefer using isEan() instead const isValidPreferred = isEan('1234567890123'); ``` ## Usage Examples ### Basic Form Validation ```typescript import { Component } from '@angular/core'; import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { eanValidator } from '@isa/utils/ean-validation'; @Component({ selector: 'app-product-form', standalone: true, imports: [ReactiveFormsModule], template: ` ` }) export class ProductFormComponent { form = new FormGroup({ ean: new FormControl('', [ Validators.required, eanValidator ]) }); get ean() { return this.form.get('ean')!; } onSubmit(): void { if (this.form.valid) { const productData = this.form.value; console.log('Saving product:', productData); // Save logic } } } ``` ### Barcode Scanner Integration ```typescript import { Component, inject, signal } from '@angular/core'; import { isEan } from '@isa/utils/ean-validation'; interface ScanResult { code: string; valid: boolean; timestamp: Date; } @Component({ selector: 'app-barcode-scanner', template: `Please enter a valid 13-digit EAN
} @if (searchResult()) {EAN: {{ searchResult()!.ean }}
Name: {{ searchResult()!.name }}
No product found with EAN: {{ lastSearch() }}
}Valid: {{ validCount() }} / {{ results().length }}
| EAN | Status |
|---|---|
| {{ result.ean }} | {{ result.valid ? '✓ Valid' : '✗ Invalid' }} |
EAN: {{ product.ean }}
} @else {No valid EAN
}Please enter a valid 13-digit EAN (e.g., 1234567890123)
} // Avoid - Generic or unclear message @if (ean.errors?.['invalidEan']) {Invalid
} ``` ### 3. Use isEan for Type Guards Use `isEan()` for runtime type checking: ```typescript // Good - Type-safe validation function processEan(code: string | undefined): void { if (isEan(code)) { // TypeScript knows code is string here console.log('Processing:', code.toUpperCase()); } } // Avoid - Unsafe type assumption function processEan(code: string): void { // Might throw if code is invalid console.log('Processing:', code.toUpperCase()); } ``` ### 4. Add Maxlength Attribute Prevent users from entering more than 13 digits: ```typescript // Good - Limit input length // Avoid - No length restriction ``` ### 5. Handle Validation in Components Keep validation logic in components, not templates: ```typescript // Good - Logic in component canSubmit(): boolean { return this.form.valid && isEan(this.form.value.ean); } // Avoid - Complex logic in template @if (form.valid && form.value.ean && /^[0-9]{13}$/.test(form.value.ean)) { ... } ``` ## Limitations ### What This Library Does NOT Do 1. **Check Digit Validation** - Does not validate the EAN-13 checksum digit 2. **Database Validation** - Does not verify if EAN exists in product database 3. **Prefix Validation** - Does not validate GS1 country/region prefixes 4. **Format Conversion** - Does not convert between EAN/UPC formats 5. **Barcode Generation** - Does not generate barcode images ### When to Use Additional Validation For production systems, consider: - **Check digit validation** for data integrity - **Database lookup** for product existence - **Prefix validation** for regional compliance - **Duplicate detection** in batch processing ## License Internal ISA Frontend library - not for external distribution.