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.
Files changed (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -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