### Install Application Executable Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Installs the main application executable to the root of the installation prefix. This is a core part of the runtime installation. ```cmake install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) ``` -------------------------------- ### Define Installation Directories Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Sets variables for the installation directories within the bundle. These are used for placing application data and libraries. ```cmake set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") ``` -------------------------------- ### Install Flutter Library Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Installs the main Flutter library file to the lib directory of the bundle. This is essential for the Flutter runtime. ```cmake install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Set Installation Prefix for Bundle Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Configures the installation prefix to point to the build directory's bundle. This makes 'install' create a relocatable bundle. ```cmake set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() ``` -------------------------------- ### Install Eskema Dependency Source: https://github.com/nombrekeff/eskema/wiki/Installation After adding the dependency to `pubspec.yaml`, run this command in your terminal to fetch the package. ```bash dart pub get ``` -------------------------------- ### Install Bundled Plugin Libraries Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Installs any bundled libraries provided by plugins to the lib directory. This ensures that plugins have their required shared libraries available. ```cmake foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) ``` -------------------------------- ### Clean Build Bundle Directory on Install Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Removes the build bundle directory before installation to ensure a clean state. This is part of the installation process for the runtime component. ```cmake install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) ``` -------------------------------- ### Install Native Assets Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Copies native assets provided by build scripts to the lib directory. This ensures that platform-specific assets are included in the bundle. ```cmake set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### String Transformer: trim and toUpperCase Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers This example shows composition of string transformers. `trim` removes leading/trailing whitespace, and `toUpperCase` converts the string to uppercase. It also includes validation for string type and length. ```dart final sku = trim(toUpperCase(all([isString(), length([isInRange(3, 10)])]))); print(sku.isValid(' abC ')); // true -> becomes 'ABC' ``` -------------------------------- ### Install ICU Data File Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Installs the ICU data file to the data directory of the bundle. This is required for internationalization and localization. ```cmake install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install Eskema using Dart Pub Source: https://github.com/nombrekeff/eskema/blob/main/README.md Add the Eskema package to your Dart project dependencies using the `dart pub add` command. ```bash dart pub add eskema ``` -------------------------------- ### Install AOT Library Conditionally Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compiled library only for non-Debug builds. This optimizes performance for release and profile builds. ```cmake if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Find and Link System Libraries (CMake) Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/flutter/CMakeLists.txt This section finds required system libraries like GTK, GLIB, and GIO using PkgConfig and makes them available for linking. Ensure these libraries are installed on your system. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Example Usage of Password Patch Validation Source: https://github.com/nombrekeff/eskema/wiki/Guide-Partial-Updates-PATCH Demonstrates how to use the `validatePasswordPatch` function with a sample patch payload. If valid, it proceeds to update the user's password hash. ```dart final patch = { 'password': 'SuperSecret123', 'passwordConfirm': 'SuperSecret123', }; final r = validatePasswordPatch(patch); if (r.isValid) { // Merge into existing user after hashing user.passwordHash = hash(patch['password']); } else { print(r.detailed()); // e.g. password_mismatch } ``` -------------------------------- ### Composition Examples with Eskema Validators Source: https://github.com/nombrekeff/eskema/wiki/Comparison-Validators Demonstrates combining multiple validators for complex checks like status, ID pairs, and non-empty lists. Requires importing Eskema validators. ```dart final status = isOneOf(['draft','live','archived']); final idPair = eskemaList([$isString, $isInt]); final nonEmptyList = $isList & length([isGte(1)]); ``` -------------------------------- ### Example Eskema with Date Validators Source: https://github.com/nombrekeff/eskema/wiki/Date-Validators Illustrates how to use date validators within an eskema object for defining 'started' and 'renews' properties. Ensures 'started' is in the past and 'renews' is in the future. ```dart final subscription = eskema({ 'started': toDateTime(isDateInPast()), 'renews': toDateTime(isDateInFuture()), }); ``` -------------------------------- ### Core Eskema Validation Example Source: https://github.com/nombrekeff/eskema/blob/main/README.md Demonstrates building a user schema with various validators and operators, then validating a JSON-like map. Shows how to check for valid data and inspect detailed validation failures. ```dart import 'package:eskema/eskema.dart'; void main() { final userValidator = eskema({ 'username': isString(), // basic type check 'lastname': $isString, // cached zero‑arg variant 'age': all([isInt(), isGte(0)]), // multi validator (AND) 'theme': isString() & (isEq('light') | isEq('dark')), // operators 'premium': nullable($isBool), // key must exist; value may be null 'birthday': optional(isDate()), // key may be absent }); final ok = userValidator.validate({ 'username': 'bob', 'lastname': 'builder', 'theme': 'light', 'age': 42, }); print(ok); // missing premium (nullable != optional) final res = userValidator.validate({'username': 'alice', 'age': -1}); print(res.isValid); // false print(res.expectations); // structured reasons (age invalid, missing keys, etc.) } ``` -------------------------------- ### Set Minimum CMake Version and Project Name Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Specifies the minimum required CMake version and the project name. This is a standard starting point for CMake projects. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) ``` -------------------------------- ### Define Schema with Number Validators Source: https://github.com/nombrekeff/eskema/wiki/Number-Validators Example of defining a schema for an order, validating quantity and price using number validators. ```dart final order = eskema({ 'qty': toInt(isInRange(1, 999)), 'price': toDouble(isGte(0)), }); ``` -------------------------------- ### Clean and Copy Flutter Assets Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Removes existing Flutter assets and then copies the new ones to the data directory. This ensures that the assets are up-to-date for each installation. ```cmake set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Pick and Get Field Transformers Source: https://github.com/nombrekeff/eskema/wiki/Transformers Demonstrates using `pickKeys` to select specific keys from a map and `getField` for validating nested fields. `pickKeys` ignores extra keys not specified. ```dart final picked = pickKeys(['id','email'], eskema({'id': $isNonEmptyString, 'email': $isString & email()})); print(picked.isValid({'id':'u1','email':'a@b.c','extra':1})); // true (extra ignored) final qty = getField('qty', toInt(gte(1))); print(qty.isValid({'qty':'5'})); // true ``` -------------------------------- ### Cross-field Validation with `resolve` Source: https://github.com/nombrekeff/eskema/wiki/Contextual-Validators Use `resolve` to access parent map data and create validators dynamically. This example enforces that `confirmPassword` matches `password`. ```dart final schema = eskema({ 'password': isString() & not(isEmpty), 'confirmPassword': resolve((data) { final password = data['password']; // Return a validator that checks equality with the password field return equals(password); }), }); print(schema.validate({ 'password': 'secret', 'confirmPassword': 'secret' }).isValid); // true print(schema.validate({ 'password': 'secret', 'confirmPassword': 'wrong' }).isValid); // false ``` -------------------------------- ### First Validation (Functional Style) Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Define a user validator using the functional style with Eskema. This example shows how to validate string, email, and integer fields, including range checks. ```dart import 'package:eskema/eskema.dart'; void main() { final userValidator = eskema({ 'id': all([isString(), not($isEmptyString)]), 'email': all([isString(), email()]), 'age': isInt() & gte(18), // You can use operators instead of all, any, and other combinators }); final input = {'id': 'u_1', 'email': 'alice@example.com', 'age': 34}; final result = userValidator.validate(input); if (result.isValid) { print('Valid ✅'); } else { print(result.detailed()); // formatted multi-line summary } } ``` -------------------------------- ### Transforming Data (Builder Style) Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Define data transformations within a schema using Eskema's builder style. This example shows trimming, converting to integer, and checking a minimum value for order data. ```dart final orderSchema = v().string().trim().toInt().gte(1); ``` -------------------------------- ### Eskema Payload Validation Example Source: https://github.com/nombrekeff/eskema/wiki/Type-Validators Defines a schema for a payload using various validators including non-empty strings, optional lists of strings, and optional maps. This demonstrates how to structure complex validation rules. ```dart final payload = eskema({ 'id': $isNonEmptyString, 'tags': optional($isList & listEach($isNonEmptyString)), 'meta': optional($isMap), }); ``` -------------------------------- ### Builder Pattern for Data Validation and Transformation Source: https://github.com/nombrekeff/eskema/wiki/Transformers Example of using the builder pattern to chain multiple transformations and validations, including string manipulation, type conversion, and range checks. ```dart final product = v().map().schema({ 'sku': v().string().trim().toUpperCase().lengthMin(3).build(), 'qty': v().string().trim().toInt().gte(1).build(), 'active': v().toBoolLenient().build(), }).build(); print(product.validate({'sku':' abc ','qty':'5','active':'yes'}).isValid); // true ``` -------------------------------- ### Define and Use Map Schema Validator Source: https://context7.com/nombrekeff/eskema/llms.txt Build a validator for a Map using `eskema({...})`. This example demonstrates defining validators for various field types, including strings, emails, optional integers, enumerated strings, nullable booleans, and optional dates. It also shows how to validate data and inspect the results. ```dart final userSchema = eskema({ 'id': $isNonEmptyString, 'email': $isString & email(), 'age': optional(toInt(isInRange(0, 130))), 'theme': isString() & (isEq('light') | isEq('dark')), 'premium': nullable($isBool), 'birthday': optional(isDate()), }); final good = userSchema.validate({ 'id': 'u_1', 'email': 'alice@example.com', 'age': '42', 'theme': 'dark', 'premium': null, }); print(good.isValid); // true final bad = userSchema.validate({'id': '', 'email': 'not-an-email', 'age': '-5'}); print(bad.isValid); // false print(bad.expectationCount); // 3 print(bad.detailed()); ``` -------------------------------- ### Combine Validators with AND Combinator (& / all) Source: https://context7.com/nombrekeff/eskema/llms.txt Use the AND combinator (`all([...])` or `&`) to chain validators sequentially. The process stops at the first failure, and transformations are threaded through the chain. This example shows validating a positive integer and trimming/coercing a string quantity. ```dart // Function form final positiveInt = all([isInt(), isGt(0)]); // Operator sugar (identical semantics) final positiveIntOp = isInt() & isGt(0); print(positiveInt.isValid(5)); // true print(positiveInt.isValid(-1)); // false print(positiveInt.isValid('5')); // false — type mismatch stops chain // Transformations thread through: trim -> toInt -> gte final qty = isString() & trim() & toInt() & isGte(1); print(qty.isValid(' 3 ')); // true print(qty.isValid('zero')); // false ``` -------------------------------- ### Typical Flow with Shortcut Helpers Source: https://github.com/nombrekeff/eskema/wiki/Builder-API Demonstrates building validators using shortcut helpers for common types like strings, integers, and dates. Includes normalization and coercion steps. ```dart final ageValidator = $string() .trim() .toIntStrict() .gte(18) .build(); final emailValidator = $string() .trim() .toLowerCase() .email() .error('Invalid email') .build(); ``` -------------------------------- ### Build User Validator with Concise Form Source: https://github.com/nombrekeff/eskema/wiki/Builder-Pattern Illustrates the preferred concise form using shortcut helpers like `$map()` and `$string()` to build a user validator, offering a more streamlined syntax. ```dart final userValidatorB = $map().schema({ 'id': $string().trim().toIntStrict().gt(0).build(), 'email': $string().trim().toLowerCase().email().build(), }).build(); ``` -------------------------------- ### Implement Custom Validator Logic Source: https://github.com/nombrekeff/eskema/wiki/Guide-Custom-Validator Implement the core validation logic for a custom validator. This example checks if a string value is capitalized. ```dart IValidator isCapitalized() => validator( (value) => (value is String && value.isNotEmpty && value[0] == value[0].toUpperCase()) ? const Result.valid() : Result.invalid(expectation: codeCapitalized), expectation: codeCapitalized, ); ``` -------------------------------- ### Typical Flow with Explicit Root Builder Source: https://github.com/nombrekeff/eskema/wiki/Builder-API Shows an equivalent validator construction using the explicit root builder form, demonstrating its flexibility. ```dart final ageValidatorAlt = b().string().toIntStrict().gte(18).build(); ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/runner/CMakeLists.txt Applies a standard set of build settings to the application target. This can be removed if the application requires custom build configurations. ```cmake # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Async Custom Validator Example Source: https://github.com/nombrekeff/eskema/wiki/Validators Defines and uses an asynchronous validator to check for unique email addresses. Requires an external `checkIsUnique` function. ```dart IValidator isEmailUnique() => Validator((value) async { final emailIsUnique = await checkIsUnique(value); return emailIsUnique ? Result.valid(value) : Result.invalid(value, expectations: [Expectation(message: 'unique', value: value)]); }); Future asyncExample() async { final validEmail = isString() & email() & isEmailUnique(); final res = await validEmail.validateAsync('taken@example.com'); print(res.isValid); // false } ``` -------------------------------- ### Dynamic Requirements with `resolve` Source: https://github.com/nombrekeff/eskema/wiki/Contextual-Validators Dynamically apply validators based on other field values using `resolve`. This example makes `creditCardNumber` required only when `type` is 'credit_card'. ```dart final paymentSchema = eskema({ 'type': isString(), 'creditCardNumber': resolve((data) { if (data['type'] == 'credit_card') { return isString() & not(isEmpty); } return null; // No validation needed if not credit card }), }); ``` -------------------------------- ### Configure Cross-Building Root Path Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Sets up the sysroot and find root path for cross-compilation. This is used when building for a different architecture or environment. ```cmake if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() ``` -------------------------------- ### Apply Standard Build Settings in CMake Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/runner/CMakeLists.txt Applies a predefined set of build settings to the specified target. This can be removed if the application requires custom build configurations. ```cmake apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Link Libraries and Include Directories Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/runner/CMakeLists.txt Adds necessary dependency libraries (flutter, flutter_wrapper_app, dwmapi.lib) and include directories to the application target. Application-specific dependencies should also be added here. ```cmake # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Combining Validators with Transformers Source: https://github.com/nombrekeff/eskema/wiki/Type-Validators Chain transformers like toInt with validators such as isGte to create more specific validation rules. This example creates a validator for positive integers. ```dart final positiveInt = toInt(isGte(1)); ``` -------------------------------- ### Minimal Custom Validator Source: https://github.com/nombrekeff/eskema/wiki/Custom-Validators Defines a basic validator that checks if a string value starts with an uppercase letter. It returns a Result.valid() on success or Result.invalid() with a 'capitalized' expectation on failure. ```dart import 'package:eskema/eskema.dart'; IValidator isCapitalized() => validator( (value) { final ok = value is String && value.isNotEmpty && value[0] == value[0].toUpperCase(); return ok ? const Result.valid() : Result.invalid(expectation: Expectation(message: 'capitalized')); }, expectation: Expectation(message: 'capitalized'), ); ``` -------------------------------- ### Simpler Custom String Transformation with Extension Source: https://github.com/nombrekeff/eskema/wiki/Builder-API Demonstrates a simpler, string-only custom transformation using an extension method on `StringBuilder` to strip a hash prefix. ```dart extension Strip on StringBuilder { StringBuilder stripHashPrefix() => wrap((c) => Validator((v) { if (v is String && v.startsWith('#')) { return c.validate(v.substring(1)); } return c.validate(v); })); } final tagValidator = $string().stripHashPrefix().lengthMin(1).build(); ``` -------------------------------- ### Find and Check GTK+ 3.0 Package Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Finds the PkgConfig tool and checks for the GTK+ 3.0 library. This is required for GTK-based Flutter applications on Linux. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) ``` -------------------------------- ### Custom Transformer with `transform` Source: https://github.com/nombrekeff/eskema/wiki/Transformers Illustrates creating a custom transformer using the low-level `transform` function for bespoke coercions. Returns `null` on failure. ```dart IValidator toTrimmedNonEmpty() => transform((v) => v is String ? v.trim() : v, all([isString(), not($isStringEmpty)])); ``` -------------------------------- ### Enable Modern CMake Behaviors Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Explicitly opts into modern CMake behaviors to avoid warnings with recent CMake versions. This ensures better compatibility and future-proofing. ```cmake cmake_policy(SET CMP0063 NEW) ``` -------------------------------- ### Date Transformer: toDateTime Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers The `toDateTime` transformer attempts to parse input into a `DateTime` object, accepting standard DateTime objects and ISO-8601-like strings. It fails if the input cannot be parsed. ```dart final pastDate = toDateTime(isDateInPast()); print(pastDate.isValid('2020-01-01')); // true (assuming today later) print(pastDate.isValid('not-a-date')); // false ``` -------------------------------- ### Boolean Transformer: toBoolLenient Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers The `toBoolLenient` transformer is the most permissive, accepting a wide range of textual representations for true/false values, including 'yes', 'no', 'on', 'off', etc. ```dart final enabledLenient = toBoolLenient(isTrue()); print(enabledLenient.isValid('yes')); // true ``` -------------------------------- ### Number Transformer: toInt Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers The `toInt` transformer attempts to coerce input into an integer. It trims whitespace and truncates doubles. Use this when you need to ensure numeric input is an integer. ```dart final quantity = toInt(gte(1)); print(quantity.isValid('5')); // true print(quantity.isValid(' 7 ')); // true (trimmed) print(quantity.isValid('zero')); // false ``` -------------------------------- ### Transforming Data (Functional Style) Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Apply data transformations before validation using the functional style in Eskema. This example chains string trimming, integer conversion, and range checking. ```dart final v = isString() & trim() & toInt() & gte(0); final v = all([isString(), trim(), toInt(), gte(0)]); ``` -------------------------------- ### Define Application Binary and ID Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Sets the name of the executable and the unique GTK application identifier. These are crucial for application deployment and system integration. ```cmake set(BINARY_NAME "flutter_forms_example") set(APPLICATION_ID "com.example.flutter_forms_example") ``` -------------------------------- ### Use Conditional Validator for Tax ID Source: https://github.com/nombrekeff/eskema/wiki/Conditional-Validation Example of using the `conditional` validator to enforce a `taxId` field only for 'business' types. Ensure the `taxId` is a string with a minimum length of 5. ```dart final mustHaveTaxIdIfBusiness = conditional( eskema({'taxId': isString() & stringLength(min: 5)}), (m) => m is Map && m['type'] == 'business', ); ``` -------------------------------- ### Configure Flutter Tool Backend Custom Command Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/flutter/CMakeLists.txt Sets up a custom command to execute the Flutter tool backend script. This command is responsible for generating build artifacts like the Flutter library and headers. A phony output file is used to ensure the command runs on every build. ```cmake set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ${PHONY_OUTPUT} COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) ``` -------------------------------- ### Build User Validator with Full Form Source: https://github.com/nombrekeff/eskema/wiki/Builder-Pattern Demonstrates the full form of the builder pattern using the root `b()` helper to construct a validator for user data, including nested validators for 'id' and 'email'. ```dart final userValidatorA = b() .map() .schema({ 'id': b().string().trim().toIntStrict().gt(0).build(), 'email': b().string().trim().toLowerCase().email().build(), }) .build(); ``` -------------------------------- ### Optional vs Nullable Fields Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Demonstrates how to define optional and nullable fields in Eskema schemas using both functional and builder styles. Understand the behavior for missing keys, null values, and empty strings. ```dart final validator = eskema({ 'nickname': isString().optional(), // may be missing 'middle': isString().nullable(), // must exist; may be null 'bio': isString().nullable().optional() // either missing or null or string }); ``` -------------------------------- ### JSON Transformer: toJsonDecoded Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers The `toJsonDecoded` transformer parses a JSON string into a Dart Map or List, or accepts already decoded Maps/Lists. It is useful for validating structured JSON data. ```dart final payload = toJsonDecoded(eskema({'id': $isNonEmptyString})); print(payload.isValid('{"id":"x"}')); // true print(payload.isValid('{"id":""}')); // false ``` -------------------------------- ### Boolean Transformer: toBool Example Source: https://github.com/nombrekeff/eskema/wiki/Transformers The `toBool` transformer accepts various forms of boolean input. If you need to accept more lenient string representations like 'yes' or 'no', use `toBoolLenient`. ```dart final enabled = toBool(isTrue()); print(enabled.isValid('true')); // true print(enabled.isValid(1)); // true print(enabled.isValid('yes')); // false (needs lenient) ``` -------------------------------- ### Basic Validator Creation and Usage Source: https://github.com/nombrekeff/eskema/wiki/Validators Demonstrates creating basic validators for types and ranges, and composing them using AND and OR operators. Use this for simple type checking and conditional validation. ```dart import 'package:eskema/eskema.dart'; void basic() { final v1 = isString(); // checks type String final v2 = isInt() & gte(10); // AND (same as all([...])) final v3 = any([isBool(), isInt()]); // OR combinator print(v1.validate('hi').isValid); // true print(v2.validate(7).isValid); // false (gte fails) print(v3.validate(true).isValid); // true } ``` -------------------------------- ### Import Specific Eskema Modules Source: https://github.com/nombrekeff/eskema/wiki/Installation For better code clarity or to enable tree-shaking, import only the specific Eskema modules you need, such as validators, transformers, or the builder. ```dart import 'package:eskema/validators.dart'; ``` ```dart import 'package:eskema/transformers.dart'; ``` ```dart import 'package:eskema/builder.dart'; ``` -------------------------------- ### Define User Schema with Fluent Builder Source: https://github.com/nombrekeff/eskema/wiki/Home Use shortcut helpers like $map(), $string(), and $int() to define a schema with various constraints such as non-empty strings, email format, minimum age, and optional fields. The .build() method finalizes the schema definition. ```dart import 'package:eskema/eskema.dart'; // Prefer the shortcut helpers ($map, $string, $int, ...) for brevity. // You can still use b().string() etc. — both produce identical validators. final userSchema = $map().schema({ 'id': $string().not.empty().build(), 'email': $string().email().build(), 'age': $int().gte(18).optional().build(), // Kept one root form for contrast: 'nickname': b().string().lengthMax(30).optional().build(), }).build(); final input = { 'id': 'u_123', 'email': 'someone@example.com', 'age': 42, }; final result = userSchema.validate(input); // or validateAsync for mixed async chains if (result.isValid) { print('OK'); } else { print(result.detailed()); } ``` -------------------------------- ### Define Custom Expectation Code and Validator Source: https://github.com/nombrekeff/eskema/wiki/Guide-Extending-Expectation-Codes Define a constant for your custom expectation code and create a validator function that uses this code when an expectation is met. This example shows how to validate an email address. ```dart const codeEmailTaken = 'user.email_taken'; IValidator emailNotTaken(Future Function(String) exists) => validator( (value) async { if (value is! String) return Result.invalid(expectation: Expectation(message: 'email', code: 'type')); if (await exists(value)) { return Result.invalid(expectation: Expectation(message: 'email taken', code: codeEmailTaken)); } return const Result.valid(); }, expectation: Expectation(message: 'email taken', code: codeEmailTaken), ); ``` -------------------------------- ### Polymorphic Validation with `switchBy` Source: https://github.com/nombrekeff/eskema/wiki/Contextual-Validators Use `switchBy` for discriminated unions, selecting a specific schema based on a key's value. This example validates `taxId` for 'business' types and `name` for 'person' types. ```dart final schema = switchBy('type', { 'business': eskema({ 'taxId': required(isString()) & stringLength([isGte(5)]), }), 'person': eskema({ 'name': required(isString() & stringLength([isGte(5)])) , }), }); final result = schema.validate({'type': 'business', 'taxId': '123456789'}); print(result.isValid); // true ``` -------------------------------- ### First Success OR Validation Source: https://github.com/nombrekeff/eskema/wiki/Combinators Use 'any' to accept the first validator that succeeds. If all validators fail, their expectations are accumulated. ```dart final emailLocalOrNormal = any([ $isEmail, stringMatchesPattern(RegExp(r'^.+@localhost$')), ]); ``` -------------------------------- ### Schema Definition with Reusable Modules Source: https://github.com/nombrekeff/eskema/wiki/Builder-API Demonstrates building a complex map schema using reusable validator modules for individual fields, enhancing maintainability. ```dart final userSchema = $map().schema({ 'email': emailField(), 'age': $string().toIntStrict().gte(18).build(), }).build(); ``` -------------------------------- ### Add Eskema Dependency to pubspec.yaml Source: https://github.com/nombrekeff/eskema/wiki/Installation Add this to your `pubspec.yaml` file to include Eskema as a project dependency. Ensure you use the latest compatible version. ```yaml dependencies: eskema: ^0.x.x ``` -------------------------------- ### Builder Style Form Validation Source: https://github.com/nombrekeff/eskema/wiki/Example-Simple-Form Defines a validator for a user registration form using the builder pattern. It validates email, password, and an optional age field. Use this for complex validation setups. ```dart final registerValidator = v().map().schema({ 'email': v().string().trim().toLowerCase().email().build(), 'password': v().string().lengthMin(8).lengthMax(64).build(), 'age': v().string().toIntStrict().gte(13).optional().build(), }).build(); final result = registerValidator.validate({ 'email': ' USER@Example.com ', 'password': 'Secr3tPass', 'age': '15', }); if (result.isValid) { print('ok'); } else { print(result.detailed()); } ``` -------------------------------- ### Creating Non-Empty String Validator Source: https://github.com/nombrekeff/eskema/wiki/Presence-Validators Demonstrates how to create a validator for non-empty strings by combining the string validator with a negation of the empty string validator. A convenience constant is also provided. ```dart final name = $isString & not(isStringEmpty()); // builder equivalent final nameB = v().string().not.empty().build(); ``` -------------------------------- ### Reusable Parameterized Validator Source: https://github.com/nombrekeff/eskema/wiki/Custom-Validators Creates a validator factory that generates validators checking if a string starts with a specified prefix. It returns an invalid result with a specific expectation message including the prefix if the condition is not met. ```dart IValidator matchesPrefix(String prefix) => validator( (value) => (value is String && value.startsWith(prefix)) ? const Result.valid() : Result.invalid(expectation: Expectation(message: 'prefix:$prefix')), expectation: Expectation(message: 'prefix:$prefix'), ); ``` -------------------------------- ### Add Include Directories in CMake Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/runner/CMakeLists.txt Specifies include directories for the application target, allowing it to find header files. ```cmake target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Include Flutter Managed Directory Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Loads bundled libraries and build rules from the Flutter managed directory. This is essential for integrating Flutter's build system. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) ``` -------------------------------- ### Validate Uniform List Elements with listEach Source: https://context7.com/nombrekeff/eskema/llms.txt Apply a single validator to all elements in a list using `listEach(v)`. This example demonstrates validating a list of non-empty strings and a list of non-negative integers, including type coercion. ```dart final tags = $isList & listEach($isNonEmptyString); print(tags.isValid(['dart', 'validation'])); // true print(tags.isValid(['dart', ''])); // false — [1]: not non-empty string final prices = listEach(toInt(isGte(0))); print(prices.isValid(['5', '0', '12'])); // true (each coerced from string) print(prices.isValid(['5', '-1', '12'])); // false — [1]: less than 0 ``` -------------------------------- ### Import Eskema Umbrella Package Source: https://github.com/nombrekeff/eskema/wiki/Installation Use this import statement for a single, convenient way to access all Eskema functionalities, including validators, transformers, and the builder. ```dart import 'package:eskema/eskema.dart'; ``` -------------------------------- ### Define and Use Positional List Validator Source: https://context7.com/nombrekeff/eskema/llms.txt Validate a fixed-length list where each element's type and constraints are defined by its position using `eskemaList([...])`. This example shows validation for a list expecting a string followed by an integer. ```dart final pair = eskemaList([$isString, $isInt]); print(pair.isValid(['hello', 42])); // true print(pair.isValid(['hello', 'x'])); // false — second element not an int print(pair.isValid([1, 2])); // false — first element not a string ``` -------------------------------- ### Define Executable Target and Source Files Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/runner/CMakeLists.txt Defines the main executable target for the Windows runner and lists all the source files required for the application. Ensure any new source files are added here. The executable name is controlled by BINARY_NAME, which should be managed in the top-level CMakeLists.txt to ensure `flutter run` compatibility. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) ``` -------------------------------- ### Set Runtime Search Path for Libraries Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Configures the runtime search path for libraries to be relative to the binary. This is important for creating relocatable application bundles. ```cmake set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") ``` -------------------------------- ### Set Runtime Output Directory for Executable Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Configures the executable to be placed in a specific subdirectory within the build directory. This is done to prevent users from running the unbundled copy. ```cmake set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Define List Prepend Function (CMake) Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/flutter/CMakeLists.txt This custom CMake function prepends a prefix to each element in a list. It's used as a workaround for older CMake versions that lack the list(TRANSFORM ... PREPEND ...) command. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Add Eskema Dependency Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Add the Eskema dependency to your pubspec.yaml file to include it in your project. ```bash $ dart pub add eskema ``` ```yaml dependencies: eskema: ^ ``` -------------------------------- ### Same Schema (Builder Style) Source: https://github.com/nombrekeff/eskema/wiki/Getting-Started Define the same user schema using Eskema's builder style. This approach is useful for complex schemas or when sharing configurations. ```dart final userEskema = v().map().schema({ 'id': v().string().not.empty().build(), 'email': v().string().email().build(), 'age': v().int_().gte(18).optional().build(), }).build(); final result = userSchema.isValid({ 'id': 'u_1', 'email': 'alice@example.com', 'age': 34, }); ``` -------------------------------- ### Create a Percentage Validator Source: https://github.com/nombrekeff/eskema/wiki/Number-Validators Use `toInt` to ensure the input is an integer and `isInRange` to validate it's between 0 and 100. ```dart final percent = toInt(isInRange(0, 100)); ``` -------------------------------- ### Dart: Schema with Optional List Field Source: https://github.com/nombrekeff/eskema/wiki/Map-and-List-Validators Demonstrates building a schema with an optional list field where each element must be a non-empty string. ```dart final config = v().map().schema({ 'roles': v().list().each($isNonEmptyString).optional().build(), }).build(); ``` -------------------------------- ### Validate User Schema and Print Expectations Source: https://github.com/nombrekeff/eskema/wiki/Error-Messages-and-Expectations Defines a user schema with required and optional fields, then validates a user object. It prints the total number of expectations and iterates through them to display their descriptions. ```dart final user = eskema({ 'id': $isNonEmptyString, 'age': optional(toInt(isInRange(0,120))), }); final res = user.validate({'id':'','age':'999'}); print(res.expectationCount); // 2 for (final e in res.expectations) { print(e.description); } // .id: lowercase string & not empty (example message) // .age: between 0 and 120 inclusive ``` -------------------------------- ### Define Flutter C++ Wrapper for Plugins Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/flutter/CMakeLists.txt Builds a static library for the C++ wrapper used by Flutter plugins. It includes core and plugin-specific source files and links against the Flutter library. ```cmake list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") # Wrapper sources needed for a plugin. add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) ``` -------------------------------- ### Optional vs Nullable Field Definitions Source: https://github.com/nombrekeff/eskema/wiki/Validators Illustrates the difference between `optional` (missing is valid, null is invalid) and `nullable` (missing is invalid, null is valid) validators. Use this to precisely control field presence and nullability. ```dart final schema = eskema({ 'maybe': optional($isString), // missing => valid, null => invalid 'maybeNull': nullable($isString), // missing => invalid, null => valid 'either': optional(nullable($isString)), // missing OR null => valid }); ``` -------------------------------- ### Set Flutter Library and Headers Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/windows/flutter/CMakeLists.txt Defines the Flutter library DLL and its associated header files, making them available for linking and inclusion in the build. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") ``` -------------------------------- ### Apply Standard Compilation Settings Source: https://github.com/nombrekeff/eskema/blob/main/example/flutter_forms_example/linux/CMakeLists.txt Defines a function to apply common compilation settings to targets. This includes C++ standard, warning levels, optimization, and NDEBUG definition. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "<$>:NDEBUG>") endfunction() ``` -------------------------------- ### Sequential AND Validation with Transformations Source: https://github.com/nombrekeff/eskema/wiki/Combinators Use 'all' to ensure every validator in a sequence succeeds. Transformations from earlier validators are passed to later ones. Handles async validators sequentially. ```dart final normalized = all([ toString(), // ensures value is a String stringMatchesPattern(RegExp(r'^user_')), // pattern check ]); ```