debugbar 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/debugbar/assets_controller.rb +1 -1
  3. data/build.sh +7 -0
  4. data/debugbar.gemspec +6 -1
  5. data/lib/debugbar/engine.rb +0 -8
  6. data/lib/debugbar/version.rb +1 -1
  7. data/lib/debugbar.rb +0 -7
  8. metadata +2 -54
  9. data/client/.gitignore +0 -25
  10. data/client/README.md +0 -0
  11. data/client/dist/.vite/manifest.json +0 -14
  12. data/client/dist/assets/debugbar-u5mP-5-z.js +0 -34
  13. data/client/dist/assets/ruby-logo-kn_8RniZ.svg +0 -946
  14. data/client/index.html +0 -78
  15. data/client/package-lock.json +0 -2393
  16. data/client/package.json +0 -32
  17. data/client/postcss.config.js +0 -6
  18. data/client/src/App.vue +0 -17
  19. data/client/src/AppDemo.vue +0 -29
  20. data/client/src/AppDev.vue +0 -20
  21. data/client/src/Debugbar.vue +0 -276
  22. data/client/src/assets/rails-logo.svg +0 -1
  23. data/client/src/assets/ruby-logo.svg +0 -946
  24. data/client/src/components/TabButton.vue +0 -32
  25. data/client/src/components/panels/CachePanel.vue +0 -41
  26. data/client/src/components/panels/JobsPanel.vue +0 -52
  27. data/client/src/components/panels/JsonPanel.vue +0 -15
  28. data/client/src/components/panels/LogsPanel.vue +0 -43
  29. data/client/src/components/panels/MessagesPanel.vue +0 -25
  30. data/client/src/components/panels/ModelsPanel.vue +0 -37
  31. data/client/src/components/panels/Panel.vue +0 -7
  32. data/client/src/components/panels/RequestPanel.vue +0 -98
  33. data/client/src/components/queries/QueriesPanel.vue +0 -17
  34. data/client/src/components/queries/QueryItem.vue +0 -65
  35. data/client/src/components/ui/Foldable.vue +0 -39
  36. data/client/src/components/ui/KeyValueTable.vue +0 -16
  37. data/client/src/components/ui/Row.vue +0 -14
  38. data/client/src/components/ui/logo-ruby.vue +0 -547
  39. data/client/src/demo.ts +0 -17
  40. data/client/src/dev.ts +0 -20
  41. data/client/src/main.ts +0 -17
  42. data/client/src/models/Config.ts +0 -27
  43. data/client/src/models/Request.ts +0 -183
  44. data/client/src/stores/RequestsStore.ts +0 -36
  45. data/client/src/stores/configStore.ts +0 -8
  46. data/client/src/style.css +0 -23
  47. data/client/src/types.d.ts +0 -9
  48. data/client/src/vite-env.d.ts +0 -1
  49. data/client/tailwind.config.js +0 -16
  50. data/client/tsconfig.json +0 -29
  51. data/client/tsconfig.node.json +0 -10
  52. data/client/vite.config.ts +0 -44
  53. data/fixtures/requests/1706607114--demo_post_list.json +0 -499
  54. data/fixtures/requests/1706607120--api_jobs.json +0 -176
  55. data/fixtures/requests/1706607123--api_jobs.json +0 -119
  56. data/fixtures/requests/1706607133--demo_slow_page.json +0 -130
  57. data/fixtures/requests/1706607136--demo_post.json +0 -164
  58. data/fixtures/requests/1706607136--demo_random_post.json +0 -106
  59. data/fixtures/requests/1706607141--api_errors.json +0 -73
  60. data/package-lock.json +0 -50
  61. data/package.json +0 -5
@@ -1,32 +0,0 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- label: string
4
- count?: number
5
- isActive: boolean
6
- }>()
7
- </script>
8
-
9
- <template>
10
- <button
11
- class="text-sm flex items-center space-x-1 px-3 py-2 border-0"
12
- :class="{
13
- 'bg-stone-300 rounded-sm': props.isActive,
14
- }"
15
- >
16
- <span :class="{ 'font-medium': props.isActive }"><slot /></span>
17
- <span
18
- v-if="props.count != undefined"
19
- class="p-0.5 rounded-full text-xs"
20
- :class="{
21
- 'px-1.5': props.count < 10,
22
- hidden: props.count == 0,
23
- 'bg-stone-300': props.count > 0 && !props.isActive,
24
- 'bg-stone-400': props.count > 0 && props.isActive,
25
- // '!bg-red-700 !text-white': props.count > 10, // TODO: Should be PER TAB (30 models is fine but 30 queries is a lot)
26
- }"
27
- v-text="props.count"
28
- />
29
- </button>
30
- </template>
31
-
32
- <style scoped></style>
@@ -1,41 +0,0 @@
1
- <script setup lang="ts">
2
- import type { Cache } from "@/models/Request.ts"
3
- import Panel from "@/components/panels/Panel.vue"
4
-
5
- const props = defineProps<{
6
- cache: Cache[]
7
- }>()
8
- </script>
9
-
10
- <template>
11
- <panel>
12
- <div v-if="props.cache.length == 0">
13
- <div class="text-gray-500">No cache used.</div>
14
- </div>
15
-
16
- <div class="space-y-3">
17
- <div v-for="cache in props.cache" class="flex items-center space-x-8">
18
- <div class="w-24 text-sm text-right text-gray-400">{{ cache.time }}</div>
19
- <div class="w-16 text-right">
20
- <span
21
- class="px-1 py-0.5 rounded text-white text-xs font-mono font-medium bg-stone-400"
22
- :class="{
23
- '!bg-emerald-500': cache.label == 'hit',
24
- '!bg-indigo-500': cache.label == 'write',
25
- '!bg-amber-400': cache.label == 'read',
26
- '!bg-red-400': cache.label == 'delete',
27
- }"
28
- >
29
- {{ cache.label }}
30
- </span>
31
- </div>
32
- <div class="text-gray-800">
33
- <div class="font-medium" title="cache key">{{ cache.key }}</div>
34
- <div class="text-xs text-gray-400" title="transaction_id">{{ cache.transaction_id }}</div>
35
- </div>
36
- </div>
37
- </div>
38
- </panel>
39
- </template>
40
-
41
- <style scoped></style>
@@ -1,52 +0,0 @@
1
- <script setup lang="ts">
2
- import { Job } from "@/models/Request.ts"
3
- import Panel from "@/components/panels/Panel.vue"
4
-
5
- const props = defineProps<{
6
- jobs: Job[]
7
- }>()
8
-
9
- function formatTs(ts: number) {
10
- if (ts == null) {
11
- return "-"
12
- }
13
- return new Date(ts * 1000).toLocaleString()
14
- }
15
- </script>
16
-
17
- <template>
18
- <panel>
19
- <div v-if="props.jobs.length == 0">
20
- <div class="text-gray-500">No jobs enqueued.</div>
21
- </div>
22
-
23
- <table v-if="props.jobs.length > 0" class="my-4 mx-6 divide-y divide-stone-300">
24
- <thead>
25
- <tr>
26
- <th scope="col" class="w-36 py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-stone-900 sm:pl-0">Job</th>
27
- <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-stone-900">Args</th>
28
- <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-stone-900">Logs</th>
29
- </tr>
30
- </thead>
31
- <tbody class="divide-y divide-stone-200">
32
- <tr v-for="(v, _k) in props.jobs" :key="v.id">
33
- <td class="whitespace-nowrap p-4 pr-8 text-stone-900">
34
- <div class="text-lg font-bold" v-text="v.class"></div>
35
- <div class="text-stone-600 text-sm">
36
- <div v-text="'Queue: ' + v.queue"></div>
37
- <div v-text="'At: ' + formatTs(v.scheduled_at)"></div>
38
- </div>
39
- </td>
40
- <td class="whitespace-nowrap px-3 p-4 pr-8 text-sm">
41
- <highlightjs language="json" :code="JSON.stringify(v.args, null, 2)" />
42
- </td>
43
- <td class="whitespace-nowrap px-3 p-4 pr-8 text-sm text-stone-500">
44
- <div v-for="(log, k) in v.logs" v-html="(k > 0 ? '&nbsp; '.repeat(k) + '↳ ' : '') + log" class="" />
45
- </td>
46
- </tr>
47
- </tbody>
48
- </table>
49
- </panel>
50
- </template>
51
-
52
- <style scoped></style>
@@ -1,15 +0,0 @@
1
- <script setup lang="ts">
2
- import type { BackendRequest } from "@/models/Request.ts"
3
-
4
- const props = defineProps<{
5
- currentRequest: BackendRequest
6
- }>()
7
- </script>
8
-
9
- <template>
10
- <div class="p-4 leading-8">
11
- <highlightjs language="json" :code="JSON.stringify(props.currentRequest, null, 2)" />
12
- </div>
13
- </template>
14
-
15
- <style scoped></style>
@@ -1,43 +0,0 @@
1
- <script setup lang="ts">
2
- import { Log } from "@/models/Request.ts"
3
- import Panel from "@/components/panels/Panel.vue"
4
-
5
- const props = defineProps<{
6
- logs: Log[]
7
- }>()
8
-
9
- function message(log: Log): string {
10
- const str = log.progname || log.message || ""
11
- return str.replace(" ", "&nbsp;&nbsp;")
12
- }
13
- </script>
14
-
15
- <template>
16
- <panel>
17
- <div v-if="props.logs.length == 0">
18
- <div class="text-gray-500">No logs to show. Are you using the correct minimum level in your config?</div>
19
- </div>
20
-
21
- <div v-for="log in props.logs" class="flex items-center space-y-1 space-x-3">
22
- <div class="w-32 text-right text-gray-400">{{ log.time }}</div>
23
- <div class="w-20 text-center">
24
- <span
25
- class="px-1 py-0.5 rounded text-white text-xs font-mono font-medium"
26
- :class="{
27
- 'bg-stone-400': log.severity == 0,
28
- 'bg-blue-500': log.severity == 1,
29
- 'bg-amber-400': log.severity == 2,
30
- 'bg-red-400': log.severity == 2,
31
- 'bg-fuchsia-500': log.severity >= 3,
32
- }"
33
- :title="log.severity_label"
34
- >
35
- {{ log.severity_label }}
36
- </span>
37
- </div>
38
- <div class="text-gray-800" v-html="message(log)"></div>
39
- </div>
40
- </panel>
41
- </template>
42
-
43
- <style scoped></style>
@@ -1,25 +0,0 @@
1
- <script setup lang="ts">
2
- import { Message } from "@/models/Request.ts"
3
- import Panel from "@/components/panels/Panel.vue"
4
-
5
- const props = defineProps<{
6
- messages: Message[]
7
- }>()
8
- </script>
9
-
10
- <template>
11
- <panel>
12
- <div class="flex flex-col space-y-8">
13
- <!-- <div v-for="(msg, idx) in props.messages" v-text="msg.msg"></div>-->
14
- <div v-for="(msg, _idx) in props.messages" class="space-y-3">
15
- <div class="font-bold text-lg" v-text="msg.msg"></div>
16
- <div class="ml-4">
17
- <div v-if="!msg.extra">–</div>
18
- <highlightjs v-if="msg.extra" language="json" :code="JSON.stringify(msg.extra)" />
19
- </div>
20
- </div>
21
- </div>
22
- </panel>
23
- </template>
24
-
25
- <style scoped></style>
@@ -1,37 +0,0 @@
1
- <script setup lang="ts">
2
- import Panel from "@/components/panels/Panel.vue"
3
-
4
- const props = defineProps<{
5
- models: { [key: string]: number }
6
- count: number
7
- }>()
8
- </script>
9
-
10
- <template>
11
- <panel>
12
- <div v-if="props.count == 0">
13
- <div class="text-gray-500">No models were initialized.</div>
14
- </div>
15
-
16
- <table v-if="props.count > 0" class="divide-y divide-stone-300">
17
- <thead>
18
- <tr>
19
- <th scope="col" class="w-36 py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-stone-900 sm:pl-0">
20
- Model
21
- </th>
22
- <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-stone-900">Count</th>
23
- </tr>
24
- </thead>
25
- <tbody class="divide-y divide-stone-200">
26
- <tr v-for="(v, k) in props.models" :key="k">
27
- <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-stone-900 sm:pl-0">
28
- {{ k }}
29
- </td>
30
- <td class="whitespace-nowrap px-3 py-4 text-sm text-stone-500 text-center">{{ v }}</td>
31
- </tr>
32
- </tbody>
33
- </table>
34
- </panel>
35
- </template>
36
-
37
- <style scoped></style>
@@ -1,7 +0,0 @@
1
- <script setup lang="ts"></script>
2
-
3
- <template>
4
- <div class="px-3 py-2">
5
- <slot></slot>
6
- </div>
7
- </template>
@@ -1,98 +0,0 @@
1
- <script setup lang="ts">
2
- import omit from "lodash/omit"
3
- import Panel from "@/components/panels/Panel.vue"
4
- import { BackendRequest } from "@/models/Request.ts"
5
- import KeyValueTable from "@/components/ui/KeyValueTable.vue"
6
- import Row from "@/components/ui/Row.vue"
7
- import Foldable from "@/components/ui/Foldable.vue"
8
-
9
- defineProps<{
10
- request: BackendRequest
11
- }>()
12
- </script>
13
-
14
- <template>
15
- <div class="flex">
16
- <div class="w-1/2">
17
- <panel>
18
- <h2 class="mt-0.5 mb-2 px-2 py-1 bg-stone-300 text-black tracking-wide text-xs uppercase font-bold rounded">
19
- HTTP Request
20
- </h2>
21
-
22
- <key-value-table>
23
- <row label="Method">{{ request.meta.method }}</row>
24
- <row label="URL">{{ request.meta.path }}</row>
25
- <row label="Params">
26
- <highlightjs
27
- class="text-sm"
28
- language="json"
29
- :code="JSON.stringify(omit(request.meta.params, ['controller', 'action']), null, 2)"
30
- />
31
- </row>
32
- <row label="Header: Version">
33
- {{ request.request.headers["Version"] }}
34
- </row>
35
- <row label="Header: Cache-Control">
36
- {{ request.request.headers["Cache-Control"] }}
37
- </row>
38
- </key-value-table>
39
-
40
- <foldable class="py-4" label="All Headers">
41
- <key-value-table>
42
- <row v-for="(v, k) in request.request.headers" :key="k" :label="k as unknown as string">{{ v }}</row>
43
- </key-value-table>
44
- </foldable>
45
-
46
- <div class="py-3 text-right italic text-sm text-stone-500">
47
- What else would like to see here?
48
- <a target="_blank" class="underline font-bold" href="https://github.com/julienbourdeau/debugbar/discussions"
49
- >Tell me!</a
50
- >
51
- </div>
52
- </panel>
53
- </div>
54
-
55
- <div class="w-1/2">
56
- <panel>
57
- <h2 class="mt-0.5 mb-2 px-2 py-1 bg-stone-300 text-black tracking-wide text-xs uppercase font-bold rounded">
58
- Routing
59
- </h2>
60
-
61
- <key-value-table>
62
- <row title="Controller"> {{ request.meta.controller }} > {{ request.meta.action }} </row>
63
- </key-value-table>
64
- </panel>
65
-
66
- <panel>
67
- <h2 class="mt-0.5 mb-2 px-2 py-1 bg-stone-300 text-black tracking-wide text-xs uppercase font-bold rounded">
68
- HTTP Response
69
- </h2>
70
-
71
- <div v-if="!request.response?.status">
72
- <div class="py-3 text-sm text-stone-500">
73
- The response was not captured.
74
- <a target="_blank" class="underline font-bold" href="https://debugbar.dev/docs/known-limitations/"
75
- >Learn more</a
76
- >
77
- </div>
78
- </div>
79
-
80
- <div v-if="request.response?.status">
81
- <key-value-table>
82
- <row label="Status">{{ request.response.status }}</row>
83
- <row label="Body">{{ request.response.body.substring(0, 140) }}</row>
84
- <row label="Header: Content-Type">
85
- {{ request.response.headers["Content-Type"] }}
86
- </row>
87
- </key-value-table>
88
-
89
- <foldable class="py-4" label="All Headers">
90
- <key-value-table>
91
- <row v-for="(v, k) in request.response.headers" :key="k" :label="k as unknown as string">{{ v }}</row>
92
- </key-value-table>
93
- </foldable>
94
- </div>
95
- </panel>
96
- </div>
97
- </div>
98
- </template>
@@ -1,17 +0,0 @@
1
- <script setup lang="ts">
2
- import type { BackendRequest } from "@/models/Request.ts"
3
- import QueryItem from "@/components/queries/QueryItem.vue"
4
- import Panel from "@/components/panels/Panel.vue"
5
-
6
- const props = defineProps<{
7
- currentRequest: BackendRequest
8
- }>()
9
- </script>
10
-
11
- <template>
12
- <panel>
13
- <div class="flex flex-col space-y-8">
14
- <query-item v-for="query in props.currentRequest.queries" :key="query.id" :query="query" />
15
- </div>
16
- </panel>
17
- </template>
@@ -1,65 +0,0 @@
1
- <script setup lang="ts">
2
- import { format } from "sql-formatter"
3
- import { ChevronDownIcon } from "@heroicons/vue/16/solid"
4
-
5
- import { Query } from "@/models/Request.ts"
6
- import { reactive } from "vue"
7
-
8
- const props = defineProps<{
9
- query: Query
10
- }>()
11
-
12
- const state = reactive({
13
- isOpen: true,
14
- isFormatted: false,
15
- })
16
-
17
- function copyToClipboard(text: string) {
18
- const type = "text/plain"
19
- const blob = new Blob([text], { type })
20
- const data = [new ClipboardItem({ [type]: blob })]
21
- navigator.clipboard.write(data)
22
- }
23
- </script>
24
-
25
- <template>
26
- <div>
27
- <div class="flex items-center space-x-3">
28
- <button class="flex items-center space-x-1" @click="state.isOpen = !state.isOpen">
29
- <chevron-down-icon
30
- class="size-4"
31
- :class="{
32
- '-rotate-90': !state.isOpen,
33
- }"
34
- />
35
- <span class="font-bold text-lg">{{ query.name }}</span>
36
- </button>
37
- <span v-if="props.query.cached" class="px-1 py-0.5 rounded text-xs bg-sky-600 text-white">cached</span>
38
- <span v-if="props.query.async" class="px-1 py-0.5 rounded text-xs bg-emerald-600 text-white">async</span>
39
- <div v-if="state.isOpen">
40
- <span
41
- @click="state.isFormatted = !state.isFormatted"
42
- class="px-3 text-xs uppercase text-stone-400 cursor-pointer"
43
- title="Format SQL query"
44
- v-text="state.isFormatted ? 'unformat' : 'format'"
45
- />
46
- <span
47
- @click="copyToClipboard(query.sql)"
48
- class="px-3 text-xs uppercase text-stone-400 cursor-pointer"
49
- title="Copy SQL query to clipboard"
50
- >copy</span
51
- >
52
- </div>
53
- </div>
54
-
55
- <div v-if="state.isOpen" class="mt-4 ml-4">
56
- <div class="">
57
- <highlightjs language="sql" :code="state.isFormatted ? format(query.sql) : query.sql" />
58
- </div>
59
- <div class="mt-3 text-stone-400 text-sm">
60
- <div v-text="query.source[0]"></div>
61
- <div v-if="query.source.length > 1" v-for="s in query.source.slice(1)" class="pl-4" v-text="'↳ ' + s"></div>
62
- </div>
63
- </div>
64
- </div>
65
- </template>
@@ -1,39 +0,0 @@
1
- <script setup lang="ts">
2
- import { reactive } from "vue"
3
- import { ChevronDownIcon } from "@heroicons/vue/16/solid"
4
-
5
- const props = withDefaults(
6
- defineProps<{
7
- label: string
8
- isOpen?: boolean
9
- }>(),
10
- {
11
- isOpen: false,
12
- }
13
- )
14
-
15
- const state = reactive({
16
- isOpen: props.isOpen,
17
- })
18
- </script>
19
-
20
- <template>
21
- <div>
22
- <div>
23
- <button class="flex items-center space-x-1" @click="state.isOpen = !state.isOpen">
24
- <chevron-down-icon
25
- class="size-4"
26
- :class="{
27
- '-rotate-90': !state.isOpen,
28
- }"
29
- />
30
- <span class="font-medium">{{ props.label }}</span>
31
- </button>
32
- </div>
33
-
34
- <div v-if="state.isOpen">
35
- <slot />
36
- </div>
37
- </div>
38
- </template>
39
- <style scoped></style>
@@ -1,16 +0,0 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- keyLabel?: string
4
- valueLabel?: string
5
- }>()
6
- </script>
7
-
8
- <template>
9
- <table class="break-all w-full border-separate border-spacing-1">
10
- <tr v-if="props.keyLabel || props.valueLabel">
11
- <th v-text="props.keyLabel" class="bg-amber-50 w-40 px-3 py-1"></th>
12
- <th v-text="props.valueLabel" class="bg-amber-50 px-3 py-1"></th>
13
- </tr>
14
- <slot />
15
- </table>
16
- </template>
@@ -1,14 +0,0 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- label?: string
4
- }>()
5
- </script>
6
-
7
- <template>
8
- <tr>
9
- <td v-text="props.label" class="w-40 font-medium bg-stone-50 px-3 py-1"></td>
10
- <td class="px-3 py-1"><slot /></td>
11
- </tr>
12
- </template>
13
-
14
- <style scoped></style>