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,96 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
# Read each broken file, extract classes, and rewrite properly
|
|
9
|
+
Dir.glob(File.join(BASE, '*/*.rb')).sort.each do |file_path|
|
|
10
|
+
next if File.basename(file_path) == 'national_id.rb' # Already fixed
|
|
11
|
+
|
|
12
|
+
content = File.read(file_path)
|
|
13
|
+
|
|
14
|
+
# Extract all class definitions with their bodies
|
|
15
|
+
classes = []
|
|
16
|
+
content.scan(/class\s+(\w+)\s*<\s*Base\s*\n(.*?)(?=\n\s*class\s+\w+\s*<\s*Base|\n\s*end\s*$|\Z)/m) do |class_name, class_body|
|
|
17
|
+
classes << { name: class_name, body: class_body }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# If no classes found, try a different pattern
|
|
21
|
+
if classes.empty?
|
|
22
|
+
# Try to find classes by looking for "class Name < Base" patterns
|
|
23
|
+
lines = content.lines
|
|
24
|
+
current_class = nil
|
|
25
|
+
class_lines = []
|
|
26
|
+
in_class = false
|
|
27
|
+
|
|
28
|
+
lines.each do |line|
|
|
29
|
+
if line =~ /class\s+(\w+)\s*<\s*Base/
|
|
30
|
+
if current_class
|
|
31
|
+
classes << { name: current_class, body: class_lines.join }
|
|
32
|
+
end
|
|
33
|
+
current_class = $1
|
|
34
|
+
class_lines = []
|
|
35
|
+
in_class = true
|
|
36
|
+
elsif in_class
|
|
37
|
+
if line.strip == 'end' && class_lines.count { |l| l.strip == 'end' } >= 1
|
|
38
|
+
# End of class
|
|
39
|
+
classes << { name: current_class, body: class_lines.join }
|
|
40
|
+
current_class = nil
|
|
41
|
+
in_class = false
|
|
42
|
+
class_lines = []
|
|
43
|
+
else
|
|
44
|
+
class_lines << line
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if current_class && !class_lines.empty?
|
|
50
|
+
classes << { name: current_class, body: class_lines.join }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Rebuild file
|
|
55
|
+
if !classes.empty?
|
|
56
|
+
rebuilt = "# frozen_string_literal: true\n\nmodule FakeDataDSL\n module Types\n"
|
|
57
|
+
|
|
58
|
+
classes.each do |cls|
|
|
59
|
+
rebuilt += "\n # #{cls[:name]} type\n"
|
|
60
|
+
rebuilt += " class #{cls[:name]} < Base\n"
|
|
61
|
+
|
|
62
|
+
# Fix indentation of class body
|
|
63
|
+
cls[:body].lines.each do |line|
|
|
64
|
+
if line.strip.empty?
|
|
65
|
+
rebuilt += "\n"
|
|
66
|
+
elsif line.strip.start_with?('#')
|
|
67
|
+
rebuilt += " #{line.lstrip}\n"
|
|
68
|
+
else
|
|
69
|
+
# Ensure proper indentation (6 spaces for method body)
|
|
70
|
+
current_indent = line[/\A */].size
|
|
71
|
+
if current_indent < 6 && line.strip != 'end'
|
|
72
|
+
rebuilt += " #{line.lstrip}\n"
|
|
73
|
+
else
|
|
74
|
+
rebuilt += line
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
rebuilt += " end\n"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
rebuilt += " end\nend\n"
|
|
83
|
+
|
|
84
|
+
File.write(file_path, rebuilt)
|
|
85
|
+
|
|
86
|
+
# Verify
|
|
87
|
+
result = `ruby -c "#{file_path}" 2>&1`
|
|
88
|
+
if result.include?("Syntax OK")
|
|
89
|
+
puts " ā
#{File.basename(File.dirname(file_path))}/#{File.basename(file_path)}"
|
|
90
|
+
else
|
|
91
|
+
puts " ā #{File.basename(File.dirname(file_path))}/#{File.basename(file_path)}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
puts "ā
Batch fix complete"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
# Delete old grouped files
|
|
9
|
+
old_files = %w[
|
|
10
|
+
address_location_types.rb
|
|
11
|
+
finance_banking_types.rb
|
|
12
|
+
technology_internet_types.rb
|
|
13
|
+
commerce_product_types.rb
|
|
14
|
+
media_entertainment_types.rb
|
|
15
|
+
personal_names_types.rb
|
|
16
|
+
text_content_types.rb
|
|
17
|
+
datetime.rb
|
|
18
|
+
hash.rb
|
|
19
|
+
time.rb
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
deleted = 0
|
|
23
|
+
old_files.each do |file|
|
|
24
|
+
path = File.join(BASE, file)
|
|
25
|
+
if File.exist?(path)
|
|
26
|
+
File.delete(path)
|
|
27
|
+
puts "ā
Deleted #{file}"
|
|
28
|
+
deleted += 1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
puts "\nā
Deleted #{deleted} old files"
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
def fix_grouped_file(file_path)
|
|
9
|
+
content = File.read(file_path)
|
|
10
|
+
lines = content.lines
|
|
11
|
+
fixed = []
|
|
12
|
+
in_class = false
|
|
13
|
+
in_method = false
|
|
14
|
+
class_name = nil
|
|
15
|
+
method_name = nil
|
|
16
|
+
depth = 0
|
|
17
|
+
class_indent = 0
|
|
18
|
+
|
|
19
|
+
i = 0
|
|
20
|
+
while i < lines.length
|
|
21
|
+
line = lines[i]
|
|
22
|
+
stripped = line.strip
|
|
23
|
+
indent = line[/\A */].size
|
|
24
|
+
|
|
25
|
+
# Class definition
|
|
26
|
+
if stripped =~ /^class\s+(\w+)\s*<\s*Base/
|
|
27
|
+
if in_class
|
|
28
|
+
# Close previous class
|
|
29
|
+
fixed << " end\n"
|
|
30
|
+
end
|
|
31
|
+
class_name = $1
|
|
32
|
+
in_class = true
|
|
33
|
+
in_method = false
|
|
34
|
+
class_indent = indent
|
|
35
|
+
fixed << " class #{class_name} < Base\n"
|
|
36
|
+
depth = 1
|
|
37
|
+
i += 1
|
|
38
|
+
next
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Method definition
|
|
42
|
+
if stripped =~ /^\s*def\s+(\w+)/
|
|
43
|
+
method_name = $1
|
|
44
|
+
in_method = true
|
|
45
|
+
# Ensure proper indentation (6 spaces for method in class)
|
|
46
|
+
fixed << " #{stripped}\n"
|
|
47
|
+
depth += 1
|
|
48
|
+
i += 1
|
|
49
|
+
next
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# 'end' statement
|
|
53
|
+
if stripped == 'end'
|
|
54
|
+
if depth > 0
|
|
55
|
+
depth -= 1
|
|
56
|
+
if depth == 0 && in_class
|
|
57
|
+
in_class = false
|
|
58
|
+
in_method = false
|
|
59
|
+
fixed << " end\n"
|
|
60
|
+
else
|
|
61
|
+
# Method or block end
|
|
62
|
+
fixed << " end\n"
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
fixed << line
|
|
66
|
+
end
|
|
67
|
+
i += 1
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Regular line - fix indentation
|
|
72
|
+
if in_class
|
|
73
|
+
if stripped.empty?
|
|
74
|
+
fixed << "\n"
|
|
75
|
+
elsif stripped.start_with?('#')
|
|
76
|
+
# Comments - preserve relative indentation but ensure minimum
|
|
77
|
+
if indent >= class_indent
|
|
78
|
+
fixed << " #{stripped}\n"
|
|
79
|
+
else
|
|
80
|
+
fixed << " #{line.lstrip}\n"
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
# Code - ensure 6 space indent (2 for module + 2 for class + 2 for method)
|
|
84
|
+
if indent < 6 && !stripped.start_with?('#')
|
|
85
|
+
fixed << " #{line.lstrip}\n"
|
|
86
|
+
else
|
|
87
|
+
fixed << line
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
fixed << line
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
i += 1
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Close any open class
|
|
98
|
+
if in_class
|
|
99
|
+
fixed << " end\n"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Ensure module ends
|
|
103
|
+
if fixed.join !~ /\n\s*end\s*\n\s*end\s*$/
|
|
104
|
+
fixed << " end\nend\n"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
File.write(file_path, fixed.join)
|
|
108
|
+
|
|
109
|
+
# Verify syntax
|
|
110
|
+
result = `ruby -c "#{file_path}" 2>&1`
|
|
111
|
+
if result.include?("Syntax OK")
|
|
112
|
+
true
|
|
113
|
+
else
|
|
114
|
+
puts " ā #{File.basename(file_path)}: #{result.split("\n").first}"
|
|
115
|
+
false
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
puts "š§ Fixing syntax errors in grouped files...\n"
|
|
120
|
+
|
|
121
|
+
fixed_count = 0
|
|
122
|
+
error_count = 0
|
|
123
|
+
|
|
124
|
+
Dir.glob(File.join(BASE, '*/*.rb')).sort.each do |file|
|
|
125
|
+
domain = File.basename(File.dirname(file))
|
|
126
|
+
filename = File.basename(file)
|
|
127
|
+
|
|
128
|
+
if fix_grouped_file(file)
|
|
129
|
+
puts " ā
#{domain}/#{filename}"
|
|
130
|
+
fixed_count += 1
|
|
131
|
+
else
|
|
132
|
+
error_count += 1
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
puts "\nā
Fixed: #{fixed_count} files"
|
|
137
|
+
puts "ā Errors: #{error_count} files" if error_count > 0
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
# Fix indentation in all domain folder files
|
|
9
|
+
Dir.glob(File.join(BASE, '*/*.rb')).each do |file|
|
|
10
|
+
content = File.read(file)
|
|
11
|
+
original = content.dup
|
|
12
|
+
|
|
13
|
+
# Check if class definition is not properly indented
|
|
14
|
+
if content =~ /^class\s+\w+\s*<\s*Base/ || content =~ /^\s{0,3}class\s+\w+\s*<\s*Base/
|
|
15
|
+
lines = content.lines
|
|
16
|
+
fixed = []
|
|
17
|
+
in_class = false
|
|
18
|
+
class_indent = 4 # 4 spaces for class in module
|
|
19
|
+
|
|
20
|
+
lines.each_with_index do |line, idx|
|
|
21
|
+
# Module/end lines
|
|
22
|
+
if line =~ /^module\s+FakeDataDSL/ || line =~ /^module\s+Types/
|
|
23
|
+
fixed << line
|
|
24
|
+
elsif line =~ /^end\s*$/ && !in_class && idx > 0 && lines[idx-1] !~ /^\s+end/
|
|
25
|
+
fixed << line
|
|
26
|
+
# Class definition
|
|
27
|
+
elsif line =~ /^\s*class\s+(\w+)\s*<\s*Base/
|
|
28
|
+
fixed << " class #{$1} < Base\n"
|
|
29
|
+
in_class = true
|
|
30
|
+
# End of class
|
|
31
|
+
elsif line =~ /^\s*end\s*$/ && in_class
|
|
32
|
+
fixed << " end\n"
|
|
33
|
+
in_class = false
|
|
34
|
+
# Inside class - indent by 6 spaces (2 for module + 2 for class + 2 for method)
|
|
35
|
+
elsif in_class
|
|
36
|
+
# Remove leading whitespace and add proper indent
|
|
37
|
+
fixed << " #{line.lstrip}"
|
|
38
|
+
else
|
|
39
|
+
fixed << line
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
File.write(file, fixed.join)
|
|
44
|
+
puts "ā
Fixed #{File.basename(File.dirname(file))}/#{File.basename(file)}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
puts "ā
Fixed indentation in all domain folder files"
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
def fix_file(file_path)
|
|
9
|
+
content = File.read(file_path)
|
|
10
|
+
lines = content.lines
|
|
11
|
+
fixed = []
|
|
12
|
+
|
|
13
|
+
in_class = false
|
|
14
|
+
class_name = nil
|
|
15
|
+
class_start_idx = nil
|
|
16
|
+
depth = 0
|
|
17
|
+
|
|
18
|
+
i = 0
|
|
19
|
+
while i < lines.length
|
|
20
|
+
line = lines[i]
|
|
21
|
+
stripped = line.strip
|
|
22
|
+
|
|
23
|
+
# Class definition
|
|
24
|
+
if stripped =~ /^class\s+(\w+)\s*<\s*Base/
|
|
25
|
+
if in_class
|
|
26
|
+
# Close previous class
|
|
27
|
+
fixed << " end\n"
|
|
28
|
+
end
|
|
29
|
+
class_name = $1
|
|
30
|
+
in_class = true
|
|
31
|
+
class_start_idx = i
|
|
32
|
+
fixed << " class #{class_name} < Base\n"
|
|
33
|
+
depth = 1
|
|
34
|
+
i += 1
|
|
35
|
+
next
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Method definition
|
|
39
|
+
if stripped =~ /^\s*def\s+(\w+)/
|
|
40
|
+
fixed << " #{stripped}\n"
|
|
41
|
+
depth += 1
|
|
42
|
+
i += 1
|
|
43
|
+
next
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# 'end' statement
|
|
47
|
+
if stripped == 'end'
|
|
48
|
+
if depth > 1
|
|
49
|
+
depth -= 1
|
|
50
|
+
fixed << " end\n"
|
|
51
|
+
elsif depth == 1 && in_class
|
|
52
|
+
depth = 0
|
|
53
|
+
in_class = false
|
|
54
|
+
fixed << " end\n"
|
|
55
|
+
else
|
|
56
|
+
fixed << line
|
|
57
|
+
end
|
|
58
|
+
i += 1
|
|
59
|
+
next
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Regular line
|
|
63
|
+
if in_class
|
|
64
|
+
if stripped.empty?
|
|
65
|
+
fixed << "\n"
|
|
66
|
+
elsif stripped.start_with?('#')
|
|
67
|
+
fixed << " #{stripped}\n"
|
|
68
|
+
else
|
|
69
|
+
# Code line - ensure proper indentation
|
|
70
|
+
current_indent = line[/\A */].size
|
|
71
|
+
if current_indent < 6
|
|
72
|
+
fixed << " #{line.lstrip}\n"
|
|
73
|
+
else
|
|
74
|
+
fixed << line
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
fixed << line
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
i += 1
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Close any open class
|
|
85
|
+
if in_class
|
|
86
|
+
fixed << " end\n"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Ensure module ends
|
|
90
|
+
if fixed.join !~ /\n\s*end\s*\n\s*end\s*$/
|
|
91
|
+
fixed << " end\nend\n"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
File.write(file_path, fixed.join)
|
|
95
|
+
|
|
96
|
+
# Verify syntax
|
|
97
|
+
result = `ruby -c "#{file_path}" 2>&1`
|
|
98
|
+
if result.include?("Syntax OK")
|
|
99
|
+
true
|
|
100
|
+
else
|
|
101
|
+
puts " ā #{File.basename(file_path)}: #{result.split("\n").first(2).join(' ')}"
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
puts "š§ Fixing all grouped files...\n"
|
|
107
|
+
|
|
108
|
+
fixed = 0
|
|
109
|
+
errors = 0
|
|
110
|
+
|
|
111
|
+
Dir.glob(File.join(BASE, '*/*.rb')).sort.each do |file|
|
|
112
|
+
domain = File.basename(File.dirname(file))
|
|
113
|
+
filename = File.basename(file)
|
|
114
|
+
|
|
115
|
+
if fix_file(file)
|
|
116
|
+
puts " ā
#{domain}/#{filename}"
|
|
117
|
+
fixed += 1
|
|
118
|
+
else
|
|
119
|
+
errors += 1
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
puts "\nā
Fixed: #{fixed} files"
|
|
124
|
+
puts "ā Errors: #{errors} files" if errors > 0
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
BASE = File.join(__dir__, '..', 'lib', 'fake_data_dsl', 'types')
|
|
7
|
+
|
|
8
|
+
# Group types within each domain into logical files
|
|
9
|
+
DOMAIN_GROUPS = {
|
|
10
|
+
'address_location' => {
|
|
11
|
+
'addresses.rb' => %w[address address_line_2 street_name street_number street_suffix],
|
|
12
|
+
'locations.rb' => %w[city state country country_code postal_code latitude longitude timezone],
|
|
13
|
+
'airports.rb' => %w[airport_name airport_continent airport_country_code airport_elevation airport_gps_code airport_latitude airport_longitude airport_municipality airport_region_code],
|
|
14
|
+
'banks_hospitals.rb' => %w[bank_city bank_country_code bank_street_address bank_state hospital_city hospital_postal_code hospital_state hospital_street_address]
|
|
15
|
+
},
|
|
16
|
+
'finance_banking' => {
|
|
17
|
+
'identifiers.rb' => %w[ssn ein national_id nhs_number medicare_beneficiary_id duns_number],
|
|
18
|
+
'banking.rb' => %w[money currency credit_card bank_name account_number iban bank_routing_number bank_swift_bic bank_lei bank_riad_code transaction_amount],
|
|
19
|
+
'credit_cards.rb' => %w[credit_card_type]
|
|
20
|
+
},
|
|
21
|
+
'personal_names' => {
|
|
22
|
+
'names.rb' => %w[name first_name last_name full_name first_name_female first_name_male first_name_european],
|
|
23
|
+
'identifiers.rb' => %w[username age gender gender_abbrev gender_binary gender_facebook],
|
|
24
|
+
'titles_suffixes.rb' => %w[title suffix],
|
|
25
|
+
'chinese.rb' => %w[family_name_chinese given_name_chinese]
|
|
26
|
+
},
|
|
27
|
+
'technology_internet' => {
|
|
28
|
+
'communication.rb' => %w[email phone url domain user_agent],
|
|
29
|
+
'networking.rb' => %w[ip mac_address ip_v4_cidr ip_v6_cidr],
|
|
30
|
+
'apps.rb' => %w[app_bundle_id app_name app_version],
|
|
31
|
+
'devices.rb' => %w[mobile_device_brand mobile_device_model mobile_device_os mobile_device_release_date],
|
|
32
|
+
'formats.rb' => %w[language language_code mime_type top_level_domain base64_image_url dummy_image_url mongodb_object_id]
|
|
33
|
+
},
|
|
34
|
+
'commerce_products' => {
|
|
35
|
+
'products.rb' => %w[product_name product_category product_description product_price product_subcategory product_grocery sku],
|
|
36
|
+
'companies.rb' => %w[company_name job_title],
|
|
37
|
+
'commerce.rb' => %w[discount tax_rate shirt_size],
|
|
38
|
+
'construction.rb' => %w[construction_heavy_equipment construction_material construction_role construction_standard_cost_code construction_subcontract_category construction_trade]
|
|
39
|
+
},
|
|
40
|
+
'text_content' => {
|
|
41
|
+
'text_generation.rb' => %w[paragraphs sentences words],
|
|
42
|
+
'business.rb' => %w[buzzword catch_phrase slogan fake_company_name],
|
|
43
|
+
'colors.rb' => %w[color hex_color short_hex_color],
|
|
44
|
+
'security.rb' => %w[password password_hash md5 sha1 sha256 encrypt],
|
|
45
|
+
'misc.rb' => %w[avatar file_name frequency linked_in_skill nato_phonetic row_number sql_expression university blank race department_corporate department_retail]
|
|
46
|
+
},
|
|
47
|
+
'health_medical' => {
|
|
48
|
+
'medical.rb' => %w[blood_type bmi heart_rate medical_code]
|
|
49
|
+
},
|
|
50
|
+
'travel' => {
|
|
51
|
+
'travel.rb' => %w[airline airport_code flight_number seat_number]
|
|
52
|
+
},
|
|
53
|
+
'date_time' => {
|
|
54
|
+
'dates.rb' => %w[date_type datetime_type time_type timestamp now past_date future_date date_between]
|
|
55
|
+
},
|
|
56
|
+
'crypto' => {
|
|
57
|
+
'crypto.rb' => %w[bitcoin_address ethereum_address private_key hash_type]
|
|
58
|
+
},
|
|
59
|
+
'media_entertainment' => {
|
|
60
|
+
'media.rb' => %w[movie_genres movie_title]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
def extract_complete_class(file_path)
|
|
65
|
+
return nil unless File.exist?(file_path)
|
|
66
|
+
|
|
67
|
+
content = File.read(file_path)
|
|
68
|
+
|
|
69
|
+
# Find class definition
|
|
70
|
+
if content =~ /class\s+(\w+)\s*<\s*Base/
|
|
71
|
+
class_name = $1
|
|
72
|
+
class_start = content.index(/class\s+#{class_name}\s*<\s*Base/)
|
|
73
|
+
|
|
74
|
+
# Find matching end by tracking indentation
|
|
75
|
+
lines = content.lines
|
|
76
|
+
start_line_idx = content[0..class_start].lines.count - 1
|
|
77
|
+
class_indent = lines[start_line_idx][/\A */].size
|
|
78
|
+
|
|
79
|
+
depth = 1
|
|
80
|
+
end_line_idx = start_line_idx + 1
|
|
81
|
+
|
|
82
|
+
while end_line_idx < lines.length && depth > 0
|
|
83
|
+
line = lines[end_line_idx]
|
|
84
|
+
line_indent = line[/\A */].size
|
|
85
|
+
|
|
86
|
+
if line =~ /^\s*class\s+\w+\s*<\s*Base/
|
|
87
|
+
depth += 1
|
|
88
|
+
elsif line =~ /^\s*end\s*$/ && line_indent <= class_indent
|
|
89
|
+
depth -= 1
|
|
90
|
+
break if depth == 0
|
|
91
|
+
end
|
|
92
|
+
end_line_idx += 1
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if depth == 0
|
|
96
|
+
class_content = lines[start_line_idx..end_line_idx].join
|
|
97
|
+
# Remove leading module wrapper if present
|
|
98
|
+
class_content = class_content.gsub(/^\s*module\s+FakeDataDSL\s*\n\s*module\s+Types\s*\n/, '')
|
|
99
|
+
class_content = class_content.gsub(/\n\s*end\s*\n\s*end\s*$/, '')
|
|
100
|
+
{ name: class_name, content: class_content }
|
|
101
|
+
else
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def merge_files(domain, group_name, file_names)
|
|
110
|
+
domain_dir = File.join(BASE, domain)
|
|
111
|
+
return unless Dir.exist?(domain_dir)
|
|
112
|
+
|
|
113
|
+
merged_content = "# frozen_string_literal: true\n\nmodule FakeDataDSL\n module Types\n"
|
|
114
|
+
|
|
115
|
+
found_count = 0
|
|
116
|
+
file_names.each do |file_name|
|
|
117
|
+
# Try both snake_case variations
|
|
118
|
+
file_paths = [
|
|
119
|
+
File.join(domain_dir, "#{file_name}.rb"),
|
|
120
|
+
File.join(domain_dir, "#{file_name.gsub('_', '')}.rb")
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
class_info = nil
|
|
124
|
+
file_paths.each do |path|
|
|
125
|
+
if File.exist?(path)
|
|
126
|
+
class_info = extract_complete_class(path)
|
|
127
|
+
break if class_info
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
next unless class_info
|
|
132
|
+
|
|
133
|
+
# Add class with proper formatting
|
|
134
|
+
merged_content += "\n"
|
|
135
|
+
# Extract and add class definition, fixing indentation
|
|
136
|
+
class_lines = class_info[:content].lines
|
|
137
|
+
class_lines.each do |line|
|
|
138
|
+
if line.strip.empty?
|
|
139
|
+
merged_content += "\n"
|
|
140
|
+
else
|
|
141
|
+
# Ensure proper indentation (6 spaces for class body)
|
|
142
|
+
current_indent = line[/\A */].size
|
|
143
|
+
if line =~ /^\s*class\s+\w+\s*<\s*Base/
|
|
144
|
+
merged_content += " #{line.lstrip}"
|
|
145
|
+
elsif line =~ /^\s*end\s*$/ && current_indent <= 4
|
|
146
|
+
merged_content += " end\n"
|
|
147
|
+
else
|
|
148
|
+
# Preserve relative indentation but ensure minimum
|
|
149
|
+
if current_indent >= 4
|
|
150
|
+
merged_content += " #{line.lstrip}\n"
|
|
151
|
+
else
|
|
152
|
+
merged_content += " #{line}\n"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
found_count += 1
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
merged_content += " end\nend\n"
|
|
161
|
+
|
|
162
|
+
output_path = File.join(domain_dir, group_name)
|
|
163
|
+
File.write(output_path, merged_content)
|
|
164
|
+
puts " ā
Created #{domain}/#{group_name} (#{found_count}/#{file_names.size} types)"
|
|
165
|
+
|
|
166
|
+
found_count
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
puts "š Fixing grouped files...\n"
|
|
170
|
+
|
|
171
|
+
total_files = 0
|
|
172
|
+
total_types = 0
|
|
173
|
+
DOMAIN_GROUPS.each do |domain, groups|
|
|
174
|
+
puts "\nš #{domain}/"
|
|
175
|
+
groups.each do |group_file, file_names|
|
|
176
|
+
count = merge_files(domain, group_file, file_names)
|
|
177
|
+
total_files += 1
|
|
178
|
+
total_types += count if count
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
puts "\nā
Total grouped files: #{total_files}"
|
|
183
|
+
puts "ā
Total types grouped: #{total_types}"
|
|
184
|
+
|