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,651 @@
1
+ # GraphQL Federation Export
2
+
3
+ FakeDataDSL can export your schemas to **GraphQL Federation 2.0** compatible SDL, perfect for microservices architectures using Apollo Federation, Netflix DGS, or other federated GraphQL implementations.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Export single schema
9
+ fake_data_dsl export schemas/user.dsl -f graphql-federation -o user.graphql
10
+
11
+ # Export all schemas
12
+ fake_data_dsl export schemas/ --all -f graphql-federation -o schema.graphql
13
+ ```
14
+
15
+ ```ruby
16
+ # Ruby API
17
+ schema = FakeDataDSL.load("schemas/user.dsl")
18
+ graphql = FakeDataDSL::Export::GraphQLFederation.new(schema).export
19
+
20
+ puts graphql
21
+ ```
22
+
23
+ ## Basic Usage
24
+
25
+ ### Single Schema Export
26
+
27
+ ```ruby
28
+ # Input schema (user.dsl)
29
+ # User:
30
+ # id: uuid
31
+ # name: name
32
+ # email: email
33
+ # role: enum(user, admin, moderator)
34
+ # active: boolean
35
+ # created_at: timestamp
36
+
37
+ schema = FakeDataDSL.load("schemas/user.dsl")
38
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema)
39
+ puts exporter.export
40
+ ```
41
+
42
+ Output:
43
+
44
+ ```graphql
45
+ extend schema
46
+ @link(url: "https://specs.apollo.dev/federation/v2.0")
47
+
48
+ type User @key(fields: "id") {
49
+ id: ID!
50
+ name: String!
51
+ email: String!
52
+ role: UserRole!
53
+ active: Boolean!
54
+ created_at: DateTime!
55
+ }
56
+
57
+ enum UserRole {
58
+ USER
59
+ ADMIN
60
+ MODERATOR
61
+ }
62
+
63
+ extend type Query {
64
+ user(id: ID!): User
65
+ users(first: Int, after: String): UserConnection!
66
+ }
67
+
68
+ type UserConnection {
69
+ edges: [UserEdge!]!
70
+ pageInfo: PageInfo!
71
+ }
72
+
73
+ type UserEdge {
74
+ node: User!
75
+ cursor: String!
76
+ }
77
+
78
+ type PageInfo {
79
+ hasNextPage: Boolean!
80
+ hasPreviousPage: Boolean!
81
+ startCursor: String
82
+ endCursor: String
83
+ }
84
+ ```
85
+
86
+ ### Multiple Schemas
87
+
88
+ ```ruby
89
+ # Export multiple schemas as one federated graph
90
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(
91
+ FakeDataDSL.load("schemas/user.dsl"),
92
+ FakeDataDSL.load("schemas/order.dsl"),
93
+ FakeDataDSL.load("schemas/product.dsl")
94
+ )
95
+
96
+ puts exporter.export
97
+ ```
98
+
99
+ ## Federation Directives
100
+
101
+ ### @key Directive
102
+
103
+ Entity keys are automatically inferred from `id` fields or fields marked with `@key`:
104
+
105
+ ```ruby
106
+ # In DSL
107
+ User:
108
+ id: uuid @key
109
+ email: email @key # Additional key
110
+
111
+ # Output
112
+ type User @key(fields: "id") @key(fields: "email") {
113
+ id: ID!
114
+ email: String!
115
+ }
116
+ ```
117
+
118
+ ### @external and @provides
119
+
120
+ For cross-service references:
121
+
122
+ ```ruby
123
+ # In DSL
124
+ Order:
125
+ id: uuid
126
+ user_id: Ref(User.id) # Reference to User service
127
+ items: array(OrderItem, 1..10)
128
+ total: money
129
+
130
+ # Configure federation
131
+ FakeDataDSL::Export::GraphQLFederation.configure do |config|
132
+ config.external_types = ["User"]
133
+ config.provides = {
134
+ "Order" => { "user" => "id name email" }
135
+ }
136
+ end
137
+ ```
138
+
139
+ Output:
140
+
141
+ ```graphql
142
+ type Order @key(fields: "id") {
143
+ id: ID!
144
+ user: User! @provides(fields: "id name email")
145
+ items: [OrderItem!]!
146
+ total: Float!
147
+ }
148
+
149
+ type User @key(fields: "id", resolvable: false) @external {
150
+ id: ID!
151
+ }
152
+ ```
153
+
154
+ ### @shareable
155
+
156
+ Mark types as shareable across services:
157
+
158
+ ```ruby
159
+ # In DSL
160
+ Address:
161
+ @shareable
162
+ street: text
163
+ city: city
164
+ country: country
165
+ ```
166
+
167
+ Output:
168
+
169
+ ```graphql
170
+ type Address @shareable {
171
+ street: String!
172
+ city: String!
173
+ country: String!
174
+ }
175
+ ```
176
+
177
+ ## Subgraph Configuration
178
+
179
+ ### Service Definition
180
+
181
+ ```ruby
182
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
183
+ service_name: "users-service",
184
+ service_url: "https://users.example.com/graphql",
185
+ version: "2.0"
186
+ )
187
+ ```
188
+
189
+ ### Multiple Subgraphs
190
+
191
+ Generate separate files for each subgraph:
192
+
193
+ ```ruby
194
+ # Define subgraph boundaries
195
+ subgraphs = {
196
+ "users" => ["User", "Profile"],
197
+ "orders" => ["Order", "OrderItem"],
198
+ "products" => ["Product", "Category"]
199
+ }
200
+
201
+ subgraphs.each do |name, types|
202
+ schemas = types.map { |t| FakeDataDSL.schema(t) }
203
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(*schemas,
204
+ service_name: "#{name}-service"
205
+ )
206
+
207
+ File.write("subgraphs/#{name}.graphql", exporter.export)
208
+ end
209
+ ```
210
+
211
+ ## Type Mapping
212
+
213
+ ### DSL to GraphQL Types
214
+
215
+ | DSL Type | GraphQL Type |
216
+ |----------|--------------|
217
+ | `uuid` | `ID!` |
218
+ | `text`, `name`, `email` | `String!` |
219
+ | `number` | `Int!` |
220
+ | `float`, `money` | `Float!` |
221
+ | `boolean` | `Boolean!` |
222
+ | `date` | `Date!` |
223
+ | `timestamp` | `DateTime!` |
224
+ | `enum(...)` | Custom Enum |
225
+ | `array(...)` | `[Type!]!` |
226
+ | `optional` (`?`) | Nullable |
227
+ | `json` | `JSON` (custom scalar) |
228
+
229
+ ### Custom Scalars
230
+
231
+ ```ruby
232
+ FakeDataDSL::Export::GraphQLFederation.configure do |config|
233
+ config.custom_scalars = {
234
+ "date" => "Date",
235
+ "timestamp" => "DateTime",
236
+ "json" => "JSON",
237
+ "money" => "BigDecimal",
238
+ "url" => "URL",
239
+ "email" => "Email"
240
+ }
241
+ end
242
+ ```
243
+
244
+ Output includes scalar definitions:
245
+
246
+ ```graphql
247
+ scalar Date
248
+ scalar DateTime
249
+ scalar JSON
250
+ scalar BigDecimal
251
+ scalar URL
252
+ scalar Email
253
+ ```
254
+
255
+ ## Mutations
256
+
257
+ ### Auto-Generated Mutations
258
+
259
+ ```ruby
260
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
261
+ generate_mutations: true
262
+ )
263
+ ```
264
+
265
+ Output:
266
+
267
+ ```graphql
268
+ extend type Mutation {
269
+ createUser(input: CreateUserInput!): User!
270
+ updateUser(id: ID!, input: UpdateUserInput!): User!
271
+ deleteUser(id: ID!): Boolean!
272
+ }
273
+
274
+ input CreateUserInput {
275
+ name: String!
276
+ email: String!
277
+ role: UserRole
278
+ active: Boolean
279
+ }
280
+
281
+ input UpdateUserInput {
282
+ name: String
283
+ email: String
284
+ role: UserRole
285
+ active: Boolean
286
+ }
287
+ ```
288
+
289
+ ### Custom Mutations
290
+
291
+ ```ruby
292
+ # In DSL with @mutation annotation
293
+ User:
294
+ id: uuid
295
+ name: name
296
+ email: email
297
+
298
+ @mutations
299
+ create: CreateUser(name!, email!, role?)
300
+ update: UpdateUser(id!, name?, email?, role?)
301
+ deactivate: DeactivateUser(id!, reason?)
302
+ ```
303
+
304
+ ## Subscriptions
305
+
306
+ ```ruby
307
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
308
+ generate_subscriptions: true
309
+ )
310
+ ```
311
+
312
+ Output:
313
+
314
+ ```graphql
315
+ extend type Subscription {
316
+ userCreated: User!
317
+ userUpdated(id: ID): User!
318
+ userDeleted: ID!
319
+ }
320
+ ```
321
+
322
+ ## Entity Resolution
323
+
324
+ ### _entities Query
325
+
326
+ Federation requires an `_entities` query for entity resolution:
327
+
328
+ ```ruby
329
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
330
+ include_entities_query: true # default: true
331
+ )
332
+ ```
333
+
334
+ Output:
335
+
336
+ ```graphql
337
+ union _Entity = User | Order | Product
338
+
339
+ type Query {
340
+ _entities(representations: [_Any!]!): [_Entity]!
341
+ _service: _Service!
342
+ }
343
+
344
+ type _Service {
345
+ sdl: String!
346
+ }
347
+
348
+ scalar _Any
349
+ ```
350
+
351
+ ## Interfaces and Unions
352
+
353
+ ### Interfaces
354
+
355
+ ```ruby
356
+ # In DSL
357
+ Node:
358
+ @interface
359
+ id: uuid
360
+
361
+ User < Node:
362
+ name: name
363
+ email: email
364
+
365
+ Product < Node:
366
+ title: text
367
+ price: money
368
+ ```
369
+
370
+ Output:
371
+
372
+ ```graphql
373
+ interface Node {
374
+ id: ID!
375
+ }
376
+
377
+ type User implements Node @key(fields: "id") {
378
+ id: ID!
379
+ name: String!
380
+ email: String!
381
+ }
382
+
383
+ type Product implements Node @key(fields: "id") {
384
+ id: ID!
385
+ title: String!
386
+ price: Float!
387
+ }
388
+ ```
389
+
390
+ ### Unions
391
+
392
+ ```ruby
393
+ # In DSL
394
+ SearchResult:
395
+ @union User | Product | Order
396
+ ```
397
+
398
+ Output:
399
+
400
+ ```graphql
401
+ union SearchResult = User | Product | Order
402
+
403
+ extend type Query {
404
+ search(query: String!): [SearchResult!]!
405
+ }
406
+ ```
407
+
408
+ ## Pagination
409
+
410
+ ### Relay-Style Connections
411
+
412
+ ```ruby
413
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
414
+ pagination_style: :relay # default
415
+ )
416
+ ```
417
+
418
+ Output:
419
+
420
+ ```graphql
421
+ type UserConnection {
422
+ edges: [UserEdge!]!
423
+ pageInfo: PageInfo!
424
+ totalCount: Int!
425
+ }
426
+
427
+ type UserEdge {
428
+ node: User!
429
+ cursor: String!
430
+ }
431
+ ```
432
+
433
+ ### Offset Pagination
434
+
435
+ ```ruby
436
+ exporter = FakeDataDSL::Export::GraphQLFederation.new(schema,
437
+ pagination_style: :offset
438
+ )
439
+ ```
440
+
441
+ Output:
442
+
443
+ ```graphql
444
+ type UserList {
445
+ items: [User!]!
446
+ total: Int!
447
+ offset: Int!
448
+ limit: Int!
449
+ }
450
+
451
+ extend type Query {
452
+ users(offset: Int, limit: Int): UserList!
453
+ }
454
+ ```
455
+
456
+ ## CLI Options
457
+
458
+ ```bash
459
+ fake_data_dsl export [SCHEMA_PATH] -f graphql-federation [OPTIONS]
460
+
461
+ Options:
462
+ -o, --output PATH Output file path
463
+ --service-name NAME Service name for subgraph
464
+ --service-url URL Service URL for federation
465
+ --federation-version VER Federation version (1 or 2, default: 2)
466
+ --no-mutations Don't generate mutations
467
+ --no-subscriptions Don't generate subscriptions
468
+ --no-pagination Don't generate connection types
469
+ --pagination-style STYLE Pagination style (relay or offset)
470
+ --external-types TYPES Comma-separated external type names
471
+ ```
472
+
473
+ Examples:
474
+
475
+ ```bash
476
+ # Basic export
477
+ fake_data_dsl export schemas/ -f graphql-federation -o schema.graphql
478
+
479
+ # With service configuration
480
+ fake_data_dsl export schemas/user.dsl -f graphql-federation \
481
+ --service-name users \
482
+ --service-url https://users.api.example.com/graphql \
483
+ -o users.graphql
484
+
485
+ # Minimal export (no mutations/subscriptions)
486
+ fake_data_dsl export schemas/ -f graphql-federation \
487
+ --no-mutations --no-subscriptions \
488
+ -o types-only.graphql
489
+ ```
490
+
491
+ ## API Reference
492
+
493
+ ### GraphQLFederation.new
494
+
495
+ ```ruby
496
+ FakeDataDSL::Export::GraphQLFederation.new(*schemas, options = {})
497
+ ```
498
+
499
+ **Parameters:**
500
+ - `schemas` - One or more Schema objects
501
+ - `options[:service_name]` - Subgraph service name
502
+ - `options[:service_url]` - Subgraph service URL
503
+ - `options[:version]` - Federation version ("1" or "2")
504
+ - `options[:generate_mutations]` - Include mutations (default: false)
505
+ - `options[:generate_subscriptions]` - Include subscriptions (default: false)
506
+ - `options[:pagination_style]` - :relay or :offset
507
+ - `options[:include_entities_query]` - Include _entities (default: true)
508
+ - `options[:external_types]` - Array of external type names
509
+ - `options[:custom_scalars]` - Hash of DSL type => GraphQL scalar
510
+
511
+ ### GraphQLFederation#export
512
+
513
+ ```ruby
514
+ exporter.export
515
+ # => String containing complete GraphQL SDL
516
+ ```
517
+
518
+ ### GraphQLFederation#export_to_file
519
+
520
+ ```ruby
521
+ exporter.export_to_file("schema.graphql")
522
+ ```
523
+
524
+ ## Integration Examples
525
+
526
+ ### Apollo Router
527
+
528
+ ```yaml
529
+ # supergraph.yaml
530
+ federation_version: 2
531
+ subgraphs:
532
+ users:
533
+ routing_url: https://users.example.com/graphql
534
+ schema:
535
+ file: ./users.graphql # Generated by FakeDataDSL
536
+ orders:
537
+ routing_url: https://orders.example.com/graphql
538
+ schema:
539
+ file: ./orders.graphql
540
+ ```
541
+
542
+ ### Netflix DGS
543
+
544
+ ```kotlin
545
+ // The generated schema works with DGS
546
+ @DgsComponent
547
+ class UserDataFetcher {
548
+ @DgsQuery
549
+ fun user(@InputArgument id: String): User {
550
+ // Resolver implementation
551
+ }
552
+
553
+ @DgsEntityFetcher(name = "User")
554
+ fun user(values: Map<String, Any>): User {
555
+ // Entity resolver for federation
556
+ }
557
+ }
558
+ ```
559
+
560
+ ### Apollo Server
561
+
562
+ ```javascript
563
+ // The generated schema works with Apollo Server
564
+ import { buildSubgraphSchema } from '@apollo/subgraph';
565
+ import { readFileSync } from 'fs';
566
+
567
+ const typeDefs = gql(readFileSync('./user.graphql', 'utf8'));
568
+
569
+ const server = new ApolloServer({
570
+ schema: buildSubgraphSchema({ typeDefs, resolvers })
571
+ });
572
+ ```
573
+
574
+ ## Best Practices
575
+
576
+ ### 1. One Entity Per Service
577
+
578
+ ```ruby
579
+ # Good: Clear ownership
580
+ # users-service owns User, Profile
581
+ # orders-service owns Order, OrderItem
582
+
583
+ # Avoid: Shared ownership
584
+ # Both services define User (unless @shareable)
585
+ ```
586
+
587
+ ### 2. Use @key Thoughtfully
588
+
589
+ ```ruby
590
+ # Good: Natural keys
591
+ User:
592
+ id: uuid @key
593
+ email: email @key # Secondary lookup
594
+
595
+ # Avoid: Composite keys when unnecessary
596
+ User:
597
+ id: uuid @key
598
+ tenant_id: uuid @key # Only if truly needed
599
+ ```
600
+
601
+ ### 3. Keep Schemas Aligned
602
+
603
+ ```ruby
604
+ # Use the DSL as source of truth
605
+ # Generate GraphQL from DSL, not the other way around
606
+ ```
607
+
608
+ ## Troubleshooting
609
+
610
+ ### Missing @key Directive
611
+
612
+ ```ruby
613
+ # Make sure id field exists or add @key annotation
614
+ User:
615
+ id: uuid # Auto-detected as key
616
+
617
+ # Or explicit
618
+ User:
619
+ user_id: uuid @key # Explicit key
620
+ ```
621
+
622
+ ### Enum Name Conflicts
623
+
624
+ ```ruby
625
+ # Use namespaced enums
626
+ User:
627
+ status: enum(active, inactive) @enum_name(UserStatus)
628
+
629
+ Product:
630
+ status: enum(draft, published) @enum_name(ProductStatus)
631
+ ```
632
+
633
+ ### Circular References
634
+
635
+ ```ruby
636
+ # Federation handles this via external types
637
+ # User service:
638
+ User:
639
+ orders: array(Ref(Order))
640
+
641
+ # Order service:
642
+ Order:
643
+ user: Ref(User) @external
644
+ ```
645
+
646
+ ## See Also
647
+
648
+ - [GraphQL Export](GRAPHQL_EXPORT.md) - Standard GraphQL (non-federated)
649
+ - [OpenAPI Export](OPENAPI_EXPORT.md)
650
+ - [Protobuf Export](PROTOBUF_EXPORT.md)
651
+ - [Type Reference](type_reference.md)