From 5e97b6dcbc904df050e0578d4bcbbf92690b079f Mon Sep 17 00:00:00 2001 From: gcch Date: Mon, 13 Apr 2026 11:45:00 +0200 Subject: [PATCH 1/7] fonc: travail en cours sur scripts page Produit --- .php-cs-fixer.dist.php | 498 +++++++++--------- bun.lock | 24 +- composer.lock | 118 ++++- config/application.php | 34 +- package.json | 8 +- scripts/remove-scaled-images.php | 40 +- web/app/themes/haiku-atelier-2024/404.php | 11 +- .../themes/haiku-atelier-2024/front-page.php | 16 +- .../themes/haiku-atelier-2024/page-about.php | 18 +- .../haiku-atelier-2024/page-checkout.php | 156 +++--- .../haiku-atelier-2024/page-failed-order.php | 8 +- .../page-terms-and-conditions.php | 8 +- .../src/inc/ChampsPersonnalises.php | 57 +- .../src/inc/ControlesPersonnalises.php | 97 ++-- .../haiku-atelier-2024/src/inc/Data/Cart.php | 207 ++++---- .../src/inc/Data/ProductVariation.php | 54 +- .../inc/Data/ProductVariationAttribute.php | 19 +- .../src/inc/Fonctionnalites.php | 43 +- .../haiku-atelier-2024/src/inc/Taxonomies.php | 51 +- .../haiku-atelier-2024/src/inc/WP/Post.php | 68 ++- .../src/scripts-effect/schemas/api.ts | 10 + .../src/scripts-effect/schemas/product.ts | 20 + .../src/scripts/page-produit/runtime.ts | 13 + .../service-dom.ts} | 227 ++++---- .../scripts/page-produit/service-elements.ts | 70 +++ .../src/scripts/page-produit/types.d.ts | 6 + .../src/scripts/scripts-page-produit.ts | 57 +- .../emails/customer-completed-order.php | 16 +- .../woocommerce/emails/customer-invoice.php | 79 ++- .../emails/customer-processing-order.php | 71 ++- 30 files changed, 1110 insertions(+), 994 deletions(-) create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts rename web/app/themes/haiku-atelier-2024/src/scripts/{scripts-page-produit-service.ts => page-produit/service-dom.ts} (52%) create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 7211fb82..80e9eb2d 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -7,257 +7,253 @@ use PhpCsFixer\Finder; use PhpCsFixer\Runner; $finder = new Finder()->in(__DIR__)->exclude([ - 'vendor', - 'web/vendor', - 'web/wp', - 'web/app/languages', - 'web/app/plugins', - 'web/app/mu-plugins', + 'vendor', + 'web/vendor', + 'web/wp', + 'web/app/languages', + 'web/app/plugins', + 'web/app/mu-plugins', ]); return new Config() - ->setRiskyAllowed(true) - ->setRules([ - 'array_syntax' => ['syntax' => 'short'], - 'assign_null_coalescing_to_coalesce_equal' => true, - 'attribute_empty_parentheses' => ['use_parentheses' => true], - 'blank_line_after_namespace' => true, - 'blank_lines_before_namespace' => ['min_line_breaks' => 1, 'max_line_breaks' => 2], - 'cast_spaces' => true, - 'class_attributes_separation' => ['elements' => [ - 'case' => 'none', - 'const' => 'none', - 'method' => 'one', - 'property' => 'one', - 'trait_import' => 'none', - ]], - 'class_reference_name_casing' => true, - 'clean_namespace' => true, - 'combine_consecutive_issets' => true, - 'combine_consecutive_unsets' => true, - 'combine_nested_dirname' => true, - 'comment_to_phpdoc' => true, - 'constant_case' => true, - 'date_time_immutable' => true, - 'declare_equal_normalize' => true, - 'declare_parentheses' => true, - 'declare_strict_types' => true, - 'dir_constant' => true, - 'echo_tag_syntax' => true, - 'encoding' => true, - 'ereg_to_preg' => true, - 'error_suppression' => true, - 'explicit_indirect_variable' => true, - 'explicit_string_variable' => true, - 'final_class' => true, - 'final_internal_class' => true, - 'full_opening_tag' => true, - 'fully_qualified_strict_types' => ['import_symbols' => true], - 'function_to_constant' => true, - 'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true], - 'heredoc_to_nowdoc' => true, - 'integer_literal_case' => true, - 'lambda_not_used_import' => true, - 'list_syntax' => true, - 'logical_operators' => true, - 'long_to_shorthand_operator' => true, - 'lowercase_cast' => true, - 'lowercase_keywords' => true, - 'lowercase_static_reference' => true, - 'magic_constant_casing' => true, - 'magic_method_casing' => true, - 'mb_str_functions' => true, - 'modernize_strpos' => ['modernize_stripos' => true], - 'modernize_types_casting' => true, - 'modifier_keywords' => true, - 'multiline_comment_opening_closing' => true, - 'native_constant_invocation' => true, - 'native_function_casing' => true, - 'native_function_invocation' => [ - 'include' => ['@compiler_optimized'], - 'scope' => 'namespaced', - 'strict' => true, - ], - 'native_type_declaration_casing' => true, - 'new_expression_parentheses' => true, - 'no_alias_functions' => ['sets' => ['@all']], - 'no_alias_language_construct_call' => true, - 'no_alternative_syntax' => true, - 'no_binary_string' => true, - 'no_closing_tag' => true, - 'no_empty_comment' => true, - 'no_homoglyph_names' => true, - 'no_leading_import_slash' => true, - 'no_mixed_echo_print' => ['use' => 'echo'], - 'no_multiline_whitespace_around_double_arrow' => true, - 'no_multiple_statements_per_line' => true, - 'no_null_property_initialization' => true, - 'no_php4_constructor' => true, - 'no_short_bool_cast' => true, - 'no_trailing_comma_in_singleline' => true, - 'no_trailing_whitespace_in_comment' => true, - 'no_unneeded_braces' => ['namespaces' => true], - 'no_unneeded_control_parentheses' => ['statements' => [ - 'break', - 'clone', - 'continue', - 'echo_print', - 'negative_instanceof', - 'others', - 'return', - 'switch_case', - 'yield', - 'yield_from', - ]], - 'no_unneeded_final_method' => true, - 'no_unneeded_import_alias' => true, - 'no_unreachable_default_argument_value' => true, - 'no_unset_cast' => true, - 'no_unset_on_property' => true, - 'no_unused_imports' => true, - 'no_useless_concat_operator' => true, - 'no_useless_nullsafe_operator' => true, - 'no_useless_printf' => true, - 'no_useless_return' => true, - 'no_useless_sprintf' => true, - 'no_whitespace_before_comma_in_array' => ['after_heredoc' => true], - 'non_printable_character' => true, - 'normalize_index_brace' => true, - 'nullable_type_declaration' => ['syntax' => 'union'], - 'nullable_type_declaration_for_default_null_value' => true, - 'numeric_literal_separator' => ['override_existing' => true, 'strategy' => 'use_separator'], - 'ordered_attributes' => true, - 'ordered_class_elements' => ['case_sensitive' => false, 'sort_algorithm' => 'alpha'], - 'ordered_imports' => ['case_sensitive' => true], - 'ordered_interfaces' => true, - 'ordered_traits' => true, - 'ordered_types' => ['null_adjustment' => 'always_last'], - 'phpdoc_readonly_class_comment_to_keyword' => true, - 'phpdoc_to_param_type' => true, - 'phpdoc_to_property_type' => true, - 'phpdoc_to_return_type' => true, - 'pow_to_exponentiation' => true, - 'protected_to_private' => true, - 'psr_autoloading' => true, - 'random_api_migration' => ['replacements' => [ - 'getrandmax' => 'mt_getrandmax', - 'rand' => 'mt_rand', - 'srand' => 'mt_srand', - ]], - 'return_assignment' => true, - 'self_accessor' => true, - 'self_static_accessor' => true, - 'set_type_to_cast' => true, - 'short_scalar_cast' => true, - 'simple_to_complex_string_variable' => true, - 'simplified_null_return' => true, - 'single_class_element_per_statement' => true, - 'single_import_per_statement' => true, - 'single_line_after_imports' => true, - 'single_line_comment_spacing' => true, - 'single_line_comment_style' => true, - 'single_line_empty_body' => true, - 'single_trait_insert_per_statement' => true, - 'standardize_not_equals' => true, - 'static_lambda' => true, - 'strict_comparison' => true, - 'strict_param' => true, - 'string_implicit_backslashes' => true, - 'string_length_to_empty' => true, - 'switch_continue_to_break' => true, - 'ternary_to_null_coalescing' => true, - 'trim_array_spaces' => true, - 'use_arrow_functions' => true, - 'void_return' => true, - 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], - // --- - // Each line of multi-line DocComments must have an asterisk [PSR-5] and must be aligned with the first one. - 'align_multiline_comment' => ['comment_type' => 'all_multiline'], - // There should not be blank lines between docblock and the documented element. - 'no_blank_lines_after_phpdoc' => true, - // There should not be empty PHPDoc blocks. - 'no_empty_phpdoc' => true, - // Removes @param, @return and @var tags that don't provide any useful information. - 'no_superfluous_phpdoc_tags' => [ - 'allow_hidden_params' => false, - 'allow_mixed' => false, - 'allow_unused_params' => false, - ], - // PHPDoc should contain @param for all params. - 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], - // All items of the given PHPDoc tags must be either left-aligned or (by default) aligned vertically. - 'phpdoc_align' => true, - // PHPDoc annotation descriptions should not be a sentence. - 'phpdoc_annotation_without_dot' => true, - // PHPDoc array type must be used instead of T[]. - 'phpdoc_array_type' => true, - // Docblocks should have the same indentation as the documented subject. - 'phpdoc_indent' => true, - // Fixes PHPDoc inline tags. - 'phpdoc_inline_tag_normalizer' => true, - // Changes doc blocks from single to multi line, or reversed. Works for class constants, properties and methods only. - 'phpdoc_line_span' => ['const' => 'single', 'method' => 'multi', 'property' => 'single'], - // PHPDoc list type must be used instead of array without a key. - 'phpdoc_list_type' => false, - // @access annotations must be removed from PHPDoc. - 'phpdoc_no_access' => true, - // No alias PHPDoc tags should be used. - 'phpdoc_no_alias_tag' => true, - // @return void and @return null annotations must be removed from PHPDoc. - 'phpdoc_no_empty_return' => false, - // @package and @subpackage annotations must be removed from PHPDoc. - 'phpdoc_no_package' => true, - // Classy that does not inherit must not have @inheritdoc tags. - 'phpdoc_no_useless_inheritdoc' => true, - // Annotations in PHPDoc should be ordered in defined sequence. - 'phpdoc_order' => true, - // Order PHPDoc tags by value. - 'phpdoc_order_by_value' => true, - // Orders all @param annotations in DocBlocks according to method signature. - 'phpdoc_param_order' => true, - // The type of @return annotations of methods returning a reference to itself must the configured one. - 'phpdoc_return_self_reference' => true, - // Scalar types should always be written in the same form. int not integer, bool not boolean, float not real or double. - 'phpdoc_scalar' => ['types' => [ - 'boolean', - 'callback', - 'double', - 'integer', - 'never-return', - 'never-returns', - 'no-return', - 'real', - 'str', - ]], - // Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other. Annotations of a different type are separated by a single blank line. - 'phpdoc_separation' => [ - 'groups' => [ - ['Annotation', 'NamedArgumentConstructor', 'Target'], - ['author', 'copyright', 'license'], - ['category', 'package', 'subpackage'], - ['property', 'property-read', 'property-write'], - ['deprecated', 'link', 'see', 'since'], - ], - 'skip_unlisted_annotations' => false, - ], - // Single line @var PHPDoc should have proper spacing. - 'phpdoc_single_line_var_spacing' => true, - // PHPDoc summary should end in either a full stop, exclamation mark, or question mark. - 'phpdoc_summary' => true, - // Docblocks should only be used on structural elements. - 'phpdoc_to_comment' => false, - // PHPDoc should start and end with content, excluding the very first and last line of the docblocks. - 'phpdoc_trim' => true, - // Removes extra blank lines after summary and after description in PHPDoc. - 'phpdoc_trim_consecutive_blank_line_separation' => true, - // The correct case must be used for standard PHP types in PHPDoc. - 'phpdoc_types' => true, - // Sorts PHPDoc types. - 'phpdoc_types_order' => ['null_adjustment' => 'always_last'], - // @var and @type annotations must have type and name in the correct order. - 'phpdoc_var_annotation_correct_order' => true, - // @var and @type annotations of classy properties should not contain the name. - 'phpdoc_var_without_name' => true, - ]) - ->setFinder($finder) - ->setParallelConfig(Runner\Parallel\ParallelConfigFactory::detect()); + ->setRiskyAllowed(true) + ->setRules([ + 'array_syntax' => ['syntax' => 'short'], + 'assign_null_coalescing_to_coalesce_equal' => true, + 'attribute_empty_parentheses' => ['use_parentheses' => true], + 'blank_line_after_namespace' => true, + 'blank_lines_before_namespace' => ['min_line_breaks' => 1, 'max_line_breaks' => 2], + 'cast_spaces' => true, + 'class_attributes_separation' => ['elements' => [ + 'case' => 'none', + 'const' => 'none', + 'method' => 'one', + 'property' => 'one', + 'trait_import' => 'none', + ]], + 'class_reference_name_casing' => true, + 'clean_namespace' => true, + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'combine_nested_dirname' => true, + 'comment_to_phpdoc' => true, + 'constant_case' => true, + 'date_time_immutable' => true, + 'declare_equal_normalize' => true, + 'declare_parentheses' => true, + 'declare_strict_types' => true, + 'dir_constant' => true, + 'echo_tag_syntax' => true, + 'encoding' => true, + 'ereg_to_preg' => true, + 'error_suppression' => true, + 'explicit_indirect_variable' => true, + 'explicit_string_variable' => true, + 'final_class' => true, + 'final_internal_class' => true, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => ['import_symbols' => true], + 'function_to_constant' => true, + 'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true], + 'heredoc_to_nowdoc' => true, + 'integer_literal_case' => true, + 'lambda_not_used_import' => true, + 'list_syntax' => true, + 'logical_operators' => true, + 'long_to_shorthand_operator' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'mb_str_functions' => true, + 'modernize_strpos' => ['modernize_stripos' => true], + 'modernize_types_casting' => true, + 'modifier_keywords' => true, + 'multiline_comment_opening_closing' => true, + 'native_constant_invocation' => true, + 'native_function_casing' => true, + 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'namespaced', 'strict' => true], + 'native_type_declaration_casing' => true, + 'new_expression_parentheses' => true, + 'no_alias_functions' => ['sets' => ['@all']], + 'no_alias_language_construct_call' => true, + 'no_alternative_syntax' => true, + 'no_binary_string' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_mixed_echo_print' => ['use' => 'echo'], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_multiple_statements_per_line' => true, + 'no_null_property_initialization' => true, + 'no_php4_constructor' => true, + 'no_short_bool_cast' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unneeded_braces' => ['namespaces' => true], + 'no_unneeded_control_parentheses' => ['statements' => [ + 'break', + 'clone', + 'continue', + 'echo_print', + 'negative_instanceof', + 'others', + 'return', + 'switch_case', + 'yield', + 'yield_from', + ]], + 'no_unneeded_final_method' => true, + 'no_unneeded_import_alias' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unset_cast' => true, + 'no_unset_on_property' => true, + 'no_unused_imports' => true, + 'no_useless_concat_operator' => true, + 'no_useless_nullsafe_operator' => true, + 'no_useless_printf' => true, + 'no_useless_return' => true, + 'no_useless_sprintf' => true, + 'no_whitespace_before_comma_in_array' => ['after_heredoc' => true], + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'nullable_type_declaration' => ['syntax' => 'union'], + 'nullable_type_declaration_for_default_null_value' => true, + 'numeric_literal_separator' => ['override_existing' => true, 'strategy' => 'use_separator'], + 'ordered_attributes' => true, + 'ordered_class_elements' => ['case_sensitive' => false, 'sort_algorithm' => 'alpha'], + 'ordered_imports' => ['case_sensitive' => true], + 'ordered_interfaces' => true, + 'ordered_traits' => true, + 'ordered_types' => ['null_adjustment' => 'always_last'], + 'phpdoc_readonly_class_comment_to_keyword' => true, + 'phpdoc_to_param_type' => true, + 'phpdoc_to_property_type' => true, + 'phpdoc_to_return_type' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'psr_autoloading' => true, + 'random_api_migration' => ['replacements' => [ + 'getrandmax' => 'mt_getrandmax', + 'rand' => 'mt_rand', + 'srand' => 'mt_srand', + ]], + 'return_assignment' => true, + 'self_accessor' => true, + 'self_static_accessor' => true, + 'set_type_to_cast' => true, + 'short_scalar_cast' => true, + 'simple_to_complex_string_variable' => true, + 'simplified_null_return' => true, + 'single_class_element_per_statement' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_line_comment_spacing' => true, + 'single_line_comment_style' => true, + 'single_line_empty_body' => true, + 'single_trait_insert_per_statement' => true, + 'standardize_not_equals' => true, + 'static_lambda' => true, + 'strict_comparison' => true, + 'strict_param' => true, + 'string_implicit_backslashes' => true, + 'string_length_to_empty' => true, + 'switch_continue_to_break' => true, + 'ternary_to_null_coalescing' => true, + 'trim_array_spaces' => true, + 'use_arrow_functions' => true, + 'void_return' => true, + 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], + // --- + // Each line of multi-line DocComments must have an asterisk [PSR-5] and must be aligned with the first one. + 'align_multiline_comment' => ['comment_type' => 'all_multiline'], + // There should not be blank lines between docblock and the documented element. + 'no_blank_lines_after_phpdoc' => true, + // There should not be empty PHPDoc blocks. + 'no_empty_phpdoc' => true, + // Removes @param, @return and @var tags that don't provide any useful information. + 'no_superfluous_phpdoc_tags' => [ + 'allow_hidden_params' => false, + 'allow_mixed' => false, + 'allow_unused_params' => false, + ], + // PHPDoc should contain @param for all params. + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], + // All items of the given PHPDoc tags must be either left-aligned or (by default) aligned vertically. + 'phpdoc_align' => true, + // PHPDoc annotation descriptions should not be a sentence. + 'phpdoc_annotation_without_dot' => true, + // PHPDoc array type must be used instead of T[]. + 'phpdoc_array_type' => true, + // Docblocks should have the same indentation as the documented subject. + 'phpdoc_indent' => true, + // Fixes PHPDoc inline tags. + 'phpdoc_inline_tag_normalizer' => true, + // Changes doc blocks from single to multi line, or reversed. Works for class constants, properties and methods only. + 'phpdoc_line_span' => ['const' => 'single', 'method' => 'multi', 'property' => 'single'], + // PHPDoc list type must be used instead of array without a key. + 'phpdoc_list_type' => false, + // @access annotations must be removed from PHPDoc. + 'phpdoc_no_access' => true, + // No alias PHPDoc tags should be used. + 'phpdoc_no_alias_tag' => true, + // @return void and @return null annotations must be removed from PHPDoc. + 'phpdoc_no_empty_return' => false, + // @package and @subpackage annotations must be removed from PHPDoc. + 'phpdoc_no_package' => true, + // Classy that does not inherit must not have @inheritdoc tags. + 'phpdoc_no_useless_inheritdoc' => true, + // Annotations in PHPDoc should be ordered in defined sequence. + 'phpdoc_order' => true, + // Order PHPDoc tags by value. + 'phpdoc_order_by_value' => true, + // Orders all @param annotations in DocBlocks according to method signature. + 'phpdoc_param_order' => true, + // The type of @return annotations of methods returning a reference to itself must the configured one. + 'phpdoc_return_self_reference' => true, + // Scalar types should always be written in the same form. int not integer, bool not boolean, float not real or double. + 'phpdoc_scalar' => ['types' => [ + 'boolean', + 'callback', + 'double', + 'integer', + 'never-return', + 'never-returns', + 'no-return', + 'real', + 'str', + ]], + // Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other. Annotations of a different type are separated by a single blank line. + 'phpdoc_separation' => [ + 'groups' => [ + ['Annotation', 'NamedArgumentConstructor', 'Target'], + ['author', 'copyright', 'license'], + ['category', 'package', 'subpackage'], + ['property', 'property-read', 'property-write'], + ['deprecated', 'link', 'see', 'since'], + ], + 'skip_unlisted_annotations' => false, + ], + // Single line @var PHPDoc should have proper spacing. + 'phpdoc_single_line_var_spacing' => true, + // PHPDoc summary should end in either a full stop, exclamation mark, or question mark. + 'phpdoc_summary' => true, + // Docblocks should only be used on structural elements. + 'phpdoc_to_comment' => false, + // PHPDoc should start and end with content, excluding the very first and last line of the docblocks. + 'phpdoc_trim' => true, + // Removes extra blank lines after summary and after description in PHPDoc. + 'phpdoc_trim_consecutive_blank_line_separation' => true, + // The correct case must be used for standard PHP types in PHPDoc. + 'phpdoc_types' => true, + // Sorts PHPDoc types. + 'phpdoc_types_order' => ['null_adjustment' => 'always_last'], + // @var and @type annotations must have type and name in the correct order. + 'phpdoc_var_annotation_correct_order' => true, + // @var and @type annotations of classy properties should not contain the name. + 'phpdoc_var_without_name' => true, + ]) + ->setFinder($finder) + ->setParallelConfig(Runner\Parallel\ParallelConfigFactory::detect()); diff --git a/bun.lock b/bun.lock index 91e07de0..18fe1f35 100644 --- a/bun.lock +++ b/bun.lock @@ -8,7 +8,7 @@ "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", "a11y-dialog": "^8.1.5", - "effect": "^4.0.0-beta.46", + "effect": "^4.0.0-beta.48", "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", @@ -34,9 +34,9 @@ "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "fdir": "^6.5.0", - "globals": "^17.4.0", + "globals": "^17.5.0", "jiti": "^2.6.1", - "knip": "^6.3.1", + "knip": "^6.4.1", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", "oxlint": "^1.59.0", @@ -46,7 +46,7 @@ "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.1", "sass-embedded": "^1.99.0", - "stylelint": "^17.6.0", + "stylelint": "^17.7.0", "stylelint-config-clean-order": "^8.0.1", "stylelint-config-sass-guidelines": "^13.0.0", "stylelint-config-standard-scss": "^17.0.0", @@ -796,7 +796,7 @@ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], - "effect": ["effect@4.0.0-beta.46", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.5.3", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.8", "multipasta": "^0.2.7", "toml": "^3.0.0", "uuid": "^13.0.0", "yaml": "^2.8.2" } }, "sha512-3f6gXvvUMtEueCRY0tU76Vq2Pej1SAwwE+s0Owd5nD53yS5n4RZhUA1rlCGFuSbQFA225pGy8vO72+lpvu7u5A=="], + "effect": ["effect@4.0.0-beta.48", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw=="], "electron-to-chromium": ["electron-to-chromium@1.5.334", "", {}, "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog=="], @@ -930,7 +930,7 @@ "global-prefix": ["global-prefix@3.0.0", "", { "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" } }, "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg=="], - "globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + "globals": ["globals@17.5.0", "", {}, "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g=="], "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], @@ -1076,7 +1076,7 @@ "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], - "knip": ["knip@6.3.1", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-22kLJloVcOVOAudCxlFOC0ICAMme7dKsS7pVTEnrmyKGpswb8ieznvAiSKUeFVDJhb01ect6dkDc1Ha1g1sPpg=="], + "knip": ["knip@6.4.1", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-Ry+ywmDFSZvKp/jx7LxMgsZWRTs931alV84e60lh0Stf6kSRYqSIUTkviyyDFRcSO3yY1Kpbi83OirN+4lA2Xw=="], "known-css-properties": ["known-css-properties@0.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="], @@ -1484,7 +1484,7 @@ "style-search": ["style-search@0.1.0", "", {}, "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg=="], - "stylelint": ["stylelint@17.6.0", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-syntax-patches-for-csstree": "^1.1.1", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0", "@csstools/selector-resolve-nested": "^4.0.0", "@csstools/selector-specificity": "^6.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.1", "css-functions-list": "^3.3.3", "css-tree": "^3.2.1", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^11.1.2", "global-modules": "^2.0.0", "globby": "^16.1.1", "globjoin": "^0.1.4", "html-tags": "^5.1.0", "ignore": "^7.0.5", "import-meta-resolve": "^4.2.0", "is-plain-object": "^5.0.0", "mathml-tag-names": "^4.0.0", "meow": "^14.1.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.8", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", "string-width": "^8.2.0", "supports-hyperlinks": "^4.4.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^7.0.1" }, "bin": { "stylelint": "bin/stylelint.mjs" } }, "sha512-tokrsMIVAR9vAQ/q3UVEr7S0dGXCi7zkCezPRnS2kqPUulvUh5Vgfwngrk4EoAoW7wnrThqTdnTFN5Ra7CaxIg=="], + "stylelint": ["stylelint@17.7.0", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-syntax-patches-for-csstree": "^1.1.2", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0", "@csstools/selector-resolve-nested": "^4.0.0", "@csstools/selector-specificity": "^6.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.1", "css-functions-list": "^3.3.3", "css-tree": "^3.2.1", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^11.1.2", "global-modules": "^2.0.0", "globby": "^16.2.0", "globjoin": "^0.1.4", "html-tags": "^5.1.0", "ignore": "^7.0.5", "import-meta-resolve": "^4.2.0", "is-plain-object": "^5.0.0", "mathml-tag-names": "^4.0.0", "meow": "^14.1.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.8", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", "string-width": "^8.2.0", "supports-hyperlinks": "^4.4.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^7.0.1" }, "bin": { "stylelint": "bin/stylelint.mjs" } }, "sha512-n/+4RheCRl+cecGnF+S/Adz59iCRaK9BVznJYB+a7GOksfwNzjiOPnYv17pTO0HgRse9IiqbMtekGNhOb2tVYQ=="], "stylelint-config-clean-order": ["stylelint-config-clean-order@8.0.1", "", { "peerDependencies": { "stylelint": ">=16", "stylelint-order": ">=6" } }, "sha512-zKjp7BiINXRZOG9m0fE/6UKoM6clPekL+LoAiHMCiQU2hgirKL5G0mKc5Z0ygIhQXfb1+DTRDM0mu6Ecdv4q8g=="], @@ -1532,7 +1532,7 @@ "to-valid-identifier": ["to-valid-identifier@1.0.0", "", { "dependencies": { "@sindresorhus/base62": "^1.0.0", "reserved-identifiers": "^1.0.0" } }, "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw=="], - "toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="], + "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], @@ -1632,6 +1632,10 @@ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "@gcch/configuration-eslint/globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + + "@gcch/configuration-oxlint/globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + "@keyv/bigmap/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -1656,6 +1660,8 @@ "eslint-plugin-jsx-a11y/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "eslint-plugin-sonarjs/globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + "eslint-plugin-unicorn/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], diff --git a/composer.lock b/composer.lock index 9a85f36f..745e769e 100644 --- a/composer.lock +++ b/composer.lock @@ -3629,15 +3629,15 @@ }, { "name": "wpackagist-plugin/query-monitor", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "svn", "url": "https://plugins.svn.wordpress.org/query-monitor/", - "reference": "tags/4.0.5" + "reference": "tags/4.0.6" }, "dist": { "type": "zip", - "url": "https://downloads.wordpress.org/plugin/query-monitor.4.0.5.zip" + "url": "https://downloads.wordpress.org/plugin/query-monitor.4.0.6.zip" }, "require": { "composer/installers": "^1.0 || ^2.0" @@ -4077,6 +4077,75 @@ ], "time": "2024-05-06T16:37:16+00:00" }, + { + "name": "ergebnis/agent-detector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/agent-detector.git", + "reference": "5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/agent-detector/zipball/5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64", + "reference": "5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64", + "shasum": "" + }, + "require": { + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.50.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.16.0", + "fakerphp/faker": "^1.24.1", + "infection/infection": "^0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.46", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^9.6.34", + "rector/rector": "^2.4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\AgentDetector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" + } + ], + "description": "Provides a detector for detecting the presence of an agent.", + "homepage": "https://github.com/ergebnis/agent-detector", + "support": { + "issues": "https://github.com/ergebnis/agent-detector/issues", + "security": "https://github.com/ergebnis/agent-detector/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/agent-detector" + }, + "time": "2026-04-10T13:45:13+00:00" + }, { "name": "evenement/evenement", "version": "v3.0.2", @@ -4187,22 +4256,23 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.94.2", + "version": "v3.95.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "7787ceff91365ba7d623ec410b8f429cdebb4f63" + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7787ceff91365ba7d623ec410b8f429cdebb4f63", - "reference": "7787ceff91365ba7d623ec410b8f429cdebb4f63", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a9727678fbd12997f1d9de8f4a37824ed9df1065", + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065", "shasum": "" }, "require": { "clue/ndjson-react": "^1.3", "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.5", + "ergebnis/agent-detector": "^1.1.1", "ext-filter": "*", "ext-hash": "*", "ext-json": "*", @@ -4227,18 +4297,18 @@ "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" }, "require-dev": { - "facile-it/paraunit": "^1.3.1 || ^2.7.1", - "infection/infection": "^0.32.3", - "justinrainbow/json-schema": "^6.6.4", + "facile-it/paraunit": "^1.3.1 || ^2.8.0", + "infection/infection": "^0.32.6", + "justinrainbow/json-schema": "^6.8.0", "keradus/cli-executor": "^2.3", "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.9.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.7", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.7", - "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.51", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", + "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", "symfony/polyfill-php85": "^1.33", - "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.4", - "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.1" + "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.8", + "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.8" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -4279,7 +4349,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.94.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.1" }, "funding": [ { @@ -4287,7 +4357,7 @@ "type": "github" } ], - "time": "2026-02-20T16:13:53+00:00" + "time": "2026-04-12T17:00:09+00:00" }, { "name": "php-standard-library/phpstan-extension", @@ -7411,16 +7481,16 @@ }, { "name": "webmozart/assert", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c" + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/1b99650e7ffcad232624a260bc7fbdec2ffc407c", - "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4", "shasum": "" }, "require": { @@ -7467,9 +7537,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.2.0" + "source": "https://github.com/webmozarts/assert/tree/2.3.0" }, - "time": "2026-04-09T16:54:47+00:00" + "time": "2026-04-11T10:33:05+00:00" } ], "aliases": [], @@ -7484,5 +7554,5 @@ "php": ">=8.5" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/config/application.php b/config/application.php index d175ad5c..bc828422 100755 --- a/config/application.php +++ b/config/application.php @@ -37,16 +37,16 @@ $webroot_dir = $root_dir . '/web'; * .env.local will override .env if it exists */ if (file_exists($root_dir . '/.env')) { - $env_files = file_exists($root_dir . '/.env.local') ? ['.env', '.env.local'] : ['.env']; + $env_files = file_exists($root_dir . '/.env.local') ? ['.env', '.env.local'] : ['.env']; - $dotenv = Dotenv\Dotenv::createImmutable($root_dir, $env_files, false); + $dotenv = Dotenv\Dotenv::createImmutable($root_dir, $env_files, false); - $dotenv->load(); + $dotenv->load(); - $dotenv->required(['WP_HOME', 'WP_SITEURL']); - if (!env('DATABASE_URL')) { - $dotenv->required(['DB_NAME', 'DB_USER', 'DB_PASSWORD']); - } + $dotenv->required(['WP_HOME', 'WP_SITEURL']); + if (!env('DATABASE_URL')) { + $dotenv->required(['DB_NAME', 'DB_USER', 'DB_PASSWORD']); + } } /* @@ -57,7 +57,7 @@ define('WP_ENV', env('WP_ENV') ?: 'production'); // Infer WP_ENVIRONMENT_TYPE based on WP_ENV if (!env('WP_ENVIRONMENT_TYPE') && in_array(WP_ENV, ['production', 'staging', 'development', 'local'], true)) { - Config::define('WP_ENVIRONMENT_TYPE', WP_ENV); + Config::define('WP_ENVIRONMENT_TYPE', WP_ENV); } // URLs @@ -71,7 +71,7 @@ Config::define('WP_CONTENT_URL', Config::get('WP_HOME') . Config::get('CONTENT_D // DB settings if (env('DB_SSL')) { - Config::define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL); + Config::define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL); } Config::define('DB_NAME', env('DB_NAME')); @@ -83,12 +83,12 @@ Config::define('DB_COLLATE', ''); $table_prefix = env('DB_PREFIX') ?: 'wp_'; if (env('DATABASE_URL')) { - $dsn = (object) parse_url(env('DATABASE_URL')); + $dsn = (object) parse_url(env('DATABASE_URL')); - Config::define('DB_NAME', mb_substr($dsn->path, 1)); - Config::define('DB_USER', $dsn->user); - Config::define('DB_PASSWORD', $dsn->pass ?? null); - Config::define('DB_HOST', isset($dsn->port) ? "{$dsn->host}:{$dsn->port}" : $dsn->host); + Config::define('DB_NAME', mb_substr($dsn->path, 1)); + Config::define('DB_USER', $dsn->user); + Config::define('DB_PASSWORD', $dsn->pass ?? null); + Config::define('DB_HOST', isset($dsn->port) ? "{$dsn->host}:{$dsn->port}" : $dsn->host); } // Authentication Unique Keys and Salts @@ -129,18 +129,18 @@ Config::define('WP_PLUGIN_DIR', Config::get('WP_CONTENT_DIR') . '/plugins'); * See https://codex.wordpress.org/Function_Reference/is_ssl#Notes */ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO']) { - $_SERVER['HTTPS'] = 'on'; + $_SERVER['HTTPS'] = 'on'; } $env_config = __DIR__ . '/environments/' . WP_ENV . '.php'; if (file_exists($env_config)) { - include_once $env_config; + include_once $env_config; } Config::apply(); // Bootstrap WordPress if (!defined('ABSPATH')) { - define('ABSPATH', $webroot_dir . '/wp/'); + define('ABSPATH', $webroot_dir . '/wp/'); } diff --git a/package.json b/package.json index 9b9db90b..2817ca75 100755 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", "a11y-dialog": "^8.1.5", - "effect": "^4.0.0-beta.46", + "effect": "^4.0.0-beta.48", "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", @@ -40,9 +40,9 @@ "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "fdir": "^6.5.0", - "globals": "^17.4.0", + "globals": "^17.5.0", "jiti": "^2.6.1", - "knip": "^6.3.1", + "knip": "^6.4.1", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", "oxlint": "^1.59.0", @@ -52,7 +52,7 @@ "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.1", "sass-embedded": "^1.99.0", - "stylelint": "^17.6.0", + "stylelint": "^17.7.0", "stylelint-config-clean-order": "^8.0.1", "stylelint-config-sass-guidelines": "^13.0.0", "stylelint-config-standard-scss": "^17.0.0", diff --git a/scripts/remove-scaled-images.php b/scripts/remove-scaled-images.php index ac57fe94..d4bd6024 100755 --- a/scripts/remove-scaled-images.php +++ b/scripts/remove-scaled-images.php @@ -14,32 +14,32 @@ global $wpdb; $wp_postmeta = "{$wpdb->prefix}postmeta"; try { - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - // Error Handling - $sql = "UPDATE {$wp_postmeta} SET meta_value = REPLACE(meta_value,'-scaled.jpg','.jpg') WHERE meta_key='_wp_attached_file' AND meta_value LIKE '%-scaled.jpg%'"; - $result = $pdo->exec($sql); - print_r($result); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + // Error Handling + $sql = "UPDATE {$wp_postmeta} SET meta_value = REPLACE(meta_value,'-scaled.jpg','.jpg') WHERE meta_key='_wp_attached_file' AND meta_value LIKE '%-scaled.jpg%'"; + $result = $pdo->exec($sql); + print_r($result); } catch (PDOException $e) { - print_r($e->getMessage()); + print_r($e->getMessage()); } // replace _wp_attachment_metadata meta_key. $image_metas = []; try { - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - // Error Handling - $sql = "SELECT * FROM {$wp_postmeta} WHERE meta_value LIKE '%-scaled.jpg%' AND meta_key='_wp_attachment_metadata'"; - $statement = $pdo->query($sql); - $image_metas = $statement->fetchAll(); - foreach ($image_metas as $meta) { - $meta_value = unserialize($meta['meta_value']); - $file = $meta_value['file']; - $meta_value['file'] = str_replace('-scaled.jpg', '.jpg', $file); - update_post_meta($meta['post_id'], $meta['meta_key'], $meta_value); - $result = get_post_meta($meta['post_id'], $meta['meta_key']); - print_r($result); - } + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + // Error Handling + $sql = "SELECT * FROM {$wp_postmeta} WHERE meta_value LIKE '%-scaled.jpg%' AND meta_key='_wp_attachment_metadata'"; + $statement = $pdo->query($sql); + $image_metas = $statement->fetchAll(); + foreach ($image_metas as $meta) { + $meta_value = unserialize($meta['meta_value']); + $file = $meta_value['file']; + $meta_value['file'] = str_replace('-scaled.jpg', '.jpg', $file); + update_post_meta($meta['post_id'], $meta['meta_key'], $meta_value); + $result = get_post_meta($meta['post_id'], $meta['meta_key']); + print_r($result); + } } catch (PDOException $e) { - print_r($e->getMessage()); + print_r($e->getMessage()); } diff --git a/web/app/themes/haiku-atelier-2024/404.php b/web/app/themes/haiku-atelier-2024/404.php index b0fe35de..f6296dd4 100755 --- a/web/app/themes/haiku-atelier-2024/404.php +++ b/web/app/themes/haiku-atelier-2024/404.php @@ -22,12 +22,11 @@ $templates = ['404.twig']; * * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger */ -function load_page_resources(): void -{ - Resource::enqueue_style_file( - handle: 'haiku-atelier-2024-styles-page-a-propos', - path: '/assets/css/pages/page-modele-simple.css', - ); +function load_page_resources(): void { + Resource::enqueue_style_file( + handle: 'haiku-atelier-2024-styles-page-a-propos', + path: '/assets/css/pages/page-modele-simple.css', + ); } add_action('wp_enqueue_scripts', load_page_resources(...)); diff --git a/web/app/themes/haiku-atelier-2024/front-page.php b/web/app/themes/haiku-atelier-2024/front-page.php index 0d9f16cc..5b890db9 100755 --- a/web/app/themes/haiku-atelier-2024/front-page.php +++ b/web/app/themes/haiku-atelier-2024/front-page.php @@ -17,14 +17,14 @@ $context = Timber::context(); $templates = ['accueil.twig']; add_action('wp_enqueue_scripts', function (): void { - Resource::enqueue_style_file( - handle: 'haiku-atelier-2024-styles-page-accueil', - path: '/assets/css/pages/page-accueil.css', - ); - Resource::enqueue_script_module_file( - id: 'haiku-atelier-2024-scripts-page-accueil', - path: '/assets/js/scripts-page-accueil.js', - ); + Resource::enqueue_style_file( + handle: 'haiku-atelier-2024-styles-page-accueil', + path: '/assets/css/pages/page-accueil.css', + ); + Resource::enqueue_script_module_file( + id: 'haiku-atelier-2024-scripts-page-accueil', + path: '/assets/js/scripts-page-accueil.js', + ); }); Timber::render(data: $context, filenames: $templates); diff --git a/web/app/themes/haiku-atelier-2024/page-about.php b/web/app/themes/haiku-atelier-2024/page-about.php index ce53c103..6d8690be 100755 --- a/web/app/themes/haiku-atelier-2024/page-about.php +++ b/web/app/themes/haiku-atelier-2024/page-about.php @@ -24,20 +24,20 @@ $templates = ['a-propos.twig']; $image_dimensions = getimagesize(filename: get_template_directory() . '/assets/img/about/haikuabout.png'); if (is_bool($image_dimensions)) { - throw new Exception("Impossible d'obtenir les dimensions de l'image principale de la page."); + throw new Exception("Impossible d'obtenir les dimensions de l'image principale de la page."); } $context['image_dimensions'] = $image_dimensions; add_action('wp_enqueue_scripts', function (): void { - Resource::enqueue_style_file( - handle: 'haiku-atelier-2024-styles-page-a-propos', - path: '/assets/css/pages/page-a-propos.css', - ); - Resource::enqueue_script_module_file( - id: 'haiku-atelier-2024-scripts-page-a-propos', - path: '/assets/js/scripts-page-a-propos.js', - ); + Resource::enqueue_style_file( + handle: 'haiku-atelier-2024-styles-page-a-propos', + path: '/assets/css/pages/page-a-propos.css', + ); + Resource::enqueue_script_module_file( + id: 'haiku-atelier-2024-scripts-page-a-propos', + path: '/assets/js/scripts-page-a-propos.js', + ); }); Timber::render(data: $context, filenames: $templates); diff --git a/web/app/themes/haiku-atelier-2024/page-checkout.php b/web/app/themes/haiku-atelier-2024/page-checkout.php index e53ed6c3..fa08f444 100755 --- a/web/app/themes/haiku-atelier-2024/page-checkout.php +++ b/web/app/themes/haiku-atelier-2024/page-checkout.php @@ -22,22 +22,20 @@ use WC_Session_Handler; header('Content-Type: application/json; charset=utf-8'); // TODO: Appliquer le bon calcul pour les montants vs. percentages -function get_discount_amount(WC_Coupon $coupon) -{ - if ($coupon->get_discount_type() === 'fixed_cart') { - return $coupon->get_amount() * 100; - } else { - return $coupon->get_amount(); - } +function get_discount_amount(WC_Coupon $coupon) { + if ($coupon->get_discount_type() === 'fixed_cart') { + return $coupon->get_amount() * 100; + } else { + return $coupon->get_amount(); + } } -function get_discount_duration(WC_Coupon $coupon): string -{ - if ($coupon->get_discount_type() === 'fixed_cart') { - return 'once'; - } else { - return 'forever'; - } +function get_discount_duration(WC_Coupon $coupon): string { + if ($coupon->get_discount_type() === 'fixed_cart') { + return 'once'; + } else { + return 'forever'; + } } // Récupère les informations nécessaires @@ -46,37 +44,37 @@ $session_wc = WC()->session; /** @var array $urls URLs utilisables pour rediriger l'Utilisateur. */ $urls = [ - 'accueil' => get_page_link(get_page_by_path('home')), - 'succes_commande' => get_page_link(get_page_by_path('successful-order')), - 'echec_commande' => get_page_link(get_page_by_path('failed-order')), + 'accueil' => get_page_link(get_page_by_path('home')), + 'succes_commande' => get_page_link(get_page_by_path('successful-order')), + 'echec_commande' => get_page_link(get_page_by_path('failed-order')), ]; // Redirige à la page d'accueil si le Panier est vide if (WC()->cart->is_empty()) { - header('Location: ' . $urls['accueil']); + header('Location: ' . $urls['accueil']); - return; + return; } // Vérifie que les paramètres d'URLs nécessaires soient présents /** @var string $order_id */ $order_id = $_GET['order_id']; if (!$order_id) { - $reponse = ['succes' => false, 'status' => 'order_key is missing']; - echo json_encode($reponse); - http_response_code(400); + $reponse = ['succes' => false, 'status' => 'order_key is missing']; + echo json_encode($reponse); + http_response_code(400); - return; + return; } /** @var string $order_key */ $order_key = $_GET['order_key']; if (!$order_key) { - $reponse = ['succes' => false, 'status' => 'order_key is missing']; - echo json_encode($reponse); - http_response_code(400); + $reponse = ['succes' => false, 'status' => 'order_key is missing']; + echo json_encode($reponse); + http_response_code(400); - return; + return; } // Récupère le Panier et l'Email du Client @@ -88,29 +86,29 @@ $email_client = WC()->session->get('customer')['email']; /** @var list $articles */ $articles = collect($panier->get_cart()) - ->map(static function ($article_panier) { - $titre_produit = match ('variable' === $article_panier['data']?->get_type()) { - true => $article_panier['data']?->get_title() - . ' (' - . explode(': ', (string) $article_panier['data']?->get_attribute_summary())[1] - . ')', - false => $article_panier['data']?->get_title(), - }; + ->map(static function ($article_panier) { + $titre_produit = match ('variable' === $article_panier['data']?->get_type()) { + true => $article_panier['data']?->get_title() + . ' (' + . explode(': ', (string) $article_panier['data']?->get_attribute_summary())[1] + . ')', + false => $article_panier['data']?->get_title(), + }; - return [ - 'price_data' => [ - 'currency' => 'EUR', - 'product_data' => [ - 'name' => $titre_produit, - 'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())], - ], - 'unit_amount' => $article_panier['data']?->get_price() * 100, - ], - 'quantity' => $article_panier['quantity'], - ]; - }) - ->values() - ->toArray(); + return [ + 'price_data' => [ + 'currency' => 'EUR', + 'product_data' => [ + 'name' => $titre_produit, + 'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())], + ], + 'unit_amount' => $article_panier['data']?->get_price() * 100, + ], + 'quantity' => $article_panier['quantity'], + ]; + }) + ->values() + ->toArray(); // Récupère la Commande et la Méthode de Livraison /** @var WC_Order $commande */ @@ -120,7 +118,7 @@ $methode_livraison = ['nom' => $commande->get_shipping_method(), 'cout' => $comm // Le nom de la méthode de livraison ne peut être une chaîne vide. if (empty($methode_livraison['nom'])) { - $methode_livraison['nom'] = 'Free'; + $methode_livraison['nom'] = 'Free'; } // Sélectionne la clé API Stripe @@ -129,39 +127,39 @@ Stripe::setApiKey(Config::get('STRIPE_API_SECRET')); // Met à jour les Codes promos $coupons_stripe = collect(Coupon::all()->data); $coupons_wc = collect(WC()->cart->get_coupons()) - ->map(static fn(WC_Coupon $coupon): array => [ - 'currency' => 'EUR', - 'duration' => get_discount_duration($coupon), - 'fixed_cart' === $coupon->get_discount_type() ? 'amount_off' : 'percent_off' => get_discount_amount($coupon), - 'id' => $coupon->get_code(), - 'name' => $coupon->get_code(), - ]) - ->each(static function (array $item) use ($coupons_stripe): void { - // Si le code promo n'existe pas, le créer - if (!$coupons_stripe->contains('name', $item['name'])) { - Coupon::create($item); - } - }); + ->map(static fn(WC_Coupon $coupon): array => [ + 'currency' => 'EUR', + 'duration' => get_discount_duration($coupon), + 'fixed_cart' === $coupon->get_discount_type() ? 'amount_off' : 'percent_off' => get_discount_amount($coupon), + 'id' => $coupon->get_code(), + 'name' => $coupon->get_code(), + ]) + ->each(static function (array $item) use ($coupons_stripe): void { + // Si le code promo n'existe pas, le créer + if (!$coupons_stripe->contains('name', $item['name'])) { + Coupon::create($item); + } + }); $reductions_stripe = $coupons_wc - ->map(static fn($coupon): array => ['coupon' => $coupon['name']]) - ->values() - ->toArray(); + ->map(static fn($coupon): array => ['coupon' => $coupon['name']]) + ->values() + ->toArray(); /** @var Session $session_checkout_stripe */ $session_checkout_stripe = Session::create([ - 'cancel_url' => $urls['echec_commande'], - 'customer_email' => $email_client, - 'discounts' => $reductions_stripe, - 'line_items' => $articles, - 'mode' => 'payment', - 'success_url' => $urls['succes_commande'] . '?session_id={CHECKOUT_SESSION_ID}', - 'metadata' => ['order_id' => $order_id, 'order_key' => $order_key], - 'shipping_options' => [['shipping_rate_data' => [ - 'display_name' => $methode_livraison['nom'], - 'fixed_amount' => ['amount' => $methode_livraison['cout'], 'currency' => 'EUR'], - 'tax_behavior' => 'inclusive', - 'type' => 'fixed_amount', - ]]], + 'cancel_url' => $urls['echec_commande'], + 'customer_email' => $email_client, + 'discounts' => $reductions_stripe, + 'line_items' => $articles, + 'mode' => 'payment', + 'success_url' => $urls['succes_commande'] . '?session_id={CHECKOUT_SESSION_ID}', + 'metadata' => ['order_id' => $order_id, 'order_key' => $order_key], + 'shipping_options' => [['shipping_rate_data' => [ + 'display_name' => $methode_livraison['nom'], + 'fixed_amount' => ['amount' => $methode_livraison['cout'], 'currency' => 'EUR'], + 'tax_behavior' => 'inclusive', + 'type' => 'fixed_amount', + ]]], ], ['idempotency_key' => Uuid::v4()]); // echo json_encode($session_checkout_stripe); header('HTTP/1.1 303 See Other'); diff --git a/web/app/themes/haiku-atelier-2024/page-failed-order.php b/web/app/themes/haiku-atelier-2024/page-failed-order.php index 1dc703c5..ea428114 100755 --- a/web/app/themes/haiku-atelier-2024/page-failed-order.php +++ b/web/app/themes/haiku-atelier-2024/page-failed-order.php @@ -17,10 +17,10 @@ $context = Timber::context(); $templates = ['echec-commande.twig']; add_action('wp_enqueue_scripts', function (): void { - Resource::enqueue_style_file( - handle: 'haiku-atelier-2024-styles-page-modele-simple', - path: '/assets/css/pages/page-modele-simple.css', - ); + Resource::enqueue_style_file( + handle: 'haiku-atelier-2024-styles-page-modele-simple', + path: '/assets/css/pages/page-modele-simple.css', + ); }); // Rendu diff --git a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php index d5584c86..0b9d5998 100755 --- a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php +++ b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php @@ -17,10 +17,10 @@ $context = Timber::context(); $templates = ['cgv.twig']; add_action('wp_enqueue_scripts', function (): void { - Resource::enqueue_style_file( - handle: '/assets/css/pages/page-modele-simple.css', - path: '/assets/css/pages/page-modele-simple.css', - ); + Resource::enqueue_style_file( + handle: '/assets/css/pages/page-modele-simple.css', + path: '/assets/css/pages/page-modele-simple.css', + ); }); // Rendu diff --git a/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php b/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php index e64ba66b..9d509e72 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php @@ -9,39 +9,36 @@ declare(strict_types=1); use Carbon_Fields\Container; use Carbon_Fields\Field; -function cree_champs_personnalises_produit(): void -{ - Container::make('post_meta', "Product's Details") - ->where('post_type', '=', 'product') - ->add_fields([ - // Galerie des photos Produit - Field::make('media_gallery', 'photos_colonne_gauche', __('Left Column Photos')) - ->set_type(['image']) - ->set_duplicates_allowed(false), - // Galerie des photos portées - Field::make('media_gallery', 'photos_colonne_droite', __('Right Column Photos')) - ->set_type(['image']) - ->set_duplicates_allowed(false), - // Texte des détails du Produit - Field::make('rich_text', 'haiku_details_produit', __("Product's Details")), - ]); -} - -function cree_champ_personnalise_commande($order): void -{ - woocommerce_wp_text_input([ - 'id' => 'tracking_number', - 'label' => 'Tracking Number:', - 'value' => $order->get_meta('tracking_number'), - 'wrapper_class' => 'form-field-wide', +function cree_champs_personnalises_produit(): void { + Container::make('post_meta', "Product's Details") + ->where('post_type', '=', 'product') + ->add_fields([ + // Galerie des photos Produit + Field::make('media_gallery', 'photos_colonne_gauche', __('Left Column Photos')) + ->set_type(['image']) + ->set_duplicates_allowed(false), + // Galerie des photos portées + Field::make('media_gallery', 'photos_colonne_droite', __('Right Column Photos')) + ->set_type(['image']) + ->set_duplicates_allowed(false), + // Texte des détails du Produit + Field::make('rich_text', 'haiku_details_produit', __("Product's Details")), ]); } -function maj_champ_personnalise_commande($order_id): void -{ - $order = wc_get_order($order_id); - $order->update_meta_data('tracking_number', wc_clean($_POST['tracking_number'])); - $order->save(); +function cree_champ_personnalise_commande($order): void { + woocommerce_wp_text_input([ + 'id' => 'tracking_number', + 'label' => 'Tracking Number:', + 'value' => $order->get_meta('tracking_number'), + 'wrapper_class' => 'form-field-wide', + ]); +} + +function maj_champ_personnalise_commande($order_id): void { + $order = wc_get_order($order_id); + $order->update_meta_data('tracking_number', wc_clean($_POST['tracking_number'])); + $order->save(); } add_action('carbon_fields_register_fields', 'cree_champs_personnalises_produit'); diff --git a/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php b/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php index 9209a485..78d633cd 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php @@ -8,74 +8,69 @@ declare(strict_types=1); -function enregistre_controle_personnalise_tinymce(): void -{ +function enregistre_controle_personnalise_tinymce(): void { + /** + * TinyMCE Custom Control. + * + * @author Anthony Hortin + * @license http://www.gnu.org/licenses/gpl-2.0.html + * + * @see https://github.com/maddisondesigns + */ + final class ControlesPersonnalises extends WP_Customize_Control { + /** The type of control being rendered. */ + public $type = 'editeur_tinymce'; + /** - * TinyMCE Custom Control. - * - * @author Anthony Hortin - * @license http://www.gnu.org/licenses/gpl-2.0.html - * - * @see https://github.com/maddisondesigns + * Enqueue our scripts and styles. */ - final class ControlesPersonnalises extends WP_Customize_Control - { - /** The type of control being rendered. */ - public $type = 'editeur_tinymce'; + public function enqueue(): void { + wp_enqueue_script( + handle: 'controle-personnalise-tinymce', + src: get_template_directory_uri() . '/assets/vendor/controle-personnalise-tinymce.js', + deps: ['jquery'], + ver: '1.3', + args: true, + ); + wp_enqueue_editor(); + } - /** - * Enqueue our scripts and styles. - */ - public function enqueue(): void - { - wp_enqueue_script( - handle: 'controle-personnalise-tinymce', - src: get_template_directory_uri() . '/assets/vendor/controle-personnalise-tinymce.js', - deps: ['jquery'], - ver: '1.3', - args: true, - ); - wp_enqueue_editor(); - } - - /** - * Render the control in the customizer. - */ - public function render_content(): void - { ?> + /** + * Render the control in the customizer. + */ + public function render_content(): void { ?>
label); ?> description)) { ?> description); ?>
json['skyrockettinymcetoolbar1'] = isset($this->input_attrs['toolbar1']) - ? esc_attr($this->input_attrs['toolbar1']) - : 'bold italic bullist numlist alignleft aligncenter alignright link'; + $this->json['skyrockettinymcetoolbar1'] = isset($this->input_attrs['toolbar1']) + ? esc_attr($this->input_attrs['toolbar1']) + : 'bold italic bullist numlist alignleft aligncenter alignright link'; - $this->json['skyrockettinymcetoolbar2'] = isset($this->input_attrs['toolbar2']) - ? esc_attr($this->input_attrs['toolbar2']) - : ''; - $this->json['skyrocketmediabuttons'] = isset($this->input_attrs['mediaButtons']) - && $this->input_attrs['mediaButtons'] === true - ? true - : false; - } + $this->json['skyrockettinymcetoolbar2'] = isset($this->input_attrs['toolbar2']) + ? esc_attr($this->input_attrs['toolbar2']) + : ''; + $this->json['skyrocketmediabuttons'] = isset($this->input_attrs['mediaButtons']) + && $this->input_attrs['mediaButtons'] === true + ? true + : false; } + } } add_action('customize_register', 'enregistre_controle_personnalise_tinymce'); diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php index 248f4bc2..1ad27c0d 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php @@ -11,116 +11,113 @@ use function is_float; use function is_int; use function is_string; -final readonly class Cart -{ - public function __construct() {} +final readonly class Cart { + public function __construct() {} - /** La valeur par défaut d'une donnée invalide du Panier. */ - private const string DEFAULT_VALUE = '0.00'; + /** La valeur par défaut d'une donnée invalide du Panier. */ + private const string DEFAULT_VALUE = '0.00'; - /** - * Retourne la liste des pays acceptés pour la livraison. - * - * @return array - */ - public static function get_allowed_countries(): array - { - return [ - 'AD', - 'AL', - 'AM', - 'AR', - 'AT', - 'AU', - 'BA', - 'BE', - 'BG', - 'BR', - 'CA', - 'CH', - 'CL', - 'CR', - 'CU', - 'CY', - 'CZ', - 'DE', - 'DK', - 'DZ', - 'EE', - 'EG', - 'ES', - 'FI', - 'FR', - 'GF', - 'GP', - 'GR', - 'HR', - 'HU', - 'IE', - 'IS', - 'IT', - 'JP', - 'KR', - 'LB', - 'LI', - 'LT', - 'LU', - 'LV', - 'MA', - 'MD', - 'ME', - 'MF', - 'MQ', - 'MT', - 'MX', - 'NC', - 'NL', - 'NO', - 'NZ', - 'PF', - 'PL', - 'PM', - 'PS', - 'PT', - 'RE', - 'RO', - 'SE', - 'SI', - 'SK', - 'SM', - 'TN', - 'TR', - 'TW', - 'US', - 'YT', - 'ZA', - ]; + /** + * Retourne la liste des pays acceptés pour la livraison. + * + * @return array + */ + public static function get_allowed_countries(): array { + return [ + 'AD', + 'AL', + 'AM', + 'AR', + 'AT', + 'AU', + 'BA', + 'BE', + 'BG', + 'BR', + 'CA', + 'CH', + 'CL', + 'CR', + 'CU', + 'CY', + 'CZ', + 'DE', + 'DK', + 'DZ', + 'EE', + 'EG', + 'ES', + 'FI', + 'FR', + 'GF', + 'GP', + 'GR', + 'HR', + 'HU', + 'IE', + 'IS', + 'IT', + 'JP', + 'KR', + 'LB', + 'LI', + 'LT', + 'LU', + 'LV', + 'MA', + 'MD', + 'ME', + 'MF', + 'MQ', + 'MT', + 'MX', + 'NC', + 'NL', + 'NO', + 'NZ', + 'PF', + 'PL', + 'PM', + 'PS', + 'PT', + 'RE', + 'RO', + 'SE', + 'SI', + 'SK', + 'SM', + 'TN', + 'TR', + 'TW', + 'US', + 'YT', + 'ZA', + ]; + } + + public static function parse_cart_value(int|float|string|bool $cart_value): string { + if (is_int($cart_value) || is_float($cart_value)) { + return self::format_number($cart_value); } - public static function parse_cart_value(int|float|string|bool $cart_value): string - { - if (is_int($cart_value) || is_float($cart_value)) { - return self::format_number($cart_value); - } + if (is_string($cart_value)) { + $number = Number::parseInt($cart_value); + $number = is_bool($number) ? 0 : $number; - if (is_string($cart_value)) { - $number = Number::parseInt($cart_value); - $number = is_bool($number) ? 0 : $number; - - return self::format_number($number); - } - - return '0.00'; + return self::format_number($number); } - private static function format_number(int|float $number): string - { - $formatted_number = Number::format( - number: $number, - // precision et max_precision sont mutuellement exclusifs. - precision: 2, - locale: 'fr', - ); - return is_bool($formatted_number) ? self::DEFAULT_VALUE : $formatted_number; - } + return '0.00'; + } + + private static function format_number(int|float $number): string { + $formatted_number = Number::format( + number: $number, + // precision et max_precision sont mutuellement exclusifs. + precision: 2, + locale: 'fr', + ); + + return is_bool($formatted_number) ? self::DEFAULT_VALUE : $formatted_number; + } } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php index eb4e5b95..11104db0 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php @@ -6,34 +6,32 @@ namespace HaikuAtelier\Data; use WC_Product; -final readonly class ProductVariation -{ - /** - * @param int $id L'ID de la Variation - * @param string $price Le prix de la Variation - * @param list $attributes Les attributs appliqués à la Variation - */ - private function __construct( - public int $id, - public string $price, - public array $attributes, - ) {} +final readonly class ProductVariation { + /** + * @param int $id L'ID de la Variation + * @param string $price Le prix de la Variation + * @param list $attributes Les attributs appliqués à la Variation + */ + private function __construct( + public int $id, + public string $price, + public array $attributes, + ) {} - /** - * Créé une nouvelle instance de `ProductVariation` à partir d'un `WC_Product`. - */ - public static function new(WC_Product $product): self - { - $id = $product->get_id(); - $price = $product->get_price(); - /** @var list */ - $attributes = array_map( - /** @phpstan-ignore argument.type (Impossible à satisfaire) */ - static fn(string $key, string $value) => new ProductVariationAttribute($key, $value), - array_keys($product->get_attributes()), - array_values($product->get_attributes()), - ); + /** + * Créé une nouvelle instance de `ProductVariation` à partir d'un `WC_Product`. + */ + public static function new(WC_Product $product): self { + $id = $product->get_id(); + $price = $product->get_price(); + /** @var list */ + $attributes = array_map( + /** @phpstan-ignore argument.type (Impossible à satisfaire) */ + static fn(string $key, string $value) => new ProductVariationAttribute($key, $value), + array_keys($product->get_attributes()), + array_values($product->get_attributes()), + ); - return new self($id, $price, $attributes); - } + return new self($id, $price, $attributes); + } } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php index 3bff266e..988ee3b4 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php @@ -4,14 +4,13 @@ declare(strict_types=1); namespace HaikuAtelier\Data; -final readonly class ProductVariationAttribute -{ - /** - * @param string $attribute Le slug de l'Attribut - * @param string $value Le slug de la valeur de l'Attribut - */ - public function __construct( - public string $attribute, - public string $value, - ) {} +final readonly class ProductVariationAttribute { + /** + * @param string $attribute Le slug de l'Attribut + * @param string $value Le slug de la valeur de l'Attribut + */ + public function __construct( + public string $attribute, + public string $value, + ) {} } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php b/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php index fc5e8947..771f1c3d 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Fonctionnalites.php @@ -9,9 +9,8 @@ declare(strict_types=1); namespace HaikuAtelier; // Désactive divers transformations du contenu par WordPress -function desactive_wpautop(): void -{ - remove_filter('the_content', 'wpautop'); +function desactive_wpautop(): void { + remove_filter('the_content', 'wpautop'); } /** @@ -21,17 +20,16 @@ function desactive_wpautop(): void * * @return array le même tableau avec des configurations en plus */ -function desactive_transformation_contenu_tinymce(array $configuration): array -{ - // Ne supprime pas les retours à la ligne - $configuration['remove_linebreaks'] = false; - // Convertis les caractères de retours à la ligne en
- $configuration['convert_newlines_to_brs'] = true; - // Supprime les
redondants - $configuration['remove_redundant_brs'] = false; +function desactive_transformation_contenu_tinymce(array $configuration): array { + // Ne supprime pas les retours à la ligne + $configuration['remove_linebreaks'] = false; + // Convertis les caractères de retours à la ligne en
+ $configuration['convert_newlines_to_brs'] = true; + // Supprime les
redondants + $configuration['remove_redundant_brs'] = false; - // Retourne $configuration à WordPress - return $configuration; + // Retourne $configuration à WordPress + return $configuration; } /** @@ -41,22 +39,19 @@ function desactive_transformation_contenu_tinymce(array $configuration): array * * @return array le même tableau avec SVG en plus */ -function autorise_import_svg_mediatheque(array $file_types): array -{ - $new_filetypes = []; - $new_filetypes['svg'] = 'image/svg+xml'; +function autorise_import_svg_mediatheque(array $file_types): array { + $new_filetypes = []; + $new_filetypes['svg'] = 'image/svg+xml'; - return [...$file_types, ...$new_filetypes]; + return [...$file_types, ...$new_filetypes]; } -function retire_motifs_blocs_gutenberg(): void -{ - remove_theme_support('core-block-patterns'); +function retire_motifs_blocs_gutenberg(): void { + remove_theme_support('core-block-patterns'); } -function retire_styles_core_block(): void -{ - wp_dequeue_style('core-block-supports'); +function retire_styles_core_block(): void { + wp_dequeue_style('core-block-supports'); } // Désactive les appels à l'API de la mise à jour des traductions diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php b/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php index 176f36f6..727459f0 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php @@ -14,33 +14,32 @@ use function register_taxonomy; /** * Enregistre la Taxonomie « Collection ». */ -function enregistre_taxonomie_collection(): void -{ - $labels = [ - 'add_new_item' => __('Add New Collection'), - 'all_items' => __('All Collections'), - 'edit_item' => __('Edit Collection'), - 'menu_name' => __('Collections'), - 'name' => __('Collections'), - 'new_item_name' => __('New Collection Name'), - 'search_items' => __('Search Collections'), - 'singular_name' => __('Collection'), - 'update_item' => __('Update Collection'), - ]; - $args = [ - 'description' => __('An ensemble of pieces thematically or chronologically grouped together.'), - 'hierarchical' => false, - 'labels' => $labels, - 'publicly_queryable' => false, - 'query_var' => true, - 'rewrite' => ['slug' => 'collection'], - 'show_admin_column' => true, - 'show_in_menu' => true, - 'show_in_quick_edit' => true, - 'show_ui' => true, - ]; +function enregistre_taxonomie_collection(): void { + $labels = [ + 'add_new_item' => __('Add New Collection'), + 'all_items' => __('All Collections'), + 'edit_item' => __('Edit Collection'), + 'menu_name' => __('Collections'), + 'name' => __('Collections'), + 'new_item_name' => __('New Collection Name'), + 'search_items' => __('Search Collections'), + 'singular_name' => __('Collection'), + 'update_item' => __('Update Collection'), + ]; + $args = [ + 'description' => __('An ensemble of pieces thematically or chronologically grouped together.'), + 'hierarchical' => false, + 'labels' => $labels, + 'publicly_queryable' => false, + 'query_var' => true, + 'rewrite' => ['slug' => 'collection'], + 'show_admin_column' => true, + 'show_in_menu' => true, + 'show_in_quick_edit' => true, + 'show_ui' => true, + ]; - register_taxonomy('collection', ['product'], $args); + register_taxonomy('collection', ['product'], $args); } add_action('init', enregistre_taxonomie_collection(...)); diff --git a/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php b/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php index 0decb949..116eb07b 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php @@ -14,50 +14,46 @@ use function is_array; use function Psl\Option\none; use function Psl\Option\some; -final readonly class Post -{ - /** - * @return Option\Option - */ - public static function get_post_meta(int $post_id, string $key): Option\Option - { - /** @var false|mixed|string */ - $value = get_post_meta($post_id, $key, true); +final readonly class Post { + /** + * @return Option\Option + */ + public static function get_post_meta(int $post_id, string $key): Option\Option { + /** @var false|mixed|string */ + $value = get_post_meta($post_id, $key, true); - if ($value === false) { - return none(); - } - - return some($value); + if ($value === false) { + return none(); } - /** - * @return Option\Option> - */ - public static function get_post_meta_array(int $post_id, string $key): Option\Option - { - /** @var array|false */ - $value = get_post_meta($post_id, $key, false); + return some($value); + } - if (is_array($value)) { - return some($value); - } + /** + * @return Option\Option> + */ + public static function get_post_meta_array(int $post_id, string $key): Option\Option { + /** @var array|false */ + $value = get_post_meta($post_id, $key, false); - return none(); + if (is_array($value)) { + return some($value); } - /** - * @return Option\Option> - */ - public static function get_terms(int $post_id, string $taxonomy_name): Option\Option - { - /** @var false|list|WP_Error */ - $terms = get_the_terms($post_id, $taxonomy_name); + return none(); + } - if (is_array($terms)) { - return some($terms); - } + /** + * @return Option\Option> + */ + public static function get_terms(int $post_id, string $taxonomy_name): Option\Option { + /** @var false|list|WP_Error */ + $terms = get_the_terms($post_id, $taxonomy_name); - return none(); + if (is_array($terms)) { + return some($terms); } + + return none(); + } } diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts new file mode 100644 index 00000000..97c8b1ff --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts @@ -0,0 +1,10 @@ +import { Schema } from "effect"; +import { ProductAttribute } from "./product.ts"; + +class AddProductToCart extends Schema.Class("AddProductToCart")({ + id: Schema.Int, + quantity: Schema.Int.check(Schema.isGreaterThan(0)), + variation: Schema.Array(ProductAttribute), +}) {} + +export { AddProductToCart }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts new file mode 100644 index 00000000..1c8055a4 --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts @@ -0,0 +1,20 @@ +// oxlint-disable no-magic-numbers -- Pas besoin ici. +import { Schema } from "effect"; + +class ProductAttribute extends Schema.Class("ProductAttribute")({ + /** L'identifiant _(slug)_ de l'Attribut. */ + attribute: Schema.String, + /** La valeur de l'attribut. */ + value: Schema.String, +}) {} + +class ProductVariation extends Schema.Class("ProductVariation")({ + /** Les Attributs présents pour cette Variation. */ + attributes: Schema.Array(ProductAttribute), + /** L'identifiant numérique unique de la Variation. */ + id: Schema.Int.check(Schema.isGreaterThan(0)), + /** Le prix de la Variation. */ + price: Schema.NonEmptyString, +}) {} + +export { ProductAttribute, ProductVariation }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts new file mode 100644 index 00000000..72941df3 --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts @@ -0,0 +1,13 @@ +import { Console, Layer, ManagedRuntime, pipe } from "effect"; +import ProductPageDOM from "./service-dom.ts"; +import ProductPageElements from "./service-elements.ts"; + +const ProductPageRuntime = ManagedRuntime.make( + pipe( + ProductPageDOM.layer, + Layer.provide(ProductPageElements.layer), + Layer.tapError(error => Console.error("ProductPageRuntime", "Impossible de créer le Layer :", error)), + ), +); + +export default ProductPageRuntime; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit-service.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts similarity index 52% rename from web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit-service.ts rename to web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts index 72469a32..672b94d0 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit-service.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts @@ -6,97 +6,28 @@ import { Effect, HashMap, Layer, - ManagedRuntime, Option, pipe, + Ref, + Schema, + SchemaIssue, Stream, } from "effect"; -import type { NonEmptyReadonlyArray } from "effect/Array"; import type { NoSuchElementError } from "effect/Cause"; -import { getAllSelectorFromDocument, getFirstSelectorFromDocument } from "../scripts-effect/lib/dom.ts"; +import { AddProductToCart } from "../../scripts-effect/schemas/api.ts"; +import { ProductAttribute, ProductVariation } from "../../scripts-effect/schemas/product.ts"; import { ATTRIBUT_ARIA_CONTROLS, ATTRIBUT_ARIA_EXPANDED, ATTRIBUT_DESACTIVE, ATTRIBUT_HIDDEN, - DOM_BOUTON_AJOUT_PANIER, - DOM_BOUTONS_ACCORDEON, - DOM_CONTENUS_ACCORDEON, - DOM_PRIX_PRODUIT, -} from "./constantes/dom.ts"; -import type { WCStoreCartAddItemArgsItems } from "./lib/types/api/cart-add-item.d.ts"; - -/** Représente un ensemble bouton-contenu d'une Section dans la description du Produit. */ -type DetailEnsemble = { - button: HTMLButtonElement; - content: HTMLDivElement; -}; - -class ProductPageElements extends Context.Service< - ProductPageElements, - { - AddToCartButton: HTMLButtonElement; - Details: HashMap.HashMap; - DetailsButtons: NonEmptyReadonlyArray; - DetailsContents: NonEmptyReadonlyArray; - ProductPrice: HTMLParagraphElement; - ProductRawJson: HTMLScriptElement; - VariationChoiceForm: HTMLFormElement; - VariationSelectors: ReadonlyArray; - } ->()("haikuatelier.fr/Produit/ProductPageElements") { - static readonly layer = Layer.effect( - ProductPageElements, - Effect.gen(function*() { - const AddToCartButton = yield* getFirstSelectorFromDocument(DOM_BOUTON_AJOUT_PANIER); - const DetailsButtons = yield* getAllSelectorFromDocument(DOM_BOUTONS_ACCORDEON); - const DetailsContents = yield* getAllSelectorFromDocument(DOM_CONTENUS_ACCORDEON); - const ProductPrice = yield* getFirstSelectorFromDocument(DOM_PRIX_PRODUIT); - const ProductRawJson = yield* getFirstSelectorFromDocument("#product-json"); - const VariationChoiceForm = yield* getFirstSelectorFromDocument("#variation-choice"); - const VariationSelectors = yield* pipe( - getAllSelectorFromDocument(".selecteur-produit select"), - Option.orElseSome(() => FxArray.empty()), - ); - - const Details = yield* pipe( - DetailsButtons, - FxArray.map( - (button: HTMLButtonElement, index: number): Effect.Effect<[string, DetailEnsemble], NoSuchElementError> => - Effect.gen(function*() { - const contentId = yield* Option.fromNullishOr(button.getAttribute(ATTRIBUT_ARIA_CONTROLS)); - const content = yield* FxArray.get(DetailsContents, index); - - return [contentId, { button, content } satisfies DetailEnsemble]; - }), - ), - Effect.all, - Effect.map(HashMap.fromIterable), - ); - - return ProductPageElements.of({ - AddToCartButton, - Details, - DetailsButtons, - DetailsContents, - ProductPrice, - ProductRawJson, - VariationChoiceForm, - VariationSelectors, - }); - }), - ); -} +} from "../constantes/dom.ts"; +import ProductPageElements from "./service-elements.ts"; +import type { DetailEnsemble } from "./types.d.ts"; class ProductPageDOM extends Context.Service< ProductPageDOM, { - initPriceUpdatesOnVariationChange: () => Effect.Effect; - onVariationChangeHandler: () => Effect.Effect; - /** - * Récupère les Attributs du Produit depuis les Elements au sein du DOM. - */ - getProductAttributesFromDOM: () => Effect.Effect>; /** * Initialise l'état initial du Bouton d'ajout au Panier. */ @@ -110,26 +41,30 @@ class ProductPageDOM extends Context.Service< */ initDetailInteractions: () => Effect.Effect; /** - * Met à jour l'état des Sections de la Description du Produit. + * Initialise la mise à jour du Prix affiché en fonction du choix de la Varation de Produit. */ - onDetailButtonClickHandler: (evt: Event) => Effect.Effect; - /** - * Met à jour l'état du Bouton d'ajout au Panier. - */ - onFormChangeHandler: (evt: Event) => Effect.Effect; + initPriceUpdatesOnVariationChange: () => Effect.Effect; /** * Replie toutes les sections de la description du Produit. */ - toggleAllDetails: () => Effect.Effect; + initAddToCartButtonClicks: () => unknown; + ProductVariations: ReadonlyArray; + CurrentVariation: Ref.Ref>; } >()("haikuatelier.fr/Produit/ProductPageDOM") { static readonly layer = Layer.effect( ProductPageDOM, Effect.gen(function*() { - const { AddToCartButton, Details, ProductPrice, DetailsButtons, ProductRawJson, VariationChoiceForm, VariationSelectors } = - yield* ProductPageElements; - - const onFormChangeHandler = Effect.fnUntraced(function*(evt: Event) { + const { + AddToCartButton, + Details, + DetailsButtons, + ProductPrice, + ProductRawJson, + VariationChoiceForm, + VariationSelectors, + } = yield* ProductPageElements; + const onFormChangeHandler = Effect.fn("onFormChangeHandler")(function*(evt: Event): Effect.fn.Return { // La cible ne peut qu'être un Formulaire. const target: HTMLFormElement = evt.target as HTMLFormElement; const isClickAllowed = target.checkValidity() === false; @@ -152,7 +87,9 @@ class ProductPageDOM extends Context.Service< ); }); - const onDetailButtonClickHandler = Effect.fnUntraced(function*(evt: Event) { + const onDetailButtonClickHandler = Effect.fn("onDetailButtonClickHandler")(function*( + evt: Event, + ): Effect.fn.Return { // Empêche la pollution de l'historique de navigation evt.preventDefault(); @@ -183,13 +120,67 @@ class ProductPageDOM extends Context.Service< return yield* Effect.void; }); - const getProductAttributesFromDOM: () => Effect.Effect> = () => - Effect.sync(() => + const ProductVariations: ReadonlyArray = yield* pipe( + JSON.parse(ProductRawJson.textContent)?.variations, + json => Schema.decodeUnknownEffect(Schema.Array(ProductVariation))(json, { onExcessProperty: "ignore" }), + Effect.mapError(error => SchemaIssue.makeFormatterStandardSchemaV1()(error.issue)), + Effect.tapCause(Console.error), + ); + + const getChosenProductAttributesFromDOM = Effect.fn("getChosenProductAttributesFromDOM")(function*() { + return yield* pipe( FxArray.map(VariationSelectors, (select: HTMLSelectElement) => ({ attribute: select.id, value: select.value, - })) + })), + variations => Schema.decodeEffect(Schema.Array(ProductAttribute))(variations), + Effect.mapError(error => SchemaIssue.makeFormatterDefault()(error.issue)), + Effect.tapCause(Console.error), ); + }); + + const CurrentVariation = yield* Ref.make(Option.none()); + + const onVariationChangeHandler = Effect.fn("onVariationChangeHandler")(function*(): Effect.fn.Return< + void, + NoSuchElementError | string + > { + yield* Console.debug("onVariationChangeHandler"); + // Ne fais rien si le Formulaire n'est pas valide. + if (VariationChoiceForm.checkValidity() === false) { + yield* Console.debug("onVariationChangeHandler", "Le formulaire est invalide."); + return yield* Effect.void; + } + + const equivalence = Schema.toEquivalence(Schema.Array(ProductAttribute)); + const chosenProductAttributes = yield* getChosenProductAttributesFromDOM(); + const chosenVariation: ProductVariation = yield* FxArray.findFirst( + ProductVariations, + (variation: ProductVariation) => equivalence(variation.attributes, chosenProductAttributes), + ); + + // Met à jour la valeur de la Variation choisie dans le Service. + yield* Ref.set(Option.some(chosenVariation))(CurrentVariation); + + const newPrice = chosenVariation.price; + ProductPrice.textContent = `${newPrice}€`; + + return yield* Effect.void; + }, Effect.tapCause(Console.error)); + + const onAddToCartButtonHandler = Effect.fn("onAddToCartButtonHandler")(function*() { + const chosenVariation = yield* Ref.getUnsafe(CurrentVariation); + const productDetails = yield* Schema.decodeEffect(AddProductToCart)( + { + id: chosenVariation.id, + quantity: 1, + variation: chosenVariation.attributes, + }, + { errors: "all" }, + ); + + console.debug(productDetails); + }); const initAddToCartButtonInitialState = Effect.fn("initAddToCartButtonInitialState")(function*() { /** Est-ce que le Produit affiché est en stock ? */ @@ -216,31 +207,23 @@ class ProductPageDOM extends Context.Service< ); }); - const initPriceUpdatesOnVariationChange = Effect.fn("initPriceUpdatesOnVariationChange")(function*(){ + const initAddToCartButtonClicks = Effect.fn("initAddToCartButtonClicks")(function*() { return yield* pipe( - Stream.fromEventListener(VariationChoiceForm, "change"), - Stream.tap(onVariationChangeHandler), + Stream.fromEventListener(AddToCartButton, "click"), + Stream.tap(onAddToCartButtonHandler), Stream.runDrain, - ) + ); }); - const onVariationChangeHandler = Effect.fn("onVariationChangeHandler")(function*(){ - if (VariationChoiceForm.checkValidity() === false) { - return yield* Effect.void; - } - - const variations = JSON.parse(ProductRawJson.textContent)?.variations as ReadonlyArray; - const chosenAttributes = yield* getProductAttributesFromDOM(); - - const equivalence = FxArray.makeEquivalence<{attribute: string,value: string}>((a,b) => { - return a.attribute === b.attribute && a.value === b.value; - }); - const chosenVariation = yield* FxArray.findFirst(variations, variation => equivalence(variation.attributes, chosenAttributes)); - const newPrice = chosenVariation.price; - - ProductPrice.textContent = `${newPrice}€`; - return yield* Effect.void; - }); + const initPriceUpdatesOnVariationChange = Effect.fn("initPriceUpdatesOnVariationChange")( + function*(): Effect.fn.Return { + return yield* pipe( + Stream.fromEventListener(VariationChoiceForm, "change"), + Stream.tap(onVariationChangeHandler), + Stream.runDrain, + ); + }, + ); const initDetailInteractions = Effect.fn("initDetailInteractions")(function*() { return yield* pipe( @@ -256,26 +239,16 @@ class ProductPageDOM extends Context.Service< }); return ProductPageDOM.of({ - getProductAttributesFromDOM, + CurrentVariation, + ProductVariations, + initAddToCartButtonClicks, initAddToCartButtonInitialState, initAddToCartButtonUpdates, initDetailInteractions, initPriceUpdatesOnVariationChange, - onDetailButtonClickHandler, - onFormChangeHandler, - onVariationChangeHandler, - toggleAllDetails, }); }), ); } -const ProductPageRuntime = ManagedRuntime.make( - pipe( - ProductPageDOM.layer, - Layer.provide(ProductPageElements.layer), - Layer.tapError(error => Console.error("ManagedRuntime", "Impossible de créer le Layer :", error.name)), - ), -); - -export { type DetailEnsemble, ProductPageDOM, ProductPageElements, ProductPageRuntime }; +export default ProductPageDOM; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts new file mode 100644 index 00000000..bb673c5f --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts @@ -0,0 +1,70 @@ +import { Array as FxArray, Context, Effect, HashMap, Layer, Option, pipe } from "effect"; +import type { NonEmptyReadonlyArray } from "effect/Array"; +import type { NoSuchElementError } from "effect/Cause"; +import { getAllSelectorFromDocument, getFirstSelectorFromDocument } from "../../scripts-effect/lib/dom.ts"; +import { + ATTRIBUT_ARIA_CONTROLS, + DOM_BOUTON_AJOUT_PANIER, + DOM_BOUTONS_ACCORDEON, + DOM_CONTENUS_ACCORDEON, + DOM_PRIX_PRODUIT, +} from "../constantes/dom.ts"; +import type { DetailEnsemble } from "./types.d.ts"; + +class ProductPageElements extends Context.Service< + ProductPageElements, + { + AddToCartButton: HTMLButtonElement; + Details: HashMap.HashMap; + DetailsButtons: NonEmptyReadonlyArray; + DetailsContents: NonEmptyReadonlyArray; + ProductPrice: HTMLParagraphElement; + ProductRawJson: HTMLScriptElement; + VariationChoiceForm: HTMLFormElement; + VariationSelectors: ReadonlyArray; + } +>()("haikuatelier.fr/Produit/ProductPageElements") { + static readonly layer = Layer.effect( + ProductPageElements, + Effect.gen(function*() { + const AddToCartButton = yield* getFirstSelectorFromDocument(DOM_BOUTON_AJOUT_PANIER); + const DetailsButtons = yield* getAllSelectorFromDocument(DOM_BOUTONS_ACCORDEON); + const DetailsContents = yield* getAllSelectorFromDocument(DOM_CONTENUS_ACCORDEON); + const ProductPrice = yield* getFirstSelectorFromDocument(DOM_PRIX_PRODUIT); + const ProductRawJson = yield* getFirstSelectorFromDocument("#product-json"); + const VariationChoiceForm = yield* getFirstSelectorFromDocument("#variation-choice"); + const VariationSelectors = yield* pipe( + getAllSelectorFromDocument(".selecteur-produit select"), + Option.orElseSome(() => FxArray.empty()), + ); + + const Details = yield* pipe( + DetailsButtons, + FxArray.map( + (button: HTMLButtonElement, index: number): Effect.Effect<[string, DetailEnsemble], NoSuchElementError> => + Effect.gen(function*() { + const contentId = yield* Option.fromNullishOr(button.getAttribute(ATTRIBUT_ARIA_CONTROLS)); + const content = yield* FxArray.get(DetailsContents, index); + + return [contentId, { button, content } satisfies DetailEnsemble]; + }), + ), + Effect.all, + Effect.map(HashMap.fromIterable), + ); + + return ProductPageElements.of({ + AddToCartButton, + Details, + DetailsButtons, + DetailsContents, + ProductPrice, + ProductRawJson, + VariationChoiceForm, + VariationSelectors, + }); + }), + ); +} + +export default ProductPageElements; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts new file mode 100644 index 00000000..f1940311 --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts @@ -0,0 +1,6 @@ +/** Représente un ensemble bouton-contenu d'une Section dans la description du Produit. */ +type DetailEnsemble = { + button: HTMLButtonElement; + content: HTMLDivElement; +}; +export { DetailEnsemble }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts index 74a5dc35..28116d1a 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts @@ -1,10 +1,8 @@ // Scripts pour la Page Produit -import { pipe } from "@mobily/ts-belt"; -import { Console, Effect, pipe as epipe } from "effect"; - - -import { ProductPageRuntime } from "./scripts-page-produit-service.ts"; +import { Console, Effect } from "effect"; +import ProductPageRuntime from "./page-produit/runtime.ts"; +import ProductPageDOM from "./page-produit/service-dom.ts"; /** États utiles pour les scripts de la page. */ type EtatsPage = { @@ -17,30 +15,28 @@ type EtatsPage = { // @ts-expect-error -- États injectés par le modèle PHP const ETATS_PAGE: EtatsPage = _etats; -const areArraysEqual = (array1: Array, array2: Array): boolean => { - if (array1 !== array2) { - const a1 = JSON.stringify(array1.toSorted()); - const a2 = JSON.stringify(array2.toSorted()); - return a1 === a2; - } - return true; -}; +document.addEventListener("DOMContentLoaded", (): void => { + console.debug("oups"); + Effect.gen(function* () { + const DOM = yield* ProductPageDOM; + console.debug("oups"); -const updatePriceOnAttributeChange = (): void => { - E.VARIATION_CHOICE_FORM.addEventListener("change", (): void => { - if (E.VARIATION_CHOICE_FORM.checkValidity() === false) { - return; - } + const effects = Effect.all( + [ + DOM.initAddToCartButtonInitialState(), + DOM.initAddToCartButtonUpdates(), + DOM.initDetailInteractions(), + DOM.initPriceUpdatesOnVariationChange(), + DOM.initAddToCartButtonClicks(), + ], + { + concurrency: "unbounded", + }, + ); - const productVariations: Array = epipe(E.PRODUCT_JSON.textContent, JSON.parse)?.variations; - const chosenAttributes = getAttributesFromDom(); - - const chosenVariation = productVariations.find(v => areArraysEqual(v.attributes, chosenAttributes)); - const newPrice: string = chosenVariation.price; - - E.PRIX_PRODUIT.textContent = `${newPrice}€`; - }); -}; + yield* effects.pipe(Effect.tapCause(Console.error)); + }).pipe(ProductPageRuntime.runFork); +}); // const ajouteProduitAuPanier = (event: MouseEvent): void => { // event.preventDefault(); @@ -129,10 +125,3 @@ const updatePriceOnAttributeChange = (): void => { // }) // .run(); // }; - -document.addEventListener("DOMContentLoaded", (): void => { - ProductPageRuntime.runFork(pipe(initAddToCartButton(), Effect.tapCause(Console.error))); - ProductPageRuntime.runFork(pipe(initAddToCartInteractionUpdates(), Effect.tapCause(Console.error))); - ProductPageRuntime.runFork(pipe(initDetailInteractions(), Effect.tapCause(Console.error))); - updatePriceOnAttributeChange(); -}); diff --git a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-completed-order.php b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-completed-order.php index db6b572b..61fbe911 100755 --- a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-completed-order.php +++ b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-completed-order.php @@ -12,7 +12,7 @@ use Illuminate\Support\Str; use Timber\Timber; if (!defined('ABSPATH')) { - exit(); + exit(); } // Initialise Timber @@ -30,13 +30,13 @@ $commande = $order; $date = new Carbon($commande->get_date_created()); $email = [ - 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], - 'livraison' => [ - 'transporteur' => Str::of($commande->get_shipping_method())->replace(' (Free)', ''), - 'numero_suivi' => blank($commande->get_meta('tracking_number')) - ? 'UNKNOWN_TRACKING_NUMBER' - : $commande->get_meta('tracking_number'), - ], + 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], + 'livraison' => [ + 'transporteur' => Str::of($commande->get_shipping_method())->replace(' (Free)', ''), + 'numero_suivi' => blank($commande->get_meta('tracking_number')) + ? 'UNKNOWN_TRACKING_NUMBER' + : $commande->get_meta('tracking_number'), + ], ]; $context['commande'] = $email; diff --git a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php index cd2e6b05..cbdcd419 100755 --- a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php +++ b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php @@ -13,7 +13,7 @@ use Illuminate\Support\Str; use Timber\Timber; if (!defined('ABSPATH')) { - exit(); + exit(); } // Initialise Timber @@ -31,49 +31,44 @@ $commande = $order; $date = new Carbon($commande->get_date_created()); $email = [ - 'adresses' => [ - 'facturation' => $commande->get_address('billing'), - 'livraison' => $commande->get_address('shipping'), - ], - 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], - 'livraison' => [ - 'methode' => $commande->get_shipping_method(), - 'numero_suivi' => $commande->get_meta('tracking_number'), - ], - 'paiement' => ['methode' => ''], - 'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) { - $produit = $article->get_product(); + 'adresses' => ['facturation' => $commande->get_address('billing'), 'livraison' => $commande->get_address('shipping')], + 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], + 'livraison' => [ + 'methode' => $commande->get_shipping_method(), + 'numero_suivi' => $commande->get_meta('tracking_number'), + ], + 'paiement' => ['methode' => ''], + 'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) { + $produit = $article->get_product(); - if (is_bool($produit) || $produit === null) { - return []; - } + if (is_bool($produit) || $produit === null) { + return []; + } - return [ - // Récupère l'Attribut d'un Produit variable ou renvoie un tableau vide - 'attribut' => $produit->is_type('variable') - ? collect($produit->get_attributes()) - ->mapWithKeys(static fn($_atr, $cle): array => [ - 'nom' => Str::lower(wc_attribute_label($cle, $produit)), - 'valeur' => $produit->get_attribute($cle), - ]) - ->toArray() - : [], - 'lien' => $produit->get_permalink(), - 'nom' => $produit->get_title(), - 'prix_total' => $article->get_total(), - 'quantite' => $article->get_quantity(), - ]; - }), - 'totaux' => [ - 'sous_total_livraison' => '0' === $commande->get_shipping_total() - ? 'Free' - : $commande->get_shipping_total() . '€', - 'sous_total_produits' => $commande->get_subtotal() . '€', - 'sous_total_reduction' => '0.00' === $commande->get_discount_total() - ? '0' - : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', - 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', - ], + return [ + // Récupère l'Attribut d'un Produit variable ou renvoie un tableau vide + 'attribut' => $produit->is_type('variable') + ? collect($produit->get_attributes()) + ->mapWithKeys(static fn($_atr, $cle): array => [ + 'nom' => Str::lower(wc_attribute_label($cle, $produit)), + 'valeur' => $produit->get_attribute($cle), + ]) + ->toArray() + : [], + 'lien' => $produit->get_permalink(), + 'nom' => $produit->get_title(), + 'prix_total' => $article->get_total(), + 'quantite' => $article->get_quantity(), + ]; + }), + 'totaux' => [ + 'sous_total_livraison' => '0' === $commande->get_shipping_total() ? 'Free' : $commande->get_shipping_total() . '€', + 'sous_total_produits' => $commande->get_subtotal() . '€', + 'sous_total_reduction' => '0.00' === $commande->get_discount_total() + ? '0' + : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', + 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', + ], ]; // Transforme les codes de pays en noms de pays $email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()]; diff --git a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php index ec64d829..830883aa 100755 --- a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php +++ b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php @@ -13,7 +13,7 @@ use Illuminate\Support\Str; use Timber\Timber; if (!defined('ABSPATH')) { - exit(); + exit(); } // Initialise Timber @@ -31,45 +31,40 @@ $commande = $order; $date = new Carbon($commande->get_date_created()); $email = [ - 'adresses' => [ - 'facturation' => $commande->get_address('billing'), - 'livraison' => $commande->get_address('shipping'), - ], - 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], - 'paiement' => ['methode' => ''], - 'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) { - $produit = $article->get_product(); + 'adresses' => ['facturation' => $commande->get_address('billing'), 'livraison' => $commande->get_address('shipping')], + 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], + 'paiement' => ['methode' => ''], + 'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) { + $produit = $article->get_product(); - if (is_bool($produit) || $produit === null) { - return []; - } + if (is_bool($produit) || $produit === null) { + return []; + } - return [ - // Récupère l'Attribut d'un Produit variable ou renvoie un tableau vide - 'attribut' => $article->is_type('variable') - ? collect($produit->get_attributes()) - ->mapWithKeys(static fn($_atr, $cle): array => [ - 'nom' => Str::lower(wc_attribute_label($cle, $produit)), - 'valeur' => $produit->get_attribute($cle), - ]) - ->toArray() - : [], - 'lien' => $produit->get_permalink(), - 'nom' => $produit->get_title(), - 'prix_total' => $article->get_total(), - 'quantite' => $article->get_quantity(), - ]; - }), - 'totaux' => [ - 'sous_total_livraison' => '0' === $commande->get_shipping_total() - ? 'Free' - : $commande->get_shipping_total() . '€', - 'sous_total_produits' => $commande->get_subtotal() . '€', - 'sous_total_reduction' => '0.00' === $commande->get_discount_total() - ? '0' - : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', - 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', - ], + return [ + // Récupère l'Attribut d'un Produit variable ou renvoie un tableau vide + 'attribut' => $article->is_type('variable') + ? collect($produit->get_attributes()) + ->mapWithKeys(static fn($_atr, $cle): array => [ + 'nom' => Str::lower(wc_attribute_label($cle, $produit)), + 'valeur' => $produit->get_attribute($cle), + ]) + ->toArray() + : [], + 'lien' => $produit->get_permalink(), + 'nom' => $produit->get_title(), + 'prix_total' => $article->get_total(), + 'quantite' => $article->get_quantity(), + ]; + }), + 'totaux' => [ + 'sous_total_livraison' => '0' === $commande->get_shipping_total() ? 'Free' : $commande->get_shipping_total() . '€', + 'sous_total_produits' => $commande->get_subtotal() . '€', + 'sous_total_reduction' => '0.00' === $commande->get_discount_total() + ? '0' + : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', + 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', + ], ]; // Transforme les codes de pays en noms de pays $email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()]; From 0e6be36e8513184971f7fe5077a5fe0528b81dad Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:00:55 +0200 Subject: [PATCH 2/7] =?UTF-8?q?corv=C3=A9e:=20met=20=C3=A0=20jour=20les=20?= =?UTF-8?q?d=C3=A9pendances?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lock | 216 +++++++++++++++++++++++++++++++++++++++----------- composer.lock | 102 ++++++++++++------------ package.json | 14 ++-- 3 files changed, 230 insertions(+), 102 deletions(-) diff --git a/bun.lock b/bun.lock index 18fe1f35..12d2b644 100644 --- a/bun.lock +++ b/bun.lock @@ -8,7 +8,7 @@ "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", "a11y-dialog": "^8.1.5", - "effect": "^4.0.0-beta.48", + "effect": "^4.0.0-beta.49", "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", @@ -26,11 +26,11 @@ "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001787", + "caniuse-lite": "^1.0.30001788", "eslint": "^10.2.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-oxlint": "^1.59.0", + "eslint-plugin-oxlint": "^1.60.0", "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "fdir": "^6.5.0", @@ -39,10 +39,10 @@ "knip": "^6.4.1", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", - "oxlint": "^1.59.0", - "oxlint-tsgolint": "^0.20.0", + "oxlint": "^1.60.0", + "oxlint-tsgolint": "^0.21.0", "playwright": "^1.59.1", - "prettier": "^3.8.1", + "prettier": "^3.8.3", "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.1", "sass-embedded": "^1.99.0", @@ -53,7 +53,7 @@ "stylelint-declaration-block-no-ignored-properties": "^3.0.0", "stylelint-plugin-logical-css": "^2.1.0", "typescript": "6.0.2", - "typescript-eslint": "^8.58.1", + "typescript-eslint": "^8.58.2", "vite": "^8.0.8", "vite-tsconfig-paths": "^6.1.1", }, @@ -428,55 +428,55 @@ "@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.19.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw=="], - "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.20.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KKQcIHZHMxqpHUA1VXIbOG6chNCFkUWbQy6M+AFVtPKkA/3xAeJkJ3njoV66bfzwPHRcWQO+kcj5XqtbkjakoA=="], + "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.21.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P20j3MLqfwIT+94qGU3htC7dWp4pXGZW1p1p7FRUzu1aopq7c9nPCgf0W/WjktqQ57+iuTq9mbSlwWinl6+H1A=="], - "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.20.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-7HeVMuclGfG+NLZi2ybY0T4fMI7/XxO/208rJk+zEIloKkVnlh11Wd241JMGwgNFXn+MLJbOqOfojDb2Dt4L1g=="], + "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.21.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-81TmmuBcPedEA0MwRmObuQuXnCprS1UiHQWGe7pseqNAJzUWXeAPrayqKTACX92VpruJI+yvY0XJrFp11PpcTA=="], - "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.20.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zxhUwz+WSxE6oWlZLK2z2ps9yC6ebmgoYmjAl0Oa48+GqkZ56NVgo+wb8DURNv6xrggzHStQxqQxe3mK51HZag=="], + "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.21.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-sbjBr6zDduX8rNO0PTjhf7VYLCPWqdijWiMPp8e10qu6Tam1GdaVLaLlX8QrNupTgglO1GvqqgY/jcacWL8a6g=="], - "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.20.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/1l6FnahC9im8PK+Ekkx/V3yetO/PzZnJegE2FXcv/iXEhbeVxP/ouiTYcUQu9shT1FWJCSNti1VJHH+21Y1dg=="], + "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.21.0", "", { "os": "linux", "cpu": "x64" }, "sha512-jNrOcy53R5TJQfrK444Cm60bW9437xDoxPbm3AdvFSo/fhdFMllawc7uZC2Wzr+EAjTkW13K8R4QHzsUdBG9fQ=="], - "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.20.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-oPZ5Yz8sVdo7P/5q+i3IKeix31eFZ55JAPa1+RGPoe9PoaYVsdMvR6Jvib6YtrqoJnFPlg3fjEjlEPL8VBKYJA=="], + "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.21.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-xWeRxJJILDE4b9UqHEWGBxcBc1TUS6zWHhxcyxTZMwf4q3wdKeu0OHYAcwLGJzoSjEIf6FTjyfPiRNil2oqsdg=="], - "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.20.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4stx8RHj3SP9vQyRF/yZbz5igtPvYMEUR8CUoha4BVNZihi39DpCR8qkU7lpjB5Ga1DRMo2pHaA4bdTOMaY4mw=="], + "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.21.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Ob9AA9teI8ckPo1whV1smLr5NrqwgBv/8boDbK0YZG+fKgNGRwr1hBj1ORgFWOQaUBv+5njp5A0RAfJJjQ95QQ=="], - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-etYDw/UaEv936AQUd/CRMBVd+e+XuuU6wC+VzOv1STvsTyZenLChepLWqLtnyTTp4YMlM22ypzogDDwqYxv5cg=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.60.0", "", { "os": "android", "cpu": "arm" }, "sha512-YdeJKaZckDQL1qa62a1aKq/goyq48aX3yOxaaWqWb4sau4Ee4IiLbamftNLU3zbePky6QsDj6thnSSzHRBjDfA=="], - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TgLc7XVLKH2a4h8j3vn1MDjfK33i9MY60f/bKhRGWyVzbk5LCZ4X01VZG7iHrMmi5vYbAp8//Ponigx03CLsdw=="], + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.60.0", "", { "os": "android", "cpu": "arm64" }, "sha512-7ANS7PpXCfq84xZQ8E5WPs14gwcuPcl+/8TFNXfpSu0CQBXz3cUo2fDpHT8v8HJN+Ut02eacvMAzTnc9s6X4tw=="], - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DXyFPf5ZKldMLloRHx/B9fsxsiTQomaw7cmEW3YIJko2HgCh+GUhp9gGYwHrqlLJPsEe3dYj9JebjX92D3j3AA=="], + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.60.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pJsgd9AfplLGBm1fIr25V6V14vMrayhx4uIQvlfH7jWs2SZwSrvi3TfgfJySB8T+hvyEH8K2zXljQiUnkgUnfQ=="], - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-LgvrsdgVLX1qWqIEmNsSmMXJhpAWdtUQ0M+oR0CySwi+9IHWyOGuIL8w8+u/kbZNMyZr4WUyYB5i0+D+AKgkLg=="], + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.60.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ue1aXHX49ivwflKqGJc7zcd/LeLgbhaTcDCQStgx5x06AXgjEAZmvrlMuIkWd4AL4FHQe6QJ9f33z04Cg448VQ=="], - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-bOJhqX/ny4hrFuTPlyk8foSRx/vLRpxJh0jOOKN2NWW6FScXHPAA5rQbrwdQPcgGB5V8Ua51RS03fke8ssBcug=="], + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.60.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YCyQzsQtusQw+gNRW9rRTifSO+Dt/+dtCl2NHoDMZqJlRTEZ/Oht9YnuporI9yiTx7+cB+eqzX3MtHHVHGIWhg=="], - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vVUXxYMF9trXCsz4m9H6U0IjehosVHxBzVgJUxly1uz4W1PdDyicaBnpC0KRXsHYretLVe+uS9pJy8iM57Kujw=="], + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.60.0", "", { "os": "linux", "cpu": "arm" }, "sha512-c7dxM2Zksa45Qw16i2iGY3Fti2NirJ38FrsBsKw+qcJ0OtqTsBgKJLF0xV+yLG56UH01Z8WRPgsw31e0MoRoGQ=="], - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-TULQW8YBPGRWg5yZpFPL54HLOnJ3/HiX6VenDPi6YfxB/jlItwSMFh3/hCeSNbh+DAMaE1Py0j5MOaivHkI/9Q=="], + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.60.0", "", { "os": "linux", "cpu": "arm" }, "sha512-ZWALoA42UYqBEP1Tbw9OWURgFGS1nWj2AAvLdY6ZcGx/Gj93qVCBKjcvwXMupZibYwFbi9s/rzqkZseb/6gVtQ=="], - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Gt54Y4eqSgYJ90xipm24xeyaPV854706o/kiT8oZvUt3VDY7qqxdqyGqchMaujd87ib+/MXvnl9WkK8Cc1BExg=="], + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.60.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-tpy+1w4p9hN5CicMCxqNy6ymfRtV5ayE573vFNjp1k1TN/qhLFgflveZoE/0++RlkHikBz2vY545NWm/hp7big=="], - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3CtsKp7NFB3OfqQzbuAecrY7GIZeiv7AD+xutU4tefVQzlfmTI7/ygWLrvkzsDEjTlMq41rYHxgsn6Yh8tybmA=="], + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.60.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-eDYDXZGhQAXyn6GwtwiX/qcLS0HlOLPJ/+iiIY8RYr+3P8oKBmgKxADLlniL6FtWfE7pPk7IGN9/xvDEvDvFeg=="], - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-K0diOpT3ncDmOfl9I1HuvpEsAuTxkts0VYwIv/w6Xiy9CdwyPBVX88Ga9l8VlGgMrwBMnSY4xIvVlVY/fkQk7Q=="], + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.60.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nxehly5XYBHUWI9VJX1bqCf9j/B43DaK/aS/T1fcxCpX3PA4Rm9BB54nPD1CKayT8xg6REN1ao+01hSRNgy8OA=="], - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-xAU7+QDU6kTJJ7mJLOGgo7oOjtAtkKyFZ0Yjdb5cEo3DiCCPFLvyr08rWiQh6evZ7RiUTf+o65NY/bqttzJiQQ=="], + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-j1qf/NaUfOWQutjeoooNG1Q0zsK0XGmSu1uDLq3cctquRF3j7t9Hxqf/76ehCc5GEUAanth2W4Fa+XT1RFg/nw=="], - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-KUmZmKlTTyauOnvUNVxK7G40sSSx0+w5l1UhaGsC6KPpOYHenx2oqJTnabmpLJicok7IC+3Y6fXAUOMyexaeJQ=="], + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-YELKPRefQ/q/h3RUmeRfPCUhh2wBvgV1RyZ/F9M9u8cDyXsQW2ojv1DeWQTt466yczDITjZnIOg/s05pk7Ve2A=="], - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4usRxC8gS0PGdkHnRmwJt/4zrQNZyk6vL0trCxwZSsAKM+OxhB8nKiR+mhjdBbl8lbMh2gc3bZpNN/ik8c4c2A=="], + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.60.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-JkO3C6Gki7Y6h/MiIkFKvHFOz98/YWvQ4WYbK9DLXACMP2rjULzkeGyAzorJE5S1dzLQGFgeqvN779kSFwoV1g=="], - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-s/rNE2gDmbwAOOP493xk2X7M8LZfI1LJFSSW1+yanz3vuQCFPiHkx4GY+O1HuLUDtkzGlhtMrIcxxzyYLv308w=="], + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.60.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XjKHdFVCpZZZSWBCKyyqCq65s2AKXykMXkjLoKYODrD+f5toLhlwsMESscu8FbgnJQ4Y/dpR/zdazsahmgBJIA=="], - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+yYj1udJa2UvvIUmEm0IcKgc0UlPMgz0nsSTvkPL2y6n0uU5LgIHSwVu4AHhrve6j9BpVSoRksnz8c9QcvITJA=="], + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.60.0", "", { "os": "linux", "cpu": "x64" }, "sha512-js29ZWIuPhNWzY8NC7KoffEMEeWG105vbmm+8EOJsC+T/jHBiKIJEUF78+F/IrgEWMMP9N0kRND4Pp75+xAhKg=="], - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bUplUb48LYsB3hHlQXP2ZMOenpieWoOyppLAnnAhuPag3MGPnt+7caxE3w/Vl9wpQsTA3gzLntQi9rxWrs7Xqg=="], + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.60.0", "", { "os": "none", "cpu": "arm64" }, "sha512-H+PUITKHk04stFpWj3x3Kg08Afp/bcXSBi0EhasR5a0Vw7StXHTzdl655PUI0fB4qdh2Wsu6Dsi+3ACxPoyQnA=="], - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/HLsLuz42rWl7h7ePdmMTpHm2HIDmPtcEMYgm5BBEHiEiuNOrzMaUpd2z7UnNni5LGN9obJy2YoAYBLXQwazrA=="], + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.60.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-WA/yc7f7ZfCefBXVzNHn1Ztulb1EFwNBb4jMZ6pjML0zz6pHujlF3Q3jySluz3XHl/GNeMTntG1seUBWVMlMag=="], - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-rUPy+JnanpPwV/aJCPnxAD1fW50+XPI0VkWr7f0vEbqcdsS8NpB24Rw6RsS7SdpFv8Dw+8ugCwao5nCFbqOUSg=="], + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.60.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-33YxL1sqwYNZXtn3MD/4dno6s0xeedXOJlT1WohkVD565WvohClZUr7vwKdAk954n4xiEWJkewiCr+zLeq7AeA=="], - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-xkE7puteDS/vUyRngLXW0t8WgdWoS/tfxXjhP/P7SMqPDx+hs44SpssO3h3qmTqECYEuXBUPzcAw5257Ka+ofA=="], + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.60.0", "", { "os": "win32", "cpu": "x64" }, "sha512-JOro4ZcfBLamJCyfURQmOQByoorgOdx3ZjAkSqnb/CyG/i+lN3KoV5LAgk5ZAW6DPq7/Cx7n23f8DuTWXTWgyQ=="], "@parcel/watcher": ["@parcel/watcher@2.5.6", "", { "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", "picomatch": "^4.0.3" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.6", "@parcel/watcher-darwin-arm64": "2.5.6", "@parcel/watcher-darwin-x64": "2.5.6", "@parcel/watcher-freebsd-x64": "2.5.6", "@parcel/watcher-linux-arm-glibc": "2.5.6", "@parcel/watcher-linux-arm-musl": "2.5.6", "@parcel/watcher-linux-arm64-glibc": "2.5.6", "@parcel/watcher-linux-arm64-musl": "2.5.6", "@parcel/watcher-linux-x64-glibc": "2.5.6", "@parcel/watcher-linux-x64-musl": "2.5.6", "@parcel/watcher-win32-arm64": "2.5.6", "@parcel/watcher-win32-ia32": "2.5.6", "@parcel/watcher-win32-x64": "2.5.6" } }, "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ=="], @@ -586,25 +586,25 @@ "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.58.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/type-utils": "8.58.1", "@typescript-eslint/utils": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.58.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.58.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/type-utils": "8.58.2", "@typescript-eslint/utils": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.58.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.58.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.58.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/types": "8.58.2", "@typescript-eslint/typescript-estree": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.1", "@typescript-eslint/types": "^8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.2", "@typescript-eslint/types": "^8.58.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg=="], "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1" } }, "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A=="], "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1", "@typescript-eslint/utils": "8.58.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w=="], "@typescript-eslint/types": ["@typescript-eslint/types@8.58.1", "", {}, "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.1", "@typescript-eslint/tsconfig-utils": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.2", "@typescript-eslint/tsconfig-utils": "8.58.2", "@typescript-eslint/types": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw=="], "@typescript-eslint/utils": ["@typescript-eslint/utils@8.58.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.2", "", { "dependencies": { "@typescript-eslint/types": "8.58.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA=="], "@typescript/lib-decorators": ["@better-typescript-lib/decorators@2.12.0", "", { "peerDependencies": { "typescript": ">=4.5.2" } }, "sha512-/m9Q5Xk66ThUJidTsxmXJH0+49iCLl5PFmue0HkNSGrcPU96oaoKNY5sH1AslwA/OWVvBg3hE58ZwSGm6TQFuQ=="], @@ -726,7 +726,7 @@ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - "caniuse-lite": ["caniuse-lite@1.0.30001787", "", {}, "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg=="], + "caniuse-lite": ["caniuse-lite@1.0.30001788", "", {}, "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ=="], "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="], @@ -796,7 +796,7 @@ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], - "effect": ["effect@4.0.0-beta.48", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-MMAM/ZabuNdNmgXiin+BAanQXK7qM8mlt7nfXDoJ/Gn9V8i89JlCq+2N0AiWmqFLXjGLA0u3FjiOjSOYQk5uMw=="], + "effect": ["effect@4.0.0-beta.49", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-4+mx856l4zxJJ+ybVNamqjAAinYsTNDVGZ5H3kstqKhDxCBW7sK/mZTtHuI7azt5AXEKX2ZXsi3EPAQVnkZk0w=="], "electron-to-chromium": ["electron-to-chromium@1.5.334", "", {}, "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog=="], @@ -838,7 +838,7 @@ "eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="], - "eslint-plugin-oxlint": ["eslint-plugin-oxlint@1.59.0", "", { "dependencies": { "jsonc-parser": "^3.3.1" }, "peerDependencies": { "oxlint": "~1.59.0" } }, "sha512-g0DR+xSsnUdyaMc2KAXvBVGWz5V4GwlAE1PM+ocKxl2Eg7YgOjkRLLbxgJ3bhYOhRLhD8F0X4DjJu2FSDvrvAg=="], + "eslint-plugin-oxlint": ["eslint-plugin-oxlint@1.60.0", "", { "dependencies": { "jsonc-parser": "^3.3.1" }, "peerDependencies": { "oxlint": "~1.60.0" } }, "sha512-9RUD23k7ablez1qg7JWnyPYPOlbucDDqaDr+qNUi0TbIQCPqIPCLzfllgqKF9lOxlg+l17H8hISErmarvm2J1w=="], "eslint-plugin-perfectionist": ["eslint-plugin-perfectionist@5.8.0", "", { "dependencies": { "@typescript-eslint/utils": "^8.58.0", "natural-orderby": "^5.0.0" }, "peerDependencies": { "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" } }, "sha512-k8uIptWIxkUclonCFGyDzgYs9NI+Qh0a7cUXS3L7IYZDEsjXuimFBVbxXPQQngWqMiaxJRwbtYB4smMGMqF+cw=="], @@ -1256,9 +1256,9 @@ "oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="], - "oxlint": ["oxlint@1.59.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.59.0", "@oxlint/binding-android-arm64": "1.59.0", "@oxlint/binding-darwin-arm64": "1.59.0", "@oxlint/binding-darwin-x64": "1.59.0", "@oxlint/binding-freebsd-x64": "1.59.0", "@oxlint/binding-linux-arm-gnueabihf": "1.59.0", "@oxlint/binding-linux-arm-musleabihf": "1.59.0", "@oxlint/binding-linux-arm64-gnu": "1.59.0", "@oxlint/binding-linux-arm64-musl": "1.59.0", "@oxlint/binding-linux-ppc64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-musl": "1.59.0", "@oxlint/binding-linux-s390x-gnu": "1.59.0", "@oxlint/binding-linux-x64-gnu": "1.59.0", "@oxlint/binding-linux-x64-musl": "1.59.0", "@oxlint/binding-openharmony-arm64": "1.59.0", "@oxlint/binding-win32-arm64-msvc": "1.59.0", "@oxlint/binding-win32-ia32-msvc": "1.59.0", "@oxlint/binding-win32-x64-msvc": "1.59.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-0xBLeGGjP4vD9pygRo8iuOkOzEU1MqOnfiOl7KYezL/QvWL8NUg6n03zXc7ZVqltiOpUxBk2zgHI3PnRIEdAvw=="], + "oxlint": ["oxlint@1.60.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.60.0", "@oxlint/binding-android-arm64": "1.60.0", "@oxlint/binding-darwin-arm64": "1.60.0", "@oxlint/binding-darwin-x64": "1.60.0", "@oxlint/binding-freebsd-x64": "1.60.0", "@oxlint/binding-linux-arm-gnueabihf": "1.60.0", "@oxlint/binding-linux-arm-musleabihf": "1.60.0", "@oxlint/binding-linux-arm64-gnu": "1.60.0", "@oxlint/binding-linux-arm64-musl": "1.60.0", "@oxlint/binding-linux-ppc64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-gnu": "1.60.0", "@oxlint/binding-linux-riscv64-musl": "1.60.0", "@oxlint/binding-linux-s390x-gnu": "1.60.0", "@oxlint/binding-linux-x64-gnu": "1.60.0", "@oxlint/binding-linux-x64-musl": "1.60.0", "@oxlint/binding-openharmony-arm64": "1.60.0", "@oxlint/binding-win32-arm64-msvc": "1.60.0", "@oxlint/binding-win32-ia32-msvc": "1.60.0", "@oxlint/binding-win32-x64-msvc": "1.60.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-tnRzTWiWJ9pg3ftRWnD0+Oqh78L6ZSwcEudvCZaER0PIqiAnNyXj5N1dPwjmNpDalkKS9m/WMLN1CTPUBPmsgw=="], - "oxlint-tsgolint": ["oxlint-tsgolint@0.20.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.20.0", "@oxlint-tsgolint/darwin-x64": "0.20.0", "@oxlint-tsgolint/linux-arm64": "0.20.0", "@oxlint-tsgolint/linux-x64": "0.20.0", "@oxlint-tsgolint/win32-arm64": "0.20.0", "@oxlint-tsgolint/win32-x64": "0.20.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-/Uc9TQyN1l8w9QNvXtVHYtz+SzDJHKpb5X0UnHodl0BVzijUPk0LPlDOHAvogd1UI+iy9ZSF6gQxEqfzUxCULQ=="], + "oxlint-tsgolint": ["oxlint-tsgolint@0.21.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.21.0", "@oxlint-tsgolint/darwin-x64": "0.21.0", "@oxlint-tsgolint/linux-arm64": "0.21.0", "@oxlint-tsgolint/linux-x64": "0.21.0", "@oxlint-tsgolint/win32-arm64": "0.21.0", "@oxlint-tsgolint/win32-x64": "0.21.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-HiWPhANwRnN1pZJQ2SgNB3WRR+1etLJHmRzQ/MJhyINsEIaOUCjxhlXJKbEaVUwdnyXwRWqo/P9Fx21lz0/mSg=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -1308,7 +1308,7 @@ "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], - "prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="], + "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], "prettier-plugin-curly": ["prettier-plugin-curly@0.4.1", "", { "peerDependencies": { "prettier": "^3" } }, "sha512-Xc7zatoD0/08zYFv+hwnlqT5ekM81DCbBr73CWAsr1Fmx7qLQT/M0wfPx6w/+zfnmXH009xYvjzLUPcwzq7Fbw=="], @@ -1556,7 +1556,7 @@ "typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], - "typescript-eslint": ["typescript-eslint@8.58.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.58.1", "@typescript-eslint/parser": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1", "@typescript-eslint/utils": "8.58.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg=="], + "typescript-eslint": ["typescript-eslint@8.58.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.58.2", "@typescript-eslint/parser": "8.58.2", "@typescript-eslint/typescript-estree": "8.58.2", "@typescript-eslint/utils": "8.58.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ=="], "unbash": ["unbash@2.2.0", "", {}, "sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w=="], @@ -1634,12 +1634,42 @@ "@gcch/configuration-eslint/globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + "@gcch/configuration-eslint/typescript-eslint": ["typescript-eslint@8.58.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.58.1", "@typescript-eslint/parser": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1", "@typescript-eslint/utils": "8.58.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg=="], + "@gcch/configuration-oxlint/globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="], + "@gcch/configuration-oxlint/oxlint": ["oxlint@1.59.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.59.0", "@oxlint/binding-android-arm64": "1.59.0", "@oxlint/binding-darwin-arm64": "1.59.0", "@oxlint/binding-darwin-x64": "1.59.0", "@oxlint/binding-freebsd-x64": "1.59.0", "@oxlint/binding-linux-arm-gnueabihf": "1.59.0", "@oxlint/binding-linux-arm-musleabihf": "1.59.0", "@oxlint/binding-linux-arm64-gnu": "1.59.0", "@oxlint/binding-linux-arm64-musl": "1.59.0", "@oxlint/binding-linux-ppc64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-musl": "1.59.0", "@oxlint/binding-linux-s390x-gnu": "1.59.0", "@oxlint/binding-linux-x64-gnu": "1.59.0", "@oxlint/binding-linux-x64-musl": "1.59.0", "@oxlint/binding-openharmony-arm64": "1.59.0", "@oxlint/binding-win32-arm64-msvc": "1.59.0", "@oxlint/binding-win32-ia32-msvc": "1.59.0", "@oxlint/binding-win32-x64-msvc": "1.59.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-0xBLeGGjP4vD9pygRo8iuOkOzEU1MqOnfiOl7KYezL/QvWL8NUg6n03zXc7ZVqltiOpUxBk2zgHI3PnRIEdAvw=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint": ["oxlint-tsgolint@0.20.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.20.0", "@oxlint-tsgolint/darwin-x64": "0.20.0", "@oxlint-tsgolint/linux-arm64": "0.20.0", "@oxlint-tsgolint/linux-x64": "0.20.0", "@oxlint-tsgolint/win32-arm64": "0.20.0", "@oxlint-tsgolint/win32-x64": "0.20.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-/Uc9TQyN1l8w9QNvXtVHYtz+SzDJHKpb5X0UnHodl0BVzijUPk0LPlDOHAvogd1UI+iy9ZSF6gQxEqfzUxCULQ=="], + + "@gcch/configuration-prettier/prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="], + "@keyv/bigmap/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.58.2", "", { "dependencies": { "@typescript-eslint/types": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2" } }, "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.58.2", "", { "dependencies": { "@typescript-eslint/types": "8.58.2", "@typescript-eslint/typescript-estree": "8.58.2", "@typescript-eslint/utils": "8.58.2", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.58.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/types": "8.58.2", "@typescript-eslint/typescript-estree": "8.58.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.58.2", "", { "dependencies": { "@typescript-eslint/types": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2" } }, "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q=="], + + "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.1", "@typescript-eslint/tsconfig-utils": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg=="], + + "@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.1", "@typescript-eslint/tsconfig-utils": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg=="], + + "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + "astro-eslint-parser/eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], "astro-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], @@ -1648,6 +1678,8 @@ "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001787", "", {}, "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg=="], + "browserslist-to-esbuild/meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], "cacheable/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], @@ -1676,6 +1708,8 @@ "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "prettier-plugin-ini/prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="], + "qified/hookified": ["hookified@2.1.1", "", {}, "sha512-AHb76R16GB5EsPBE2J7Ko5kiEyXwviB9P5SMrAKcuAu4vJPZttViAbj9+tZeaQE5zjDme+1vcHP78Yj/WoAveA=="], "rolldown/@oxc-project/types": ["@oxc-project/types@0.124.0", "", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="], @@ -1694,8 +1728,84 @@ "table/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.58.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.58.2", "@typescript-eslint/types": "8.58.2", "@typescript-eslint/typescript-estree": "8.58.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA=="], + "vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.58.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/type-utils": "8.58.1", "@typescript-eslint/utils": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.58.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.58.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/typescript-estree": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.58.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.58.1", "@typescript-eslint/tsconfig-utils": "8.58.1", "@typescript-eslint/types": "8.58.1", "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-etYDw/UaEv936AQUd/CRMBVd+e+XuuU6wC+VzOv1STvsTyZenLChepLWqLtnyTTp4YMlM22ypzogDDwqYxv5cg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TgLc7XVLKH2a4h8j3vn1MDjfK33i9MY60f/bKhRGWyVzbk5LCZ4X01VZG7iHrMmi5vYbAp8//Ponigx03CLsdw=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DXyFPf5ZKldMLloRHx/B9fsxsiTQomaw7cmEW3YIJko2HgCh+GUhp9gGYwHrqlLJPsEe3dYj9JebjX92D3j3AA=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-LgvrsdgVLX1qWqIEmNsSmMXJhpAWdtUQ0M+oR0CySwi+9IHWyOGuIL8w8+u/kbZNMyZr4WUyYB5i0+D+AKgkLg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-bOJhqX/ny4hrFuTPlyk8foSRx/vLRpxJh0jOOKN2NWW6FScXHPAA5rQbrwdQPcgGB5V8Ua51RS03fke8ssBcug=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vVUXxYMF9trXCsz4m9H6U0IjehosVHxBzVgJUxly1uz4W1PdDyicaBnpC0KRXsHYretLVe+uS9pJy8iM57Kujw=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-TULQW8YBPGRWg5yZpFPL54HLOnJ3/HiX6VenDPi6YfxB/jlItwSMFh3/hCeSNbh+DAMaE1Py0j5MOaivHkI/9Q=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Gt54Y4eqSgYJ90xipm24xeyaPV854706o/kiT8oZvUt3VDY7qqxdqyGqchMaujd87ib+/MXvnl9WkK8Cc1BExg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3CtsKp7NFB3OfqQzbuAecrY7GIZeiv7AD+xutU4tefVQzlfmTI7/ygWLrvkzsDEjTlMq41rYHxgsn6Yh8tybmA=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-K0diOpT3ncDmOfl9I1HuvpEsAuTxkts0VYwIv/w6Xiy9CdwyPBVX88Ga9l8VlGgMrwBMnSY4xIvVlVY/fkQk7Q=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-xAU7+QDU6kTJJ7mJLOGgo7oOjtAtkKyFZ0Yjdb5cEo3DiCCPFLvyr08rWiQh6evZ7RiUTf+o65NY/bqttzJiQQ=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-KUmZmKlTTyauOnvUNVxK7G40sSSx0+w5l1UhaGsC6KPpOYHenx2oqJTnabmpLJicok7IC+3Y6fXAUOMyexaeJQ=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4usRxC8gS0PGdkHnRmwJt/4zrQNZyk6vL0trCxwZSsAKM+OxhB8nKiR+mhjdBbl8lbMh2gc3bZpNN/ik8c4c2A=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-s/rNE2gDmbwAOOP493xk2X7M8LZfI1LJFSSW1+yanz3vuQCFPiHkx4GY+O1HuLUDtkzGlhtMrIcxxzyYLv308w=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+yYj1udJa2UvvIUmEm0IcKgc0UlPMgz0nsSTvkPL2y6n0uU5LgIHSwVu4AHhrve6j9BpVSoRksnz8c9QcvITJA=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bUplUb48LYsB3hHlQXP2ZMOenpieWoOyppLAnnAhuPag3MGPnt+7caxE3w/Vl9wpQsTA3gzLntQi9rxWrs7Xqg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/HLsLuz42rWl7h7ePdmMTpHm2HIDmPtcEMYgm5BBEHiEiuNOrzMaUpd2z7UnNni5LGN9obJy2YoAYBLXQwazrA=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-rUPy+JnanpPwV/aJCPnxAD1fW50+XPI0VkWr7f0vEbqcdsS8NpB24Rw6RsS7SdpFv8Dw+8ugCwao5nCFbqOUSg=="], + + "@gcch/configuration-oxlint/oxlint/@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-xkE7puteDS/vUyRngLXW0t8WgdWoS/tfxXjhP/P7SMqPDx+hs44SpssO3h3qmTqECYEuXBUPzcAw5257Ka+ofA=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.20.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KKQcIHZHMxqpHUA1VXIbOG6chNCFkUWbQy6M+AFVtPKkA/3xAeJkJ3njoV66bfzwPHRcWQO+kcj5XqtbkjakoA=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.20.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-7HeVMuclGfG+NLZi2ybY0T4fMI7/XxO/208rJk+zEIloKkVnlh11Wd241JMGwgNFXn+MLJbOqOfojDb2Dt4L1g=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.20.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zxhUwz+WSxE6oWlZLK2z2ps9yC6ebmgoYmjAl0Oa48+GqkZ56NVgo+wb8DURNv6xrggzHStQxqQxe3mK51HZag=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.20.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/1l6FnahC9im8PK+Ekkx/V3yetO/PzZnJegE2FXcv/iXEhbeVxP/ouiTYcUQu9shT1FWJCSNti1VJHH+21Y1dg=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.20.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-oPZ5Yz8sVdo7P/5q+i3IKeix31eFZ55JAPa1+RGPoe9PoaYVsdMvR6Jvib6YtrqoJnFPlg3fjEjlEPL8VBKYJA=="], + + "@gcch/configuration-oxlint/oxlint-tsgolint/@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.20.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4stx8RHj3SP9vQyRF/yZbz5igtPvYMEUR8CUoha4BVNZihi39DpCR8qkU7lpjB5Ga1DRMo2pHaA4bdTOMaY4mw=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.1", "@typescript-eslint/types": "^8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw=="], + + "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.1", "@typescript-eslint/types": "^8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw=="], + + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + "eslint-plugin-jsx-a11y/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], "stylelint/file-entry-cache/flat-cache": ["flat-cache@6.1.22", "", { "dependencies": { "cacheable": "^2.3.4", "flatted": "^3.4.2", "hookified": "^1.15.0" } }, "sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug=="], @@ -1706,6 +1816,22 @@ "table/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.58.2", "", { "dependencies": { "@typescript-eslint/types": "8.58.2", "@typescript-eslint/visitor-keys": "8.58.2" } }, "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q=="], + + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.58.2", "", {}, "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.58.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.58.1", "@typescript-eslint/types": "^8.58.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.58.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw=="], + + "@gcch/configuration-eslint/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.58.1", "", { "dependencies": { "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ=="], + "eslint-plugin-jsx-a11y/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], } } diff --git a/composer.lock b/composer.lock index 745e769e..90852164 100644 --- a/composer.lock +++ b/composer.lock @@ -585,7 +585,7 @@ }, { "name": "illuminate/collections", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -644,7 +644,7 @@ }, { "name": "illuminate/conditionable", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -690,16 +690,16 @@ }, { "name": "illuminate/contracts", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8" + "reference": "022d9816b4ff052a3db5946a86be3cd2e224db0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8", - "reference": "8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/022d9816b4ff052a3db5946a86be3cd2e224db0f", + "reference": "022d9816b4ff052a3db5946a86be3cd2e224db0f", "shasum": "" }, "require": { @@ -734,11 +734,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-26T17:13:01+00:00" + "time": "2026-04-12T17:46:48+00:00" }, { "name": "illuminate/macroable", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -784,7 +784,7 @@ }, { "name": "illuminate/reflection", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/reflection.git", @@ -835,16 +835,16 @@ }, { "name": "illuminate/support", - "version": "v13.4.0", + "version": "v13.5.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "e7ce0496cae80c3e1aa72e37f09335a6454846dc" + "reference": "0e8642a79d385c644a75400cad176b042242c894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/e7ce0496cae80c3e1aa72e37f09335a6454846dc", - "reference": "e7ce0496cae80c3e1aa72e37f09335a6454846dc", + "url": "https://api.github.com/repos/illuminate/support/zipball/0e8642a79d385c644a75400cad176b042242c894", + "reference": "0e8642a79d385c644a75400cad176b042242c894", "shasum": "" }, "require": { @@ -910,7 +910,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-04-07T13:34:38+00:00" + "time": "2026-04-13T14:52:53+00:00" }, { "name": "laravel/helpers", @@ -2506,7 +2506,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2565,7 +2565,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.35.0" }, "funding": [ { @@ -2589,7 +2589,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -2650,7 +2650,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.35.0" }, "funding": [ { @@ -2674,7 +2674,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -2734,7 +2734,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.35.0" }, "funding": [ { @@ -2758,7 +2758,7 @@ }, { "name": "symfony/polyfill-php84", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", @@ -2814,7 +2814,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.35.0" }, "funding": [ { @@ -2838,7 +2838,7 @@ }, { "name": "symfony/polyfill-php85", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", @@ -2894,7 +2894,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.35.0" }, "funding": [ { @@ -2918,7 +2918,7 @@ }, { "name": "symfony/polyfill-uuid", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", @@ -2977,7 +2977,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.35.0" }, "funding": [ { @@ -3701,15 +3701,15 @@ }, { "name": "wpackagist-plugin/woocommerce", - "version": "10.6.2", + "version": "10.7.0", "source": { "type": "svn", "url": "https://plugins.svn.wordpress.org/woocommerce/", - "reference": "tags/10.6.2" + "reference": "tags/10.7.0" }, "dist": { "type": "zip", - "url": "https://downloads.wordpress.org/plugin/woocommerce.10.6.2.zip" + "url": "https://downloads.wordpress.org/plugin/woocommerce.10.7.0.zip" }, "require": { "composer/installers": "^1.0 || ^2.0" @@ -4516,11 +4516,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.46", + "version": "2.1.47", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a193923fc2d6325ef4e741cf3af8c3e8f54dbf25", - "reference": "a193923fc2d6325ef4e741cf3af8c3e8f54dbf25", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/79015445d8bd79e62b29140f12e5bfced1dcca65", + "reference": "79015445d8bd79e62b29140f12e5bfced1dcca65", "shasum": "" }, "require": { @@ -4565,7 +4565,7 @@ "type": "github" } ], - "time": "2026-04-01T09:25:14+00:00" + "time": "2026-04-13T15:49:08+00:00" }, { "name": "psr/event-dispatcher", @@ -5199,12 +5199,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "d830a949e5c180e97c2245221daf8b589552cc2c" + "reference": "f8c7911d543be053da1601797a9d471110222b08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/d830a949e5c180e97c2245221daf8b589552cc2c", - "reference": "d830a949e5c180e97c2245221daf8b589552cc2c", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f8c7911d543be053da1601797a9d471110222b08", + "reference": "f8c7911d543be053da1601797a9d471110222b08", "shasum": "" }, "conflict": { @@ -5334,7 +5334,7 @@ "codingms/modules": "<4.3.11|>=5,<5.7.4|>=6,<6.4.2|>=7,<7.5.5", "commerceteam/commerce": ">=0.9.6,<0.9.9", "components/jquery": ">=1.0.3,<3.5", - "composer/composer": "<1.10.27|>=2,<2.2.26|>=2.3,<2.9.3", + "composer/composer": "<1.10.27|>=2,<2.2.27|>=2.3,<2.9.6", "concrete5/concrete5": "<9.4.8", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", @@ -5351,7 +5351,7 @@ "cpsit/typo3-mailqueue": "<0.4.5|>=0.5,<0.5.2", "craftcms/aws-s3": ">=2.0.2,<=2.2.4", "craftcms/azure-blob": ">=2.0.0.0-beta1,<=2.1", - "craftcms/cms": "<=4.17.7|>=5,<=5.9.13", + "craftcms/cms": "<=4.17.8|>=5,<5.9.15", "craftcms/commerce": ">=4,<4.11|>=5,<5.6", "craftcms/composer": ">=4.0.0.0-RC1-dev,<=4.10|>=5.0.0.0-RC1-dev,<=5.5.1", "craftcms/craft": ">=3.5,<=4.16.17|>=5.0.0.0-RC1-dev,<=5.8.21", @@ -5619,7 +5619,7 @@ "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", "khodakhah/nodcms": "<=3", - "kimai/kimai": "<=2.50", + "kimai/kimai": "<=2.52", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", "knplabs/knp-snappy": "<=1.4.2", @@ -5637,7 +5637,7 @@ "laravel/fortify": "<1.11.1", "laravel/framework": "<10.48.29|>=11,<11.44.1|>=12,<12.1.1", "laravel/laravel": ">=5.4,<5.4.22", - "laravel/passport": "<13.7.1", + "laravel/passport": ">=13,<13.7.1", "laravel/pulse": "<1.3.1", "laravel/reverb": "<1.7", "laravel/socialite": ">=1,<2.0.10", @@ -5760,8 +5760,8 @@ "october/backend": "<1.1.2", "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", "october/october": "<3.7.5", - "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<=3.7.12|>=4,<=4.0.11", + "october/rain": "<=3.7.13|>=4,<=4.1.9", + "october/system": "<=3.7.13|>=4,<=4.1.9", "oliverklee/phpunit": "<3.5.15", "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.21.1|>=3,<3.8.1|>=4,<4.3.1", @@ -5894,6 +5894,7 @@ "rudloff/rtmpdump-bin": "<=2.3.1", "s-cart/core": "<=9.0.5", "s-cart/s-cart": "<6.9", + "s9y/serendipity": "<2.6", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", "saloonphp/saloon": "<4", @@ -6123,6 +6124,7 @@ "webcoast/deferred-image-processing": "<1.0.2", "webklex/laravel-imap": "<5.3", "webklex/php-imap": "<5.3", + "webonyx/graphql-php": "<=15.31.4", "webpa/webpa": "<3.1.2", "webreinvent/vaahcms": "<=2.3.1", "wikibase/wikibase": "<=1.39.3", @@ -6142,7 +6144,7 @@ "wpcloud/wp-stateless": "<3.2", "wpglobus/wpglobus": "<=1.9.6", "wpmetabox/meta-box": "<5.11.2", - "wwbn/avideo": "<=26", + "wwbn/avideo": "<=29", "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", @@ -6242,7 +6244,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T21:13:58+00:00" + "time": "2026-04-15T00:40:17+00:00" }, { "name": "sebastian/diff", @@ -6785,7 +6787,7 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", @@ -6843,7 +6845,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.35.0" }, "funding": [ { @@ -6867,7 +6869,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -6928,7 +6930,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.35.0" }, "funding": [ { @@ -6952,7 +6954,7 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.34.0", + "version": "v1.35.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", @@ -7008,7 +7010,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.34.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.35.0" }, "funding": [ { diff --git a/package.json b/package.json index 2817ca75..11513c4d 100755 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@mobily/ts-belt": "v4.0.0-rc.5", "@sentry/browser": "^10.47.0", "a11y-dialog": "^8.1.5", - "effect": "^4.0.0-beta.48", + "effect": "^4.0.0-beta.49", "lit-html": "^3.3.2", "purify-ts": "2.1.2", "ts-pattern": "^5.9.0", @@ -32,11 +32,11 @@ "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001787", + "caniuse-lite": "^1.0.30001788", "eslint": "^10.2.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-oxlint": "^1.59.0", + "eslint-plugin-oxlint": "^1.60.0", "eslint-plugin-perfectionist": "^5.8.0", "eslint-plugin-sonarjs": "^4.0.2", "fdir": "^6.5.0", @@ -45,10 +45,10 @@ "knip": "^6.4.1", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", - "oxlint": "^1.59.0", - "oxlint-tsgolint": "^0.20.0", + "oxlint": "^1.60.0", + "oxlint-tsgolint": "^0.21.0", "playwright": "^1.59.1", - "prettier": "^3.8.1", + "prettier": "^3.8.3", "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.1", "sass-embedded": "^1.99.0", @@ -59,7 +59,7 @@ "stylelint-declaration-block-no-ignored-properties": "^3.0.0", "stylelint-plugin-logical-css": "^2.1.0", "typescript": "6.0.2", - "typescript-eslint": "^8.58.1", + "typescript-eslint": "^8.58.2", "vite": "^8.0.8", "vite-tsconfig-paths": "^6.1.1" }, From 20935b7b5043f53f784a0cbf2244eeea63f56b15 Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:10:39 +0200 Subject: [PATCH 3/7] =?UTF-8?q?fonc:=20d=C3=A9place=20l'injection=20de=20d?= =?UTF-8?q?onn=C3=A9es=20du=20Produit=20dans=20un=20script=20JSON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haiku-atelier-2024/single-product.php | 21 +++++++++++----- .../haiku-atelier-2024/views/produit.twig | 25 ++++++------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/web/app/themes/haiku-atelier-2024/single-product.php b/web/app/themes/haiku-atelier-2024/single-product.php index e08501e1..445b0b68 100755 --- a/web/app/themes/haiku-atelier-2024/single-product.php +++ b/web/app/themes/haiku-atelier-2024/single-product.php @@ -22,7 +22,9 @@ use function add_action; use function assert; use function collect; use function is_array; +use function is_string; use function wc_get_product; +use function wp_create_nonce; use function wp_json_encode; $context = Timber::context(); @@ -66,12 +68,19 @@ $product_tags = $raw_product->get_tag_ids() |> (static fn(/** @var list> */ $tags) => Arr::map($tags, static fn($tag) => $tag->unwrap())); $tags = get_terms(['taxonomy' => 'product_tag', 'hide_empty' => true]); -// echo '
';
-// print_r($product_tags);
-// print_r($tags);
-// echo '
'; - -// exit(); +// Injecte les états initiaux des données du Produit sous forme de JSON dans le contexte. +$page_states = [ + 'nonce' => wp_create_nonce('wc_store_api'), + 'product' => [ + 'attributes' => $product->attributes, + 'id' => $product->id, + 'price' => $product->price, + 'variations' => $product->variations, + ], +] + |> wp_json_encode(...); +assert(is_string($page_states)); +$context['page_states'] = $page_states; add_action('wp_enqueue_scripts', function (): void { Resource::enqueue_script_module_file( diff --git a/web/app/themes/haiku-atelier-2024/views/produit.twig b/web/app/themes/haiku-atelier-2024/views/produit.twig index 8835f74b..fe259b74 100755 --- a/web/app/themes/haiku-atelier-2024/views/produit.twig +++ b/web/app/themes/haiku-atelier-2024/views/produit.twig @@ -1,23 +1,6 @@ {% extends 'base.twig' %} {% block head %} - - + + + {% endblock head %} {% block contenu %} From 2bc7af69fe8c27d79d2d41a8f455edb186a1051a Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:30:27 +0200 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20linte=20avec=20oxc=20seulement=20?= =?UTF-8?q?=C3=A0=20la=20sauvegarde=20du=20fichier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Un passage de lint peut prendre jusqu'à 100% du CPU. --- .zed/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zed/settings.json b/.zed/settings.json index fd002a27..ec9c977f 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -17,7 +17,7 @@ "configPath": "cfg/oxlint.config.ts", "disableNestedConfig": false, "fixKind": "safe_fix", - "run": "onType", + "run": "onSave", "unusedDisableDirectives": "deny" } } From cf761709ddb259b4a08e670f034f849754e04b56 Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:30:27 +0200 Subject: [PATCH 5/7] =?UTF-8?q?corv=C3=A9e:=20met=20=C3=A0=20jour=20Mago?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mago-schema.json | 1689 +++++++++++++++++++++++++++++----------------- mago.toml | 8 +- 2 files changed, 1063 insertions(+), 634 deletions(-) diff --git a/mago-schema.json b/mago-schema.json index a4a12e52..6d8bf9d4 100644 --- a/mago-schema.json +++ b/mago-schema.json @@ -9,6 +9,11 @@ "description": "Allow accessing array keys that may not be defined without reporting an issue.", "type": "boolean" }, + "allow-side-effects-in-conditions": { + "default": true, + "description": "Whether to allow calls to impure functions inside conditions.\n\nWhen set to `false`, any call to a function not marked `@pure` or\n`@mutation-free` inside an `if`, `while`, `for`, ternary, or `match`\ncondition is reported. This helps catch surprising evaluation-order\nbugs where a side effect in one part of a condition silently alters\na variable used in another part.\n\nDefaults to `true` (impure calls in conditions are allowed).", + "type": "boolean" + }, "analyze-dead-code": { "default": false, "description": "Whether to analyze dead code.", @@ -98,6 +103,11 @@ }, "type": "array" }, + "find-overly-wide-return-types": { + "default": false, + "description": "Whether to warn when a function's declared return type contains a branch the body never\nactually returns (e.g. `: string|false` on a function that always returns a string).", + "type": "boolean" + }, "find-unused-definitions": { "default": true, "description": "Whether to find unused definitions.", @@ -147,11 +157,12 @@ "performance": { "$ref": "#/$defs/PerformanceConfiguration", "default": { - "array-combination-threshold": 128, + "array-combination-threshold": 32, "consensus-limit-threshold": 256, "disjunction-complexity-threshold": 4096, "formula-size-threshold": 512, "integer-combination-threshold": 128, + "loop-assignment-depth-threshold": 1, "negation-complexity-threshold": 4096, "saturation-complexity-threshold": 8192, "string-combination-threshold": 128 @@ -271,6 +282,33 @@ ], "description": "An entry that can be either a simple string or an object with name and optional help." }, + "DisallowedTypeEntry": { + "anyOf": [ + { + "description": "Simple string entry (just the name).", + "type": "string" + }, + { + "description": "Entry with name and optional help message.", + "properties": { + "help": { + "type": [ + "null", + "string" + ] + }, + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + ], + "description": "An entry that can be either a simple string or an object with name and optional help." + }, "EndOfLine": { "description": "Specifies the style of line endings.", "enum": [ @@ -290,6 +328,16 @@ "description": "Whether to align consecutive assignment-like constructs in columns.\n\nWhen enabled, consecutive variable assignments, class properties, class constants,\nglobal constants, array key-value pairs, and backed enum cases are column-aligned.\n\nFor arrays, this applies to multiline or width-broken mappings. Compact inline arrays\nstay compact and are not padded into columns.\n\nExample with `true`:\n```php\n$foo = 1;\n$b = 2;\n$ccccccc = 3;\n\nclass X {\n public string $foo = 1;\n public readonly int $barrrr = 2;\n}\n```\n\nExample with `false`:\n```php\n$foo = 1;\n$b = 2;\n$ccccccc = 3;\n```\n\nNote: Blank lines and comments break alignment runs. In class bodies,\ndifferent member types (properties vs constants) are aligned separately.\n\nDefault: false", "type": "boolean" }, + "align-named-arguments": { + "default": false, + "description": "Whether to align named arguments in multiline argument lists.\n\nWhen enabled:\n```php\nsome_function(\n short: 1,\n longerName: 2,\n longestName: 3,\n);\n```\n\nSingle-line argument lists remain inline, and positional arguments are not aligned.\n\nDefault: false", + "type": "boolean" + }, + "align-parameters": { + "default": false, + "description": "Whether to align multiline function and method parameter lists by the variable column.\n\nThis is especially useful for promoted constructor properties with visibility modifiers.\n\nDefault: false", + "type": "boolean" + }, "always-break-attribute-named-argument-lists": { "default": false, "description": "Whether to always break named argument lists in attributes into multiple lines.\n\nWhen enabled:\n```php\n#[SomeAttribute(\n argument1: 'value1',\n argument2: 'value2',\n)]\nclass Foo {}\n```\n\nDefault: false", @@ -512,6 +560,16 @@ "default": "question", "description": "How to format null type hints.\n\nWith `Question`:\n```php\nfunction foo(\n ?string $a,\n null|int|string $b,\n int|null|string $c,\n) {}\n```\n\nWith `NullPipe`:\n```php\nfunction foo(\n null|string $a,\n null|int|string $b,\n int|null|string $c,\n) {}\n```\n\nWith `NullPipeLast`:\n```php\nfunction foo(\n string|null $a,\n int|string|null $b,\n int|string|null $c,\n) {}\n```\n\nDefault: `Question`" }, + "omit-redundant-arithmetic-binary-expression-parentheses": { + "default": false, + "description": "Whether to omit redundant parentheses around arithmetic binary expressions under comparison and null coalesce expressions.\n\nWhen enabled, parentheses are omitted where PHP precedence already preserves meaning:\n```php\nif ($i === $retries - 1) {\n}\n```\n\nWhen disabled, arithmetic binary expressions keep Mago's default grouping style:\n```php\nif ($i === ($retries - 1)) {\n}\n```\n\nDefault: false", + "type": "boolean" + }, + "omit-redundant-bitwise-binary-expression-parentheses": { + "default": false, + "description": "Whether to omit redundant parentheses around bitwise binary child expressions.\n\nWhen enabled, parentheses are omitted around bitwise binary child expressions where PHP precedence and\nassociativity already preserve meaning:\n```php\nif ($mask === $flags << 1) {\n}\n```\n\nWhen disabled, bitwise binary child expressions keep Mago's default grouping style:\n```php\nif ($mask === ($flags << 1)) {\n}\n```\n\nDefault: false", + "type": "boolean" + }, "opening-tag-on-own-line": { "default": true, "description": "Whether the opening `method1()\n ->method2()\n ->method3();\n```\n\nWhen disabled:\n```php\n$object\n ->method1()\n ->method2()\n ->method3();\n```\n\nDefault: false", + "type": "boolean" + }, "preserve-breaking-parameter-list": { "default": false, "description": "Whether to preserve line breaks in parameter lists, even if they could fit on a single line.\n\nDefault: false", @@ -833,7 +896,7 @@ "type": "string" }, { - "description": "Ignore a code in specific paths: `{ code = \"code2\", in = \"path/\" }`", + "description": "Ignore a code in specific paths or glob patterns:\n`{ code = \"code2\", in = [\"tests/\", \"src/**/*.php\"] }`", "properties": { "code": { "type": "string" @@ -852,7 +915,7 @@ "type": "object" } ], - "description": "Represents an entry in the analyzer's `ignore` configuration.\n\nCan be either a plain code string (ignored everywhere) or a scoped entry\nthat only ignores a code in specific paths." + "description": "Represents an entry in the analyzer's `ignore` configuration.\n\nCan be either a plain code string (ignored everywhere) or a scoped entry\nthat only ignores a code in specific paths. Scoped paths accept both\nplain directory/file prefixes (e.g. `\"tests/\"`, `\"src/Legacy.php\"`) and\nglob patterns (e.g. `\"src/**/*.php\"`); entries\ncontaining any of `*`, `?`, `[`, `{` are matched with [`ExclusionMatcher`]." }, "Level": { "description": "Represents the severity level of an issue.", @@ -990,6 +1053,11 @@ "functions": [], "level": "Warning" }, + "disallowed-type-instantiation": { + "enabled": false, + "level": "Warning", + "types": [] + }, "enum-name": { "enabled": true, "level": "Help" @@ -1241,6 +1309,10 @@ "enabled": false, "level": "Warning" }, + "no-literal-namespace-string": { + "enabled": false, + "level": "Warning" + }, "no-literal-password": { "enabled": true, "level": "Error" @@ -1257,6 +1329,10 @@ "enabled": true, "level": "Help" }, + "no-null-property-init": { + "enabled": false, + "level": "Help" + }, "no-only": { "enabled": true, "level": "Error" @@ -1357,6 +1433,25 @@ "enabled": true, "level": "Warning" }, + "no-service-state-mutation": { + "allowed-methods": [ + "__construct", + "reset" + ], + "enabled": false, + "exclude-namespaces": [ + "App\\DTO\\", + "App\\Entity\\", + "App\\ValueObject\\" + ], + "include-namespaces": [ + "App\\" + ], + "level": "Warning", + "reset-interfaces": [ + "Symfony\\Contracts\\Service\\ResetInterface" + ] + }, "no-shell-execute-string": { "enabled": true, "level": "Error" @@ -1373,6 +1468,13 @@ "enabled": true, "level": "Warning" }, + "no-side-effects-with-declarations": { + "allow-class-alias": true, + "allow-class-exists": true, + "allow-conditional-declarations": true, + "enabled": false, + "level": "Warning" + }, "no-sprintf-concat": { "enabled": true, "level": "Warning" @@ -1536,6 +1638,11 @@ "enabled": true, "level": "Warning" }, + "string-style": { + "enabled": false, + "level": "Note", + "style": "interpolation" + }, "switch-continue-to-break": { "enabled": false, "level": "Warning" @@ -1663,8 +1770,8 @@ "description": "Performance tuning settings for the analyzer.\n\nThese thresholds control the complexity limits for logical formula operations.\nAdjusting these values allows trading off between analysis precision and speed.", "properties": { "array-combination-threshold": { - "default": 128, - "description": "Maximum number of array elements to track individually.\n\nWhen building array types through repeated push operations (`$arr[] = ...`),\nthis limits how many individual elements are tracked before generalizing\nto a simpler array type. This prevents memory explosion on files with\nthousands of array pushes.\n\nDefaults to `128`.", + "default": 32, + "description": "Maximum number of array elements to track individually.\n\nWhen building array types through repeated push operations (`$arr[] = ...`),\nthis limits how many individual elements are tracked before generalizing\nto a simpler array type. This prevents memory explosion on files with\nthousands of array pushes.\n\nDefaults to `32`.", "format": "uint16", "maximum": 65535, "minimum": 0, @@ -1702,6 +1809,14 @@ "minimum": 0, "type": "integer" }, + "loop-assignment-depth-threshold": { + "default": 1, + "description": "Maximum depth of the loop assignment dependency graph that the\nfixed-point analyzer will explore when re-analysing loop bodies.\n\nThe analyzer uses fixed-point iteration to propagate widened types\nalong loop-carried dependency chains. A chain of length `N` can\nrequire up to `N` extra passes for the type at the end of the chain\nto fully stabilise, and each pass re-analyses the entire loop body.\nOn large, complex loops the per-pass cost dominates file analysis\ntime.\n\nThe default of `1` means each loop body is re-analysed at most once\nafter the initial pass; enough to stabilise virtually all real-world\ncode while keeping analysis cost bounded. Projects that require\nmaximally precise narrowing of long loop-carried chains can raise\nthis value (typically to `2` or `3`) at the cost of significantly\nslower analysis on complex files. Setting this to `0` disables\nfixed-point iteration entirely.\n\nDefaults to `1`.", + "format": "uint8", + "maximum": 255, + "minimum": 0, + "type": "integer" + }, "negation-complexity-threshold": { "default": 4096, "description": "Maximum cumulative complexity during formula negation.\n\nControls how complex the negation of a formula can become.\nIf exceeded, negation gives up to avoid exponential blowup.\n\nDefaults to `4096`.", @@ -1888,12 +2003,32 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" }, "RuleSettings102": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Help" + } + }, + "type": "object" + }, + "RuleSettings103": { "additionalProperties": false, "properties": { "enabled": { @@ -1919,7 +2054,7 @@ }, "type": "object" }, - "RuleSettings103": { + "RuleSettings104": { "additionalProperties": false, "properties": { "enabled": { @@ -1939,7 +2074,7 @@ }, "type": "object" }, - "RuleSettings104": { + "RuleSettings105": { "additionalProperties": false, "properties": { "enabled": { @@ -1959,7 +2094,7 @@ }, "type": "object" }, - "RuleSettings105": { + "RuleSettings106": { "additionalProperties": false, "properties": { "enabled": { @@ -1979,7 +2114,7 @@ }, "type": "object" }, - "RuleSettings106": { + "RuleSettings107": { "additionalProperties": false, "properties": { "enabled": { @@ -1999,26 +2134,6 @@ }, "type": "object" }, - "RuleSettings107": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Note" - } - }, - "type": "object" - }, "RuleSettings108": { "additionalProperties": false, "properties": { @@ -2034,7 +2149,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Note" } }, "type": "object" @@ -2138,7 +2253,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Warning" } }, "type": "object" @@ -2158,7 +2273,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Error" } }, "type": "object" @@ -2266,10 +2381,6 @@ "RuleSettings119": { "additionalProperties": false, "properties": { - "allow-loose-behavior": { - "default": false, - "type": "boolean" - }, "enabled": { "default": true, "type": "boolean" @@ -2310,7 +2421,7 @@ "RuleSettings120": { "additionalProperties": false, "properties": { - "allow-disabling": { + "allow-loose-behavior": { "default": false, "type": "boolean" }, @@ -2334,6 +2445,10 @@ "RuleSettings121": { "additionalProperties": false, "properties": { + "allow-disabling": { + "default": false, + "type": "boolean" + }, "enabled": { "default": true, "type": "boolean" @@ -2386,14 +2501,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" - }, - "threshold": { - "default": 20, - "format": "uint16", - "maximum": 65535, - "minimum": 0, - "type": "integer" + "default": "Warning" } }, "type": "object" @@ -2401,14 +2509,6 @@ "RuleSettings124": { "additionalProperties": false, "properties": { - "count-hooks": { - "default": false, - "type": "boolean" - }, - "count-setters-and-getters": { - "default": false, - "type": "boolean" - }, "enabled": { "default": true, "type": "boolean" @@ -2424,7 +2524,7 @@ "default": "Error" }, "threshold": { - "default": 10, + "default": 20, "format": "uint16", "maximum": 65535, "minimum": 0, @@ -2436,6 +2536,14 @@ "RuleSettings125": { "additionalProperties": false, "properties": { + "count-hooks": { + "default": false, + "type": "boolean" + }, + "count-setters-and-getters": { + "default": false, + "type": "boolean" + }, "enabled": { "default": true, "type": "boolean" @@ -2475,11 +2583,14 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Error" }, - "psr": { - "default": false, - "type": "boolean" + "threshold": { + "default": 10, + "format": "uint16", + "maximum": 65535, + "minimum": 0, + "type": "integer" } }, "type": "object" @@ -2499,12 +2610,36 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Help" + }, + "psr": { + "default": false, + "type": "boolean" } }, "type": "object" }, "RuleSettings128": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Note" + } + }, + "type": "object" + }, + "RuleSettings129": { "additionalProperties": false, "properties": { "camel": { @@ -2536,26 +2671,6 @@ }, "type": "object" }, - "RuleSettings129": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Help" - } - }, - "type": "object" - }, "RuleSettings13": { "additionalProperties": false, "properties": { @@ -2580,7 +2695,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -2591,7 +2706,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -2600,7 +2715,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -2620,7 +2735,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -2651,7 +2766,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Warning" } }, "type": "object" @@ -2660,7 +2775,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -2679,8 +2794,23 @@ "RuleSettings135": { "additionalProperties": false, "properties": { - "enabled": { + "allow-class-alias": { "default": true, + "description": "When true, top-level `class_alias(...)` calls are allowed alongside\ndeclarations.", + "type": "boolean" + }, + "allow-class-exists": { + "default": true, + "description": "When true, top-level `class_exists(...)` calls are allowed alongside\ndeclarations. This is commonly used to trigger autoloading/preloading.", + "type": "boolean" + }, + "allow-conditional-declarations": { + "default": true, + "description": "When true, conditional declarations (`if (...) { class Foo {} }`)\nare allowed alongside declarations. This covers the common pattern\nof polyfilling a class depending on an extension or PHP version.", + "type": "boolean" + }, + "enabled": { + "default": false, "type": "boolean" }, "exclude": { @@ -2691,7 +2821,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Warning" } }, "type": "object" @@ -2709,16 +2839,6 @@ }, "type": "array" }, - "known-sink-functions": { - "default": [ - "printf" - ], - "items": { - "type": "string" - }, - "type": "array", - "uniqueItems": true - }, "level": { "$ref": "#/$defs/Level", "default": "Error" @@ -2749,16 +2869,8 @@ "RuleSettings138": { "additionalProperties": false, "properties": { - "camel": { - "default": true, - "type": "boolean" - }, - "either": { - "default": false, - "type": "boolean" - }, "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -2767,9 +2879,19 @@ }, "type": "array" }, + "known-sink-functions": { + "default": [ + "printf" + ], + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Error" } }, "type": "object" @@ -2833,10 +2955,18 @@ "RuleSettings140": { "additionalProperties": false, "properties": { - "enabled": { + "camel": { "default": true, "type": "boolean" }, + "either": { + "default": false, + "type": "boolean" + }, + "enabled": { + "default": false, + "type": "boolean" + }, "exclude": { "items": { "type": "string" @@ -2845,7 +2975,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -2865,7 +2995,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Error" } }, "type": "object" @@ -2925,12 +3055,71 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" }, "RuleSettings145": { + "additionalProperties": false, + "properties": { + "allowed-methods": { + "default": [ + "__construct", + "reset" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "enabled": { + "default": false, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "exclude-namespaces": { + "default": [ + "App\\DTO\\", + "App\\Entity\\", + "App\\ValueObject\\" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "include-namespaces": { + "default": [ + "App\\" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Warning" + }, + "reset-interfaces": { + "default": [ + "Symfony\\Contracts\\Service\\ResetInterface" + ], + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "RuleSettings146": { "additionalProperties": false, "properties": { "enabled": { @@ -2950,31 +3139,11 @@ }, "type": "object" }, - "RuleSettings146": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": false, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Warning" - } - }, - "type": "object" - }, "RuleSettings147": { "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -3014,7 +3183,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -3026,13 +3195,6 @@ "level": { "$ref": "#/$defs/Level", "default": "Warning" - }, - "min-digits": { - "default": 5, - "description": "Minimum number of digits before suggesting separators.", - "format": "uint", - "minimum": 0, - "type": "integer" } }, "type": "object" @@ -3106,7 +3268,11 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Note" + }, + "style": { + "$ref": "#/$defs/StringStyleOption", + "default": "interpolation" } }, "type": "object" @@ -3115,7 +3281,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -3135,7 +3301,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -3146,7 +3312,14 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" + }, + "min-digits": { + "default": 5, + "description": "Minimum number of digits before suggesting separators.", + "format": "uint", + "minimum": 0, + "type": "integer" } }, "type": "object" @@ -3166,7 +3339,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -3175,7 +3348,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -3186,7 +3359,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -3195,7 +3368,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -3215,7 +3388,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -3226,7 +3399,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Help" } }, "type": "object" @@ -3235,7 +3408,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -3246,12 +3419,59 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Warning" } }, "type": "object" }, "RuleSettings159": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Help" + } + }, + "type": "object" + }, + "RuleSettings16": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Warning" + }, + "types": { + "default": [], + "items": { + "$ref": "#/$defs/DisallowedTypeEntry" + }, + "type": "array" + } + }, + "type": "object" + }, + "RuleSettings160": { "additionalProperties": false, "properties": { "enabled": { @@ -3271,7 +3491,7 @@ }, "type": "object" }, - "RuleSettings16": { + "RuleSettings161": { "additionalProperties": false, "properties": { "enabled": { @@ -3286,12 +3506,72 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" }, - "RuleSettings160": { + "RuleSettings162": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Error" + } + }, + "type": "object" + }, + "RuleSettings163": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Error" + } + }, + "type": "object" + }, + "RuleSettings164": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Warning" + } + }, + "type": "object" + }, + "RuleSettings165": { "additionalProperties": false, "properties": { "classes": { @@ -3351,7 +3631,47 @@ }, "type": "object" }, + "RuleSettings166": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Warning" + } + }, + "type": "object" + }, "RuleSettings17": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Help" + } + }, + "type": "object" + }, + "RuleSettings18": { "additionalProperties": false, "properties": { "enabled": { @@ -3387,7 +3707,7 @@ }, "type": "object" }, - "RuleSettings18": { + "RuleSettings19": { "additionalProperties": false, "properties": { "constructor-threshold": { @@ -3424,26 +3744,6 @@ }, "type": "object" }, - "RuleSettings19": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Error" - } - }, - "type": "object" - }, "RuleSettings2": { "additionalProperties": false, "properties": { @@ -3465,6 +3765,26 @@ "type": "object" }, "RuleSettings20": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Error" + } + }, + "type": "object" + }, + "RuleSettings21": { "additionalProperties": false, "properties": { "difficulty-threshold": { @@ -3499,7 +3819,7 @@ }, "type": "object" }, - "RuleSettings21": { + "RuleSettings22": { "additionalProperties": false, "properties": { "enabled": { @@ -3524,7 +3844,7 @@ }, "type": "object" }, - "RuleSettings22": { + "RuleSettings23": { "additionalProperties": false, "properties": { "check-first-argument": { @@ -3555,7 +3875,7 @@ }, "type": "object" }, - "RuleSettings23": { + "RuleSettings24": { "additionalProperties": false, "properties": { "enabled": { @@ -3575,7 +3895,7 @@ }, "type": "object" }, - "RuleSettings24": { + "RuleSettings25": { "additionalProperties": false, "properties": { "enabled": { @@ -3595,7 +3915,7 @@ }, "type": "object" }, - "RuleSettings25": { + "RuleSettings26": { "additionalProperties": false, "properties": { "camel": { @@ -3630,26 +3950,6 @@ }, "type": "object" }, - "RuleSettings26": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Note" - } - }, - "type": "object" - }, "RuleSettings27": { "additionalProperties": false, "properties": { @@ -3665,7 +3965,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Note" } }, "type": "object" @@ -3705,7 +4005,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Error" } }, "type": "object" @@ -3805,7 +4105,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Warning" } }, "type": "object" @@ -3865,7 +4165,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Error" } }, "type": "object" @@ -3873,10 +4173,6 @@ "RuleSettings37": { "additionalProperties": false, "properties": { - "check-functions": { - "default": false, - "type": "boolean" - }, "enabled": { "default": true, "type": "boolean" @@ -3897,6 +4193,10 @@ "RuleSettings38": { "additionalProperties": false, "properties": { + "check-functions": { + "default": false, + "type": "boolean" + }, "enabled": { "default": true, "type": "boolean" @@ -3969,7 +4269,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Warning" } }, "type": "object" @@ -3989,7 +4289,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Note" } }, "type": "object" @@ -4189,7 +4489,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -4209,7 +4509,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" @@ -4309,7 +4609,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -4329,7 +4629,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" @@ -4349,7 +4649,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -4369,7 +4669,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" @@ -4413,7 +4713,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Help" } }, "type": "object" @@ -4433,7 +4733,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Note" } }, "type": "object" @@ -4453,7 +4753,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Help" } }, "type": "object" @@ -4473,7 +4773,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Error" } }, "type": "object" @@ -4573,7 +4873,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Warning" } }, "type": "object" @@ -4593,7 +4893,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Error" + "default": "Note" } }, "type": "object" @@ -4702,7 +5002,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -4713,7 +5013,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Error" } }, "type": "object" @@ -4733,12 +5033,32 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Note" } }, "type": "object" }, "RuleSettings76": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Warning" + } + }, + "type": "object" + }, + "RuleSettings77": { "additionalProperties": false, "properties": { "allow-array-checks": { @@ -4762,26 +5082,6 @@ }, "type": "object" }, - "RuleSettings77": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Note" - } - }, - "type": "object" - }, "RuleSettings78": { "additionalProperties": false, "properties": { @@ -4798,10 +5098,6 @@ "level": { "$ref": "#/$defs/Level", "default": "Note" - }, - "preserve-single-line-comments": { - "default": false, - "type": "boolean" } }, "type": "object" @@ -4821,7 +5117,11 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Note" + }, + "preserve-single-line-comments": { + "default": false, + "type": "boolean" } }, "type": "object" @@ -4865,7 +5165,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" @@ -4891,6 +5191,26 @@ "type": "object" }, "RuleSettings82": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Help" + } + }, + "type": "object" + }, + "RuleSettings83": { "additionalProperties": false, "properties": { "enabled": { @@ -4920,31 +5240,11 @@ }, "type": "object" }, - "RuleSettings83": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": false, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Warning" - } - }, - "type": "object" - }, "RuleSettings84": { "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -4964,7 +5264,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": false, + "default": true, "type": "boolean" }, "exclude": { @@ -4975,7 +5275,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Warning" } }, "type": "object" @@ -5024,7 +5324,7 @@ "additionalProperties": false, "properties": { "enabled": { - "default": true, + "default": false, "type": "boolean" }, "exclude": { @@ -5035,7 +5335,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Help" } }, "type": "object" @@ -5055,7 +5355,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" + "default": "Note" } }, "type": "object" @@ -5095,7 +5395,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Warning" + "default": "Help" } }, "type": "object" @@ -5195,11 +5495,7 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Help" - }, - "psr": { - "default": false, - "type": "boolean" + "default": "Warning" } }, "type": "object" @@ -5219,12 +5515,36 @@ }, "level": { "$ref": "#/$defs/Level", - "default": "Note" + "default": "Help" + }, + "psr": { + "default": false, + "type": "boolean" } }, "type": "object" }, "RuleSettings97": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "level": { + "$ref": "#/$defs/Level", + "default": "Note" + } + }, + "type": "object" + }, + "RuleSettings98": { "additionalProperties": false, "properties": { "check-functions": { @@ -5248,7 +5568,7 @@ }, "type": "object" }, - "RuleSettings98": { + "RuleSettings99": { "additionalProperties": false, "properties": { "camel": { @@ -5276,26 +5596,6 @@ }, "type": "object" }, - "RuleSettings99": { - "additionalProperties": false, - "properties": { - "enabled": { - "default": true, - "type": "boolean" - }, - "exclude": { - "items": { - "type": "string" - }, - "type": "array" - }, - "level": { - "$ref": "#/$defs/Level", - "default": "Warning" - } - }, - "type": "object" - }, "RulesSettings": { "additionalProperties": false, "properties": { @@ -5366,7 +5666,7 @@ } }, "constant-condition": { - "$ref": "#/$defs/RuleSettings129", + "$ref": "#/$defs/RuleSettings130", "default": { "enabled": true, "level": "Help" @@ -5389,26 +5689,26 @@ } }, "deprecated-cast": { - "$ref": "#/$defs/RuleSettings33", - "default": { - "enabled": true, - "level": "Error" - } - }, - "deprecated-shell-execute-string": { "$ref": "#/$defs/RuleSettings34", "default": { "enabled": true, "level": "Error" } }, - "deprecated-switch-semicolon": { + "deprecated-shell-execute-string": { "$ref": "#/$defs/RuleSettings35", "default": { "enabled": true, "level": "Error" } }, + "deprecated-switch-semicolon": { + "$ref": "#/$defs/RuleSettings36", + "default": { + "enabled": true, + "level": "Error" + } + }, "disallowed-functions": { "$ref": "#/$defs/RuleSettings15", "default": { @@ -5418,15 +5718,23 @@ "level": "Warning" } }, - "enum-name": { + "disallowed-type-instantiation": { "$ref": "#/$defs/RuleSettings16", + "default": { + "enabled": false, + "level": "Warning", + "types": [] + } + }, + "enum-name": { + "$ref": "#/$defs/RuleSettings17", "default": { "enabled": true, "level": "Help" } }, "excessive-nesting": { - "$ref": "#/$defs/RuleSettings17", + "$ref": "#/$defs/RuleSettings18", "default": { "enabled": true, "function-like-threshold": null, @@ -5435,7 +5743,7 @@ } }, "excessive-parameter-list": { - "$ref": "#/$defs/RuleSettings18", + "$ref": "#/$defs/RuleSettings19", "default": { "constructor-threshold": null, "enabled": true, @@ -5444,21 +5752,21 @@ } }, "explicit-nullable-param": { - "$ref": "#/$defs/RuleSettings99", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "explicit-octal": { "$ref": "#/$defs/RuleSettings100", "default": { "enabled": true, "level": "Warning" } }, + "explicit-octal": { + "$ref": "#/$defs/RuleSettings101", + "default": { + "enabled": true, + "level": "Warning" + } + }, "file-name": { - "$ref": "#/$defs/RuleSettings97", + "$ref": "#/$defs/RuleSettings98", "default": { "check-functions": false, "enabled": true, @@ -5466,14 +5774,14 @@ } }, "final-controller": { - "$ref": "#/$defs/RuleSettings19", + "$ref": "#/$defs/RuleSettings20", "default": { "enabled": true, "level": "Error" } }, "function-name": { - "$ref": "#/$defs/RuleSettings98", + "$ref": "#/$defs/RuleSettings99", "default": { "camel": false, "either": false, @@ -5482,7 +5790,7 @@ } }, "halstead": { - "$ref": "#/$defs/RuleSettings20", + "$ref": "#/$defs/RuleSettings21", "default": { "difficulty-threshold": 12, "effort-threshold": 5000, @@ -5492,42 +5800,42 @@ } }, "identity-comparison": { - "$ref": "#/$defs/RuleSettings90", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "ineffective-format-ignore-next": { "$ref": "#/$defs/RuleSettings91", "default": { "enabled": true, "level": "Warning" } }, - "ineffective-format-ignore-region": { + "ineffective-format-ignore-next": { "$ref": "#/$defs/RuleSettings92", "default": { "enabled": true, "level": "Warning" } }, - "inline-variable-return": { + "ineffective-format-ignore-region": { "$ref": "#/$defs/RuleSettings93", "default": { "enabled": true, "level": "Warning" } }, - "instanceof-stringable": { + "inline-variable-return": { "$ref": "#/$defs/RuleSettings94", "default": { "enabled": true, "level": "Warning" } }, - "interface-name": { + "instanceof-stringable": { "$ref": "#/$defs/RuleSettings95", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "interface-name": { + "$ref": "#/$defs/RuleSettings96", "default": { "enabled": true, "level": "Help", @@ -5535,14 +5843,14 @@ } }, "invalid-open-tag": { - "$ref": "#/$defs/RuleSettings96", + "$ref": "#/$defs/RuleSettings97", "default": { "enabled": true, "level": "Note" } }, "kan-defect": { - "$ref": "#/$defs/RuleSettings21", + "$ref": "#/$defs/RuleSettings22", "default": { "enabled": true, "level": "Error", @@ -5550,7 +5858,7 @@ } }, "literal-named-argument": { - "$ref": "#/$defs/RuleSettings22", + "$ref": "#/$defs/RuleSettings23", "default": { "check-first-argument": false, "enabled": true, @@ -5559,28 +5867,28 @@ } }, "loop-does-not-iterate": { - "$ref": "#/$defs/RuleSettings23", + "$ref": "#/$defs/RuleSettings24", "default": { "enabled": true, "level": "Warning" } }, "lowercase-keyword": { - "$ref": "#/$defs/RuleSettings24", + "$ref": "#/$defs/RuleSettings25", "default": { "enabled": true, "level": "Help" } }, "lowercase-type-hint": { - "$ref": "#/$defs/RuleSettings89", + "$ref": "#/$defs/RuleSettings90", "default": { "enabled": true, "level": "Help" } }, "method-name": { - "$ref": "#/$defs/RuleSettings25", + "$ref": "#/$defs/RuleSettings26", "default": { "camel": true, "either": false, @@ -5590,14 +5898,14 @@ } }, "middleware-in-routes": { - "$ref": "#/$defs/RuleSettings143", + "$ref": "#/$defs/RuleSettings146", "default": { "enabled": true, "level": "Warning" } }, "missing-docs": { - "$ref": "#/$defs/RuleSettings160", + "$ref": "#/$defs/RuleSettings165", "default": { "classes": false, "constants": true, @@ -5614,42 +5922,42 @@ } }, "no-alias-function": { - "$ref": "#/$defs/RuleSettings88", + "$ref": "#/$defs/RuleSettings89", "default": { "enabled": true, "level": "Note" } }, "no-alternative-syntax": { - "$ref": "#/$defs/RuleSettings152", + "$ref": "#/$defs/RuleSettings156", "default": { "enabled": false, "level": "Warning" } }, "no-array-accumulation-in-loop": { - "$ref": "#/$defs/RuleSettings130", + "$ref": "#/$defs/RuleSettings131", "default": { "enabled": false, "level": "Warning" } }, "no-assign-in-argument": { - "$ref": "#/$defs/RuleSettings83", + "$ref": "#/$defs/RuleSettings84", "default": { "enabled": false, "level": "Warning" } }, "no-assign-in-condition": { - "$ref": "#/$defs/RuleSettings84", + "$ref": "#/$defs/RuleSettings85", "default": { "enabled": true, "level": "Warning" } }, "no-boolean-flag-parameter": { - "$ref": "#/$defs/RuleSettings82", + "$ref": "#/$defs/RuleSettings83", "default": { "enabled": true, "exclude-constructors": true, @@ -5658,56 +5966,56 @@ } }, "no-closing-tag": { - "$ref": "#/$defs/RuleSettings81", + "$ref": "#/$defs/RuleSettings82", "default": { "enabled": true, "level": "Help" } }, "no-db-schema-change": { - "$ref": "#/$defs/RuleSettings157", + "$ref": "#/$defs/RuleSettings162", "default": { "enabled": true, "level": "Error" } }, "no-debug-symbols": { - "$ref": "#/$defs/RuleSettings26", + "$ref": "#/$defs/RuleSettings27", "default": { "enabled": true, "level": "Note" } }, "no-direct-db-query": { - "$ref": "#/$defs/RuleSettings156", + "$ref": "#/$defs/RuleSettings161", "default": { "enabled": true, "level": "Warning" } }, "no-else-clause": { - "$ref": "#/$defs/RuleSettings80", + "$ref": "#/$defs/RuleSettings81", "default": { "enabled": true, "level": "Help" } }, "no-empty": { - "$ref": "#/$defs/RuleSettings73", + "$ref": "#/$defs/RuleSettings74", "default": { "enabled": true, "level": "Error" } }, "no-empty-catch-clause": { - "$ref": "#/$defs/RuleSettings79", + "$ref": "#/$defs/RuleSettings80", "default": { "enabled": true, "level": "Warning" } }, "no-empty-comment": { - "$ref": "#/$defs/RuleSettings78", + "$ref": "#/$defs/RuleSettings79", "default": { "enabled": true, "level": "Note", @@ -5715,112 +6023,112 @@ } }, "no-empty-loop": { - "$ref": "#/$defs/RuleSettings77", + "$ref": "#/$defs/RuleSettings78", "default": { "enabled": true, "level": "Note" } }, "no-error-control-operator": { - "$ref": "#/$defs/RuleSettings72", + "$ref": "#/$defs/RuleSettings73", "default": { "enabled": true, "level": "Error" } }, "no-eval": { - "$ref": "#/$defs/RuleSettings71", + "$ref": "#/$defs/RuleSettings72", "default": { "enabled": true, "level": "Error" } }, "no-ffi": { - "$ref": "#/$defs/RuleSettings70", + "$ref": "#/$defs/RuleSettings71", "default": { "enabled": true, "level": "Error" } }, "no-fully-qualified-global-class-like": { - "$ref": "#/$defs/RuleSettings85", - "default": { - "enabled": false, - "level": "Help" - } - }, - "no-fully-qualified-global-constant": { "$ref": "#/$defs/RuleSettings86", "default": { "enabled": false, "level": "Help" } }, - "no-fully-qualified-global-function": { + "no-fully-qualified-global-constant": { "$ref": "#/$defs/RuleSettings87", "default": { "enabled": false, "level": "Help" } }, + "no-fully-qualified-global-function": { + "$ref": "#/$defs/RuleSettings88", + "default": { + "enabled": false, + "level": "Help" + } + }, "no-global": { - "$ref": "#/$defs/RuleSettings69", + "$ref": "#/$defs/RuleSettings70", "default": { "enabled": true, "level": "Error" } }, "no-goto": { - "$ref": "#/$defs/RuleSettings68", + "$ref": "#/$defs/RuleSettings69", "default": { "enabled": true, "level": "Note" } }, "no-hash-comment": { - "$ref": "#/$defs/RuleSettings66", + "$ref": "#/$defs/RuleSettings67", "default": { "enabled": true, "level": "Warning" } }, "no-hash-emoji": { - "$ref": "#/$defs/RuleSettings65", + "$ref": "#/$defs/RuleSettings66", "default": { "enabled": true, "level": "Warning" } }, "no-ini-set": { - "$ref": "#/$defs/RuleSettings131", + "$ref": "#/$defs/RuleSettings132", "default": { "enabled": true, "level": "Warning" } }, "no-inline": { - "$ref": "#/$defs/RuleSettings133", + "$ref": "#/$defs/RuleSettings134", "default": { "enabled": false, "level": "Error" } }, "no-insecure-comparison": { - "$ref": "#/$defs/RuleSettings134", + "$ref": "#/$defs/RuleSettings136", "default": { "enabled": true, "level": "Error" } }, "no-is-null": { - "$ref": "#/$defs/RuleSettings74", + "$ref": "#/$defs/RuleSettings75", "default": { "enabled": false, "level": "Note" } }, "no-isset": { - "$ref": "#/$defs/RuleSettings76", + "$ref": "#/$defs/RuleSettings77", "default": { "allow-array-checks": false, "enabled": true, @@ -5828,315 +6136,361 @@ } }, "no-iterator-to-array-in-foreach": { - "$ref": "#/$defs/RuleSettings75", + "$ref": "#/$defs/RuleSettings76", + "default": { + "enabled": false, + "level": "Warning" + } + }, + "no-literal-namespace-string": { + "$ref": "#/$defs/RuleSettings166", "default": { "enabled": false, "level": "Warning" } }, "no-literal-password": { - "$ref": "#/$defs/RuleSettings135", + "$ref": "#/$defs/RuleSettings137", "default": { "enabled": true, "level": "Error" } }, "no-multi-assignments": { - "$ref": "#/$defs/RuleSettings63", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-nested-ternary": { "$ref": "#/$defs/RuleSettings64", "default": { "enabled": true, "level": "Warning" } }, + "no-nested-ternary": { + "$ref": "#/$defs/RuleSettings65", + "default": { + "enabled": true, + "level": "Warning" + } + }, "no-noop": { - "$ref": "#/$defs/RuleSettings61", + "$ref": "#/$defs/RuleSettings62", "default": { "enabled": true, "level": "Help" } }, + "no-null-property-init": { + "$ref": "#/$defs/RuleSettings159", + "default": { + "enabled": false, + "level": "Help" + } + }, "no-only": { - "$ref": "#/$defs/RuleSettings62", + "$ref": "#/$defs/RuleSettings63", "default": { "enabled": true, "level": "Error" } }, "no-parameter-shadowing": { - "$ref": "#/$defs/RuleSettings132", + "$ref": "#/$defs/RuleSettings133", "default": { "enabled": false, "level": "Warning" } }, "no-php-tag-terminator": { - "$ref": "#/$defs/RuleSettings60", + "$ref": "#/$defs/RuleSettings61", "default": { "enabled": true, "level": "Note" } }, "no-protected-in-final": { - "$ref": "#/$defs/RuleSettings59", + "$ref": "#/$defs/RuleSettings60", "default": { "enabled": true, "level": "Help" } }, "no-redundant-binary-string-prefix": { - "$ref": "#/$defs/RuleSettings43", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-block": { - "$ref": "#/$defs/RuleSettings55", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-continue": { - "$ref": "#/$defs/RuleSettings54", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-file": { - "$ref": "#/$defs/RuleSettings53", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-final": { - "$ref": "#/$defs/RuleSettings51", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-isset": { - "$ref": "#/$defs/RuleSettings46", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-label": { - "$ref": "#/$defs/RuleSettings49", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-literal-return": { - "$ref": "#/$defs/RuleSettings50", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-redundant-math": { - "$ref": "#/$defs/RuleSettings48", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-method-override": { - "$ref": "#/$defs/RuleSettings45", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-nullsafe": { - "$ref": "#/$defs/RuleSettings47", - "default": { - "enabled": true, - "level": "Help" - } - }, - "no-redundant-parentheses": { "$ref": "#/$defs/RuleSettings44", "default": { "enabled": true, "level": "Help" } }, - "no-redundant-readonly": { + "no-redundant-block": { + "$ref": "#/$defs/RuleSettings56", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-continue": { + "$ref": "#/$defs/RuleSettings55", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-file": { + "$ref": "#/$defs/RuleSettings54", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-final": { "$ref": "#/$defs/RuleSettings52", "default": { "enabled": true, "level": "Help" } }, + "no-redundant-isset": { + "$ref": "#/$defs/RuleSettings47", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-label": { + "$ref": "#/$defs/RuleSettings50", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-literal-return": { + "$ref": "#/$defs/RuleSettings51", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "no-redundant-math": { + "$ref": "#/$defs/RuleSettings49", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-method-override": { + "$ref": "#/$defs/RuleSettings46", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-nullsafe": { + "$ref": "#/$defs/RuleSettings48", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-parentheses": { + "$ref": "#/$defs/RuleSettings45", + "default": { + "enabled": true, + "level": "Help" + } + }, + "no-redundant-readonly": { + "$ref": "#/$defs/RuleSettings53", + "default": { + "enabled": true, + "level": "Help" + } + }, "no-redundant-string-concat": { - "$ref": "#/$defs/RuleSettings42", + "$ref": "#/$defs/RuleSettings43", "default": { "enabled": true, "level": "Help" } }, "no-redundant-use": { - "$ref": "#/$defs/RuleSettings56", + "$ref": "#/$defs/RuleSettings57", "default": { "enabled": true, "level": "Warning" } }, "no-redundant-write-visibility": { - "$ref": "#/$defs/RuleSettings41", + "$ref": "#/$defs/RuleSettings42", "default": { "enabled": true, "level": "Help" } }, "no-redundant-yield-from": { - "$ref": "#/$defs/RuleSettings57", + "$ref": "#/$defs/RuleSettings58", "default": { "enabled": true, "level": "Help" } }, "no-request-all": { - "$ref": "#/$defs/RuleSettings142", + "$ref": "#/$defs/RuleSettings144", "default": { "enabled": true, "level": "Warning" } }, "no-request-variable": { - "$ref": "#/$defs/RuleSettings27", - "default": { - "enabled": true, - "level": "Error" - } - }, - "no-roles-as-capabilities": { - "$ref": "#/$defs/RuleSettings159", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-self-assignment": { - "$ref": "#/$defs/RuleSettings58", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-shell-execute-string": { "$ref": "#/$defs/RuleSettings28", "default": { "enabled": true, "level": "Error" } }, + "no-roles-as-capabilities": { + "$ref": "#/$defs/RuleSettings164", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "no-self-assignment": { + "$ref": "#/$defs/RuleSettings59", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "no-service-state-mutation": { + "$ref": "#/$defs/RuleSettings145", + "default": { + "allowed-methods": [ + "__construct", + "reset" + ], + "enabled": false, + "exclude-namespaces": [ + "App\\DTO\\", + "App\\Entity\\", + "App\\ValueObject\\" + ], + "include-namespaces": [ + "App\\" + ], + "level": "Warning", + "reset-interfaces": [ + "Symfony\\Contracts\\Service\\ResetInterface" + ] + } + }, + "no-shell-execute-string": { + "$ref": "#/$defs/RuleSettings29", + "default": { + "enabled": true, + "level": "Error" + } + }, "no-short-bool-cast": { - "$ref": "#/$defs/RuleSettings151", + "$ref": "#/$defs/RuleSettings155", "default": { "enabled": false, "level": "Help" } }, "no-short-opening-tag": { - "$ref": "#/$defs/RuleSettings29", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-shorthand-ternary": { "$ref": "#/$defs/RuleSettings30", "default": { "enabled": true, "level": "Warning" } }, - "no-sprintf-concat": { + "no-shorthand-ternary": { "$ref": "#/$defs/RuleSettings31", "default": { "enabled": true, "level": "Warning" } }, - "no-trailing-space": { - "$ref": "#/$defs/RuleSettings40", + "no-side-effects-with-declarations": { + "$ref": "#/$defs/RuleSettings135", "default": { - "enabled": true, - "level": "Note" - } - }, - "no-underscore-class": { - "$ref": "#/$defs/RuleSettings39", - "default": { - "enabled": true, + "allow-class-alias": true, + "allow-class-exists": true, + "allow-conditional-declarations": true, + "enabled": false, "level": "Warning" } }, - "no-unescaped-output": { - "$ref": "#/$defs/RuleSettings158", - "default": { - "enabled": true, - "level": "Error" - } - }, - "no-unsafe-finally": { - "$ref": "#/$defs/RuleSettings139", - "default": { - "enabled": true, - "level": "Error" - } - }, - "no-variable-variable": { - "$ref": "#/$defs/RuleSettings67", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "no-void-reference-return": { - "$ref": "#/$defs/RuleSettings38", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "optional-param-order": { + "no-sprintf-concat": { "$ref": "#/$defs/RuleSettings32", "default": { "enabled": true, "level": "Warning" } }, + "no-trailing-space": { + "$ref": "#/$defs/RuleSettings41", + "default": { + "enabled": true, + "level": "Note" + } + }, + "no-underscore-class": { + "$ref": "#/$defs/RuleSettings40", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "no-unescaped-output": { + "$ref": "#/$defs/RuleSettings163", + "default": { + "enabled": true, + "level": "Error" + } + }, + "no-unsafe-finally": { + "$ref": "#/$defs/RuleSettings141", + "default": { + "enabled": true, + "level": "Error" + } + }, + "no-variable-variable": { + "$ref": "#/$defs/RuleSettings68", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "no-void-reference-return": { + "$ref": "#/$defs/RuleSettings39", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "optional-param-order": { + "$ref": "#/$defs/RuleSettings33", + "default": { + "enabled": true, + "level": "Warning" + } + }, "prefer-anonymous-migration": { - "$ref": "#/$defs/RuleSettings36", + "$ref": "#/$defs/RuleSettings37", "default": { "enabled": true, "level": "Warning" } }, "prefer-arrow-function": { - "$ref": "#/$defs/RuleSettings101", + "$ref": "#/$defs/RuleSettings102", "default": { "enabled": true, "level": "Help" } }, "prefer-early-continue": { - "$ref": "#/$defs/RuleSettings102", + "$ref": "#/$defs/RuleSettings103", "default": { "enabled": true, "level": "Help", @@ -6144,7 +6498,7 @@ } }, "prefer-first-class-callable": { - "$ref": "#/$defs/RuleSettings37", + "$ref": "#/$defs/RuleSettings38", "default": { "check-functions": false, "enabled": true, @@ -6152,49 +6506,49 @@ } }, "prefer-interface": { - "$ref": "#/$defs/RuleSettings103", + "$ref": "#/$defs/RuleSettings104", "default": { "enabled": true, "level": "Note" } }, "prefer-pre-increment": { - "$ref": "#/$defs/RuleSettings153", + "$ref": "#/$defs/RuleSettings157", "default": { "enabled": false, "level": "Help" } }, "prefer-static-closure": { - "$ref": "#/$defs/RuleSettings104", + "$ref": "#/$defs/RuleSettings105", "default": { "enabled": true, "level": "Help" } }, "prefer-test-attribute": { - "$ref": "#/$defs/RuleSettings105", + "$ref": "#/$defs/RuleSettings106", "default": { "enabled": false, "level": "Warning" } }, "prefer-view-array": { - "$ref": "#/$defs/RuleSettings106", + "$ref": "#/$defs/RuleSettings107", "default": { "enabled": true, "level": "Help" } }, "prefer-while-loop": { - "$ref": "#/$defs/RuleSettings107", + "$ref": "#/$defs/RuleSettings108", "default": { "enabled": true, "level": "Note" } }, "property-name": { - "$ref": "#/$defs/RuleSettings138", + "$ref": "#/$defs/RuleSettings140", "default": { "camel": true, "either": false, @@ -6203,70 +6557,70 @@ } }, "psl-array-functions": { - "$ref": "#/$defs/RuleSettings108", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "psl-data-structures": { "$ref": "#/$defs/RuleSettings109", "default": { "enabled": true, "level": "Warning" } }, - "psl-datetime": { + "psl-data-structures": { "$ref": "#/$defs/RuleSettings110", "default": { "enabled": true, "level": "Warning" } }, - "psl-math-functions": { + "psl-datetime": { "$ref": "#/$defs/RuleSettings111", "default": { "enabled": true, "level": "Warning" } }, - "psl-output": { + "psl-math-functions": { "$ref": "#/$defs/RuleSettings112", + "default": { + "enabled": true, + "level": "Warning" + } + }, + "psl-output": { + "$ref": "#/$defs/RuleSettings113", "default": { "enabled": true, "level": "Error" } }, "psl-randomness-functions": { - "$ref": "#/$defs/RuleSettings113", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "psl-regex-functions": { "$ref": "#/$defs/RuleSettings114", "default": { "enabled": true, "level": "Warning" } }, - "psl-sleep-functions": { + "psl-regex-functions": { "$ref": "#/$defs/RuleSettings115", "default": { "enabled": true, "level": "Warning" } }, - "psl-string-functions": { + "psl-sleep-functions": { "$ref": "#/$defs/RuleSettings116", "default": { "enabled": true, "level": "Warning" } }, + "psl-string-functions": { + "$ref": "#/$defs/RuleSettings117", + "default": { + "enabled": true, + "level": "Warning" + } + }, "readable-literal": { - "$ref": "#/$defs/RuleSettings149", + "$ref": "#/$defs/RuleSettings153", "default": { "enabled": true, "level": "Warning", @@ -6274,63 +6628,63 @@ } }, "require-namespace": { - "$ref": "#/$defs/RuleSettings146", + "$ref": "#/$defs/RuleSettings149", "default": { "enabled": false, "level": "Warning" } }, "require-preg-quote-delimiter": { - "$ref": "#/$defs/RuleSettings145", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "sensitive-parameter": { - "$ref": "#/$defs/RuleSettings137", - "default": { - "enabled": true, - "level": "Error" - } - }, - "single-class-per-file": { "$ref": "#/$defs/RuleSettings148", "default": { "enabled": true, "level": "Warning" } }, + "sensitive-parameter": { + "$ref": "#/$defs/RuleSettings139", + "default": { + "enabled": true, + "level": "Error" + } + }, + "single-class-per-file": { + "$ref": "#/$defs/RuleSettings152", + "default": { + "enabled": true, + "level": "Warning" + } + }, "sorted-integer-keys": { - "$ref": "#/$defs/RuleSettings147", + "$ref": "#/$defs/RuleSettings150", "default": { "enabled": false, "level": "Help" } }, "str-contains": { - "$ref": "#/$defs/RuleSettings117", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "str-starts-with": { "$ref": "#/$defs/RuleSettings118", "default": { "enabled": true, "level": "Warning" } }, + "str-starts-with": { + "$ref": "#/$defs/RuleSettings119", + "default": { + "enabled": true, + "level": "Warning" + } + }, "strict-assertions": { - "$ref": "#/$defs/RuleSettings140", + "$ref": "#/$defs/RuleSettings142", "default": { "enabled": true, "level": "Warning" } }, "strict-behavior": { - "$ref": "#/$defs/RuleSettings119", + "$ref": "#/$defs/RuleSettings120", "default": { "allow-loose-behavior": false, "enabled": true, @@ -6338,36 +6692,44 @@ } }, "strict-types": { - "$ref": "#/$defs/RuleSettings120", + "$ref": "#/$defs/RuleSettings121", "default": { "allow-disabling": false, "enabled": true, "level": "Warning" } }, + "string-style": { + "$ref": "#/$defs/RuleSettings151", + "default": { + "enabled": false, + "level": "Note", + "style": "interpolation" + } + }, "switch-continue-to-break": { - "$ref": "#/$defs/RuleSettings154", + "$ref": "#/$defs/RuleSettings158", "default": { "enabled": false, "level": "Warning" } }, "tagged-fixme": { - "$ref": "#/$defs/RuleSettings121", - "default": { - "enabled": true, - "level": "Warning" - } - }, - "tagged-todo": { "$ref": "#/$defs/RuleSettings122", "default": { "enabled": true, "level": "Warning" } }, + "tagged-todo": { + "$ref": "#/$defs/RuleSettings123", + "default": { + "enabled": true, + "level": "Warning" + } + }, "tainted-data-to-sink": { - "$ref": "#/$defs/RuleSettings136", + "$ref": "#/$defs/RuleSettings138", "default": { "enabled": true, "known-sink-functions": [ @@ -6377,7 +6739,7 @@ } }, "too-many-enum-cases": { - "$ref": "#/$defs/RuleSettings123", + "$ref": "#/$defs/RuleSettings124", "default": { "enabled": true, "level": "Error", @@ -6385,7 +6747,7 @@ } }, "too-many-methods": { - "$ref": "#/$defs/RuleSettings124", + "$ref": "#/$defs/RuleSettings125", "default": { "count-hooks": false, "count-setters-and-getters": false, @@ -6395,7 +6757,7 @@ } }, "too-many-properties": { - "$ref": "#/$defs/RuleSettings125", + "$ref": "#/$defs/RuleSettings126", "default": { "enabled": true, "level": "Error", @@ -6403,7 +6765,7 @@ } }, "trait-name": { - "$ref": "#/$defs/RuleSettings126", + "$ref": "#/$defs/RuleSettings127", "default": { "enabled": true, "level": "Help", @@ -6411,7 +6773,7 @@ } }, "use-compound-assignment": { - "$ref": "#/$defs/RuleSettings144", + "$ref": "#/$defs/RuleSettings147", "default": { "enabled": true, "level": "Help" @@ -6432,7 +6794,7 @@ } }, "use-specific-assertions": { - "$ref": "#/$defs/RuleSettings141", + "$ref": "#/$defs/RuleSettings143", "default": { "enabled": true, "level": "Warning" @@ -6446,21 +6808,21 @@ } }, "use-wp-functions": { - "$ref": "#/$defs/RuleSettings155", + "$ref": "#/$defs/RuleSettings160", "default": { "enabled": true, "level": "Warning" } }, "valid-docblock": { - "$ref": "#/$defs/RuleSettings127", + "$ref": "#/$defs/RuleSettings128", "default": { "enabled": true, "level": "Note" } }, "variable-name": { - "$ref": "#/$defs/RuleSettings128", + "$ref": "#/$defs/RuleSettings129", "default": { "camel": false, "check-parameters": true, @@ -6470,7 +6832,7 @@ } }, "yoda-conditions": { - "$ref": "#/$defs/RuleSettings150", + "$ref": "#/$defs/RuleSettings154", "default": { "enabled": false, "level": "Help" @@ -6528,15 +6890,20 @@ "type": "array" }, "workspace": { + "default": "/home/gcch/Répertoires/git.gcch.fr/haiku-atelier-2024", "description": "The workspace directory from which to start scanning.\n\nDefaults to the current working directory.", "type": "string" } }, - "required": [ - "workspace" - ], "type": "object" }, + "StringStyleOption": { + "enum": [ + "concatenation", + "interpolation" + ], + "type": "string" + }, "StructuralInheritanceConstraint": { "anyOf": [ { @@ -6738,6 +7105,7 @@ "$ref": "#/$defs/AnalyzerConfiguration", "default": { "allow-possibly-undefined-array-keys": true, + "allow-side-effects-in-conditions": true, "analyze-dead-code": false, "baseline": null, "baseline-variant": "loose", @@ -6754,6 +7122,7 @@ "disable-default-plugins": false, "enforce-class-finality": false, "excludes": [], + "find-overly-wide-return-types": false, "find-unused-definitions": true, "find-unused-expressions": true, "find-unused-parameters": false, @@ -6762,11 +7131,12 @@ "minimum-fail-level": "Error", "no-boolean-literal-comparison": false, "performance": { - "array-combination-threshold": 128, + "array-combination-threshold": 32, "consensus-limit-threshold": 256, "disjunction-complexity-threshold": 4096, "formula-size-threshold": 512, "integer-combination-threshold": 128, + "loop-assignment-depth-threshold": 1, "negation-complexity-threshold": 4096, "saturation-complexity-threshold": 8192, "string-combination-threshold": 128 @@ -6895,6 +7265,11 @@ "functions": [], "level": "Warning" }, + "disallowed-type-instantiation": { + "enabled": false, + "level": "Warning", + "types": [] + }, "enum-name": { "enabled": true, "level": "Help" @@ -7146,6 +7521,10 @@ "enabled": false, "level": "Warning" }, + "no-literal-namespace-string": { + "enabled": false, + "level": "Warning" + }, "no-literal-password": { "enabled": true, "level": "Error" @@ -7162,6 +7541,10 @@ "enabled": true, "level": "Help" }, + "no-null-property-init": { + "enabled": false, + "level": "Help" + }, "no-only": { "enabled": true, "level": "Error" @@ -7262,6 +7645,25 @@ "enabled": true, "level": "Warning" }, + "no-service-state-mutation": { + "allowed-methods": [ + "__construct", + "reset" + ], + "enabled": false, + "exclude-namespaces": [ + "App\\DTO\\", + "App\\Entity\\", + "App\\ValueObject\\" + ], + "include-namespaces": [ + "App\\" + ], + "level": "Warning", + "reset-interfaces": [ + "Symfony\\Contracts\\Service\\ResetInterface" + ] + }, "no-shell-execute-string": { "enabled": true, "level": "Error" @@ -7278,6 +7680,13 @@ "enabled": true, "level": "Warning" }, + "no-side-effects-with-declarations": { + "allow-class-alias": true, + "allow-class-exists": true, + "allow-conditional-declarations": true, + "enabled": false, + "level": "Warning" + }, "no-sprintf-concat": { "enabled": true, "level": "Warning" @@ -7441,6 +7850,11 @@ "enabled": true, "level": "Warning" }, + "string-style": { + "enabled": false, + "level": "Note", + "style": "interpolation" + }, "switch-continue-to-break": { "enabled": false, "level": "Warning" @@ -7525,6 +7939,11 @@ }, "description": "Linter service configuration.\n\nControls linting behavior, including enabled/disabled rules, rule-specific\nsettings, and reporting preferences. Defaults to an empty configuration\nif not specified in the config file." }, + "no-version-check": { + "default": false, + "description": "Whether to silence the project version drift warning.\n\nAffects only the minor / patch drift warning emitted when the installed\nmago binary does not match the `version` pinned in `mago.toml`. A major\ndrift is always fatal and is *not* affected by this flag; the whole\npoint of a major pin is to stop runs across incompatible config schemas.\n\nCan be enabled via `MAGO_NO_VERSION_CHECK` environment variable or\n`--no-version-check` CLI flag.", + "type": "boolean" + }, "parser": { "$ref": "#/$defs/ParserConfiguration", "default": { @@ -7569,6 +7988,14 @@ "format": "uint", "minimum": 0, "type": "integer" + }, + "version": { + "default": null, + "description": "The mago version this project is pinned to.\n\nAccepts three pin levels:\n\n- `\"1\"`: major pin; any `1.x.y` satisfies it. `mago init` emits this\n by default. Minor/patch drift within major 1 is a warning; a bump to\n `2.x` is a hard error.\n- `\"1.19\"`: minor pin; any `1.19.y` satisfies it.\n- `\"1.19.3\"`: exact pin; any drift is a warning, and this is the only\n form that `mago self-update --to-project-version` can target without\n ambiguity.\n\nEmpty / missing is currently a no-op; a future mago release is likely\nto start warning when the pin is absent, to prepare projects for 2.0.\n\n# Compatibility invariant (**do not break**)\n\nThis field's location (top-level) and type (string) are a load-bearing\ncontract for cross-major config compatibility: a future mago 2.x must\nbe able to read a mago 1.x `mago.toml` via a permissive top-level TOML\npass, find this field, and refuse to run with\n\"this config is pinned to mago 1\" *before* it ever hits its own strict\nschema. That means:\n\n- never move this field into a `[metadata]` section,\n- never rename it,\n- never change it from a string,\n- never change the pin grammar from `major[.minor[.patch]]`.", + "type": [ + "null", + "string" + ] } }, "title": "Configuration", diff --git a/mago.toml b/mago.toml index bdcdd94f..453893a5 100644 --- a/mago.toml +++ b/mago.toml @@ -37,27 +37,29 @@ threads = 0 [analyzer] allow-possibly-undefined-array-keys = false + allow-side-effects-in-conditions = true analyze-dead-code = true check-arrow-function-missing-type-hints = true check-closure-missing-type-hints = true + check-experimental = true check-missing-override = true check-missing-type-hints = true + check-name-casing = true check-property-initialization = true check-throws = true check-use-statements = true enforce-class-finality = true + find-overly-wide-return-types = true find-unused-definitions = true find-unused-expressions = true find-unused-parameters = true + memoize-properties = true no-boolean-literal-comparison = false perform-heuristic-checks = true plugins = ["psl"] require-api-or-internal = true strict-list-index-checks = true trust-existence-checks = false - check-experimental = true - check-name-casing = true - memoize-properties = true [analyzer.performance] array-combination-threshold = 256 From 2013b4e1ccaddef15d359204e492dd5ae45a33d9 Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:30:27 +0200 Subject: [PATCH 6/7] fix: retourne un tableau pour les Options d'un Attribut --- web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php index 3e9e57a9..36c2c669 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php @@ -27,7 +27,8 @@ final readonly class Attribute { $terms = $attribute->get_terms() ?? []; /** @var list */ $options = Arr::map($terms, AttributeOption::new(...)) - |> (static fn($options) => Arr::sort($options, static fn($attribute) => $attribute->id)); + |> (static fn($options) => Arr::sort($options, static fn($attribute) => $attribute->id)) + |> array_values(...); return new self(name: $name, slug: $slug, options: $options); } From 89d0c807363fbfe4ecdb034df05420c4c2cc150c Mon Sep 17 00:00:00 2001 From: gcch Date: Tue, 14 Apr 2026 11:30:27 +0200 Subject: [PATCH 7/7] ref: refactorise les scripts de la page Produit --- .../src/scripts-effect/api-service.ts | 50 ++++ .../src/scripts-effect/schemas/api.ts | 12 +- .../src/scripts-effect/schemas/product.ts | 73 +++++- .../src/scripts/page-produit/errors.ts | 18 ++ .../src/scripts/page-produit/runtime.ts | 2 + .../src/scripts/page-produit/service-dom.ts | 240 +++++++++++------- .../scripts/page-produit/service-elements.ts | 9 +- .../src/scripts/page-produit/types.d.ts | 1 + .../src/scripts/scripts-page-produit.ts | 17 +- 9 files changed, 303 insertions(+), 119 deletions(-) create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts-effect/api-service.ts create mode 100644 web/app/themes/haiku-atelier-2024/src/scripts/page-produit/errors.ts diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/api-service.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/api-service.ts new file mode 100644 index 00000000..f5492385 --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/api-service.ts @@ -0,0 +1,50 @@ +import { Context, Effect, Layer, Schema } from "effect"; +import { ENTETE_WC_NONCE, ROUTE_API_AJOUTE_ARTICLE_PANIER } from "../scripts/constantes/api.ts"; +import { CartProduct } from "./schemas/api.ts"; + +const REQUEST_TIMEOUT = 5_000; + +class APIError extends Schema.TaggedErrorClass()("APIError", { + cause: Schema.Defect, +}) {} + +class WooCommerceAPI extends Context.Service< + WooCommerceAPI, + { + AddProductToCart: (nonce: string, requestBody: CartProduct) => Effect.Effect; + } +>()("haikuatelier.fr/WooCommerceAPI") { + static readonly layer = Layer.effect( + WooCommerceAPI, + // oxlint-disable-next-line require-yield + Effect.gen(function*() { + const AddProductToCart = Effect.fn("AddProductToCart")(function*(nonce: string, product: CartProduct) { + const response = yield* Effect.tryPromise({ + catch: error => new APIError({ cause: error }), + try: async () => + fetch(ROUTE_API_AJOUTE_ARTICLE_PANIER, { + // Convertis en chaîne de caractères (équivalent à JSON.stringify). + body: Schema.encodeSync(Schema.fromJsonString(CartProduct))(product), + credentials: "same-origin", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + [ENTETE_WC_NONCE]: nonce, + }, + method: "POST", + mode: "same-origin", + signal: AbortSignal.timeout(REQUEST_TIMEOUT), + }), + }); + + return response; + }); + + return WooCommerceAPI.of({ + AddProductToCart, + }); + }), + ); +} + +export { WooCommerceAPI }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts index 97c8b1ff..e3480331 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/api.ts @@ -1,10 +1,10 @@ import { Schema } from "effect"; -import { ProductAttribute } from "./product.ts"; +import { ProductId, ProductQuantity, ProductVariationAttribute } from "./product.ts"; -class AddProductToCart extends Schema.Class("AddProductToCart")({ - id: Schema.Int, - quantity: Schema.Int.check(Schema.isGreaterThan(0)), - variation: Schema.Array(ProductAttribute), +class CartProduct extends Schema.Class("CartProduct")({ + id: ProductId, + quantity: ProductQuantity, + variation: Schema.Array(ProductVariationAttribute), }) {} -export { AddProductToCart }; +export { CartProduct }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts index 1c8055a4..80cb0405 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/schemas/product.ts @@ -1,7 +1,49 @@ // oxlint-disable no-magic-numbers -- Pas besoin ici. -import { Schema } from "effect"; +import { Effect, Option, pipe, Schema, SchemaIssue, SchemaTransformation } from "effect"; +import type { SchemaError } from "effect/Schema"; + +/** Représente l'identifiant numérique unique d'un Produit. */ +const ProductId = Schema.Int.pipe(Schema.brand("ProductId")).check(Schema.isGreaterThan(0)); + +/** Représente l'identifiant numérique unique d'un Attribut. */ +const AttributeId = Schema.Int.pipe(Schema.brand("AttributeId")).check(Schema.isGreaterThan(0)); + +/** Réprésente une quantité (nombre d'unités) de Produit. */ +const ProductQuantity = Schema.Int.pipe(Schema.brand("ProductQuantity")).check(Schema.isGreaterThanOrEqualTo(0)); +/** Schéma transformant une chaîne de caractères en `ProductId` avec validation. */ +const ProductQuantityFromString = Schema.String.pipe( + Schema.decodeTo( + ProductQuantity, + SchemaTransformation.transformOrFail({ + decode: (value: string) => + pipe( + globalThis.Number(value), + (number: number) => ProductQuantity.makeEffect(number), + Effect.mapError((error: SchemaError) => new SchemaIssue.InvalidValue(Option.some(value), { cause: error })), + ), + encode: (value: number) => Effect.succeed(String(value)), + }), + ), +); + +class AttributeValue extends Schema.Class("AttributeValue")({ + /** L'identifiant numérique de la Valeur de l'Attribut. */ + id: AttributeId, + /** Le nom (texte affiché) de la Valeur de l'Attribut. */ + name: Schema.String, + /** L'identifiant alphanumérique _(slug)_ de la Valeur de l'Attribut. */ + slug: Schema.String, +}) {} class ProductAttribute extends Schema.Class("ProductAttribute")({ + /** Le nom de l'Attribut. */ + name: Schema.String, + options: Schema.Array(AttributeValue), + /** L'identifiant _(slug)_ de l'Attribut. */ + slug: Schema.String, +}) {} + +class ProductVariationAttribute extends Schema.Class("ProductVariationAttribute")({ /** L'identifiant _(slug)_ de l'Attribut. */ attribute: Schema.String, /** La valeur de l'attribut. */ @@ -10,11 +52,32 @@ class ProductAttribute extends Schema.Class("ProductAttribute" class ProductVariation extends Schema.Class("ProductVariation")({ /** Les Attributs présents pour cette Variation. */ - attributes: Schema.Array(ProductAttribute), + attributes: Schema.Array(ProductVariationAttribute), /** L'identifiant numérique unique de la Variation. */ - id: Schema.Int.check(Schema.isGreaterThan(0)), + id: ProductId, /** Le prix de la Variation. */ - price: Schema.NonEmptyString, + price: ProductQuantityFromString, }) {} -export { ProductAttribute, ProductVariation }; +class Product extends Schema.Class("Product")({ + /** Les Attributs applicables au Produit (en cas de Produit simple). */ + attributes: Schema.Union([Schema.Record(Schema.String, ProductAttribute), Schema.Array(ProductAttribute)]), + /** L'identifiant numérique unique du Produit. */ + id: ProductId, + /** Le prix du Produit. */ + price: ProductQuantityFromString, + /** Les Variations existantes du Produit (en cas de Produit variable). */ + variations: Schema.Array(ProductVariation), +}) {} + +export { + AttributeId, + AttributeValue, + Product, + ProductAttribute, + ProductId, + ProductQuantity, + ProductQuantityFromString, + ProductVariation, + ProductVariationAttribute, +}; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/errors.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/errors.ts new file mode 100644 index 00000000..ce6e4f35 --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/errors.ts @@ -0,0 +1,18 @@ +import { Schema, SchemaIssue } from "effect"; +import { NoSuchElementError } from "effect/Cause"; +import { SchemaError } from "effect/Schema"; + +class IncoherentDOMError extends Schema.TaggedErrorClass()("IncoherentDOMError", { + cause: Schema.String, +}) { + static readonly fromSchemaError = (error: SchemaError): IncoherentDOMError => + new IncoherentDOMError({ + cause: SchemaIssue.makeFormatterDefault()(error.issue), + }); + static readonly fromNoSuchElementError = (error: NoSuchElementError): IncoherentDOMError => + new IncoherentDOMError({ + cause: `Impossible de trouver l'Element suivant dans le DOM : ${error.message}.`, + }); +} + +export { IncoherentDOMError }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts index 72941df3..0564730d 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/runtime.ts @@ -1,4 +1,5 @@ import { Console, Layer, ManagedRuntime, pipe } from "effect"; +import { WooCommerceAPI } from "../../scripts-effect/api-service.ts"; import ProductPageDOM from "./service-dom.ts"; import ProductPageElements from "./service-elements.ts"; @@ -6,6 +7,7 @@ const ProductPageRuntime = ManagedRuntime.make( pipe( ProductPageDOM.layer, Layer.provide(ProductPageElements.layer), + Layer.provide(WooCommerceAPI.layer), Layer.tapError(error => Console.error("ProductPageRuntime", "Impossible de créer le Layer :", error)), ), ); diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts index 672b94d0..8e323b67 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-dom.ts @@ -14,17 +14,36 @@ import { Stream, } from "effect"; import type { NoSuchElementError } from "effect/Cause"; -import { AddProductToCart } from "../../scripts-effect/schemas/api.ts"; -import { ProductAttribute, ProductVariation } from "../../scripts-effect/schemas/product.ts"; +import type { SchemaError } from "effect/Schema"; +import { WooCommerceAPI } from "../../scripts-effect/api-service.ts"; +import { AddProductToCart, CartProduct } from "../../scripts-effect/schemas/api.ts"; +import { Product, ProductVariation, ProductVariationAttribute } from "../../scripts-effect/schemas/product.ts"; import { ATTRIBUT_ARIA_CONTROLS, ATTRIBUT_ARIA_EXPANDED, + ATTRIBUT_CHARGEMENT, ATTRIBUT_DESACTIVE, ATTRIBUT_HIDDEN, } from "../constantes/dom.ts"; +import { lanceAnimationCycleLoading } from "../lib/animations.ts"; +import { IncoherentDOMError } from "./errors.ts"; import ProductPageElements from "./service-elements.ts"; import type { DetailEnsemble } from "./types.d.ts"; +const PageStatesSchema = Schema.Struct({ + nonce: Schema.NonEmptyString, + product: Product, +}); + +class InvalidPageStateError extends Schema.TaggedErrorClass()("InvalidPageStateError", { + cause: Schema.String, +}) { + static readonly fromSchemaError = (schemaError: SchemaError): InvalidPageStateError => + new InvalidPageStateError({ + cause: SchemaIssue.makeFormatterDefault()(schemaError.issue), + }); +} + class ProductPageDOM extends Context.Service< ProductPageDOM, { @@ -48,7 +67,7 @@ class ProductPageDOM extends Context.Service< * Replie toutes les sections de la description du Produit. */ initAddToCartButtonClicks: () => unknown; - ProductVariations: ReadonlyArray; + PageStates: typeof PageStatesSchema.Type; CurrentVariation: Ref.Ref>; } >()("haikuatelier.fr/Produit/ProductPageDOM") { @@ -60,11 +79,23 @@ class ProductPageDOM extends Context.Service< Details, DetailsButtons, ProductPrice, - ProductRawJson, VariationChoiceForm, VariationSelectors, + PageStatesRawJson, } = yield* ProductPageElements; - const onFormChangeHandler = Effect.fn("onFormChangeHandler")(function*(evt: Event): Effect.fn.Return { + const API = yield* WooCommerceAPI; + + const PageStates = yield* pipe( + PageStatesRawJson.textContent, + (textContent: string) => + Schema.decodeUnknownEffect(Schema.fromJsonString(PageStatesSchema))(textContent, { errors: "all" }), + Effect.mapError(InvalidPageStateError.fromSchemaError), + Effect.tapError(Console.error), + ); + + const CurrentProduct = yield* Ref.make(Option.none()); + + const onFormChangeHandler = Effect.fn("onFormChangeHandler")(function*(evt: Event) { // La cible ne peut qu'être un Formulaire. const target: HTMLFormElement = evt.target as HTMLFormElement; const isClickAllowed = target.checkValidity() === false; @@ -75,56 +106,57 @@ class ProductPageDOM extends Context.Service< return yield* Effect.void; }); - const toggleAllDetails: () => Effect.Effect = () => + const toggleAllDetails: (shouldOpen: boolean) => Effect.Effect = (shouldOpen: boolean) => Effect.sync((): void => { + console.debug("toggleAllDetails"); pipe( // Récupère les Sections sous forme d'Ensembles. [...HashMap.values(Details)], FxArray.forEach((detail: DetailEnsemble) => { - detail.button.toggleAttribute(ATTRIBUT_ARIA_EXPANDED, false); - detail.content.toggleAttribute(ATTRIBUT_HIDDEN, true); + detail.button.toggleAttribute(ATTRIBUT_ARIA_EXPANDED, shouldOpen); + detail.content.toggleAttribute(ATTRIBUT_HIDDEN, !shouldOpen); }), ); }); - const onDetailButtonClickHandler = Effect.fn("onDetailButtonClickHandler")(function*( - evt: Event, - ): Effect.fn.Return { - // Empêche la pollution de l'historique de navigation - evt.preventDefault(); + const onDetailButtonClickHandler = Effect.fn("onDetailButtonClickHandler")( + function*(evt: Event) { + // Empêche la pollution de l'historique de navigation + evt.preventDefault(); - // La cible est connue. - const target = evt.target as HTMLButtonElement; + // La cible est connue. + const target = evt.target as HTMLButtonElement; - // Récupère le contenu correspondant au Bouton. - const linkedSection = yield* pipe( - Option.fromNullishOr(target.getAttribute(ATTRIBUT_ARIA_CONTROLS)), - Option.flatMap((contentId: string) => HashMap.get(Details, contentId)), - ); + // Récupère le contenu correspondant au Bouton. + const linkedSection = yield* pipe( + Option.fromNullishOr(target.getAttribute(ATTRIBUT_ARIA_CONTROLS)), + Option.flatMap((contentId: string) => HashMap.get(Details, contentId)), + Effect.fromOption, + Effect.mapError( + () => new IncoherentDOMError({ cause: "Un bouton de section ne correspond à aucun contenu." }), + ), + ); - // Sauvegarde l'état d'ouverture de la Section avant de toutes les fermer. - const wasCurrentSection: boolean = target.getAttribute(ATTRIBUT_ARIA_EXPANDED) === "true"; + // Sauvegarde l'état d'ouverture de la Section avant de toutes les fermer. + const wasCurrentSection: boolean = target.getAttribute(ATTRIBUT_ARIA_EXPANDED) === "true"; - // Replie toutes les Sections. - yield* toggleAllDetails(); + // Replie toutes les Sections. + yield* toggleAllDetails(false); + + // Ne fais rien de plus si l'onglet sélectionné était le courant. + if (wasCurrentSection === true) { + return yield* Effect.void; + } + + // Ouvre le nouvel onglet sélectionné. + target.toggleAttribute(ATTRIBUT_ARIA_EXPANDED, true); + linkedSection.content.toggleAttribute(ATTRIBUT_HIDDEN, false); - // Ne fais rien de plus si l'onglet sélectionné était le courant - if (wasCurrentSection === true) { return yield* Effect.void; - } - - // Ouvre le nouvel onglet sélectionné - target.toggleAttribute(ATTRIBUT_ARIA_EXPANDED, true); - linkedSection.content.toggleAttribute(ATTRIBUT_HIDDEN, false); - - return yield* Effect.void; - }); - - const ProductVariations: ReadonlyArray = yield* pipe( - JSON.parse(ProductRawJson.textContent)?.variations, - json => Schema.decodeUnknownEffect(Schema.Array(ProductVariation))(json, { onExcessProperty: "ignore" }), - Effect.mapError(error => SchemaIssue.makeFormatterStandardSchemaV1()(error.issue)), - Effect.tapCause(Console.error), + }, + Effect.tapError(Console.error), + // Ouvre toutes les Sections en cas d'erreur. + Effect.catch(() => toggleAllDetails(true)), ); const getChosenProductAttributesFromDOM = Effect.fn("getChosenProductAttributesFromDOM")(function*() { @@ -133,60 +165,90 @@ class ProductPageDOM extends Context.Service< attribute: select.id, value: select.value, })), - variations => Schema.decodeEffect(Schema.Array(ProductAttribute))(variations), - Effect.mapError(error => SchemaIssue.makeFormatterDefault()(error.issue)), - Effect.tapCause(Console.error), + variations => + Schema.decodeEffect(Schema.Array(ProductVariationAttribute))(variations, { + errors: "all", + onExcessProperty: "error", + }), + Effect.mapError(IncoherentDOMError.fromSchemaError), + Effect.tapError(Console.error), ); }); - const CurrentVariation = yield* Ref.make(Option.none()); - - const onVariationChangeHandler = Effect.fn("onVariationChangeHandler")(function*(): Effect.fn.Return< - void, - NoSuchElementError | string - > { - yield* Console.debug("onVariationChangeHandler"); + const onVariationChangeHandler = Effect.fn("onVariationChangeHandler")(function*() { + yield* Console.log("onVariationChangeHandler"); // Ne fais rien si le Formulaire n'est pas valide. if (VariationChoiceForm.checkValidity() === false) { yield* Console.debug("onVariationChangeHandler", "Le formulaire est invalide."); return yield* Effect.void; } - const equivalence = Schema.toEquivalence(Schema.Array(ProductAttribute)); + const equivalence = Schema.toEquivalence(Schema.Array(ProductVariationAttribute)); const chosenProductAttributes = yield* getChosenProductAttributesFromDOM(); - const chosenVariation: ProductVariation = yield* FxArray.findFirst( - ProductVariations, - (variation: ProductVariation) => equivalence(variation.attributes, chosenProductAttributes), + yield* Console.debug("onVariationChangeHandler", "chosenProductAttributes", chosenProductAttributes); + const chosenVariation = yield* pipe( + FxArray.findFirst( + PageStates.product.variations, + variation => equivalence(variation.attributes, chosenProductAttributes), + ), + Effect.fromOption, + Effect.mapError(error => new Error("Impossible de trouver la variation demandée.", { cause: error })), ); + yield* Console.debug("onVariationChangeHandler", "chosenVariation", chosenVariation); // Met à jour la valeur de la Variation choisie dans le Service. - yield* Ref.set(Option.some(chosenVariation))(CurrentVariation); + yield* Ref.set(Option.some(chosenVariation))(CurrentProduct); - const newPrice = chosenVariation.price; + const newPrice = String(chosenVariation.price); ProductPrice.textContent = `${newPrice}€`; return yield* Effect.void; - }, Effect.tapCause(Console.error)); + }, Effect.tapError(Console.error)); - const onAddToCartButtonHandler = Effect.fn("onAddToCartButtonHandler")(function*() { - const chosenVariation = yield* Ref.getUnsafe(CurrentVariation); - const productDetails = yield* Schema.decodeEffect(AddProductToCart)( - { - id: chosenVariation.id, - quantity: 1, - variation: chosenVariation.attributes, - }, - { errors: "all" }, + /** + * Déclenche une ajout du Produit demandé au Panier auprès du Backend. + */ + const addToCartButtonClickHandler = Effect.fn("addToCartButtonClickHandler")(function*() { + yield* Console.log("addToCartButtonClickHandler"); + + // Créé le corps de la requête + const requestBody: CartProduct = yield* pipe( + Ref.get(CurrentProduct), + Effect.flatMap(Effect.fromOption), + // Pour un Produit simple, le Ref sera vide. + Effect.orElseSucceed(() => + ProductVariation.make({ + attributes: [], + id: PageStates.product.id, + price: PageStates.product.price, + }) + ), + Effect.map(({ id, attributes }) => + // Les données ont été validées en amont. + Schema.decodeSync(CartProduct)({ id: id, quantity: 1, variation: attributes }) + ), + Effect.tap(body => Console.debug("addToCartButtonClickHandler", "requestBody", body)), ); - console.debug(productDetails); + // Désactive les interactions le temps de la requête. + AddToCartButton.toggleAttribute(ATTRIBUT_DESACTIVE); + AddToCartButton.toggleAttribute(ATTRIBUT_CHARGEMENT); + lanceAnimationCycleLoading(AddToCartButton, 500); + + const responseBody = yield* pipe( + API.AddProductToCart(PageStates.nonce, requestBody), + Effect.flatMap((response: Response) => Effect.tryPromise(async () => response.json())), + Effect.tap((response: JSONValue) => Console.debug("addToCartButtonClickHandler", "response", response)), + ); + + return responseBody; }); const initAddToCartButtonInitialState = Effect.fn("initAddToCartButtonInitialState")(function*() { /** Est-ce que le Produit affiché est en stock ? */ const isProductInStock = AddToCartButton.hasAttribute("data-in-stock") === true; - // S'il n'y a pas de stock, ne rien faire. + // S'('y a pas de stock, ne rien faire. if (isProductInStock === false) { return yield* Effect.void; } @@ -199,32 +261,32 @@ class ProductPageDOM extends Context.Service< return yield* Effect.void; }); - const initAddToCartButtonUpdates = Effect.fn("initAddToCartInteractionUpdates")(function*() { - return yield* pipe( - Stream.fromEventListener(VariationChoiceForm, "change"), - Stream.tap(onFormChangeHandler), - Stream.runDrain, - ); - }); - - const initAddToCartButtonClicks = Effect.fn("initAddToCartButtonClicks")(function*() { - return yield* pipe( - Stream.fromEventListener(AddToCartButton, "click"), - Stream.tap(onAddToCartButtonHandler), - Stream.runDrain, - ); - }); - - const initPriceUpdatesOnVariationChange = Effect.fn("initPriceUpdatesOnVariationChange")( - function*(): Effect.fn.Return { + const initAddToCartButtonUpdates = Effect.fn("initAddToCartInteractionUpdates")( + function*(): Effect.fn.Return { return yield* pipe( Stream.fromEventListener(VariationChoiceForm, "change"), - Stream.tap(onVariationChangeHandler), + Stream.tap(onFormChangeHandler), Stream.runDrain, ); }, ); + const initAddToCartButtonClicks = Effect.fn("initAddToCartButtonClicks")(function*() { + return yield* pipe( + Stream.fromEventListener(AddToCartButton, "click"), + Stream.tap(addToCartButtonClickHandler), + Stream.runDrain, + ); + }); + + const initPriceUpdatesOnVariationChange = Effect.fn("initPriceUpdatesOnVariationChange")(function*() { + return yield* pipe( + Stream.fromEventListener(VariationChoiceForm, "change"), + Stream.tap(onVariationChangeHandler), + Stream.runDrain, + ); + }); + const initDetailInteractions = Effect.fn("initDetailInteractions")(function*() { return yield* pipe( // Créé un Stream par Bouton de Section. @@ -239,13 +301,13 @@ class ProductPageDOM extends Context.Service< }); return ProductPageDOM.of({ - CurrentVariation, - ProductVariations, + CurrentVariation: CurrentProduct, initAddToCartButtonClicks, initAddToCartButtonInitialState, initAddToCartButtonUpdates, initDetailInteractions, initPriceUpdatesOnVariationChange, + PageStates, }); }), ); diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts index bb673c5f..4bacd823 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/service-elements.ts @@ -9,6 +9,7 @@ import { DOM_CONTENUS_ACCORDEON, DOM_PRIX_PRODUIT, } from "../constantes/dom.ts"; +import { IncoherentDOMError } from "./errors.ts"; import type { DetailEnsemble } from "./types.d.ts"; class ProductPageElements extends Context.Service< @@ -18,8 +19,8 @@ class ProductPageElements extends Context.Service< Details: HashMap.HashMap; DetailsButtons: NonEmptyReadonlyArray; DetailsContents: NonEmptyReadonlyArray; + PageStatesRawJson: HTMLScriptElement; ProductPrice: HTMLParagraphElement; - ProductRawJson: HTMLScriptElement; VariationChoiceForm: HTMLFormElement; VariationSelectors: ReadonlyArray; } @@ -30,8 +31,8 @@ class ProductPageElements extends Context.Service< const AddToCartButton = yield* getFirstSelectorFromDocument(DOM_BOUTON_AJOUT_PANIER); const DetailsButtons = yield* getAllSelectorFromDocument(DOM_BOUTONS_ACCORDEON); const DetailsContents = yield* getAllSelectorFromDocument(DOM_CONTENUS_ACCORDEON); + const PageStatesRawJson = yield* getFirstSelectorFromDocument("#page-states"); const ProductPrice = yield* getFirstSelectorFromDocument(DOM_PRIX_PRODUIT); - const ProductRawJson = yield* getFirstSelectorFromDocument("#product-json"); const VariationChoiceForm = yield* getFirstSelectorFromDocument("#variation-choice"); const VariationSelectors = yield* pipe( getAllSelectorFromDocument(".selecteur-produit select"), @@ -58,12 +59,12 @@ class ProductPageElements extends Context.Service< Details, DetailsButtons, DetailsContents, + PageStatesRawJson, ProductPrice, - ProductRawJson, VariationChoiceForm, VariationSelectors, }); - }), + }).pipe(Effect.mapError(IncoherentDOMError.fromNoSuchElementError)), ); } diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts index f1940311..e2d10ebd 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/page-produit/types.d.ts @@ -3,4 +3,5 @@ type DetailEnsemble = { button: HTMLButtonElement; content: HTMLDivElement; }; + export { DetailEnsemble }; diff --git a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts index 28116d1a..574086ef 100755 --- a/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts/scripts-page-produit.ts @@ -4,30 +4,17 @@ import { Console, Effect } from "effect"; import ProductPageRuntime from "./page-produit/runtime.ts"; import ProductPageDOM from "./page-produit/service-dom.ts"; -/** États utiles pour les scripts de la page. */ -type EtatsPage = { - /** L'ID en base de données du Produit. */ - idProduit: number; - /** Un nonce pour l'authentification de requêtes API vers le backend WooCommerce. */ - nonce: string; -}; - -// @ts-expect-error -- États injectés par le modèle PHP -const ETATS_PAGE: EtatsPage = _etats; - document.addEventListener("DOMContentLoaded", (): void => { - console.debug("oups"); - Effect.gen(function* () { + Effect.gen(function*() { const DOM = yield* ProductPageDOM; - console.debug("oups"); const effects = Effect.all( [ DOM.initAddToCartButtonInitialState(), DOM.initAddToCartButtonUpdates(), + DOM.initAddToCartButtonClicks(), DOM.initDetailInteractions(), DOM.initPriceUpdatesOnVariationChange(), - DOM.initAddToCartButtonClicks(), ], { concurrency: "unbounded",