kayvee 3.17.0 → 4.0.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 (61) hide show
  1. package/README.md +147 -202
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +29 -0
  5. package/dist/kayvee.d.ts +12 -0
  6. package/dist/kayvee.d.ts.map +1 -0
  7. package/dist/kayvee.js +50 -0
  8. package/dist/logger/logger.d.ts +49 -0
  9. package/dist/logger/logger.d.ts.map +1 -0
  10. package/dist/logger/logger.js +237 -0
  11. package/dist/middleware.d.ts +23 -0
  12. package/dist/middleware.d.ts.map +1 -0
  13. package/dist/middleware.js +196 -0
  14. package/dist/package.json +89 -0
  15. package/dist/router/index.d.ts +23 -0
  16. package/dist/router/index.d.ts.map +1 -0
  17. package/dist/router/index.js +184 -0
  18. package/package.json +64 -24
  19. package/.circleci/config.yml +0 -25
  20. package/.eslintrc.yml +0 -44
  21. package/.nvmrc +0 -1
  22. package/.prettierrc.json +0 -1
  23. package/Makefile +0 -56
  24. package/benchmarks/data/.keep +0 -1
  25. package/benchmarks/data/corpus-basic.json +0 -22
  26. package/benchmarks/data/corpus-pathological.json +0 -22
  27. package/benchmarks/data/corpus-realistic.json +0 -22
  28. package/benchmarks/data/kvconfig-basic.yml +0 -7
  29. package/benchmarks/data/kvconfig-pathological.yml +0 -222
  30. package/benchmarks/data/kvconfig-realistic.yml +0 -39
  31. package/benchmarks/routing.js +0 -116
  32. package/build/lib/kayvee.js +0 -67
  33. package/build/lib/logger/helpers.js +0 -0
  34. package/build/lib/logger/logger.js +0 -221
  35. package/build/lib/middleware.js +0 -302
  36. package/build/lib/router/index.js +0 -198
  37. package/build/package.json +0 -49
  38. package/build/test/context_logger.js +0 -77
  39. package/build/test/kayvee.js +0 -36
  40. package/build/test/logger_test.js +0 -334
  41. package/build/test/middleware.js +0 -557
  42. package/build/test/router.js +0 -311
  43. package/index.js +0 -7
  44. package/lib/kayvee.ts +0 -73
  45. package/lib/logger/helpers.ts +0 -0
  46. package/lib/logger/logger.ts +0 -296
  47. package/lib/middleware.ts +0 -317
  48. package/lib/router/index.ts +0 -234
  49. package/lib/router/schema_definitions.json +0 -158
  50. package/test/context_logger.ts +0 -76
  51. package/test/kayvee.ts +0 -50
  52. package/test/kvconfig.yml +0 -14
  53. package/test/logger_test.ts +0 -378
  54. package/test/middleware.ts +0 -632
  55. package/test/router.ts +0 -558
  56. package/test/static/empty.css +0 -0
  57. package/test/static/js/empty.js +0 -0
  58. package/test/tests.json +0 -100
  59. package/tsconfig.json +0 -10
  60. package/tslint.json +0 -134
  61. /package/{build/lib → dist}/router/schema_definitions.json +0 -0
package/test/router.ts DELETED
@@ -1,558 +0,0 @@
1
- var assert = require("assert");
2
- var router = require("../lib/router");
3
-
4
- describe("router.Router", () => {
5
- describe("constructor", () => {
6
- it("parses well formatted configs", () => {
7
- process.env.SCHOOL = "Hogwarts";
8
- const conf = `
9
- routes:
10
- rule-one:
11
- matchers:
12
- title: ["authorize-app"]
13
- output:
14
- type: "notifications"
15
- channel: "%{foo.bar}"
16
- icon: ":rocket:"
17
- message: "authorized %{foo.bar} in \${SCHOOL}"
18
- user: "@fishman"
19
- rule-two:
20
- matchers:
21
- foo.bar: ["multiple", "matches"]
22
- baz: ["whatever"]
23
- output:
24
- type: "alerts"
25
- series: "other-series"
26
- dimensions: ["baz"]
27
- stat_type: "gauge"
28
- rule-three:
29
- matchers:
30
- foo.bar: ["multiple", "matches"]
31
- baz: ["whatever"]
32
- output:
33
- type: "alerts"
34
- series: "other-series"
35
- dimensions: ["baz"]
36
- stat_type: "gauge"
37
- value_field: "hello"
38
- rule-four:
39
- matchers:
40
- foo.bar: ["multiple", "matches"]
41
- baz: ["whatever"]
42
- output:
43
- type: "alerts"
44
- series: "other-series"
45
- dimensions: []
46
- stat_type: "gauge"
47
- rule-five:
48
- matchers:
49
- foo.bar: [true]
50
- baz: [false]
51
- output:
52
- type: "alerts"
53
- series: "other-series"
54
- dimensions: []
55
- stat_type: "gauge"
56
- `;
57
- const expected = [
58
- new router.Rule(
59
- "rule-one",
60
- { title: ["authorize-app"] },
61
- {
62
- type: "notifications",
63
- channel: "%{foo.bar}",
64
- icon: ":rocket:",
65
- message: "authorized %{foo.bar} in Hogwarts",
66
- user: "@fishman",
67
- },
68
- ),
69
- new router.Rule(
70
- "rule-two",
71
- { "foo.bar": ["multiple", "matches"], baz: ["whatever"] },
72
- {
73
- type: "alerts",
74
- series: "other-series",
75
- dimensions: ["baz"],
76
- stat_type: "gauge",
77
- value_field: "value",
78
- },
79
- ),
80
- new router.Rule(
81
- "rule-three",
82
- { "foo.bar": ["multiple", "matches"], baz: ["whatever"] },
83
- {
84
- type: "alerts",
85
- series: "other-series",
86
- dimensions: ["baz"],
87
- stat_type: "gauge",
88
- value_field: "hello",
89
- },
90
- ),
91
- new router.Rule(
92
- "rule-four",
93
- { "foo.bar": ["multiple", "matches"], baz: ["whatever"] },
94
- {
95
- type: "alerts",
96
- series: "other-series",
97
- dimensions: [],
98
- stat_type: "gauge",
99
- value_field: "value",
100
- },
101
- ),
102
- new router.Rule(
103
- "rule-five",
104
- { "foo.bar": [true], baz: [false] },
105
- {
106
- type: "alerts",
107
- series: "other-series",
108
- dimensions: [],
109
- stat_type: "gauge",
110
- value_field: "value",
111
- },
112
- ),
113
- ];
114
- const actual = new router.Router();
115
- actual._loadConfigString(conf);
116
- assert.deepEqual(actual.rules, expected);
117
- });
118
-
119
- it("rejects specials in matchers", () => {
120
- const confTmpl = (v) => `
121
- routes:
122
- non-string-values:
123
- matchers:
124
- no-numbers: [${v}]
125
- output:
126
- type: "analytics"
127
- series: "fun"
128
- `;
129
-
130
- // Make sure the template works
131
- const conf = confTmpl('"valid"');
132
- const actual = new router.Router();
133
- assert.doesNotThrow(() => actual._loadConfigString(conf));
134
-
135
- for (const invalidVal of ["5", "[]", "{}"]) {
136
- const invalidConf = confTmpl(invalidVal);
137
- assert.throws(() => actual._loadConfigString(invalidConf));
138
- }
139
- assert.throws(() => actual._loadConfigString(confTmpl('""')));
140
- return;
141
- });
142
-
143
- it("rejects duplicates in matchers", () => {
144
- const confTmpl = (v) => `
145
- routes:
146
- sloppy:
147
- matchers:
148
- title: [${v}]
149
- output:
150
- type: "analytics"
151
- series: "fun"
152
- `;
153
-
154
- const actual = new router.Router();
155
- const validConf = confTmpl('"non-repeated", "name"');
156
- assert.doesNotThrow(() => actual._loadConfigString(validConf));
157
-
158
- const invalidConf = confTmpl('"repeated", "repeated", "name"');
159
- assert.throws(() => actual._loadConfigString(invalidConf));
160
- });
161
-
162
- it("requires correct types in outputs", () => {
163
- const confTmpl = (series, dimensions) => `
164
- routes:
165
- wrong:
166
- matchers:
167
- title: ["test"]
168
- output:
169
- type: "alerts"
170
- series: ${series}
171
- dimensions: ${dimensions}
172
- value_field: "hihi"
173
- stat_type: "gauge"
174
- `;
175
-
176
- const actual = new router.Router();
177
- const validConf = confTmpl('"my-series"', '["dim1", "dim2"]');
178
- assert.doesNotThrow(() => actual._loadConfigString(validConf));
179
-
180
- const invalidConf0 = confTmpl('["my-series"]', '["dim1", "dim2"]');
181
- assert.throws(() => actual._loadConfigString(invalidConf0));
182
-
183
- const invalidConf1 = confTmpl('"my-series"', '"dim1"');
184
- assert.throws(() => actual._loadConfigString(invalidConf1));
185
- });
186
-
187
- it("requires all keys in outputs", () => {
188
- const confTmpl = (v) => `
189
- routes:
190
- wrong:
191
- matchers:
192
- title: ["test"]
193
- output:
194
- type: "alerts"${v}
195
- dimensions: ["dim1", "dim2"]
196
- stat_type: "gauge"
197
- `;
198
-
199
- const actual = new router.Router();
200
- const validConf = confTmpl(`
201
- series: "whatever"`);
202
- assert.doesNotThrow(() => actual._loadConfigString(validConf));
203
-
204
- const invalidConf = confTmpl("");
205
- assert.throws(() => actual._loadConfigString(invalidConf));
206
- });
207
-
208
- it("doesn't allow extra keys", () => {
209
- const confTmpl = (v) => `
210
- routes:
211
- wrong:
212
- matchers:
213
- title: ["test"]
214
- output:
215
- type: "metrics"${v}
216
- dimensions: ["dim1", "dim2"]
217
- `;
218
-
219
- const actual = new router.Router();
220
- const validConf = confTmpl(`
221
- series: "whatever"`);
222
- assert.doesNotThrow(() => actual._loadConfigString(validConf));
223
-
224
- const invalidConf = confTmpl(`
225
- series: "whatever"
226
- something-else: "hi there"`);
227
- assert.throws(() => actual._loadConfigString(invalidConf));
228
- });
229
-
230
- it("errors on type-os", () => {
231
- const actual = new router.Router();
232
- let config;
233
-
234
- config = `
235
- route: # Should be routes (plural)
236
- string-values:
237
- matchers:
238
- errors: [ "type-o" ]
239
- output:
240
- type: "analytics"
241
- series: "fun"
242
- `;
243
- assert.throws(() => actual._loadConfigString(config));
244
-
245
- config = `
246
- routes:
247
- string-values:
248
- matcher: # Should be matchers (plural)
249
- errors: [ "type-o" ]
250
- output:
251
- type: "analytics"
252
- series: "fun"
253
- `;
254
- assert.throws(() => actual._loadConfigString(config));
255
-
256
- config = `
257
- routes:
258
- string-values:
259
- matchers:
260
- errors: [ "type-o" ]
261
- outputs: # Should be output (signular)
262
- type: "analytics"
263
- series: "fun"
264
- `;
265
- assert.throws(() => actual._loadConfigString(config));
266
-
267
- config = `
268
- routes:
269
- $invalid-string-values: # Invalid rule name
270
- matchers:
271
- errors: [ "type-o" ]
272
- output:
273
- type: "analytics"
274
- series: "fun"
275
- `;
276
- assert.throws(() => actual._loadConfigString(config));
277
-
278
- config = `
279
- routes:
280
- string-values:
281
- matchers:
282
- errors: [ "type-o" ]
283
- output:
284
- type: "analytic" # Should be analytics (plural)p
285
- series: "fun"
286
- `;
287
- assert.throws(() => actual._loadConfigString(config));
288
-
289
- config = `
290
- routes:
291
- string-values:
292
- matchers:
293
- errors: [ "*", "type-o" ] # A wildcard cannot exist with other matchers
294
- output:
295
- type: "analytics"
296
- series: "fun"
297
- `;
298
- assert.throws(() => actual._loadConfigString(config));
299
- });
300
- });
301
-
302
- describe("route", () => {
303
- it("matches one or more rule and returns appropriate outputs", () => {
304
- const r = new router.Router([
305
- new router.Rule(
306
- "rule-one",
307
- { title: ["hello", "hi"], foo: ["bar", "baz"] },
308
- { channel: "#-%{foo}-", dimensions: ["-%{foo}-"] },
309
- ),
310
- new router.Rule("rule-two", { "bing.bong": ["buzz"] }, { series: "x" }),
311
- ]);
312
-
313
- const msg0 = {
314
- title: "hi",
315
- foo: "bar",
316
- };
317
- const expected0 = [
318
- {
319
- rule: "rule-one",
320
- channel: "#-bar-",
321
- dimensions: ["-bar-"],
322
- },
323
- ];
324
- const actual0 = r.route(msg0).routes;
325
- assert.deepEqual(expected0, actual0);
326
-
327
- const msg1 = {
328
- title: "hi",
329
- bing: {
330
- bong: "buzz",
331
- },
332
- };
333
- const expected1 = [
334
- {
335
- rule: "rule-two",
336
- series: "x",
337
- },
338
- ];
339
- const actual1 = r.route(msg1).routes;
340
- assert.deepEqual(expected1, actual1);
341
-
342
- const msg2 = {
343
- title: "hello",
344
- foo: "baz",
345
- bing: {
346
- bong: "buzz",
347
- },
348
- };
349
- const expected2 = [
350
- {
351
- rule: "rule-one",
352
- channel: "#-baz-",
353
- dimensions: ["-baz-"],
354
- },
355
- {
356
- rule: "rule-two",
357
- series: "x",
358
- },
359
- ];
360
- const actual2 = r.route(msg2).routes;
361
- assert.deepEqual(expected2, actual2);
362
- });
363
- });
364
- });
365
-
366
- describe("router.Rule", () => {
367
- describe("matches", () => {
368
- it("works on simple cases", () => {
369
- const r = new router.Rule("test-rule", { title: ["hello", "hi"], foo: ["bar"] }, {});
370
- assert(
371
- r.matches({
372
- title: "hello",
373
- foo: "bar",
374
- }),
375
- );
376
- assert(
377
- r.matches({
378
- title: "hi",
379
- foo: "bar",
380
- }),
381
- );
382
- assert(
383
- !r.matches({
384
- title: "hi",
385
- foo: "fighters",
386
- }),
387
- );
388
- assert(
389
- !r.matches({
390
- title: "howdy",
391
- foo: "bar",
392
- }),
393
- );
394
- assert(
395
- !r.matches({
396
- "missing-stuff": "indeed",
397
- }),
398
- );
399
- });
400
-
401
- it("works on nested messages", () => {
402
- const r = new router.Rule("test-rule", { "foo.bar": ["hello", "hi"] }, {});
403
- assert(
404
- r.matches({
405
- title: "greeting",
406
- foo: {
407
- bar: "hello",
408
- },
409
- }),
410
- );
411
- assert(
412
- r.matches({
413
- title: "greeting",
414
- foo: {
415
- bar: "hi",
416
- },
417
- }),
418
- );
419
- assert(
420
- !r.matches({
421
- title: "greeting",
422
- foo: {
423
- bar: "howdy",
424
- },
425
- }),
426
- );
427
- assert(
428
- !r.matches({
429
- title: "greeting",
430
- foo: {
431
- baz: "howdy",
432
- },
433
- }),
434
- );
435
- assert(
436
- !r.matches({
437
- title: "greeting",
438
- boo: {
439
- bar: "howdy",
440
- },
441
- }),
442
- );
443
- assert(
444
- !r.matches({
445
- title: "greeting",
446
- foo: "hi",
447
- }),
448
- );
449
- });
450
- it("wild card matching", () => {
451
- const r = new router.Rule("test-rule", { any: ["*"] }, {});
452
- assert(
453
- r.matches({
454
- any: false,
455
- }),
456
- );
457
- assert(
458
- r.matches({
459
- any: 5,
460
- }),
461
- );
462
- assert(
463
- r.matches({
464
- any: "hello",
465
- }),
466
- );
467
- assert(
468
- r.matches({
469
- any: {
470
- bar: "hi",
471
- },
472
- }),
473
- );
474
- assert(
475
- !r.matches({
476
- any: "",
477
- }),
478
- );
479
- assert(
480
- !r.matches({
481
- any: null,
482
- }),
483
- );
484
- assert(
485
- !r.matches({
486
- any: undefined,
487
- }),
488
- );
489
- assert(
490
- !r.matches({
491
- title: "greeting",
492
- foo: {
493
- bar: "howdy",
494
- },
495
- }),
496
- );
497
- });
498
- it("bool matching", () => {
499
- const r = new router.Rule("test-rule", { bull: [true] }, {});
500
- assert(
501
- r.matches({
502
- bull: true,
503
- }),
504
- );
505
- assert(
506
- r.matches({
507
- any: false,
508
- bull: true,
509
- }),
510
- );
511
- assert(
512
- !r.matches({
513
- bull: false,
514
- }),
515
- );
516
- assert(
517
- !r.matches({
518
- bull: "false",
519
- }),
520
- );
521
- assert(
522
- !r.matches({
523
- title: "greeting",
524
- foo: {
525
- bar: "howdy",
526
- },
527
- }),
528
- );
529
- });
530
- });
531
-
532
- describe("outputFor", () => {
533
- it("substitutes kv entries", () => {
534
- const r = new router.Rule(
535
- "myrule",
536
- {},
537
- {
538
- channel: "#-%{foo}-",
539
- dimensions: ["-%{foo}-", "-%{bar.baz}-"],
540
- },
541
- );
542
- const msg = {
543
- title: "greeting",
544
- foo: "partner",
545
- bar: {
546
- baz: "nest egg",
547
- },
548
- };
549
- const expected = {
550
- rule: "myrule",
551
- channel: "#-partner-",
552
- dimensions: ["-partner-", "-nest egg-"],
553
- };
554
- const actual = r.outputFor(msg);
555
- assert.deepEqual(expected, actual);
556
- });
557
- });
558
- });
File without changes
File without changes
package/test/tests.json DELETED
@@ -1,100 +0,0 @@
1
- {
2
- "version": "1.0.0",
3
- "format": [
4
- {
5
- "title": "allows empty data",
6
- "input": {
7
- "data" : {}
8
- },
9
- "output": "{}"
10
- },
11
- {
12
- "title": "maps one data field",
13
- "input": {
14
- "data" : {
15
- "context": "fake_context"
16
- }
17
- },
18
- "output": "{\"context\":\"fake_context\"}"
19
- },
20
- {
21
- "title": "maps multiple data fields",
22
- "input": {
23
- "data" : {
24
- "level": "WARNING",
25
- "context": "fake_context"
26
- }
27
- },
28
- "output": "{\"context\":\"fake_context\",\"level\":\"WARNING\"}"
29
- },
30
- {
31
- "title": "allows nested objects",
32
- "input": {
33
- "data" : {
34
- "baz": {
35
- "nested": "object"
36
- }
37
- }
38
-
39
- },
40
- "output": "{\"baz\":{\"nested\":\"object\"}}"
41
- },
42
- {
43
- "title": "allows spaces",
44
- "input": {
45
- "data" : {
46
- "spaces": " set c"
47
- }
48
- },
49
- "output": "{\"spaces\":\" set c\"}"
50
- },
51
- {
52
- "title": "allows single-quote",
53
- "input": {
54
- "data" : {
55
- "singlequote": "'"
56
- }
57
- },
58
- "output": "{\"singlequote\":\"'\"}"
59
- },
60
- {
61
- "title": "allows double-quote",
62
- "input": {
63
- "data" : {
64
- "doublequote": "\""
65
- }
66
- },
67
- "output": "{\"doublequote\":\"\\\"\"}"
68
- }
69
- ],
70
- "formatLog": [
71
- {
72
- "title": "outputs reserved fields",
73
- "input": {
74
- "source": "SOURCE",
75
- "level": "error",
76
- "title": "BAD_THINGS_HAPPENING",
77
- "data": {}
78
- },
79
- "output": "{\"source\":\"SOURCE\",\"level\":\"error\",\"title\":\"BAD_THINGS_HAPPENING\"}"
80
- },
81
- {
82
- "title": "outputs reserved fields and sorted data",
83
- "input": {
84
- "source": "SOURCE",
85
- "level": "error",
86
- "title": "BAD_THINGS_HAPPENING",
87
- "data": {
88
- "foo": "bar",
89
- "baz": "boo"
90
- }
91
- },
92
- "output": "{\"source\":\"SOURCE\",\"level\":\"error\",\"title\":\"BAD_THINGS_HAPPENING\",\"baz\":\"boo\",\"foo\":\"bar\"}"
93
- },
94
- {
95
- "title": "outputs reserved fields, even if undefined",
96
- "input": {},
97
- "output": "{\"source\":\"\",\"level\":\"\",\"title\":\"\"}"
98
- }
99
- ]
100
- }
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "module": "commonjs",
4
- "target": "es5",
5
- "noImplicitAny": false
6
- },
7
- "exclude": [
8
- "node_modules"
9
- ]
10
- }