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
data/lib/synthra/api.rb
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Synthra Public API
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# This module contains all public API methods for Synthra.
|
|
8
|
+
# It's mixed into the main Synthra module to provide a clean interface.
|
|
9
|
+
#
|
|
10
|
+
# =============================================================================
|
|
11
|
+
|
|
12
|
+
module Synthra
|
|
13
|
+
# Valid generation modes, in dispatch order (see Generator::Modes). Exposed so callers can
|
|
14
|
+
# discover the accepted `mode:` values instead of guessing.
|
|
15
|
+
MODES = %i[random edge invalid hostile mixed].freeze
|
|
16
|
+
|
|
17
|
+
# Public API methods for Synthra
|
|
18
|
+
#
|
|
19
|
+
# This module is extended into Synthra to provide all public methods.
|
|
20
|
+
# Separating the API from configuration keeps the main module clean.
|
|
21
|
+
#
|
|
22
|
+
module API
|
|
23
|
+
# ========================================================================
|
|
24
|
+
# Configuration API
|
|
25
|
+
# ========================================================================
|
|
26
|
+
|
|
27
|
+
# Returns the global configuration instance
|
|
28
|
+
#
|
|
29
|
+
# @return [Configuration] the global configuration singleton
|
|
30
|
+
#
|
|
31
|
+
def configuration
|
|
32
|
+
@configuration ||= Configuration.new
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Configure Synthra with a block
|
|
36
|
+
#
|
|
37
|
+
# @yield [Configuration] the configuration object to modify
|
|
38
|
+
# @return [void]
|
|
39
|
+
#
|
|
40
|
+
def configure
|
|
41
|
+
yield(configuration)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Reset configuration to default values
|
|
45
|
+
#
|
|
46
|
+
# @return [void]
|
|
47
|
+
#
|
|
48
|
+
def reset_configuration!
|
|
49
|
+
@configuration = Configuration.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# ========================================================================
|
|
53
|
+
# Loading & Parsing API
|
|
54
|
+
# ========================================================================
|
|
55
|
+
|
|
56
|
+
# Load and parse a single DSL file
|
|
57
|
+
#
|
|
58
|
+
# @param path [String] path to the DSL file
|
|
59
|
+
# @return [Schema] the parsed schema object
|
|
60
|
+
# @raise [Errors::ParseError] if the DSL syntax is invalid
|
|
61
|
+
#
|
|
62
|
+
def load(path)
|
|
63
|
+
registry = Registry.new
|
|
64
|
+
registry.load_file(path)
|
|
65
|
+
registry.schemas.values.first
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Parse a DSL string and return the first schema
|
|
69
|
+
#
|
|
70
|
+
# @param source [String] DSL source code
|
|
71
|
+
# @return [Schema] the parsed schema object
|
|
72
|
+
#
|
|
73
|
+
def parse(source)
|
|
74
|
+
registry = Registry.new
|
|
75
|
+
registry.load_string(source)
|
|
76
|
+
registry.schemas.values.first
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Parse a DSL string and return ALL schemas it defines (not just the first).
|
|
80
|
+
#
|
|
81
|
+
# `parse`/`load` return a single schema for convenience, which silently drops the rest of a
|
|
82
|
+
# multi-schema file. Use these when a source may define more than one schema.
|
|
83
|
+
#
|
|
84
|
+
# @param source [String] DSL source code
|
|
85
|
+
# @return [Array<Schema>] every schema defined in the source
|
|
86
|
+
def parse_all(source)
|
|
87
|
+
registry = Registry.new
|
|
88
|
+
registry.load_string(source)
|
|
89
|
+
registry.schemas.values
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Load a DSL file and return ALL schemas it defines (not just the first).
|
|
93
|
+
#
|
|
94
|
+
# @param path [String] path to the DSL file
|
|
95
|
+
# @return [Array<Schema>] every schema defined in the file
|
|
96
|
+
def load_all(path)
|
|
97
|
+
registry = Registry.new
|
|
98
|
+
registry.load_file(path)
|
|
99
|
+
registry.schemas.values
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# ========================================================================
|
|
103
|
+
# Native Engine API
|
|
104
|
+
# ========================================================================
|
|
105
|
+
|
|
106
|
+
# Check if native Rust engine is available
|
|
107
|
+
#
|
|
108
|
+
# @return [Boolean] true if native extension is available
|
|
109
|
+
#
|
|
110
|
+
def native_available?
|
|
111
|
+
NativeEngine.available?
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Create a native engine for a schema
|
|
115
|
+
#
|
|
116
|
+
# @param schema [Schema] the schema to use
|
|
117
|
+
# @param locale [String] locale for data generation
|
|
118
|
+
# @return [NativeEngine] configured native engine
|
|
119
|
+
#
|
|
120
|
+
def native_engine(schema, locale: "en")
|
|
121
|
+
NativeEngine.new(schema, locale: locale)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Generate records using native engine
|
|
125
|
+
#
|
|
126
|
+
# @param schema_or_dsl [Schema, String] schema instance or DSL string
|
|
127
|
+
# @param count [Integer] number of records to generate
|
|
128
|
+
# @param seed [Integer, nil] random seed for reproducibility
|
|
129
|
+
# @param locale [String] locale for data generation
|
|
130
|
+
# @param threads [Integer, nil] number of threads
|
|
131
|
+
# @return [Array<Hash>] generated records
|
|
132
|
+
#
|
|
133
|
+
def generate_native(schema_or_dsl, count, seed: nil, locale: "en", threads: nil)
|
|
134
|
+
schema = schema_or_dsl.is_a?(String) ? parse(schema_or_dsl) : schema_or_dsl
|
|
135
|
+
engine = NativeEngine.new(schema, locale: locale, threads: threads)
|
|
136
|
+
engine.generate_many(count, seed: seed)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Generate records to file using native engine
|
|
140
|
+
#
|
|
141
|
+
# @param schema_or_dsl [Schema, String] schema instance or DSL string
|
|
142
|
+
# @param count [Integer] number of records to generate
|
|
143
|
+
# @param path [String] output file path
|
|
144
|
+
# @param seed [Integer, nil] random seed
|
|
145
|
+
# @param locale [String] locale for data generation
|
|
146
|
+
# @param format [String] output format: "jsonl", "json", "csv"
|
|
147
|
+
# @param threads [Integer, nil] number of threads
|
|
148
|
+
# @return [Integer] number of records written
|
|
149
|
+
#
|
|
150
|
+
def generate_native_to_file(schema_or_dsl, count, path, seed: nil, locale: "en", format: "jsonl", threads: nil)
|
|
151
|
+
schema = schema_or_dsl.is_a?(String) ? parse(schema_or_dsl) : schema_or_dsl
|
|
152
|
+
engine = NativeEngine.new(schema, locale: locale, threads: threads)
|
|
153
|
+
engine.generate_to_file(count, path, seed: seed, format: format)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# ========================================================================
|
|
157
|
+
# Registration API
|
|
158
|
+
# ========================================================================
|
|
159
|
+
|
|
160
|
+
# Register a custom type generator
|
|
161
|
+
#
|
|
162
|
+
# @param name [String, Symbol] the type name to use in DSL files
|
|
163
|
+
# @param klass [Class, nil] optional class inheriting from Types::Base
|
|
164
|
+
# @yield [rng, context, args, mode] block for generating values
|
|
165
|
+
# @return [void]
|
|
166
|
+
#
|
|
167
|
+
def register_type(name, klass = nil, &block)
|
|
168
|
+
Types::Registry.register(name.to_s, klass, &block)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Register a custom function for computed fields
|
|
172
|
+
#
|
|
173
|
+
# @param name [Symbol] the function name
|
|
174
|
+
# @param force [Boolean] if true, overwrites existing function
|
|
175
|
+
# @yield [context] block that computes the value
|
|
176
|
+
# @return [void]
|
|
177
|
+
#
|
|
178
|
+
def register_function(name, force: false, &block)
|
|
179
|
+
Functions::Registry.register(name, force: force, &block)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Register a custom behavior
|
|
183
|
+
#
|
|
184
|
+
# @param name [Symbol] the behavior name
|
|
185
|
+
# @param klass [Class, nil] optional class inheriting from Behaviors::Base
|
|
186
|
+
# @yield [result, context, value] block for applying behavior
|
|
187
|
+
# @return [void]
|
|
188
|
+
#
|
|
189
|
+
def register_behavior(name, klass = nil, &block)
|
|
190
|
+
Behaviors::Registry.register(name, klass, &block)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# ========================================================================
|
|
194
|
+
# Export API - Schema Exports
|
|
195
|
+
# ========================================================================
|
|
196
|
+
|
|
197
|
+
# Export schema to JSON Schema format
|
|
198
|
+
def to_json_schema(schema, registry: nil)
|
|
199
|
+
Export::JsonSchema.new(schema, registry: registry).export
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Export schema to TypeScript interface
|
|
203
|
+
def to_typescript(schema, registry: nil, comments: false)
|
|
204
|
+
Export::Typescript.new(schema, registry: registry, comments: comments).export
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Export all schemas to TypeScript
|
|
208
|
+
def to_typescript_all(registry)
|
|
209
|
+
Export::Typescript.export_all(registry)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Export schema to SQL CREATE TABLE
|
|
213
|
+
def to_sql(schema, registry: nil, dialect: :postgresql)
|
|
214
|
+
Export::Sql.new(schema, registry: registry, dialect: dialect).export
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Export all schemas to SQL
|
|
218
|
+
def to_sql_all(registry, dialect: :postgresql)
|
|
219
|
+
Export::Sql.export_all(registry, dialect: dialect)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Export schema to GraphViz DOT format
|
|
223
|
+
def to_graphviz(schema = nil, registry: nil, direction: "LR", group: false)
|
|
224
|
+
Export::Graphviz.new(schema, registry: registry, direction: direction, group: group).export
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Export schema to JavaScript with JSDoc
|
|
228
|
+
def to_javascript(schema, registry: nil)
|
|
229
|
+
Export::Javascript.new(schema, registry: registry).export
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Export all schemas to JavaScript
|
|
233
|
+
def to_javascript_all(registry)
|
|
234
|
+
Export::Javascript.export_all(registry)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Export schema to Python
|
|
238
|
+
def to_python(schema, registry: nil, style: :pydantic)
|
|
239
|
+
Export::Python.new(schema, registry: registry, style: style).export
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Export all schemas to Python
|
|
243
|
+
def to_python_all(registry, style: :pydantic)
|
|
244
|
+
Export::Python.export_all(registry, style: style)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Export schema to GraphQL
|
|
248
|
+
def to_graphql(schema, registry: nil)
|
|
249
|
+
Export::Graphql.new(schema, registry: registry).export
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Export all schemas to GraphQL
|
|
253
|
+
def to_graphql_all(registry)
|
|
254
|
+
Export::Graphql.export_all(registry)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# ========================================================================
|
|
258
|
+
# Export API - Data Exports
|
|
259
|
+
# ========================================================================
|
|
260
|
+
|
|
261
|
+
# Export generated data as CSV
|
|
262
|
+
def to_csv(schema, registry: nil, count: 10, seed: nil, mode: :random)
|
|
263
|
+
Export::Csv.new(schema, registry: registry, count: count, seed: seed, mode: mode).export
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Export generated data as JSON
|
|
267
|
+
def to_json(schema, registry: nil, count: 10, seed: nil, mode: :random, pretty: true, envelope: nil)
|
|
268
|
+
Export::JsonData.new(schema, registry: registry, count: count, seed: seed, mode: mode, pretty: pretty, envelope: envelope).export
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Export generated data as SQL INSERT statements
|
|
272
|
+
def to_sql_insert(schema, registry: nil, count: 10, seed: nil, dialect: :postgresql, batch_insert: false)
|
|
273
|
+
Export::SqlInsert.new(schema, registry: registry, count: count, seed: seed, dialect: dialect, batch_insert: batch_insert).export
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Export generated data as YAML
|
|
277
|
+
def to_yaml(schema, registry: nil, count: 10, seed: nil, root_key: nil)
|
|
278
|
+
Export::YamlData.new(schema, registry: registry, count: count, seed: seed, root_key: root_key).export
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Export generated data as XML
|
|
282
|
+
def to_xml(schema, registry: nil, count: 10, seed: nil, root: nil, item: nil)
|
|
283
|
+
Export::XmlData.new(schema, registry: registry, count: count, seed: seed, root: root, item: item).export
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# ========================================================================
|
|
287
|
+
# Export Utilities
|
|
288
|
+
# ========================================================================
|
|
289
|
+
|
|
290
|
+
# Export to file with auto-generated filename
|
|
291
|
+
def export_to_file(format, schema, output_dir: ".", **options)
|
|
292
|
+
Export.export_to_file(format, schema, output_dir: output_dir, **options)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Get file extension for export format
|
|
296
|
+
def export_extension(format)
|
|
297
|
+
Export.file_extension(format)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Generate auto filename for export
|
|
301
|
+
def export_filename(schema_name, format)
|
|
302
|
+
Export.auto_filename(schema_name, format)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Export to any supported format
|
|
306
|
+
def export(format, schema, **options)
|
|
307
|
+
Export.export(format, schema, **options)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# List available export formats
|
|
311
|
+
def export_formats
|
|
312
|
+
Export.available_formats
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# List schema export formats
|
|
316
|
+
def schema_export_formats
|
|
317
|
+
Export.schema_formats
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# List data export formats
|
|
321
|
+
def data_export_formats
|
|
322
|
+
Export.data_formats
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# ========================================================================
|
|
326
|
+
# Factory Bot Integration
|
|
327
|
+
# ========================================================================
|
|
328
|
+
|
|
329
|
+
# Define a factory using a Synthra schema
|
|
330
|
+
#
|
|
331
|
+
# @param factory_name [Symbol] the factory name
|
|
332
|
+
# @param schema [String] schema name
|
|
333
|
+
# @yield block for defining traits and overrides
|
|
334
|
+
# @return [void]
|
|
335
|
+
#
|
|
336
|
+
# @example
|
|
337
|
+
# Synthra.define_factory(:user, schema: "User") do
|
|
338
|
+
# trait(:admin) { role { "admin" } }
|
|
339
|
+
# end
|
|
340
|
+
#
|
|
341
|
+
def define_factory(factory_name, schema:, &block)
|
|
342
|
+
FactoryBotIntegration.define_factory(factory_name, schema: schema, &block)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# ========================================================================
|
|
346
|
+
# Snapshot Testing
|
|
347
|
+
# ========================================================================
|
|
348
|
+
|
|
349
|
+
# Iterate over all loaded schemas
|
|
350
|
+
#
|
|
351
|
+
# @yield [schema] block to execute for each schema
|
|
352
|
+
#
|
|
353
|
+
def each_schema(&block)
|
|
354
|
+
return enum_for(:each_schema) unless block_given?
|
|
355
|
+
|
|
356
|
+
@default_registry ||= Registry.new
|
|
357
|
+
@default_registry.schemas.each_value(&block)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# Load schemas into default registry for iteration
|
|
361
|
+
#
|
|
362
|
+
# @param path [String] path to schema file or directory
|
|
363
|
+
#
|
|
364
|
+
def load_schemas(path)
|
|
365
|
+
@default_registry ||= Registry.new
|
|
366
|
+
if File.directory?(path)
|
|
367
|
+
@default_registry.load_dir(path)
|
|
368
|
+
else
|
|
369
|
+
@default_registry.load_file(path)
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# Access the default registry
|
|
374
|
+
#
|
|
375
|
+
# @return [Registry] the default schema registry
|
|
376
|
+
#
|
|
377
|
+
def registry
|
|
378
|
+
@default_registry ||= Registry.new
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|