mockaton 12.7.0 → 12.7.2

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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mockaton",
3
3
  "description": "HTTP Mock Server",
4
4
  "type": "module",
5
- "version": "12.7.0",
5
+ "version": "12.7.2",
6
6
  "exports": {
7
7
  ".": {
8
8
  "import": "./index.js",
@@ -1,8 +1,4 @@
1
- import {
2
- API,
3
- HEADER_SYNC_VERSION,
4
- LONG_POLL_SERVER_TIMEOUT
5
- } from './ApiConstants.js'
1
+ import { API } from './ApiConstants.js'
6
2
 
7
3
 
8
4
  /** Client for controlling Mockaton via its HTTP API */
@@ -13,37 +9,30 @@ export class Commander {
13
9
  this.addr = addr
14
10
  }
15
11
 
12
+ /** @returns {Promise<Response>} */
16
13
  #patch = (api, body) => fetch(this.addr + api, {
17
14
  method: 'PATCH',
18
15
  body: JSON.stringify(body)
19
16
  })
20
17
 
21
- /** @returns {Promise<Response>} */
22
18
  reset = () => this.#patch(API.reset)
23
19
 
24
- /** @returns {Promise<Response>} */
25
20
  setGlobalDelay = delay => this.#patch(API.globalDelay, delay)
26
21
 
27
- /** @returns {Promise<Response>} */
28
22
  setGlobalDelayJitter = jitterPct => this.#patch(API.globalDelayJitter, jitterPct)
29
23
 
30
- /** @returns {Promise<Response>} */
31
24
  setCorsAllowed = value => this.#patch(API.cors, value)
32
25
 
33
- /** @returns {Promise<Response>} */
34
26
  setWatchMocks = enabled => this.#patch(API.watchMocks, enabled)
35
27
 
36
- /** @returns {Promise<Response>} */
37
28
  setProxyFallback = proxyAddr => this.#patch(API.fallback, proxyAddr)
38
29
 
39
- /** @returns {Promise<Response>} */
40
30
  setCollectProxied = shouldCollect => this.#patch(API.collectProxied, shouldCollect)
41
31
 
42
32
  /** @returns {JsonPromise<State.cookies>} */
43
33
  selectCookie = label => this.#patch(API.cookies, label)
44
34
 
45
35
 
46
- /** @returns {Promise<Response>} */
47
36
  bulkSelectByComment = comment => this.#patch(API.bulkSelect, comment)
48
37
 
49
38
  /** @returns {JsonPromise<ClientMockBroker>} */
@@ -60,10 +49,8 @@ export class Commander {
60
49
  setRouteIsDelayed = (method, urlMask, delayed) => this.#patch(API.delay, [method, urlMask, delayed])
61
50
 
62
51
 
63
- /** @returns {Promise<Response>} */
64
52
  setStaticRouteStatus = (urlMask, status) => this.#patch(API.staticStatus, [urlMask, status])
65
53
 
66
- /** @returns {Promise<Response>} */
67
54
  setStaticRouteIsDelayed = (urlMask, delayed) => this.#patch(API.delayStatic, [urlMask, delayed])
68
55
 
69
56
 
@@ -71,20 +58,10 @@ export class Commander {
71
58
  /** @returns {JsonPromise<State>} */
72
59
  getState = () => fetch(this.addr + API.state)
73
60
 
61
+
74
62
  /**
75
- * This is for listening to real-time updates. It responds when a new mock is added, deleted, or renamed.
76
- * @param {number?} currSyncVer - On mismatch, it responds immediately. Otherwise, long polls.
77
- * @param {AbortSignal} abortSignal
78
- * @returns {JsonPromise<number>}
63
+ * SSE - Streams an incremental version when a mock is added, deleted, or renamed
64
+ * @returns {Promise<Response>}
79
65
  */
80
- getSyncVersion = (currSyncVer = undefined, abortSignal = undefined) =>
81
- fetch(this.addr + API.syncVersion, {
82
- signal: AbortSignal.any([
83
- abortSignal,
84
- AbortSignal.timeout(LONG_POLL_SERVER_TIMEOUT + 1000)
85
- ].filter(Boolean)),
86
- headers: currSyncVer !== undefined
87
- ? { [HEADER_SYNC_VERSION]: currSyncVer }
88
- : {}
89
- })
66
+ getSyncVersion = () => fetch(this.addr + API.syncVersion)
90
67
  }
@@ -27,10 +27,8 @@ export const API = {
27
27
  }
28
28
 
29
29
  export const HEADER_502 = 'Mockaton502'
30
- export const HEADER_SYNC_VERSION = 'sync_version'
31
30
 
32
31
  export const DEFAULT_MOCK_COMMENT = '(default)'
33
- export const LONG_POLL_SERVER_TIMEOUT = 8_000
34
32
 
35
33
  export const EXT_UNKNOWN_MIME = 'unknown'
36
34
  export const EXT_EMPTY = 'empty'
@@ -61,9 +61,9 @@ function responseStatusIsValid(status) {
61
61
  && status <= 599
62
62
  }
63
63
 
64
- export function makeMockFilename(url, method, status, ext) {
64
+ export function makeMockFilename(url, method, status, ext, comment = '') {
65
65
  const urlMask = replaceIds(removeTrailingSlash(url))
66
- return [urlMask, method, status, ext].join('.')
66
+ return [urlMask + comment, method, status, ext].join('.')
67
67
  }
68
68
 
69
69
  const reUuidV4 = /([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/gi
@@ -5,10 +5,8 @@ export const CSP = [
5
5
  `img-src data: blob: 'self'`
6
6
  ].join(';')
7
7
 
8
-
9
8
  // language=html
10
- export const IndexHtml = (hotReloadEnabled, version) =>
11
- `
9
+ export const IndexHtml = (hotReloadEnabled, version) => `
12
10
  <!DOCTYPE html>
13
11
  <html lang="en-US">
14
12
  <head>
@@ -25,8 +23,8 @@ export const IndexHtml = (hotReloadEnabled, version) =>
25
23
  </head>
26
24
  <body>
27
25
  ${hotReloadEnabled
28
- ? '<script type="module" src="watcherDev.js"></script>'
29
- : ''}
26
+ ? '<script type="module" src="watcherDev.js"></script>'
27
+ : ''}
30
28
  </body>
31
29
  </html>
32
- `.trim()
30
+ `
@@ -0,0 +1,161 @@
1
+ import { createElement as r, t, defineClassNames } from './dom-utils.js'
2
+ import { Logo, HelpIcon } from './app-icons.js'
3
+ import { store } from './app-store.js'
4
+
5
+ import CSS from './app.css' with { type: 'css' }
6
+ defineClassNames(CSS)
7
+
8
+
9
+ export function Header() {
10
+ return (
11
+ r('header', null,
12
+ r('a', {
13
+ className: CSS.Logo,
14
+ href: 'https://mockaton.com',
15
+ alt: t`Documentation`
16
+ },
17
+ Logo()),
18
+ r('div', null,
19
+ r('div', { className: CSS.GlobalDelayWrap },
20
+ GlobalDelayField(),
21
+ GlobalDelayJitterField()),
22
+ CookieSelector(),
23
+ store.showProxyField && ProxyFallbackField(),
24
+ ResetButton(),
25
+ HelpLink())))
26
+ }
27
+
28
+
29
+ function GlobalDelayField() {
30
+ function onChange() {
31
+ store.setGlobalDelay(this.valueAsNumber)
32
+ }
33
+ function onWheel(event) {
34
+ if (event.deltaY > 0)
35
+ this.stepUp()
36
+ else
37
+ this.stepDown()
38
+ clearTimeout(onWheel.timer)
39
+ onWheel.timer = setTimeout(onChange.bind(this), 300)
40
+ }
41
+ return (
42
+ r('label', { className: CSS.GlobalDelay },
43
+ r('span', null, t`Delay (ms)`),
44
+ r('input', {
45
+ type: 'number',
46
+ min: 0,
47
+ step: 100,
48
+ autocomplete: 'none',
49
+ value: store.delay,
50
+ onChange,
51
+ onWheel: [onWheel, { passive: true }]
52
+ })))
53
+ }
54
+
55
+
56
+ function GlobalDelayJitterField() {
57
+ function onChange() {
58
+ this.value = this.valueAsNumber.toFixed(0)
59
+ this.value = Math.max(0, this.valueAsNumber)
60
+ this.value = Math.min(300, this.valueAsNumber)
61
+ store.setGlobalDelayJitter(this.valueAsNumber / 100)
62
+ }
63
+ function onWheel(event) {
64
+ if (event.deltaY > 0)
65
+ this.stepUp()
66
+ else
67
+ this.stepDown()
68
+ clearTimeout(onWheel.timer)
69
+ onWheel.timer = setTimeout(onChange.bind(this), 300)
70
+ }
71
+ return (
72
+ r('label', { className: CSS.GlobalDelayJitter },
73
+ r('span', null, t`Max Jitter %`),
74
+ r('input', {
75
+ type: 'number',
76
+ min: 0,
77
+ max: 300,
78
+ step: 10,
79
+ autocomplete: 'none',
80
+ value: (store.delayJitter * 100).toFixed(0),
81
+ onChange,
82
+ onWheel: [onWheel, { passive: true }]
83
+ })))
84
+ }
85
+
86
+
87
+ function CookieSelector() {
88
+ const { cookies } = store
89
+ const disabled = cookies.length <= 1
90
+ const list = cookies.length ? cookies : [[t`None`, true]]
91
+ return (
92
+ r('label', { className: CSS.CookieSelector },
93
+ r('span', null, t`Cookie`),
94
+ r('select', {
95
+ autocomplete: 'off',
96
+ disabled,
97
+ title: disabled
98
+ ? t`No cookies specified in config.cookies`
99
+ : undefined,
100
+ onChange() { store.selectCookie(this.value) }
101
+ }, list.map(([value, selected]) =>
102
+ r('option', { value, selected }, value)))))
103
+ }
104
+
105
+
106
+ function ProxyFallbackField() {
107
+ const checkboxRef = {}
108
+ function onChange() {
109
+ checkboxRef.elem.disabled = !this.validity.valid || !this.value.trim()
110
+ if (!this.validity.valid)
111
+ this.reportValidity()
112
+ else
113
+ store.setProxyFallback(this.value.trim())
114
+ }
115
+ return (
116
+ r('div', { className: CSS.FallbackBackend },
117
+ r('label', null,
118
+ r('span', null, t`Fallback`),
119
+ r('input', {
120
+ type: 'url',
121
+ name: 'fallback',
122
+ placeholder: t`Type backend address`,
123
+ value: store.proxyFallback,
124
+ onChange
125
+ })),
126
+ SaveProxiedCheckbox(checkboxRef)))
127
+ }
128
+
129
+
130
+ function SaveProxiedCheckbox(ref) {
131
+ return (
132
+ r('label', { className: CSS.SaveProxiedCheckbox },
133
+ r('input', {
134
+ ref,
135
+ type: 'checkbox',
136
+ disabled: !store.canProxy,
137
+ checked: store.collectProxied,
138
+ onChange() { store.setCollectProxied(this.checked) }
139
+ }),
140
+ r('span', { className: CSS.checkboxBody }, t`Save Mocks`)))
141
+ }
142
+
143
+
144
+ function ResetButton() {
145
+ return (
146
+ r('button', {
147
+ className: CSS.ResetButton,
148
+ onClick: store.reset
149
+ }, t`Reset`))
150
+ }
151
+
152
+
153
+ function HelpLink() {
154
+ return (
155
+ r('a', {
156
+ target: '_blank',
157
+ href: 'https://mockaton.com',
158
+ title: t`Documentation`,
159
+ className: CSS.HelpLink
160
+ }, HelpIcon()))
161
+ }
@@ -0,0 +1,29 @@
1
+ import { createSvgElement as s } from './dom-utils.js'
2
+
3
+
4
+ export function Logo() {
5
+ return (
6
+ s('svg', { viewBox: '0 0 556 100' },
7
+ s('path', { d: 'm13.75 1.8789c-5.9487 0.19352-10.865 4.5652-11.082 11.686v81.445c-1e-7 2.216 1.784 4 4 4h4.793c2.216 0 4-1.784 4-4v-64.982c0.02794-3.4488 3.0988-3.5551 4.2031-1.1562l16.615 59.059c1.4393 5.3711 5.1083 7.9633 8.7656 7.9473 3.6573 0.01603 7.3263-2.5762 8.7656-7.9473l16.615-59.059c1.1043-2.3989 4.1752-2.2925 4.2031 1.1562v64.982c0 2.216 1.784 4 4 4h4.793c2.216 0 4-1.784 4-4v-81.445c-0.17732-7.0807-5.1334-11.492-11.082-11.686-5.9487-0.19352-12.652 3.8309-15.609 13.619l-15.686 57.334-15.686-57.334c-2.9569-9.7882-9.6607-13.813-15.609-13.619zm239.19 0.074219c-2.216 0-4 1.784-4 4v89.057c0 2.216 1.784 4 4 4h4.793c2.216 0 3.9868-1.784 4-4l0.10644-17.94c0.0734-0.07237 12.175-13.75 12.175-13.75 5.6772 11.091 11.404 22.158 17.113 33.232 1.0168 1.9689 3.4217 2.7356 5.3906 1.7188l4.2578-2.1992c1.9689-1.0168 2.7356-3.4217 1.7188-5.3906-6.4691-12.585-12.958-25.16-19.442-37.738l17.223-19.771c1.4555-1.671 1.2803-4.189-0.39062-5.6445l-3.6133-3.1465c-0.73105-0.63679-1.6224-0.96212-2.5176-0.98633-1.151-0.03113-2.3063 0.43508-3.125 1.375l-28.896 33.174v-51.99c0-2.216-1.784-4-4-4zm-58.255 23.316c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312l-0.125-7.8457c0-2.216-1.784-4-4-4h-4.6524c-2.216 0-4 1.784-4 4l3e-3 6.7888c3e-3 3.8063-1.5601 9.3694-8.4716 9.3694h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.6937 0 8.3697 5.2207 8.4687 11.828v2.2207c0 2.216 1.784 4 4 4h4.6524c2.216 0 4-1.784 4-4l0.125-5.7363c0-10.699-8.6117-19.312-19.311-19.312zm-72.182 0c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312v-34.535c0-10.699-8.6117-19.312-19.311-19.312zm1.9356 11h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v26.209c0 6.9115-1.5631 12.475-8.4746 12.475h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477z' }),
8
+ s('path', { opacity: 0.7, d: 'm331.9 25.27c-10.699 0-19.312 8.6137-19.312 19.312v4.3682c0 2.216 1.784 4 4 4h4.7715c2.216 0 4-1.784 4-4v-0.20414c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v7.0148h-28.059c-10.699 0-19.312 8.6117-19.312 19.311v4.0477c0 10.699 8.6137 19.313 19.312 19.312h17.812c2.216-1e-6 4-1.784 4-4v-4.7715c0-2.216-1.784-4-4-4h-13.648c-6.9115-2e-5 -12.477-1.5651-12.477-8.5649 0-6.9998 5.5651-8.5629 12.477-8.5629h23.895v25.897c0 2.216 1.784 4 4 4h4.7715c2.216-1e-6 4-1.784 4-4v-49.848c0-10.699-8.6117-19.312-19.311-19.312z' }),
9
+ s('path', { d: 'm392.75 1.373c-2.216 0-4 1.784-4 4v18.043h-5.3086c-2.216 0-4 1.784-4 4v4.793c0 2.216 1.784 4 4 4h5.3086v51.398c0 6.1465 3.7064 10.823 9.232 10.823h16.531c2.216 0 4-1.784 4-4v-4.793c0-2.216-1.784-4-4-4h-12.97v-49.428h9.8711c2.216 0 4-1.784 4-4v-4.793c0-2.216-1.784-4-4-4h-9.8711v-18.043c0-2.216-1.784-4-4-4zm122.96 23.896c-10.699 0-19.312 8.6137-19.312 19.312v49.812c0 2.216 1.784 4 4 4h4.7715c2.216 0 4-1.784 4-4v-45.648c0-6.9115 1.5651-12.477 8.4766-12.477h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v45.684c0 2.216 1.784 4 4 4h4.7715c2.216-1e-6 4-1.784 4-4v-49.848c0-10.699-8.6117-19.312-19.311-19.312zm-69.999 0c-10.699 0-19.312 8.6137-19.312 19.312v34.535c0 10.699 8.6137 19.312 19.312 19.312h19.717c10.699 0 19.311-8.6137 19.311-19.312v-34.535c0-10.699-8.6117-19.312-19.311-19.312zm1.9356 11h15.846c6.9115 0 8.4746 5.5651 8.4746 12.477v26.209c0 6.9115-1.5631 12.475-8.4746 12.475h-15.846c-6.9115 0-8.4766-5.5631-8.4766-12.475v-26.209c0-6.9115 1.5651-12.477 8.4766-12.477z' })))
10
+ }
11
+
12
+ export function TimerIcon() {
13
+ return (
14
+ s('svg', { viewBox: '0 0 24 24' },
15
+ s('path', { d: 'm11 5.6 0.14 7.2 6 3.7' })))
16
+ }
17
+
18
+ export function CloudIcon() {
19
+ return (
20
+ s('svg', { viewBox: '0 0 24 24' },
21
+ s('path', { d: 'm6.1 8.9c0.98-2.3 3.3-3.9 6-3.9 3.3-2e-7 6 2.5 6.4 5.7 0.018 0.15 0.024 0.18 0.026 0.23 0.0016 0.037 8.2e-4 0.084 0.098 0.14 0.097 0.054 0.29 0.05 0.48 0.05 2.2 0 4 1.8 4 4s-1.8 4-4 4c-4-0.038-9-0.038-13-0.018-2.8 0-5-2.2-5-5-2.2e-7 -2.8 2.2-5 5-5 2.8 2e-7 5 2.2 5 5' }),
22
+ s('path', { d: 'm6.1 9.1c2.8 0 5 2.3 5 5' })))
23
+ }
24
+
25
+ export function HelpIcon() {
26
+ return (
27
+ s('svg', { viewBox: '0 0 24 24' },
28
+ s('path', { d: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m1 17h-2v-2h2zm2.07-7.75-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25' })))
29
+ }
@@ -1,34 +1,28 @@
1
- import {
2
- createElement as r,
3
- t, classNames, defineClassNames
4
- } from './dom-utils.js'
5
- import { parseFilename } from './Filename.js'
1
+ import { createElement as r, t, defineClassNames } from './dom-utils.js'
6
2
  import { HEADER_502 } from './ApiConstants.js'
3
+ import { parseFilename } from './Filename.js'
7
4
  import { store } from './app-store.js'
8
5
 
9
6
  import CSS from './app.css' with { type: 'css' }
10
7
  defineClassNames(CSS)
11
8
 
12
9
 
13
- const payloadViewerTitleRef = {}
14
- const payloadViewerCodeRef = {}
10
+ const titleRef = {}
11
+ const codeRef = {}
15
12
 
16
13
  export function PayloadViewer() {
17
14
  return (
18
- r('div', classNames(CSS.PayloadViewer),
19
- RightToolbar(),
15
+ r('div', { className: CSS.PayloadViewer },
16
+
17
+ r('div', { className: CSS.SubToolbar },
18
+ r('h2', { ref: titleRef },
19
+ !store.hasChosenLink && t`Preview`)),
20
+
20
21
  r('pre', null,
21
- r('code', { ref: payloadViewerCodeRef },
22
+ r('code', { ref: codeRef },
22
23
  !store.hasChosenLink && t`Click a link to preview it`))))
23
24
  }
24
25
 
25
- function RightToolbar() {
26
- return (
27
- r('div', classNames(CSS.SubToolbar),
28
- r('h2', { ref: payloadViewerTitleRef },
29
- !store.hasChosenLink && t`Preview`)))
30
- }
31
-
32
26
 
33
27
  function PayloadViewerTitle(file, statusText) {
34
28
  const { method, status, ext } = parseFilename(file)
@@ -40,6 +34,7 @@ function PayloadViewerTitle(file, statusText) {
40
34
  '.' + ext))
41
35
  }
42
36
 
37
+
43
38
  function PayloadViewerTitleWhenProxied(response) {
44
39
  const mime = response.headers.get('content-type') || ''
45
40
  const badGateway = response.headers.get(HEADER_502)
@@ -55,7 +50,7 @@ function PayloadViewerTitleWhenProxied(response) {
55
50
  const SPINNER_DELAY = 80
56
51
  function PayloadViewerProgressBar() {
57
52
  return (
58
- r('div', classNames(CSS.ProgressBar),
53
+ r('div', { className: CSS.ProgressBar },
59
54
  r('div', {
60
55
  style: {
61
56
  animationDuration: store.delay - SPINNER_DELAY + 'ms'
@@ -63,6 +58,7 @@ function PayloadViewerProgressBar() {
63
58
  })))
64
59
  }
65
60
 
61
+
66
62
  export async function previewMock() {
67
63
  const { method, urlMask } = store.chosenLink
68
64
 
@@ -70,8 +66,8 @@ export async function previewMock() {
70
66
  previewMock.controller = new AbortController
71
67
 
72
68
  const spinnerTimer = setTimeout(() => {
73
- payloadViewerTitleRef.elem.replaceChildren(t`Fetching…`)
74
- payloadViewerCodeRef.elem.replaceChildren(PayloadViewerProgressBar())
69
+ titleRef.elem.replaceChildren(t`Fetching…`)
70
+ codeRef.elem.replaceChildren(PayloadViewerProgressBar())
75
71
  }, SPINNER_DELAY)
76
72
 
77
73
  try {
@@ -87,29 +83,30 @@ export async function previewMock() {
87
83
  catch (error) {
88
84
  clearTimeout(spinnerTimer)
89
85
  store.onError(error)
90
- payloadViewerCodeRef.elem.replaceChildren()
86
+ codeRef.elem.replaceChildren()
91
87
  }
92
88
  }
93
89
 
90
+
94
91
  async function updatePayloadViewer(proxied, file, response) {
95
92
  const mime = response.headers.get('content-type') || ''
96
93
 
97
- payloadViewerTitleRef.elem.replaceChildren(proxied
94
+ titleRef.elem.replaceChildren(proxied
98
95
  ? PayloadViewerTitleWhenProxied(response)
99
96
  : PayloadViewerTitle(file, response.statusText))
100
97
 
101
98
  if (mime.startsWith('image/')) // Naively assumes GET 200
102
- payloadViewerCodeRef.elem.replaceChildren(r('img', {
99
+ codeRef.elem.replaceChildren(r('img', {
103
100
  src: URL.createObjectURL(await response.blob())
104
101
  }))
105
102
  else {
106
103
  const body = await response.text() || t`/* Empty Response Body */`
107
104
  if (mime === 'application/json')
108
- payloadViewerCodeRef.elem.replaceChildren(SyntaxJSON(body))
105
+ codeRef.elem.replaceChildren(SyntaxJSON(body))
109
106
  else if (isXML(mime))
110
- payloadViewerCodeRef.elem.replaceChildren(SyntaxXML(body))
107
+ codeRef.elem.replaceChildren(SyntaxXML(body))
111
108
  else
112
- payloadViewerCodeRef.elem.textContent = body
109
+ codeRef.elem.textContent = body
113
110
  }
114
111
  }
115
112
 
@@ -42,8 +42,6 @@ export const store = {
42
42
  },
43
43
 
44
44
 
45
- getSyncVersion: api.getSyncVersion,
46
-
47
45
  _request(action, onSuccess) {
48
46
  Promise.try(async () => {
49
47
  const response = await action()
@@ -11,6 +11,7 @@
11
11
  --colorLabel: light-dark(#555, #aaa);
12
12
  --colorDisabledMockSelector: light-dark(#444, #a9b9b9);
13
13
  --colorText: light-dark(#000, #fff);
14
+
14
15
  --colorAccent: light-dark(#0059dd, #2495ff);
15
16
  --colorHover: light-dark(rgba(119, 193, 255, 0.4), rgba(0, 63, 115, 0.5));
16
17
  --colorRed: light-dark(#da0f00, #f41606);
@@ -45,7 +46,7 @@ body {
45
46
  font-family: inherit;
46
47
  font-size: 100%;
47
48
  scrollbar-width: thin;
48
- corner-shape: squircle
49
+ corner-shape: squircle;
49
50
  }
50
51
 
51
52
  a:focus-visible,
@@ -99,6 +100,7 @@ select {
99
100
  }
100
101
  }
101
102
 
103
+
102
104
  header {
103
105
  display: flex;
104
106
  flex: 0 0 100%;
@@ -192,7 +194,10 @@ header {
192
194
  }
193
195
  }
194
196
 
195
- .Field {
197
+ .GlobalDelay,
198
+ .GlobalDelayJitter,
199
+ .CookieSelector,
200
+ .FallbackBackend {
196
201
  width: 116px;
197
202
 
198
203
  span {
@@ -226,7 +231,7 @@ header {
226
231
  border-radius: var(--radius);
227
232
  }
228
233
 
229
- &.GlobalDelayField {
234
+ &.GlobalDelay {
230
235
  position: relative;
231
236
  width: 76px;
232
237
 
@@ -249,7 +254,7 @@ header {
249
254
  }
250
255
  }
251
256
 
252
- &.GlobalDelayJitterField {
257
+ &.GlobalDelayJitter {
253
258
  width: 80px;
254
259
  span {
255
260
  margin-left: 4px;
@@ -415,7 +420,7 @@ main {
415
420
  text-align: left;
416
421
 
417
422
  &:first-of-type {
418
- border-top: 0
423
+ border-top: 0;
419
424
  }
420
425
 
421
426
  &.canProxy {
@@ -528,7 +533,7 @@ main {
528
533
  &:focus-visible {
529
534
  outline: 0;
530
535
  & + .checkboxBody {
531
- outline: 2px solid var(--colorAccent)
536
+ outline: 2px solid var(--colorAccent);
532
537
  }
533
538
  }
534
539