mockaton 10.3.3 → 10.3.5

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": "10.3.3",
5
+ "version": "10.3.5",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
@@ -28,8 +28,11 @@ export const DF = { // Dashboard Fields (XHR)
28
28
  syncVersion: 'last_received_sync_version'
29
29
  }
30
30
 
31
+ // TODO @ThinkAbout these affecting partial matches when bulk-selecting
32
+ // e.g. 'ton' would match
31
33
  export const AUTOGENERATED_500_COMMENT = '(Mockaton 500)'
32
34
  export const DEFAULT_MOCK_COMMENT = '(default)'
35
+
33
36
  export const EXT_FOR_UNKNOWN_MIME = 'unknown'
34
37
  export const LONG_POLL_SERVER_TIMEOUT = 8_000
35
38
 
package/src/Dashboard.css CHANGED
@@ -102,10 +102,6 @@ select, a, input, button {
102
102
 
103
103
  a {
104
104
  text-decoration: none;
105
-
106
- &:hover {
107
- text-decoration: underline;
108
- }
109
105
  }
110
106
 
111
107
  a,
@@ -141,6 +137,7 @@ select {
141
137
  }
142
138
  &:disabled {
143
139
  cursor: not-allowed;
140
+ opacity: 0.5;
144
141
  }
145
142
  }
146
143
 
@@ -151,22 +148,38 @@ header {
151
148
  border-bottom: 1px solid var(--colorSecondaryActionBorder);
152
149
  background: var(--colorHeaderBackground);
153
150
 
151
+ > img {
152
+ width: 120px;
153
+ align-self: end;
154
+ margin-right: 22px;
155
+ margin-bottom: 5px;
156
+ }
157
+
154
158
  > div {
155
159
  display: flex;
160
+ width: 100%;
156
161
  flex-wrap: wrap;
157
162
  align-items: flex-end;
158
163
  gap: 16px 8px;
164
+ }
159
165
 
160
- @media (max-width: 760px) {
161
- max-width: 400px;
166
+ @media (max-width: 760px) {
167
+ > img {
168
+ width: 100px;
169
+ align-self: center;
170
+ }
171
+
172
+ > div {
173
+ width: 400px;
174
+ .MenuTrigger {
175
+ margin-left: unset;
176
+ }
162
177
  }
163
178
  }
164
-
165
- img {
166
- width: 120px;
167
- align-self: end;
168
- margin-right: 22px;
169
- margin-bottom: 5px;
179
+ @media (max-width: 424px) {
180
+ > img {
181
+ display: none;
182
+ }
170
183
  }
171
184
 
172
185
  .Field {
@@ -253,7 +266,9 @@ header {
253
266
  .ResetButton {
254
267
  padding: 6px 12px;
255
268
  border: 1px solid var(--colorRed);
269
+ margin-right: 8px;
256
270
  margin-left: 4px;
271
+ outline-offset: 1px;
257
272
  background: transparent;
258
273
  color: var(--colorRed);
259
274
  border-radius: 50px;
@@ -269,6 +284,7 @@ header {
269
284
  height: 24px;
270
285
  flex-shrink: 0;
271
286
  align-self: end;
287
+ margin-bottom: 2px;
272
288
  margin-left: auto;
273
289
  fill: var(--colorSecondaryAction);
274
290
  background: transparent;
@@ -278,6 +294,7 @@ header {
278
294
  fill: var(--colorAccent);
279
295
  }
280
296
  }
297
+
281
298
  }
282
299
 
283
300
  .SettingsMenu {
@@ -362,10 +379,6 @@ main {
362
379
  table {
363
380
  border-collapse: collapse;
364
381
 
365
- tr {
366
- border-top: 3px solid transparent;
367
- }
368
-
369
382
  th {
370
383
  padding-bottom: 2px;
371
384
  padding-left: 4px;
@@ -395,7 +408,6 @@ table {
395
408
 
396
409
  &:hover {
397
410
  background: var(--colorHover);
398
- text-decoration: none;
399
411
  }
400
412
  &.chosen {
401
413
  color: white;
@@ -404,7 +416,7 @@ table {
404
416
  }
405
417
 
406
418
  .MockSelector {
407
- height: 26px;
419
+ height: 24px;
408
420
  padding-right: 20px;
409
421
  padding-left: 8px;
410
422
  text-overflow: ellipsis;
package/src/Dashboard.js CHANGED
@@ -20,7 +20,9 @@ const Strings = {
20
20
  got: 'Got',
21
21
  group_by_method: 'Group by Method',
22
22
  internal_server_error: 'Internal Server Error',
23
+ mock_selector: 'Mock Selector',
23
24
  no_mocks_found: 'No mocks found',
25
+ none: 'None',
24
26
  not_found: 'Not Found',
25
27
  pick_comment: 'Pick Comment…',
26
28
  preview: 'Preview',
@@ -28,6 +30,7 @@ const Strings = {
28
30
  proxy_toggler: 'Proxy Toggler',
29
31
  reset: 'Reset',
30
32
  save_proxied: 'Save Mocks',
33
+ settings: 'Settings',
31
34
  static_get: 'Static GET',
32
35
  title: 'Mockaton'
33
36
  }
@@ -158,11 +161,11 @@ function Header() {
158
161
  }),
159
162
  r('div', null,
160
163
  GlobalDelayField(),
161
- CookieSelector(),
162
164
  BulkSelector(),
165
+ CookieSelector(),
163
166
  ProxyFallbackField(),
164
- ResetButton()),
165
- SettingsMenu()))
167
+ ResetButton(),
168
+ SettingsMenu())))
166
169
  }
167
170
 
168
171
  function SettingsMenu() {
@@ -199,6 +202,7 @@ function SettingsMenu() {
199
202
 
200
203
  return (
201
204
  r('button', {
205
+ title: Strings.settings,
202
206
  onClick() {
203
207
  if (!this.querySelector('menu'))
204
208
  this.appendChild(MenuContent())
@@ -216,6 +220,7 @@ function CookieSelector() {
216
220
  .catch(onError)
217
221
  }
218
222
  const disabled = cookies.length <= 1
223
+ const list = cookies.length ? cookies : [[Strings.none, true]]
219
224
  return (
220
225
  r('label', className(CSS.Field, CSS.CookieSelector),
221
226
  r('span', null, Strings.cookie),
@@ -224,7 +229,7 @@ function CookieSelector() {
224
229
  disabled,
225
230
  title: disabled ? Strings.cookie_disabled_title : '',
226
231
  onChange
227
- }, cookies.map(([value, selected]) =>
232
+ }, list.map(([value, selected]) =>
228
233
  r('option', { value, selected }, value)))))
229
234
  }
230
235
 
@@ -239,6 +244,7 @@ function BulkSelector() {
239
244
  mockaton.bulkSelectByComment(value)
240
245
  .then(parseError)
241
246
  .then(updateState)
247
+ .then(() => focus(`.${CSS.BulkSelector}`))
242
248
  .catch(onError)
243
249
  }
244
250
  const disabled = !comments.length
@@ -247,7 +253,6 @@ function BulkSelector() {
247
253
  r('span', null, Strings.bulk_select),
248
254
  r('select', {
249
255
  className: CSS.BulkSelector,
250
- 'data-qaid': 'BulkSelector',
251
256
  autocomplete: 'off',
252
257
  disabled,
253
258
  title: disabled ? Strings.bulk_select_disabled_title : '',
@@ -295,6 +300,7 @@ function ProxyFallbackField() {
295
300
  mockaton.setProxyFallback(this.value.trim())
296
301
  .then(parseError)
297
302
  .then(updateState)
303
+ .then(() => focus(`.${CSS.FallbackBackend} input`))
298
304
  .catch(onError)
299
305
  }
300
306
  return (
@@ -334,6 +340,7 @@ function ResetButton() {
334
340
  mockaton.reset()
335
341
  .then(parseError)
336
342
  .then(updateState)
343
+ .then(() => focus(`.${CSS.ResetButton}`))
337
344
  .catch(onError)
338
345
  }
339
346
  return (
@@ -466,7 +473,7 @@ function MockSelector(broker) {
466
473
  r('select', {
467
474
  onChange,
468
475
  autocomplete: 'off',
469
- 'data-qaid': urlMask,
476
+ 'aria-label': Strings.mock_selector,
470
477
  disabled: files.length <= 1,
471
478
  ...className(
472
479
  CSS.MockSelector,
@@ -666,7 +673,7 @@ Resizer.panelWidth = 0
666
673
  Resizer.onPointerDown = function (event) {
667
674
  Resizer.initialX = event.clientX
668
675
  Resizer.panelWidth = leftSideRef.current.clientWidth
669
- addEventListener('pointerup', Resizer.onUp)
676
+ addEventListener('pointerup', Resizer.onUp, { once: true })
670
677
  addEventListener('pointermove', Resizer.onMove)
671
678
  document.body.style.userSelect = 'none'
672
679
  document.body.style.cursor = 'col-resize'
@@ -681,7 +688,6 @@ Resizer.onMove = function (event) {
681
688
  }
682
689
  Resizer.onUp = function () {
683
690
  removeEventListener('pointermove', Resizer.onMove)
684
- removeEventListener('pointerup', Resizer.onUp)
685
691
  cancelAnimationFrame(Resizer.raf)
686
692
  Resizer.raf = 0
687
693
  document.body.style.userSelect = 'auto'
@@ -712,7 +718,7 @@ function PayloadViewerTitle({ file, statusText }) {
712
718
  const tokens = file.split('.')
713
719
  const ext = tokens.pop()
714
720
  const status = tokens.pop()
715
- const urlAndMethod = '/' + tokens.join('.') + '.'
721
+ const urlAndMethod = tokens.join('.') + '.'
716
722
  return (
717
723
  r('span', null,
718
724
  urlAndMethod,
@@ -800,6 +806,9 @@ function mockSelectorFor(method, urlMask) {
800
806
  return trFor(method, urlMask)?.querySelector(`select.${CSS.MockSelector}`)
801
807
  }
802
808
 
809
+ function focus(selector) {
810
+ document.querySelector(selector)?.focus()
811
+ }
803
812
 
804
813
  /** # Misc */
805
814
 
package/src/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { join } from 'node:path'
3
+ import { resolve } from 'node:path'
4
4
  import { parseArgs } from 'node:util'
5
5
 
6
6
  import { isFile } from './utils/fs.js'
@@ -68,7 +68,7 @@ else if (args.config && !isFile(args.config)) {
68
68
  process.exitCode = 1
69
69
  }
70
70
  else {
71
- const userConf = join(process.cwd(), args.config ?? 'mockaton.config.js')
71
+ const userConf = resolve(args.config ?? 'mockaton.config.js')
72
72
  const opts = isFile(userConf)
73
73
  ? (await import(userConf)).default ?? {}
74
74
  : {}
package/src/config.js CHANGED
@@ -1,4 +1,4 @@
1
- import { join, isAbsolute } from 'node:path'
1
+ import { resolve } from 'node:path'
2
2
 
3
3
  import { logger } from './utils/logger.js'
4
4
  import { isDirectory } from './utils/fs.js'
@@ -16,8 +16,8 @@ import { validateCorsAllowedMethods, validateCorsAllowedOrigins } from './utils/
16
16
  * ]
17
17
  * }} */
18
18
  const schema = {
19
- mocksDir: [join(process.cwd(), 'mockaton-mocks'), isDirectory],
20
- staticDir: [join(process.cwd(), 'mockaton-static-mocks'), optional(isDirectory)],
19
+ mocksDir: [resolve('mockaton-mocks'), isDirectory],
20
+ staticDir: [resolve('mockaton-static-mocks'), optional(isDirectory)],
21
21
  ignore: [/(\.DS_Store|~)$/, is(RegExp)], // TODO think about .well-known/appspecific/com.chrome.devtools
22
22
 
23
23
  host: ['127.0.0.1', is(String)],
@@ -69,13 +69,12 @@ export const ConfigValidator = Object.freeze(validators)
69
69
 
70
70
  /** @param {Partial<Config>} options */
71
71
  export function setup(options) {
72
- if (options.mocksDir && !isAbsolute(options.mocksDir))
73
- options.mocksDir = join(process.cwd(), options.mocksDir)
72
+ if (options.mocksDir)
73
+ options.mocksDir = resolve(options.mocksDir)
74
74
 
75
- if (options.staticDir && !isAbsolute(options.staticDir))
76
- options.staticDir = join(process.cwd(), options.staticDir)
77
-
78
- if (!options.staticDir && !isDirectory(defaults.staticDir))
75
+ if (options.staticDir)
76
+ options.staticDir = resolve(options.staticDir)
77
+ else if (!isDirectory(defaults.staticDir))
79
78
  options.staticDir = ''
80
79
 
81
80
  Object.assign(config, options)