From f48577ffea57174c0efc8796ea41674df1acf2b9 Mon Sep 17 00:00:00 2001 From: Roman Cinis <52065414+tsinis@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:22:10 +0100 Subject: [PATCH 1/3] ci: add explicit permissions to github workflows - Add `contents: read` and `pull-requests: write` permissions to analyze workflow - Add `contents: read` permission to backup workflow - Add `contents: write` permission to publish workflow - Add `contents: read` permission to test workflow --- .github/workflows/analyze.yaml | 4 ++++ .github/workflows/backup.yaml | 3 +++ .github/workflows/publish.yaml | 3 +++ .github/workflows/test.yaml | 3 +++ 4 files changed, 13 insertions(+) diff --git a/.github/workflows/analyze.yaml b/.github/workflows/analyze.yaml index 879e0f4..d2ef86f 100644 --- a/.github/workflows/analyze.yaml +++ b/.github/workflows/analyze.yaml @@ -11,6 +11,10 @@ on: - "pubspec.yaml" - ".github/workflows/analyze.yaml" +permissions: + contents: read + pull-requests: write + jobs: analysis: name: ๐Ÿ•ต๏ธ Analyze diff --git a/.github/workflows/backup.yaml b/.github/workflows/backup.yaml index 9681f59..79efb58 100644 --- a/.github/workflows/backup.yaml +++ b/.github/workflows/backup.yaml @@ -5,6 +5,9 @@ on: branches: - main +permissions: + contents: read + jobs: mirror-to-gitlab: name: ๐Ÿ’พ Backup to GitLab diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 6f7d85e..f508b0a 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -12,6 +12,9 @@ on: tags: - "[1-9]+.[0-9]+.[0-9]+*" +permissions: + contents: write + jobs: publish-dry-run: name: ๐Ÿ“ Publish dry run diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3851f03..4a7578f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,6 +20,9 @@ on: - "pubspec.yaml" - ".github/workflows/test.yaml" +permissions: + contents: read + jobs: test: name: ๐Ÿงช Test From ff718f2ecddbe271964e9dd67cf7eed9ab18fc06 Mon Sep 17 00:00:00 2001 From: Roman Cinis <52065414+tsinis@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:22:37 +0100 Subject: [PATCH 2/3] chore(lint): enable additional dcm rules and update dependencies - Enable shorthand preference rules that were previously disabled - Enable new metrics rules: avoid-missing-test-files, avoid-unassigned-local-variable, avoid-undisposed-instances, avoid-unnecessary-parentheses, prefer-non-nulls - Disable avoid-throw rule due to breaking change and use of maybe* methods - Update dart_code_metrics_presets to ^2.30.0 - Update test to ^1.31.0 - Update SDK constraint to ^3.11.3 - Fix RegExp instantiation to use shorthand syntax - Update example code to use maybeMapStatusCode with proper parameter handling --- analysis_options.yaml | 18 +++++++++++------- example/analysis_options.yaml | 2 +- example/lib/main.dart | 24 +++++++++++++++--------- example/pubspec.yaml | 6 +++--- lib/src/status_code.dart | 2 +- pubspec.yaml | 4 ++-- 6 files changed, 33 insertions(+), 23 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index fd5b073..88fd8e2 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -122,17 +122,12 @@ dart_code_metrics: min-occurrences: 4 # Disabled: - # Shorthands: - - prefer-returning-shorthands: false - - prefer-shorthands-with-constructors: false - - prefer-shorthands-with-enums: false - - prefer-shorthands-with-static-fields: false - # Other disabled: - arguments-ordering: false # This will be a breaking change. - avoid-continue: false # Just a matter of style. - avoid-deprecated-usage: false # Using default deprecated_member_use_from_same_package. - avoid-inferrable-type-arguments: false # Against prefer-explicit-type-arguments. - avoid-long-files: false # A lot of data and collections. + - avoid-throw: false # Breaking change + we have maybe* methods. - no-magic-number: false # Packages contain a lot of numbers. - no-magic-string: false # Packages contain a lot of strings. - parameters-ordering: false # This will be a breaking change. @@ -218,6 +213,7 @@ dart_code_metrics: - avoid-missing-completer-stack-trace: true - avoid-missing-enum-constant-in-map: true - avoid-missing-interpolation: true + - avoid-missing-test-files: true - avoid-misused-set-literals: true - avoid-misused-test-matchers: true - avoid-misused-wildcard-pattern: true @@ -276,9 +272,11 @@ dart_code_metrics: - avoid-type-casts: true - avoid-unassigned-fields: true - avoid-unassigned-late-fields: true + - avoid-unassigned-local-variable: true - avoid-unassigned-stream-subscriptions: true - avoid-uncaught-future-errors: true - avoid-unconditional-break: true + - avoid-undisposed-instances: true - avoid-unknown-pragma: true - avoid-unnecessary-block: true - avoid-unnecessary-call: true @@ -304,6 +302,7 @@ dart_code_metrics: - avoid-unnecessary-nullable-parameters: true - avoid-unnecessary-nullable-return-type: true - avoid-unnecessary-overrides: true + - avoid-unnecessary-parentheses: true - avoid-unnecessary-patterns: true - avoid-unnecessary-reassignment: true - avoid-unnecessary-return: true @@ -401,6 +400,7 @@ dart_code_metrics: - prefer-match-file-name: true - prefer-moving-to-variable: true - prefer-named-boolean-parameters: true + - prefer-non-nulls: true - prefer-null-aware-elements: true - prefer-null-aware-spread: true - prefer-overriding-parent-equality: true @@ -413,6 +413,10 @@ dart_code_metrics: - prefer-return-await: true - prefer-returning-condition: true - prefer-returning-conditional-expressions: true + - prefer-returning-shorthands: true + - prefer-shorthands-with-constructors: true + - prefer-shorthands-with-enums: true + - prefer-shorthands-with-static-fields: true - prefer-simpler-boolean-expressions: true - prefer-simpler-patterns-null-check: true - prefer-single-declaration-per-file: true @@ -658,4 +662,4 @@ linter: use_to_and_as_if_applicable: true use_truncating_division: true valid_regexps: true - void_checks: true \ No newline at end of file + void_checks: true diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0caccc8..5e2133e 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -1 +1 @@ -include: ../analysis_options.yaml \ No newline at end of file +include: ../analysis_options.yaml diff --git a/example/lib/main.dart b/example/lib/main.dart index 30c95ba..761fe26 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -85,14 +85,13 @@ Future _realClient(List arguments, [http.Client? client]) async { // If the status code is a success status code, check if it is a 201 // (Created) or 200 (OK) code. - return response.statusCode.maybeWhenStatusCode( - isSuccess: () { + return response.statusCode.maybeMapStatusCode( + isSuccess: (successStatus) { // If the status code is success one, convert it to a registered // status code object. - final registeredCode = response.statusCode.toRegisteredStatusCode(); + final registeredCode = successStatus.toRegisteredStatusCode(); - // Use the [StatusCode] type to determine the specific status code - // type. + // Use the [StatusCode] type to determine the specific status code type. return registeredCode?.maybeMap( createdHttp201: (status) { print('Response has registered success status but not 200 code'); @@ -114,17 +113,24 @@ Future _realClient(List arguments, [http.Client? client]) async { print('Response has success status but not 200 code'); // Return the status code. - return response.statusCode; + return successStatus; }, ) ?? // If the status code is not a registered status code, return the // status code. - response.statusCode; + successStatus; }, - orElse: () { + isClientError: (errorStatus) { + if (errorStatus.isOneOf(const [StatusCode.tooManyRequestsHttp429])) { + print('Response has too many requests status :('); + } + + return errorStatus; // Return the status code. + }, + orElse: (otherStatus) { // If the status code is not a success status code, print an error // message and return the status code. - print('Request failed with status: ${response.statusCode}!'); + print('Request failed with status: $otherStatus!'); return response.statusCode; }, diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 75e028c..1b7cfaf 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: A simple one and modified http package example with use of function publish_to: none environment: - sdk: ^3.11.1 + sdk: ^3.11.3 dependencies: functional_status_codes: @@ -11,6 +11,6 @@ dependencies: http: any # ignore: avoid-any-version, it's exampe app. dev_dependencies: - dart_code_metrics_presets: ^2.29.0 # DCM. + dart_code_metrics_presets: ^2.30.0 # DCM. lints: ^6.1.0 # From Google. - test: ^1.30.0 # From Google. + test: ^1.31.0 # From Google. diff --git a/lib/src/status_code.dart b/lib/src/status_code.dart index 3c8e8a1..01b9e79 100644 --- a/lib/src/status_code.dart +++ b/lib/src/status_code.dart @@ -734,7 +734,7 @@ extension type const StatusCode._(int _code) implements int { /// See also: /// - [pattern], the raw regular expression string this getter utilizes. /// - [StatusCode], which contains standard HTTP status codes. - static RegExp get regExp => RegExp(pattern, caseSensitive: false); + static RegExp get regExp => .new(pattern, caseSensitive: false); /// Returns the [StatusCode] type value for the given status code, if it /// exists. Otherwise, returns `null`. diff --git a/pubspec.yaml b/pubspec.yaml index 1a916aa..2cd86ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,6 @@ environment: dev_dependencies: coverage: ^1.15.0 # From Google. - dart_code_metrics_presets: ^2.29.0 # DCM. + dart_code_metrics_presets: ^2.30.0 # DCM. lints: ^6.1.0 # From Google. - test: ^1.30.0 # From Google. + test: ^1.31.0 # From Google. From 6409495e31b6062c5fc726d080509e4a44d874e5 Mon Sep 17 00:00:00 2001 From: Roman Cinis <52065414+tsinis@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:37:31 +0100 Subject: [PATCH 3/3] chore: refactor workflow permissions and update readme - Move `contents: write` permission from global to `check-version` job only - Reorder debug configurations in `.zed/debug.json` for consistency - Add GitHub issues badge to README - Update test count from 1000 to 1120 in documentation - Clarify industry adoption timeline (remove specific year reference) - Add verified publisher feature to README - Fix status code variable reference in example code --- .github/workflows/publish.yaml | 5 ++--- .zed/debug.json | 10 ++++++---- README.md | 7 +++++-- example/lib/main.dart | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index f508b0a..1264f2c 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -12,9 +12,6 @@ on: tags: - "[1-9]+.[0-9]+.[0-9]+*" -permissions: - contents: write - jobs: publish-dry-run: name: ๐Ÿ“ Publish dry run @@ -37,6 +34,8 @@ jobs: check-version: name: ๐Ÿ’ก Check version runs-on: ubuntu-latest + permissions: + contents: write if: github.ref_type == 'tag' timeout-minutes: 10 steps: diff --git a/.zed/debug.json b/.zed/debug.json index 4419b2c..328caf0 100644 --- a/.zed/debug.json +++ b/.zed/debug.json @@ -1,17 +1,19 @@ [ { "adapter": "Dart", - "label": "Run example (simple)", + "label": "Run example (real client)", "type": "dart", - "args": ["--simple"], "request": "launch", "program": "$ZED_WORKTREE_ROOT/example/lib/main.dart" }, { "adapter": "Dart", - "label": "Run example (real client)", + "label": "Run example (simple)", "type": "dart", "request": "launch", - "program": "$ZED_WORKTREE_ROOT/example/lib/main.dart" + "program": "$ZED_WORKTREE_ROOT/example/lib/main.dart", + "args": [ + "--simple" + ] } ] diff --git a/README.md b/README.md index 0f481f6..08ea95f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![CodeFactor](https://www.codefactor.io/repository/github/tsinis/functional_status_codes/badge)](https://www.codefactor.io/repository/github/tsinis/functional_status_codes) [![Pub points](https://img.shields.io/pub/points/functional_status_codes)](https://pub.dev/packages/functional_status_codes/score) [![Created](https://img.shields.io/github/created-at/tsinis/functional_status_codes)](https://github.com/tsinis/functional_status_codes/commit/23d35c4fc890d01b8dc93409738e4fc61712e94f) +[![GitHub issues](https://img.shields.io/github/issues-raw/tsinis/functional_status_codes)](https://github.com/tsinis/functional_status_codes/issues?q=is%3Aissue+is%3Aopen) ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/tsinis/functional_status_codes?utm_source=oss&utm_medium=github&utm_campaign=tsinis%2Ffunctional_status_codes&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Size](https://img.shields.io/github/languages/code-size/tsinis/functional_status_codes)](https://github.com/tsinis/functional_status_codes#why-should-i-use-this-package) @@ -139,9 +140,9 @@ The use of `StatusCode` extension type and boolean getters (`isInformational`, ` 10. **No 3rd-party dependencies**: This package has no third-party dependencies, ensuring that you won't have any issues or conflicts with other dependencies (no even `meta` here, because of that). -11. **High code coverage**: The code in this package has almost 100% code coverage, with more than 1000 tests, providing confidence in its reliability and stability. +11. **High code coverage**: The code in this package has almost 100% code coverage, with more than 1120 tests, providing confidence in its reliability and stability. -12. **Industry adopted**: This package is actively used (since 2022) in production by numerous European companies, ensuring its efficacy and robustness in real-world scenarios. +12. **Industry adopted**: This package is actively used (for years) in production by numerous European companies, ensuring its efficacy and robustness in real-world scenarios. 13. **BSD-3-Clause License**: This package and sources are released under the BSD-3-Clause license, a permissive license that is also used by the Dart and Flutter SDKs. It allows users to use, modify, and distribute the code with minimal restrictions. @@ -151,6 +152,8 @@ The use of `StatusCode` extension type and boolean getters (`isInformational`, ` 16. **Mirrored Repository**: The GitHub repository, including all package tags, is mirrored on [GitLab](https://gitlab.com/tsinis/functional_status_codes/), providing an alternative access point should GitHub become unavailable. +17. **Verified publisher**: Published and maintained under an active, verified pub.dev publisher account since 2022. + By using these features of the `functional_status_codes` package, you promote a more robust, readable, and maintainable approach to HTTP status code handling in your Dart projects. ### Getting started diff --git a/example/lib/main.dart b/example/lib/main.dart index 761fe26..ebefbaf 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -132,7 +132,7 @@ Future _realClient(List arguments, [http.Client? client]) async { // message and return the status code. print('Request failed with status: $otherStatus!'); - return response.statusCode; + return otherStatus; }, ); }