bug_bunny 3.1.5 → 3.1.6
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/CHANGELOG.md +8 -0
- data/lib/bug_bunny/consumer.rb +33 -14
- data/lib/bug_bunny/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7fec9f487076682121e6d8586e44fe9d70f380bd809fb46014265105421a0d8f
|
|
4
|
+
data.tar.gz: e847fc6f1943f9921f2250a46a20bd6f76b20736812fcbf6bfc437ab49a8a30c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 199faaa596f52cc1c192259e8fe3e7da95152d117db9ded079051bebdff985793e63acde11cb8ceed5e0e216d6934ff35056993947609f2818d8429f524a789a
|
|
7
|
+
data.tar.gz: dfefdd78b4597f90dc059ef07d7423dda86d2630cdab409c514941708cc539d174a763d1a6e18c918dee7058d25c0a996aac0bb52f1b440573b42480e723e284
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
## [3.1.6] - 2026-02-27
|
|
3
|
+
|
|
4
|
+
### 🐛 Bug Fixes & Router Improvements
|
|
5
|
+
* **Enhanced Heuristic Router (ID Detection):** Mejoras críticas en `Consumer#router_dispatch` para soportar una gama mucho más amplia de formatos de identificadores y evitar colisiones con namespaces:
|
|
6
|
+
* **Soporte para Swarm/NanoID:** Se amplió la expresión regular de detección de IDs para capturar hashes alfanuméricos de 20 o más caracteres (`[a-zA-Z0-9_-]{20,}`), permitiendo el correcto ruteo de IDs generados por Docker Swarm (25 caracteres) o NanoID.
|
|
7
|
+
* **Escaneo Inverso (Right-to-Left):** Se modificó la búsqueda del ID para que escanee los segmentos de la URL desde el final hacia el principio (`rindex`). Esto evita falsos positivos donde namespaces cortos como `v1` (ej. `api/v1/...`) eran confundidos accidentalmente con un ID.
|
|
8
|
+
* **Fallback Semántico Posicional:** Se introdujo una red de seguridad (fallback) que infiere la posición del ID basándose en el Verbo HTTP. Si el ID no coincide con ningún patrón Regex (ej. es un ID corto como `node-1`), pero el método es `PUT`, `PATCH` o `DELETE`, el enrutador ahora asume inteligentemente que el penúltimo/último segmento corresponde al ID del recurso.
|
|
9
|
+
|
|
2
10
|
## [3.1.5] - 2026-02-25
|
|
3
11
|
|
|
4
12
|
### ✨ New Features & Improvements
|
data/lib/bug_bunny/consumer.rb
CHANGED
|
@@ -180,7 +180,7 @@ module BugBunny
|
|
|
180
180
|
# Interpreta la URL y el verbo para decidir qué controlador ejecutar.
|
|
181
181
|
#
|
|
182
182
|
# Implementa un Router Heurístico que soporta namespaces y acciones custom
|
|
183
|
-
# buscando dinámicamente el ID en la ruta.
|
|
183
|
+
# buscando dinámicamente el ID en la ruta mediante Regex y Fallback Semántico.
|
|
184
184
|
#
|
|
185
185
|
# @param method [String] Verbo HTTP (GET, POST, etc).
|
|
186
186
|
# @param path [String] URL virtual del recurso (ej: 'foo/bar/algo/13/test').
|
|
@@ -196,30 +196,49 @@ module BugBunny
|
|
|
196
196
|
|
|
197
197
|
# 1. Acción Built-in: Health Check Global (/up o /api/up)
|
|
198
198
|
if segments.last == 'up' && method.to_s.upcase == 'GET'
|
|
199
|
-
# Si la ruta es solo 'up', usamos un controlador genérico 'application'
|
|
200
199
|
ctrl = segments.size > 1 ? segments[0...-1].join('/') : 'application'
|
|
201
200
|
return { controller: ctrl, action: 'up', id: nil, params: query_params }
|
|
202
201
|
end
|
|
203
202
|
|
|
204
|
-
# 2. Búsqueda dinámica del ID (Heurística)
|
|
205
|
-
# Patrón:
|
|
206
|
-
id_pattern = /^(?:\d+|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|[
|
|
207
|
-
id_index = segments.find_index { |s| s.match?(id_pattern) }
|
|
203
|
+
# 2. Búsqueda dinámica del ID (Heurística por Regex)
|
|
204
|
+
# Patrón: Enteros, UUIDs, o Hashes largos (Docker Swarm 25 chars, Mongo 24 chars)
|
|
205
|
+
id_pattern = /^(?:\d+|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|[a-zA-Z0-9_-]{20,})$/
|
|
208
206
|
|
|
207
|
+
# FIX: Usamos rindex (de derecha a izquierda) para evitar falsos positivos con namespaces como 'v1'
|
|
208
|
+
id_index = segments.rindex { |s| s.match?(id_pattern) }
|
|
209
|
+
|
|
210
|
+
# 3. Fallback Semántico Posicional
|
|
211
|
+
# Si el regex no detectó el ID (ej: ID corto como "node-1"), pero la semántica HTTP
|
|
212
|
+
# indica que es una operación singular (PUT/DELETE/GET), asumimos que el último segmento es el ID.
|
|
213
|
+
if id_index.nil? && segments.size >= 2
|
|
214
|
+
last_segment = segments.last
|
|
215
|
+
method_up = method.to_s.upcase
|
|
216
|
+
|
|
217
|
+
is_member_verb = %w[PUT PATCH DELETE].include?(method_up)
|
|
218
|
+
# En GET, nos aseguramos que la última palabra no sea una acción estándar de REST
|
|
219
|
+
is_get_member = method_up == 'GET' && !%w[index new edit up action].include?(last_segment)
|
|
220
|
+
|
|
221
|
+
if is_member_verb || is_get_member
|
|
222
|
+
# Si tiene 3 o más segmentos (ej. nodes/node-1/stats), el ID no está al final.
|
|
223
|
+
# Este fallback asume que para IDs raros, el formato clásico es recurso/id
|
|
224
|
+
id_index = segments.size - 1
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# 4. Asignación de variables según escenario
|
|
209
229
|
if id_index
|
|
210
|
-
# ESCENARIO A: Ruta Miembro (ej.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
action = segments[id_index + 1] # "test" (puede ser nil)
|
|
230
|
+
# ESCENARIO A: Ruta Miembro (ej. nodes/4bv445vgc158hk4twlxmdjo0v/stats)
|
|
231
|
+
controller_name = segments[0...id_index].join('/')
|
|
232
|
+
id = segments[id_index]
|
|
233
|
+
action = segments[id_index + 1] # Puede ser nil si no hay acción extra al final
|
|
215
234
|
else
|
|
216
|
-
# ESCENARIO B: Ruta Colección (ej.
|
|
235
|
+
# ESCENARIO B: Ruta Colección (ej. api/v1/nodes)
|
|
217
236
|
controller_name = segments.join('/')
|
|
218
237
|
id = nil
|
|
219
238
|
action = nil
|
|
220
239
|
end
|
|
221
240
|
|
|
222
|
-
#
|
|
241
|
+
# 5. Inferimos la acción clásica de Rails si no hay una explícita
|
|
223
242
|
unless action
|
|
224
243
|
action = case method.to_s.upcase
|
|
225
244
|
when 'GET' then id ? 'show' : 'index'
|
|
@@ -230,7 +249,7 @@ module BugBunny
|
|
|
230
249
|
end
|
|
231
250
|
end
|
|
232
251
|
|
|
233
|
-
#
|
|
252
|
+
# 6. Inyectamos el ID en los parámetros para fácil acceso en el Controlador
|
|
234
253
|
query_params['id'] = id if id
|
|
235
254
|
|
|
236
255
|
{ controller: controller_name, action: action, id: id, params: query_params }
|
data/lib/bug_bunny/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bug_bunny
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- gabix
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-02-
|
|
11
|
+
date: 2026-02-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bunny
|