funapi 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 (87) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/25-09-01-OPENAPI_IMPLEMENTATION.md +233 -0
  3. data/.claude/25-09-05-RESPONSE_SCHEMA.md +383 -0
  4. data/.claude/25-09-10-OPENAPI_PLAN.md +219 -0
  5. data/.claude/25-10-26-MIDDLEWARE_IMPLEMENTATION.md +230 -0
  6. data/.claude/25-10-26-MIDDLEWARE_PLAN.md +353 -0
  7. data/.claude/25-10-27-BACKGROUND_TASKS_ANALYSIS.md +325 -0
  8. data/.claude/25-10-27-DEPENDENCY_IMPLEMENTATION_SUMMARY.md +325 -0
  9. data/.claude/25-10-27-DEPENDENCY_INJECTION_PLAN.md +753 -0
  10. data/.claude/25-12-24-LIFECYCLE_HOOKS_PLAN.md +421 -0
  11. data/.claude/25-12-24-PUBLISHING_AND_DOGFOODING_PLAN.md +327 -0
  12. data/.claude/25-12-24-TEMPLATE_RENDERING_PLAN.md +704 -0
  13. data/.claude/DECISIONS.md +397 -0
  14. data/.claude/PROJECT_PLAN.md +80 -0
  15. data/.claude/TESTING_PLAN.md +285 -0
  16. data/.claude/TESTING_STATUS.md +157 -0
  17. data/.tool-versions +1 -0
  18. data/AGENTS.md +416 -0
  19. data/CHANGELOG.md +5 -0
  20. data/CODE_OF_CONDUCT.md +132 -0
  21. data/LICENSE.txt +21 -0
  22. data/README.md +660 -0
  23. data/Rakefile +10 -0
  24. data/docs +8 -0
  25. data/docs-site/.gitignore +3 -0
  26. data/docs-site/Gemfile +9 -0
  27. data/docs-site/app.rb +138 -0
  28. data/docs-site/content/essential/handler.md +156 -0
  29. data/docs-site/content/essential/lifecycle.md +161 -0
  30. data/docs-site/content/essential/middleware.md +201 -0
  31. data/docs-site/content/essential/openapi.md +155 -0
  32. data/docs-site/content/essential/routing.md +123 -0
  33. data/docs-site/content/essential/validation.md +166 -0
  34. data/docs-site/content/getting-started/at-glance.md +82 -0
  35. data/docs-site/content/getting-started/key-concepts.md +150 -0
  36. data/docs-site/content/getting-started/quick-start.md +127 -0
  37. data/docs-site/content/index.md +81 -0
  38. data/docs-site/content/patterns/async-operations.md +137 -0
  39. data/docs-site/content/patterns/background-tasks.md +143 -0
  40. data/docs-site/content/patterns/database.md +175 -0
  41. data/docs-site/content/patterns/dependencies.md +141 -0
  42. data/docs-site/content/patterns/deployment.md +212 -0
  43. data/docs-site/content/patterns/error-handling.md +184 -0
  44. data/docs-site/content/patterns/response-schema.md +159 -0
  45. data/docs-site/content/patterns/templates.md +193 -0
  46. data/docs-site/content/patterns/testing.md +218 -0
  47. data/docs-site/mise.toml +2 -0
  48. data/docs-site/public/css/style.css +234 -0
  49. data/docs-site/templates/layouts/docs.html.erb +28 -0
  50. data/docs-site/templates/page.html.erb +3 -0
  51. data/docs-site/templates/partials/_nav.html.erb +19 -0
  52. data/examples/background_tasks_demo.rb +159 -0
  53. data/examples/demo_middleware.rb +55 -0
  54. data/examples/demo_openapi.rb +63 -0
  55. data/examples/dependency_block_demo.rb +150 -0
  56. data/examples/dependency_cleanup_demo.rb +146 -0
  57. data/examples/dependency_injection_demo.rb +200 -0
  58. data/examples/lifecycle_demo.rb +57 -0
  59. data/examples/middleware_demo.rb +74 -0
  60. data/examples/templates/layouts/application.html.erb +66 -0
  61. data/examples/templates/todos/_todo.html.erb +15 -0
  62. data/examples/templates/todos/index.html.erb +12 -0
  63. data/examples/templates_demo.rb +87 -0
  64. data/lib/funapi/application.rb +521 -0
  65. data/lib/funapi/async.rb +57 -0
  66. data/lib/funapi/background_tasks.rb +52 -0
  67. data/lib/funapi/config.rb +23 -0
  68. data/lib/funapi/database/sequel/fibered_connection_pool.rb +87 -0
  69. data/lib/funapi/dependency_wrapper.rb +66 -0
  70. data/lib/funapi/depends.rb +138 -0
  71. data/lib/funapi/exceptions.rb +72 -0
  72. data/lib/funapi/middleware/base.rb +13 -0
  73. data/lib/funapi/middleware/cors.rb +23 -0
  74. data/lib/funapi/middleware/request_logger.rb +32 -0
  75. data/lib/funapi/middleware/trusted_host.rb +34 -0
  76. data/lib/funapi/middleware.rb +4 -0
  77. data/lib/funapi/openapi/schema_converter.rb +85 -0
  78. data/lib/funapi/openapi/spec_generator.rb +179 -0
  79. data/lib/funapi/router.rb +43 -0
  80. data/lib/funapi/schema.rb +65 -0
  81. data/lib/funapi/server/falcon.rb +38 -0
  82. data/lib/funapi/template_response.rb +17 -0
  83. data/lib/funapi/templates.rb +111 -0
  84. data/lib/funapi/version.rb +5 -0
  85. data/lib/funapi.rb +14 -0
  86. data/sig/fun_api.rbs +499 -0
  87. metadata +220 -0
data/AGENTS.md ADDED
@@ -0,0 +1,416 @@
1
+ # FunApi - Agent Instructions
2
+
3
+ FunApi is a minimal, async-first Ruby web framework inspired by FastAPI. This file contains essential context for AI coding agents working on this project.
4
+
5
+ ## Project Overview
6
+
7
+ **Goal**: Bring FastAPI's excellent developer experience to Ruby with async-first architecture.
8
+
9
+ **Core Philosophy**:
10
+ - Async-first using Ruby's `Async` library and Falcon server
11
+ - Simple validation with dry-schema
12
+ - Minimal magic, clear explicit APIs
13
+ - Automatic OpenAPI/Swagger documentation
14
+ - Rack-compatible middleware system
15
+
16
+ **Target Ruby Version**: >= 3.2.0
17
+
18
+ ## Setup Commands
19
+
20
+ ```bash
21
+ # Install dependencies
22
+ ./bin/bundle install
23
+
24
+ # Run tests
25
+ ./bin/bundle exec rake test
26
+
27
+ # Run linter (Standard Ruby)
28
+ ./bin/bundle exec rake standard
29
+
30
+ # Run linter with auto-fix
31
+ ./bin/bundle exec standardrb --fix
32
+
33
+ # Run both tests and linting
34
+ ./bin/bundle exec rake
35
+ ```
36
+
37
+ ## Development Workflow
38
+
39
+ ### Running Examples
40
+
41
+ ```bash
42
+ # Middleware demo (port 3000)
43
+ ruby examples/middleware_demo.rb
44
+
45
+ # OpenAPI demo (port 9292)
46
+ ruby test/demo_openapi.rb
47
+
48
+ # Middleware test demo
49
+ ruby test/demo_middleware.rb
50
+ ```
51
+
52
+ ### Testing Changes
53
+
54
+ 1. Run examples to verify functionality manually
55
+ 2. Run `bundle exec rake test` to ensure tests pass
56
+ 3. Run `bundle exec rake standard` to check code style
57
+ 4. Check OpenAPI docs at `http://localhost:PORT/docs` when running examples
58
+
59
+ ## Code Style Guidelines
60
+
61
+ **Linter**: Standard Ruby (standardrb)
62
+ - Ruby version: 3.2 (configured in `.standard.yml`)
63
+ - **IMPORTANT**: DO NOT add comments unless explicitly requested
64
+ - Follow Standard Ruby formatting automatically
65
+
66
+ **Conventions**:
67
+ - Use frozen string literals: `# frozen_string_literal: true`
68
+ - Prefer keyword arguments for options
69
+ - Use Ruby 3+ pattern matching where appropriate
70
+ - Keep methods focused and single-purpose
71
+ - Use descriptive variable names (no abbreviations)
72
+
73
+ **File Organization**:
74
+ - Core framework: `lib/funapi/`
75
+ - Middleware: `lib/funapi/middleware/`
76
+ - OpenAPI: `lib/funapi/openapi/`
77
+ - Server adapters: `lib/funapi/server/`
78
+ - Examples: `examples/`
79
+ - Tests/Demos: `test/`
80
+
81
+ ## Architecture Patterns
82
+
83
+ ### Route Handlers
84
+
85
+ All route handlers receive three parameters:
86
+ ```ruby
87
+ api.get '/path' do |input, req, task|
88
+ # input: { path: {...}, query: {...}, body: {...} }
89
+ # req: Rack::Request object
90
+ # task: Async::Task for concurrent operations
91
+
92
+ [response_data, status_code]
93
+ end
94
+ ```
95
+
96
+ ### Async Operations
97
+
98
+ Use the `task` parameter for concurrent operations:
99
+ ```ruby
100
+ api.get '/dashboard/:id' do |input, req, task|
101
+ user_task = task.async { fetch_user(id) }
102
+ posts_task = task.async { fetch_posts(id) }
103
+
104
+ data = {
105
+ user: user_task.wait,
106
+ posts: posts_task.wait
107
+ }
108
+
109
+ [data, 200]
110
+ end
111
+ ```
112
+
113
+ ### Validation Schemas
114
+
115
+ Use dry-schema for request validation:
116
+ ```ruby
117
+ MySchema = FunApi::Schema.define do
118
+ required(:name).filled(:string)
119
+ optional(:age).filled(:integer)
120
+ end
121
+
122
+ # Apply to routes
123
+ api.post '/users', body: MySchema do |input, req, task|
124
+ user = input[:body] # Already validated
125
+ [user, 201]
126
+ end
127
+ ```
128
+
129
+ ### Middleware
130
+
131
+ Follow standard Rack middleware pattern:
132
+ ```ruby
133
+ class MyMiddleware
134
+ def initialize(app)
135
+ @app = app
136
+ end
137
+
138
+ def call(env)
139
+ # Before request
140
+ status, headers, body = @app.call(env)
141
+ # After request
142
+ [status, headers, body]
143
+ end
144
+ end
145
+
146
+ # Use keyword arguments for options
147
+ class ConfigurableMiddleware
148
+ def initialize(app, **options)
149
+ @app = app
150
+ @option = options[:option]
151
+ end
152
+ end
153
+ ```
154
+
155
+ ### Lifecycle Hooks
156
+
157
+ Run code at startup/shutdown:
158
+ ```ruby
159
+ api.on_startup do
160
+ DB.connect
161
+ Cache.warm
162
+ end
163
+
164
+ api.on_shutdown do
165
+ DB.disconnect
166
+ end
167
+ ```
168
+
169
+ - Multiple hooks allowed (run in registration order)
170
+ - Startup hooks run before server accepts requests
171
+ - Shutdown hooks run after server stops
172
+ - Shutdown errors logged but don't stop other hooks
173
+
174
+ ### Template Rendering
175
+
176
+ Return `TemplateResponse` for HTML instead of JSON:
177
+ ```ruby
178
+ require 'funapi/templates'
179
+
180
+ templates = FunApi::Templates.new(
181
+ directory: 'templates',
182
+ layout: 'layouts/application.html.erb' # optional default layout
183
+ )
184
+
185
+ api.get '/' do |input, req, task|
186
+ templates.response('home.html.erb', title: 'Home', user: current_user)
187
+ end
188
+
189
+ # Disable layout for HTMX partials
190
+ api.post '/items' do |input, req, task|
191
+ templates.response('_item.html.erb', layout: false, item: item, status: 201)
192
+ end
193
+
194
+ # Use with_layout for route groups
195
+ admin = templates.with_layout('layouts/admin.html.erb')
196
+ api.get '/admin' do |input, req, task|
197
+ admin.response('dashboard.html.erb', title: 'Admin')
198
+ end
199
+ ```
200
+
201
+ **Layout templates** use `yield_content`:
202
+ ```erb
203
+ <!DOCTYPE html>
204
+ <html>
205
+ <head><title><%= title %></title></head>
206
+ <body><%= yield_content %></body>
207
+ </html>
208
+ ```
209
+
210
+ **Partials** via `render_partial`:
211
+ ```erb
212
+ <% items.each do |item| %>
213
+ <%= render_partial('_item.html.erb', item: item) %>
214
+ <% end %>
215
+ ```
216
+
217
+ ## Key Files and Their Purpose
218
+
219
+ - `lib/funapi/application.rb` - Main App class, route registration, middleware system
220
+ - `lib/funapi/router.rb` - Route matching and path parameter extraction
221
+ - `lib/funapi/schema.rb` - Validation wrapper around dry-schema
222
+ - `lib/funapi/exceptions.rb` - HTTPException, ValidationError, TemplateNotFoundError
223
+ - `lib/funapi/templates.rb` - ERB template rendering with layouts/partials
224
+ - `lib/funapi/template_response.rb` - HTML response wrapper
225
+ - `lib/funapi/middleware/` - Built-in middleware (CORS, TrustedHost, RequestLogger)
226
+ - `lib/funapi/openapi/` - OpenAPI spec generation from routes and schemas
227
+ - `lib/funapi/server/falcon.rb` - Falcon server integration
228
+
229
+ ## Common Tasks
230
+
231
+ ### Adding a New Built-in Middleware
232
+
233
+ 1. Create file in `lib/funapi/middleware/my_middleware.rb`
234
+ 2. Follow pattern:
235
+ ```ruby
236
+ module FunApi
237
+ module Middleware
238
+ class MyMiddleware
239
+ def initialize(app, **options)
240
+ @app = app
241
+ # Store options
242
+ end
243
+
244
+ def call(env)
245
+ # Middleware logic
246
+ @app.call(env)
247
+ end
248
+ end
249
+ end
250
+ end
251
+ ```
252
+ 3. Add convenience method to `lib/funapi/application.rb`:
253
+ ```ruby
254
+ def add_my_middleware(**options)
255
+ require_relative 'middleware/my_middleware'
256
+ use FunApi::Middleware::MyMiddleware, **options
257
+ end
258
+ ```
259
+ 4. Require in `lib/funapi/middleware.rb`
260
+ 5. Add example to `examples/middleware_demo.rb`
261
+ 6. Update README.md middleware section
262
+
263
+ ### Adding a New Route Helper
264
+
265
+ 1. Add method to `lib/funapi/application.rb`
266
+ 2. Follow existing pattern (get, post, put, patch, delete)
267
+ 3. Use `add_route` internally with proper verb
268
+
269
+ ### Extending OpenAPI Generation
270
+
271
+ 1. Schema conversion: `lib/funapi/openapi/schema_converter.rb`
272
+ 2. Spec generation: `lib/funapi/openapi/spec_generator.rb`
273
+ 3. Test with `ruby test/demo_openapi.rb` and check `/docs`
274
+
275
+ ## Testing Instructions
276
+
277
+ **Test Framework**: Minitest
278
+ **Test Structure**: Flat (following Sidekiq pattern)
279
+ **Current Status**: 174 tests, 487 assertions, all passing (~220ms)
280
+
281
+ ### Running Tests
282
+
283
+ ```bash
284
+ # All tests
285
+ bundle exec rake test
286
+
287
+ # Single test file
288
+ bundle exec ruby -Itest test/test_router.rb
289
+
290
+ # Single test
291
+ bundle exec ruby -Itest test/test_router.rb -n test_root_route_matches
292
+
293
+ # Tests + linting
294
+ bundle exec rake
295
+ ```
296
+
297
+ ### Test Files
298
+
299
+ All tests live in `test/` (flat structure):
300
+ - `test_fun_api.rb` - Basic smoke tests (10 tests)
301
+ - `test_router.rb` - Router functionality (11 tests)
302
+ - `test_schema.rb` - Schema validation (14 tests)
303
+ - `test_middleware.rb` - Middleware chain (12 tests)
304
+ - `test_validation.rb` - Request validation (14 tests)
305
+ - `test_response_schema.rb` - Response filtering (9 tests)
306
+ - `test_async.rb` - Async operations (10 tests)
307
+ - `test_exceptions.rb` - Error handling (10 tests)
308
+ - `test_templates.rb` - Template rendering (37 tests)
309
+ - `test_lifecycle.rb` - Lifecycle hooks (14 tests)
310
+
311
+ ### Writing Tests
312
+
313
+ Follow existing patterns:
314
+ ```ruby
315
+ class TestMyFeature < Minitest::Test
316
+ def async_request(app, method, path, **options)
317
+ Async do
318
+ Rack::MockRequest.new(app).send(method, path, **options)
319
+ end.wait
320
+ end
321
+
322
+ def test_something
323
+ app = FunApi::App.new do |api|
324
+ api.get '/test' do |input, req, task|
325
+ [{ message: 'test' }, 200]
326
+ end
327
+ end
328
+
329
+ res = async_request(app, :get, '/test')
330
+ assert_equal 200, res.status
331
+ end
332
+ end
333
+ ```
334
+
335
+ ### Test Coverage
336
+
337
+ ✅ Router (path matching, parameters, 404s)
338
+ ✅ Schema validation (success, failure, errors, arrays)
339
+ ✅ Middleware (chain building, ordering, built-ins)
340
+ ✅ Request validation (query/body, error format)
341
+ ✅ Response schemas (filtering, arrays, nested)
342
+ ✅ Async operations (concurrency, timeouts, dependencies)
343
+ ✅ Exceptions (HTTPException, custom errors)
344
+ ✅ Templates (rendering, layouts, partials, with_layout)
345
+ ✅ Lifecycle hooks (startup/shutdown, error handling)
346
+
347
+ ### Manual Testing
348
+
349
+ 1. Run example apps in `examples/`
350
+ 2. Test with curl:
351
+ ```bash
352
+ curl http://localhost:3000/
353
+ curl -X POST http://localhost:3000/users \
354
+ -H 'Content-Type: application/json' \
355
+ -d '{"name":"Test","email":"test@example.com"}'
356
+ ```
357
+ 3. Check OpenAPI docs at `/docs`
358
+ 4. Verify middleware behavior (CORS headers, logging, etc.)
359
+
360
+ ### Before Committing
361
+
362
+ - Run `bundle exec rake` (tests + linting)
363
+ - Ensure all tests pass
364
+ - Check no temporary files in project root
365
+ - Update tests if adding new features
366
+
367
+ ## Security Considerations
368
+
369
+ - **Sensitive Data**: Never log passwords, tokens, or API keys
370
+ - **Response Schemas**: Use response_schema to filter sensitive fields from responses
371
+ - **Trusted Host**: Always use `add_trusted_host` in production
372
+ - **CORS**: Configure `add_cors` with specific origins, not `['*']` in production
373
+ - **Validation**: Always validate user input with schemas
374
+
375
+ ## Common Pitfalls
376
+
377
+ 1. **Root Route Bug**: The router has special handling for `/` - don't change it
378
+ 2. **Keyword Arguments**: Middleware must accept `**options`, not positional args
379
+ 3. **Async Context**: Route handlers must be called within Async::Task context
380
+ 4. **Path Params**: Always strings in `input[:path]`, convert types manually
381
+ 5. **Response Format**: Must return `[data, status_code]` from handlers
382
+ 6. **Middleware Order**: First registered runs first (FIFO execution, LIFO wrapping)
383
+
384
+ ## Dependencies
385
+
386
+ **Core**:
387
+ - `async` (>= 2.8) - Async/concurrency primitives
388
+ - `falcon` (>= 0.44) - Async HTTP server
389
+ - `rack` (>= 3.0.0) - Web server interface
390
+ - `dry-schema` (>= 1.13) - Validation
391
+
392
+ **Middleware**:
393
+ - `rack-cors` (>= 2.0) - CORS support
394
+
395
+ **Development**:
396
+ - `standard` - Ruby style guide and linter
397
+ - `minitest` - Testing framework
398
+
399
+
400
+ ## Future Enhancements Roadmap
401
+
402
+ See `README.md` for full list. Key priorities:
403
+ 1. ~~Dependency injection system~~ ✅ Done
404
+ 2. ~~Background tasks~~ ✅ Done
405
+ 3. ~~Template rendering~~ ✅ Done
406
+ 4. ~~Lifecycle hooks (startup/shutdown)~~ ✅ Done
407
+ 5. Path parameter type validation
408
+ 6. WebSocket support
409
+
410
+ ## Questions?
411
+
412
+ Check these resources:
413
+ - `/examples` - Working demo applications
414
+ - `/test` - Demo scripts showing features
415
+ - `/.claude` - Implementation plans and notes
416
+ - `README.md` - User-facing documentation
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-10-12
4
+
5
+ - Initial release
@@ -0,0 +1,132 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official email address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ [INSERT CONTACT METHOD].
64
+ All complaints will be reviewed and investigated promptly and fairly.
65
+
66
+ All community leaders are obligated to respect the privacy and security of the
67
+ reporter of any incident.
68
+
69
+ ## Enforcement Guidelines
70
+
71
+ Community leaders will follow these Community Impact Guidelines in determining
72
+ the consequences for any action they deem in violation of this Code of Conduct:
73
+
74
+ ### 1. Correction
75
+
76
+ **Community Impact**: Use of inappropriate language or other behavior deemed
77
+ unprofessional or unwelcome in the community.
78
+
79
+ **Consequence**: A private, written warning from community leaders, providing
80
+ clarity around the nature of the violation and an explanation of why the
81
+ behavior was inappropriate. A public apology may be requested.
82
+
83
+ ### 2. Warning
84
+
85
+ **Community Impact**: A violation through a single incident or series of
86
+ actions.
87
+
88
+ **Consequence**: A warning with consequences for continued behavior. No
89
+ interaction with the people involved, including unsolicited interaction with
90
+ those enforcing the Code of Conduct, for a specified period of time. This
91
+ includes avoiding interactions in community spaces as well as external channels
92
+ like social media. Violating these terms may lead to a temporary or permanent
93
+ ban.
94
+
95
+ ### 3. Temporary Ban
96
+
97
+ **Community Impact**: A serious violation of community standards, including
98
+ sustained inappropriate behavior.
99
+
100
+ **Consequence**: A temporary ban from any sort of interaction or public
101
+ communication with the community for a specified period of time. No public or
102
+ private interaction with the people involved, including unsolicited interaction
103
+ with those enforcing the Code of Conduct, is allowed during this period.
104
+ Violating these terms may lead to a permanent ban.
105
+
106
+ ### 4. Permanent Ban
107
+
108
+ **Community Impact**: Demonstrating a pattern of violation of community
109
+ standards, including sustained inappropriate behavior, harassment of an
110
+ individual, or aggression toward or disparagement of classes of individuals.
111
+
112
+ **Consequence**: A permanent ban from any sort of public interaction within the
113
+ community.
114
+
115
+ ## Attribution
116
+
117
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
+ version 2.1, available at
119
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120
+
121
+ Community Impact Guidelines were inspired by
122
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123
+
124
+ For answers to common questions about this code of conduct, see the FAQ at
125
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
126
+ [https://www.contributor-covenant.org/translations][translations].
127
+
128
+ [homepage]: https://www.contributor-covenant.org
129
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130
+ [Mozilla CoC]: https://github.com/mozilla/diversity
131
+ [FAQ]: https://www.contributor-covenant.org/faq
132
+ [translations]: https://www.contributor-covenant.org/translations
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Felipe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.