rhales 0.3.0 → 0.5.3
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 +4 -4
- data/.github/renovate.json5 +52 -0
- data/.github/workflows/ci.yml +123 -0
- data/.github/workflows/claude-code-review.yml +69 -0
- data/.github/workflows/claude.yml +49 -0
- data/.github/workflows/code-smells.yml +146 -0
- data/.github/workflows/ruby-lint.yml +78 -0
- data/.github/workflows/yardoc.yml +126 -0
- data/.gitignore +55 -0
- data/.pr_agent.toml +63 -0
- data/.pre-commit-config.yaml +89 -0
- data/.prettierignore +8 -0
- data/.prettierrc +38 -0
- data/.reek.yml +98 -0
- data/.rubocop.yml +428 -0
- data/.serena/.gitignore +3 -0
- data/.yardopts +56 -0
- data/CHANGELOG.md +44 -0
- data/CLAUDE.md +1 -2
- data/Gemfile +29 -0
- data/Gemfile.lock +189 -0
- data/README.md +706 -589
- data/Rakefile +46 -0
- data/debug_context.rb +25 -0
- data/demo/rhales-roda-demo/.gitignore +7 -0
- data/demo/rhales-roda-demo/Gemfile +32 -0
- data/demo/rhales-roda-demo/Gemfile.lock +151 -0
- data/demo/rhales-roda-demo/MAIL.md +405 -0
- data/demo/rhales-roda-demo/README.md +376 -0
- data/demo/rhales-roda-demo/RODA-TEMPLATE-ENGINES.md +192 -0
- data/demo/rhales-roda-demo/Rakefile +49 -0
- data/demo/rhales-roda-demo/app.rb +325 -0
- data/demo/rhales-roda-demo/bin/rackup +26 -0
- data/demo/rhales-roda-demo/config.ru +13 -0
- data/demo/rhales-roda-demo/db/migrate/001_create_rodauth_tables.rb +266 -0
- data/demo/rhales-roda-demo/db/migrate/002_create_rodauth_password_tables.rb +79 -0
- data/demo/rhales-roda-demo/db/migrate/003_add_admin_account.rb +68 -0
- data/demo/rhales-roda-demo/templates/change_login.rue +31 -0
- data/demo/rhales-roda-demo/templates/change_password.rue +36 -0
- data/demo/rhales-roda-demo/templates/close_account.rue +31 -0
- data/demo/rhales-roda-demo/templates/create_account.rue +40 -0
- data/demo/rhales-roda-demo/templates/dashboard.rue +150 -0
- data/demo/rhales-roda-demo/templates/home.rue +78 -0
- data/demo/rhales-roda-demo/templates/layouts/main.rue +168 -0
- data/demo/rhales-roda-demo/templates/login.rue +65 -0
- data/demo/rhales-roda-demo/templates/logout.rue +25 -0
- data/demo/rhales-roda-demo/templates/reset_password.rue +26 -0
- data/demo/rhales-roda-demo/templates/verify_account.rue +27 -0
- data/demo/rhales-roda-demo/test_full_output.rb +27 -0
- data/demo/rhales-roda-demo/test_simple.rb +24 -0
- data/docs/.gitignore +9 -0
- data/docs/architecture/data-flow.md +499 -0
- data/examples/dashboard-with-charts.rue +271 -0
- data/examples/form-with-validation.rue +180 -0
- data/examples/simple-page.rue +61 -0
- data/examples/vue.rue +136 -0
- data/generate-json-schemas.ts +158 -0
- data/json_schemer_migration_summary.md +172 -0
- data/lib/rhales/adapters/base_auth.rb +2 -0
- data/lib/rhales/adapters/base_request.rb +2 -0
- data/lib/rhales/adapters/base_session.rb +2 -0
- data/lib/rhales/adapters.rb +7 -0
- data/lib/rhales/configuration.rb +161 -1
- data/lib/rhales/core/context.rb +354 -0
- data/lib/rhales/{rue_document.rb → core/rue_document.rb} +59 -43
- data/lib/rhales/{template_engine.rb → core/template_engine.rb} +80 -33
- data/lib/rhales/core/view.rb +529 -0
- data/lib/rhales/{view_composition.rb → core/view_composition.rb} +81 -9
- data/lib/rhales/core.rb +9 -0
- data/lib/rhales/errors/hydration_collision_error.rb +2 -0
- data/lib/rhales/errors.rb +2 -0
- data/lib/rhales/hydration/earliest_injection_detector.rb +153 -0
- data/lib/rhales/hydration/hydration_data_aggregator.rb +487 -0
- data/lib/rhales/hydration/hydration_endpoint.rb +215 -0
- data/lib/rhales/hydration/hydration_injector.rb +175 -0
- data/lib/rhales/{hydration_registry.rb → hydration/hydration_registry.rb} +2 -0
- data/lib/rhales/hydration/hydrator.rb +102 -0
- data/lib/rhales/hydration/link_based_injection_detector.rb +195 -0
- data/lib/rhales/hydration/mount_point_detector.rb +109 -0
- data/lib/rhales/hydration/safe_injection_validator.rb +103 -0
- data/lib/rhales/hydration.rb +13 -0
- data/lib/rhales/{refinements → integrations/refinements}/require_refinements.rb +7 -13
- data/lib/rhales/{tilt.rb → integrations/tilt.rb} +26 -18
- data/lib/rhales/integrations.rb +6 -0
- data/lib/rhales/middleware/json_responder.rb +191 -0
- data/lib/rhales/middleware/schema_validator.rb +300 -0
- data/lib/rhales/middleware.rb +6 -0
- data/lib/rhales/parsers/handlebars_parser.rb +2 -0
- data/lib/rhales/parsers/rue_format_parser.rb +55 -36
- data/lib/rhales/parsers.rb +9 -0
- data/lib/rhales/{csp.rb → security/csp.rb} +27 -3
- data/lib/rhales/utils/json_serializer.rb +114 -0
- data/lib/rhales/utils/logging_helpers.rb +75 -0
- data/lib/rhales/utils/schema_extractor.rb +132 -0
- data/lib/rhales/utils/schema_generator.rb +194 -0
- data/lib/rhales/utils.rb +40 -0
- data/lib/rhales/version.rb +5 -1
- data/lib/rhales.rb +47 -19
- data/lib/tasks/rhales_schema.rake +197 -0
- data/package.json +10 -0
- data/pnpm-lock.yaml +345 -0
- data/pnpm-workspace.yaml +2 -0
- data/proofs/error_handling.rb +79 -0
- data/proofs/expanded_object_inheritance.rb +82 -0
- data/proofs/partial_context_scoping_fix.rb +168 -0
- data/proofs/ui_context_partial_inheritance.rb +236 -0
- data/rhales.gemspec +14 -6
- data/schema_vs_data_comparison.md +254 -0
- data/test_direct_access.rb +36 -0
- metadata +142 -18
- data/CLAUDE.locale.txt +0 -7
- data/lib/rhales/context.rb +0 -240
- data/lib/rhales/hydration_data_aggregator.rb +0 -220
- data/lib/rhales/hydrator.rb +0 -141
- data/lib/rhales/parsers/handlebars-grammar-review.txt +0 -39
- data/lib/rhales/view.rb +0 -412
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# .rubocop.yml
|
|
2
|
+
#
|
|
3
|
+
# This is the RuboCop configuration file.
|
|
4
|
+
# It contains the rules and settings for the RuboCop linter.
|
|
5
|
+
#
|
|
6
|
+
# Enable/disable the cops individually. For more information,
|
|
7
|
+
# refer to the RuboCop documentation:
|
|
8
|
+
# https://docs.rubocop.org/rubocop/cops.html
|
|
9
|
+
|
|
10
|
+
plugins:
|
|
11
|
+
- rubocop-thread_safety
|
|
12
|
+
- rubocop-performance
|
|
13
|
+
- rubocop-rspec
|
|
14
|
+
|
|
15
|
+
AllCops:
|
|
16
|
+
NewCops: enable
|
|
17
|
+
DisabledByDefault: false # flip to true for a good autocorrect time
|
|
18
|
+
UseCache: true
|
|
19
|
+
MaxFilesInCache: 1000
|
|
20
|
+
TargetRubyVersion: 3.4
|
|
21
|
+
Exclude:
|
|
22
|
+
- 'bin/bundle'
|
|
23
|
+
- 'node_modules/**/*'
|
|
24
|
+
- 'tmp/**/*'
|
|
25
|
+
- 'vendor/**/*'
|
|
26
|
+
|
|
27
|
+
RSpec/MultipleExpectations:
|
|
28
|
+
Enabled: true
|
|
29
|
+
Max: 5
|
|
30
|
+
|
|
31
|
+
RSpec/ExampleLength:
|
|
32
|
+
Enabled: true
|
|
33
|
+
Max: 10
|
|
34
|
+
|
|
35
|
+
Layout/CaseIndentation:
|
|
36
|
+
Enabled: true
|
|
37
|
+
EnforcedStyle: end # case, end
|
|
38
|
+
IndentOneStep: false
|
|
39
|
+
IndentationWidth: 2
|
|
40
|
+
|
|
41
|
+
Layout/CommentIndentation:
|
|
42
|
+
Enabled: true
|
|
43
|
+
|
|
44
|
+
Layout/MultilineMethodCallBraceLayout:
|
|
45
|
+
Enabled: true
|
|
46
|
+
EnforcedStyle: new_line # symmetrical, new_line, same_line
|
|
47
|
+
|
|
48
|
+
Layout/TrailingWhitespace:
|
|
49
|
+
Enabled: true
|
|
50
|
+
|
|
51
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
|
52
|
+
Enabled: true
|
|
53
|
+
|
|
54
|
+
Layout/SpaceAroundOperators:
|
|
55
|
+
Enabled: false
|
|
56
|
+
|
|
57
|
+
# Use parentheses around a logical expression if it makes easier to read.
|
|
58
|
+
Style/RedundantParentheses:
|
|
59
|
+
Enabled: false
|
|
60
|
+
|
|
61
|
+
Lint/UnusedMethodArgument:
|
|
62
|
+
Enabled: true
|
|
63
|
+
|
|
64
|
+
Lint/UselessAssignment:
|
|
65
|
+
Enabled: true
|
|
66
|
+
|
|
67
|
+
Lint/DuplicateBranch:
|
|
68
|
+
Enabled: true
|
|
69
|
+
IgnoreLiteralBranches: false
|
|
70
|
+
IgnoreConstantBranches: false
|
|
71
|
+
IgnoreDuplicateElseBranch: false
|
|
72
|
+
|
|
73
|
+
# Offense count: 3
|
|
74
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
75
|
+
Metrics/PerceivedComplexity:
|
|
76
|
+
Max: 20
|
|
77
|
+
|
|
78
|
+
# Offense count: 186
|
|
79
|
+
# Configuration parameters: AllowedConstants.
|
|
80
|
+
Style/Documentation:
|
|
81
|
+
Enabled: false
|
|
82
|
+
|
|
83
|
+
Style/RescueStandardError:
|
|
84
|
+
Enabled: true
|
|
85
|
+
EnforcedStyle: explicit
|
|
86
|
+
|
|
87
|
+
# When true: Use match? instead of =~ when MatchData is not used. True is preferred but not for autocorrection. Regexs are too picky. Need to manually check every time.
|
|
88
|
+
Performance/RegexpMatch:
|
|
89
|
+
Enabled: false
|
|
90
|
+
|
|
91
|
+
Style/TrailingCommaInHashLiteral:
|
|
92
|
+
Enabled: true
|
|
93
|
+
EnforcedStyleForMultiline: comma
|
|
94
|
+
|
|
95
|
+
Style/StringLiterals:
|
|
96
|
+
Enabled: true
|
|
97
|
+
EnforcedStyle: single_quotes
|
|
98
|
+
|
|
99
|
+
# The Style/DoubleNegation cop is disabled because double negation provides
|
|
100
|
+
# a concise, idiomatic way to convert values to boolean in Ruby. Alternative
|
|
101
|
+
# approaches like ternary expressions or comparison with nil create unnecessary
|
|
102
|
+
# verbosity without adding clarity. In cases where boolean coercion is the
|
|
103
|
+
# explicit intent, !! clearly communicates this purpose to other Ruby developers.
|
|
104
|
+
Style/DoubleNegation:
|
|
105
|
+
Enabled: false
|
|
106
|
+
|
|
107
|
+
# Offense count: non-0
|
|
108
|
+
Style/FormatString:
|
|
109
|
+
EnforcedStyle: format
|
|
110
|
+
Enabled: true
|
|
111
|
+
|
|
112
|
+
Style/FormatStringToken:
|
|
113
|
+
EnforcedStyle: unannotated
|
|
114
|
+
Enabled: true
|
|
115
|
+
|
|
116
|
+
Style/RedundantReturn:
|
|
117
|
+
Enabled: true
|
|
118
|
+
AllowMultipleReturnValues: false
|
|
119
|
+
|
|
120
|
+
Style/IfUnlessModifier:
|
|
121
|
+
Enabled: false
|
|
122
|
+
|
|
123
|
+
# We prefer `extend self` and `class << self`.
|
|
124
|
+
Style/ModuleFunction:
|
|
125
|
+
Enabled: true
|
|
126
|
+
AutoCorrect: false
|
|
127
|
+
EnforcedStyle: extend_self
|
|
128
|
+
|
|
129
|
+
Style/SymbolArray:
|
|
130
|
+
EnforcedStyle: brackets
|
|
131
|
+
Enabled: true
|
|
132
|
+
|
|
133
|
+
Style/StringLiteralsInInterpolation:
|
|
134
|
+
Enabled: true
|
|
135
|
+
|
|
136
|
+
Style/BlockDelimiters:
|
|
137
|
+
Enabled: true
|
|
138
|
+
|
|
139
|
+
Naming/PredicateMethod:
|
|
140
|
+
Enabled: true
|
|
141
|
+
Mode: 'conservative'
|
|
142
|
+
AllowedMethods:
|
|
143
|
+
- validate!
|
|
144
|
+
- migrate
|
|
145
|
+
|
|
146
|
+
# We use class instance variables quite a bit, mostly for readonly values set
|
|
147
|
+
# at boot time. Except for our models with have redis-rb Redis instances
|
|
148
|
+
# connected on their associated db via ModelClass.redis. We're well aware
|
|
149
|
+
# so keeping this disabled reduces warning noise.
|
|
150
|
+
ThreadSafety/ClassInstanceVariable:
|
|
151
|
+
Enabled: false
|
|
152
|
+
|
|
153
|
+
Naming/RescuedExceptionsVariableName:
|
|
154
|
+
Enabled: true
|
|
155
|
+
PreferredName: ex # Default is 'e'
|
|
156
|
+
|
|
157
|
+
Naming/PredicatePrefix:
|
|
158
|
+
Enabled: true
|
|
159
|
+
ForbiddenPrefixes: [is_, has_, have_]
|
|
160
|
+
AllowedMethods: [
|
|
161
|
+
has_passphrase?, # correlates with the REST API field `has_passphrase`
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
Layout/MultilineMethodCallIndentation:
|
|
165
|
+
EnforcedStyle: indented
|
|
166
|
+
IndentationWidth: 2
|
|
167
|
+
|
|
168
|
+
Gemspec/DeprecatedAttributeAssignment:
|
|
169
|
+
Enabled: true
|
|
170
|
+
|
|
171
|
+
Gemspec/DevelopmentDependencies:
|
|
172
|
+
Enabled: true
|
|
173
|
+
|
|
174
|
+
Layout/ElseAlignment:
|
|
175
|
+
Enabled: false
|
|
176
|
+
|
|
177
|
+
Layout/EndAlignment:
|
|
178
|
+
Enabled: false
|
|
179
|
+
# Severity: low
|
|
180
|
+
# SupportedStylesAlignWith: 2
|
|
181
|
+
# Leave commented out. When we set align with, endless "error occurred"
|
|
182
|
+
# EnforcedStyle: keyword # keyword, variable, start_of_line
|
|
183
|
+
|
|
184
|
+
## vvvvvv Causing ruby-lsp errors in zed ? (July 8)
|
|
185
|
+
##
|
|
186
|
+
# Prefer 3 line if/else over one-liner
|
|
187
|
+
Style/GuardClause:
|
|
188
|
+
Enabled: false
|
|
189
|
+
MinBodyLength: 3
|
|
190
|
+
AllowConsecutiveConditionals: false
|
|
191
|
+
|
|
192
|
+
Layout/ExtraSpacing:
|
|
193
|
+
Enabled: false
|
|
194
|
+
AllowForAlignment: true
|
|
195
|
+
AllowBeforeTrailingComments: true
|
|
196
|
+
ForceEqualSignAlignment: true
|
|
197
|
+
## ^^^^^^
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
Layout/IndentationConsistency:
|
|
201
|
+
EnforcedStyle: indented_internal_methods
|
|
202
|
+
Enabled: true
|
|
203
|
+
|
|
204
|
+
Layout/IndentationWidth:
|
|
205
|
+
# We don't want to enforce indentation width because it's doing weird things
|
|
206
|
+
# with if/else statements that capture values. The `if` expression is aligned
|
|
207
|
+
# with the right side of the `test` but the `else` expression is aligned with
|
|
208
|
+
# the start of the line.
|
|
209
|
+
Width: 2
|
|
210
|
+
Enabled: false
|
|
211
|
+
|
|
212
|
+
Layout/HashAlignment:
|
|
213
|
+
Enabled: true
|
|
214
|
+
|
|
215
|
+
Layout/FirstHashElementIndentation:
|
|
216
|
+
Enabled: true
|
|
217
|
+
|
|
218
|
+
Lint/Void:
|
|
219
|
+
Enabled: true
|
|
220
|
+
|
|
221
|
+
Lint/CopDirectiveSyntax:
|
|
222
|
+
Enabled: true
|
|
223
|
+
|
|
224
|
+
# Offense count: 122
|
|
225
|
+
# Assignment Branch Condition size
|
|
226
|
+
Metrics/AbcSize:
|
|
227
|
+
Enabled: false
|
|
228
|
+
Max: 20
|
|
229
|
+
|
|
230
|
+
# Offense count: 217
|
|
231
|
+
Layout/LineLength:
|
|
232
|
+
Enabled: false
|
|
233
|
+
AllowHeredoc: true
|
|
234
|
+
AllowURI: true
|
|
235
|
+
URISchemes:
|
|
236
|
+
- https
|
|
237
|
+
IgnoreCopDirectives: true
|
|
238
|
+
AllowedPatterns: []
|
|
239
|
+
SplitStrings: false
|
|
240
|
+
Max: 100
|
|
241
|
+
|
|
242
|
+
# Align the arguments of a method call if they span more than one line.
|
|
243
|
+
Layout/ArgumentAlignment:
|
|
244
|
+
Enabled: true
|
|
245
|
+
EnforcedStyle: with_fixed_indentation # with_first_argument, with_fixed_indentation
|
|
246
|
+
IndentationWidth: 2
|
|
247
|
+
|
|
248
|
+
Layout/EmptyLineAfterGuardClause:
|
|
249
|
+
Enabled: true
|
|
250
|
+
|
|
251
|
+
Layout/EmptyLineBetweenDefs:
|
|
252
|
+
Enabled: true
|
|
253
|
+
|
|
254
|
+
Layout/EmptyLines:
|
|
255
|
+
Enabled: true
|
|
256
|
+
|
|
257
|
+
Layout/EmptyLinesAroundAccessModifier:
|
|
258
|
+
Enabled: true
|
|
259
|
+
|
|
260
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
|
261
|
+
Enabled: true
|
|
262
|
+
|
|
263
|
+
Layout/EmptyLinesAroundBlockBody:
|
|
264
|
+
Enabled: true
|
|
265
|
+
|
|
266
|
+
Layout/EmptyLinesAroundClassBody:
|
|
267
|
+
Enabled: true
|
|
268
|
+
|
|
269
|
+
Layout/EmptyLinesAroundExceptionHandlingKeywords:
|
|
270
|
+
Enabled: true
|
|
271
|
+
|
|
272
|
+
Layout/EmptyLinesAroundMethodBody:
|
|
273
|
+
Enabled: true
|
|
274
|
+
|
|
275
|
+
Layout/EmptyLinesAroundModuleBody:
|
|
276
|
+
Enabled: true
|
|
277
|
+
|
|
278
|
+
Metrics/ClassLength:
|
|
279
|
+
Enabled: true
|
|
280
|
+
Max: 350
|
|
281
|
+
|
|
282
|
+
# Offense count: non-0
|
|
283
|
+
Metrics/MethodLength:
|
|
284
|
+
Enabled: true
|
|
285
|
+
Max: 50
|
|
286
|
+
CountAsOne: ['method_call']
|
|
287
|
+
|
|
288
|
+
Metrics/ModuleLength:
|
|
289
|
+
Enabled: true
|
|
290
|
+
Max: 350
|
|
291
|
+
CountAsOne: ['method_call']
|
|
292
|
+
|
|
293
|
+
Performance/Size:
|
|
294
|
+
Enabled: true
|
|
295
|
+
Exclude: []
|
|
296
|
+
|
|
297
|
+
Naming/AsciiIdentifiers:
|
|
298
|
+
Enabled: true
|
|
299
|
+
|
|
300
|
+
Metrics/CyclomaticComplexity:
|
|
301
|
+
Enabled: false
|
|
302
|
+
|
|
303
|
+
Style/NegatedIfElseCondition:
|
|
304
|
+
Enabled: true
|
|
305
|
+
|
|
306
|
+
Style/TrailingCommaInArguments:
|
|
307
|
+
Enabled: true
|
|
308
|
+
EnforcedStyleForMultiline: comma
|
|
309
|
+
|
|
310
|
+
Style/TrailingCommaInArrayLiteral:
|
|
311
|
+
Enabled: true
|
|
312
|
+
EnforcedStyleForMultiline: comma
|
|
313
|
+
|
|
314
|
+
# Use #empty? when testing for objects of length 0.
|
|
315
|
+
Style/ZeroLengthPredicate:
|
|
316
|
+
Enabled: true
|
|
317
|
+
Safe: true
|
|
318
|
+
|
|
319
|
+
Style/MethodDefParentheses:
|
|
320
|
+
Enabled: true
|
|
321
|
+
|
|
322
|
+
Style/FrozenStringLiteralComment:
|
|
323
|
+
Enabled: true
|
|
324
|
+
EnforcedStyle: never
|
|
325
|
+
|
|
326
|
+
Style/SuperArguments:
|
|
327
|
+
Enabled: true
|
|
328
|
+
|
|
329
|
+
# Offense count: non-0
|
|
330
|
+
ThreadSafety/ClassAndModuleAttributes:
|
|
331
|
+
Description: Avoid mutating class and module attributes.
|
|
332
|
+
Enabled: true
|
|
333
|
+
ActiveSupportClassAttributeAllowed: false
|
|
334
|
+
|
|
335
|
+
ThreadSafety/DirChdir:
|
|
336
|
+
Description: Avoid using `Dir.chdir` due to its process-wide effect.
|
|
337
|
+
Enabled: true
|
|
338
|
+
AllowCallWithBlock: false
|
|
339
|
+
|
|
340
|
+
# Do not assign mutable objects to class instance variables.
|
|
341
|
+
ThreadSafety/MutableClassInstanceVariable:
|
|
342
|
+
Description:
|
|
343
|
+
Enabled: true
|
|
344
|
+
EnforcedStyle: literals # one of literals, strict
|
|
345
|
+
SafeAutoCorrect: false
|
|
346
|
+
|
|
347
|
+
# Avoid starting new threads. Let a framework like Sidekiq handle the threads.
|
|
348
|
+
ThreadSafety/NewThread:
|
|
349
|
+
Enabled: true
|
|
350
|
+
|
|
351
|
+
# Avoid instance variables in Rack middleware.
|
|
352
|
+
ThreadSafety/RackMiddlewareInstanceVariable:
|
|
353
|
+
Description:
|
|
354
|
+
Enabled: true
|
|
355
|
+
Include:
|
|
356
|
+
- lib/middleware/*.rb
|
|
357
|
+
|
|
358
|
+
# Unsafe autocorrect:
|
|
359
|
+
Performance/MapCompact:
|
|
360
|
+
Enabled: false
|
|
361
|
+
Performance/StringInclude:
|
|
362
|
+
Enabled: false
|
|
363
|
+
Style/ClassAndModuleChildren:
|
|
364
|
+
Enabled: false
|
|
365
|
+
Style/GlobalStdStream:
|
|
366
|
+
Enabled: false
|
|
367
|
+
Style/HashConversion:
|
|
368
|
+
Enabled: false
|
|
369
|
+
Style/HashEachMethods:
|
|
370
|
+
Enabled: false
|
|
371
|
+
Style/IdenticalConditionalBranches:
|
|
372
|
+
Enabled: false
|
|
373
|
+
Style/MinMaxComparison:
|
|
374
|
+
Enabled: false
|
|
375
|
+
Style/MutableConstant:
|
|
376
|
+
Enabled: false
|
|
377
|
+
Style/NumericPredicate:
|
|
378
|
+
Enabled: false
|
|
379
|
+
Style/RaiseArgs:
|
|
380
|
+
Enabled: false
|
|
381
|
+
Style/RedundantInterpolation:
|
|
382
|
+
Enabled: false
|
|
383
|
+
Style/SafeNavigation:
|
|
384
|
+
Enabled: false
|
|
385
|
+
Style/SpecialGlobalVars:
|
|
386
|
+
Enabled: false
|
|
387
|
+
Style/StringConcatenation:
|
|
388
|
+
Enabled: false
|
|
389
|
+
Style/SymbolProc:
|
|
390
|
+
Enabled: false
|
|
391
|
+
|
|
392
|
+
# warnings
|
|
393
|
+
Lint/RedundantCopDisableDirective:
|
|
394
|
+
Enabled: false
|
|
395
|
+
Lint/AssignmentInCondition:
|
|
396
|
+
Enabled: false
|
|
397
|
+
|
|
398
|
+
# Manual corrections
|
|
399
|
+
Metrics/BlockLength:
|
|
400
|
+
Enabled: false
|
|
401
|
+
Metrics/BlockNesting:
|
|
402
|
+
Enabled: false
|
|
403
|
+
Metrics/ParameterLists:
|
|
404
|
+
Enabled: false
|
|
405
|
+
Naming/AccessorMethodName:
|
|
406
|
+
Enabled: false
|
|
407
|
+
Naming/MethodParameterName:
|
|
408
|
+
Enabled: false
|
|
409
|
+
Performance/CollectionLiteralInLoop:
|
|
410
|
+
Enabled: false
|
|
411
|
+
Style/OptionalBooleanParameter:
|
|
412
|
+
Enabled: false
|
|
413
|
+
|
|
414
|
+
# warnings
|
|
415
|
+
Lint/DuplicateMethods:
|
|
416
|
+
Enabled: false
|
|
417
|
+
Lint/UselessOr:
|
|
418
|
+
Enabled: false
|
|
419
|
+
Lint/UnreachableLoop:
|
|
420
|
+
Enabled: false
|
|
421
|
+
Lint/MissingCopEnableDirective:
|
|
422
|
+
Enabled: false
|
|
423
|
+
Lint/MissingSuper:
|
|
424
|
+
Enabled: false
|
|
425
|
+
Lint/EmptyFile:
|
|
426
|
+
Enabled: false
|
|
427
|
+
Lint/RescueException:
|
|
428
|
+
Enabled: false
|
data/.serena/.gitignore
ADDED
data/.yardopts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# YARD Documentation Configuration
|
|
2
|
+
# Systematic parameter specification for comprehensive API documentation generation
|
|
3
|
+
|
|
4
|
+
# Access level configuration: Include protected and private methods for complete API coverage
|
|
5
|
+
--protected
|
|
6
|
+
--private
|
|
7
|
+
|
|
8
|
+
# Markup processing configuration
|
|
9
|
+
--markup markdown
|
|
10
|
+
--markup-provider kramdown
|
|
11
|
+
|
|
12
|
+
# Output directory specification
|
|
13
|
+
--output-dir doc
|
|
14
|
+
|
|
15
|
+
# Primary documentation entry point
|
|
16
|
+
--readme README.md
|
|
17
|
+
|
|
18
|
+
# Supplementary documentation files
|
|
19
|
+
--files CHANGELOG.md,LICENSE.txt
|
|
20
|
+
|
|
21
|
+
# Path exclusion patterns: Remove non-library code from documentation scope
|
|
22
|
+
--exclude spec/**/*
|
|
23
|
+
--exclude demo/**/*
|
|
24
|
+
--exclude examples/**/*
|
|
25
|
+
--exclude apps/**/*
|
|
26
|
+
--exclude test/**/*
|
|
27
|
+
--exclude tmp/**/*
|
|
28
|
+
|
|
29
|
+
# Source file inclusion patterns: Target library implementation files
|
|
30
|
+
lib/**/*.rb
|
|
31
|
+
|
|
32
|
+
# Template specification for comprehensive documentation structure
|
|
33
|
+
--template default
|
|
34
|
+
|
|
35
|
+
# Additional processing directives
|
|
36
|
+
--verbose
|
|
37
|
+
|
|
38
|
+
# Documentation metadata
|
|
39
|
+
--title "Rhales - Server-rendered Components with Client-side Hydration"
|
|
40
|
+
|
|
41
|
+
# Tag processing configuration
|
|
42
|
+
--tag param:"Parameters"
|
|
43
|
+
--tag option:"Options"
|
|
44
|
+
--tag return:"Returns"
|
|
45
|
+
--tag raise:"Raises"
|
|
46
|
+
--tag example:"Example Usage"
|
|
47
|
+
--tag since:"Since"
|
|
48
|
+
--tag todo:"TODO"
|
|
49
|
+
--tag deprecated:"Deprecated"
|
|
50
|
+
--tag api:"API"
|
|
51
|
+
--tag internal:"Internal Use"
|
|
52
|
+
|
|
53
|
+
# Additional files for processing
|
|
54
|
+
-
|
|
55
|
+
README.md
|
|
56
|
+
CHANGELOG.md
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Production Logging**: Structured logging via `Rhales.logger=` for security auditing and debugging
|
|
12
|
+
- View rendering events with template details, timing, and hydration size
|
|
13
|
+
- Schema validation warnings for production debugging (missing/extra keys)
|
|
14
|
+
- Error logging with line numbers and section context
|
|
15
|
+
- Security events: unescaped variable warnings, CSP nonce generation
|
|
16
|
+
- Performance logging: template compilation, cache behavior, partial resolution
|
|
17
|
+
- Window collision detection prevents silent data overwrites when multiple templates use the same window attribute
|
|
18
|
+
- Explicit merge strategies (shallow, deep, strict) for controlled data sharing between templates
|
|
19
|
+
- `HydrationCollisionError` with detailed error messages showing file paths and line numbers
|
|
20
|
+
- `HydrationRegistry` for thread-safe tracking of window attributes per request
|
|
21
|
+
- `merge_strategy` method on RueDocument to extract merge attribute from data elements
|
|
22
|
+
- JavaScript merge functions for client-side data composition
|
|
23
|
+
- Comprehensive test coverage for collision detection and merge strategies
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- Replaced `json-schema` gem with `json_schemer` for better JSON Schema Draft 2020-12 support
|
|
27
|
+
- Improved validation error messages with more structured output from json_schemer
|
|
28
|
+
- Validation performance improved to <0.05ms average (was ~2ms with json-schema)
|
|
29
|
+
|
|
30
|
+
### Security
|
|
31
|
+
- Window collision detection prevents accidental data exposure by making overwrites explicit
|
|
32
|
+
- All merge operations happen client-side after server-side interpolation and JSON serialization
|
|
33
|
+
- Request-scoped registry prevents cross-request data leakage
|
|
34
|
+
|
|
35
|
+
## [0.1.0] - 2024-01-XX
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- Initial release of Rhales
|
|
39
|
+
- Ruby Single File Components (.rue files) with server-side rendering
|
|
40
|
+
- Client-side data hydration with secure JSON injection
|
|
41
|
+
- Handlebars-style template syntax
|
|
42
|
+
- Pluggable authentication adapters
|
|
43
|
+
- Framework-agnostic design with Rails and Roda examples
|
|
44
|
+
- Comprehensive test suite
|
data/CLAUDE.md
CHANGED
|
@@ -29,7 +29,6 @@ Follow test-driven development when possible:
|
|
|
29
29
|
2. Confirm tests fail appropriately
|
|
30
30
|
3. Commit tests
|
|
31
31
|
4. Implement code to pass tests WITHOUT modifying tests
|
|
32
|
-
5. Ensure no global state dependencies (OT.conf references)
|
|
33
32
|
6. Verify HTML escaping and security measures
|
|
34
33
|
7. Commit implementation
|
|
35
34
|
|
|
@@ -78,7 +77,7 @@ For complex features requiring parallel work:
|
|
|
78
77
|
|
|
79
78
|
### Key Patterns
|
|
80
79
|
- **Template Syntax**: Uses Handlebars-style syntax (e.g., `{{variable}}`, `{{#if condition}}...{{/if}}`, `{{> partial_name}}`)
|
|
81
|
-
- **Data Hydration**: Uses a `<
|
|
80
|
+
- **Data Hydration**: Uses a `<schema>` block in `.rue` files to define a zod v4 schema in plain Javascript for client-side hydration
|
|
82
81
|
- **Security**: Default HTML escaping, CSP nonce support for scripts, and CSRF token handling are built-in
|
|
83
82
|
- **Configuration**: All configuration is handled via an injected `Configuration` object, avoiding global state
|
|
84
83
|
|
data/Gemfile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Specify your gem's dependencies in rhales.gemspec
|
|
4
|
+
gemspec
|
|
5
|
+
|
|
6
|
+
group :development, :test do
|
|
7
|
+
gem 'benchmark'
|
|
8
|
+
gem 'rack-test'
|
|
9
|
+
gem 'reek', '~> 6.5'
|
|
10
|
+
gem 'rspec', '~> 3.12'
|
|
11
|
+
gem 'simplecov', '~> 0.22'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
group :development do
|
|
15
|
+
gem 'benchmark-ips', '~> 2.0'
|
|
16
|
+
gem 'bundler', '~> 2.0'
|
|
17
|
+
gem 'debug'
|
|
18
|
+
gem 'kramdown', '~> 2.0' # Required for YARD markdown processing
|
|
19
|
+
gem 'rack', '>= 3.2', '< 4.0'
|
|
20
|
+
gem 'rack-proxy', require: false
|
|
21
|
+
gem 'rake', '~> 13.0'
|
|
22
|
+
gem 'rubocop', '1.81'
|
|
23
|
+
gem 'rubocop-performance', require: false
|
|
24
|
+
gem 'rubocop-rspec', require: false
|
|
25
|
+
gem 'rubocop-thread_safety', require: false
|
|
26
|
+
gem 'stackprof', require: false
|
|
27
|
+
gem 'syntax_tree', require: false
|
|
28
|
+
gem 'yard', '~> 0.9'
|
|
29
|
+
end
|