heimdall-api-platform 1.7.0 → 1.8.1

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 (80) hide show
  1. package/dist/lib/clients/http-client.js +1 -1
  2. package/dist/lib/environment.js +1 -1
  3. package/dist/lib/factory/api-gateway.js +1 -1
  4. package/dist/lib/factory/client-factory.js +1 -1
  5. package/dist/lib/factory/function-factory.js +1 -1
  6. package/dist/lib/factory/operation-flow-factory.js +1 -1
  7. package/dist/lib/factory/server-factory.js +1 -1
  8. package/dist/lib/factory/transformation-function-factory.js +1 -1
  9. package/dist/lib/handle-route.js +1 -1
  10. package/dist/lib/index.js +1 -1
  11. package/dist/lib/integrations/commons-elasticsearch.js +1 -1
  12. package/dist/lib/integrations/commons-opensearch.js +1 -1
  13. package/dist/lib/integrations/commons-splunk.js +1 -1
  14. package/dist/lib/license/license-service.js +1 -1
  15. package/dist/lib/models/base-context.js +1 -1
  16. package/dist/lib/models/flow-context.js +1 -1
  17. package/dist/lib/models/monitor-request-view.js +1 -1
  18. package/dist/lib/models/route-context.js +1 -1
  19. package/dist/lib/models/security-route.js +1 -1
  20. package/dist/lib/models/service-context.js +1 -1
  21. package/dist/lib/models/service-group.js +1 -1
  22. package/dist/lib/models/service-route.js +1 -1
  23. package/dist/lib/models/splunk-data.js +1 -1
  24. package/dist/lib/observability/models/monitor-flow-step.js +1 -1
  25. package/dist/lib/observability/models/monitor-function-operation.js +1 -1
  26. package/dist/lib/observability/models/monitor-function-transformation.js +1 -1
  27. package/dist/lib/observability/models/monitor-http-operation.js +1 -1
  28. package/dist/lib/observability/models/monitor-mock-operation.js +1 -1
  29. package/dist/lib/observability/monitor-event-bus.js +1 -1
  30. package/dist/lib/observability/monitor-event.js +1 -1
  31. package/dist/lib/observability/subscribers/monitor-event-subscriber.js +1 -1
  32. package/dist/lib/observability/subscribers/opensearch-event-subscriber.js +1 -1
  33. package/dist/lib/observability/subscribers/redis-event-subscriber.js +1 -1
  34. package/dist/lib/observability/subscribers/splunk-event-subscriber.js +1 -1
  35. package/dist/lib/operations/abstract-operation.js +1 -1
  36. package/dist/lib/operations/function.js +1 -1
  37. package/dist/lib/operations/http.js +1 -1
  38. package/dist/lib/operations/mock.js +1 -1
  39. package/dist/lib/operations/monitor-check.js +1 -1
  40. package/dist/lib/orchestration-flow.js +1 -1
  41. package/dist/lib/router.js +1 -1
  42. package/dist/lib/routes/default-routes-admin.js +1 -1
  43. package/dist/lib/routes/default-routes-docs.js +1 -1
  44. package/dist/lib/routes/default-routes-monitor-metrics.js +1 -1
  45. package/dist/lib/routes/default-routes-opensearch.js +1 -1
  46. package/dist/lib/routes/default-routes-pos.js +1 -1
  47. package/dist/lib/routes/default-routes-pre.js +1 -1
  48. package/dist/lib/routes/native-routes-catalog.js +1 -1
  49. package/dist/lib/security/api-key-validator.js +1 -1
  50. package/dist/lib/security/jwt-util.js +1 -1
  51. package/dist/lib/security/quota-enforcer.js +1 -1
  52. package/dist/lib/security/rate-limiter.js +1 -1
  53. package/dist/lib/security/security-validation.js +1 -1
  54. package/dist/lib/services/api-key-service.js +1 -1
  55. package/dist/lib/services/consumer-service.js +1 -1
  56. package/dist/lib/services/fixed-window-rate-limit-service.js +1 -1
  57. package/dist/lib/services/health-service.js +1 -1
  58. package/dist/lib/services/metrics-service.js +1 -1
  59. package/dist/lib/services/monitor-metrics-service.js +1 -1
  60. package/dist/lib/services/quota-service.js +1 -1
  61. package/dist/lib/services/rate-limit-service.js +1 -1
  62. package/dist/lib/services/server.js +1 -1
  63. package/dist/lib/services/template-monitorcheck-route.js +1 -1
  64. package/dist/lib/storage/key-value-storage.js +1 -1
  65. package/dist/lib/utils/commons-cache.js +1 -1
  66. package/dist/lib/utils/commons-const.js +1 -1
  67. package/dist/lib/utils/commons-context.js +1 -1
  68. package/dist/lib/utils/commons-cookie.js +1 -1
  69. package/dist/lib/utils/commons-date.js +1 -1
  70. package/dist/lib/utils/commons-encoding.js +1 -1
  71. package/dist/lib/utils/commons-errors.js +1 -1
  72. package/dist/lib/utils/commons-logger.js +1 -1
  73. package/dist/lib/utils/commons-trace.js +1 -1
  74. package/dist/lib/utils/commons-util.js +1 -1
  75. package/dist/lib/utils/document-utils.js +1 -1
  76. package/dist/lib/utils/monitor-filter-builder.js +1 -1
  77. package/dist/public/redoc.html +8 -10
  78. package/dist/public/scalardoc.html +40 -10
  79. package/dist/public/swagger.html +842 -145
  80. package/package.json +4 -3
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="pt-BR" data-theme="light">
2
+ <html lang="pt-BR">
3
3
 
4
4
  <head>
5
5
  <meta charset="UTF-8"/>
@@ -8,21 +8,21 @@
8
8
  content="Heimdall API Platform - Microgateway de alta performance para APIs, com orquestração inteligente, roteamento dinâmico e integração entre microsserviços"/>
9
9
  <meta name="keywords"
10
10
  content="API Gateway, microgateway, orquestração, roteamento dinâmico, Node.js, Redis, OpenSearch, Swagger, microsserviços, REST API, cache, throttling, observabilidade"/>
11
- <meta name="author" content="P4F - Protonss4Fun"/>
11
+ <meta name="author" content="P4F"/>
12
12
  <meta name="theme-color" content="#003d7a"/>
13
13
  <meta property="og:title" content="Heimdall API Platform - Interactive Documentation"/>
14
14
  <meta property="og:description"
15
15
  content="Microgateway de alta performance com orquestração inteligente e roteamento dinâmico para APIs"/>
16
16
  <meta property="og:type" content="website"/>
17
- <meta property="og:url" content="https://www.protonss4fun.com.br"/>
18
- <meta property="og:image" content="https://p4f.dev/img/logo-p4f.svg"/>
17
+ <meta property="og:url" content="https://p4f.dev"/>
18
+ <meta property="og:image" content="https://p4f.dev/img/logo-p4f.png"/>
19
19
  <meta name="twitter:card" content="summary_large_image"/>
20
20
  <meta name="twitter:title" content="Heimdall API Platform - Interactive Documentation"/>
21
21
  <meta name="twitter:description"
22
22
  content="Microgateway de alta performance com orquestração inteligente e roteamento dinâmico para APIs"/>
23
23
  <title>Heimdall API Platform - Interactive Documentation | Swagger UI</title>
24
24
 
25
- <link rel="icon" href="https://p4f.dev/img/logo-p4f.svg" type="image/svg+xml"/>
25
+ <link rel="icon" href="https://p4f.dev/favicon.ico" type="image/x-icon"/>
26
26
  <link rel="preconnect" href="https://fonts.googleapis.com"/>
27
27
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
28
28
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"
@@ -33,43 +33,48 @@
33
33
  <script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist/swagger-ui-standalone-preset.js"></script>
34
34
 
35
35
  <style>
36
+ /*
37
+ * Design tokens — always-dark theme inspired by Vercel/Linear/Stripe:
38
+ * true neutrals (no blue-tinted slate), low-contrast borders, single
39
+ * sky accent reserved for interactive surfaces, semantic method
40
+ * colors for HTTP verbs. The P4F logo PNG is white-on-transparent,
41
+ * so the light theme was dropped entirely.
42
+ */
36
43
  :root {
37
- --primary-color: #003d7a;
38
- --primary-hover: #002b5a;
44
+ --primary-color: #38bdf8;
45
+ --primary-hover: #7dd3fc;
39
46
  --secondary-color: #b8d430;
40
- --accent-color: #0ea5e9;
41
- --bg-primary: #ffffff;
42
- --bg-secondary: #f8fafc;
43
- --bg-tertiary: #f1f5f9;
44
- --text-primary: #0f172a;
45
- --text-secondary: #475569;
46
- --text-tertiary: #64748b;
47
- --border-color: #e2e8f0;
48
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
49
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
50
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
51
- --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
47
+ --accent-color: #22d3ee;
48
+
49
+ --bg-primary: #000000;
50
+ --bg-secondary: #0a0a0a;
51
+ --bg-tertiary: #141414;
52
+ --bg-elevated: #1c1c1c;
53
+
54
+ --border-color: #1f1f1f;
55
+ --border-strong: #2e2e2e;
56
+
57
+ --text-primary: #fafafa;
58
+ --text-secondary: #a3a3a3;
59
+ --text-tertiary: #737373;
60
+ --text-muted: #525252;
61
+
62
+ --method-get: #10b981;
63
+ --method-post: #3b82f6;
64
+ --method-put: #f59e0b;
65
+ --method-delete: #ef4444;
66
+ --method-patch: #8b5cf6;
67
+
68
+ --font-mono: 'JetBrains Mono', 'SF Mono', Monaco, Menlo, Consolas, monospace;
69
+
70
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
71
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.55), 0 2px 4px -1px rgba(0, 0, 0, 0.45);
72
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.6), 0 4px 6px -2px rgba(0, 0, 0, 0.5);
73
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.7), 0 10px 10px -5px rgba(0, 0, 0, 0.6);
74
+
52
75
  --navbar-height: 64px;
53
76
  --footer-height: 80px;
54
- --transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
55
- }
56
-
57
- [data-theme="dark"] {
58
- --primary-color: #0ea5e9;
59
- --primary-hover: #0284c7;
60
- --secondary-color: #b8d430;
61
- --accent-color: #22d3ee;
62
- --bg-primary: #0f172a;
63
- --bg-secondary: #1e293b;
64
- --bg-tertiary: #334155;
65
- --text-primary: #f8fafc;
66
- --text-secondary: #cbd5e1;
67
- --text-tertiary: #94a3b8;
68
- --border-color: #334155;
69
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
70
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
71
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4);
72
- --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 10px 10px -5px rgba(0, 0, 0, 0.5);
77
+ --transition-smooth: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
73
78
  }
74
79
 
75
80
  * {
@@ -154,15 +159,16 @@
154
159
  .navbar__badge {
155
160
  display: inline-flex;
156
161
  align-items: center;
157
- padding: 4px 12px;
158
- background: linear-gradient(135deg, #3B82F6, #06B6D4);
159
- color: white;
160
- border-radius: 16px;
161
- font-size: 12px;
162
- font-weight: 600;
163
- letter-spacing: 0.02em;
162
+ padding: 3px 10px;
163
+ background: var(--bg-tertiary);
164
+ color: var(--text-secondary);
165
+ border: 1px solid var(--border-color);
166
+ border-radius: 999px;
167
+ font-size: 11px;
168
+ font-weight: 500;
169
+ letter-spacing: 0.06em;
164
170
  text-transform: uppercase;
165
- box-shadow: var(--shadow-sm);
171
+ font-family: var(--font-mono);
166
172
  }
167
173
 
168
174
  .navbar__right {
@@ -205,31 +211,6 @@
205
211
  width: 100%;
206
212
  }
207
213
 
208
- .theme-toggle {
209
- display: flex;
210
- align-items: center;
211
- justify-content: center;
212
- width: 40px;
213
- height: 40px;
214
- border: none;
215
- background: var(--bg-tertiary);
216
- border-radius: 10px;
217
- cursor: pointer;
218
- transition: var(--transition-smooth);
219
- color: var(--text-primary);
220
- font-size: 18px;
221
- }
222
-
223
- .theme-toggle:hover {
224
- background: var(--primary-color);
225
- color: white;
226
- transform: rotate(15deg) scale(1.05);
227
- }
228
-
229
- .theme-toggle:active {
230
- transform: rotate(15deg) scale(0.95);
231
- }
232
-
233
214
  .status-badge {
234
215
  display: inline-flex;
235
216
  align-items: center;
@@ -262,30 +243,765 @@
262
243
  #swagger-ui {
263
244
  margin: 0 auto;
264
245
  max-width: 1440px;
265
- padding: 16px 24px;
246
+ padding: 24px;
266
247
  min-height: calc(100vh - var(--navbar-height) - var(--footer-height));
267
248
  }
268
249
 
269
- [data-theme="dark"] #swagger-ui {
270
- filter: invert(0.88) hue-rotate(180deg);
271
- }
272
-
273
- [data-theme="dark"] #swagger-ui img,
274
- [data-theme="dark"] #swagger-ui .swagger-ui .opblock-tag,
275
- [data-theme="dark"] #swagger-ui .swagger-ui .opblock {
276
- filter: invert(0.88) hue-rotate(180deg);
250
+ /* ============================================================
251
+ * Swagger UI — dark theme overrides.
252
+ *
253
+ * We target the bundled `swagger-ui.css` classes directly instead
254
+ * of relying on the `filter: invert + hue-rotate` hack (which
255
+ * washes out colors, breaks icons and produces inconsistent
256
+ * rendering). The result is a single-tone dark surface that mirrors
257
+ * Vercel/Linear/Stripe conventions: true neutrals, low-contrast
258
+ * borders, accent only on interactive elements, semantic method
259
+ * colors for badges.
260
+ * ============================================================ */
261
+
262
+ .swagger-ui {
263
+ color: var(--text-primary);
264
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
277
265
  }
278
266
 
279
267
  .swagger-ui .topbar {
280
268
  display: none;
281
269
  }
282
270
 
271
+ /* Info block (title, description, contact, license) */
272
+ .swagger-ui .info {
273
+ margin: 24px 0 32px;
274
+ }
275
+
276
+ .swagger-ui .info .title {
277
+ color: var(--text-primary);
278
+ font-size: 32px;
279
+ font-weight: 700;
280
+ letter-spacing: -0.025em;
281
+ }
282
+
283
+ .swagger-ui .info .title small,
284
+ .swagger-ui .info .title small.version-stamp {
285
+ background: var(--bg-tertiary);
286
+ color: var(--text-secondary);
287
+ border: 1px solid var(--border-color);
288
+ border-radius: 6px;
289
+ padding: 3px 10px;
290
+ margin-left: 12px;
291
+ font-size: 13px;
292
+ font-weight: 500;
293
+ font-family: var(--font-mono);
294
+ }
295
+
296
+ .swagger-ui .info .title small pre {
297
+ background: transparent;
298
+ border: none;
299
+ padding: 0;
300
+ color: inherit;
301
+ font-family: inherit;
302
+ }
303
+
304
+ .swagger-ui .info p,
305
+ .swagger-ui .info li,
306
+ .swagger-ui .info table,
307
+ .swagger-ui .markdown p,
308
+ .swagger-ui .markdown li,
309
+ .swagger-ui .renderedMarkdown p,
310
+ .swagger-ui .renderedMarkdown li {
311
+ color: var(--text-secondary);
312
+ font-size: 14px;
313
+ line-height: 1.65;
314
+ }
315
+
316
+ .swagger-ui .info h1,
317
+ .swagger-ui .info h2,
318
+ .swagger-ui .info h3,
319
+ .swagger-ui .info h4,
320
+ .swagger-ui .markdown h1,
321
+ .swagger-ui .markdown h2,
322
+ .swagger-ui .markdown h3,
323
+ .swagger-ui .markdown h4 {
324
+ color: var(--text-primary);
325
+ font-weight: 600;
326
+ letter-spacing: -0.015em;
327
+ }
328
+
329
+ .swagger-ui a,
330
+ .swagger-ui .info a,
331
+ .swagger-ui .markdown a {
332
+ color: var(--primary-color);
333
+ text-decoration: none;
334
+ transition: color 0.15s ease;
335
+ }
336
+
337
+ .swagger-ui a:hover,
338
+ .swagger-ui .info a:hover,
339
+ .swagger-ui .markdown a:hover {
340
+ color: var(--primary-hover);
341
+ text-decoration: underline;
342
+ }
343
+
344
+ /* Inline code in descriptions */
345
+ .swagger-ui code,
346
+ .swagger-ui .info code,
347
+ .swagger-ui .markdown code,
348
+ .swagger-ui .renderedMarkdown code {
349
+ background: var(--bg-tertiary);
350
+ color: var(--primary-hover);
351
+ border: 1px solid var(--border-color);
352
+ padding: 1px 6px;
353
+ border-radius: 4px;
354
+ font-family: var(--font-mono);
355
+ font-size: 12.5px;
356
+ }
357
+
358
+ /* Server selector / scheme container */
359
+ .swagger-ui .scheme-container {
360
+ background: var(--bg-secondary);
361
+ border: 1px solid var(--border-color);
362
+ border-radius: 12px;
363
+ box-shadow: none;
364
+ margin: 0 0 24px;
365
+ padding: 20px;
366
+ }
367
+
368
+ .swagger-ui .scheme-container .schemes-title {
369
+ color: var(--text-secondary);
370
+ font-weight: 500;
371
+ }
372
+
373
+ /* Authorize button (top-right) */
374
+ .swagger-ui .auth-wrapper .authorize {
375
+ background: var(--bg-tertiary);
376
+ color: var(--text-primary);
377
+ border: 1px solid var(--border-color);
378
+ border-radius: 8px;
379
+ padding: 8px 14px;
380
+ font-weight: 500;
381
+ box-shadow: none;
382
+ transition: var(--transition-smooth);
383
+ }
384
+
385
+ .swagger-ui .auth-wrapper .authorize:hover {
386
+ background: var(--bg-elevated);
387
+ border-color: var(--border-strong);
388
+ }
389
+
390
+ .swagger-ui .auth-wrapper .authorize svg {
391
+ fill: var(--text-primary);
392
+ }
393
+
394
+ /* Filter input */
395
+ .swagger-ui .filter-container {
396
+ margin: 0 0 16px;
397
+ }
398
+
399
+ .swagger-ui .filter .operation-filter-input {
400
+ background: var(--bg-secondary);
401
+ color: var(--text-primary);
402
+ border: 1px solid var(--border-color);
403
+ border-radius: 10px;
404
+ padding: 12px 16px;
405
+ box-shadow: none;
406
+ font-size: 14px;
407
+ transition: border-color 0.15s ease;
408
+ }
409
+
410
+ .swagger-ui .filter .operation-filter-input::placeholder {
411
+ color: var(--text-muted);
412
+ }
413
+
414
+ .swagger-ui .filter .operation-filter-input:focus {
415
+ border-color: var(--primary-color);
416
+ outline: 2px solid rgba(56, 189, 248, 0.18);
417
+ outline-offset: 0;
418
+ }
419
+
420
+ /* Tag section heading */
421
+ .swagger-ui .opblock-tag {
422
+ color: var(--text-primary);
423
+ font-size: 20px;
424
+ font-weight: 600;
425
+ letter-spacing: -0.01em;
426
+ border-bottom: 1px solid var(--border-color);
427
+ padding: 16px 0 12px;
428
+ margin-top: 32px;
429
+ }
430
+
431
+ .swagger-ui .opblock-tag:hover {
432
+ background: transparent;
433
+ }
434
+
435
+ .swagger-ui .opblock-tag small,
436
+ .swagger-ui .opblock-tag .renderedMarkdown p {
437
+ color: var(--text-tertiary);
438
+ font-weight: 400;
439
+ font-size: 13px;
440
+ }
441
+
442
+ .swagger-ui .opblock-tag a.nostyle {
443
+ color: var(--text-primary);
444
+ }
445
+
446
+ .swagger-ui .opblock-tag svg,
447
+ .swagger-ui .expand-operation svg,
448
+ .swagger-ui section.models svg,
449
+ .swagger-ui svg.arrow {
450
+ fill: var(--text-secondary);
451
+ }
452
+
453
+ /* Operation block */
454
+ .swagger-ui .opblock {
455
+ background: var(--bg-secondary);
456
+ border: 1px solid var(--border-color);
457
+ border-radius: 12px;
458
+ box-shadow: none;
459
+ margin: 10px 0;
460
+ overflow: hidden;
461
+ transition: border-color 0.15s ease;
462
+ }
463
+
464
+ .swagger-ui .opblock:hover {
465
+ border-color: var(--border-strong);
466
+ }
467
+
468
+ .swagger-ui .opblock .opblock-summary {
469
+ padding: 12px 16px;
470
+ border: none;
471
+ align-items: center;
472
+ gap: 12px;
473
+ }
474
+
475
+ .swagger-ui .opblock .opblock-summary-path,
476
+ .swagger-ui .opblock .opblock-summary-path__deprecated {
477
+ color: var(--text-primary);
478
+ font-family: var(--font-mono);
479
+ font-weight: 600;
480
+ font-size: 14px;
481
+ text-shadow: none;
482
+ }
483
+
484
+ .swagger-ui .opblock .opblock-summary-description {
485
+ color: var(--text-tertiary);
486
+ font-size: 13px;
487
+ }
488
+
489
+ .swagger-ui .opblock .opblock-summary-method {
490
+ border-radius: 6px;
491
+ font-weight: 700;
492
+ font-family: var(--font-mono);
493
+ min-width: 80px;
494
+ text-shadow: none;
495
+ box-shadow: none;
496
+ color: #ffffff;
497
+ }
498
+
499
+ /* Method colors (semantic, uniform across all opblocks) */
500
+ .swagger-ui .opblock.opblock-get {
501
+ background: var(--bg-secondary);
502
+ border-color: rgba(16, 185, 129, 0.25);
503
+ }
504
+ .swagger-ui .opblock.opblock-get .opblock-summary {
505
+ background: rgba(16, 185, 129, 0.06);
506
+ border-color: transparent;
507
+ }
508
+ .swagger-ui .opblock.opblock-get .opblock-summary-method {
509
+ background: var(--method-get);
510
+ }
511
+
512
+ .swagger-ui .opblock.opblock-post {
513
+ background: var(--bg-secondary);
514
+ border-color: rgba(59, 130, 246, 0.25);
515
+ }
516
+ .swagger-ui .opblock.opblock-post .opblock-summary {
517
+ background: rgba(59, 130, 246, 0.06);
518
+ border-color: transparent;
519
+ }
520
+ .swagger-ui .opblock.opblock-post .opblock-summary-method {
521
+ background: var(--method-post);
522
+ }
523
+
524
+ .swagger-ui .opblock.opblock-put {
525
+ background: var(--bg-secondary);
526
+ border-color: rgba(245, 158, 11, 0.25);
527
+ }
528
+ .swagger-ui .opblock.opblock-put .opblock-summary {
529
+ background: rgba(245, 158, 11, 0.06);
530
+ border-color: transparent;
531
+ }
532
+ .swagger-ui .opblock.opblock-put .opblock-summary-method {
533
+ background: var(--method-put);
534
+ }
535
+
536
+ .swagger-ui .opblock.opblock-delete {
537
+ background: var(--bg-secondary);
538
+ border-color: rgba(239, 68, 68, 0.25);
539
+ }
540
+ .swagger-ui .opblock.opblock-delete .opblock-summary {
541
+ background: rgba(239, 68, 68, 0.06);
542
+ border-color: transparent;
543
+ }
544
+ .swagger-ui .opblock.opblock-delete .opblock-summary-method {
545
+ background: var(--method-delete);
546
+ }
547
+
548
+ .swagger-ui .opblock.opblock-patch {
549
+ background: var(--bg-secondary);
550
+ border-color: rgba(139, 92, 246, 0.25);
551
+ }
552
+ .swagger-ui .opblock.opblock-patch .opblock-summary {
553
+ background: rgba(139, 92, 246, 0.06);
554
+ border-color: transparent;
555
+ }
556
+ .swagger-ui .opblock.opblock-patch .opblock-summary-method {
557
+ background: var(--method-patch);
558
+ }
559
+
560
+ /* Inner sections (Parameters, Request body, Responses, ...) */
561
+ .swagger-ui .opblock-section-header {
562
+ background: var(--bg-tertiary);
563
+ border: none;
564
+ border-top: 1px solid var(--border-color);
565
+ box-shadow: none;
566
+ padding: 12px 16px;
567
+ }
568
+
569
+ .swagger-ui .opblock-section-header h4,
570
+ .swagger-ui .opblock-section-header > label {
571
+ color: var(--text-primary);
572
+ font-weight: 600;
573
+ font-size: 14px;
574
+ }
575
+
576
+ .swagger-ui .opblock-description-wrapper,
577
+ .swagger-ui .opblock-body,
578
+ .swagger-ui .opblock-external-docs-wrapper,
579
+ .swagger-ui .responses-wrapper {
580
+ background: transparent;
581
+ }
582
+
583
+ .swagger-ui .opblock-description-wrapper p,
584
+ .swagger-ui .opblock-external-docs-wrapper p {
585
+ color: var(--text-secondary);
586
+ }
587
+
588
+ .swagger-ui .opblock h4,
589
+ .swagger-ui .opblock h5,
590
+ .swagger-ui .opblock h3,
591
+ .swagger-ui .responses-inner h4,
592
+ .swagger-ui .responses-inner h5,
593
+ .swagger-ui .response-content-type {
594
+ color: var(--text-primary);
595
+ }
596
+
597
+ .swagger-ui .response-content-type {
598
+ font-family: var(--font-mono);
599
+ font-size: 12px;
600
+ }
601
+
602
+ /* Tables (parameters, responses) */
603
+ .swagger-ui table {
604
+ background: transparent;
605
+ }
606
+
607
+ .swagger-ui table thead tr td,
608
+ .swagger-ui table thead tr th {
609
+ color: var(--text-tertiary);
610
+ border-bottom: 1px solid var(--border-color);
611
+ background: transparent;
612
+ font-size: 11px;
613
+ text-transform: uppercase;
614
+ letter-spacing: 0.06em;
615
+ font-weight: 600;
616
+ padding: 10px 16px;
617
+ }
618
+
619
+ .swagger-ui table tbody tr td {
620
+ color: var(--text-primary);
621
+ border-bottom: 1px solid var(--border-color);
622
+ background: transparent;
623
+ padding: 12px 16px;
624
+ font-size: 13px;
625
+ }
626
+
627
+ .swagger-ui .parameter__name {
628
+ color: var(--text-primary);
629
+ font-family: var(--font-mono);
630
+ font-weight: 600;
631
+ font-size: 13px;
632
+ }
633
+
634
+ .swagger-ui .parameter__name.required::after {
635
+ color: var(--method-delete);
636
+ content: ' *';
637
+ }
638
+
639
+ .swagger-ui .parameter__type {
640
+ color: var(--primary-color);
641
+ font-family: var(--font-mono);
642
+ font-size: 12px;
643
+ }
644
+
645
+ .swagger-ui .parameter__in,
646
+ .swagger-ui .parameter__deprecated,
647
+ .swagger-ui .parameter__extension {
648
+ color: var(--text-tertiary);
649
+ font-size: 11px;
650
+ font-style: normal;
651
+ }
652
+
653
+ /* Response status codes */
654
+ .swagger-ui .response-col_status,
655
+ .swagger-ui .responses-table .response-col_status {
656
+ color: var(--text-primary);
657
+ font-family: var(--font-mono);
658
+ font-weight: 600;
659
+ }
660
+
661
+ .swagger-ui .response-col_description__inner div.markdown,
662
+ .swagger-ui .response-col_description__inner div.renderedMarkdown {
663
+ color: var(--text-secondary);
664
+ }
665
+
666
+ /* Code blocks (examples, schemas) */
667
+ .swagger-ui pre,
668
+ .swagger-ui .microlight,
669
+ .swagger-ui .highlight-code,
670
+ .swagger-ui .opblock-body pre.microlight,
671
+ .swagger-ui .responses-inner pre {
672
+ background: #050505 !important;
673
+ color: #fafafa !important;
674
+ border: 1px solid var(--border-color);
675
+ border-radius: 8px;
676
+ font-family: var(--font-mono) !important;
677
+ font-size: 12.5px;
678
+ line-height: 1.55;
679
+ text-shadow: none;
680
+ }
681
+
682
+ .swagger-ui .highlight-code .copy-to-clipboard {
683
+ background: var(--bg-tertiary);
684
+ border: 1px solid var(--border-color);
685
+ border-radius: 6px;
686
+ }
687
+
688
+ .swagger-ui .highlight-code .copy-to-clipboard:hover {
689
+ background: var(--bg-elevated);
690
+ }
691
+
692
+ /* Microlight token colors (JSON/YAML syntax highlight) */
693
+ .swagger-ui .microlight .token.string {
694
+ color: #a5f3fc;
695
+ }
696
+ .swagger-ui .microlight .token.number {
697
+ color: #fcd34d;
698
+ }
699
+ .swagger-ui .microlight .token.boolean,
700
+ .swagger-ui .microlight .token.null {
701
+ color: #f472b6;
702
+ }
703
+ .swagger-ui .microlight .token.property {
704
+ color: #93c5fd;
705
+ }
706
+
707
+ /* Models / schemas */
708
+ .swagger-ui section.models {
709
+ background: var(--bg-secondary);
710
+ border: 1px solid var(--border-color);
711
+ border-radius: 12px;
712
+ box-shadow: none;
713
+ }
714
+
715
+ .swagger-ui section.models h4 {
716
+ color: var(--text-primary);
717
+ font-weight: 600;
718
+ }
719
+
720
+ .swagger-ui section.models.is-open h4 {
721
+ border-bottom: 1px solid var(--border-color);
722
+ }
723
+
724
+ .swagger-ui .model-container {
725
+ background: transparent;
726
+ border-bottom: 1px solid var(--border-color);
727
+ }
728
+
729
+ .swagger-ui .model-container:last-child {
730
+ border-bottom: none;
731
+ }
732
+
733
+ .swagger-ui .model-box {
734
+ background: var(--bg-tertiary);
735
+ border-radius: 8px;
736
+ padding: 12px;
737
+ }
738
+
739
+ .swagger-ui .model-title,
740
+ .swagger-ui .model .model-title {
741
+ color: var(--text-primary);
742
+ font-family: var(--font-mono);
743
+ }
744
+
745
+ .swagger-ui .model,
746
+ .swagger-ui .model .property {
747
+ color: var(--text-secondary);
748
+ font-family: var(--font-mono);
749
+ font-size: 13px;
750
+ }
751
+
752
+ .swagger-ui .model .property.primitive {
753
+ color: var(--primary-hover);
754
+ }
755
+
756
+ .swagger-ui .prop-type,
757
+ .swagger-ui .prop .prop-type {
758
+ color: var(--primary-color);
759
+ font-family: var(--font-mono);
760
+ }
761
+
762
+ .swagger-ui .prop-format {
763
+ color: var(--text-tertiary);
764
+ font-family: var(--font-mono);
765
+ }
766
+
767
+ .swagger-ui .model .model-deprecated-warning {
768
+ color: var(--method-put);
769
+ }
770
+
771
+ /* Buttons */
772
+ .swagger-ui .btn {
773
+ background: var(--bg-tertiary);
774
+ color: var(--text-primary);
775
+ border: 1px solid var(--border-color);
776
+ border-radius: 8px;
777
+ padding: 8px 16px;
778
+ font-weight: 500;
779
+ font-family: 'Inter', sans-serif;
780
+ font-size: 13px;
781
+ box-shadow: none;
782
+ text-shadow: none;
783
+ transition: all 0.15s ease;
784
+ }
785
+
786
+ .swagger-ui .btn:hover {
787
+ background: var(--bg-elevated);
788
+ border-color: var(--border-strong);
789
+ transform: none;
790
+ box-shadow: none;
791
+ }
792
+
793
+ .swagger-ui .btn.try-out__btn {
794
+ color: var(--primary-color);
795
+ border-color: rgba(56, 189, 248, 0.3);
796
+ background: rgba(56, 189, 248, 0.08);
797
+ }
798
+
799
+ .swagger-ui .btn.try-out__btn:hover {
800
+ background: rgba(56, 189, 248, 0.16);
801
+ border-color: var(--primary-color);
802
+ color: var(--primary-hover);
803
+ }
804
+
805
+ .swagger-ui .btn.execute {
806
+ background: var(--primary-color);
807
+ color: #000000;
808
+ border: 1px solid var(--primary-color);
809
+ font-weight: 600;
810
+ }
811
+
812
+ .swagger-ui .btn.execute:hover {
813
+ background: var(--primary-hover);
814
+ border-color: var(--primary-hover);
815
+ }
816
+
817
+ .swagger-ui .btn.cancel {
818
+ background: transparent;
819
+ color: var(--text-secondary);
820
+ border-color: var(--border-color);
821
+ }
822
+
823
+ .swagger-ui .btn.cancel:hover {
824
+ color: var(--text-primary);
825
+ border-color: var(--border-strong);
826
+ background: var(--bg-tertiary);
827
+ }
828
+
829
+ /* Form inputs */
830
+ .swagger-ui input[type=text],
831
+ .swagger-ui input[type=password],
832
+ .swagger-ui input[type=email],
833
+ .swagger-ui input[type=number],
834
+ .swagger-ui input[type=search],
835
+ .swagger-ui textarea,
836
+ .swagger-ui select {
837
+ background: var(--bg-tertiary);
838
+ color: var(--text-primary);
839
+ border: 1px solid var(--border-color);
840
+ border-radius: 8px;
841
+ padding: 8px 12px;
842
+ box-shadow: none;
843
+ font-family: var(--font-mono);
844
+ font-size: 13px;
845
+ transition: border-color 0.15s ease, outline 0.15s ease;
846
+ }
847
+
848
+ .swagger-ui input[type=text]::placeholder,
849
+ .swagger-ui input[type=password]::placeholder,
850
+ .swagger-ui input[type=email]::placeholder,
851
+ .swagger-ui input[type=number]::placeholder,
852
+ .swagger-ui input[type=search]::placeholder,
853
+ .swagger-ui textarea::placeholder {
854
+ color: var(--text-muted);
855
+ }
856
+
857
+ .swagger-ui input[type=text]:focus,
858
+ .swagger-ui input[type=password]:focus,
859
+ .swagger-ui input[type=email]:focus,
860
+ .swagger-ui input[type=number]:focus,
861
+ .swagger-ui input[type=search]:focus,
862
+ .swagger-ui textarea:focus,
863
+ .swagger-ui select:focus {
864
+ outline: 2px solid rgba(56, 189, 248, 0.2);
865
+ border-color: var(--primary-color);
866
+ outline-offset: 0;
867
+ }
868
+
869
+ /* Tabs (Example Value / Schema) */
870
+ .swagger-ui .tab li button.tablinks {
871
+ color: var(--text-tertiary);
872
+ border: none;
873
+ background: transparent;
874
+ padding: 8px 0;
875
+ font-weight: 500;
876
+ }
877
+
878
+ .swagger-ui .tab li button.tablinks.active {
879
+ color: var(--primary-color);
880
+ border-bottom: 2px solid var(--primary-color);
881
+ }
882
+
883
+ /* Modal (Authorize, etc.) */
884
+ .swagger-ui .dialog-ux .modal-ux {
885
+ background: var(--bg-secondary);
886
+ border: 1px solid var(--border-color);
887
+ border-radius: 16px;
888
+ box-shadow: var(--shadow-xl);
889
+ }
890
+
891
+ .swagger-ui .dialog-ux .modal-ux-header {
892
+ background: var(--bg-tertiary);
893
+ border-bottom: 1px solid var(--border-color);
894
+ border-radius: 16px 16px 0 0;
895
+ }
896
+
897
+ .swagger-ui .dialog-ux .modal-ux-header h3,
898
+ .swagger-ui .dialog-ux .modal-ux-content h4,
899
+ .swagger-ui .dialog-ux .modal-ux-content h5 {
900
+ color: var(--text-primary);
901
+ }
902
+
903
+ .swagger-ui .dialog-ux .modal-ux-content {
904
+ color: var(--text-secondary);
905
+ background: var(--bg-secondary);
906
+ }
907
+
908
+ .swagger-ui .dialog-ux .modal-ux-content p {
909
+ color: var(--text-secondary);
910
+ }
911
+
912
+ .swagger-ui .dialog-ux .backdrop-ux {
913
+ background: rgba(0, 0, 0, 0.75);
914
+ backdrop-filter: blur(4px);
915
+ }
916
+
917
+ .swagger-ui .auth-container .auth-container-header {
918
+ color: var(--text-primary);
919
+ }
920
+
921
+ .swagger-ui .auth-container code {
922
+ background: var(--bg-tertiary);
923
+ }
924
+
925
+ /* Error states */
926
+ .swagger-ui .errors-wrapper {
927
+ background: rgba(239, 68, 68, 0.08);
928
+ border: 1px solid rgba(239, 68, 68, 0.3);
929
+ border-radius: 12px;
930
+ color: #fca5a5;
931
+ box-shadow: none;
932
+ }
933
+
934
+ .swagger-ui .errors-wrapper .errors h4 {
935
+ color: #fca5a5;
936
+ }
937
+
938
+ .swagger-ui .opblock-deprecated {
939
+ opacity: 0.55;
940
+ }
941
+
942
+ /* Loading state */
943
+ .swagger-ui .loading-container .loading {
944
+ color: var(--text-secondary);
945
+ }
946
+
947
+ /* Scrollbars inside swagger-ui (webkit only) */
948
+ .swagger-ui *::-webkit-scrollbar {
949
+ width: 8px;
950
+ height: 8px;
951
+ }
952
+
953
+ .swagger-ui *::-webkit-scrollbar-track {
954
+ background: var(--bg-secondary);
955
+ }
956
+
957
+ .swagger-ui *::-webkit-scrollbar-thumb {
958
+ background: var(--border-strong);
959
+ border-radius: 4px;
960
+ }
961
+
962
+ .swagger-ui *::-webkit-scrollbar-thumb:hover {
963
+ background: var(--text-tertiary);
964
+ }
965
+
966
+ /* Try-it-out form labels */
967
+ .swagger-ui .opblock .opblock-section-header label {
968
+ color: var(--text-primary);
969
+ }
970
+
971
+ .swagger-ui label {
972
+ color: var(--text-secondary);
973
+ font-size: 13px;
974
+ }
975
+
976
+ /* Markdown tables inside descriptions */
977
+ .swagger-ui .markdown table {
978
+ border-collapse: collapse;
979
+ margin: 12px 0;
980
+ }
981
+
982
+ .swagger-ui .markdown table th,
983
+ .swagger-ui .markdown table td {
984
+ border: 1px solid var(--border-color);
985
+ padding: 8px 12px;
986
+ color: var(--text-secondary);
987
+ }
988
+
989
+ .swagger-ui .markdown table th {
990
+ background: var(--bg-tertiary);
991
+ color: var(--text-primary);
992
+ }
993
+
994
+ /*
995
+ * Footer mirrors the navbar token-wise: same --bg-primary surface,
996
+ * same border treatment, same subtle pill-style CTAs. No gradient
997
+ * backgrounds, no decorative emojis — single sky accent reserved
998
+ * for actual interactive elements.
999
+ */
283
1000
  .pay2b-footer {
284
1001
  background: var(--bg-primary);
285
1002
  border-top: 1px solid var(--border-color);
286
- padding: 24px 32px;
1003
+ padding: 20px 32px;
287
1004
  min-height: var(--footer-height);
288
- transition: var(--transition-smooth);
289
1005
  }
290
1006
 
291
1007
  .footer__container {
@@ -317,7 +1033,7 @@
317
1033
  }
318
1034
 
319
1035
  .footer__logo-p4f {
320
- height: 44px;
1036
+ height: 32px;
321
1037
  width: auto;
322
1038
  object-fit: contain;
323
1039
  }
@@ -326,6 +1042,13 @@
326
1042
  font-size: 13px;
327
1043
  color: var(--text-tertiary);
328
1044
  font-weight: 400;
1045
+ margin: 0;
1046
+ }
1047
+
1048
+ .footer__separator {
1049
+ color: var(--border-strong);
1050
+ margin: 0 4px;
1051
+ user-select: none;
329
1052
  }
330
1053
 
331
1054
  .footer__right {
@@ -372,55 +1095,54 @@
372
1095
 
373
1096
  .footer__social {
374
1097
  display: flex;
375
- gap: 12px;
1098
+ gap: 8px;
376
1099
  }
377
1100
 
378
1101
  .footer__social-link {
379
- display: flex;
1102
+ display: inline-flex;
380
1103
  align-items: center;
381
1104
  justify-content: center;
382
- width: 36px;
383
- height: 36px;
1105
+ width: 32px;
1106
+ height: 32px;
384
1107
  border-radius: 8px;
385
1108
  background: var(--bg-tertiary);
1109
+ border: 1px solid var(--border-color);
386
1110
  color: var(--text-secondary);
387
1111
  text-decoration: none;
388
- transition: var(--transition-smooth);
389
- font-size: 16px;
1112
+ font-family: var(--font-mono);
1113
+ font-size: 12px;
1114
+ font-weight: 600;
1115
+ letter-spacing: -0.02em;
1116
+ transition: all 0.15s ease;
390
1117
  }
391
1118
 
392
1119
  .footer__social-link:hover {
393
- background: var(--primary-color);
394
- color: white;
395
- transform: translateY(-2px);
396
- box-shadow: var(--shadow-md);
1120
+ background: var(--bg-elevated);
1121
+ border-color: var(--border-strong);
1122
+ color: var(--text-primary);
397
1123
  }
398
1124
 
399
1125
  .powered-by {
400
1126
  display: inline-flex;
401
1127
  align-items: center;
402
- gap: 6px;
403
- padding: 6px 14px;
404
- background: linear-gradient(135deg, var(--accent-color), var(--primary-color));
405
- color: white;
1128
+ padding: 5px 12px;
1129
+ background: var(--bg-tertiary);
1130
+ color: var(--text-secondary);
1131
+ border: 1px solid var(--border-color);
1132
+ border-radius: 999px;
406
1133
  text-decoration: none;
407
- border-radius: 8px;
408
- font-size: 12px;
409
- font-weight: 600;
410
- letter-spacing: 0.02em;
411
- transition: var(--transition-smooth);
412
- box-shadow: var(--shadow-sm);
1134
+ font-size: 11px;
1135
+ font-weight: 500;
1136
+ letter-spacing: 0.06em;
1137
+ text-transform: uppercase;
1138
+ font-family: var(--font-mono);
1139
+ transition: all 0.15s ease;
413
1140
  }
414
1141
 
415
1142
  .powered-by:hover {
416
- transform: translateY(-2px);
417
- box-shadow: var(--shadow-md);
418
- opacity: 0.9;
419
- }
420
-
421
- .powered-by::before {
422
- content: '⚡';
423
- font-size: 14px;
1143
+ background: var(--bg-elevated);
1144
+ border-color: var(--border-strong);
1145
+ color: var(--text-primary);
424
1146
  }
425
1147
 
426
1148
  @media (max-width: 768px) {
@@ -476,7 +1198,7 @@
476
1198
  <div class="navbar__container">
477
1199
  <div class="navbar__left">
478
1200
  <a href="/" class="navbar__logo">
479
- <img src="https://p4f.dev/img/logo-p4f.svg"
1201
+ <img src="https://p4f.dev/img/logo-p4f.png"
480
1202
  alt="P4F Logo" class="navbar__logo-p4f"/>
481
1203
  <span class="navbar__title">Heimdall API Platform</span>
482
1204
  </a>
@@ -488,10 +1210,6 @@
488
1210
  <span class="status-dot"></span>
489
1211
  <span>All Systems Operational</span>
490
1212
  </div>
491
-
492
- <button class="theme-toggle" id="themeToggle" aria-label="Toggle theme">
493
- <span id="themeIcon">🌙</span>
494
- </button>
495
1213
  </div>
496
1214
  </div>
497
1215
  </nav>
@@ -501,48 +1219,27 @@
501
1219
  <footer class="pay2b-footer">
502
1220
  <div class="footer__container">
503
1221
  <div class="footer__left">
504
- <img src="https://p4f.dev/img/logo-p4f.svg"
1222
+ <img src="https://p4f.dev/img/logo-p4f.png"
505
1223
  alt="P4F Logo" class="footer__logo-p4f"/>
506
- <p class="footer__copyright">© 2026 P4F. All rights reserved.</p>
1224
+ <p class="footer__copyright">
1225
+ © 2026 P4F · Heimdall API Platform
1226
+ </p>
507
1227
  </div>
508
1228
 
509
1229
  <div class="footer__right">
510
1230
  <div class="footer__social">
511
- <a href="https://www.linkedin.com/company/protonss4fun" class="footer__social-link" target="_blank"
512
- rel="noopener noreferrer" aria-label="LinkedIn P4F"
513
- style="background: linear-gradient(135deg, var(--accent-color), var(--primary-color)); color: white;">
514
- in
515
- </a>
1231
+ <a href="https://www.linkedin.com/company/protonss4fun" class="footer__social-link"
1232
+ target="_blank" rel="noopener noreferrer" aria-label="LinkedIn P4F">in</a>
516
1233
  </div>
517
1234
 
518
- <a href="https://www.protonss4fun.com.br/" class="powered-by" target="_blank" rel="noopener noreferrer">
519
- Powered by P4F
1235
+ <a href="https://p4f.dev" class="powered-by" target="_blank" rel="noopener noreferrer">
1236
+ p4f.dev
520
1237
  </a>
521
1238
  </div>
522
1239
  </div>
523
1240
  </footer>
524
1241
 
525
1242
  <script>
526
- const themeToggle = document.getElementById('themeToggle');
527
- const themeIcon = document.getElementById('themeIcon');
528
- const html = document.documentElement;
529
-
530
- const savedTheme = localStorage.getItem('theme') || 'light';
531
- html.setAttribute('data-theme', savedTheme);
532
- updateThemeIcon(savedTheme);
533
-
534
- themeToggle.addEventListener('click', () => {
535
- const currentTheme = html.getAttribute('data-theme');
536
- const newTheme = currentTheme === 'light' ? 'dark' : 'light';
537
- html.setAttribute('data-theme', newTheme);
538
- localStorage.setItem('theme', newTheme);
539
- updateThemeIcon(newTheme);
540
- });
541
-
542
- function updateThemeIcon(theme) {
543
- themeIcon.textContent = theme === 'light' ? '🌙' : '☀️';
544
- }
545
-
546
1243
  window.onload = () => {
547
1244
  SwaggerUIBundle({
548
1245
  url: "/docs/openapi.yaml",