Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b3caec7
feat!: consolidate Ack 2.0 single-part codegen and Draft 2020-12 runtime
leoafarias Oct 9, 2026
4d70eea
refactor(ack): unify native and imported multipleOf on exact decimal …
leoafarias Oct 9, 2026
05ab5b6
style: format workspace with dart format
leoafarias Oct 9, 2026
0dd6677
Merge remote-tracking branch 'origin/main' into leoafarias/ack-2-0-pr…
leoafarias Oct 9, 2026
0dfbf93
feat(ack)!: preserve Draft 2020-12 by default on toJsonSchema and toS…
leoafarias Oct 9, 2026
092ed37
feat(ack,ack_generator): unify constraint annotations under @Check.* …
leoafarias Oct 9, 2026
43d3698
feat(ack): seal SchemaError and AckSchema hierarchies
leoafarias Oct 9, 2026
309d494
feat(ack,ack_generator): make trim, toLowerCase, and toUpperCase two-…
leoafarias Oct 9, 2026
047b807
test(ack_generator): align exports and guide integration tests with @…
leoafarias Oct 9, 2026
39ae10e
Merge remote-tracking branch 'origin/main' into leoafarias/ack-2-0-pr…
leoafarias Oct 9, 2026
9e77a96
feat(ack): add StandardSchemaV1 interoperability contract (#129)
leoafarias Oct 10, 2026
556e426
feat(ack,ack_generator): add JsonMaybe<T> for PATCH key presence (#148)
leoafarias Oct 10, 2026
5f71972
feat(ack,ack_generator): enforce type-owned schema bounds/boundaries …
leoafarias Oct 10, 2026
90eebfa
feat(ack,ack_generator): support @Schemable(schemas: [...]) + auto li…
leoafarias Oct 10, 2026
66cb812
docs,test(ack_generator): align READMEs, docs, and llms.txt with Ack …
leoafarias Oct 10, 2026
1ace93b
chore(release): prepare Ack 2.0.0-beta.1
leoafarias Oct 10, 2026
7bde538
ci: remove consolidated json_schema_format_import_test from Chrome list
leoafarias Oct 10, 2026
5b11c5a
feat(ack,ack_generator)!: rename @Check to @Validate and polish class…
leoafarias Oct 10, 2026
b66b26f
refactor!: complete 2.0 reference design audit, API cleanup, and code…
leoafarias Oct 11, 2026
a764f47
refactor(ack,ack_generator): decompose model graph builders, emitters…
leoafarias Oct 11, 2026
4f1c54d
fix(ack_generator): read AST doc comments on primary constructor decl…
leoafarias Oct 12, 2026
38af885
chore(ack_generator): widen analyzer constraint to >=10.0.0 <15.0.0 f…
leoafarias Oct 12, 2026
cabd6cd
chore(ack_generator): migrate AST helpers to analyzer 13
leoafarias Oct 12, 2026
d616763
fix(ack,ack_generator): harden JSON Schema export composition, Draft-…
leoafarias Oct 12, 2026
0f508da
fix(ack): preserve source allOf when layering conflicting constraints
leoafarias Oct 12, 2026
2c2baa9
chore(ack): pin Flutter 3.47.5 in .fvmrc and update ack_generator tes…
leoafarias Oct 12, 2026
dcaf31d
docs: add migration guide, ecosystem integrations guide, and merge v1…
leoafarias Oct 12, 2026
5608c4f
chore(ci): add Flutter 3.47.5 to flutter-releases.json and format wit…
leoafarias Oct 12, 2026
b5045ff
refactor(ack)!: unify @Validate.optional, @Validate.required, and @Va…
leoafarias Oct 12, 2026
b4c4f05
feat(ack)!: prepare 2.0.0-alpha.1 on release/2.0 with @AckKey and rev…
leoafarias Oct 14, 2026
8290120
feat(ack_generator): allow non-nullable Object override in class @Sch…
leoafarias Oct 14, 2026
9678ac3
feat(ack_generator): support scalar @Validate.* item constraints on L…
leoafarias Oct 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .fvmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"flutter": "3.41.2"
"flutter": "3.47.5"
}
4 changes: 4 additions & 0 deletions .github/flutter-releases.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"3.41.2": {
"dart": "3.11.0",
"sha256": "4a04f8a6152986d14fc137ffaf98106ca743c0f9ab66f1bc2f20ee84eb573e5c"
},
"3.47.5": {
"dart": "3.13.4",
"sha256": "2132e990f236f8d22e7c6314b29a191a95b10d7cbcfec9b4e2e303d996652cbb"
}
}
}
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [main]
branches: [main, 'release/**']
# No `branches:` filter. A stacked pull request targets its parent
# branch, not main, and would otherwise run no checks at all.
pull_request:
Expand Down Expand Up @@ -50,8 +50,7 @@ jobs:
test/schemas/extensions/list_schema_extensions_test.dart \
test/utils/collection_utils_test.dart \
test/json_schema_import_test.dart \
test/json_schema_import_api_test.dart \
test/json_schema_format_import_test.dart
test/json_schema_import_api_test.dart

- name: Test JSON Schema import bridge in Chrome
working-directory: packages/ack_json_schema_builder
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Release preflight

on:
push:
branches: [main]
branches: [main, 'release/**']
# No `branches:` filter. A stacked pull request targets its parent
# branch, not main, and would otherwise run no checks at all.
pull_request:
Expand All @@ -25,8 +25,9 @@ env:
# against the change severity, so a breaking change requires a major bump.
API_BASELINE_VERSION: '1.6.2'
# The lowest SDK versions that packages/*/pubspec.yaml accept.
MINIMUM_DART_VERSION: '3.9.0'
MINIMUM_FLUTTER_VERSION: '3.35.0'
MINIMUM_DART_VERSION: '3.11.0'
MINIMUM_FLUTTER_VERSION: '3.41.2'


jobs:
minimum-dart-sdk:
Expand Down Expand Up @@ -192,13 +193,12 @@ jobs:
- name: Resolve workspace dependencies
run: dart pub get

# `.ack.dart` holds the generated models and `.ack.g.dart` holds the JSON
# mapping. Both are generated, so a clean rebuild must reproduce them.
# The `*.g.dart` glob below also matches `*.ack.g.dart`.
# `.g.dart` holds the generated Ack models, schemas, and JSON mapping.
# A clean rebuild must reproduce them identically.
- name: Delete the committed generator output
run: |
set -euo pipefail
git ls-files -z -- '*.ack.dart' '*.g.dart' \
git ls-files -z -- '*.g.dart' \
| xargs -0 --no-run-if-empty rm --

- name: Regenerate from a clean tree
Expand Down
25 changes: 19 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ jobs:
fetch-depth: 0
persist-credentials: false

# A full checkout already carries origin/main. The refresh keeps the
# check current when the tag lands moments after a merge, and the
# verification step reports a missing ref on its own.
# A full checkout already carries origin/main and origin/release/*. The
# refresh keeps the check current when the tag lands moments after a
# merge, and the verification step reports a missing ref on its own.
- name: Refresh the release branch
run: |
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main \
|| echo "Could not refresh origin/main; using the checked-out refs."
git fetch --no-tags origin \
+refs/heads/main:refs/remotes/origin/main \
'+refs/heads/release/*:refs/remotes/origin/release/*' \
|| echo "Could not refresh origin refs; using the checked-out refs."

- name: Set up the pinned Flutter SDK
uses: ./.github/actions/setup-flutter
Expand All @@ -42,10 +44,21 @@ jobs:

# A tag is the only trigger of this workflow, so the tag must prove that
# it points at reviewed code and that every package agrees on the version.
# Pre-release tags may also publish from a matching `release/<major>.<minor>`
# branch.
- name: Require a releasable tag
run: |
set -euo pipefail
main_ref="origin/main"
if [[ "$GITHUB_REF_NAME" =~ ^v([0-9]+\.[0-9]+)\.[0-9]+- ]]; then
release_ref="origin/release/${BASH_REMATCH[1]}"
if git rev-parse --verify "${release_ref}^{commit}" >/dev/null 2>&1 \
&& git merge-base --is-ancestor "$GITHUB_SHA" "$release_ref"; then
main_ref="$release_ref"
fi
fi
dart scripts/verify_release_tag.dart "$GITHUB_REF_NAME" \
--commit="$GITHUB_SHA" --main-ref=origin/main
--commit="$GITHUB_SHA" --main-ref="$main_ref"

preflight:
name: Preflight
Expand Down
90 changes: 90 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,96 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## 2.0.0-alpha.1

### Breaking & Substitutions

* **Single `.g.dart` part & direct JSON emitter (`#189`)**: `ack_generator:ack_generator`
now emits a single `<file>.g.dart` part via `SharedPartBuilder` with direct
`toJson()` / `fromJson()` helpers (no `json_serializable` or `json_annotation`
dependency).
* **Substitute:** Replace `part '<file>.ack.dart';` + `part '<file>.ack.g.dart';`
with `part '<file>.g.dart';`.
* **Substitute:** Replace `ack_generator|ack_models` and
`ack_generator|ack_model_json` in `build.yaml` with
`ack_generator|ack_generator`.
* **Unified `@Validate.*` presence & constraint namespace (`#191`)**: Removed the
top-level presence classes (`@Optional`, `@Required`, `@NotNull`), the 18
`@Deprecated` 1.x top-level constraint classes (`@Min`, `@Max`, `@Email`, etc.),
and `package:ack/format_annotations.dart`.
* **Substitute:** Use `@Validate.<name>(...)` from `package:ack/ack.dart`
(`@Validate.optional()`, `@Validate.required()`, `@Validate.notNull()`,
`@Validate.min(...)`, `@Validate.max(...)`, `@Validate.multipleOf(...)`,
`@Validate.positive()`, `@Validate.negative()`, `@Validate.minLength(...)`,
`@Validate.maxLength(...)`, `@Validate.matches(...)`, `@Validate.notEmpty()`,
`@Validate.email()`, `@Validate.url()`, `@Validate.uuid()`, `@Validate.date()`,
`@Validate.dateTime()`, `@Validate.uri()`, `@Validate.ip()`, `@Validate.ipv4()`,
`@Validate.ipv6()`, `@Validate.minItems(...)`, `@Validate.maxItems(...)`,
`@Validate.uniqueItems()`).
* **Removed legacy 1.x generator annotations & shims (`#188`, `#189`)**:
Removed `@AckType`, `@AckInfer`, `@AckModel`, `@AckField`, `JsonKeyCaseStyle`,
`AckTypeDef`, `AckFieldPresence`, `*Type` extension-type models, and the
`@JsonKey(name: ...)` fallback.
* **Substitute:** Use `@Schemable()` on schemas and classes,
`@Validate.optional()` / `@Validate.required()` / `@Validate.notNull()` for
field presence, `/// @description ...` for field descriptions, and
`@AckKey('...')` for wire-name overrides.
* **Removed redundant helpers & `StandardSchemaV1` (`#129`)**:
* **Substitute:** `Ack.enumCodec(E.values)` $\rightarrow$ `Ack.enumValues(E.values)`.
* **Substitute:** `registerAckModelTool(...)` $\rightarrow$
`registerAckTool(..., input: Model.schema)`.
* **Substitute:** `convertAckSchemaModelToBuilder(m)` $\rightarrow$
`schema.toJsonSchemaBuilder()`.
* **Substitute:** `StandardSchemaV1` $\rightarrow$ `AckSchema<Boundary, Runtime>`
+ `SchemaResult<T>`.
* **Sealed `SchemaError` & `AckSchema` hierarchies + decoder `Error` propagation (`#163`)**:
`SchemaError` and `AckSchema` are now `sealed class`es for exhaustive pattern
matching. `CodecSchema` rethrows programmer `Error`s during `parse` /
`safeParse` (matching `encode` / `safeEncode`) and catches only `Exception`s
as `SchemaTransformError`.
* **JSON Schema Draft 2020-12 default export & `format` annotation mode (`#171`, `#186`)**:
`Ack.fromJsonSchema()` defaults to `assertFormats: false` (pass
`assertFormats: true` or declare the `format-assertion` vocabulary to enforce
format assertions). `toJsonSchema()`, `toSchemaModel()`, and
`toJsonSchemaBuilder()` preserve imported Draft 2020-12 resources by default;
use `toJsonSchemaDraft7()`, `toSchemaModelDraft7()`, or
`toJsonSchemaBuilderDraft7()` when legacy Draft-07 lowering is needed.

### Added

* **`JsonMaybe<T>` tri-state presence (`#148`)**: `sealed class JsonMaybe<T>`
(`JsonAbsent<T>`, `JsonValue<T>`) distinguishes omitted keys (`JsonAbsent`),
explicit `null` (`JsonValue(null)`), and present values (`JsonValue(v)`) in
`@Schemable()` class-first models for `PATCH` payloads.
* **Layered custom schema resolution (`#185`)**: Class-first `@Schemable()`
fields resolve custom types via `@Schemable(schemas: [...])` (on classes,
unions, or `library;` directives), type-owned `T.schema` / `T.schema<...>()`
factories, or automatic detection of a unique top-level
`AckSchema<Boundary, T>` in the current library.
* **Two-way `StringSchema` normalizers**: `.trim()`, `.toLowerCase()`, and
`.toUpperCase()` execute in declaration order during both `parse` and `encode`,
preserve `StringSchema` chaining, work in `@Schemable()` models, and export as
`type: 'string'` without `'x-transformed': true`.
* **Full JSON Schema Draft 2020-12 runtime & `.schema.json` generator (`#167`, `#171`, `#186`)**:
Supports `$dynamicRef`, `$dynamicAnchor`, `unevaluatedProperties`,
`unevaluatedItems`, `prefixItems`, `dependentRequired`, `dependentSchemas`,
`patternProperties`, `minContains`, `maxContains`, bundled offline 2020-12
meta-schemas, and all 19 Draft 2020-12 formats. Opt-in
`ack_generator:ack_json_schema` compiles `lib/**/*.schema.json` into
`<name>.schema.dart` + `<name>.schema.g.dart`.

### Fixed

* Explicit Draft-7 export rejects unsupported Draft 2020-12 assertions rather
than emitting keywords that Draft-7 validators ignore.
* Imported schema exports preserve JSON Pointer targets through retrieval URI
aliases, share identical identified resources across composed imports, and
preserve occurrence-level nullability and constraints (including source
`allOf` when layering conflicting constraints).
* Preserve integral decimal length and item bounds in `.schema.json` generation,
and use validated value models for Unicode regex patterns and named scalar
unions.

## 1.7.0

* Remove `ack_annotations`; annotations now ship in `ack` (`package:ack/ack.dart`,
Expand Down
45 changes: 21 additions & 24 deletions PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,17 @@ new compatible features/packages, and major when any stable public API breaks.
For 1.7.0, the imported-pattern Unicode behavior change is a deliberately
accepted exception to this major-version policy.

The next release is **1.7.0**, promoting the 1.7.0 beta series to stable across
all five publishable packages. It ships annotations in `package:ack`, unifies
model and schema generation on `@Schemable()`, adds `multipleOf`, `contains`,
`if`/`then`/`else`, built-in `format` assertions, `x-*` vendor extension
tolerance, Draft-07 `$schema` URI support, and `JsonSchemaValidationError`
diagnostics (`keyword`, `keywordLocation`, `documentUri`, `pointer`) to
`Ack.fromJsonSchema()`, and speeds up validation and JSON Schema export.
The beta.5 imported-pattern change to ECMA-262 Unicode mode applies when
upgrading from stable 1.6.2 or earlier 1.7.0 betas; review imported patterns,
including identity escapes and expressions that count UTF-16 code units. Native
`Ack.string().matches()` keeps its Dart regex contract. The beta.3 annotation
and generator migration applies to consumers coming from 1.6.2 or earlier
betas. The API check compares all five packages against 1.6.2; generator
compatibility also requires the consumer build and runtime tests because the
API check cannot inspect generated consumer code.
The next candidate is **2.0.0-alpha.1**. It introduces single-pass `.g.dart`
code generation without a runtime `json_serializable` delegation step, the
unified `@Validate.*` constraint annotation namespace, custom schema resolution
via `@Schemable(schemas: [...])` and automatic same-library detection,
`JsonMaybe<T>` PATCH presence semantics, two-way `StringSchema` normalizers
(`.trim()`, `.toLowerCase()`, `.toUpperCase()`), sealed `SchemaError` and
`AckSchema` hierarchies, full JSON Schema Draft 2020-12 runtime validation and
`.schema.json` model generation with default Draft 2020-12 preservation on
`toJsonSchema()`, and removal of deprecated 1.x compatibility shims
(`StandardSchemaV1`, `@AckType`, `@AckInfer`, `@AckModel`, and `.ack.dart` /
`.ack.g.dart` dual-part generation).

The shared API baseline for this release is 1.6.2. Confirm that all five
packages have published 1.6.2 versions before preparing the release.
Expand Down Expand Up @@ -61,7 +57,7 @@ References: [Melos versioning](https://melos.invertase.dev/commands/version),
3. Preview/prepare a coordinated version without creating commits or tags:

```sh
dart run melos version --manual-version=ack:1.7.0 --yes --no-git-commit-version
dart run melos version --manual-version=ack:2.0.0-alpha.1 --yes --no-git-commit-version
```

Use the named flag, not a positional package argument: the positional form
Expand All @@ -76,7 +72,7 @@ References: [Melos versioning](https://melos.invertase.dev/commands/version),
Update installation snippets to match each package's version.
5. Compare against the most recent coordinated stable release in
`API_BASELINE_VERSION` in `.github/workflows/preflight.yml` (currently
`1.6.2`). Keep that stable baseline for prereleases, so a beta cannot hide a
`1.6.2`). Keep that stable baseline for prereleases, so a prerelease cannot hide a
breaking change since the last stable version. Raise it after the next
stable release. Record a new
package's actual first release in `ackPackageFirstReleases` in
Expand All @@ -88,15 +84,16 @@ References: [Melos versioning](https://melos.invertase.dev/commands/version),
7. Validate the complete release from that clean commit:

```sh
dart scripts/verify_release_tag.dart v1.7.0 --skip-ancestry
dart scripts/verify_release_tag.dart v2.0.0-alpha.1 --skip-ancestry
dart run melos run ci
dart scripts/api_check.dart 1.6.2
dart scripts/publish_dry_run.dart
dart run melos run validate-jsonschema:batch
```

`--skip-ancestry` is only for preparing a version before the tag exists.
The actual release workflow always enforces ancestry on `origin/main`.
The actual release workflow always enforces ancestry on `origin/main` (or the
matching `origin/release/<major>.<minor>` branch for pre-release tags).
CI also runs minimum Dart/Flutter SDK checks, deterministic generation, and
staged hosted-dependency analysis; all must pass on the release merge commit.
8. Review and merge the release PR before creating the tag.
Expand Down Expand Up @@ -142,9 +139,9 @@ After the release commit's CI/preflight succeeds:
```sh
git fetch origin main --tags
# Use the exact reviewed release merge commit, not an arbitrary later main head.
git tag -a v1.7.0 <release-merge-sha> -m 'Ack 1.7.0'
dart scripts/verify_release_tag.dart v1.7.0
git push origin v1.7.0
git tag -a v2.0.0-alpha.1 <release-merge-sha> -m 'Ack 2.0.0 alpha 1'
dart scripts/verify_release_tag.dart v2.0.0-alpha.1
git push origin v2.0.0-alpha.1
```

Pushing the tag triggers `.github/workflows/release.yml`; there is no Melos
Expand Down Expand Up @@ -172,6 +169,6 @@ or republish different contents under an existing version.

After all five exact versions are visible, create the GitHub Release from the
existing tag using the prepared release notes and mark it as a prerelease for
beta versions. Before the first subsequent code
alpha/beta versions. Before the first subsequent code
change, begin a new unreleased changelog section instead of editing the
1.7.0 notes.
2.0.0-alpha.1 notes.
Loading
Loading