terradart_codegen 0.35.0
terradart_codegen: ^0.35.0 copied to clipboard
terradart maintainer tooling — parses Terraform provider schema JSON and Magic Modules YAML and emits curated factory wrappers via wrap. Ships the terradart-codegen maintainer CLI.
Changelog #
0.35.0 - 2026-10-03 #
- No API changes. Lockstep release with the
terradartcommand's--jsonoutput, fixed exit codes,--no-input,--dry-run,terradart help <topic>and bundled agent skill.
0.34.0 - 2026-10-03 #
- No API changes. Lockstep release with the
terradartcommand'sinit,validateandstate migrate.
0.33.0 - 2026-10-02 #
- Breaking: the executable
dart pub global activate terradart_codegeninstalls isterradart-codegen(terradart-codegen wrap), so theterradartcommand belongs toterradart_cli.dart run terradart_codegen:terradartis unchanged. See MIGRATING.md.
0.32.1 - 2026-10-02 #
- No API changes. Republishes the 0.32.0 workspace so
terradart_appwrite,terradart_cloudflare,terradart_awsandterradart_migratereach pub.dev; the 0.32.0 publish workflow stopped them at a wrapper-count check that also counted hand-written files, and now counts only generated wrappers (#877).
0.32.0 - 2026-10-02 #
- Breaking: every generated attribute getter is the attribute's camelCase name (
name,secretId) instead of<name>Ref, and returns aTfRef<T>an argument takes directly. A name that is a Dart reserved word or aResource/Datamember takes anAttrsuffix (kindAttr,defaultAttr,refAttr,localNameAttr). See MIGRATING.md. - Breaking:
- mm: resource-refsin a reference ledger types every Magic ModulesResourceRefinput of the google and google-beta lanes as the same-product resource it imports (explicit rules win; its ownattributes/excludecover the rest), so the weekly MM re-sync types new references too. See MIGRATING.md. - Breaking:
- parents: iam-adjunctstypes the parent of every*_iam_member/*_iam_binding/*_iam_policyadjunct as oneRefTo<Parent>argument named after the parent, replacing the identity input; the positional keys the parent also exports stay optional and default toRefTo.alsoAs(...). A ledger rule'swith: [location, project]absorbs keys the same way. See MIGRATING.md. - Breaking:
- principals: <Type>types the IAM grant inputs itsslots/typespatterns match as a hand-written principal type —IamPrincipalon google,AppwritePermissionon appwrite (principalTypes) — and every block with a computed-onlymemberattribute gets anIamPrincipal get principal. The migration manifest records these slots asprincipal. See MIGRATING.md. - Generated doc-comment examples build a block nested inside another block or a sealed variant with
.new(...). - Breaking: a sealed variant whose member is a single block with no fields takes its helper as an optional positional parameter defaulting to the empty helper (
.avroFormat()), and the migration manifest's helper extractor reads optional positional parameters. See MIGRATING.md. - Breaking: every generated barrel re-exports
terradart_core, and a data source is also exported from the service barrel its name matches (an exact resource twin, else the longest barrel the name starts with);dataSourceBarrels:in a barrels manifest places the rest. Every data source class takes theDataprefix. Helperencode()and sealedblockKey/encode()/argMapare@internal. See MIGRATING.md. - Breaking: generated factories forward
provider:assuper.provider(aStackProvider?). A lane with--resource-provideroverridesResource.defaultProviderinstead of defaultingproviderto a string. See MIGRATING.md. - Breaking:
wraptypes an input the provider schema marks sensitiveSensitive<T>instead ofTfArg<T>— constructor parameters, nested helper fields and sealed variants. A helper shared between blocks takesSensitive<T>wherever one occurrence is sensitive. The migration manifest records these slots as before. See MIGRATING.md. - Breaking:
wrapemits every enum (derived, prelude andwrap-promotevalid values) as an extension type implementingTfArg<String>with.variable/.expression/.argconstructors, and an enum slot takes the enum bare (E,List<E>) instead ofTfArg<E>.EnumExtractor.lenient()is removed; the one extractor reads the new shape. See MIGRATING.md. - Breaking: generated resource and data-source factories take the local name first:
GooglePubsubTopic(super.localName, {...}).
0.31.0 - 2026-10-01 #
- Breaking —
terradart wrapnames derived helper, enum and nested sealed types<ResourceStem><Leaf>(nested_type_names.dart): the nearest parent joins only to tell two differently shaped blocks apart, blocks (and enum inputs) of the same name and shape share one type, andjoinTypeNamedrops the words the stem ends with unless the shorter name is reserved.tool/type_name_length_test.dartandtool/type_name_stutter_test.dartgate the result. See MIGRATING.md. - Wrappers with
deriveOutputGetters: truederive a<name>Refgetter for every input attribute (scope_id→TfRef<String> get scopeIdRef,optional + computedincluded; enum inputs areTfRef<String>, their Terraform value). Write-only inputs,tags_all, a name a computed-only getter already has, and a name a hand-writtenextraGettersgetter declares are skipped. Data-source wrappers now also let a hand-writtenextraGettersgetter shadow a derived one. - Nested helper classes type a list or set of strings, numbers or booleans by its element type (
TfArg<List<String>>,List<num>,List<bool>), aswriteDartTypedoes at the top level, instead ofTfArg<List<Object?>>; lists of objects stayList<Object?>. - The Magic Modules parser pairs every
write_only: truefield with its generated<field>_wosibling: the sibling joins eachexactly_one_of/at_least_one_ofgroup the field is in, the pair is aconflictsset (the provider rejects both), and a required write-only field makes the pair anexactly_one_ofgroup — sopassword/password_wowrap as one sealed argument. - Override axes
exactlyOneOf/atMostOneOf: lists of comma-separated dotted member paths ("template.volumes.gcs, template.volumes.secret") for an exclusive group no group source declares — an API rule the provider leaves to the service.wrapseals them like the source's groups (sealedNamesnames them) and fails (E406) on an entry that names no input or that the source already declares. - A reference input held by a hand-written prelude class at any depth (a hand-sealed variant or a hand helper declaring
final RefTo<Target> <input>;) counts as typed ininputs typed as referencesand imports its target, instead of printingreference input not typed. Only top-level inputs of hand-sealed variants counted before. terradart wrapdrops each exclusive-group member the provider schema has no input for, and a group left with fewer than two members, printingexclusive group names no schema input: <type> [<members>]for the latter. Magic Modules YAML is shared by the GA and beta providers, so the GA lane read groups namingmin_version: betafields (google_compute_region_network_endpoint_groupserverless_deployment) or fields at the wrong depth, which could never seal.- The Magic Modules parser lifts the fields of a
flatten_objectproperty into its parent, as Terraform does, in group paths and enum paths:google_monitoring_slo'sservice_level_indicator.basic_sligroups arebasic_sligroups now. dartTypeOverridestakes dotted keys for inputs of derived nested helpers (scheduling.on_host_maintenance: OnHostMaintenance), so an override that moves toderiveNestedTypeskeeps a hand-written enum; such an input is not derived as an enum or a reference.wrapfails on a dotted key that names no input of a derived helper.terradart wrapprints two more kinds of typing debt, beside the unsealed groups:reference input not typed: <type>.<path>for each input the reference-target ledger matches that stays a string (a hand-written helper, a sealed variant, an untyped passthrough), andnested helper not reachable from the constructor: <type>.<block>for each derived top-level helper no constructor input or sealed variant takes (a prelude class whose name only starts with the helper's, such asComputeFirewallAllowPolicyforComputeFirewallAllow, does not take it). Inputs in an unreachable helper no longer count as typed in theinputs typed as referencestotal. Generated output is unchanged.- The Magic Modules parser ignores
exactly_one_of/at_least_one_of/conflictsdeclared on anoutput: trueproperty (or below one) and drops output-only members from every group: upstream lists enum values there on some output fields (google_network_connectivity_hub.state), which read as a group of inputs that do not exist. terradart wrap --reference-targets FILEreads the provider's section of a reference-target ledger (tool/reference_targets.yaml): per referenced resource type, a regex over input paths, the attribute a matched input emits,attributesoverrides andexcludeentries. Every run validates it against the schema and fails with E406 on a target the lane does not curate, an attribute the target or its data source does not export, an input two rules claim, or (outside--only) a rule, override or exclusion that matches nothing.--typed-referencesalso types each matched string input asRefTo<Target>(a list asTfArg<List<RefTo<Target>>>), top-level and in nested helpers, encoding it withencodeAs('<attribute>'); enum-typed inputs, inputs an override types, sealed-group members and the target's own top-level inputs stay as they are. A lane opts in withreferences: checkorreferences: typedintool/providers.yaml.- The migration manifest has a
referenceslot kind with the target class (dartType) and the emittedattribute, derived fromRefTo<C>/TfArg<List<RefTo<C>>>parameters and fields and theirencodeAscall. - Breaking — a derived sealed type declares one
const factoryconstructor per member, named after it and taking its value positionally (const factory LambdaFunctionCode.filename(TfArg<String> filename) = ...;), so a caller writes the Dart 3.10 dot shorthand.filename(...). The variant classes are renamed<SealedType><Member>(was<Prefix><Member>Option) and take their member positionally. The migration manifest records each variant's factory asMigrateHelper.shorthand, read from any sealed type's redirecting factories, hand-written ones included. - Every resource wrapper emits
RefTo<Class> get ref => RefTo.of(this), and every data source whose Terraform type has a resource wrapper in the same run emits the samerefgetter (RefTo.read(this), importing the resource's file). A data source that already has a getter namedref(cloudflarecloudflare_filter,cloudflare_firewall_rule) keeps it and gets none; so does a resource with arefoutput attribute (cloudflare_firewall_rule). - Breaking — requires Dart 3.10 (
sdk: ^3.10.0, was^3.6.0). Source is formatted in the Dart 3.7+ tall style. deriveExactlyOnealso seals at-most-one groups — mutually exclusive inputs the provider also accepts none of. A hints file'sat_most_one_of_groups(same shape asexactly_one_of_groups) becomes one nullable sealed-type argument per resource-level group (aSealed? slotcustom slot spread with...?slot?.argMap) or nullable helper field per nested group (...?field?.encode()); exactly-one groups claim their members first.wrapprints each at-most-one group it cannot seal (at-most-one group not sealed: ...). The migration manifest records these slots as optional mergedsealedslots. No lane's hints carry the key yet, so generated output is unchanged.- The migration manifest emitter writes a dartdoc line on the generated
<package>MigrateManifestconstant. terradart wrap --mm-groups(a lane'smmGroups: trueintool/providers.yaml, now set on the google GA lane): the Magic Modulesexactly_one_of/conflicts/at_least_one_ofgroups of--mm-hintsfeedderiveExactlyOnewhile enum typing stays the merged IR's. Exclusive with--mm-hintsand--provider-enums. No GA override setsderiveExactlyOneyet, so generated output is unchanged.deriveExactlyOnetakes a group member that a custom slot holds as an optional hand-written helper (Helper? xwithif (x != null) '<key>': TfArg.literal(...)) as a variant that keeps the helper type, instead of leaving the group unsealed; it also rewritesargMapOrderalong withparamOrder.GoogleProviderRulesscaffoldsderiveExactlyOne: trueon new google resources (wrap-init, and so the weekly bump's new types).- Breaking — sealed slots take a concept name instead of the members joined with
Or: the new wrapper override axissealedNames(group key of comma-separated member paths → snake_case concept,"filename, image_uri, s3_bucket": code) names a group, elsederiveSealedConceptderives one (the members' shared prefix or suffix — plural-insensitive, never one generic word likeenableorarn), else the slot falls back to theOrname. A name whose slot or classes clash with the resource's falls back too.wrap --sealed-name-debt <file>(every lane,tool/sealed_name_debt.yaml) records each fallback asawaiting-name:and drops stale entries;--checkfails on either instead.wrapfails with E406 on asealedNamesentry that clashes, repeats the derived name, or matches no sealed group. There is no member cap any more: a group of any size seals. - Breaking — no sealed type or variant name says a block segment twice:
joinTypeNamedrops the words the halves share (RdsCluster+cluster_identifier→RdsClusterIdentifier), a derived concept whose type would still repeat a segment falls through to the next rule, and a variant whose name repeats a segment or takes a declared class (usually the member block's own helper) ends inChoice/Option/Variant. A non-keyed block whose inputs are exactly one exactly-one group — or one at-most-one group, when the block is optional — gets no sealed field: the block's helper class becomes the sealed type (amount: .lastPeriodAmount(...)), and the migration manifest records the block's slot as a non-mergedsealedslot at every depth. A wrapper importspackage:metaonly when it emits@immutable. wrapemits optionalargMapand helperencode()entries as Dart 3.8 null-aware map elements ('k': ?x,'k': ?x?.toTfJson()) instead ofif (x != null) 'k': x/if (x != null) 'k': x!.toTfJson(). Entries whose value wraps the input (TfArg.literal(...), a collectionforover a repeated or keyed value) keep the guard. No API change; synth output is unchanged.
0.30.0 - 2026-09-28 #
- Fix: a nested block with
nesting_mode: "map"(a plugin-framework map of objects) derived one helper object instead ofMap<String, Helper>, and its encode wrote one object where Terraform expects a map.NestedBlockSpec.keyedmarks it; the slot, helper field and encode are keyed by the map key, and the migration manifest records the slot askeyed: true. A hand-writtenMap<String, Helper>slot whose encode is not a keyed map comprehension staysmanual. Passthrough slots (TfArg<Map>vsTfArg<List<Map>>) treatmapandgroupblocks as objects (nestedBlockIsObject). - Sensitive-field sets write a
*segment for each map-of-blocks level (deployment_configs.preview.env_vars.*.value). terradart wrap --provider-enums(a lane'sproviderEnums: trueintool/providers.yaml) types enum-valued string attributes, top-level and nested (a list of strings becomesList<TfArg<Enum>>), from<schemaDir>/hints/*.yaml(Magic Modules YAML subset, extracted from the provider's Go validators bytool/extract_provider_hints.dart) and fromAvailable values:descriptions (not when the description names the attribute an expression, whose list names fields). Hints extracted at another provider version than the fixture fail the wrap with E405. Off by default; no lane's output changes until one opts in.- New wrapper override axis
deriveExactlyOne: true: under--provider-enums, eachexactly_one_of_groupsentry in the type's hints becomes one required sealed-type argument (a resource-level group, as a custom slot with...slot.argMap) or helper field (a nested-block group), with one<Prefix><Member>Optionvariant per member.wrapprints each group it cannot seal (a required member, one a custom slot owns, one an earlier group took, a nested block with no typed helper). Off by default;AwsProviderRulesscaffolds it on. - A full
terradart wrapdeletes every generated wrapper or barrel no override emits any more, andwrap --checkfails on one. wrapemitslib/src/_provider_version.g.dartfrom the fixture'sprovider_version.txt; the exact aws / cloudflare pins read it.- The migration manifest derives a custom slot whose argMap entry is
...<slot>.argMapas a merged sealed slot, so the migrator translates sealed write-only secret choices. - Enum member names cover any value: operators (
<→lt), leading digits (1.2→v1p2), names an enum cannot declare (values→valuesCase,override→overrideCase), and repeats get a numeric suffix. Emitted literals escape\,',$and newlines.
0.29.0 - 2026-09-27 #
terradart lint-overridereads the shared lint ledgers (tool/exactly_one_lint_debt.yaml,tool/migrate_manifest_debt.yaml) for every override lane and validates only the entries naming its own overrides.- New wrapper override axis
dedupeNestedTypes: true(requiresderiveNestedTypes: true): nested blocks with an identical shape inside one resource share one helper class, named after the shallowest occurrence (ties broken by path segments). Opt-in and off by default, because it renames the deeper occurrences' helpers.
0.28.1 - 2026-09-13 #
Lockstep release with terradart_migrate 0.28.1 (passthrough emission fix — a bare Map / List parameter no longer comes out as TfArg.literal). No terradart_codegen API changes.
0.28.0 - 2026-09-13 #
terradart wrapemits Terraform'sprovidermeta-argument on every generated constructor:super.provideron resource factories and data sources, and on a--resource-providerlane aString? providerparameter that defaults to the lane's provider (provider: provider ?? 'google-beta'), so a beta wrapper can still select an alias of it (#666).
0.27.0 - 2026-08-30 #
Lockstep release with terradart_core 0.27.0 (TfVariable / Stack.addVariable and S3Backend). No terradart_codegen API changes.
0.26.0 - 2026-08-24 #
- Plugin-framework
nested_typeattributes emit typed nested helper classes (notTfArg<Map<String, dynamic>>). Computed-only objects stay skipped. Data-source nested helpers use aDataprefix to avoid resource name clashes. Reserved Dart identifiers (e.g.default) are escaped. skipAttribute/skipDataSourceAttributekeep a requiredid(create-time / lookup key). Synthetic optional/computedidis still dropped.- Wrap fixtures:
hashicorp/googleandhashicorp/google-beta7.45.0. Cloudflarewrap --checkremains intool/agent_verify.sh.
0.25.3 - 2026-08-23 #
extract_schema_subset accepts --data-sources= (and --resources-from unions fixture data sources). Catalog constructorParams for data sources now includes a required lookup id, matching the emitted constructor. No user-facing CLI flag changes.
0.25.2 - 2026-08-22 #
Plugin-framework schema support: SchemaJsonParser normalizes nested_type object attributes into the nested-block IR (first consumer: the cloudflare 5.23.0 fixture); computed-only object attributes are excluded from constructors. No user-facing CLI flag changes.
0.25.1 - 2026-08-19 #
Lockstep release with terradart_google_beta 0.25.1 (beta-only catalog filled). No user-facing CLI flag changes.
0.25.0 - 2026-08-15 #
Lockstep release with terradart_google 0.25.0 (GA hashicorp/google catalog filled). Wrap emits GA data-source factories (data_<type>.yaml twins, Data class prefix). No user-facing CLI flag changes.
0.24.0 - 2026-07-03 #
New maintainer derivation gate deriveNestedTypes: true (+ nestedTypeExcludes): generates typed helper classes for nested blocks from the provider schema — fields typed per schema, enums parsed from attribute descriptions (single-sourced with check_override_enum_gaps, which is now excludes-aware and strict on nested sites in CI). Non-breaking for the wrap CLI; overrides that do not set the gate are unaffected.
0.23.0 - 2026-07-02 #
Lockstep release for terradart_core / terradart_google 0.23.0. No CLI or codegen API changes.
0.22.0 - 2026-06-30 #
Lockstep release for Waves 76–77. Agent guide: co-authorship commit policy removed from AGENTS.md.
0.21.0 - 2026-06-28 #
Lockstep release for Wave 74. Apply-smoke test 13 (cost-comment gate) and tool/apply_cost_comment_debt.yaml.
0.20.0 - 2026-06-21 #
Lockstep release for Wave 73. No CLI or codegen API changes.
0.19.0 - 2026-06-21 #
Lockstep release. No API changes vs 0.18.0.
0.18.0 - 2026-06-21 #
Lockstep release. No API changes vs 0.17.1.
0.17.1 - 2026-06-21 #
Lockstep release. No user-facing CLI changes.
0.17.0 - 2026-06-21 #
Lockstep release. No user-facing CLI changes.
0.16.0 - 2026-06-21 #
Lockstep release. No user-facing CLI changes.
Added #
- Wrapper overrides / manifest entries for Waves 42–70 (66 new curated factories through
google_vertex_ai_cache_config).
0.15.0 - 2026-06-20 #
Lockstep release. No user-facing CLI changes.
Added #
- Wrapper overrides / manifest entries for the post-
0.14.0curated expansion through Wave 41, covering Apigee, Dataplex, License Manager, Discovery Engine, Config Deployment, Contact Center Insights, Dialogflow, Network Connectivity, Chronicle, Migration Center, Network Security ULL, Oracle Database@Google Cloud, and IAM binding/policy adjuncts.
Fixed #
- Aligned the Contact Center Insights output directory with the wrap-init anchor.
- Added Config Deployment Gate 6 thunks for blueprint source variants.
0.14.0 - 2026-06-16 #
- Refresh the provider schema fixture to
hashicorp/google7.36.0. - Type the
google_compute_region_backend_service.connection_tracking_policynested block in the wrapper override (2 enums + block class), closing the lastcheck_override_enum_gaps --strict-nestedgap.
0.13.0 - 2026-06-14 #
BREAKING — removes the terradart codegen CLI subcommand, runCodegen, CodegenResult, and FileEmitter. Maintainer generation is terradart wrap only. See MIGRATING.md.
Maintainer:
-
Added —
lint-overridephase-2 ruleexactly-one-paramorder-fanoutwhen MM YAML declares anexactly_one_ofsibling group but the override lists two or more schema-default members inparamOrderwithout a sealed virtualcustomSlot(closes thecustomSlots-less escape hatch). -
Changed —
exactly-one-optional-fanoutnow uses canonical MM sibling groups; pre-existing violations are listed intool/exactly_one_lint_debt.yaml(#107). -
Added —
tool/example_synth_gates.dart(synth-based example coverage + API-enablement dependency checker, #108). -
Added — label-gated
apply-smokeGitHub workflow +tool/apply_smoke.sh(#109). -
Added —
lint-overridedead-customSlots rulescustom-slot-missing-param-order,custom-slot-not-in-param-order,custom-slot-not-in-arg-map-order: a customSlot the emitter would silently skip now fails the gate (caught the Wave 32google_redis_instanceregression and two latenturl_mapslots thatwrap --checkcould not see). -
Added —
tool/append_curation_backlog.dartfor idempotent schema-bump backlog updates (#35). -
Fixed — schema-bump workflow no longer appends invalid YAML outside
entries:; excludes.schema-bump/from commits. -
Changed — the example synth gate's API-enablement check now MANDATES that an example enabling any API enables every API its resources require (
tool/example_api_debt.yamlis the audited escape hatch; the Wave 32 secretmanager gap becomes a hard failure). The gate already ran viacheck_docs_consistency.dart(CI + agent gate) but only validated already-enabled APIs, so an enablement omission passed silently. Atool/example_synth_gates_test.dartunit test now guards the ratchet logic itself. -
Added —
dart analyze tool/joins CI and the agent gate (the gate scripts themselves were unanalyzed; two latent errors fixed;pathadded as a direct dev dependency). -
Added — universal invariant
deletion_protectionparity: a curated resource whose schema exposesdeletion_protectionmust list it in an explicitparamOrder(immediately caughtgoogle_alloydb_clusterandgoogle_memcache_instancefrom Waves 33/35). -
Added —
tool/check_mm_upstream_fingerprint.dartgate (CI + agent gate): flagsupstream: nullmanifest entries that carry an MM fingerprint (effective_labels/Possible values:docs) and therefore almost certainly have an mmv1 upstream. Stops the Wave 26-32 copy-paste-nullclass. -
Changed — synced 73 MM YAML fixtures (the manifest corrections above), activating the enum-drift checks that were vacuous without them (zero drift across the frozen prelude enums).
google_dns_record_setcorrected toupstream: null(nommv1ResourceRecordSet exists; the stale path 404'd on first sync). -
Fixed —
canonicalExactlyOneOfGroupsskips groups containing a list-indexed nested-block member (e.g.[network, subnet.0.name]ongoogle_vpc_access_connector), which previously collapsed to a bogus[name, network]sibling group and would have demanded an impossible sealing. -
Changed —
google_certificate_manager_certificate_map_entrysealedmatchslot andgoogle_logging_saved_queryderivedvisibilityenum (the hand-written duplicate, shadowed byderiveEnums, is removed) — both surfaced by the fixture sync and the now-non-vacuous lint/invariants. -
Fixed —
tool/mm_yaml_sources.yaml: corrected 29 mislabeledupstream: nullentries (certificatemanager, privateca, alloydb, memcache, spanner, filestore, vpc-access, gke_hub_fleet, several logging, storage_hmac_key, eventarc, analytics-hub subscription, redis) to their realmmv1/products/...paths, plus 6 broken non-null paths (analyticshub→bigqueryanalyticshub rename, cloudrun→cloudrunv2 worker pool, sql_ssl_cert→null, the crossed monitoring service/custom_service pair). Re-activates MM enum-drift checks across those resources. -
Changed — catalog counts in
tool/doc_expectations.dartare now DERIVED from_catalog.g.dartinstead of hand-bumped constants, removing the parallel-wave count race that forced reconcile cycles in #136/#137/#138.catalog_count_testno longer pins a literal total; only human-readable prose still needs syncing (andcheck_docs_consistencyenforces it). -
Added — pre-merge
pub publish --dry-runCI job forterradart_core/terradart_codegen/terradart_google, catching fixture secret-scanner trips before they break publish (the reactive 0.12.5 and 0.12.11 false-secret fixes). -
Added — Wave 33–35 wrapper overrides: AlloyDB (
google_alloydb_cluster/_instance/_user/_backup), Cloud Filestore (google_filestore_instance/_backup/_snapshot),google_memcache_instance, Spanner (google_spanner_instance/_database); newalloydb/filestore/memcache/spannerMM manifest entries.
0.12.19 #
Wave 32 override: google_redis_instance (RedisInstanceTier, RedisInstanceConnectMode enums).
0.12.18 #
Wave 31 overrides: google_privateca_certificate_template (identity constraints slot), google_privateca_ca_pool_iam_member.
0.12.17 #
No codegen changes. Lockstep version bump for terradart_google v0.12.17 (Apis.required helper).
0.12.16 #
Wave 30 override: google_privateca_certificate (typed config custom slot + PrivatecaCertificateX509Config.serverTls()).
0.12.15 #
Wave 29 override: google_privateca_certificate_authority (typed config + key_spec custom slots).
0.12.14 #
Wave 28 override: google_privateca_ca_pool (google_privateca_ → privateca.googleapis.com in tool/terraform_api_requirements.dart).
0.12.13 #
Wave 27 overrides: google_certificate_manager_trust_config, google_certificate_manager_certificate_issuance_config (certificatemanager.googleapis.com prefix).
0.12.12 #
Maintainer: sealed virtual slots for seven exactly_one_of overrides (firewall,
health check ×2, uptime check, BigQuery job/connection, Cloud Build trigger).
tool/exactly_one_lint_debt.yaml is now empty (#107).
0.12.11 #
Wave 25 google_vpc_access_connector override (google_vpc_access_ → vpcaccess.googleapis.com). Four Wave 26 Certificate Manager overrides (google_certificate_manager_ → certificatemanager.googleapis.com). google_artifact_registry_repository override: typed remote docker_repository / maven_repository / npm_repository helpers and public-registry enums.
0.12.10 #
Ten new wrapper overrides (Waves 23–24). Maintainer enum-gap gate extended:
- Added —
check_override_enum_gaps.dartnested scan (NESTED_PARTIALfails CI;NESTED_THINfails when--strict-nestedis passed). - Changed —
tool/agent_verify.shruns the enum gate with--strict-nested.
0.12.9 #
Five new wrapper overrides (Wave 22). No CLI changes.
0.12.8 #
Twenty-four new wrapper overrides (Waves 17–21). No CLI changes.
0.12.7 #
Maintainer:
- Added — Wave 12 Monitoring overrides (four types; SLO uses sealed
MonitoringSloSli). - Added — Waves 13–16 overrides (Compute region SSL + NEG endpoint, KMS key version, Pub/Sub schema IAM member, Storage HMAC key, Logging log scope + linked dataset).
0.12.6 #
Maintainer:
- Added — Wave 10 GKE Backup overrides (six
google_gke_backup_*types; plan IAM isiam_member-only). - Added — Wave 11 Logging project ops overrides (five
google_logging_*types; log view IAM isiam_member-only).
0.12.5 #
Maintainer:
- Added — Wave 9 GKE Hub overrides (
google_gke_hub_fleet,google_gke_hub_membership).
0.12.4 #
Maintainer:
- Added — Wave 8 GKE overrides (
google_container_cluster,google_container_node_pool) andtool/batch_wrap_init.dart.
0.12.3 #
Maintainer:
- Changed —
google_iam_workload_identity_pool_provideroverride uses sealedtrust_sourcevirtual slot (matches scheduler / firestore convention). - Added —
lint-overridephase-2 ruleexactly-one-optional-fanoutwhen MM YAML declares top-levelexactly_one_ofbut the override fans out optional membercustomSlots.
0.12.2 #
Maintainer-only: wrapper overrides for google_iam_workload_identity_pool_provider and google_iap_web_backend_service_iam_binding, plus synced MM YAML fixture for the WIF provider. No CLI changes. Lockstep bump; terradart_core constraint ^0.12.2.
0.12.1 #
No user-facing changes. Lockstep version bump alongside the terradart_agent v0.12.1 fix. terradart_core constraint bumped to ^0.12.1.
0.12.0 #
Adds static-catalog emission so the curated terradart_google surface can be introspected without loading or analyzing the wrapper source. Powers the new terradart-mcp server (terradart_agent).
- Bumped
terradart_coreconstraint to^0.12.0. - New
CatalogMetadataEmitter— emitsterradart_google/lib/src/_catalog.g.dart, a generatedconst List<CatalogEntry> terradartCatalogwith one entry per curated resource and data source (tfType, Dart class name, per-service barrel, kind, summary, constructor params, nested types, sensitive fields, doc comment). - New
catalog_entry_builder.dart— builds the per-resourceCatalogEntrymetadata from the same parsed IR + YAML overrides the wrapper emitters consume, so the catalog never drifts from the emitted wrappers. terradart wrapnow emits the catalog. The catalog file is regenerated as part of the normal wrap cycle (and verified underwrap --check) alongside the wrapper files — no separate command, and zero drift against the emitted source.- No new CLI surface in this release.
0.11.0 2026-MM-DD #
BREAKING — template-side rename pass that pairs with the terradart_core 0.11.0 public-surface change (ADR-0016). v0.x permits breaking changes; emitted wrappers in terradart_google 0.11.0 follow the new shape. See MIGRATING.md for before / after snippets.
- Bumped
terradart_coreconstraint to^0.11.0. wrapper_emitter.dart/data_source_wrapper_emitter.dartemitstatic const String tfTypeandSet<String> get sensitiveFields(andbool get supportsDeletionProtectionwhen the schema opts in) without the dollar prefix. The accompanying// ignore: constant_identifier_namesand// ignore: non_constant_identifier_namesdirectives are dropped.enum_emitter.dartappendsimplements TerraformEnumon every emitted enum declaration. The wrapper file already importspackage:terradart_core/terradart_core.dart, which re-exports the interface — no additional import at the enum-emit site.valid_values_emitter.dart(wrap-promote scaffold) emits the sameimplements TerraformEnumclause plus@overrideon the generatedString get terraformValuebody.universal_invariants/enum_extractor.dartregex now tolerates the optionalimplements TerraformEnumclause so the extractor stays backwards-compatible with wrap-promote scaffolds that haven't been fleshed out yet.- YAML prelude bodies (62 files, 233 enums) updated:
implements TerraformEnumadded to everyenum X {declaration plus@overrideon the matchingfinal String terraformValue;field. Doc-comment / inline-comment references to the dollar-prefixed identifiers are renamed in sync so the regen output and the override YAML stay aligned. wrapper_override.dart/sensitive_set_emitter.dartdartdoc strings referencesensitiveFields/tfTypewithout the dollar prefix.- No new CLI surface in this release.
0.10.0 2026-MM-DD #
- Bumped
terradart_coreconstraint to^0.10.0. - New YAML override
wrapper_overrides/yaml/google_firestore_document.yamlenabling theterradart_googlev0.10.0 Firestore document curation.
0.9.0 - 2026-05-21 #
BREAKING — pre-1.0 polish wave. Codegen template changes that propagate to terradart_google's emitted wrappers (0.9.x staging for the 1.0 surface; breaking changes still permitted within 0.9.x → 1.0):
- Bumped
terradart_coreconstraint to^0.9.0. - Wrapper emitter emits
@override bool get $supportsDeletionProtection => true;on wrappers whose schema includes adeletion_protectionattribute. - Abstract-class emitter emits service-prefixed nested helper class names (
SqlDatabaseInstanceSettings,BigqueryDatasetAccess,SecretManagerSecretReplication,LoggingProjectSinkBigqueryOptions, etc.) — no more bareSettings/Access/Replication/BigqueryOptionsWave 4-era shapes. - Abstract-class emitter emits
TfArg<T>-wrapped nested-helper fields uniformly. Plain Dart-type fields on helpers (Wave 7-era Monitoring uptime check shapes) are eliminated. - Wrapper emitter emits
.iamMembergetter (was.member) for IAM-binding refs. - Wrapper emitter emits
.locationRefmirror getter ongoogle_cloud_run_v2_service+google_cloud_run_v2_job(cookbook-evidence allow list; v1.x may extend). - Added Gates 6 (nested-helper prefix), 7 (TfArg-wrap uniformity), 8 (enum value identifier length ≥ 4 with industry-acronym allow-list) to
universal_invariants_test. - YAML override format extended for per-resource class renames.
See MIGRATING.md for the full migration guide.
0.8.0-dev - 2026-05-19 #
- Plan 5.H Wave 7: 23 new curated GA resources added to the registry (Data ops + observability + CI/CD).
- Constraint bump:
terradart_core: ^0.8.0-dev(lockstep withterradart_coreandterradart_google). - Discovered + corrected a manifest naming bug in
tool/mm_yaml_sources.yaml: the Wave 7 Batch 0 seed usedgoogle_logging_log_metric(a non-existent Terraform resource); the actual provider resource isgoogle_logging_metric(renamed in Batch 2, see pitfall #12 in wave-commit-pitfalls memory). - No CLI / codegen / wrap-promote changes.
0.7.0-dev - 2026-05-19 #
- Plan 5.G Wave 6: 25 new curated GA resources added to the registry (Compute LB stack — L7 Application LB Global + Regional/Internal cores + Health checks + MIG/Autoscaler + NEG + Cloud Armor + SSL Policy).
- Constraint bump:
terradart_core: ^0.7.0-dev(lockstep withterradart_coreandterradart_google). - No CLI / codegen / wrap-promote changes.
0.6.0-dev - 2026-05-18 #
Plan 5.E: Schema-bump automation. Adds a weekly GitHub Actions workflow
(.github/workflows/schema-bump.yml) that detects terraform-provider-google
v7 bumps + magic-modules MM YAML overlay updates, runs drift detection
(terradart wrap --check + 6 universal QA gates), and opens a PR with a
structured drift report. v8+ majors are surfaced as a banner but never
auto-bumped. New google_* resources are appended to
tool/curation_backlog.yaml.
- New:
tool/fetch_schema.dart,tool/sync_mm_yaml.dart,tool/generate_drift_report.dart,tool/mm_yaml_sources.yaml,tool/curation_backlog.yaml. - New:
dev_dependenciesaddhttp: ^1.0.0andpub_semver: ^2.1.0. - See ADR-aligned spec at
docs/superpowers/specs/2026-05-17-plan5e-schema-bump-automation-design.md.
WrapperOverride YAML registry expands from 49 to 71 resources (Wave 5 additions; see terradart_google 0.6.0-dev for the resource list). All 6 universal QA gates continue to hold over the expanded registry. Workspace consistency bump alongside terradart_google 0.6.0-dev.
0.5.0-dev #
Plan 5.X: schemantic codegen path removed.
file_emitterno longer emitspart 'X.schema.g.dart';.abstract_class_emitter+data_source_class_emitterdeactivated (Layer 1 schema-carrier classes no longer emitted).wrapper_emitter+data_source_wrapper_emitter: stop emitting_<R>SchemaInstancestub block, stop emittingschema:arg, drop generic fromextends Resource, emit file-private_<resource>Sensitiveconst at the top of the wrapper file.sensitive_set_emitterretargeted to wrapper-file inline (no longer writes into.schema.dart).wrap_command: Layer 1 emit step + Layer 2 build_runner invocation removed.WrapperOverride.schemaStubCommentaxis dropped fromwrapper_override.dart+yaml_loader.dart+ 14 YAML override files.- Dropped
terradart_annotationsruntime dep. - See ADR-0013 for full rationale.
0.4.0-dev - 2026-05-17 #
Plan 5.D — codegen correctness improvements (4 PRs).
Added #
- Gate 6: sealed-class
encode()round-trip (structural) — new universal QA gate (joining the existing 5 from Plan 5.A) that, for every shipped sealed-class member, constructs a synthetic instance, callsencode()(ortoArgMap()fallback), and asserts the result is a non-emptyMap<String, Object?>(or single-elementList<Map<...>>fornesting_mode: list, max_items: 1), every required ctor param's snake_case schema key is present (recursively — discriminator-block wire formats nest required keys inside), no rawTfArg<T>values leak, and noUnimplementedErroris thrown. Currently covers 34 sealed-class members across 11 sealed classes. SealedClassExtractor+SyntheticInstanceBuildermodules underlib/src/codegen/universal_invariants/— building blocks for Gate 6 (regex-based prelude parsing).MinItemsAssertEmitter— wrap-promote now emits curator-facing commentedassert(list.length >= N)hint snippets for top-level list-shape nested blocks withmin_items >= 1 && max_items != 1. Curator copies the snippet into their helper-class constructor on next regen. Scalar attribute constraints (min_length/max_length/min/max/regex) stay at the schemantic layer.tool/measure_param_order.dart— standalone measurement script that quantifies how well a candidate paramOrder heuristic predicts the curator-curated orders across the 49-yaml corpus. Output (gitignored, regenerable) drives a Wave 5-close decision matrix on whether to ship the heuristic.
Fixed #
MmYamlParsernow readsdeprecation_message:from MM YAML field overrides intoConstraints.deprecationMessage.IrMerger._mergeAttrpropagates the field with the MM-wins precedence used forregex/minLength/ etc. Closes a Plan 4.2-era dead-code path inwrap_init_generator._buildDeprecatedParamsAxisthat read a perpetually-null field. Skeleton emission ofdeprecatedParams:(the now-populated downstream consumer) stays deferred to Plan 5.E (Renovate-driven schema-bump automation).exactly_one_of_emitter.dartskeleton: replaced misleadingString encode()signature withMap<String, Object?> encode(). The previous shape mismatched all 12 production sealed-class instances and pointed curators at the wrong wire format.
0.3.0-dev - 2026-05-16 #
No user-facing CLI changes. WrapperOverride YAML registry expands from 30 to 49 resources (Wave 4 additions: see terradart_google 0.3.0-dev for the resource list). Plan 5.A's 5 universal QA gates continue to hold over the expanded registry. Workspace consistency bump alongside terradart_google 0.3.0-dev.
0.2.1-dev - 2026-05-16 #
No API change since 0.2.0-dev. Re-published after the 0.2.0-dev tag's publish run failed at the parallel matrix validation step — terradart_codegen was uploaded before pub.dev's index had terradart_core 0.2.0-dev, causing the ^0.2.0-dev constraint to fail version solving. 0.2.1-dev ships through a re-ordered publish pipeline (publish-codegen now waits for publish-no-deps to complete + pub.dev index propagation before uploading).
0.2.0-dev - 2026-05-16 #
Added #
extraSensitiveFields:yaml override axis — curators can declare per-resource sensitive paths beyond what the Terraform schema flags. Each entry is a dotted path (e.g.metadata_startup_script); the resulting<Resource>Sensitiveconst ships the union of schema-declared and curator-declared paths.terradart wrap --only=<resource>— regenerates a single wrapper file even when sibling yaml overrides have validation errors. Designed for the case where unrelated breakage in another resource blocks the whole-packagewrapcycle.wrap-promotenow extracts enum candidates from prose descriptions matchingPossible values: A, B, Cin addition to schemaenum_valuesblocks. Falls back to the prose set when the schema declares no enum, with MM yaml taking priority when both are present.- 5 universal QA gates (CI-only invariants over
terradart_google/lib/src/**):paramOrdercovers every required schema attribute, emitted enumterraformValuematches schemaenum_values, noUnimplementedError('TODO(wrap-promote)')ships in the curated source, every emitted enum member is lowerCamelCase, and sensitive path masking round-trips to"".
0.1.0-dev - 2026-05-14 #
Added #
- New
terradart wrap-promotesubcommand. Scans a curated override yaml against the parsed provider schema and appends a# === wrap-promote additions ===marker block proposingenum_valuesblocks anddartTypeOverridesentries for fields whose schema declares a fixed value set. Authors review, integrate into the mainprelude:/dartTypeOverrides:blocks, then strip the marker. Naming choices stay with the human. dartTypeOverridesnow correctly handles ALL_CAPS leaf field names (ADD_COST_TO_MED→addCostToMed), Dart reserved words via aCasesuffix (default→defaultCase), and aggregates all generated enums into a singleprelude: |block per resource.- Schema descriptions containing literal
$(e.g. BigQuery'ssample_table$20190123partition-decorator example) and over-escaped apostrophes (e.g.compute_instance.advanced_machine_features.visible_core_count'sinstance\'s nominal CPU) are now sanitized at the parser layer ($→$,\'→') so the generated.schema.g.dartremains parseable Dart. ProviderRulesabstraction lets non-hashicorp/googleproviders ship their own resource allow/deny lists, output-dir aliases, and slot-resolution rules.GoogleProviderRulesis the built-in implementation for the google provider; existing behaviour is unchanged.- WrapperOverride YAML registry expanded from 13 to 27 resources + 1 data source.
0.0.4-dev - 2026-05-11 #
- feat: new
terradart wrapsubcommand regenerates the curated factory wrapper files from the package's production YAML overrides. Flags:--provider,--source,--output,--check(CI-gate mode, exit 65 on divergence),--force(overwrite non-generated files). - feat:
DataSourceWrapperEmitterproduces data source Layer 2 factories (final class X extends Data<$X>).DataSourceClassEmitterproduces Layer 1 schema carriers (data_<resource>.schema.dart). - feat: WrapperOverride YAML schema extended from 11 to 15 axes (
kind,outputDir,schemaStubBodyMode,fileLeadingComment); kind dispatches resource vs data source overrides. - feat:
LoaderErrorReportaggregates YAML override validation failures into a single report with stable error codes (E101unknownKind, E102outputDirRequired, E103outputDirInvalid, E104outputDirMismatchForDataSource, E201axisNotAllowedForDataSource, E301checkMismatch, E401refuseOverwriteNonGenerated). - feat:
generatedFileHeaderconstant prepended to all wrap-emitted files (3 lines: GENERATED FILE marker + regen hint +ignore_for_file: prefer_relative_imports). - chore: production YAML registry covers 12 resources + 1 data source (google_project).
0.0.3-dev - 2026-05-09 #
- Fix: rename terradart_core main library file to match package name.
0.0.2-dev - 2026-05-09 #
- CI automated publishing via OIDC trusted publisher.
- Fix: prepare_publish.sh now syncs version from tag name.
0.0.1-dev - 2026-05-09 #
Added #
- Initial pre-alpha release of
terradart_codegen. terradart codegenCLI — consumesterraform providers schema -jsonoutput (+ optional Magic Modules YAML overlay) and emits annotated abstract Dart classes forschemantic.- Pipelines together with
terradart_annotationsto feedpackage:schemantic/build_runnercodegen.
Notes #
- Pre-alpha — emitted symbol names and CLI flags may change between 0.0.x releases.