synthra 0.1.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 +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +40 -0
- data/.yardopts +18 -0
- data/ACCESS_DOCS.md +116 -0
- data/ADVANCED_FEATURES_SUMMARY.md +245 -0
- data/CHANGELOG.md +498 -0
- data/CODE_OF_CONDUCT.md +122 -0
- data/CONTRIBUTING.md +307 -0
- data/DOCUMENTATION.md +204 -0
- data/DOCUMENTATION_GUIDE.md +194 -0
- data/LICENSE +22 -0
- data/README.md +1458 -0
- data/Rakefile +128 -0
- data/benchmark/README.md +591 -0
- data/benchmark/batch_generation.rb +63 -0
- data/benchmark/engine_comparison.rb +295 -0
- data/benchmark/single_record.rb +108 -0
- data/benchmark/streaming.rb +74 -0
- data/docs/ACTIVERECORD_INFERENCE.md +524 -0
- data/docs/API_SERVER.md +278 -0
- data/docs/CONFIG_FILE.md +315 -0
- data/docs/DATA_CONTRACTS.md +312 -0
- data/docs/ENHANCED_REPL.md +304 -0
- data/docs/FACTORY_BOT.md +271 -0
- data/docs/GITHUB_ACTION.md +420 -0
- data/docs/GRAPHQL_EXPORT.md +303 -0
- data/docs/GRAPHQL_FEDERATION.md +651 -0
- data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
- data/docs/LSP.md +189 -0
- data/docs/MIGRATION_GENERATOR.md +547 -0
- data/docs/MOCK_SERVER.md +280 -0
- data/docs/NATIVE_ENGINE.md +298 -0
- data/docs/OPENAPI_EXPORT.md +252 -0
- data/docs/PERFORMANCE_MODE.md +228 -0
- data/docs/PERSONAS.md +547 -0
- data/docs/PROPERTY_TESTING.md +284 -0
- data/docs/PROTOBUF_EXPORT.md +276 -0
- data/docs/QUALITY_METRICS.md +555 -0
- data/docs/QUICK_REFERENCE.md +88 -0
- data/docs/RAILS_ENGINE.md +404 -0
- data/docs/RAILS_INTEGRATION.md +454 -0
- data/docs/README.md +175 -0
- data/docs/REPL_QUICK_REFERENCE.md +149 -0
- data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
- data/docs/SCENARIOS.md +576 -0
- data/docs/SECURITY_TESTING.md +318 -0
- data/docs/SNAPSHOT_TESTING.md +308 -0
- data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
- data/docs/TERRAFORM_EXPORT.md +447 -0
- data/docs/TIME_TRAVEL.md +507 -0
- data/docs/USAGE_GUIDE.md +980 -0
- data/docs/WEBHOOK_SIMULATOR.md +579 -0
- data/docs/advanced_features.md +183 -0
- data/docs/api_reference.md +153 -0
- data/docs/behaviors.md +138 -0
- data/docs/best_practices.md +191 -0
- data/docs/dsl_reference.md +172 -0
- data/docs/examples.md +162 -0
- data/docs/generation_modes.md +125 -0
- data/docs/getting_started.md +92 -0
- data/docs/index.html +177 -0
- data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
- data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
- data/docs/troubleshooting.md +215 -0
- data/docs/type_reference.md +224 -0
- data/examples/hostile_mode_demo.rb +64 -0
- data/exe/synthra +6 -0
- data/ext/synthra_native/Cargo.lock +972 -0
- data/ext/synthra_native/Cargo.toml +46 -0
- data/ext/synthra_native/extconf.rb +41 -0
- data/ext/synthra_native/src/generator.rs +397 -0
- data/ext/synthra_native/src/lib.rs +229 -0
- data/ext/synthra_native/src/types.rs +1485 -0
- data/lib/generators/synthra/install_generator.rb +86 -0
- data/lib/generators/synthra/templates/api_response.dsl +15 -0
- data/lib/generators/synthra/templates/fake_data.rake +116 -0
- data/lib/generators/synthra/templates/synthra.yml +31 -0
- data/lib/generators/synthra/templates/synthra_support.rb +19 -0
- data/lib/generators/synthra/templates/user.dsl +11 -0
- data/lib/synthra/activerecord_inference.rb +394 -0
- data/lib/synthra/api.rb +381 -0
- data/lib/synthra/api_server.rb +718 -0
- data/lib/synthra/behaviors/applicator.rb +165 -0
- data/lib/synthra/behaviors/base.rb +155 -0
- data/lib/synthra/behaviors/close_connection.rb +60 -0
- data/lib/synthra/behaviors/deprecated.rb +100 -0
- data/lib/synthra/behaviors/failure.rb +69 -0
- data/lib/synthra/behaviors/latency.rb +103 -0
- data/lib/synthra/behaviors/partial_data.rb +83 -0
- data/lib/synthra/behaviors/randomize_order.rb +74 -0
- data/lib/synthra/behaviors/registry.rb +238 -0
- data/lib/synthra/behaviors/simulate_error.rb +79 -0
- data/lib/synthra/cli/commands/base.rb +105 -0
- data/lib/synthra/cli/commands/diff.rb +227 -0
- data/lib/synthra/cli/commands/docs.rb +67 -0
- data/lib/synthra/cli/commands/export.rb +150 -0
- data/lib/synthra/cli/commands/generate.rb +72 -0
- data/lib/synthra/cli/commands/import.rb +80 -0
- data/lib/synthra/cli/commands/lint.rb +53 -0
- data/lib/synthra/cli/commands/live.rb +57 -0
- data/lib/synthra/cli/commands/seed.rb +99 -0
- data/lib/synthra/cli/commands/validate.rb +28 -0
- data/lib/synthra/cli.rb +2471 -0
- data/lib/synthra/config_file.rb +129 -0
- data/lib/synthra/configuration.rb +281 -0
- data/lib/synthra/contracts_registry.rb +408 -0
- data/lib/synthra/database_seeder.rb +268 -0
- data/lib/synthra/deterministic_ids.rb +218 -0
- data/lib/synthra/documentation_generator.rb +414 -0
- data/lib/synthra/engine.rb +251 -0
- data/lib/synthra/errors.rb +1169 -0
- data/lib/synthra/export/base.rb +85 -0
- data/lib/synthra/export/csv.rb +101 -0
- data/lib/synthra/export/graphql.rb +266 -0
- data/lib/synthra/export/graphql_federation.rb +377 -0
- data/lib/synthra/export/graphviz.rb +258 -0
- data/lib/synthra/export/javascript.rb +327 -0
- data/lib/synthra/export/json_data.rb +61 -0
- data/lib/synthra/export/json_schema.rb +290 -0
- data/lib/synthra/export/openapi.rb +514 -0
- data/lib/synthra/export/protobuf.rb +483 -0
- data/lib/synthra/export/python.rb +560 -0
- data/lib/synthra/export/sql.rb +381 -0
- data/lib/synthra/export/sql_insert.rb +152 -0
- data/lib/synthra/export/terraform.rb +501 -0
- data/lib/synthra/export/type_mapping.rb +389 -0
- data/lib/synthra/export/typescript.rb +300 -0
- data/lib/synthra/export/xml_data.rb +104 -0
- data/lib/synthra/export/yaml_data.rb +56 -0
- data/lib/synthra/export.rb +404 -0
- data/lib/synthra/factory_bot_integration.rb +157 -0
- data/lib/synthra/field.rb +440 -0
- data/lib/synthra/functions/registry.rb +104 -0
- data/lib/synthra/generator/context.rb +372 -0
- data/lib/synthra/generator/engine.rb +336 -0
- data/lib/synthra/generator/faker_adapter.rb +425 -0
- data/lib/synthra/generator/modes.rb +444 -0
- data/lib/synthra/generator/resolver.rb +256 -0
- data/lib/synthra/generator/rng.rb +273 -0
- data/lib/synthra/generator/streamer.rb +63 -0
- data/lib/synthra/generator/uniqueness.rb +118 -0
- data/lib/synthra/initializer.rb +97 -0
- data/lib/synthra/limits.rb +279 -0
- data/lib/synthra/live_preview.rb +518 -0
- data/lib/synthra/loader_config.rb +78 -0
- data/lib/synthra/lsp/server.rb +689 -0
- data/lib/synthra/migration_generator.rb +301 -0
- data/lib/synthra/mixin.rb +174 -0
- data/lib/synthra/mock_server.rb +458 -0
- data/lib/synthra/native_engine.rb +304 -0
- data/lib/synthra/openapi_importer.rb +228 -0
- data/lib/synthra/output/json_formatter.rb +40 -0
- data/lib/synthra/output/ndjson_formatter.rb +55 -0
- data/lib/synthra/parser/ast.rb +1287 -0
- data/lib/synthra/parser/lexer.rb +1152 -0
- data/lib/synthra/parser/parser.rb +1664 -0
- data/lib/synthra/parser/tokens.rb +461 -0
- data/lib/synthra/performance_mode.rb +364 -0
- data/lib/synthra/personas.rb +397 -0
- data/lib/synthra/property_testing.rb +172 -0
- data/lib/synthra/quality_metrics.rb +405 -0
- data/lib/synthra/rails_test_helper.rb +248 -0
- data/lib/synthra/registry.rb +533 -0
- data/lib/synthra/relationships.rb +193 -0
- data/lib/synthra/repl/enhanced_repl.rb +607 -0
- data/lib/synthra/repl/formatter.rb +191 -0
- data/lib/synthra/scenarios.rb +423 -0
- data/lib/synthra/schema.rb +605 -0
- data/lib/synthra/schema_inheritance.rb +104 -0
- data/lib/synthra/schema_versioning.rb +212 -0
- data/lib/synthra/snapshot_testing.rb +199 -0
- data/lib/synthra/time_travel.rb +338 -0
- data/lib/synthra/type_definitions.rb +274 -0
- data/lib/synthra/types/address_location/addresses.rb +125 -0
- data/lib/synthra/types/address_location/airports.rb +200 -0
- data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
- data/lib/synthra/types/address_location/locations.rb +406 -0
- data/lib/synthra/types/base.rb +48 -0
- data/lib/synthra/types/commerce_products/commerce.rb +119 -0
- data/lib/synthra/types/commerce_products/companies.rb +71 -0
- data/lib/synthra/types/commerce_products/construction.rb +126 -0
- data/lib/synthra/types/commerce_products/products.rb +205 -0
- data/lib/synthra/types/core/collections.rb +513 -0
- data/lib/synthra/types/core/defaults.rb +76 -0
- data/lib/synthra/types/core/enums.rb +102 -0
- data/lib/synthra/types/core/identifiers.rb +445 -0
- data/lib/synthra/types/core/primitives.rb +586 -0
- data/lib/synthra/types/core/references.rb +466 -0
- data/lib/synthra/types/core/sequences.rb +304 -0
- data/lib/synthra/types/crypto/crypto.rb +162 -0
- data/lib/synthra/types/date_time/dates.rb +387 -0
- data/lib/synthra/types/finance_banking/banking.rb +424 -0
- data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
- data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
- data/lib/synthra/types/formula.rb +184 -0
- data/lib/synthra/types/health_medical/medical.rb +150 -0
- data/lib/synthra/types/hostile_payloads.rb +122 -0
- data/lib/synthra/types/json_array.rb +51 -0
- data/lib/synthra/types/media_entertainment/media.rb +62 -0
- data/lib/synthra/types/naughty_string.rb +30 -0
- data/lib/synthra/types/personal_names/chinese.rb +41 -0
- data/lib/synthra/types/personal_names/identifiers.rb +187 -0
- data/lib/synthra/types/personal_names/names.rb +246 -0
- data/lib/synthra/types/personal_names/national_id.rb +89 -0
- data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
- data/lib/synthra/types/regex.rb +248 -0
- data/lib/synthra/types/registry.rb +182 -0
- data/lib/synthra/types/repeating_element.rb +50 -0
- data/lib/synthra/types/scenario.rb +29 -0
- data/lib/synthra/types/technology_internet/apps.rb +67 -0
- data/lib/synthra/types/technology_internet/communication.rb +162 -0
- data/lib/synthra/types/technology_internet/devices.rb +80 -0
- data/lib/synthra/types/technology_internet/formats.rb +139 -0
- data/lib/synthra/types/technology_internet/networking.rb +143 -0
- data/lib/synthra/types/template.rb +92 -0
- data/lib/synthra/types/text_content/business.rb +128 -0
- data/lib/synthra/types/text_content/colors.rb +70 -0
- data/lib/synthra/types/text_content/misc.rb +237 -0
- data/lib/synthra/types/text_content/security.rb +130 -0
- data/lib/synthra/types/text_content/text_generation.rb +532 -0
- data/lib/synthra/types/travel/travel.rb +150 -0
- data/lib/synthra/utils/string_distance.rb +133 -0
- data/lib/synthra/validator/dsl_validator.rb +339 -0
- data/lib/synthra/validator/path_validator.rb +615 -0
- data/lib/synthra/version.rb +35 -0
- data/lib/synthra/webhook_simulator.rb +341 -0
- data/lib/synthra.rb +259 -0
- data/schemas/address.dsl +16 -0
- data/schemas/api_response.dsl +8 -0
- data/schemas/error_payload.dsl +9 -0
- data/schemas/order.dsl +10 -0
- data/schemas/order_item.dsl +8 -0
- data/schemas/payment.dsl +11 -0
- data/schemas/social_post.dsl +13 -0
- data/schemas/user.dsl +10 -0
- data/scripts/batch_fix_all.rb +96 -0
- data/scripts/delete_old_files.rb +32 -0
- data/scripts/fix_all_grouped_files.rb +137 -0
- data/scripts/fix_all_indentation.rb +48 -0
- data/scripts/fix_all_syntax.rb +124 -0
- data/scripts/fix_grouped_files.rb +184 -0
- data/scripts/fix_syntax_errors.rb +108 -0
- data/scripts/group_domain_types.rb +112 -0
- data/scripts/group_domain_types_fixed.rb +150 -0
- data/scripts/merge_domains_to_one_file.rb +68 -0
- data/scripts/move_existing_types.rb +130 -0
- data/scripts/split_grouped_types.rb +142 -0
- data/tech_docs/README.md +134 -0
- data/tech_docs/advanced/streaming.md +405 -0
- data/tech_docs/advanced/thread_safety.md +253 -0
- data/tech_docs/api/overview.md +485 -0
- data/tech_docs/appendices/type_chart.md +193 -0
- data/tech_docs/basic_concepts.md +383 -0
- data/tech_docs/behaviors/overview.md +346 -0
- data/tech_docs/dsl/complex_types.md +790 -0
- data/tech_docs/dsl/core_types.md +464 -0
- data/tech_docs/dsl/datetime_types.md +325 -0
- data/tech_docs/dsl/field_modifiers.md +414 -0
- data/tech_docs/dsl/grammar.md +431 -0
- data/tech_docs/dsl/schema_definition.md +399 -0
- data/tech_docs/export/README.md +276 -0
- data/tech_docs/installation.md +273 -0
- data/tech_docs/integration/ci_cd.md +707 -0
- data/tech_docs/integration/ci_cd_guide.md +579 -0
- data/tech_docs/integration/factory_bot.md +485 -0
- data/tech_docs/integration/rails.md +630 -0
- data/tech_docs/integration/rspec.md +449 -0
- data/tech_docs/modes/overview.md +350 -0
- data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
- data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
- data/tech_docs/quick_start.md +256 -0
- data/tech_docs/templates/README.md +805 -0
- data/tech_docs/tutorials/advanced.md +371 -0
- data/tech_docs/tutorials/getting_started.md +189 -0
- data/tech_docs/tutorials/intermediate.md +231 -0
- data/tech_docs/tutorials/template_gallery.md +569 -0
- data/tech_example/01_basic_usage.rb +238 -0
- data/tech_example/02_types_demo.rb +336 -0
- data/tech_example/04_cli_usage.md +429 -0
- data/tech_example/05_database_seeding.rb +283 -0
- data/tech_example/07_rspec_integration.rb +359 -0
- data/tech_example/10_custom_types.rb +387 -0
- data/tech_example/12_behaviors.rb +372 -0
- data/tech_example/13_twitter_dm_example.rb +120 -0
- data/tech_example/14_exact_json_structure.rb +253 -0
- data/tech_example/16_lsp_server.rb +56 -0
- data/tech_example/17_property_testing.rb +92 -0
- data/tech_example/18_enhanced_repl.rb +120 -0
- data/tech_example/19_security_fuzzing.rb +145 -0
- data/tech_example/NEW_FEATURES.md +169 -0
- data/tech_example/README.md +118 -0
- data/tech_example/schemas/api_response.dsl +123 -0
- data/tech_example/schemas/ecommerce.dsl +121 -0
- data/tech_example/schemas/twitter_dm.dsl +109 -0
- data/tech_example/schemas/user.dsl +36 -0
- data/vscode-extension/README.md +246 -0
- data/vscode-extension/language-configuration.json +31 -0
- data/vscode-extension/package.json +55 -0
- data/vscode-extension/snippets/fakedatadsl.json +198 -0
- data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
- metadata +478 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Synthra
|
|
4
|
+
# Rails Engine for zero-configuration integration
|
|
5
|
+
#
|
|
6
|
+
# Provides automatic setup for Rails applications:
|
|
7
|
+
# - Auto-discovers schemas from standard locations
|
|
8
|
+
# - Mounts API in development mode
|
|
9
|
+
# - Integrates with Factory Bot if present
|
|
10
|
+
# - Auto-configures for test environment
|
|
11
|
+
#
|
|
12
|
+
# @example Gemfile
|
|
13
|
+
# gem 'synthra'
|
|
14
|
+
#
|
|
15
|
+
# @example Generate initializer
|
|
16
|
+
# rails generate synthra:install
|
|
17
|
+
#
|
|
18
|
+
class Engine < ::Rails::Engine
|
|
19
|
+
isolate_namespace Synthra
|
|
20
|
+
|
|
21
|
+
# Schema search paths (in priority order)
|
|
22
|
+
SCHEMA_PATHS = %w[
|
|
23
|
+
db/schemas
|
|
24
|
+
app/schemas
|
|
25
|
+
schemas
|
|
26
|
+
spec/schemas
|
|
27
|
+
test/schemas
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
config.synthra = ActiveSupport::OrderedOptions.new
|
|
31
|
+
config.synthra.auto_discover = true
|
|
32
|
+
config.synthra.auto_mount = true
|
|
33
|
+
config.synthra.mount_path = "/fake_data"
|
|
34
|
+
config.synthra.factory_bot_integration = true
|
|
35
|
+
config.synthra.infer_from_models = false
|
|
36
|
+
|
|
37
|
+
# Initialize configuration
|
|
38
|
+
initializer "synthra.configure", before: :load_config_initializers do |app|
|
|
39
|
+
# Set default schema directory
|
|
40
|
+
config.synthra.schema_dir ||= find_schema_directory(app.root)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Auto-discover and load schemas
|
|
44
|
+
initializer "synthra.load_schemas", after: :load_config_initializers do |app|
|
|
45
|
+
next unless config.synthra.auto_discover
|
|
46
|
+
|
|
47
|
+
schema_dir = config.synthra.schema_dir
|
|
48
|
+
if schema_dir && Dir.exist?(schema_dir)
|
|
49
|
+
# Set schema_dir on configuration if the method exists
|
|
50
|
+
if Synthra.configuration.respond_to?(:schema_dir=)
|
|
51
|
+
Synthra.configuration.schema_dir = schema_dir.to_s
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Load all schemas
|
|
55
|
+
Dir.glob(File.join(schema_dir, "**/*.dsl")).each do |file|
|
|
56
|
+
Synthra.load(file)
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
Rails.logger.warn "[Synthra] Failed to load schema #{file}: #{e.message}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Rails.logger.info "[Synthra] Loaded #{Synthra.registry.names.count} schemas from #{schema_dir}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Mount API in development
|
|
66
|
+
initializer "synthra.routes", after: :add_routing_paths do |app|
|
|
67
|
+
next unless config.synthra.auto_mount
|
|
68
|
+
next unless Rails.env.development? || Rails.env.test?
|
|
69
|
+
|
|
70
|
+
schema_dir = config.synthra.schema_dir
|
|
71
|
+
next unless schema_dir && Dir.exist?(schema_dir)
|
|
72
|
+
|
|
73
|
+
mount_path = config.synthra.mount_path
|
|
74
|
+
|
|
75
|
+
app.routes.append do
|
|
76
|
+
mount Synthra::Engine, at: mount_path
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
Rails.logger.info "[Synthra] API mounted at #{mount_path}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Integrate with Factory Bot
|
|
83
|
+
initializer "synthra.factory_bot", after: "factory_bot.set_factory_paths" do |_app|
|
|
84
|
+
next unless config.synthra.factory_bot_integration
|
|
85
|
+
|
|
86
|
+
if defined?(FactoryBot)
|
|
87
|
+
Synthra::FactoryBotBridge.integrate!
|
|
88
|
+
Rails.logger.info "[Synthra] Integrated with Factory Bot"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Configure for test environment
|
|
93
|
+
initializer "synthra.test_setup" do |_app|
|
|
94
|
+
next unless Rails.env.test?
|
|
95
|
+
|
|
96
|
+
# Enable deterministic generation in tests
|
|
97
|
+
# Note: default_seed is not currently supported
|
|
98
|
+
# Synthra.configure do |c|
|
|
99
|
+
# c.default_seed = 42
|
|
100
|
+
# end
|
|
101
|
+
|
|
102
|
+
# Add test helpers
|
|
103
|
+
if defined?(RSpec) && RSpec.respond_to?(:configure)
|
|
104
|
+
RSpec.configure do |rspec|
|
|
105
|
+
rspec.include Synthra::TestHelpers
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if defined?(ActiveSupport::TestCase)
|
|
110
|
+
ActiveSupport::TestCase.include Synthra::TestHelpers
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Auto-infer schemas from ActiveRecord models
|
|
115
|
+
initializer "synthra.infer_models", after: :load_active_record do |_app|
|
|
116
|
+
next unless config.synthra.infer_from_models
|
|
117
|
+
|
|
118
|
+
ActiveSupport.on_load(:active_record) do
|
|
119
|
+
Rails.application.eager_load! if Rails.env.development?
|
|
120
|
+
|
|
121
|
+
ActiveRecord::Base.descendants.each do |model|
|
|
122
|
+
next if model.abstract_class?
|
|
123
|
+
next if model.name.start_with?("ActiveRecord::")
|
|
124
|
+
|
|
125
|
+
begin
|
|
126
|
+
schema = Synthra::ActiveRecordInference.infer(model)
|
|
127
|
+
Synthra.registry.register_schema(model.name, schema)
|
|
128
|
+
rescue StandardError => e
|
|
129
|
+
Rails.logger.debug "[Synthra] Could not infer schema for #{model.name}: #{e.message}"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Engine routes
|
|
136
|
+
def self.routes
|
|
137
|
+
@routes ||= ActionDispatch::Routing::RouteSet.new.tap do |routes|
|
|
138
|
+
routes.draw do
|
|
139
|
+
get "/", to: "synthra/api#index"
|
|
140
|
+
get "/schemas", to: "synthra/api#schemas"
|
|
141
|
+
get "/:schema", to: "synthra/api#generate"
|
|
142
|
+
get "/:schema/batch", to: "synthra/api#batch"
|
|
143
|
+
get "/:schema/stream", to: "synthra/api#stream"
|
|
144
|
+
post "/:schema", to: "synthra/api#create"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def find_schema_directory(root)
|
|
152
|
+
SCHEMA_PATHS.each do |path|
|
|
153
|
+
full_path = root.join(path)
|
|
154
|
+
return full_path if Dir.exist?(full_path)
|
|
155
|
+
end
|
|
156
|
+
nil
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Factory Bot bridge for automatic integration
|
|
161
|
+
module FactoryBotBridge
|
|
162
|
+
class << self
|
|
163
|
+
def integrate!
|
|
164
|
+
return unless defined?(FactoryBot)
|
|
165
|
+
|
|
166
|
+
# Add Synthra strategy to Factory Bot
|
|
167
|
+
FactoryBot.register_strategy(:fake_data, FakeDataStrategy)
|
|
168
|
+
|
|
169
|
+
# Auto-define factories for all schemas
|
|
170
|
+
Synthra.registry.names.each do |name|
|
|
171
|
+
define_factory_for(name)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def define_factory_for(schema_name)
|
|
176
|
+
factory_name = schema_name.underscore.to_sym
|
|
177
|
+
schema = Synthra.registry.schema(schema_name)
|
|
178
|
+
|
|
179
|
+
FactoryBot.define do
|
|
180
|
+
factory factory_name, class: OpenStruct do
|
|
181
|
+
transient do
|
|
182
|
+
fake_data_seed { nil }
|
|
183
|
+
fake_data_mode { :random }
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
initialize_with do
|
|
187
|
+
data = Synthra.registry.schema(schema_name.to_s).generate(
|
|
188
|
+
seed: fake_data_seed,
|
|
189
|
+
mode: fake_data_mode
|
|
190
|
+
)
|
|
191
|
+
OpenStruct.new(data)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
rescue FactoryBot::DuplicateDefinitionError
|
|
196
|
+
# Factory already exists, skip
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Custom Factory Bot strategy
|
|
201
|
+
class FakeDataStrategy
|
|
202
|
+
def association(runner)
|
|
203
|
+
runner.run
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def result(evaluation)
|
|
207
|
+
evaluation.object
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Test helpers for RSpec and Minitest
|
|
213
|
+
module TestHelpers
|
|
214
|
+
extend ActiveSupport::Concern
|
|
215
|
+
|
|
216
|
+
# Generate fake data for a schema
|
|
217
|
+
#
|
|
218
|
+
# @param schema_name [String, Symbol] schema name
|
|
219
|
+
# @param options [Hash] generation options
|
|
220
|
+
# @return [Hash] generated data
|
|
221
|
+
#
|
|
222
|
+
def fake_data(schema_name, **options)
|
|
223
|
+
Synthra.generate(schema_name.to_s, **options)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Generate multiple fake data records
|
|
227
|
+
#
|
|
228
|
+
# @param schema_name [String, Symbol] schema name
|
|
229
|
+
# @param count [Integer] number of records
|
|
230
|
+
# @param options [Hash] generation options
|
|
231
|
+
# @return [Array<Hash>] generated data
|
|
232
|
+
#
|
|
233
|
+
def fake_data_list(schema_name, count = 10, **options)
|
|
234
|
+
Synthra.generate_many(schema_name.to_s, count, **options)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Shorthand accessor
|
|
238
|
+
#
|
|
239
|
+
# @example
|
|
240
|
+
# Synthra[:User]
|
|
241
|
+
# Synthra[:Order, seed: 42]
|
|
242
|
+
#
|
|
243
|
+
def Synthra.[](*args, **options)
|
|
244
|
+
if args.length == 1
|
|
245
|
+
generate(args.first.to_s, **options)
|
|
246
|
+
else
|
|
247
|
+
args.map { |name| generate(name.to_s, **options) }
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|