logster 2.11.4 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +63 -12
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +10 -5
  5. data/README.md +8 -0
  6. data/assets/javascript/.gitkeep +0 -0
  7. data/assets/javascript/chunk.143.2faa04830259ce9aa59a.js +22 -0
  8. data/assets/javascript/chunk.178.ca5ade1d8cbdbfbe6d72.js +22 -0
  9. data/assets/javascript/chunk.468.95dd450003497c781cb3.js +1213 -0
  10. data/assets/javascript/chunk.916.85a3fc9d873df80f5ea5.js +579 -0
  11. data/assets/javascript/client-app.js +1257 -280
  12. data/assets/javascript/vendor.js +4068 -3375
  13. data/assets/stylesheets/.gitkeep +0 -0
  14. data/assets/stylesheets/client-app.css +1 -1
  15. data/assets/stylesheets/vendor.css +1 -1
  16. data/build_client_app.sh +6 -8
  17. data/client-app/.editorconfig +0 -1
  18. data/client-app/.eslintignore +2 -0
  19. data/client-app/.eslintrc +10 -0
  20. data/client-app/.gitignore +1 -1
  21. data/client-app/.prettierignore +21 -0
  22. data/client-app/.prettierrc +1 -0
  23. data/client-app/.template-lintrc.js +10 -0
  24. data/client-app/README.md +4 -5
  25. data/client-app/app/app.js +2 -2
  26. data/client-app/app/components/actions-menu.js +21 -21
  27. data/client-app/app/components/back-trace.js +89 -90
  28. data/client-app/app/components/env-tab.js +41 -29
  29. data/client-app/app/components/message-info.js +78 -75
  30. data/client-app/app/components/message-row.js +20 -17
  31. data/client-app/app/components/page-nav.js +33 -24
  32. data/client-app/app/components/panel-resizer.js +53 -37
  33. data/client-app/app/components/patterns-list.js +101 -84
  34. data/client-app/app/components/tab-contents.js +15 -19
  35. data/client-app/app/components/tabbed-section.js +30 -18
  36. data/client-app/app/components/time-formatter.js +29 -18
  37. data/client-app/app/controllers/index.js +143 -119
  38. data/client-app/app/controllers/show.js +17 -13
  39. data/client-app/app/helpers/or.js +1 -1
  40. data/client-app/app/initializers/app-init.js +23 -34
  41. data/client-app/app/lib/decorators.js +4 -2
  42. data/client-app/app/lib/preload.js +7 -4
  43. data/client-app/app/lib/utilities.js +55 -54
  44. data/client-app/app/models/group.js +20 -15
  45. data/client-app/app/models/message-collection.js +153 -149
  46. data/client-app/app/models/message.js +60 -58
  47. data/client-app/app/models/pattern-item.js +24 -22
  48. data/client-app/app/router.js +2 -2
  49. data/client-app/app/routes/index.js +19 -12
  50. data/client-app/app/routes/settings.js +12 -10
  51. data/client-app/app/routes/show.js +6 -4
  52. data/client-app/app/services/events.js +4 -0
  53. data/client-app/app/styles/app.css +2 -0
  54. data/client-app/app/templates/application.hbs +1 -2
  55. data/client-app/app/templates/components/actions-menu.hbs +23 -8
  56. data/client-app/app/templates/components/back-trace.hbs +10 -3
  57. data/client-app/app/templates/components/env-tab.hbs +9 -7
  58. data/client-app/app/templates/components/message-info.hbs +65 -34
  59. data/client-app/app/templates/components/message-row.hbs +25 -8
  60. data/client-app/app/templates/components/page-nav.hbs +34 -10
  61. data/client-app/app/templates/components/panel-resizer.hbs +3 -3
  62. data/client-app/app/templates/components/patterns-list.hbs +54 -20
  63. data/client-app/app/templates/components/tabbed-section.hbs +12 -4
  64. data/client-app/app/templates/components/time-formatter.hbs +1 -1
  65. data/client-app/app/templates/index.hbs +100 -78
  66. data/client-app/app/templates/settings.hbs +30 -19
  67. data/client-app/app/templates/show.hbs +9 -8
  68. data/client-app/config/ember-cli-update.json +18 -0
  69. data/client-app/config/environment.js +13 -13
  70. data/client-app/config/icons.js +3 -3
  71. data/client-app/config/targets.js +16 -8
  72. data/client-app/ember-cli-build.js +4 -4
  73. data/client-app/package.json +41 -31
  74. data/client-app/testem.js +16 -17
  75. data/client-app/tests/index.html +8 -1
  76. data/client-app/tests/integration/components/back-trace-test.js +32 -26
  77. data/client-app/tests/integration/components/env-tab-test.js +79 -53
  78. data/client-app/tests/integration/components/message-info-test.js +25 -23
  79. data/client-app/tests/integration/components/patterns-list-test.js +14 -11
  80. data/client-app/tests/test-helper.js +8 -4
  81. data/client-app/tests/unit/controllers/index-test.js +32 -16
  82. data/client-app/tests/unit/controllers/show-test.js +5 -5
  83. data/client-app/tests/unit/routes/index-test.js +5 -5
  84. data/client-app/tests/unit/routes/show-test.js +5 -5
  85. data/client-app/yarn.lock +9673 -0
  86. data/lib/logster/version.rb +1 -1
  87. data/logster.gemspec +6 -3
  88. metadata +15 -6
  89. data/client-app/.eslintrc.js +0 -60
  90. data/client-app/.travis.yml +0 -28
  91. data/client-app/app/components/update-time.js +0 -21
  92. data/client-app/package-lock.json +0 -16639
@@ -1,19 +1,23 @@
1
+ import classic from "ember-classic-decorator";
1
2
  import Controller from "@ember/controller";
3
+ import { action } from "@ember/object";
2
4
 
3
- export default Controller.extend({
4
- envPosition: 0,
5
+ @classic
6
+ export default class ShowController extends Controller {
7
+ envPosition = 0;
5
8
 
6
- actions: {
7
- protect() {
8
- this.get("model").protect();
9
- },
9
+ @action
10
+ protect() {
11
+ this.model.protect();
12
+ }
10
13
 
11
- unprotect() {
12
- this.get("model").unprotect();
13
- },
14
+ @action
15
+ unprotect() {
16
+ this.model.unprotect();
17
+ }
14
18
 
15
- envChanged(newPosition) {
16
- this.set("envPosition", newPosition);
17
- }
19
+ @action
20
+ envChanged(newPosition) {
21
+ this.set("envPosition", newPosition);
18
22
  }
19
- });
23
+ }
@@ -1,7 +1,7 @@
1
1
  import { helper } from "@ember/component/helper";
2
2
 
3
3
  export function or(params) {
4
- return params.some(p => p);
4
+ return params.some((p) => p);
5
5
  }
6
6
 
7
7
  export default helper(or);
@@ -1,28 +1,28 @@
1
1
  import {
2
- updateHiddenProperty,
2
+ ajax,
3
3
  resetTitleCount,
4
- ajax
4
+ updateHiddenProperty,
5
5
  } from "client-app/lib/utilities";
6
- import Evented from "@ember/object/evented";
7
- import EmberObject from "@ember/object";
8
6
  import { setRootPath } from "client-app/lib/preload";
9
7
 
10
- const TARGETS = ["component", "route"];
11
-
12
- export function initialize(app) {
8
+ export async function initialize(app) {
13
9
  const config = app.resolveRegistration("config:environment");
14
10
  setRootPath(config.rootURL.replace(/\/$/, ""));
15
11
 
16
12
  if (config.environment === "development") {
17
13
  app.deferReadiness();
18
- ajax("/development-preload.json")
19
- .then(data => {
20
- const elem = document.getElementById("preloaded-data");
21
- elem.setAttribute("data-preloaded", JSON.stringify(data));
22
- })
23
- .catch(xhr => console.error("Fetching preload data failed.", xhr)) // eslint-disable-line no-console
24
- .finally(() => app.advanceReadiness());
14
+
15
+ try {
16
+ const data = await ajax("/development-preload.json");
17
+ const elem = document.getElementById("preloaded-data");
18
+ elem.setAttribute("data-preloaded", JSON.stringify(data));
19
+ } catch (xhr) {
20
+ console.error("Fetching preload data failed.", xhr); // eslint-disable-line no-console
21
+ } finally {
22
+ app.advanceReadiness();
23
+ }
25
24
  }
25
+
26
26
  // config for moment.js
27
27
  moment.updateLocale("en", {
28
28
  relativeTime: {
@@ -38,45 +38,34 @@ export function initialize(app) {
38
38
  M: "a mth",
39
39
  MM: "%d mths",
40
40
  y: "a yr",
41
- yy: "%d yrs"
42
- }
41
+ yy: "%d yrs",
42
+ },
43
43
  });
44
44
 
45
45
  // setup event for updating document title and title count
46
46
  let hiddenProperty;
47
47
  let visibilitychange;
48
48
 
49
- ["", "webkit", "ms", "moz", "ms"].forEach(prefix => {
49
+ for (const prefix of ["", "webkit", "ms", "moz", "ms"]) {
50
50
  const check = prefix + (prefix === "" ? "hidden" : "Hidden");
51
- if (document[check] !== undefined && !hiddenProperty) {
51
+
52
+ if (document[check] !== undefined) {
52
53
  hiddenProperty = check;
53
54
  visibilitychange = prefix + "visibilitychange";
55
+ break;
54
56
  }
55
- });
57
+ }
56
58
 
57
59
  updateHiddenProperty(hiddenProperty);
58
- document.addEventListener(
59
- visibilitychange,
60
- () => {
61
- resetTitleCount();
62
- },
63
- false
64
- );
65
-
66
- app.register("events:main", EmberObject.extend(Evented).create(), {
67
- instantiate: false
68
- });
69
- TARGETS.forEach(t => app.inject(t, "events", "events:main"));
60
+ document.addEventListener(visibilitychange, resetTitleCount, false);
70
61
 
71
62
  const isMobile =
72
63
  /mobile/i.test(navigator.userAgent) && !/iPad/.test(navigator.userAgent);
73
64
  if (isMobile) {
74
65
  document.body.classList.add("mobile");
75
66
  }
76
- app.register("site:main", { isMobile }, { instantiate: false });
77
- app.inject("controller", "site", "site:main");
78
67
  }
79
68
 
80
69
  export default {
81
- initialize
70
+ initialize,
82
71
  };
@@ -3,9 +3,11 @@ export function bound(target, key, desc) {
3
3
  const boundKey = `_${key}Bound`;
4
4
  return {
5
5
  get() {
6
- if (this[boundKey]) return this[boundKey];
6
+ if (this[boundKey]) {
7
+ return this[boundKey];
8
+ }
7
9
  this.set(boundKey, orig.bind(this));
8
10
  return this[boundKey];
9
- }
11
+ },
10
12
  };
11
13
  }
@@ -1,3 +1,5 @@
1
+ import { set } from "@ember/object";
2
+
1
3
  let CONTAINER = {};
2
4
  let isInitialized = false;
3
5
  let rootPath;
@@ -13,7 +15,7 @@ export function getRootPath() {
13
15
  // exported so that it can be used in tests
14
16
  export function init() {
15
17
  const dataset = document.getElementById("preloaded-data").dataset;
16
- CONTAINER = JSON.parse(dataset.preloaded);
18
+ CONTAINER = dataset.preloaded ? JSON.parse(dataset.preloaded) : {};
17
19
  CONTAINER.rootPath = rootPath;
18
20
  isInitialized = true;
19
21
  }
@@ -23,8 +25,8 @@ export default {
23
25
  if (!isInitialized) {
24
26
  init();
25
27
  }
26
- return Em.get(CONTAINER, key);
27
- }
28
+ return CONTAINER[key];
29
+ },
28
30
  };
29
31
 
30
32
  // used in tests
@@ -32,7 +34,8 @@ export function mutatePreload(key, value) {
32
34
  if (!isInitialized) {
33
35
  init();
34
36
  }
35
- Em.set(CONTAINER, key, value);
37
+
38
+ set(CONTAINER, key, value);
36
39
  }
37
40
 
38
41
  export function uninitialize() {
@@ -1,5 +1,4 @@
1
- import { default as Preload, getRootPath } from "client-app/lib/preload";
2
- import { Promise, resolve } from "rsvp";
1
+ import Preload, { getRootPath } from "client-app/lib/preload";
3
2
 
4
3
  const entityMap = {
5
4
  "&": "&",
@@ -7,32 +6,36 @@ const entityMap = {
7
6
  ">": ">",
8
7
  '"': """,
9
8
  "'": "'",
10
- "/": "/"
9
+ "/": "/",
11
10
  };
12
11
 
13
12
  export function escapeHtml(string) {
14
- return String(string).replace(/[&<>"'/]/g, s => entityMap[s]);
13
+ return String(string).replace(/[&<>"'/]/g, (s) => entityMap[s]);
15
14
  }
16
15
 
17
16
  export function ajax(url, settings) {
17
+ // eslint-disable-next-line no-restricted-globals
18
18
  return new Promise((resolve, reject) => {
19
- settings = settings || {};
19
+ settings ||= {};
20
20
  const xhr = new XMLHttpRequest();
21
21
  url = getRootPath() + url;
22
+
22
23
  if (settings.data) {
23
- for (let param in settings.data) {
24
- const prefix = url.indexOf("?") === -1 ? "?" : "&";
25
- url += prefix;
26
- url += `${param}=${encodeURIComponent(settings.data[param])}`;
24
+ for (const [param, value] of Object.entries(settings.data)) {
25
+ url += url.includes("?") ? "&" : "?";
26
+ url += `${param}=${encodeURIComponent(value)}`;
27
27
  }
28
28
  }
29
+
29
30
  xhr.open(settings.method || settings.type || "GET", url);
30
31
  xhr.setRequestHeader("X-SILENCE-LOGGER", true);
32
+
31
33
  if (settings.headers) {
32
- for (let header in settings.headers) {
33
- xhr.setRequestHeader(header, settings.headers[header]);
34
+ for (const [header, value] of Object.entries(settings.headers)) {
35
+ xhr.setRequestHeader(header, value);
34
36
  }
35
37
  }
38
+
36
39
  xhr.onreadystatechange = () => {
37
40
  if (xhr.readyState === 4) {
38
41
  let status = xhr.status;
@@ -48,16 +51,17 @@ export function ajax(url, settings) {
48
51
  }
49
52
  }
50
53
  };
54
+
51
55
  xhr.send();
52
56
  });
53
57
  }
54
58
 
55
- export function preloadOrAjax(url, settings) {
59
+ export async function preloadOrAjax(url, settings) {
56
60
  const preloaded = Preload.get(url.replace(".json", ""));
57
61
  if (preloaded) {
58
- return resolve(preloaded);
62
+ return preloaded;
59
63
  } else {
60
- return ajax(url, settings);
64
+ return await ajax(url, settings);
61
65
  }
62
66
  }
63
67
 
@@ -81,8 +85,9 @@ export function increaseTitleCount(increment) {
81
85
  if (!isHidden()) {
82
86
  return;
83
87
  }
84
- TITLE = TITLE || document.title;
85
- TITLE_COUNT = TITLE_COUNT || 0;
88
+
89
+ TITLE ||= document.title;
90
+ TITLE_COUNT ||= 0;
86
91
  TITLE_COUNT += increment;
87
92
  document.title = `${TITLE} (${TITLE_COUNT})`;
88
93
  }
@@ -93,57 +98,52 @@ export function resetTitleCount() {
93
98
  }
94
99
 
95
100
  export function formatTime(timestamp) {
96
- let formatted;
97
101
  const time = moment(timestamp);
98
102
  const now = moment();
99
103
 
100
104
  if (time.diff(now.startOf("day")) > 0) {
101
- formatted = time.format("h:mm a");
105
+ return time.format("h:mm a");
106
+ } else if (time.diff(now.startOf("week")) > 0) {
107
+ return time.format("dd h:mm a");
108
+ } else if (time.diff(now.startOf("year")) > 0) {
109
+ return time.format("D MMM h:mm a");
102
110
  } else {
103
- if (time.diff(now.startOf("week")) > 0) {
104
- formatted = time.format("dd h:mm a");
105
- } else {
106
- if (time.diff(now.startOf("year")) > 0) {
107
- formatted = time.format("D MMM h:mm a");
108
- } else {
109
- formatted = time.format("D MMM YY");
110
- }
111
- }
111
+ return time.format("D MMM YY");
112
112
  }
113
-
114
- return formatted;
115
113
  }
116
114
 
117
115
  export function buildArrayString(array) {
118
- const buffer = [];
119
- array.forEach(v => {
116
+ const buffer = array.map((v) => {
120
117
  if (v === null) {
121
- buffer.push("null");
122
- } else if (Object.prototype.toString.call(v) === "[object Array]") {
123
- buffer.push(buildArrayString(v));
118
+ return "null";
119
+ } else if (Array.isArray(v)) {
120
+ return buildArrayString(v);
124
121
  } else {
125
- buffer.push(escapeHtml(v.toString()));
122
+ return escapeHtml(v.toString());
126
123
  }
127
124
  });
125
+
128
126
  return "[" + buffer.join(", ") + "]";
129
127
  }
130
128
 
131
129
  export function buildHashString(hash, recurse, expanded = []) {
132
- if (!hash) return "";
130
+ if (!hash) {
131
+ return "";
132
+ }
133
133
 
134
134
  const buffer = [];
135
135
  const hashes = [];
136
136
  const expandableKeys = Preload.get("env_expandable_keys") || [];
137
- Object.keys(hash).forEach(k => {
138
- const v = hash[k];
137
+
138
+ for (const [k, v] of Object.entries(hash)) {
139
139
  if (v === null) {
140
140
  buffer.push("null");
141
141
  } else if (Object.prototype.toString.call(v) === "[object Array]") {
142
142
  let valueHtml = "";
143
143
  if (
144
- expandableKeys.indexOf(k) !== -1 &&
144
+ expandableKeys.includes(k) &&
145
145
  !recurse &&
146
- expanded.indexOf(k) === -1 &&
146
+ !expanded.includes(k) &&
147
147
  v.length > 3
148
148
  ) {
149
149
  valueHtml = `${escapeHtml(
@@ -168,18 +168,17 @@ export function buildHashString(hash, recurse, expanded = []) {
168
168
  );
169
169
  }
170
170
  }
171
- });
171
+ }
172
172
 
173
- if (hashes.length > 0) {
174
- hashes.forEach(k1 => {
175
- const v = hash[k1];
176
- buffer.push("<tr><td></td><td><table>");
177
- buffer.push(
178
- `<td>${escapeHtml(k1)}</td><td>${buildHashString(v, true)}</td>`
179
- );
180
- buffer.push("</table></td></tr>");
181
- });
173
+ for (const k1 of hashes) {
174
+ const v = hash[k1];
175
+ buffer.push("<tr><td></td><td><table>");
176
+ buffer.push(
177
+ `<td>${escapeHtml(k1)}</td><td>${buildHashString(v, true)}</td>`
178
+ );
179
+ buffer.push("</table></td></tr>");
182
180
  }
181
+
183
182
  const className = recurse ? "" : "env-table";
184
183
  return `<table class='${className}'>${buffer.join("\n")}</table>`;
185
184
  }
@@ -188,9 +187,9 @@ export function clone(object) {
188
187
  // simple function to clone an object
189
188
  // we don't need it fancier than this
190
189
  const copy = {};
191
- Object.keys(object).forEach(k => {
192
- copy[k] = object[k];
193
- });
190
+ for (const [k, v] of Object.entries(object)) {
191
+ copy[k] = v;
192
+ }
194
193
  return copy;
195
194
  }
196
195
 
@@ -200,7 +199,9 @@ export function setLocalStorage(key, value) {
200
199
  key = "logster-" + key;
201
200
  window.localStorage.setItem(key, value);
202
201
  }
203
- } catch { /* do nothing */ }
202
+ } catch {
203
+ /* do nothing */
204
+ }
204
205
  }
205
206
 
206
207
  export function getLocalStorage(key, fallback) {
@@ -1,29 +1,34 @@
1
- import Message from "client-app/models/message";
2
- import { default as EmberObject, computed } from "@ember/object";
1
+ import classic from "ember-classic-decorator";
3
2
  import { reads } from "@ember/object/computed";
3
+ import Message from "client-app/models/message";
4
+ import EmberObject, { computed } from "@ember/object";
4
5
  import { ajax } from "client-app/lib/utilities";
5
6
 
6
- export default EmberObject.extend({
7
- selected: false,
8
- showCount: true,
9
- key: reads("regex"),
10
- displayMessage: reads("messages.firstObject.message"),
7
+ @classic
8
+ export default class Group extends EmberObject {
9
+ selected = false;
10
+ showCount = true;
11
+
12
+ @reads("regex") key;
13
+ @reads("messages.firstObject.message") displayMessage;
11
14
 
12
15
  init() {
13
- this._super(...arguments);
14
- const messages = this.messages.map(m => Message.create(m));
16
+ super.init(...arguments);
17
+ const messages = this.messages.map((m) => Message.create(m));
15
18
  this.set("messages", messages);
16
- },
19
+ }
17
20
 
18
- glyph: computed(function() {
21
+ @computed
22
+ get glyph() {
19
23
  return "clone";
20
- }),
24
+ }
21
25
 
22
- prefix: computed(function() {
26
+ @computed
27
+ get prefix() {
23
28
  return "far";
24
- }),
29
+ }
25
30
 
26
31
  solveAll() {
27
32
  return ajax("/solve-group", { type: "POST", data: { regex: this.regex } });
28
33
  }
29
- });
34
+ }