app-devtools 0.1.0 → 0.3.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 (83) hide show
  1. package/dist/main.d.ts +62 -0
  2. package/dist/main.js +2396 -0
  3. package/dist/main.umd.cjs +753 -0
  4. package/package.json +21 -16
  5. package/.eslintignore +0 -3
  6. package/.eslintrc.cjs +0 -112
  7. package/.gitattributes +0 -22
  8. package/.prettierrc +0 -10
  9. package/.quokka.ts +0 -115
  10. package/.vscode/settings.json +0 -7
  11. package/.vscode/snippets.code-snippets +0 -75
  12. package/.vscode/tasks.json +0 -17
  13. package/index.html +0 -46
  14. package/pnpm-lock.yaml +0 -5313
  15. package/scripts/check-if-is-sync.sh +0 -6
  16. package/scripts/filterFetchRequests.ts +0 -60
  17. package/src/Root.tsx +0 -11
  18. package/src/assets/icons/caret-down.svg +0 -11
  19. package/src/assets/icons/network.svg +0 -6
  20. package/src/assets/icons/search.svg +0 -3
  21. package/src/assets/icons/send.svg +0 -3
  22. package/src/assets/icons/settings.svg +0 -3
  23. package/src/components/ButtonElement.tsx +0 -18
  24. package/src/components/Icon.tsx +0 -44
  25. package/src/components/Section.tsx +0 -57
  26. package/src/components/Select.tsx +0 -101
  27. package/src/components/ValueVisualizer.tsx +0 -397
  28. package/src/config/icons.tsx +0 -23
  29. package/src/initializeApp.tsx +0 -28
  30. package/src/initializeDevTools.ts +0 -33
  31. package/src/main.ts +0 -42
  32. package/src/mocks/mockedRequests.json +0 -28391
  33. package/src/pages/api-explorer/ApiExplorerMenu.tsx +0 -136
  34. package/src/pages/api-explorer/ApiExplorerMenuItem.tsx +0 -208
  35. package/src/pages/api-explorer/Diff.tsx +0 -223
  36. package/src/pages/api-explorer/RequestDetails.tsx +0 -264
  37. package/src/pages/api-explorer/Timeline.tsx +0 -174
  38. package/src/pages/api-explorer/api-explorer.tsx +0 -21
  39. package/src/pages/api-explorer/getRequestPayload.tsx +0 -15
  40. package/src/pages/app/App.tsx +0 -79
  41. package/src/stores/callsStore.ts +0 -267
  42. package/src/stores/uiStore.ts +0 -15
  43. package/src/style/globalStyle.ts +0 -54
  44. package/src/style/helpers/allowTextSelection.ts +0 -7
  45. package/src/style/helpers/anchorColor.ts +0 -9
  46. package/src/style/helpers/centerContent.ts +0 -5
  47. package/src/style/helpers/circle.ts +0 -7
  48. package/src/style/helpers/ellipsis.ts +0 -8
  49. package/src/style/helpers/fillContainer.ts +0 -7
  50. package/src/style/helpers/gradientBorder.ts +0 -28
  51. package/src/style/helpers/gradientText.ts +0 -8
  52. package/src/style/helpers/inline.ts +0 -34
  53. package/src/style/helpers/mountAnim.ts +0 -26
  54. package/src/style/helpers/multilineEllipsis.ts +0 -8
  55. package/src/style/helpers/outline.ts +0 -5
  56. package/src/style/helpers/responsiveSize.ts +0 -27
  57. package/src/style/helpers/stack.ts +0 -36
  58. package/src/style/helpers/transition.ts +0 -63
  59. package/src/style/mediaQueries.ts +0 -6
  60. package/src/style/reset.ts +0 -75
  61. package/src/style/scrollBar.ts +0 -37
  62. package/src/style/theme.ts +0 -35
  63. package/src/types/global.d.ts +0 -8
  64. package/src/utils/initializeScreenLogger.ts +0 -12
  65. package/tsconfig.json +0 -36
  66. package/tsconfig.prod.json +0 -10
  67. package/tsup.config.ts +0 -7
  68. package/utils/arrayUtils.ts +0 -29
  69. package/utils/assertions.ts +0 -7
  70. package/utils/autoIncrementId.ts +0 -5
  71. package/utils/createThemev2.ts +0 -64
  72. package/utils/cx.ts +0 -27
  73. package/utils/getDiff.ts +0 -15
  74. package/utils/hexToRgb.ts +0 -14
  75. package/utils/objectUtils.ts +0 -3
  76. package/utils/parseUnit.ts +0 -10
  77. package/utils/solid.ts +0 -76
  78. package/utils/truncateText.ts +0 -7
  79. package/utils/tryExpression.ts +0 -14
  80. package/utils/typed.ts +0 -23
  81. package/utils/typings.ts +0 -40
  82. package/utils/urlPattern.ts +0 -25
  83. package/vite.config.ts +0 -46
@@ -1,136 +0,0 @@
1
- import Icon from '@src/components/Icon'
2
- import {
3
- ApiExplorerMenuItem,
4
- MenuItem,
5
- } from '@src/pages/api-explorer/ApiExplorerMenuItem'
6
- import { callsStore } from '@src/stores/callsStore'
7
- import { uiStore } from '@src/stores/uiStore'
8
- import { inline } from '@src/style/helpers/inline'
9
- import { stack } from '@src/style/helpers/stack'
10
- import { colors, fonts } from '@src/style/theme'
11
- import { createReconciledArray, createSignalRef } from '@utils/solid'
12
- import { css } from 'solid-styled-components'
13
-
14
- const containerStyle = css`
15
- &&& {
16
- ${stack()};
17
- border-right: 1px solid ${colors.white.alpha(0.1)};
18
-
19
- > h1 {
20
- font-size: 18px;
21
- padding-left: 12px;
22
- padding-top: 10px;
23
- font-family: ${fonts.decorative};
24
- color: ${colors.secondary.var};
25
- padding-bottom: 16px;
26
- }
27
- }
28
- `
29
-
30
- const menuContainerStyle = css`
31
- &&& {
32
- ${stack()};
33
- flex: 1 1;
34
- overflow-y: auto;
35
- padding-bottom: 16px;
36
- }
37
- `
38
-
39
- const searchStyle = css`
40
- &&& {
41
- ${inline({ gap: 8 })};
42
- margin: 0 10px;
43
- margin-bottom: 8px;
44
-
45
- display: grid;
46
- grid-template-columns: 14px 1fr;
47
- background: ${colors.white.alpha(0.05)};
48
- border-radius: 4px;
49
- --icon-size: 16px;
50
- padding: 4px 0;
51
- padding-left: 6px;
52
-
53
- .icon {
54
- color: ${colors.secondary.var};
55
- }
56
-
57
- input {
58
- border: none;
59
- background: transparent;
60
- color: ${colors.white.var};
61
-
62
- &:focus {
63
- outline: none;
64
- }
65
- }
66
- }
67
- `
68
-
69
- export const ApiExplorerMenu = () => {
70
- const search = createSignalRef('')
71
-
72
- const menuItems = createReconciledArray(() => {
73
- const callsEntries = Object.entries(callsStore.calls)
74
-
75
- const filtered: MenuItem[] = []
76
-
77
- for (const [key, value] of callsEntries.reverse()) {
78
- if (
79
- search.value.trim() &&
80
- !value.name.includes(search.value.toLowerCase())
81
- ) {
82
- continue
83
- }
84
-
85
- const subitemsWithAlias = new Set<string>()
86
-
87
- for (const request of value.requests) {
88
- if (request.alias) {
89
- subitemsWithAlias.add(request.alias)
90
- }
91
- }
92
-
93
- filtered.push({
94
- id: key,
95
- subitemsWithAlias: [...subitemsWithAlias],
96
- ...value,
97
- })
98
- }
99
-
100
- return filtered
101
- }, 'id')
102
-
103
- const currentCallId = $(uiStore.selectedCall)
104
-
105
- return (
106
- <div class={containerStyle}>
107
- <h1>API EXPLORER</h1>
108
-
109
- <label class={searchStyle}>
110
- <Icon name="search" />
111
- <input
112
- type="text"
113
- placeholder="Search"
114
- value={search.value}
115
- onInput={(e) => {
116
- search.value = e.currentTarget.value
117
- }}
118
- />
119
- </label>
120
-
121
- <div class={menuContainerStyle}>
122
- <For each={menuItems()}>
123
- {(item, i) => {
124
- return (
125
- <ApiExplorerMenuItem
126
- index={i()}
127
- item={item}
128
- currentCallId={currentCallId}
129
- />
130
- )
131
- }}
132
- </For>
133
- </div>
134
- </div>
135
- )
136
- }
@@ -1,208 +0,0 @@
1
- import ButtonElement from '@src/components/ButtonElement'
2
- import Icon from '@src/components/Icon'
3
- import { ApiCall, RequestSubTypes, RequestTypes } from '@src/stores/callsStore'
4
- import { setUiStore, uiStore } from '@src/stores/uiStore'
5
- import { ellipsis } from '@src/style/helpers/ellipsis'
6
- import { inline } from '@src/style/helpers/inline'
7
- import { stack } from '@src/style/helpers/stack'
8
- import { colors, fonts } from '@src/style/theme'
9
- import { createSignalRef } from '@utils/solid'
10
- import { css } from 'solid-styled-components'
11
-
12
- const menuItemStyle = css`
13
- &&& {
14
- font-size: 14px;
15
- ${stack()};
16
-
17
- > .call {
18
- padding: 4px 12px;
19
- ${inline()};
20
- opacity: 0.8;
21
-
22
- &.selected {
23
- opacity: 1;
24
- background-color: ${colors.secondary.alpha(0.16)};
25
- }
26
-
27
- > button {
28
- text-align: left;
29
- ${inline({ gap: 8 })};
30
-
31
- > .tag {
32
- font-weight: 600;
33
- font-family: ${fonts.decorative};
34
- }
35
-
36
- > span {
37
- ${ellipsis};
38
- flex-shrink: 1;
39
- }
40
- }
41
- }
42
-
43
- .subitem {
44
- text-align: left;
45
- padding: 4px 12px;
46
- padding-left: 14px;
47
- margin-left: 16px;
48
- border-left: 1px solid ${colors.white.alpha(0.1)};
49
-
50
- span {
51
- opacity: 0.6;
52
- padding: 4px 8px;
53
- margin-left: -8px;
54
- border-radius: 4px;
55
- }
56
-
57
- &.selected span {
58
- opacity: 1;
59
- background-color: ${colors.secondary.alpha(0.16)};
60
- }
61
-
62
- &:first-of-type {
63
- margin-top: 2px;
64
- }
65
-
66
- &:last-of-type {
67
- border-radius: 0 0 0 10px;
68
- border-bottom: 1px solid ${colors.white.alpha(0.1)};
69
- padding-bottom: 10px;
70
- margin-bottom: 4px;
71
- }
72
- }
73
-
74
- .expand-button {
75
- margin-left: auto;
76
- --icon-size: 16px;
77
-
78
- &.expanded {
79
- transform: rotate(180deg);
80
- }
81
- }
82
- }
83
- `
84
-
85
- type ApiExplorerMenuItemProps = {
86
- index: number
87
- currentCallId: string | null
88
- item: MenuItem
89
- }
90
-
91
- export type MenuItem = ApiCall & {
92
- id: string
93
- subitemsWithAlias: string[]
94
- }
95
-
96
- export const ApiExplorerMenuItem = (props: ApiExplorerMenuItemProps) => {
97
- const { item, currentCallId } = $destructure(props)
98
-
99
- const showSubitems = createSignalRef(props.item.subitemsWithAlias.length < 4)
100
-
101
- const typeIcon = getTypeIcon(item.type, item.subType)
102
-
103
- return (
104
- <div class={menuItemStyle}>
105
- <div
106
- class="call"
107
- classList={{
108
- selected: currentCallId
109
- ? currentCallId === item.id
110
- : props.index === 0,
111
- }}
112
- >
113
- <ButtonElement
114
- onClick={() => {
115
- setUiStore({ selectedCall: item.id, selectedSubitem: null })
116
- }}
117
- >
118
- <div
119
- class="tag"
120
- title={`${item.type}${item.subType ? ` (${item.subType})` : ''}`}
121
- style={{ color: typeIcon.color }}
122
- >
123
- {typeIcon.icon}
124
- </div>
125
-
126
- <span title={item.name}>{item.name}</span>
127
- </ButtonElement>
128
-
129
- {item.subitemsWithAlias.length > 0 && (
130
- <ButtonElement
131
- class="expand-button"
132
- classList={{
133
- expanded: showSubitems.value,
134
- }}
135
- onClick={() => {
136
- showSubitems.value = !showSubitems.value
137
- }}
138
- >
139
- <Icon name="caret-down" />
140
- </ButtonElement>
141
- )}
142
- </div>
143
-
144
- <Show when={showSubitems.value}>
145
- <For each={item.subitemsWithAlias}>
146
- {(subitem) => (
147
- <ButtonElement
148
- class="subitem"
149
- classList={{
150
- selected:
151
- currentCallId === item.id &&
152
- uiStore.selectedSubitem === subitem,
153
- }}
154
- onClick={() => {
155
- setUiStore({
156
- selectedCall: item.id,
157
- selectedSubitem: subitem,
158
- })
159
- }}
160
- >
161
- <span>{subitem}</span>
162
- </ButtonElement>
163
- )}
164
- </For>
165
- </Show>
166
- </div>
167
- )
168
- }
169
-
170
- function getTypeIcon(
171
- type: RequestTypes,
172
- subType: RequestSubTypes | undefined,
173
- ): {
174
- icon: string
175
- color: string
176
- } {
177
- let icon = ''
178
- let color = ''
179
-
180
- if (type === 'fetch') {
181
- icon = 'F'
182
- color = '#FDE047'
183
- } else {
184
- if (subType) {
185
- if (subType === 'create') {
186
- icon = 'C'
187
- color = '#6EE7B7'
188
- } else if (subType === 'update') {
189
- icon = 'U'
190
- color = '#A78BFA'
191
- } else if (subType === 'delete') {
192
- icon = 'D'
193
- color = '#E53558'
194
- } else {
195
- icon = subType[0]?.toUpperCase() || '?'
196
- color = '#FDE047'
197
- }
198
- } else {
199
- icon = 'M'
200
- color = '#A78BFA'
201
- }
202
- }
203
-
204
- return {
205
- icon,
206
- color,
207
- }
208
- }
@@ -1,223 +0,0 @@
1
- import { Section } from '@src/components/Section'
2
- import Select from '@src/components/Select'
3
- import { getRequestPayload } from '@src/pages/api-explorer/getRequestPayload'
4
- import { ApiRequest, callsStore } from '@src/stores/callsStore'
5
- import { uiStore } from '@src/stores/uiStore'
6
- import { stack } from '@src/style/helpers/stack'
7
- import { colors, fonts } from '@src/style/theme'
8
- import { reverseCopy } from '@utils/arrayUtils'
9
- import { getDiff } from '@utils/getDiff'
10
- import { createReconciledArray, createSignalRef } from '@utils/solid'
11
- import { truncateText } from '@utils/truncateText'
12
- import dayjs from 'dayjs'
13
- import { createMemo } from 'solid-js'
14
- import { css } from 'solid-styled-components'
15
-
16
- const containerStyle = css`
17
- &&& {
18
- ${stack({ gap: 14 })};
19
-
20
- .changes-count {
21
- color: ${colors.white.alpha(0.5)};
22
- font-size: 14px;
23
-
24
- .additions {
25
- color: ${colors.success.var};
26
- }
27
-
28
- .removals {
29
- color: ${colors.error.var};
30
- }
31
- }
32
- }
33
- `
34
-
35
- const diffContainerStyle = css`
36
- &&& {
37
- ${stack({ gap: 0 })};
38
- font-size: 14px;
39
- font-family: ${fonts.decorative};
40
- white-space: pre;
41
- overflow-x: auto;
42
-
43
- .line {
44
- opacity: 0.7;
45
- padding-left: 10px;
46
-
47
- &.added {
48
- opacity: 1;
49
- color: ${colors.success.var};
50
- background: ${colors.success.alpha(0.1)};
51
-
52
- &::before {
53
- content: '+';
54
- position: absolute;
55
- left: 0;
56
- }
57
- }
58
-
59
- &.removed {
60
- opacity: 1;
61
- color: ${colors.error.var};
62
- background: ${colors.error.alpha(0.1)};
63
-
64
- &::before {
65
- content: '-';
66
- position: absolute;
67
- left: 0;
68
- }
69
- }
70
- }
71
- }
72
- `
73
-
74
- export const Diff = () => {
75
- const currentCall = createMemo(() => {
76
- const { selectedCall } = uiStore
77
-
78
- if (!selectedCall) return Object.values(callsStore.calls).at(-1)
79
-
80
- return callsStore.calls[selectedCall]
81
- })
82
-
83
- const requestOptions = createReconciledArray(() => {
84
- const call = currentCall()
85
-
86
- if (!call) return []
87
-
88
- return reverseCopy(call.requests)
89
- .map((request) => {
90
- return {
91
- value: request.id,
92
- label: `${dayjs(request.startTime).format(
93
- 'HH:mm:ss',
94
- )} | ${truncateText(getRequestPayload(request), 50)}`,
95
- }
96
- })
97
- .filter((request) => request.value !== uiStore.selectedRequest)
98
- }, 'value')
99
-
100
- const compareRequest = createSignalRef<null | string>(null)
101
-
102
- const activeRequest = createMemo(() => {
103
- if (!uiStore.selectedRequest) return null
104
-
105
- return currentCall()?.requests.find(
106
- (request) => request.id === uiStore.selectedRequest,
107
- )
108
- })
109
-
110
- const compareFromRequest = createMemo(() => {
111
- if (!compareRequest.value) return null
112
-
113
- return currentCall()?.requests.find(
114
- (request) => request.id === compareRequest.value,
115
- )
116
- })
117
-
118
- const responseDiff = createMemo(() => {
119
- if (!compareRequest.value || !uiStore.selectedRequest) return []
120
-
121
- const activeResponse = activeRequest()?.response
122
-
123
- const compareFromResponse = compareFromRequest()?.response
124
-
125
- const diffParts = getDiff(compareFromResponse, activeResponse)
126
-
127
- return diffParts === 'no changes' ? [] : diffParts
128
- })
129
-
130
- const payloadDiff = createMemo(() => {
131
- if (!compareRequest.value || !uiStore.selectedRequest) return []
132
-
133
- const activePayload = getPayload(activeRequest())
134
-
135
- const compareFromPayload = getPayload(compareFromRequest())
136
-
137
- const diffParts = getDiff(compareFromPayload, activePayload)
138
-
139
- return diffParts === 'no changes' ? [] : diffParts
140
- })
141
-
142
- return (
143
- <div class={containerStyle}>
144
- <Select
145
- value={compareRequest.value}
146
- label="Select a request to compare with"
147
- options={requestOptions()}
148
- onChange={(value) => {
149
- compareRequest.value = value
150
- }}
151
- />
152
-
153
- <Show when={compareRequest.value}>
154
- <div class="changes-count">
155
- <span class="additions">
156
- + <b>{responseDiff().filter((item) => item.added).length}</b> lines
157
- </span>{' '}
158
- |{' '}
159
- <span class="removals">
160
- - <b>{responseDiff().filter((item) => item.removed).length}</b>{' '}
161
- lines
162
- </span>
163
- </div>
164
-
165
- <Section
166
- title={
167
- activeRequest()?.payload
168
- ? 'Payload Diff'
169
- : activeRequest()?.searchParams
170
- ? 'Search Params Diff'
171
- : 'Path Params Diff'
172
- }
173
- >
174
- <div class={diffContainerStyle}>
175
- <For
176
- each={payloadDiff()}
177
- fallback={<div>No changes</div>}
178
- >
179
- {(item) => (
180
- <div
181
- class="line"
182
- classList={{
183
- added: item.added,
184
- removed: item.removed,
185
- }}
186
- >
187
- {item.value}
188
- </div>
189
- )}
190
- </For>
191
- </div>
192
- </Section>
193
-
194
- <Section title={'Response Diff'}>
195
- <div class={diffContainerStyle}>
196
- <For
197
- each={responseDiff()}
198
- fallback={<div>No changes</div>}
199
- >
200
- {(item) => (
201
- <div
202
- class="line"
203
- classList={{
204
- added: item.added,
205
- removed: item.removed,
206
- }}
207
- >
208
- {item.value}
209
- </div>
210
- )}
211
- </For>
212
- </div>
213
- </Section>
214
- </Show>
215
- </div>
216
- )
217
- }
218
-
219
- function getPayload(request: ApiRequest | undefined | null) {
220
- if (!request) return null
221
-
222
- return request.payload || request.searchParams || request.pathParams
223
- }