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
@@ -1,221 +0,0 @@
1
- var _ = require("underscore");
2
- var kv = require("../kayvee");
3
- var router = require("../router");
4
- var LEVELS = {
5
- Trace: "trace",
6
- Debug: "debug",
7
- Info: "info",
8
- Warning: "warning",
9
- Error: "error",
10
- Critical: "critical",
11
- };
12
- var LOG_LEVEL_ENUM = {
13
- trace: 0,
14
- debug: 1,
15
- info: 2,
16
- warning: 3,
17
- error: 4,
18
- critical: 5,
19
- };
20
- var assign = Object.assign || _.assign; // Use the faster Object.assign if possible
21
- var globalRouter;
22
- function setGlobalRouting(filename) {
23
- globalRouter = new router.Router();
24
- globalRouter.loadConfig(filename);
25
- }
26
- function getGlobalRouter() {
27
- return globalRouter;
28
- }
29
- // This is a port from kayvee-go/logger/logger.go
30
- var Logger = /** @class */ (function () {
31
- function Logger(source, logLvl, formatter, output) {
32
- if (logLvl === void 0) { logLvl = process.env.KAYVEE_LOG_LEVEL; }
33
- if (formatter === void 0) { formatter = kv.format; }
34
- if (output === void 0) { output = console.error; }
35
- this.formatter = null;
36
- this.logLvl = null;
37
- this.globals = null;
38
- this.logWriter = null;
39
- this.logRouter = null;
40
- this.formatter = formatter;
41
- this.logLvl = this._validateLogLvl(logLvl);
42
- this.globals = {};
43
- this.globals.source = source;
44
- this.logWriter = output;
45
- if (process.env._TEAM_OWNER) {
46
- this.globals.team = process.env._TEAM_OWNER;
47
- }
48
- if (process.env._DEPLOY_ENV) {
49
- this.globals.deploy_env = process.env._DEPLOY_ENV;
50
- }
51
- if (process.env._EXECUTION_NAME) {
52
- this.globals.wf_id = process.env._EXECUTION_NAME;
53
- }
54
- if (process.env._POD_ID) {
55
- this.globals["pod-id"] = process.env._POD_ID;
56
- }
57
- if (process.env._POD_SHORTNAME) {
58
- this.globals["pod-shortname"] = process.env._POD_SHORTNAME;
59
- }
60
- if (process.env._POD_REGION) {
61
- this.globals["pod-region"] = process.env._POD_REGION;
62
- }
63
- if (process.env._POD_ACCOUNT) {
64
- this.globals["pod-account"] = process.env._POD_ACCOUNT;
65
- }
66
- }
67
- Logger.prototype.setRouter = function (r) {
68
- this.logRouter = r;
69
- };
70
- Logger.prototype.setConfig = function (source, logLvl, formatter, output) {
71
- this.globals.source = source;
72
- this.logLvl = this._validateLogLvl(logLvl);
73
- this.formatter = formatter;
74
- this.logWriter = output;
75
- return this.logWriter;
76
- };
77
- Logger.prototype._validateLogLvl = function (logLvl) {
78
- if (logLvl == null) {
79
- return LEVELS.Debug;
80
- }
81
- for (var key in LEVELS) {
82
- if (Object.prototype.hasOwnProperty.call(LEVELS, key)) {
83
- var value = LEVELS[key];
84
- if (logLvl.toLowerCase() === value) {
85
- return value;
86
- }
87
- }
88
- }
89
- return LEVELS.Debug;
90
- };
91
- Logger.prototype.setLogLevel = function (logLvl) {
92
- this.logLvl = this._validateLogLvl(logLvl);
93
- return this.logLvl;
94
- };
95
- Logger.prototype.setFormatter = function (formatter) {
96
- this.formatter = formatter;
97
- return this.formatter;
98
- };
99
- Logger.prototype.setOutput = function (output) {
100
- this.logWriter = output;
101
- return this.logWriter;
102
- };
103
- Logger.prototype.trace = function (title) {
104
- this.traceD(title, {});
105
- };
106
- Logger.prototype.debug = function (title) {
107
- this.debugD(title, {});
108
- };
109
- Logger.prototype.info = function (title) {
110
- this.infoD(title, {});
111
- };
112
- Logger.prototype.warn = function (title) {
113
- this.warnD(title, {});
114
- };
115
- Logger.prototype.error = function (title) {
116
- this.errorD(title, {});
117
- };
118
- Logger.prototype.critical = function (title) {
119
- this.criticalD(title, {});
120
- };
121
- Logger.prototype.counter = function (title) {
122
- this.counterD(title, 1, {});
123
- };
124
- Logger.prototype.gauge = function (title, value) {
125
- this.gaugeD(title, value, {});
126
- };
127
- Logger.prototype.traceD = function (title, data) {
128
- this._logWithLevel(LEVELS.Trace, {
129
- title: title,
130
- }, data);
131
- };
132
- Logger.prototype.debugD = function (title, data) {
133
- this._logWithLevel(LEVELS.Debug, {
134
- title: title,
135
- }, data);
136
- };
137
- Logger.prototype.infoD = function (title, data) {
138
- this._logWithLevel(LEVELS.Info, {
139
- title: title,
140
- }, data);
141
- };
142
- Logger.prototype.warnD = function (title, data) {
143
- this._logWithLevel(LEVELS.Warning, {
144
- title: title,
145
- }, data);
146
- };
147
- Logger.prototype.errorD = function (title, data) {
148
- this._logWithLevel(LEVELS.Error, {
149
- title: title,
150
- }, data);
151
- };
152
- Logger.prototype.criticalD = function (title, data) {
153
- this._logWithLevel(LEVELS.Critical, {
154
- title: title,
155
- }, data);
156
- };
157
- Logger.prototype.counterD = function (title, value, data) {
158
- this._logWithLevel(LEVELS.Info, {
159
- title: title,
160
- value: value,
161
- type: "counter",
162
- }, data);
163
- };
164
- Logger.prototype.gaugeD = function (title, value, data) {
165
- this._logWithLevel(LEVELS.Info, {
166
- title: title,
167
- value: value,
168
- type: "gauge",
169
- }, data);
170
- };
171
- Logger.prototype._logWithLevel = function (logLvl, metadata, userdata) {
172
- if (LOG_LEVEL_ENUM[logLvl] < LOG_LEVEL_ENUM[this.logLvl]) {
173
- return;
174
- }
175
- var data = assign({ level: logLvl }, this.globals, metadata, userdata);
176
- if (this.logRouter) {
177
- data._kvmeta = this.logRouter.route(data);
178
- }
179
- else if (globalRouter) {
180
- data._kvmeta = globalRouter.route(data);
181
- }
182
- this.logWriter(this.formatter(data));
183
- };
184
- return Logger;
185
- }());
186
- module.exports = Logger;
187
- module.exports.setGlobalRouting = setGlobalRouting;
188
- module.exports.getGlobalRouter = getGlobalRouter;
189
- module.exports.mockRouting = function (cb) {
190
- var _logWithLevel = Logger.prototype._logWithLevel;
191
- if (_logWithLevel.isMocked) {
192
- throw Error("Nested kv.mockRouting calls are not supported");
193
- }
194
- var ruleMatches = {};
195
- Logger.prototype._logWithLevel = function (logLvl, metadata, userdata) {
196
- var formatter = this.formatter;
197
- var logWriter = this.logWriter;
198
- this.formatter = function (msg) { return msg; };
199
- this.logWriter = function (msg) {
200
- if (!msg._kvmeta) {
201
- return;
202
- }
203
- msg._kvmeta.routes.forEach(function (route) {
204
- ruleMatches[route.rule] = (ruleMatches[route.rule] || []).concat(route);
205
- });
206
- };
207
- _logWithLevel.call(this, logLvl, metadata, userdata);
208
- this.formatter = formatter;
209
- this.logWriter = logWriter;
210
- };
211
- var stfuTypeScript = Logger.prototype._logWithLevel;
212
- stfuTypeScript.isMocked = true;
213
- var done = function () {
214
- Logger.prototype._logWithLevel = _logWithLevel;
215
- return ruleMatches;
216
- };
217
- cb(done);
218
- };
219
- _.extend(module.exports, LEVELS);
220
- module.exports.LEVELS = ["trace", "debug", "info", "warn", "error", "critical"];
221
- module.exports.METRICS = ["counter", "gauge"];
@@ -1,302 +0,0 @@
1
- /**
2
- * Module dependencies.
3
- * @private
4
- */
5
- var __spreadArrays = (this && this.__spreadArrays) || function () {
6
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
7
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
8
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
9
- r[k] = a[j];
10
- return r;
11
- };
12
- var fs = require("fs");
13
- var path = require("path");
14
- var kayvee = require("../lib/kayvee");
15
- var KayveeLogger = require("../lib/logger/logger");
16
- var morgan = require("morgan");
17
- var _ = require("underscore");
18
- /**
19
- * all relative files path in a directory
20
- */
21
- function walkDirSync(dir, files) {
22
- if (files === void 0) { files = []; }
23
- var list = fs.readdirSync(dir);
24
- list.forEach(function (file) {
25
- var f = path.join(dir, file);
26
- if (fs.statSync(path.join(dir, file)).isDirectory()) {
27
- walkDirSync(f, files);
28
- }
29
- else {
30
- files.push(f);
31
- }
32
- });
33
- return files.map(function (f) { return path.relative(dir, f); });
34
- }
35
- /**
36
- * returns a middleware function that checks if path exists in dir.
37
- *
38
- * Files in the directory are prefixed by base_path and compared to
39
- * req.path
40
- */
41
- function skip_path(dir, base_path) {
42
- if (base_path === void 0) { base_path = "/"; }
43
- var files = walkDirSync(dir);
44
- files = files.map(function (file) { return path.join(base_path, file); });
45
- console.error("KayveeMiddleware: Skipping successful requests for files in " + dir + " at " + base_path);
46
- return function (req, res) { return _(files).contains(req.path) && res.statusCode < 400; };
47
- }
48
- /**
49
- * request path
50
- */
51
- function getBaseUrl(req) {
52
- var url = req.originalUrl || req.url;
53
- var parsed = require("url").parse(url, true);
54
- return parsed.pathname;
55
- }
56
- /**
57
- * request query params
58
- */
59
- function getQueryParams(req) {
60
- var url = req.originalUrl || req.url;
61
- var parsed = require("url").parse(url, true);
62
- var parsedQueryString = require("qs").parse(parsed.search, {
63
- allowPrototypes: false,
64
- ignoreQueryPrefix: true,
65
- });
66
- return "?" + require("qs").stringify(parsedQueryString);
67
- }
68
- /**
69
- * response size
70
- */
71
- function getResponseSize(res) {
72
- var result = undefined;
73
- var headers = res.headers || res._headers;
74
- if (headers && headers["content-length"]) {
75
- result = Number(headers["content-length"]);
76
- }
77
- else if (res.data) {
78
- result = res.data.length;
79
- }
80
- return result;
81
- }
82
- /**
83
- * response time in nanoseconds
84
- */
85
- function getResponseTimeNs(req, res) {
86
- if (!req._startAt || !res._startAt) {
87
- // missing request and/or response start time
88
- return undefined;
89
- }
90
- // calculate diff
91
- var ns = (res._startAt[0] - req._startAt[0]) * 1e9 + (res._startAt[1] - req._startAt[1]);
92
- return ns;
93
- }
94
- /**
95
- * IP address that sent the request.
96
- *
97
- * `req.ip` is defined in Express: http://expressjs.com/en/api.html#req.ip
98
- */
99
- function getIp(req) {
100
- var remoteAddress = req.connection ? req.connection.remoteAddress : undefined;
101
- return req.ip || remoteAddress;
102
- }
103
- /**
104
- * Log level
105
- */
106
- function getLogLevel(req, res) {
107
- var statusCode = res.statusCode;
108
- var result;
109
- if (statusCode >= 499) {
110
- result = KayveeLogger.Error;
111
- }
112
- else {
113
- result = KayveeLogger.Info;
114
- }
115
- return result;
116
- }
117
- /*
118
- * Default handlers
119
- */
120
- var defaultHandlers = [
121
- // Request method
122
- function (req) { return ({ method: req.method }); },
123
- // Path (URL without query params)
124
- function (req) { return ({ path: getBaseUrl(req) }); },
125
- // Query params
126
- function (req) { return ({ params: getQueryParams(req) }); },
127
- // Response size
128
- function (req, res) { return ({ "response-size": getResponseSize(res) }); },
129
- // Response time (ns)
130
- function (req, res) { return ({ "response-time": getResponseTimeNs(req, res) }); },
131
- // Status code
132
- function (req, res) { return ({ "status-code": res.statusCode }); },
133
- // Ip address
134
- function (req) { return ({ ip: getIp(req) }); },
135
- // Via -- what library/code produced this log?
136
- function () { return ({ via: "kayvee-middleware" }); },
137
- // Kayvee's reserved fields
138
- // Log level
139
- function (req, res) { return ({ level: getLogLevel(req, res) }); },
140
- // Source -- which app emitted this log?
141
- // -> Gets passed in among `options` during library initialization
142
- // Title
143
- function () { return ({ title: "request-finished" }); },
144
- ];
145
- var defaultContextHandlers = [];
146
- function handlerData(handlers) {
147
- var args = [];
148
- for (var _i = 1; _i < arguments.length; _i++) {
149
- args[_i - 1] = arguments[_i];
150
- }
151
- var data = {};
152
- handlers.forEach(function (h) {
153
- try {
154
- var handler_data = h.apply(void 0, args);
155
- _.extend(data, handler_data);
156
- }
157
- catch (e) {
158
- // ignore invalid handler
159
- }
160
- });
161
- return data;
162
- }
163
- var ContextLogger = /** @class */ (function () {
164
- function ContextLogger(logger, handlers) {
165
- var args = [];
166
- for (var _i = 2; _i < arguments.length; _i++) {
167
- args[_i - 2] = arguments[_i];
168
- }
169
- this.logger = null;
170
- this.handlers = [];
171
- this.args = [];
172
- this.logger = logger;
173
- this.handlers = handlers;
174
- this.args = args;
175
- }
176
- ContextLogger.prototype._contextualData = function (data) {
177
- return _.extend(handlerData.apply(void 0, __spreadArrays([this.handlers], this.args)), data);
178
- };
179
- return ContextLogger;
180
- }());
181
- var _loop_1 = function (func) {
182
- ContextLogger.prototype[func] = function (title) {
183
- this[func + "D"](title, {});
184
- };
185
- ContextLogger.prototype[func + "D"] = function (title, data) {
186
- this.logger[func + "D"](title, this._contextualData(data));
187
- };
188
- };
189
- for (var _i = 0, _a = KayveeLogger.LEVELS; _i < _a.length; _i++) {
190
- var func = _a[_i];
191
- _loop_1(func);
192
- }
193
- var _loop_2 = function (func) {
194
- ContextLogger.prototype[func] = function (title, value) {
195
- this[func + "D"](title, value, {});
196
- };
197
- ContextLogger.prototype[func + "D"] = function (title, value, data) {
198
- this.logger[func + "D"](title, value, this._contextualData(data));
199
- };
200
- };
201
- for (var _b = 0, _c = KayveeLogger.METRICS; _b < _c.length; _b++) {
202
- var func = _c[_b];
203
- _loop_2(func);
204
- }
205
- /*
206
- * User configuration is passed via an `options` object.
207
- * Results from configuration are prioritized such that (`base_handlers` > `handlers` > `headers`).
208
- *
209
- * // `headers` - logs these request headers, if they exist
210
- *
211
- * headers: e.g. ['X-Request-Id', 'Host']
212
- *
213
- * // `handlers` - an array of functions of that return dicts to be logged.
214
- *
215
- * handlers: e.g. [function(request, response) { return {"key":"val"}]
216
- *
217
- * // `base_handlers` - an array of functions of that return dicts to be logged.
218
- * // Barring exceptional circumstances, `base_handlers` should not be overriden by the user.
219
- * // `base_handlers` defaults to a core set of handlers to run... see `defaultHandlers`.
220
- * //
221
- * // Separating `base_handlers` from `handlers` is done to ensure that reserved keys
222
- * // don't accidentally get overriden by custom handlers. This can now only happen if
223
- * // the user explicitly overrides `base_handlers`.
224
- *
225
- * base_handlers: e.g. [function(request, response) { return {"key":"val"}]
226
- *
227
- */
228
- var formatLine = function (options_arg) {
229
- var options = options_arg || {};
230
- // `source` is the one required field
231
- if (!options.source) {
232
- throw Error("Missing required config for 'source' in Kayvee middleware 'options'");
233
- }
234
- var router = KayveeLogger.getGlobalRouter();
235
- return function (tokens, req, res) {
236
- // Build a dict of data to log
237
- var data = { _kvmeta: undefined }; // Adding _kvmeta here to make typescript compile happy
238
- // Add user-configured request headers
239
- var custom_headers = options.headers || [];
240
- var header_data = {};
241
- custom_headers.forEach(function (h) {
242
- // Header field names are case insensitive, so let's be consistent
243
- var lc = h.toLowerCase();
244
- header_data[lc] = req.headers[lc];
245
- });
246
- _.extend(data, header_data);
247
- // Run user-configured handlers; add custom data
248
- var custom_handlers = options.handlers || [];
249
- // Allow user to override `base_handlers`; provide sane default set of handlers
250
- var base_handlers = options.base_handlers || defaultHandlers;
251
- base_handlers = base_handlers.concat([function () { return ({ source: options.source }); }]);
252
- // Execute custom-handlers THEN base-handlers
253
- var all_handlers = custom_handlers.concat(base_handlers);
254
- _.extend(data, handlerData(all_handlers, req, res));
255
- if (router) {
256
- data._kvmeta = router.route(data);
257
- }
258
- return kayvee.format(data);
259
- };
260
- };
261
- var defaultContextLoggerOpts = {
262
- enabled: true,
263
- handlers: defaultContextHandlers,
264
- };
265
- /**
266
- * Module exports.
267
- * @public
268
- */
269
- if (process.env.NODE_ENV === "test") {
270
- module.exports = function (clever_options, morgan_options) {
271
- if (morgan_options === void 0) { morgan_options = { skip: null }; }
272
- if (clever_options.ignore_dir) {
273
- morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
274
- }
275
- return morgan(formatLine(clever_options), morgan_options);
276
- };
277
- module.exports.ContextLogger = ContextLogger;
278
- }
279
- else {
280
- module.exports = function (clever_options, context_logger_options) {
281
- if (context_logger_options === void 0) { context_logger_options = defaultContextLoggerOpts; }
282
- // `source` is the one required field
283
- if (!clever_options.source) {
284
- throw new Error("Missing required config for 'source' in Kayvee middleware 'options'");
285
- }
286
- var logger = new KayveeLogger(clever_options.source);
287
- var morgan_options = {
288
- stream: process.stderr,
289
- skip: null,
290
- };
291
- if (clever_options.ignore_dir) {
292
- morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
293
- }
294
- var morgan_logger = morgan(formatLine(clever_options), morgan_options);
295
- return function (req, res, next) {
296
- if (context_logger_options.enabled) {
297
- req.log = new ContextLogger(logger, context_logger_options.handlers, req);
298
- }
299
- morgan_logger(req, res, next);
300
- };
301
- };
302
- }