hecks 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/hecks +4 -6
- data/lib/hecks/adapters/driven/claude_code.rb +4 -104
- data/lib/hecks/adapters/driven/d1.rb +44 -237
- data/lib/hecks/adapters/driven/folder.rb +17 -76
- data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
- data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
- data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
- data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
- data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
- data/lib/hecks/adapters/driven/heki.rb +13 -42
- data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
- data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
- data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
- data/lib/hecks/adapters/driven/lambda.rb +10 -84
- data/lib/hecks/adapters/driven/local_storage.rb +5 -40
- data/lib/hecks/adapters/driven/memory.rb +17 -98
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
- data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
- data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +4 -30
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
- data/lib/hecks/adapters/driven/postgres.rb +145 -134
- data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
- data/lib/hecks/adapters/driven/prism.rb +7 -30
- data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
- data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
- data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
- data/lib/hecks/adapters/driven/sqlite.rb +128 -65
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +5 -48
- data/lib/hecks/adapters/driven.rb +5 -36
- data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
- data/lib/hecks/behaviors/dsl.rb +7 -25
- data/lib/hecks/behaviors/expectations.rb +31 -141
- data/lib/hecks/behaviors/ir.rb +7 -20
- data/lib/hecks/behaviors/rspec.rb +6 -17
- data/lib/hecks/behaviors/runner.rb +10 -34
- data/lib/hecks/behaviors.rb +4 -8
- data/lib/hecks/bluebook/aggregate.rb +9 -75
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
- data/lib/hecks/bluebook/assembly/build.rb +4 -15
- data/lib/hecks/bluebook/assembly/contract.rb +15 -136
- data/lib/hecks/bluebook/assembly/contracts.rb +54 -174
- data/lib/hecks/bluebook/assembly/marks.rb +31 -223
- data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
- data/lib/hecks/bluebook/assembly.rb +6 -45
- data/lib/hecks/bluebook/attribute.rb +12 -61
- data/lib/hecks/bluebook/behaviour/aggregate.rb +10 -39
- data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
- data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
- data/lib/hecks/bluebook/behaviour/command.rb +14 -66
- data/lib/hecks/bluebook/behaviour/domain_port.rb +4 -20
- data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
- data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
- data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
- data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
- data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
- data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
- data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
- data/lib/hecks/bluebook/capabilities.rb +17 -49
- data/lib/hecks/bluebook/chapter.rb +10 -48
- data/lib/hecks/bluebook/command.rb +23 -81
- data/lib/hecks/bluebook/domain_port.rb +14 -63
- data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +86 -708
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +56 -170
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +1 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
- data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +12 -87
- data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +26 -194
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
- data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
- data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
- data/lib/hecks/bluebook/dsl/query_builder.rb +11 -42
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
- data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
- data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
- data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
- data/lib/hecks/bluebook/dsl/world_builder.rb +19 -111
- data/lib/hecks/bluebook/entity.rb +13 -71
- data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
- data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
- data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
- data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
- data/lib/hecks/bluebook/expression/resolver.rb +37 -660
- data/lib/hecks/bluebook/hexagon.rb +5 -28
- data/lib/hecks/bluebook/lifecycle.rb +5 -16
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
- data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
- data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
- data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +24 -176
- data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +43 -305
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
- data/lib/hecks/bluebook/meta_validator.rb +79 -349
- data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
- data/lib/hecks/bluebook/model_check.rb +100 -597
- data/lib/hecks/bluebook/pattern_subset.rb +11 -69
- data/lib/hecks/bluebook/process_manager.rb +13 -83
- data/lib/hecks/bluebook/project_loader.rb +3 -39
- data/lib/hecks/bluebook/project_register.rb +12 -60
- data/lib/hecks/bluebook/query.rb +9 -48
- data/lib/hecks/bluebook/read_model.rb +57 -81
- data/lib/hecks/bluebook/reference.rb +7 -41
- data/lib/hecks/bluebook/smoke_test.rb +8 -98
- data/lib/hecks/bluebook/synthesizer.rb +13 -62
- data/lib/hecks/bluebook/translation.rb +26 -62
- data/lib/hecks/bluebook/value_object.rb +11 -36
- data/lib/hecks/bluebook.rb +5 -22
- data/lib/hecks/cache_dir.rb +4 -23
- data/lib/hecks/cli/document.rb +3 -21
- data/lib/hecks/cli/ir.rb +3 -5
- data/lib/hecks/cli/mcp.rb +2 -3
- data/lib/hecks/cli/mcp_door.rb +19 -114
- data/lib/hecks/cli/model_check.rb +18 -85
- data/lib/hecks/cli/project_cli.rb +7 -40
- data/lib/hecks/cli/project_diagrams.rb +0 -7
- data/lib/hecks/cli/run.rb +12 -58
- data/lib/hecks/cli/smoke_test.rb +2 -16
- data/lib/hecks/cli/stores.rb +1 -2
- data/lib/hecks/cli.rb +18 -24
- data/lib/hecks/construct.rb +8 -34
- data/lib/hecks/deploy/bluebook/deploy.bluebook +33 -142
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +2 -9
- data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
- data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
- data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
- data/lib/hecks/embryonaut_bluebook.rb +4 -71
- data/lib/hecks/facade/cli_door.rb +24 -106
- data/lib/hecks/facade/cli_runner.rb +28 -172
- data/lib/hecks/facade/command_request.rb +13 -33
- data/lib/hecks/facade/handle.rb +34 -121
- data/lib/hecks/facade/json_door.rb +31 -146
- data/lib/hecks/facade/surface/aggregate_door.rb +39 -104
- data/lib/hecks/facade/surface/chapter.rb +10 -54
- data/lib/hecks/facade/surface.rb +8 -23
- data/lib/hecks/facade.rb +10 -25
- data/lib/hecks/forms/app.rb +15 -70
- data/lib/hecks/forms/command_form_renderer.rb +10 -29
- data/lib/hecks/forms/field_renderer.rb +17 -156
- data/lib/hecks/forms/field_shape.rb +30 -222
- data/lib/hecks/forms/html.rb +12 -47
- data/lib/hecks/forms/index_renderer.rb +1 -4
- data/lib/hecks/forms/page.rb +3 -9
- data/lib/hecks/forms/params.rb +14 -60
- data/lib/hecks/forms/port_argument.rb +2 -19
- data/lib/hecks/forms/query_form_renderer.rb +4 -79
- data/lib/hecks/forms/record_renderer.rb +8 -75
- data/lib/hecks/forms/record_table.rb +7 -50
- data/lib/hecks/forms/reference_options.rb +3 -30
- data/lib/hecks/forms/value_object_shape.rb +8 -35
- data/lib/hecks/forms.rb +5 -33
- data/lib/hecks/fqn.rb +5 -12
- data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
- data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
- data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
- data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
- data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
- data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
- data/lib/hecks/framework.rb +11 -80
- data/lib/hecks/freezer.rb +5 -39
- data/lib/hecks/grammar/expression.bluebook +15 -40
- data/lib/hecks/grammar/translation.bluebook +3 -6
- data/lib/hecks/grammar.rb +16 -41
- data/lib/hecks/ir.rb +14 -83
- data/lib/hecks/language/adapter.bluebook +2 -7
- data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -83
- data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
- data/lib/hecks/language/bluebook/command.bluebook +27 -144
- data/lib/hecks/language/bluebook/entity.bluebook +24 -97
- data/lib/hecks/language/bluebook/policy.bluebook +16 -67
- data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
- data/lib/hecks/language/bluebook/projection.bluebook +126 -60
- data/lib/hecks/language/bluebook/query.bluebook +12 -43
- data/lib/hecks/language/bluebook/shape.bluebook +23 -73
- data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
- data/lib/hecks/language/bluebook/vocabulary.bluebook +82 -197
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
- data/lib/hecks/language/hecksagon/domain_port.bluebook +4 -19
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +6 -25
- data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
- data/lib/hecks/language/oidc.json +35 -0
- data/lib/hecks/language/port.bluebook +4 -17
- data/lib/hecks/language/translation/translation.bluebook +3 -9
- data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
- data/lib/hecks/language/world/wiring.bluebook +1 -3
- data/lib/hecks/language/world/world.bluebook +5 -7
- data/lib/hecks/literal.rb +8 -50
- data/lib/hecks/mcp_door_scope.rb +9 -90
- data/lib/hecks/mcp_stdio_guard.rb +4 -41
- data/lib/hecks/naming.rb +29 -137
- data/lib/hecks/ports/access_control.rb +7 -23
- data/lib/hecks/ports/agent/answers.rb +5 -23
- data/lib/hecks/ports/agent.rb +47 -172
- data/lib/hecks/ports/authentication.rb +12 -39
- data/lib/hecks/ports/authorization.rb +16 -43
- data/lib/hecks/ports/clock.rb +5 -45
- data/lib/hecks/ports/extraction.rb +7 -12
- data/lib/hecks/ports/identity_assignment.rb +8 -29
- data/lib/hecks/ports/identity_generation.rb +6 -29
- data/lib/hecks/ports/identity_resolution.rb +2 -10
- data/lib/hecks/ports/key_vault.rb +9 -45
- data/lib/hecks/ports/persistence/append_only.rb +61 -64
- data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
- data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
- data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
- data/lib/hecks/ports/persistence/plugin.rb +13 -42
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +38 -141
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +16 -84
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +3 -22
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +18 -75
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +14 -115
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +127 -554
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +9 -25
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
- data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
- data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
- data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
- data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
- data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
- data/lib/hecks/ports/persistence/state_codec.rb +23 -103
- data/lib/hecks/ports/persistence.rb +7 -14
- data/lib/hecks/ports/projection.rb +42 -84
- data/lib/hecks/ports/query/in_memory.rb +10 -58
- data/lib/hecks/ports/query/ordering.rb +11 -32
- data/lib/hecks/ports/query.rb +14 -37
- data/lib/hecks/ports.rb +2 -8
- data/lib/hecks/projections/bootstrap_table.rb +11 -43
- data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
- data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
- data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
- data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
- data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
- data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
- data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
- data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
- data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
- data/lib/hecks/projections/deploy/fargate.rb +35 -202
- data/lib/hecks/projections/deploy/lambda.rb +150 -678
- data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
- data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
- data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
- data/lib/hecks/projections/deploy/preview/script.rb +2 -14
- data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
- data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
- data/lib/hecks/projections/deploy/preview/template.rb +2 -58
- data/lib/hecks/projections/deploy/preview.rb +2 -67
- data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
- data/lib/hecks/projections/deploy/scripts.rb +4 -57
- data/lib/hecks/projections/deploy/shared.rb +47 -146
- data/lib/hecks/projections/deploy/smoke.rb +4 -61
- data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
- data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
- data/lib/hecks/projections/deploy/template_diff.rb +5 -57
- data/lib/hecks/projections/diagrams.rb +20 -582
- data/lib/hecks/projections/glossary/html.rb +14 -130
- data/lib/hecks/projections/glossary/markdown.rb +8 -69
- data/lib/hecks/projections/glossary/mermaid.rb +9 -66
- data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
- data/lib/hecks/projections/glossary/sentences.rb +14 -159
- data/lib/hecks/projections/glossary.rb +30 -222
- data/lib/hecks/projections/ir.rb +3 -10
- data/lib/hecks/projections/model/deviations.rb +15 -42
- data/lib/hecks/projections/model.rb +12 -51
- data/lib/hecks/projections/oidc.rb +12 -56
- data/lib/hecks/projections/parser_table.rb +9 -28
- data/lib/hecks/projections/reference.rb +2 -15
- data/lib/hecks/projections/rust_vocabulary.rb +12 -250
- data/lib/hecks/projections/shape.rb +3 -29
- data/lib/hecks/projections/statements.rb +7 -86
- data/lib/hecks/projections/vocabulary.rb +6 -22
- data/lib/hecks/projections.rb +2 -16
- data/lib/hecks/projector/cli_projector.rb +60 -375
- data/lib/hecks/projector/docs_projector.rb +10 -201
- data/lib/hecks/projector/exporter.rb +42 -134
- data/lib/hecks/projector/ir_projector.rb +2 -9
- data/lib/hecks/projector/narrate_projector.rb +15 -189
- data/lib/hecks/projector/target.rb +13 -76
- data/lib/hecks/projector.rb +30 -121
- data/lib/hecks/query_specification/common/comparators.rb +5 -26
- data/lib/hecks/query_specification/common/comparison.rb +35 -143
- data/lib/hecks/query_specification/common/dsl.rb +8 -24
- data/lib/hecks/query_specification/common/null_policy.rb +20 -70
- data/lib/hecks/query_specification/common/options.rb +2 -6
- data/lib/hecks/query_specification/common/where_clause.rb +2 -10
- data/lib/hecks/query_specification/field_path.rb +37 -77
- data/lib/hecks/query_specification/hop_path.rb +12 -76
- data/lib/hecks/release/gem_pin.rb +2 -26
- data/lib/hecks/release/runner/ci_publisher.rb +3 -6
- data/lib/hecks/release/runner/commands.rb +2 -4
- data/lib/hecks/release/runner/gem_publisher.rb +2 -3
- data/lib/hecks/release/runner/npm_publisher.rb +6 -20
- data/lib/hecks/release/runner/preflight.rb +4 -19
- data/lib/hecks/release/runner/tagger.rb +2 -9
- data/lib/hecks/release/runner.rb +3 -32
- data/lib/hecks/rendering.rb +4 -26
- data/lib/hecks/router/namespace_installer.rb +12 -36
- data/lib/hecks/router.rb +4 -8
- data/lib/hecks/runtime/aggregate_lock.rb +8 -33
- data/lib/hecks/runtime/boot_gates.rb +3 -18
- data/lib/hecks/runtime/caller.rb +19 -59
- data/lib/hecks/runtime/capability_graph.rb +5 -21
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +23 -160
- data/lib/hecks/runtime/command_interpreter.rb +124 -306
- data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
- data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
- data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
- data/lib/hecks/runtime/command_rules/emission.rb +8 -21
- data/lib/hecks/runtime/command_rules/references.rb +23 -202
- data/lib/hecks/runtime/dependency_planning.rb +30 -102
- data/lib/hecks/runtime/dispatcher.rb +82 -241
- data/lib/hecks/runtime/entity_element.rb +40 -462
- data/lib/hecks/runtime/entity_interpreter.rb +64 -219
- data/lib/hecks/runtime/errors.rb +32 -115
- data/lib/hecks/runtime/event.rb +3 -25
- data/lib/hecks/runtime/identity.rb +18 -154
- data/lib/hecks/runtime/instance.rb +18 -150
- data/lib/hecks/runtime/interpreting.rb +11 -70
- data/lib/hecks/runtime/invocation.rb +28 -164
- data/lib/hecks/runtime/loader.rb +48 -186
- data/lib/hecks/runtime/outbox.rb +38 -261
- data/lib/hecks/runtime/policy_interpreter.rb +38 -200
- data/lib/hecks/runtime/port_operation_interpreter.rb +26 -87
- data/lib/hecks/runtime/query_interpreter.rb +45 -187
- data/lib/hecks/runtime/reaction_invocation.rb +36 -138
- data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
- data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
- data/lib/hecks/runtime/reference_hop.rb +8 -81
- data/lib/hecks/runtime/refusal_wording.rb +8 -89
- data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
- data/lib/hecks/runtime/registry/verification.rb +52 -225
- data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
- data/lib/hecks/runtime/registry.rb +99 -244
- data/lib/hecks/runtime/remote_dispatcher.rb +37 -152
- data/lib/hecks/runtime/routing.rb +4 -15
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
- data/lib/hecks/runtime/saga_interpreter.rb +79 -263
- data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
- data/lib/hecks/runtime/tenant_check.rb +6 -68
- data/lib/hecks/runtime/tenant_scope.rb +3 -28
- data/lib/hecks/runtime/value/admission.rb +16 -67
- data/lib/hecks/runtime/value/coercion.rb +155 -641
- data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
- data/lib/hecks/runtime/value.rb +12 -84
- data/lib/hecks/runtime.rb +17 -65
- data/lib/hecks/storehouse.rb +141 -568
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +8 -32
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
- data/lib/hecks/vendoring/git_environment.rb +2 -8
- data/lib/hecks/vendoring/git_source.rb +4 -10
- data/lib/hecks/vendoring.rb +7 -46
- data/lib/hecks/version.rb +3 -14
- data/lib/hecks.rb +26 -81
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
- metadata +3 -2
|
@@ -6,12 +6,8 @@ require_relative "../../query_specification/common/comparison"
|
|
|
6
6
|
module Hecks
|
|
7
7
|
module Ports
|
|
8
8
|
module Query
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# records instead of compiling SQL. Deliberately kept in exact
|
|
12
|
-
# LIMIT/OFFSET-order agreement with SqlQueryBuilder (see #execute's
|
|
13
|
-
# own comment) so a query answers the same page regardless of
|
|
14
|
-
# which adapter backs it.
|
|
9
|
+
# Applies wheres, order_by, offset and limit to an Array of records, in the same order
|
|
10
|
+
# as `SqlQueryBuilder` so every adapter answers the same page.
|
|
15
11
|
module InMemory
|
|
16
12
|
FieldPath = QuerySpecification::FieldPath
|
|
17
13
|
Comparison = QuerySpecification::Common::Comparison
|
|
@@ -20,17 +16,12 @@ module Hecks
|
|
|
20
16
|
|
|
21
17
|
# Filters, orders and pages `records` against a declared query specification.
|
|
22
18
|
#
|
|
23
|
-
# @param records [Array<Runtime::Instance, Hash>] the
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# @
|
|
29
|
-
# where clause, `offset`, or `limit`
|
|
30
|
-
# @param registry [Runtime::Registry, nil] the booted registry, passed through to a
|
|
31
|
-
# registry-aware comparison; nil when none is available
|
|
32
|
-
# @return [Array<Runtime::Instance, Hash>] the matching records, ordered and paged;
|
|
33
|
-
# the same element type as `records`
|
|
19
|
+
# @param records [Array<Runtime::Instance, Hash>] the candidates
|
|
20
|
+
# @param declared [QuerySpecification::Common::Options] provides `wheres`, `order_by`,
|
|
21
|
+
# `offset` and `limit`
|
|
22
|
+
# @param args [Hash{Symbol => Object}] values for Symbol placeholders
|
|
23
|
+
# @param registry [Runtime::Registry, nil] passed to registry-aware comparisons
|
|
24
|
+
# @return [Array<Runtime::Instance, Hash>] the matching records, ordered and paged
|
|
34
25
|
def execute(records, declared, args = {}, registry: nil)
|
|
35
26
|
matched = records.select do |record|
|
|
36
27
|
declared.wheres.all? do |clause|
|
|
@@ -40,58 +31,19 @@ module Hecks
|
|
|
40
31
|
field = declared.order_by&.field
|
|
41
32
|
matched = Ordering.apply(matched, declared.order_by, declared.null_semantics,
|
|
42
33
|
identity: ->(record) { record.id.to_s }) { |record| comparable(FieldPath.dig(record, field)) }
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# what every SQL-backed aggregate already answers. Written the
|
|
46
|
-
# other way round here, and the two engines disagreed on the
|
|
47
|
-
# same declaration: `limit 2, offset 1` over three rows is rows
|
|
48
|
-
# two and three in Postgres and Sqlite, and was row two alone in
|
|
49
|
-
# memory. Silently — a short page reads exactly like a page that
|
|
50
|
-
# ran out of rows.
|
|
51
|
-
#
|
|
52
|
-
# It gets worse the further you page, which is the case nobody
|
|
53
|
-
# writing the first page ever sees: at `limit 10, offset 10`,
|
|
54
|
-
# taking ten and then dropping ten leaves nothing, so page two
|
|
55
|
-
# of a memory-backed query came back empty however many rows
|
|
56
|
-
# were really there.
|
|
34
|
+
# Offset before limit, as SQL means `LIMIT n OFFSET m`; the reverse order returns a short
|
|
35
|
+
# or empty page (`limit 10, offset 10` would drop everything).
|
|
57
36
|
matched = matched.drop(resolve(declared.offset.value, args).to_i) if declared.offset
|
|
58
37
|
matched = matched.first(resolve(declared.limit.value, args).to_i) if declared.limit
|
|
59
38
|
matched
|
|
60
39
|
end
|
|
61
40
|
|
|
62
|
-
# The comparator table itself lives in
|
|
63
|
-
# QuerySpecification::Common::Comparison, not duplicated per
|
|
64
|
-
# caller — this module and Runtime::QueryInterpreter drifted
|
|
65
|
-
# when each carried its own copy (see that file's own comment
|
|
66
|
-
# for what it cost). What stays here is how a value is reached
|
|
67
|
-
# for this path: a registry arrives as an argument rather than
|
|
68
|
-
# as instance state, and the field is dug through FieldPath
|
|
69
|
-
# before it arrives.
|
|
70
|
-
# @param clause [QuerySpecification::Common::WhereClause] the declared comparison
|
|
71
|
-
# @param held [Object, nil] the record's own value for `clause.field`
|
|
72
|
-
# @param args [Hash{Symbol => Object}] bound values for a Symbol-named `clause.value`
|
|
73
|
-
# @param registry [Runtime::Registry, nil] used only by `none_in_state`; see
|
|
74
|
-
# `Comparison.holds?`
|
|
75
|
-
# @return [Boolean] whether the comparison holds
|
|
76
|
-
# @raise [Runtime::WiringError] if `clause.op` names no comparator in
|
|
77
|
-
# `Comparison`'s table, or `none_in_state`'s target aggregate has no wired repository
|
|
78
41
|
def holds?(clause, held, args, registry: nil)
|
|
79
42
|
Comparison.holds?(clause.op, held, comparable(resolve(clause.value, args)), registry: registry)
|
|
80
43
|
end
|
|
81
44
|
|
|
82
|
-
# Resolves a where-clause value, looking up a Symbol placeholder in `args`.
|
|
83
|
-
#
|
|
84
|
-
# @param value [Object] a literal value, or a Symbol naming a key in `args`
|
|
85
|
-
# @param args [Hash{Symbol => Object}] bound argument values
|
|
86
|
-
# @return [Object] `args[value]` when `value` is a Symbol, else `value` unchanged
|
|
87
45
|
def resolve(value, args) = value.is_a?(Symbol) ? args[value] : value
|
|
88
46
|
|
|
89
|
-
# Normalises a value into the shape `Comparison` compares against.
|
|
90
|
-
#
|
|
91
|
-
# @param value [Runtime::Value, Hash, Object, nil] a held or wanted value; a
|
|
92
|
-
# `Runtime::Value` is read through its `to_h`
|
|
93
|
-
# @return [Object, nil] the sole numeric member, or the sole member, of a Hash-shaped
|
|
94
|
-
# value; otherwise `value` unchanged
|
|
95
47
|
def comparable(value) = Comparison.comparable(value)
|
|
96
48
|
end
|
|
97
49
|
end
|
|
@@ -3,46 +3,25 @@ require_relative "../../query_specification/common/null_policy"
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Ports
|
|
5
5
|
module Query
|
|
6
|
-
#
|
|
7
|
-
# of the store that happens to hold it. Declared here once so an adapter
|
|
8
|
-
# may satisfy it natively but never redefine it : SQLite pushes both
|
|
9
|
-
# tiers into SQL (NullPolicy.sql_order renders `field DIR, id DIR`),
|
|
10
|
-
# while Heki and Memory have no query engine and delegate straight back
|
|
11
|
-
# to InMemory.
|
|
6
|
+
# The order an ask answers in: the declared order_by, then identity as a total tiebreaker.
|
|
12
7
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# Without it, an ask with no order_by — or a declared order with tied
|
|
16
|
-
# keys — hands back whatever order the store happened to hold, and
|
|
17
|
-
# store order was quietly standing in for a rule while every
|
|
18
|
-
# hand-written query in the corpus stayed green : not one of them
|
|
19
|
-
# had a tie for store order to decide.
|
|
20
|
-
#
|
|
21
|
-
# An adapter that pushes ordering down must push limit down with it.
|
|
22
|
-
# Re-ordering a page the store already cut would be a top-N of the
|
|
23
|
-
# wrong N — the one way this can be got quietly, expensively wrong.
|
|
8
|
+
# An adapter that pushes ordering down must push limit down with it; re-ordering
|
|
9
|
+
# a page the store already cut yields a top-N of the wrong N.
|
|
24
10
|
module Ordering
|
|
25
11
|
module_function
|
|
26
12
|
|
|
27
|
-
# Orders
|
|
28
|
-
# tiebreaker.
|
|
13
|
+
# Orders rows by `order_by`, breaking ties by `identity`.
|
|
29
14
|
#
|
|
30
|
-
# @param rows [Array<Object>] the rows to order
|
|
31
|
-
#
|
|
32
|
-
# @param
|
|
33
|
-
# nil
|
|
34
|
-
# @param
|
|
35
|
-
# nil-valued row sorts, passed to `NullPolicy.order`; nil uses its native default
|
|
36
|
-
# @param identity [Proc] yields a row, returns its comparable identity value, used
|
|
37
|
-
# as the stable tiebreaker
|
|
15
|
+
# @param rows [Array<Object>] the rows to order
|
|
16
|
+
# @param order_by [QuerySpecification::Common::OrderBy, nil] nil orders by identity alone
|
|
17
|
+
# @param null_semantics [QuerySpecification::Common::NullSemantics, nil] where nil values
|
|
18
|
+
# sort; nil uses the native default
|
|
19
|
+
# @param identity [Proc] returns a row's comparable identity value
|
|
38
20
|
# @yieldparam row [Object] one row being ordered
|
|
39
21
|
# @yieldreturn [Object, nil] the row's comparable value for `order_by`'s field
|
|
40
|
-
# @return [Array<Object>]
|
|
41
|
-
# alone when `order_by` is nil)
|
|
22
|
+
# @return [Array<Object>] the ordered rows
|
|
42
23
|
def apply(rows, order_by, null_semantics = nil, identity:, &value_of)
|
|
43
|
-
#
|
|
44
|
-
# otherwise swap arbitrarily, and a tier meant to remove store-dependence
|
|
45
|
-
# would be adding a coin flip of its own.
|
|
24
|
+
# The index keeps the sort stable; sort_by alone would order tied identities arbitrarily.
|
|
46
25
|
rows = rows.each_with_index.sort_by { |row, index| [identity.call(row), index] }.map(&:first)
|
|
47
26
|
return rows unless order_by
|
|
48
27
|
|
data/lib/hecks/ports/query.rb
CHANGED
|
@@ -1,39 +1,25 @@
|
|
|
1
1
|
module Hecks
|
|
2
2
|
module Ports
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# Ordering (the meaning of an ask's answer order) and InMemory (the
|
|
6
|
-
# fallback engine for stores with no query engine of their own) are
|
|
7
|
-
# its collaborators — query/ordering.rb and query/in_memory.rb.
|
|
3
|
+
# Query execution boundary: an adapter may expose one native `query` hook, and everything
|
|
4
|
+
# else runs in the shared interpreter (`query/ordering.rb`, `query/in_memory.rb`).
|
|
8
5
|
module Query
|
|
9
|
-
# A declared query the chosen adapter cannot honour as written
|
|
10
|
-
# by `validate!` before the adapter runs it.
|
|
6
|
+
# A declared query the chosen adapter cannot honour as written.
|
|
11
7
|
class Unsupported < StandardError; end
|
|
12
8
|
|
|
13
9
|
module_function
|
|
14
10
|
|
|
15
11
|
# Runs a declared query through the adapter's own `query` hook, if it has one.
|
|
16
12
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
13
|
+
# nil means "no native engine here" and the caller falls back to `InMemory.execute`; no
|
|
14
|
+
# rows is `[]`.
|
|
19
15
|
#
|
|
20
|
-
# @param repository [Persistence::AppendOnly, Object]
|
|
21
|
-
#
|
|
22
|
-
# @param
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# @
|
|
27
|
-
# `aggregate:` and, where a comparator needs one, `registry:`
|
|
28
|
-
# @return [Array<Runtime::Instance>, nil] the matching records, filtered, ordered and
|
|
29
|
-
# paged by the adapter (`[]` when none match); nil if the adapter has no `query`
|
|
30
|
-
# method
|
|
31
|
-
# @raise [Ports::Query::Unsupported] if the specification combines cursor and offset
|
|
32
|
-
# pagination, or asks for inspection the adapter cannot provide
|
|
33
|
-
# @raise [Runtime::WiringError] if a where-clause names an operation no comparator
|
|
34
|
-
# handles (raised by the in-memory engine behind `Memory`, `Heki` and the like)
|
|
35
|
-
# @raise [ArgumentError] if a SQL-backed adapter cannot compile a where-clause's
|
|
36
|
-
# operator
|
|
16
|
+
# @param repository [Persistence::AppendOnly, Object] a repository, or a bare adapter
|
|
17
|
+
# @param specification [QuerySpecification::Common::Options] the declared query
|
|
18
|
+
# @param args [Hash{Symbol => Object}] values for Symbol-valued wheres, limit and offset
|
|
19
|
+
# @param context [Hash{Symbol => Object}] passed to the adapter: `domain:`, `aggregate:`,
|
|
20
|
+
# and `registry:` where a comparator needs one
|
|
21
|
+
# @return [Array<Runtime::Instance>, nil] matches, or nil if the adapter has no `query`
|
|
22
|
+
# @raise [Ports::Query::Unsupported] see `validate!`
|
|
37
23
|
def execute(repository, specification, args = {}, context: {})
|
|
38
24
|
adapter = repository.respond_to?(:adapter) ? repository.adapter : repository
|
|
39
25
|
return nil unless adapter.respond_to?(:query)
|
|
@@ -42,17 +28,8 @@ module Hecks
|
|
|
42
28
|
adapter.query(specification, args, context: context)
|
|
43
29
|
end
|
|
44
30
|
|
|
45
|
-
# Refuses
|
|
46
|
-
#
|
|
47
|
-
# Inspection is honoured by an adapter with an `inspect_query` method, or, for the
|
|
48
|
-
# `"sql"` mode alone, by any adapter with a native `query`.
|
|
49
|
-
#
|
|
50
|
-
# @param specification [QuerySpecification::Common::Options] the declared query to check
|
|
51
|
-
# @param adapter [Object] the persistence adapter that would run it; only what it
|
|
52
|
-
# responds to (`inspect_query`, `query`) is read
|
|
53
|
-
# @return [void]
|
|
54
|
-
# @raise [Ports::Query::Unsupported] if the specification declares both a cursor and
|
|
55
|
-
# an offset, or asks for inspection the adapter cannot provide
|
|
31
|
+
# Refuses cursor with offset pagination, and inspection the adapter cannot provide (`"sql"`
|
|
32
|
+
# mode needs only a native `query`, other modes an `inspect_query` method).
|
|
56
33
|
def validate!(specification, adapter)
|
|
57
34
|
raise Unsupported, "a query cannot combine cursor and offset pagination" if specification.cursor && specification.offset
|
|
58
35
|
|
data/lib/hecks/ports.rb
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
# Hecks::Ports
|
|
2
2
|
#
|
|
3
|
-
# The runtime's named boundaries
|
|
4
|
-
# `ports/persistence.rb`, `ports/query.rb`, … — and a port with supporting
|
|
5
|
-
# cast keeps it in a same-named directory (`ports/persistence/` holds the
|
|
6
|
-
# binding policy, the journal-translation lineage, the repository factory).
|
|
7
|
-
# The `.port` files beside them are the DSL declarations the meta-validator
|
|
8
|
-
# and the Folder adapter load as data.
|
|
3
|
+
# The runtime's named boundaries; each port is a file under `ports/`.
|
|
9
4
|
|
|
10
5
|
module Hecks
|
|
11
|
-
#
|
|
12
|
-
# to add its own port; see the header comment above for what a port is.
|
|
6
|
+
# The runtime's named boundaries; each port is a file under `ports/`.
|
|
13
7
|
module Ports
|
|
14
8
|
end
|
|
15
9
|
end
|
|
@@ -2,28 +2,12 @@ require_relative "../projector"
|
|
|
2
2
|
|
|
3
3
|
module Hecks
|
|
4
4
|
module Projections
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# Projects lib/hecks/bluebook/dsl/bootstrap_table.rb from the chapter's Keyword rows.
|
|
6
|
+
# Committed, not built at boot: it is read before the grammar table exists.
|
|
7
7
|
#
|
|
8
8
|
# Projector.call(:bootstrap_table, bluebook: <the Bluebook chapter>)
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
# yet, so `WordGate#method_missing` and `RuleReference#lookup` cannot
|
|
12
|
-
# read `calls:`/`resolves_via:`/`disambiguator:` off it — this table is
|
|
13
|
-
# what they read instead.
|
|
14
|
-
#
|
|
15
|
-
# A partition, not a filter: every live row lands in the table, not only
|
|
16
|
-
# the ones a bootstrap chapter happens to call. Picking a subset by
|
|
17
|
-
# grepping which words the core chapters use during bootstrap would risk
|
|
18
|
-
# quietly dropping any word a chapter starts using later. Including
|
|
19
|
-
# every row instead costs nothing: a builder with its own `def` never
|
|
20
|
-
# reaches `method_missing` at all, so a row no bootstrap chapter calls
|
|
21
|
-
# is simply never read.
|
|
22
|
-
#
|
|
23
|
-
# The table cannot be built at boot for the same reason it exists: it
|
|
24
|
-
# is read before the grammar it comes from has been assembled. So it is
|
|
25
|
-
# committed, like lib/hecks/vocabulary.rb, and spec/bootstrap_table_
|
|
26
|
-
# spec.rb re-projects it in memory and refuses a diff.
|
|
10
|
+
# Every live row is included, not only those a bootstrap chapter calls.
|
|
27
11
|
module BootstrapTable
|
|
28
12
|
extend Projector::Target
|
|
29
13
|
|
|
@@ -45,20 +29,13 @@ module Hecks
|
|
|
45
29
|
|
|
46
30
|
module_function
|
|
47
31
|
|
|
48
|
-
# Projects the bootstrap fallback table
|
|
49
|
-
#
|
|
50
|
-
# not any one chapter's.
|
|
32
|
+
# Projects the bootstrap fallback table; both arguments are ignored (the table is
|
|
33
|
+
# the whole grammar) and exist for the `Projector::Target` calling convention.
|
|
51
34
|
#
|
|
52
|
-
# @param bluebook [Bluebook::Chapter] ignored; present to satisfy the
|
|
53
|
-
# `Projector::Target` calling convention
|
|
54
|
-
# @param options [Hash{Symbol => Object}] ignored; present to satisfy the
|
|
55
|
-
# `Projector::Target` calling convention
|
|
56
35
|
# @return [String] the rendered `lib/hecks/bluebook/dsl/bootstrap_table.rb` source
|
|
57
36
|
def call(bluebook:, options: {}) = render(bluebook)
|
|
58
37
|
|
|
59
|
-
#
|
|
60
|
-
# still dispatch — the same `status != "retired"` reading
|
|
61
|
-
# `GenericDispatch.shape_for` gives the live table.
|
|
38
|
+
# Every keyword row that is not retired; admitted and deprecated rows still dispatch.
|
|
62
39
|
#
|
|
63
40
|
# @return [Array<Hash{Symbol => String}>] every non-retired keyword row, each with
|
|
64
41
|
# at least `:context`, `:word`, `:status`, `:calls`, `:resolves_via` and
|
|
@@ -67,11 +44,8 @@ module Hecks
|
|
|
67
44
|
Bluebook::MetaValidator::SyntaxBoot.call[:keywords].reject { |row| row[:status] == "retired" }
|
|
68
45
|
end
|
|
69
46
|
|
|
70
|
-
# `[context, word] => :method
|
|
71
|
-
#
|
|
72
|
-
# An overloaded word has one row per argument shape, and they all
|
|
73
|
-
# name the same method. Two that don't would make the table keep
|
|
74
|
-
# whichever came last, so that is refused instead.
|
|
47
|
+
# `[context, word] => :method`, in WordGate's key order.
|
|
48
|
+
# Overloaded rows must all name the same method; a mismatch raises rather than last-wins.
|
|
75
49
|
#
|
|
76
50
|
# @param rows [Array<Hash{Symbol => String}>] the keyword rows to build from,
|
|
77
51
|
# defaulting to every live one
|
|
@@ -90,9 +64,7 @@ module Hecks
|
|
|
90
64
|
end
|
|
91
65
|
end
|
|
92
66
|
|
|
93
|
-
# `[word, context] => { resolves_via:, disambiguator: }
|
|
94
|
-
# RuleReference's own key order, blank columns omitted, the same
|
|
95
|
-
# shape its live `lookup` answers.
|
|
67
|
+
# `[word, context] => { resolves_via:, disambiguator: }`, in RuleReference's key order.
|
|
96
68
|
#
|
|
97
69
|
# @param rows [Array<Hash{Symbol => String}>] the keyword rows to build from,
|
|
98
70
|
# defaulting to every live one
|
|
@@ -106,13 +78,9 @@ module Hecks
|
|
|
106
78
|
end
|
|
107
79
|
end
|
|
108
80
|
|
|
109
|
-
# Renders the
|
|
110
|
-
# `RESOLVES` frozen Hash literals under the generated-file header.
|
|
81
|
+
# Renders the `CALLS` and `RESOLVES` frozen Hash literals as Ruby source.
|
|
111
82
|
#
|
|
112
|
-
# @
|
|
113
|
-
# language's grammar, not this argument
|
|
114
|
-
# @return [String] the full `lib/hecks/bluebook/dsl/bootstrap_table.rb` source,
|
|
115
|
-
# ready to write to disk
|
|
83
|
+
# @return [String] the full `lib/hecks/bluebook/dsl/bootstrap_table.rb` source
|
|
116
84
|
def render(_bluebook)
|
|
117
85
|
rows = live_keywords
|
|
118
86
|
calls_lines = calls(rows).map { |key, target| " #{key.inspect} => #{target.inspect}" }
|
|
@@ -5,25 +5,12 @@ module Hecks
|
|
|
5
5
|
module Projections
|
|
6
6
|
module Deploy
|
|
7
7
|
module Fargate
|
|
8
|
-
# Fills the optional sections of a rendered Fargate template
|
|
9
|
-
#
|
|
10
|
-
# The template text carries `# TMPL:<name>` marker lines where an
|
|
11
|
-
# optional section belongs. `apply` replaces each with what the stack's
|
|
12
|
-
# `Settings::Plan` calls for, and with nothing when the plan sets
|
|
13
|
-
# nothing there, so a world that uses none of the optional settings
|
|
14
|
-
# renders the template it always did.
|
|
8
|
+
# Fills the optional `# TMPL:<name>` sections of a rendered Fargate template with
|
|
9
|
+
# what the plan calls for, or nothing when a world uses none of them.
|
|
15
10
|
module Assembly
|
|
16
11
|
module_function
|
|
17
12
|
|
|
18
13
|
# Replaces every optional-section marker in a rendered template.
|
|
19
|
-
#
|
|
20
|
-
# @param template [String] the rendered template holding `# TMPL:` marker lines
|
|
21
|
-
# @param plan [Settings::Plan] the stack's checked optional settings
|
|
22
|
-
# @param context [Hash{Symbol => Object}] `:stack_name`, `:vpc_ref`, `:listener_id`,
|
|
23
|
-
# `:alb_id`, `:distribution_id` and `:db_secret_ref`
|
|
24
|
-
# @return [String] the template with the markers replaced
|
|
25
|
-
# @raise [ArgumentError] if `domain_env` removes a variable the generator does not set, or
|
|
26
|
-
# the finished template declares one logical id or parameter twice
|
|
27
14
|
def apply(template, plan, context)
|
|
28
15
|
text = override_domain_env(template, plan.domain_env)
|
|
29
16
|
sections(plan, context).each { |marker, block| text = Yaml.splice(text, marker, block) }
|
|
@@ -7,38 +7,7 @@ module Hecks
|
|
|
7
7
|
module Deploy
|
|
8
8
|
module Fargate
|
|
9
9
|
# The CloudFront distribution in front of the load balancer.
|
|
10
|
-
#
|
|
11
|
-
# With no `cdn` setting the stack gets `default_yaml`: the default
|
|
12
|
-
# certificate, one origin, and one behavior that caches nothing. A
|
|
13
|
-
# `cdn` setting replaces that with a distribution described by the
|
|
14
|
-
# world.
|
|
15
|
-
#
|
|
16
|
-
# ## Settings
|
|
17
|
-
#
|
|
18
|
-
# `cdn` is a hash with these optional keys:
|
|
19
|
-
#
|
|
20
|
-
# - `aliases`: hostnames the distribution answers to. Needs `certificate_arn`.
|
|
21
|
-
# - `certificate_arn`: an `ACM` certificate in us-east-1, or an intrinsic such as
|
|
22
|
-
# `"!Ref CertArn"`.
|
|
23
|
-
# - `minimum_protocol`: the TLS policy for the certificate; `TLSv1.2_2021` by default.
|
|
24
|
-
# - `origin_id`: the id of the load-balancer origin; `<AlbId>Origin` by default.
|
|
25
|
-
# - `origin_ssl_protocols`: the TLS versions CloudFront may use to reach the origin, such
|
|
26
|
-
# as `["TLSv1.2"]`.
|
|
27
|
-
# - `explicit_origin_ports`: false leaves `HTTPPort` and `HTTPSPort` unset; true by
|
|
28
|
-
# default.
|
|
29
|
-
# - `origin_secret`: `{header:, parameter:}` sends a secret header to the origin, filled
|
|
30
|
-
# from a `NoEcho` template parameter the stack declares under that name.
|
|
31
|
-
# - `extra_origins`: S3 origins, each `{id:, domain_name:, origin_access_control_id:}`.
|
|
32
|
-
# - `default_behavior`: `{origin:, viewer_protocol:, methods:, compress:, cache_policy:,
|
|
33
|
-
# origin_request_policy:}`.
|
|
34
|
-
# - `behaviors`: entries of the same shape with a required `path`; the first match wins,
|
|
35
|
-
# so order matters.
|
|
36
|
-
# - `retain`: true keeps the distribution when the stack is deleted or replaces it.
|
|
37
|
-
#
|
|
38
|
-
# A cache or origin-request policy is a managed policy's name (`caching_disabled`,
|
|
39
|
-
# `caching_optimized`, `all_viewer`, `all_viewer_except_host`, or `none` to omit an origin
|
|
40
|
-
# request policy) or the id of a policy in the account. `methods` is `all`, `read` or
|
|
41
|
-
# `get_head`.
|
|
10
|
+
# With no `cdn` setting the stack gets `default_yaml`; settings are in the DSL reference.
|
|
42
11
|
module Cdn
|
|
43
12
|
module_function
|
|
44
13
|
|
|
@@ -64,14 +33,6 @@ module Hecks
|
|
|
64
33
|
HOSTNAME = /\A(\*\.)?([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z]{2,}\z/
|
|
65
34
|
|
|
66
35
|
# Reads and checks the `cdn` setting.
|
|
67
|
-
#
|
|
68
|
-
# @param setting [Hash, nil] the world's `cdn` value, or nil when it sets none
|
|
69
|
-
# @param default_origin_id [String] the load-balancer origin's id when `origin_id` is not
|
|
70
|
-
# set
|
|
71
|
-
# @return [Hash{Symbol => Object}, nil] the checked options with defaults applied, or nil
|
|
72
|
-
# for none
|
|
73
|
-
# @raise [ArgumentError] if an option is unknown, malformed, or names an origin that does
|
|
74
|
-
# not exist
|
|
75
36
|
def normalize(setting, default_origin_id:)
|
|
76
37
|
return nil if setting.nil?
|
|
77
38
|
|
|
@@ -87,9 +48,6 @@ module Hecks
|
|
|
87
48
|
end
|
|
88
49
|
|
|
89
50
|
# Lists the template parameters the options need.
|
|
90
|
-
#
|
|
91
|
-
# @param options [Hash, nil] the checked options from `normalize`
|
|
92
|
-
# @return [String] flush-left parameter text, or empty
|
|
93
51
|
def parameters_yaml(options)
|
|
94
52
|
secret = options && options[:origin_secret]
|
|
95
53
|
return "" unless secret
|
|
@@ -103,11 +61,6 @@ module Hecks
|
|
|
103
61
|
end
|
|
104
62
|
|
|
105
63
|
# Renders the distribution for a set of checked options.
|
|
106
|
-
#
|
|
107
|
-
# @param options [Hash] the checked options from `normalize`
|
|
108
|
-
# @param distribution_id [String] the logical id the distribution is given
|
|
109
|
-
# @param alb_id [String] the logical id of the load balancer the origin points at
|
|
110
|
-
# @return [String] the flush-left resource text ending in a newline
|
|
111
64
|
def yaml(options, distribution_id:, alb_id:)
|
|
112
65
|
lines = ["#{distribution_id}:", " Type: AWS::CloudFront::Distribution"]
|
|
113
66
|
lines.push(" DeletionPolicy: Retain", " UpdateReplacePolicy: Retain") if options[:retain]
|
|
@@ -6,17 +6,8 @@ module Hecks
|
|
|
6
6
|
module Cdn
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
|
-
# The distribution a stack gets when its world sets no `cdn` options
|
|
10
|
-
#
|
|
11
|
-
# Real HTTPS in front of the load balancer's HTTP-only listener, and
|
|
12
|
-
# the one safe caching default the generator can offer: every route
|
|
13
|
-
# is treated as session-driven, so nothing is cached. The comment
|
|
14
|
-
# inside the rendered block explains why, and reaches the generated
|
|
15
|
-
# template unchanged.
|
|
16
|
-
#
|
|
17
|
-
# @param alb_id [String] the logical id of the load balancer
|
|
18
|
-
# @param distribution_id [String] the logical id the distribution is given
|
|
19
|
-
# @return [String] the flush-left resource text with its comments, ending in a newline
|
|
9
|
+
# The distribution a stack gets when its world sets no `cdn` options: HTTPS in
|
|
10
|
+
# front of the HTTP-only ALB, caching disabled since every route is session-driven.
|
|
20
11
|
def default_yaml(alb_id:, distribution_id:)
|
|
21
12
|
<<~DEFAULT
|
|
22
13
|
# Real HTTPS (the ALB's own Listener above is HTTP-only —
|
|
@@ -2,15 +2,8 @@ module Hecks
|
|
|
2
2
|
module Projections
|
|
3
3
|
module Deploy
|
|
4
4
|
module Fargate
|
|
5
|
-
# Validation for the optional settings
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# `FargateTarget.Declare` in deploy.bluebook owns the baseline
|
|
9
|
-
# settings (`cpu`, `memory`, `port`, `database`, `web`). The keys added
|
|
10
|
-
# for multi-container stacks are nested shapes (lists of hashes, maps),
|
|
11
|
-
# which that aggregate's flat attributes cannot describe, so they are
|
|
12
|
-
# checked here. Every check raises `ArgumentError` naming the setting
|
|
13
|
-
# it was reading, so a mistake in a `.world` file points at its line.
|
|
5
|
+
# Validation for the optional Fargate settings beyond the baseline ones.
|
|
6
|
+
# Every check raises `ArgumentError` naming the setting it was reading.
|
|
14
7
|
module Check
|
|
15
8
|
module_function
|
|
16
9
|
|
|
@@ -71,7 +64,7 @@ module Hecks
|
|
|
71
64
|
"(letters and digits, starting with a letter), got #{value.inspect}"
|
|
72
65
|
end
|
|
73
66
|
|
|
74
|
-
# Checks that a value is a name AWS accepts for a container, repository or stack
|
|
67
|
+
# Checks that a value is a name AWS accepts for a container, repository or stack.
|
|
75
68
|
#
|
|
76
69
|
# @param value [Object] the name as written in the world file
|
|
77
70
|
# @param where [String] the setting's name, used in the error message
|
|
@@ -116,7 +109,7 @@ module Hecks
|
|
|
116
109
|
# @param min [Integer] the fewest entries allowed
|
|
117
110
|
# @param max [Integer, nil] the most entries allowed, or nil for no limit
|
|
118
111
|
# @return [Array<String>] the entries as strings
|
|
119
|
-
# @raise [ArgumentError] if the value is not a list of strings or
|
|
112
|
+
# @raise [ArgumentError] if the value is not a list of strings or is out of size range
|
|
120
113
|
def strings!(value, where, min: 0, max: nil)
|
|
121
114
|
list = value.is_a?(Array) ? value : nil
|
|
122
115
|
ok = list&.all? { |item| (item.is_a?(String) || item.is_a?(Symbol)) && !item.to_s.empty? }
|
|
@@ -128,9 +121,7 @@ module Hecks
|
|
|
128
121
|
end
|
|
129
122
|
|
|
130
123
|
# Checks that a value is a map of names to strings and returns it string-keyed.
|
|
131
|
-
#
|
|
132
|
-
# A `nil` value is kept: for the domain container's environment it
|
|
133
|
-
# removes a default variable.
|
|
124
|
+
# A `nil` value is kept: the domain container's env setting removes a variable with it.
|
|
134
125
|
#
|
|
135
126
|
# @param value [Object] the map as written in the world file
|
|
136
127
|
# @param where [String] the setting's name, used in the error message
|