otto 1.6.0 → 2.0.0.pre1

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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/claude-code-review.yml +53 -0
  4. data/.github/workflows/claude.yml +49 -0
  5. data/.gitignore +3 -0
  6. data/.rubocop.yml +24 -345
  7. data/CHANGELOG.rst +83 -0
  8. data/CLAUDE.md +56 -0
  9. data/Gemfile +10 -3
  10. data/Gemfile.lock +23 -28
  11. data/README.md +2 -0
  12. data/bin/rspec +4 -4
  13. data/changelog.d/20250911_235619_delano_next.rst +28 -0
  14. data/changelog.d/20250912_123055_delano_remove_ostruct.rst +21 -0
  15. data/changelog.d/20250912_175625_claude_delano_remove_ostruct.rst +21 -0
  16. data/changelog.d/README.md +120 -0
  17. data/changelog.d/scriv.ini +5 -0
  18. data/docs/.gitignore +1 -0
  19. data/docs/migrating/v2.0.0-pre1.md +276 -0
  20. data/examples/.gitignore +1 -0
  21. data/examples/advanced_routes/README.md +33 -0
  22. data/examples/advanced_routes/app/controllers/handlers/async.rb +9 -0
  23. data/examples/advanced_routes/app/controllers/handlers/dynamic.rb +9 -0
  24. data/examples/advanced_routes/app/controllers/handlers/static.rb +9 -0
  25. data/examples/advanced_routes/app/controllers/modules/auth.rb +9 -0
  26. data/examples/advanced_routes/app/controllers/modules/transformer.rb +9 -0
  27. data/examples/advanced_routes/app/controllers/modules/validator.rb +9 -0
  28. data/examples/advanced_routes/app/controllers/routes_app.rb +232 -0
  29. data/examples/advanced_routes/app/controllers/v2/admin.rb +9 -0
  30. data/examples/advanced_routes/app/controllers/v2/config.rb +9 -0
  31. data/examples/advanced_routes/app/controllers/v2/settings.rb +9 -0
  32. data/examples/advanced_routes/app/logic/admin/logic/manager.rb +27 -0
  33. data/examples/advanced_routes/app/logic/admin/panel.rb +27 -0
  34. data/examples/advanced_routes/app/logic/analytics_processor.rb +25 -0
  35. data/examples/advanced_routes/app/logic/complex/business/handler.rb +27 -0
  36. data/examples/advanced_routes/app/logic/data_logic.rb +23 -0
  37. data/examples/advanced_routes/app/logic/data_processor.rb +25 -0
  38. data/examples/advanced_routes/app/logic/input_validator.rb +24 -0
  39. data/examples/advanced_routes/app/logic/nested/feature/logic.rb +27 -0
  40. data/examples/advanced_routes/app/logic/reports_generator.rb +27 -0
  41. data/examples/advanced_routes/app/logic/simple_logic.rb +25 -0
  42. data/examples/advanced_routes/app/logic/system/config/manager.rb +27 -0
  43. data/examples/advanced_routes/app/logic/test_logic.rb +23 -0
  44. data/examples/advanced_routes/app/logic/transform_logic.rb +23 -0
  45. data/examples/advanced_routes/app/logic/upload_logic.rb +23 -0
  46. data/examples/advanced_routes/app/logic/v2/logic/dashboard.rb +27 -0
  47. data/examples/advanced_routes/app/logic/v2/logic/processor.rb +27 -0
  48. data/examples/advanced_routes/app.rb +33 -0
  49. data/examples/advanced_routes/config.rb +23 -0
  50. data/examples/advanced_routes/config.ru +7 -0
  51. data/examples/advanced_routes/puma.rb +20 -0
  52. data/examples/advanced_routes/routes +167 -0
  53. data/examples/advanced_routes/run.rb +39 -0
  54. data/examples/advanced_routes/test.rb +58 -0
  55. data/examples/authentication_strategies/README.md +32 -0
  56. data/examples/authentication_strategies/app/auth.rb +68 -0
  57. data/examples/authentication_strategies/app/controllers/auth_controller.rb +29 -0
  58. data/examples/authentication_strategies/app/controllers/main_controller.rb +28 -0
  59. data/examples/authentication_strategies/config.ru +24 -0
  60. data/examples/authentication_strategies/routes +37 -0
  61. data/examples/basic/README.md +29 -0
  62. data/examples/basic/app.rb +7 -35
  63. data/examples/basic/routes +0 -9
  64. data/examples/mcp_demo/README.md +87 -0
  65. data/examples/mcp_demo/app.rb +29 -34
  66. data/examples/mcp_demo/config.ru +9 -60
  67. data/examples/security_features/README.md +46 -0
  68. data/examples/security_features/app.rb +23 -24
  69. data/examples/security_features/config.ru +8 -10
  70. data/lib/otto/core/configuration.rb +167 -0
  71. data/lib/otto/core/error_handler.rb +86 -0
  72. data/lib/otto/core/file_safety.rb +61 -0
  73. data/lib/otto/core/middleware_stack.rb +157 -0
  74. data/lib/otto/core/router.rb +183 -0
  75. data/lib/otto/core/uri_generator.rb +44 -0
  76. data/lib/otto/design_system.rb +7 -5
  77. data/lib/otto/helpers/base.rb +3 -0
  78. data/lib/otto/helpers/request.rb +10 -8
  79. data/lib/otto/helpers/response.rb +5 -4
  80. data/lib/otto/helpers/validation.rb +9 -7
  81. data/lib/otto/mcp/auth/token.rb +10 -9
  82. data/lib/otto/mcp/protocol.rb +24 -27
  83. data/lib/otto/mcp/rate_limiting.rb +8 -3
  84. data/lib/otto/mcp/registry.rb +7 -2
  85. data/lib/otto/mcp/route_parser.rb +10 -15
  86. data/lib/otto/mcp/server.rb +21 -11
  87. data/lib/otto/mcp/validation.rb +14 -10
  88. data/lib/otto/response_handlers/auto.rb +39 -0
  89. data/lib/otto/response_handlers/base.rb +16 -0
  90. data/lib/otto/response_handlers/default.rb +16 -0
  91. data/lib/otto/response_handlers/factory.rb +39 -0
  92. data/lib/otto/response_handlers/json.rb +28 -0
  93. data/lib/otto/response_handlers/redirect.rb +25 -0
  94. data/lib/otto/response_handlers/view.rb +24 -0
  95. data/lib/otto/response_handlers.rb +9 -135
  96. data/lib/otto/route.rb +9 -9
  97. data/lib/otto/route_definition.rb +15 -18
  98. data/lib/otto/route_handlers/base.rb +121 -0
  99. data/lib/otto/route_handlers/class_method.rb +89 -0
  100. data/lib/otto/route_handlers/factory.rb +29 -0
  101. data/lib/otto/route_handlers/instance_method.rb +69 -0
  102. data/lib/otto/route_handlers/lambda.rb +59 -0
  103. data/lib/otto/route_handlers/logic_class.rb +93 -0
  104. data/lib/otto/route_handlers.rb +10 -405
  105. data/lib/otto/security/authentication/auth_strategy.rb +44 -0
  106. data/lib/otto/security/authentication/authentication_middleware.rb +123 -0
  107. data/lib/otto/security/authentication/failure_result.rb +36 -0
  108. data/lib/otto/security/authentication/strategies/api_key_strategy.rb +40 -0
  109. data/lib/otto/security/authentication/strategies/permission_strategy.rb +47 -0
  110. data/lib/otto/security/authentication/strategies/public_strategy.rb +19 -0
  111. data/lib/otto/security/authentication/strategies/role_strategy.rb +57 -0
  112. data/lib/otto/security/authentication/strategies/session_strategy.rb +41 -0
  113. data/lib/otto/security/authentication/strategy_result.rb +223 -0
  114. data/lib/otto/security/authentication.rb +28 -282
  115. data/lib/otto/security/config.rb +14 -12
  116. data/lib/otto/security/configurator.rb +219 -0
  117. data/lib/otto/security/csrf.rb +8 -143
  118. data/lib/otto/security/middleware/csrf_middleware.rb +151 -0
  119. data/lib/otto/security/middleware/rate_limit_middleware.rb +38 -0
  120. data/lib/otto/security/middleware/validation_middleware.rb +252 -0
  121. data/lib/otto/security/rate_limiter.rb +86 -0
  122. data/lib/otto/security/rate_limiting.rb +10 -105
  123. data/lib/otto/security/validator.rb +8 -253
  124. data/lib/otto/static.rb +3 -0
  125. data/lib/otto/utils.rb +14 -0
  126. data/lib/otto/version.rb +3 -1
  127. data/lib/otto.rb +142 -498
  128. data/otto.gemspec +2 -2
  129. metadata +89 -28
  130. data/examples/dynamic_pages/app.rb +0 -115
  131. data/examples/dynamic_pages/config.ru +0 -30
  132. data/examples/dynamic_pages/routes +0 -21
  133. data/examples/helpers_demo/app.rb +0 -244
  134. data/examples/helpers_demo/config.ru +0 -26
  135. data/examples/helpers_demo/routes +0 -7
  136. data/lib/concurrent_cache_store.rb +0 -68
@@ -1,68 +0,0 @@
1
- # lib/concurrent_cache_store.rb
2
-
3
- require 'concurrent-ruby'
4
-
5
- # Thread-safe cache store with TTL support for Rack::Attack
6
- # Provides ActiveSupport::Cache::MemoryStore-compatible interface
7
- #
8
- # Usage:
9
- #
10
- # Rack::Attack.cache.store = ConcurrentCacheStore.new(default_ttl: 300)
11
- #
12
- class ConcurrentCacheStore
13
- # @param default_ttl [Integer] Default time-to-live in seconds for cache entries
14
- def initialize(default_ttl: 300)
15
- @store = Concurrent::Map.new
16
- @default_ttl = default_ttl
17
- end
18
-
19
- # Retrieves a value from the cache
20
- # @param key [String] The cache key
21
- # @return [Object, nil] The cached value or nil if expired/missing
22
- def read(key)
23
- entry = @store[key]
24
- return nil unless entry
25
-
26
- if Time.now > entry[:expires_at]
27
- @store.delete(key)
28
- nil
29
- else
30
- entry[:value]
31
- end
32
- end
33
-
34
- # Stores a value in the cache with expiration
35
- # @param key [String] The cache key
36
- # @param value [Object] The value to store
37
- # @param expires_in [Integer] TTL in seconds (optional)
38
- # @return [Object] The stored value
39
- def write(key, value, expires_in: @default_ttl)
40
- @store[key] = {
41
- value: value,
42
- expires_at: Time.now + expires_in,
43
- }
44
- value
45
- end
46
-
47
- # Atomically increments a numeric value, creating if missing
48
- # @param key [String] The cache key
49
- # @param amount [Integer] Amount to increment by
50
- # @param expires_in [Integer] TTL in seconds for new entries
51
- # @return [Integer] The new value after increment
52
- def increment(key, amount = 1, expires_in: @default_ttl)
53
- @store.compute(key) do |_, entry|
54
- if entry && Time.now <= entry[:expires_at]
55
- entry[:value] += amount
56
- entry
57
- else
58
- { value: amount, expires_at: Time.now + expires_in }
59
- end
60
- end[:value]
61
- end
62
-
63
- # Removes all entries from the cache
64
- # @return [void]
65
- def clear
66
- @store.clear
67
- end
68
- end