diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 2db8f495..775a72dd 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v9 + - uses: actions/stale@v10 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days." diff --git a/README.md b/README.md index 04cf44ba..c3af11be 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,7 @@ Validators support default `errorText` messages in these languages: - Finnish (fi) - Farsi/Persian (fa) - French (fr) +- Georgian (ka) - German (de) - Greek (el) - Hebrew (he) diff --git a/doc/migration.md b/doc/migration.md index 204323b7..7b4c3f96 100644 --- a/doc/migration.md +++ b/doc/migration.md @@ -65,6 +65,7 @@ FormBuilderValidators.hasMinSomethingChars(...); Validators.string(Validators.hasMinSomethingChars(...)); ``` +> [x] dart fix: OK - `FormBuilderValidators.hasLowercaseChars` ```dart @@ -83,6 +84,7 @@ Validators.hasMinLowercaseChars( ); ``` +> [ ] dart fix: ?? - `FormBuilderValidators.hasNumericChars` ```dart diff --git a/lib/fix_data.yaml b/lib/fix_data.yaml index e827ab5f..25bc185a 100644 --- a/lib/fix_data.yaml +++ b/lib/fix_data.yaml @@ -1,19 +1,625 @@ +# Docs: https://github.com/flutter/flutter/blob/master/docs/contributing/Data-driven-Fixes.md +# Rules: +# 1. You do not talk about dart_fixes.yaml +# 2. Newer transforms come last (to maintain the same order of the migration guide) version: 1 transforms: - - title: 'Rename to new API class name' - date: 2025-10-01 + # hasLowercaseChars - Parameters: atLeast, regex, errorText, checkNullOrEmpty + - title: 'Migrate hasLowercaseChars' + date: 2025-01-15 element: - uris: [ 'form_builder_validators.dart' ] - class: 'FormBuilderValidators' - changes: - - kind: 'rename' - newName: 'Validators' - - title: 'Remove deprecated checkNullOrEmpty property on FormBuilderValidators' - date: 2025-10-01 - element: - uris: [ 'form_builder_validators.dart' ] - constructor: '' + uris: ['form_builder_validators.dart'] + method: 'hasLowercaseChars' inClass: 'FormBuilderValidators' - changes: - - kind: 'removeParameter' - name: 'checkNullOrEmpty' \ No newline at end of file + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + checkNullOrEmpty: + kind: fragment + value: 'arguments[checkNullOrEmpty]' + oneOf: + # ===== checkNullOrEmpty: false (use Validators.optional) ===== + + # F1: checkNullOrEmpty:false + atLeast + errorText + regex + - if: "checkNullOrEmpty == 'false' && atLeast != '' && errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # F2: checkNullOrEmpty:false + atLeast + errorText + - if: "checkNullOrEmpty == 'false' && atLeast != '' && errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + + # F3: checkNullOrEmpty:false + atLeast + regex + - if: "checkNullOrEmpty == 'false' && atLeast != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + regex: + kind: fragment + value: 'arguments[regex]' + + # F4: checkNullOrEmpty:false + errorText + regex + - if: "checkNullOrEmpty == 'false' && errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # F5: checkNullOrEmpty:false + atLeast + - if: "checkNullOrEmpty == 'false' && atLeast != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + + # F6: checkNullOrEmpty:false + errorText + - if: "checkNullOrEmpty == 'false' && errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + + # F7: checkNullOrEmpty:false + regex + - if: "checkNullOrEmpty == 'false' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + regex: + kind: fragment + value: 'arguments[regex]' + + # F8: checkNullOrEmpty:false only + - if: "checkNullOrEmpty == 'false'" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'optional' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars())' + + # ===== checkNullOrEmpty: true (use Validators.required) ===== + + # T1: checkNullOrEmpty:true + atLeast + errorText + regex + - if: "checkNullOrEmpty == 'true' && atLeast != '' && errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # T2: checkNullOrEmpty:true + atLeast + errorText + - if: "checkNullOrEmpty == 'true' && atLeast != '' && errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + + # T3: checkNullOrEmpty:true + atLeast + regex + - if: "checkNullOrEmpty == 'true' && atLeast != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + regex: + kind: fragment + value: 'arguments[regex]' + + # T4: checkNullOrEmpty:true + errorText + regex + - if: "checkNullOrEmpty == 'true' && errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # T5: checkNullOrEmpty:true + atLeast + - if: "checkNullOrEmpty == 'true' && atLeast != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + + # T6: checkNullOrEmpty:true + errorText + - if: "checkNullOrEmpty == 'true' && errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + + # T7: checkNullOrEmpty:true + regex + - if: "checkNullOrEmpty == 'true' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + regex: + kind: fragment + value: 'arguments[regex]' + + # T8: checkNullOrEmpty:true only + - if: "checkNullOrEmpty == 'true'" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'checkNullOrEmpty' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars())' + + # ===== Default cases (checkNullOrEmpty not provided = true) ===== + + # D1: atLeast + errorText + regex + - if: "atLeast != '' && errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # D2: atLeast + errorText + - if: "atLeast != '' && errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, msg: {% errorText %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + errorText: + kind: fragment + value: 'arguments[errorText]' + + # D3: atLeast + regex + - if: "atLeast != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}, customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + regex: + kind: fragment + value: 'arguments[regex]' + + # D4: errorText + regex + - if: "errorText != '' && regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length, msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + regex: + kind: fragment + value: 'arguments[regex]' + + # D5: Only atLeast + - if: "atLeast != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'atLeast' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(min: {% atLeast %}))' + variables: + atLeast: + kind: fragment + value: 'arguments[atLeast]' + + # D6: Only errorText + - if: "errorText != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'errorText' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(msg: {% errorText %}))' + variables: + errorText: + kind: fragment + value: 'arguments[errorText]' + + # D7: Only regex + - if: "regex != ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'removeParameter' + name: 'regex' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => {% regex %}.allMatches(input).length))' + variables: + regex: + kind: fragment + value: 'arguments[regex]' + + # D8: No parameters (default) + - if: "atLeast == '' && errorText == '' && regex == '' && checkNullOrEmpty == ''" + changes: + - kind: 'replacedBy' + newElement: + uris: ['form_builder_validators.dart'] + method: 'required' + inClass: 'Validators' + - kind: 'addParameter' + index: 0 + name: 'next' + style: 'required_positional' + argumentValue: + expression: 'Validators.string(Validators.hasMinLowercaseChars())' \ No newline at end of file diff --git a/lib/l10n/intl_ka.arb b/lib/l10n/intl_ka.arb new file mode 100644 index 00000000..ce8584cb --- /dev/null +++ b/lib/l10n/intl_ka.arb @@ -0,0 +1,90 @@ +{ + "@@locale": "ka", + "creditCardErrorText": "ველის მნიშვნელობა უნდა იყოს საკრედიტო ბარათის ნომერი.", + "dateStringErrorText": "ველი უნდა იყოს თარიღი.", + "emailErrorText": "ველი უნდა იყოს email მისამართი.", + "equalErrorText": "ველის მნიშვნელობა უნდა იყოს ტოლი {value}.", + "equalLengthErrorText": "მნიშვნელობას უნდა ჰქონდეს სიგრძე, რომელიც ტოლი უნდა იყოს {length}.", + "integerErrorText": "ველი უნდა იყოს მთელი რიცხვი.", + "ipErrorText": "ველი უნდა იყოს IP მისამართი.", + "matchErrorText": "მნიშვნელობა უნდა შეესაბამებოდეს ნიმუშს.", + "maxErrorText": "მნიშვნელობა უნდა იყოს ნაკლები ან ტოლი {max}.", + "maxLengthErrorText": "მნიშვნელობის სიგრძე უნდა იყოს ნაკლები ან ტოლი {maxLength}.", + "maxWordsCountErrorText": "მნიშვნელობას უნდა ჰქონდეს სიტყვების რაოდენობა ნაკლები ან ტოლი {maxWordsCount}.", + "minErrorText": "მნიშვნელობა უნდა იყოს მეტი ან ტოლი {min}.", + "minLengthErrorText": "მნიშვნელობის სიგრძე უნდა იყოს მეტი ან ტოლი {minLength}.", + "minWordsCountErrorText": "მნიშვნელობას უნდა ჰქონდეს სიტყვების რაოდენობა მეტი ან ტოლი {minWordsCount}.", + "notEqualErrorText": "ველის მნიშვნელობა არ უნდა იყოს ტოლი {value}.", + "numericErrorText": "მნიშვნელობა უნდა იყოს რიცხვი.", + "requiredErrorText": "ველი არ შეიძლება იყოს ცარიელი.", + "urlErrorText": "ველი უნდა იყოს URL მისამართი.", + "phoneErrorText": "ველი უნდა იყოს ტელეფონის ნომერი.", + "creditCardExpirationDateErrorText": "ველი უნდა იყოს საკრედიტო ბარათის ვადის გასვლის მოქმედი თარიღი.", + "creditCardExpiredErrorText": "საკრედიტო ბარათს ვადა გაუვიდა.", + "creditCardCVCErrorText": "ველი უნდა იყოს მოქმედი საკრედიტო ბარათის CVC კოდი.", + "colorCodeErrorText": "ველი უნდა იყოს სწორი ფერის კოდი.", + "uppercaseErrorText": "ველი უნდა შეიცავდეს დიდი ასოებით დაწერილს.", + "lowercaseErrorText": "ველი უნდა შეიცავდეს პატარა ასოებს.", + "fileExtensionErrorText": "ველი უნდა იყოს ფაილის სწორი გაფართოება.", + "fileSizeErrorText": "ფაილი აღემატება მაქსიმალურ დაშვებულ ზომას.", + "dateRangeErrorText": "თარიღი უნდა იყოს ვალიდურ დიაპაზონში.", + "mustBeTrueErrorText": "ველი უნდა იყოს ჭეშმარიტი.", + "mustBeFalseErrorText": "ველი უნდა იყოს ყალბი.", + "containsSpecialCharErrorText": "ველი უნდა შეიცავდეს განსაკუთრებულ ხასიათს.", + "containsUppercaseCharErrorText": "ველი უნდა შეიცავდეს დიდ ასოებს.", + "containsLowercaseCharErrorText": "ველი უნდა შეიცავდეს მცირე ასოებს.", + "containsNumberErrorText": "ველი უნდა შეიცავდეს რიცხვებს.", + "alphabeticalErrorText": "ველი უნდა შეიცავდეს მხოლოდ ასოებს.", + "uuidErrorText": "ველი უნდა იყოს მოქმედი UUID.", + "jsonErrorText": "ველი უნდა იყოს მოქმედი JSON.", + "latitudeErrorText": "ველი უნდა იყოს სწორი განედი.", + "longitudeErrorText": "ველი უნდა იყოს სწორი გრძედი.", + "base64ErrorText": "ველი უნდა იყოს მოქმედი Base64 სტრიქონი.", + "pathErrorText": "ველი უნდა იყოს სწორი გზა.", + "oddNumberErrorText": "ველი კენტი რიცხვი უნდა იყოს.", + "evenNumberErrorText": "ველი ლუწი რიცხვი უნდა იყოს.", + "portNumberErrorText": "ველი უნდა იყოს სწორი პორტის ნომერი.", + "macAddressErrorText": "ველი უნდა იყოს სწორი MAC მისამართი.", + "startsWithErrorText": "მნიშვნელობა უნდა იწყებოდეს {value}.", + "endsWithErrorText": "მნიშვნელობა უნდა მთავრდებოდეს {value}.", + "containsErrorText": "მნიშვნელობა უნდა შეიცავდეს {value}.", + "betweenErrorText": "მნიშვნელობა უნდა იყოს შორის {min} და {max}.", + "containsElementErrorText": "მნიშვნელობა უნდა იყოს ვალიდური მნიშვნელობების სიაში.", + "ibanErrorText": "ველი უნდა იყოს სწორი IBAN ნომერი.", + "uniqueErrorText": "ველი უნიკალური უნდა იყოს.", + "bicErrorText": "ველი უნდა იყოს მოქმედი BIC კოდი.", + "isbnErrorText": "ველი უნდა იყოს სწორი ISBN ნომერი.", + "singleLineErrorText": "ველი უნდა შეიცავდეს მხოლოდ ერთ ხაზს.", + "timeErrorText": "ველი უნდა იყოს სწორი დრო.", + "dateMustBeInTheFutureErrorText": "თარიღი მომავალში უნდა იყოს.", + "dateMustBeInThePastErrorText": "თარიღი წარსულში უნდა იყოს.", + "fileNameErrorText": "მნიშვნელობა უნდა იყოს ფაილის სწორი სახელი.", + "negativeNumberErrorText": "მნიშვნელობა უარყოფითი რიცხვი უნდა იყოს.", + "positiveNumberErrorText": "მნიშვნელობა უნდა იყოს დადებითი რიცხვი.", + "notZeroNumberErrorText": "მნიშვნელობა არ უნდა იყოს ნული.", + "ssnErrorText": "მნიშვნელობა უნდა იყოს მოქმედი სოციალური დაზღვევის ნომერი.", + "zipCodeErrorText": "მნიშვნელობა უნდა იყოს მოქმედი საფოსტო ინდექსი.", + "usernameErrorText": "მნიშვნელობა უნდა იყოს სწორი მომხმარებლის სახელი.", + "usernameCannotContainNumbersErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს ციფრებს.", + "usernameCannotContainUnderscoreErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს ქვედახაზებს.", + "usernameCannotContainSpecialCharErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს სპეციალურ სიმბოლოებს.", + "usernameCannotContainSpacesErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს სივრცეებს.", + "usernameCannotContainDotsErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს წერტილებს.", + "usernameCannotContainDashesErrorText": "მომხმარებლის სახელი არ შეიძლება შეიცავდეს დეფისებს.", + "invalidMimeTypeErrorText": "არასწორი MIME-ტიპი.", + "timezoneErrorText": "მნიშვნელობა უნდა იყოს სწორი დროის სარტყელი.", + "cityErrorText": "მნიშვნელობა უნდა იყოს ქალაქის სწორი სახელი.", + "countryErrorText": "მნიშვნელობა უნდა იყოს ქვეყნის სწორი სახელი.", + "stateErrorText": "მნიშვნელობა უნდა იყოს მოქმედი შტატის სახელი.", + "streetErrorText": "მნიშვნელობა უნდა იყოს სწორი ქუჩის სახელი.", + "firstNameErrorText": "მნიშვნელობა უნდა იყოს სწორი სახელი.", + "lastNameErrorText": "მნიშვნელობა უნდა იყოს სწორი გვარი.", + "passportNumberErrorText": "მნიშვნელობა უნდა იყოს მოქმედი პასპორტის ნომერი.", + "primeNumberErrorText": "მნიშვნელობა უნდა იყოს მარტივი რიცხვი.", + "dunsErrorText": "მნიშვნელობა უნდა იყოს სწორი DUNS ნომერი.", + "licensePlateErrorText": "მნიშვნელობა უნდა იყოს მოქმედი სანომრე ნიშნის ნომერი.", + "vinErrorText": "მნიშვნელობა უნდა იყოს მოქმედი VIN.", + "languageCodeErrorText": "მნიშვნელობა უნდა იყოს ვალიდური ენის კოდი.", + "floatErrorText": "მნიშვნელობა უნდა იყოს სწორი მცურავი წვეთოვანი რიცხვი.", + "hexadecimalErrorText": "მნიშვნელობა უნდა იყოს სწორი თექვსმეტობითი რიცხვი." +} \ No newline at end of file diff --git a/lib/src/form_builder_validators.dart b/lib/src/form_builder_validators.dart index 57d9e1b3..b56d7ea2 100644 --- a/lib/src/form_builder_validators.dart +++ b/lib/src/form_builder_validators.dart @@ -23,6 +23,9 @@ class FormBuilderValidators { /// - [checkNullOrEmpty] Whether to check for null or empty values. /// /// {@macro lowercase_chars_template} + @Deprecated( + 'Use Validators.string(Validators.hasMinLowercaseChars(...)) instead. See migration guide.', + ) static FormFieldValidator hasLowercaseChars({ int atLeast = 1, RegExp? regex, @@ -2995,15 +2998,26 @@ final class Validators { /// work correctly for all languages. Custom lowercase counter function should /// be provided for special language requirements /// {@endtemplate} + // TODO: update the documentation and change the implementation to handle the new msg arg. Also, update about the argument condition error static Validator hasMinLowercaseChars({ c.int min = 1, c.int Function(String input)? customLowercaseCounter, + String? msg, String Function(String input, c.int min)? hasMinLowercaseCharsMsg, - }) => val.hasMinLowercaseChars( - min: min, - customLowercaseCounter: customLowercaseCounter, - hasMinLowercaseCharsMsg: hasMinLowercaseCharsMsg, - ); + }) { + if (msg != null && hasMinLowercaseCharsMsg != null) { + throw ArgumentError( + 'Cannot provide both msg and hasMinLowercaseCharsMsg. Use only one.', + ); + } + return val.hasMinLowercaseChars( + min: min, + customLowercaseCounter: customLowercaseCounter, + hasMinLowercaseCharsMsg: msg != null + ? (_, _) => msg + : hasMinLowercaseCharsMsg, + ); + } /// {@template validator_has_min_numeric_chars} /// Creates a validator function that checks if the [String] input contains a diff --git a/test_fixes/fixes_12.0.0.dart b/test_fixes/fixes_12.0.0.dart deleted file mode 100644 index 133b0655..00000000 --- a/test_fixes/fixes_12.0.0.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:form_builder_validators/form_builder_validators.dart'; - -/// Basic examples involving only one validator per example -class BasicExamplesPage extends StatelessWidget { - /// Constructs a new instance of the [BasicExamplesPage] class. - const BasicExamplesPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Basic Examples (one validator per example)'), - ), - body: Column( - children: [ - TextFormField( - validator: FormBuilderValidators.equal('-', checkNullOrEmpty: true), - ), - TextFormField(validator: FormBuilderValidators.equal('-')), - TextFormField(validator: FormBuilderValidators.notEqual('-')), - TextFormField( - validator: FormBuilderValidators.equal( - 'test', - checkNullOrEmpty: false, - ), - ), - TextFormField( - validator: FormBuilderValidators.notEqual( - 'test', - checkNullOrEmpty: false, - ), - ), - TextFormField( - validator: FormBuilderValidators.required(checkNullOrEmpty: true), - ), - TextFormField( - validator: FormBuilderValidators.required(checkNullOrEmpty: false), - ), - TextFormField( - validator: FormBuilderValidators.email(checkNullOrEmpty: true), - ), - TextFormField( - validator: FormBuilderValidators.email(checkNullOrEmpty: false), - ), - TextFormField( - validator: (String? input) { - final String? isRequiredMsg = FormBuilderValidators.required()( - input, - ); - return isRequiredMsg?.toUpperCase().replaceFirst( - 'OVERRIDE: ', - '', - ); - }, - ), - ], - ), - ); - } -} diff --git a/test_fixes/fixes_12.0.0.dart.expect b/test_fixes/fixes_12.0.0.dart.expect deleted file mode 100644 index b1b767de..00000000 --- a/test_fixes/fixes_12.0.0.dart.expect +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:form_builder_validators/form_builder_validators.dart'; - -/// Basic examples involving only one validator per example -class BasicExamplesPage extends StatelessWidget { - /// Constructs a new instance of the [BasicExamplesPage] class. - const BasicExamplesPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Basic Examples (one validator per example)'), - ), - body: Column( - children: [ - TextFormField( - validator: Validators.equal('-'), - ), - TextFormField(validator: Validators.equal('-')), - TextFormField(validator: Validators.notEqual('-')), - TextFormField( - validator: Validators.equal( - 'test', - ), - ), - TextFormField( - validator: Validators.notEqual( - 'test', - ), - ), - TextFormField( - validator: Validators.required(), - ), - TextFormField( - validator: Validators.required(), - ), - TextFormField( - validator: Validators.email(), - ), - TextFormField( - validator: Validators.email(), - ), - TextFormField( - validator: (String? input) { - final String? isRequiredMsg = Validators.required()( - input, - ); - return isRequiredMsg?.toUpperCase().replaceFirst( - 'OVERRIDE: ', - '', - ); - }, - ), - ], - ), - ); - } -} diff --git a/test_fixes/has_lowercase_chars.dart b/test_fixes/has_lowercase_chars.dart new file mode 100644 index 00000000..3590dfe9 --- /dev/null +++ b/test_fixes/has_lowercase_chars.dart @@ -0,0 +1,164 @@ +import 'package:flutter/material.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; + +void main() { + // ===== checkNullOrEmpty: false cases (Validators.optional) ===== + + // F1: checkNullOrEmpty:false + atLeast + errorText + regex + FormBuilderValidators.hasLowercaseChars( + atLeast: 3, + errorText: 'Need 3', + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: false, + ); + + // F2: checkNullOrEmpty:false + atLeast + errorText + FormBuilderValidators.hasLowercaseChars( + atLeast: 2, + errorText: 'Need 2', + checkNullOrEmpty: false, + ); + + // F3: checkNullOrEmpty:false + atLeast + regex + FormBuilderValidators.hasLowercaseChars( + atLeast: 4, + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: false, + ); + + // F4: checkNullOrEmpty:false + errorText + regex + FormBuilderValidators.hasLowercaseChars( + errorText: 'Error', + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: false, + ); + + // F5: checkNullOrEmpty:false + atLeast + FormBuilderValidators.hasLowercaseChars(atLeast: 5, checkNullOrEmpty: false); + + // F6: checkNullOrEmpty:false + errorText + FormBuilderValidators.hasLowercaseChars( + errorText: 'Must have lowercase', + checkNullOrEmpty: false, + ); + + // F7: checkNullOrEmpty:false + regex + FormBuilderValidators.hasLowercaseChars( + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: false, + ); + + // F8: checkNullOrEmpty:false only + FormBuilderValidators.hasLowercaseChars(checkNullOrEmpty: false); + + // ===== checkNullOrEmpty: true cases (Validators.required) ===== + + // T1: checkNullOrEmpty:true + atLeast + errorText + regex + FormBuilderValidators.hasLowercaseChars( + atLeast: 3, + errorText: 'Need 3', + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: true, + ); + + // T2: checkNullOrEmpty:true + atLeast + errorText + FormBuilderValidators.hasLowercaseChars( + atLeast: 2, + errorText: 'Need 2', + checkNullOrEmpty: true, + ); + + // T3: checkNullOrEmpty:true + atLeast + regex + FormBuilderValidators.hasLowercaseChars( + atLeast: 4, + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: true, + ); + + // T4: checkNullOrEmpty:true + errorText + regex + FormBuilderValidators.hasLowercaseChars( + errorText: 'Error', + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: true, + ); + + // T5: checkNullOrEmpty:true + atLeast + FormBuilderValidators.hasLowercaseChars(atLeast: 5, checkNullOrEmpty: true); + + // T6: checkNullOrEmpty:true + errorText + FormBuilderValidators.hasLowercaseChars( + errorText: 'Must have lowercase', + checkNullOrEmpty: true, + ); + + // T7: checkNullOrEmpty:true + regex + FormBuilderValidators.hasLowercaseChars( + regex: RegExp(r'[a-z]'), + checkNullOrEmpty: true, + ); + + // T8: checkNullOrEmpty:true only + FormBuilderValidators.hasLowercaseChars(checkNullOrEmpty: true); + + // ===== Default cases (checkNullOrEmpty not provided = true) ===== + + // D1: atLeast + errorText + regex + FormBuilderValidators.hasLowercaseChars( + atLeast: 3, + errorText: 'Need 3', + regex: RegExp(r'[a-z]'), + ); + + // D2: atLeast + errorText + FormBuilderValidators.hasLowercaseChars(atLeast: 2, errorText: 'Need 2'); + + // D3: atLeast + regex + FormBuilderValidators.hasLowercaseChars(atLeast: 4, regex: RegExp(r'[a-z]')); + + // D4: errorText + regex + FormBuilderValidators.hasLowercaseChars( + errorText: 'Error', + regex: RegExp(r'[a-z]'), + ); + + // D5: Only atLeast + FormBuilderValidators.hasLowercaseChars(atLeast: 5); + + // D6: Only errorText + FormBuilderValidators.hasLowercaseChars(errorText: 'Must have lowercase'); + + // D7: Only regex + FormBuilderValidators.hasLowercaseChars(regex: RegExp(r'[a-z]')); + + // D8: No parameters + FormBuilderValidators.hasLowercaseChars(); + + // ===== Real-world usage examples ===== + + // Used in TextFormField + TextFormField( + decoration: const InputDecoration(labelText: 'Password'), + validator: FormBuilderValidators.hasLowercaseChars( + atLeast: 2, + errorText: 'Password needs at least 2 lowercase letters', + ), + ); + + // Used in Form with optional field + Form( + child: TextFormField( + decoration: const InputDecoration(labelText: 'Nickname (optional)'), + validator: FormBuilderValidators.hasLowercaseChars( + checkNullOrEmpty: false, + errorText: 'If provided, must have lowercase', + ), + ), + ); + + // Assigned to variable + final passwordValidator = FormBuilderValidators.hasLowercaseChars( + atLeast: 3, + regex: RegExp(r'[a-z]'), + errorText: 'Need 3 lowercase', + ); +} diff --git a/test_fixes/has_lowercase_chars.dart.expect b/test_fixes/has_lowercase_chars.dart.expect new file mode 100644 index 00000000..ea9b7f5a --- /dev/null +++ b/test_fixes/has_lowercase_chars.dart.expect @@ -0,0 +1,135 @@ +import 'package:flutter/material.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; + +void main() { + // ===== checkNullOrEmpty: false cases (Validators.optional) ===== + + // F1: checkNullOrEmpty:false + atLeast + errorText + regex + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(min: 3, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Need 3')), + ); + + // F2: checkNullOrEmpty:false + atLeast + errorText + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(min: 2, msg: 'Need 2')), + ); + + // F3: checkNullOrEmpty:false + atLeast + regex + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(min: 4, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length)), + ); + + // F4: checkNullOrEmpty:false + errorText + regex + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Error')), + ); + + // F5: checkNullOrEmpty:false + atLeast + Validators.optional(Validators.string(Validators.hasMinLowercaseChars(min: 5))); + + // F6: checkNullOrEmpty:false + errorText + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(msg: 'Must have lowercase')), + ); + + // F7: checkNullOrEmpty:false + regex + Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length)), + ); + + // F8: checkNullOrEmpty:false only + Validators.optional(Validators.string(Validators.hasMinLowercaseChars())); + + // ===== checkNullOrEmpty: true cases (Validators.required) ===== + + // T1: checkNullOrEmpty:true + atLeast + errorText + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 3, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Need 3')), + ); + + // T2: checkNullOrEmpty:true + atLeast + errorText + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 2, msg: 'Need 2')), + ); + + // T3: checkNullOrEmpty:true + atLeast + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 4, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length)), + ); + + // T4: checkNullOrEmpty:true + errorText + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Error')), + ); + + // T5: checkNullOrEmpty:true + atLeast + Validators.required(Validators.string(Validators.hasMinLowercaseChars(min: 5))); + + // T6: checkNullOrEmpty:true + errorText + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(msg: 'Must have lowercase')), + ); + + // T7: checkNullOrEmpty:true + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length)), + ); + + // T8: checkNullOrEmpty:true only + Validators.required(Validators.string(Validators.hasMinLowercaseChars())); + + // ===== Default cases (checkNullOrEmpty not provided = true) ===== + + // D1: atLeast + errorText + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 3, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Need 3')), + ); + + // D2: atLeast + errorText + Validators.required(Validators.string(Validators.hasMinLowercaseChars(min: 2, msg: 'Need 2'))); + + // D3: atLeast + regex + Validators.required(Validators.string(Validators.hasMinLowercaseChars(min: 4, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length))); + + // D4: errorText + regex + Validators.required( + Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Error')), + ); + + // D5: Only atLeast + Validators.required(Validators.string(Validators.hasMinLowercaseChars(min: 5))); + + // D6: Only errorText + Validators.required(Validators.string(Validators.hasMinLowercaseChars(msg: 'Must have lowercase'))); + + // D7: Only regex + Validators.required(Validators.string(Validators.hasMinLowercaseChars(customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length))); + + // D8: No parameters + Validators.required(Validators.string(Validators.hasMinLowercaseChars())); + + // ===== Real-world usage examples ===== + + // Used in TextFormField + TextFormField( + decoration: const InputDecoration(labelText: 'Password'), + validator: Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 2, msg: 'Password needs at least 2 lowercase letters')), + ), + ); + + // Used in Form with optional field + Form( + child: TextFormField( + decoration: const InputDecoration(labelText: 'Nickname (optional)'), + validator: Validators.optional( + Validators.string(Validators.hasMinLowercaseChars(msg: 'If provided, must have lowercase')), + ), + ), + ); + + // Assigned to variable + final passwordValidator = Validators.required( + Validators.string(Validators.hasMinLowercaseChars(min: 3, customLowercaseCounter: (input) => RegExp(r'[a-z]').allMatches(input).length, msg: 'Need 3 lowercase')), + ); +}