opticore-profiler 1.0.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 (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -0
  3. package/dist/assets/css/debug-message.css +16 -0
  4. package/dist/assets/css/home-page.css +177 -0
  5. package/dist/assets/css/profiler-detail.css +215 -0
  6. package/dist/assets/css/profiler-list.css +131 -0
  7. package/dist/assets/css/toolbar-standalone.css +213 -0
  8. package/dist/assets/js/home-particles.js +65 -0
  9. package/dist/assets/js/profiler-detail.js +77 -0
  10. package/dist/assets/js/profiler-list.js +76 -0
  11. package/dist/assets/js/toolbar.js +230 -0
  12. package/dist/index.cjs +1942 -0
  13. package/dist/index.d.cts +488 -0
  14. package/dist/index.d.ts +488 -0
  15. package/dist/index.js +1893 -0
  16. package/dist/utils/translations/message.translation.en.json +190 -0
  17. package/dist/utils/translations/message.translation.fr.json +190 -0
  18. package/dist/views/templates/home.njk +120 -0
  19. package/dist/views/templates/macros/icons.njk +19 -0
  20. package/dist/views/templates/macros/tables.njk +17 -0
  21. package/dist/views/templates/message.njk +14 -0
  22. package/dist/views/templates/panels/configuration.njk +16 -0
  23. package/dist/views/templates/panels/database.njk +36 -0
  24. package/dist/views/templates/panels/exception.njk +26 -0
  25. package/dist/views/templates/panels/logs.njk +44 -0
  26. package/dist/views/templates/panels/performance.njk +56 -0
  27. package/dist/views/templates/panels/request.njk +141 -0
  28. package/dist/views/templates/panels/routes.njk +51 -0
  29. package/dist/views/templates/panels/routing.njk +22 -0
  30. package/dist/views/templates/profiler-detail.njk +114 -0
  31. package/dist/views/templates/profiler-list.njk +163 -0
  32. package/dist/views/templates/toolbar-wdt.njk +161 -0
  33. package/package.json +73 -0
@@ -0,0 +1,161 @@
1
+ <div class="toolbar" id="wdt">
2
+ <div class="tb-block-wrap">
3
+ <a href="{{ profilerUrl }}" class="tb-badge tb-badge--{{ statusCls }}">{{ statusCode }}</a>
4
+ <div class="tb-tooltip">
5
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.profile_token') }}</span><span class="tt-val"><code>{{ token }}</code></span></div>
6
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.method') }}</span><span class="tt-val"><span class="tt-badge" style="background:#1565c0">{{ method }}</span></span></div>
7
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.url') }}</span><span class="tt-val" style="word-break:break-all;">{{ url }}</span></div>
8
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.status') }}</span><span class="tt-val"><span class="tt-badge" style="background:{{ '#2e7d32' if statusCode < 400 else '#c0392b' }}">{{ statusCode }} {{ statusMessage }}</span></span></div>
9
+ <div class="tt-sep"></div>
10
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.duration') }}</span><span class="tt-val">{{ duration.formatted }}</span></div>
11
+ <a href="{{ profilerUrl }}" class="tt-link">{{ t('toolbar.open_profiler') }}</a>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="tb-block-wrap">
16
+ <a href="{{ base }}?panel=performance" class="tb-block" style="position:relative;">
17
+ <span class="tb-icon">
18
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
19
+ <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
20
+ </svg>
21
+ </span>
22
+ <span class="tb-label tb-underline">{{ duration.formatted }}</span>
23
+ <span class="tb-time-bar" style="width:{{ duration.barWidth }}%"></span>
24
+ </a>
25
+ <div class="tb-tooltip">
26
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.total_time') }}</span><span class="tt-val"><b>{{ duration.appFormatted }}</b></span></div>
27
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.application') }}</span><span class="tt-val">{{ duration.appFormatted }}</span></div>
28
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.database') }}</span><span class="tt-val">{{ duration.dbFormatted }}</span></div>
29
+ <div class="tt-sep"></div>
30
+ <a href="{{ base }}?panel=performance" class="tt-link">{{ t('toolbar.performance') }}</a>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="tb-block-wrap">
35
+ <a href="{{ base }}?panel=performance" class="tb-block">
36
+ <span class="tb-icon"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 7V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2"/></svg></span>
37
+ <span class="tb-label">{{ memory.formatted }}</span>
38
+ </a>
39
+ <div class="tb-tooltip">
40
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.heap_used') }}</span><span class="tt-val">{{ memory.formatted }}</span></div>
41
+ <div class="tt-sep"></div>
42
+ <a href="{{ base }}?panel=performance" class="tt-link">{{ t('toolbar.performance') }}</a>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="tb-block-wrap">
47
+ <a href="{{ base }}?panel=logs" class="tb-block">
48
+ <span class="tb-icon"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg></span>
49
+ <span class="tb-label">{{ logs.count }}</span>
50
+ {% if logs.errors > 0 %}<span class="tb-badge-pill">{{ logs.errors }}</span>{% endif %}
51
+ {% if logs.warnings > 0 %}<span class="tb-badge-pill tb-badge-pill--warn">{{ logs.warnings }}</span>{% endif %}
52
+ </a>
53
+ <div class="tb-tooltip">
54
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.errors') }}</span><span class="tt-val">{% if logs.errors > 0 %}<span class="tt-badge" style="background:#c0392b">{{ logs.errors }}</span>{% else %}<span style="color:#555;">0</span>{% endif %}</span></div>
55
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.warnings') }}</span><span class="tt-val">{% if logs.warnings > 0 %}<span class="tt-badge" style="background:#e67e22">{{ logs.warnings }}</span>{% else %}<span style="color:#555;">0</span>{% endif %}</span></div>
56
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.deprecations') }}</span><span class="tt-val">{% if logs.deprecations > 0 %}<span class="tt-badge" style="background:#8e44ad">{{ logs.deprecations }}</span>{% else %}<span style="color:#555;">0</span>{% endif %}</span></div>
57
+ <div class="tt-sep"></div>
58
+ <a href="{{ base }}?panel=logs" class="tt-link">{{ t('toolbar.logs') }}</a>
59
+ </div>
60
+ </div>
61
+
62
+ <div class="tb-block-wrap">
63
+ <a href="{{ base }}?panel=routing" class="tb-block">
64
+ <span class="tb-icon"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="22"/><polygon points="12,5 19,5 22,9 19,13 12,13"/><polygon points="12,14 5,14 2,18 5,21 12,21"/></svg></span>
65
+ <span class="tb-label">{{ route.label }}</span>
66
+ </a>
67
+ <div class="tb-tooltip">
68
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.method') }}</span><span class="tt-val"><span class="tt-badge" style="background:#1565c0">{{ route.method }}</span></span></div>
69
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.url') }}</span><span class="tt-val"><code>{{ route.label }}</code></span></div>
70
+ <div class="tt-sep"></div>
71
+ <a href="{{ base }}?panel=routing" class="tt-link">{{ t('toolbar.routing') }}</a>
72
+ </div>
73
+ </div>
74
+
75
+ <div class="tb-block tb-http-block" id="wdt-ajax-block">
76
+ <span class="tb-icon"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg></span>
77
+ <span class="tb-label">{{ t('toolbar.http_requests') }}</span>
78
+ <span class="tb-badge-pill" id="wdt-ajax-count">{{ http.count }}</span>
79
+ <div class="tb-http-tooltip">
80
+ <div class="tb-tip-header" id="wdt-ajax-header">
81
+ {% if http.rows.length > 0 %}
82
+ <span>{{ t('toolbar.last_n_requests', { n: http.rows.length }) }}</span>
83
+ <a href="{{ profilerBase }}" class="tb-tip-viewall">{{ t('toolbar.view_all') }}</a>
84
+ {% else %}
85
+ <span>{{ t('toolbar.http_requests') }}</span>
86
+ {% endif %}
87
+ </div>
88
+ <table class="tb-tip-table" id="wdt-ajax-table">
89
+ <thead><tr><th>{{ t('toolbar.method') }}</th><th>{{ t('toolbar.url') }}</th><th>{{ t('toolbar.status') }}</th><th>{{ t('toolbar.duration') }}</th></tr></thead>
90
+ <tbody>
91
+ {% for row in http.rows %}
92
+ <tr class="{{ 'tip-current' if row.isCurrent }}">
93
+ <td><span class="tip-method tip-m-{{ row.method | lower }}">{{ row.method }}</span></td>
94
+ <td><a href="{{ profilerBase }}/{{ row.token }}" class="tip-url-link" title="{{ row.fullUrl }}">{{ row.url }}</a></td>
95
+ <td class="{{ row.statusClass }}">{{ row.statusCode }}</td>
96
+ <td class="tip-dur">{{ row.duration }}</td>
97
+ </tr>
98
+ {% endfor %}
99
+ </tbody>
100
+ </table>
101
+ {% if http.rows.length == 0 %}
102
+ <div id="wdt-ajax-empty" style="padding:12px;color:#666;font-size:11px;">{{ t('toolbar.no_requests_yet') }}</div>
103
+ {% endif %}
104
+ </div>
105
+ </div>
106
+
107
+ <div class="tb-spacer"></div>
108
+
109
+ <div class="tb-block-wrap">
110
+ <div class="lang-switch lang-switch--toolbar">
111
+ {% for l in languages %}
112
+ <a href="#" class="lang-switch-item{{ ' active' if l.active }}" onclick="event.preventDefault();var u=new URL(location.href);u.searchParams.set('lang','{{ l.code }}');location.href=u.toString();">{{ l.code | upper }}</a>
113
+ {% endfor %}
114
+ </div>
115
+ </div>
116
+
117
+ <div class="tb-block-wrap">
118
+ <a href="{{ profilerUrl }}" class="tb-brand">
119
+ <div class="tb-brand-icon">OP</div>
120
+ <span>{{ t('toolbar.server') }}</span>
121
+ </a>
122
+ <div class="tb-tooltip tb-tooltip--right">
123
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.nodejs') }}</span><span class="tt-val"><span class="tt-badge" style="background:#1b3d1a">{{ nodeVersion }}</span></span></div>
124
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.environment') }}</span><span class="tt-val"><span class="tt-badge" style="background:{{ '#1a3320' if environment != 'production' else '#3d0a0a' }}">{{ environment }}</span></span></div>
125
+ <div class="tt-sep"></div>
126
+ <a href="{{ profilerUrl }}" class="tt-link">{{ t('toolbar.open_profiler_emoji') }}</a>
127
+ <a href="https://github.com/guyzoum77/opticore-api-restfull-template-mysql" target="_blank" class="tt-link">{{ t('toolbar.documentation') }}</a>
128
+ <a href="https://github.com/guyzoum77/opticore-api-restfull-template-mysql/issues" target="_blank" class="tt-link">{{ t('toolbar.help_support') }}</a>
129
+ </div>
130
+ </div>
131
+
132
+ <div class="tb-block-wrap">
133
+ <div class="tb-version">v{{ appVersion }}</div>
134
+ <div class="tb-tooltip tb-tooltip--right">
135
+ <div class="tt-row"><span class="tt-label">OptiCoreJs</span><span class="tt-val"><span class="tt-badge" style="background:#3D1E08">v{{ appVersion }}</span></span></div>
136
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.nodejs') }}</span><span class="tt-val"><span class="tt-badge" style="background:#1b3d1a">{{ nodeVersion }}</span></span></div>
137
+ <div class="tt-row"><span class="tt-label">{{ t('toolbar.environment') }}</span><span class="tt-val"><span class="tt-badge" style="background:{{ '#1a3320' if environment != 'production' else '#3d0a0a' }}">{{ environment }}</span></span></div>
138
+ <div class="tt-sep"></div>
139
+ <a href="{{ profilerUrl }}" class="tt-link">{{ t('toolbar.open_profiler_emoji') }}</a>
140
+ <a href="https://github.com/guyzoum77/opticore-api-restfull-template-mysql" target="_blank" class="tt-link">{{ t('toolbar.documentation') }}</a>
141
+ <a href="https://github.com/guyzoum77/opticore-api-restfull-template-mysql/issues" target="_blank" class="tt-link">{{ t('toolbar.help_support') }}</a>
142
+ </div>
143
+ </div>
144
+
145
+ <!-- collapse button — shrinks to mini pill, does NOT close -->
146
+ <button class="tb-collapse" onclick="wdtCollapse()" title="{{ t('toolbar.minimize') }}">
147
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="18 15 12 9 6 15"/></svg>
148
+ </button>
149
+ </div>
150
+
151
+ <!-- mini collapsed pill (bottom-right) -->
152
+ <div id="wdt-mini">
153
+ <a href="{{ profilerUrl }}" id="wdt-mini-logo">
154
+ <div id="wdt-mini-logo-icon">OP</div>
155
+ <span style="color:#888;font-size:11px;">{{ t('toolbar.profiler') }}</span>
156
+ </a>
157
+ <a href="{{ profilerUrl }}" id="wdt-mini-status" class="tb-badge--{{ statusCls }}">{{ statusCode }}</a>
158
+ <button id="wdt-mini-expand" onclick="wdtExpand()" title="{{ t('toolbar.expand') }}">
159
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
160
+ </button>
161
+ </div>
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "opticore-profiler",
3
+ "version": "1.0.0",
4
+ "description": "Web debug toolbar",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "test": "jest",
28
+ "smoke": "npm run build && node smoke-test.mjs && node smoke-test.cjs && node smoke-test-i18n.mjs",
29
+ "prepublishOnly": "npm run build && npm test"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/guyzoum77/opticore-profiler.git"
37
+ },
38
+ "keywords": [
39
+ "opticore",
40
+ "opticore-webapp",
41
+ "opticore-express",
42
+ "profiler",
43
+ "web-profiler",
44
+ "debug-toolbar",
45
+ "express",
46
+ "middleware"
47
+ ],
48
+ "author": "Guy-serge Kouacou",
49
+ "license": "MIT",
50
+ "bugs": {
51
+ "url": "https://github.com/guyzoum77/opticore-profiler/issues"
52
+ },
53
+ "homepage": "https://github.com/guyzoum77/opticore-profiler#readme",
54
+ "dependencies": {
55
+ "nunjucks": "^3.2.4",
56
+ "opticore-express": "^1.0.9",
57
+ "opticore-router": "^1.0.21"
58
+ },
59
+ "overrides": {
60
+ "js-yaml": "^4.2.0",
61
+ "esbuild": "^0.28.1"
62
+ },
63
+ "devDependencies": {
64
+ "@types/jest": "^30.0.0",
65
+ "@types/node": "^24.12.4",
66
+ "@types/nunjucks": "^3.2.6",
67
+ "jest": "^30.0.0",
68
+ "ts-jest": "^29.2.5",
69
+ "tslib": "^2.8.1",
70
+ "tsup": "^8.5.1",
71
+ "typescript": "^6.0.3"
72
+ }
73
+ }