kayvee 3.18.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 (58) 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/{build/lib → dist}/kayvee.js +17 -30
  8. package/dist/logger/logger.d.ts +49 -0
  9. package/dist/logger/logger.d.ts.map +1 -0
  10. package/{build/lib → dist}/logger/logger.js +91 -83
  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/{build/lib → dist}/router/index.js +33 -45
  18. package/package.json +63 -27
  19. package/.circleci/config.yml +0 -25
  20. package/.eslintrc.js +0 -124
  21. package/.github/workflows/notify-ci-status.yml +0 -20
  22. package/.nvmrc +0 -1
  23. package/.prettierrc.json +0 -1
  24. package/Makefile +0 -55
  25. package/benchmarks/data/.keep +0 -1
  26. package/benchmarks/data/corpus-basic.json +0 -22
  27. package/benchmarks/data/corpus-pathological.json +0 -22
  28. package/benchmarks/data/corpus-realistic.json +0 -22
  29. package/benchmarks/data/kvconfig-basic.yml +0 -7
  30. package/benchmarks/data/kvconfig-pathological.yml +0 -222
  31. package/benchmarks/data/kvconfig-realistic.yml +0 -39
  32. package/benchmarks/routing.js +0 -116
  33. package/build/lib/logger/helpers.js +0 -0
  34. package/build/lib/middleware.js +0 -274
  35. package/build/package.json +0 -53
  36. package/build/test/context_logger.js +0 -69
  37. package/build/test/kayvee.js +0 -36
  38. package/build/test/logger_test.js +0 -345
  39. package/build/test/middleware.js +0 -556
  40. package/build/test/router.js +0 -451
  41. package/index.js +0 -7
  42. package/lib/kayvee.ts +0 -73
  43. package/lib/logger/helpers.ts +0 -0
  44. package/lib/logger/logger.ts +0 -312
  45. package/lib/middleware.ts +0 -317
  46. package/lib/router/index.ts +0 -234
  47. package/lib/router/schema_definitions.json +0 -158
  48. package/test/context_logger.ts +0 -76
  49. package/test/kayvee.ts +0 -50
  50. package/test/kvconfig.yml +0 -14
  51. package/test/logger_test.ts +0 -378
  52. package/test/middleware.ts +0 -632
  53. package/test/router.ts +0 -558
  54. package/test/static/empty.css +0 -0
  55. package/test/static/js/empty.js +0 -0
  56. package/test/tests.json +0 -100
  57. package/tsconfig.json +0 -10
  58. /package/{build/lib → dist}/router/schema_definitions.json +0 -0
@@ -1,7 +1,45 @@
1
- var _ = require("underscore");
2
- var kv = require("../kayvee");
3
- var router = require("../router");
4
- var LEVELS = {
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Logger = void 0;
37
+ exports.setGlobalRouting = setGlobalRouting;
38
+ exports.getGlobalRouter = getGlobalRouter;
39
+ exports.mockRouting = mockRouting;
40
+ const kv = __importStar(require("../kayvee"));
41
+ const router_1 = require("../router");
42
+ const LEVELS = {
5
43
  Trace: "trace",
6
44
  Debug: "debug",
7
45
  Info: "info",
@@ -9,7 +47,7 @@ var LEVELS = {
9
47
  Error: "error",
10
48
  Critical: "critical",
11
49
  };
12
- var LOG_LEVEL_ENUM = {
50
+ const LOG_LEVEL_ENUM = {
13
51
  trace: 0,
14
52
  debug: 1,
15
53
  info: 2,
@@ -17,51 +55,51 @@ var LOG_LEVEL_ENUM = {
17
55
  error: 4,
18
56
  critical: 5,
19
57
  };
20
- const assign = Object.assign || _.assign; // Use the faster Object.assign if possible
21
58
  let globalRouter;
22
59
  function setGlobalRouting(filename) {
23
- globalRouter = new router.Router();
60
+ globalRouter = new router_1.Router();
24
61
  globalRouter.loadConfig(filename);
25
62
  }
26
63
  function getGlobalRouter() {
27
64
  return globalRouter;
28
65
  }
29
- // This is a port from kayvee-go/logger/logger.go
30
66
  class Logger {
67
+ static Trace = LEVELS.Trace;
68
+ static Debug = LEVELS.Debug;
69
+ static Info = LEVELS.Info;
70
+ static Warning = LEVELS.Warning;
71
+ static Error = LEVELS.Error;
72
+ static Critical = LEVELS.Critical;
73
+ static LEVELS = ["trace", "debug", "info", "warn", "error", "critical"];
74
+ static METRICS = ["counter", "gauge"];
75
+ formatter;
76
+ logLvl;
77
+ globals;
78
+ logWriter;
79
+ logRouter;
80
+ asyncLocalStorage;
31
81
  constructor(source, logLvl = process.env.KAYVEE_LOG_LEVEL, formatter = kv.format, output = console.error) {
32
- this.formatter = null;
33
- this.logLvl = null;
34
- this.globals = null;
35
- this.logWriter = null;
36
- this.logRouter = null;
37
- this.asyncLocalStorage = null;
38
82
  this.formatter = formatter;
39
83
  this.logLvl = this._validateLogLvl(logLvl);
40
84
  this.globals = {};
41
85
  this.globals.source = source;
42
86
  this.logWriter = output;
87
+ this.logRouter = null;
43
88
  this.asyncLocalStorage = null;
44
- if (process.env._TEAM_OWNER) {
89
+ if (process.env._TEAM_OWNER)
45
90
  this.globals.team = process.env._TEAM_OWNER;
46
- }
47
- if (process.env._DEPLOY_ENV) {
91
+ if (process.env._DEPLOY_ENV)
48
92
  this.globals.deploy_env = process.env._DEPLOY_ENV;
49
- }
50
- if (process.env._EXECUTION_NAME) {
93
+ if (process.env._EXECUTION_NAME)
51
94
  this.globals.wf_id = process.env._EXECUTION_NAME;
52
- }
53
- if (process.env._POD_ID) {
95
+ if (process.env._POD_ID)
54
96
  this.globals["pod-id"] = process.env._POD_ID;
55
- }
56
- if (process.env._POD_SHORTNAME) {
97
+ if (process.env._POD_SHORTNAME)
57
98
  this.globals["pod-shortname"] = process.env._POD_SHORTNAME;
58
- }
59
- if (process.env._POD_REGION) {
99
+ if (process.env._POD_REGION)
60
100
  this.globals["pod-region"] = process.env._POD_REGION;
61
- }
62
- if (process.env._POD_ACCOUNT) {
101
+ if (process.env._POD_ACCOUNT)
63
102
  this.globals["pod-account"] = process.env._POD_ACCOUNT;
64
- }
65
103
  }
66
104
  setAsyncLocalStorage(asyncLocalStorage) {
67
105
  this.asyncLocalStorage = asyncLocalStorage;
@@ -77,16 +115,11 @@ class Logger {
77
115
  return this.logWriter;
78
116
  }
79
117
  _validateLogLvl(logLvl) {
80
- if (logLvl == null) {
118
+ if (logLvl == null)
81
119
  return LEVELS.Debug;
82
- }
83
- for (var key in LEVELS) {
84
- if (Object.prototype.hasOwnProperty.call(LEVELS, key)) {
85
- var value = LEVELS[key];
86
- if (logLvl.toLowerCase() === value) {
87
- return value;
88
- }
89
- }
120
+ for (const value of Object.values(LEVELS)) {
121
+ if (logLvl.toLowerCase() === value)
122
+ return value;
90
123
  }
91
124
  return LEVELS.Debug;
92
125
  }
@@ -127,61 +160,37 @@ class Logger {
127
160
  this.gaugeD(title, value, {});
128
161
  }
129
162
  traceD(title, data) {
130
- this._logWithLevel(LEVELS.Trace, {
131
- title,
132
- }, data);
163
+ this._logWithLevel(LEVELS.Trace, { title }, data);
133
164
  }
134
165
  debugD(title, data) {
135
- this._logWithLevel(LEVELS.Debug, {
136
- title,
137
- }, data);
166
+ this._logWithLevel(LEVELS.Debug, { title }, data);
138
167
  }
139
168
  infoD(title, data) {
140
- this._logWithLevel(LEVELS.Info, {
141
- title,
142
- }, data);
169
+ this._logWithLevel(LEVELS.Info, { title }, data);
143
170
  }
144
171
  warnD(title, data) {
145
- this._logWithLevel(LEVELS.Warning, {
146
- title,
147
- }, data);
172
+ this._logWithLevel(LEVELS.Warning, { title }, data);
148
173
  }
149
174
  errorD(title, data) {
150
- this._logWithLevel(LEVELS.Error, {
151
- title,
152
- }, data);
175
+ this._logWithLevel(LEVELS.Error, { title }, data);
153
176
  }
154
177
  criticalD(title, data) {
155
- this._logWithLevel(LEVELS.Critical, {
156
- title,
157
- }, data);
178
+ this._logWithLevel(LEVELS.Critical, { title }, data);
158
179
  }
159
180
  counterD(title, value, data) {
160
- this._logWithLevel(LEVELS.Info, {
161
- title,
162
- value,
163
- type: "counter",
164
- }, data);
181
+ this._logWithLevel(LEVELS.Info, { title, value, type: "counter" }, data);
165
182
  }
166
183
  gaugeD(title, value, data) {
167
- this._logWithLevel(LEVELS.Info, {
168
- title,
169
- value,
170
- type: "gauge",
171
- }, data);
184
+ this._logWithLevel(LEVELS.Info, { title, value, type: "gauge" }, data);
172
185
  }
173
186
  _logWithLevel(logLvl, metadata, userdata) {
174
- if (LOG_LEVEL_ENUM[logLvl] < LOG_LEVEL_ENUM[this.logLvl]) {
187
+ if (LOG_LEVEL_ENUM[logLvl] < LOG_LEVEL_ENUM[this.logLvl])
175
188
  return;
176
- }
177
- // I'm not clever enough to want to do these in one line without extra vars.
178
- // We're on a REALLY old version of TS compiling to ES5. So I don't get a lot of the fancy tools
179
- // like ?. and ??.
180
189
  const store = this.asyncLocalStorage && this.asyncLocalStorage.getStore();
181
190
  const storeData = store || { get: () => ({}) };
182
191
  const contextData = storeData.get("context") ? storeData.get("context") : {};
183
192
  const plainContextData = contextData instanceof Map ? Object.fromEntries(contextData) : contextData;
184
- var data = assign({ level: logLvl }, this.globals, metadata, plainContextData, userdata);
193
+ const data = Object.assign({ level: logLvl }, this.globals, metadata, plainContextData, userdata);
185
194
  if (this.logRouter) {
186
195
  data._kvmeta = this.logRouter.route(data);
187
196
  }
@@ -191,10 +200,8 @@ class Logger {
191
200
  this.logWriter(this.formatter(data));
192
201
  }
193
202
  }
194
- module.exports = Logger;
195
- module.exports.setGlobalRouting = setGlobalRouting;
196
- module.exports.getGlobalRouter = getGlobalRouter;
197
- module.exports.mockRouting = (cb) => {
203
+ exports.Logger = Logger;
204
+ function mockRouting(cb) {
198
205
  const _logWithLevel = Logger.prototype._logWithLevel;
199
206
  if (_logWithLevel.isMocked) {
200
207
  throw Error("Nested kv.mockRouting calls are not supported");
@@ -205,9 +212,8 @@ module.exports.mockRouting = (cb) => {
205
212
  const logWriter = this.logWriter;
206
213
  this.formatter = (msg) => msg;
207
214
  this.logWriter = (msg) => {
208
- if (!msg._kvmeta) {
215
+ if (!msg._kvmeta)
209
216
  return;
210
- }
211
217
  msg._kvmeta.routes.forEach((route) => {
212
218
  ruleMatches[route.rule] = (ruleMatches[route.rule] || []).concat(route);
213
219
  });
@@ -216,14 +222,16 @@ module.exports.mockRouting = (cb) => {
216
222
  this.formatter = formatter;
217
223
  this.logWriter = logWriter;
218
224
  };
219
- const stfuTypeScript = Logger.prototype._logWithLevel;
220
- stfuTypeScript.isMocked = true;
225
+ Logger.prototype._logWithLevel.isMocked = true;
221
226
  const done = () => {
222
227
  Logger.prototype._logWithLevel = _logWithLevel;
223
228
  return ruleMatches;
224
229
  };
225
230
  cb(done);
226
- };
227
- _.extend(module.exports, LEVELS);
228
- module.exports.LEVELS = ["trace", "debug", "info", "warn", "error", "critical"];
229
- module.exports.METRICS = ["counter", "gauge"];
231
+ }
232
+ // Expose module-level functions as static members on Logger for backwards compatibility.
233
+ // Tests and consumers that do `const { Logger: KV } = require("kayvee/logger")`
234
+ // can call `KV.setGlobalRouting(...)` and `KV.mockRouting(...)`.
235
+ Logger.setGlobalRouting = setGlobalRouting;
236
+ Logger.getGlobalRouter = getGlobalRouter;
237
+ Logger.mockRouting = mockRouting;
@@ -0,0 +1,23 @@
1
+ import type { Request, Response, NextFunction } from "express";
2
+ type Handler = (req: Request, res?: Response) => Record<string, unknown>;
3
+ export declare class ContextLogger {
4
+ logger: any;
5
+ handlers: Handler[];
6
+ req: Request;
7
+ res?: Response;
8
+ constructor(logger: any, handlers: Handler[], req: Request, res?: Response);
9
+ _contextualData(data: Record<string, unknown>): Record<string, unknown>;
10
+ }
11
+ export interface MiddlewareOptions {
12
+ source: string;
13
+ headers?: string[];
14
+ handlers?: Handler[];
15
+ base_handlers?: Handler[];
16
+ ignore_dir?: {
17
+ directory: string;
18
+ path: string;
19
+ };
20
+ }
21
+ export declare function middleware(clever_options: MiddlewareOptions, secondOpt?: any): (req: Request, res: Response, next: NextFunction) => void;
22
+ export {};
23
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../lib/middleware.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyE/D,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAoCzE,qBAAa,aAAa;IACxB,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,QAAQ,CAAC;gBAEH,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ;IAO1E,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGxE;AA2BD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AA0CD,wBAAgB,UAAU,CACxB,cAAc,EAAE,iBAAiB,EACjC,SAAS,CAAC,EAAE,GAAG,GACd,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAkC3D"}
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ContextLogger = void 0;
7
+ exports.middleware = middleware;
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const node_url_1 = require("node:url");
11
+ const morgan_1 = __importDefault(require("morgan"));
12
+ const qs_1 = __importDefault(require("qs"));
13
+ const kayvee_1 = require("./kayvee");
14
+ const logger_1 = require("./logger/logger");
15
+ function walkDirSync(dir, files = []) {
16
+ const list = node_fs_1.default.readdirSync(dir);
17
+ list.forEach((file) => {
18
+ const f = node_path_1.default.join(dir, file);
19
+ if (node_fs_1.default.statSync(node_path_1.default.join(dir, file)).isDirectory()) {
20
+ walkDirSync(f, files);
21
+ }
22
+ else {
23
+ files.push(f);
24
+ }
25
+ });
26
+ return files.map((f) => node_path_1.default.relative(dir, f));
27
+ }
28
+ function skip_path(dir, base_path = "/") {
29
+ let files = walkDirSync(dir);
30
+ files = files.map((file) => node_path_1.default.join(base_path, file));
31
+ console.error(`KayveeMiddleware: Skipping successful requests for files in ${dir} at ${base_path}`);
32
+ return (req, res) => files.includes(req.path) && res.statusCode < 400;
33
+ }
34
+ function getBaseUrl(req) {
35
+ const url = req.originalUrl || req.url;
36
+ const parsed = (0, node_url_1.parse)(url, true);
37
+ return parsed.pathname ?? null;
38
+ }
39
+ function getQueryParams(req) {
40
+ const url = req.originalUrl || req.url;
41
+ const parsed = (0, node_url_1.parse)(url, true);
42
+ const parsedQueryString = qs_1.default.parse(parsed.search ?? "", {
43
+ allowPrototypes: false,
44
+ ignoreQueryPrefix: true,
45
+ });
46
+ return `?${qs_1.default.stringify(parsedQueryString)}`;
47
+ }
48
+ function getResponseSize(res) {
49
+ const headers = res.getHeaders ? res.getHeaders() : res._headers;
50
+ if (headers && headers["content-length"]) {
51
+ return Number(headers["content-length"]);
52
+ }
53
+ else if (res.data) {
54
+ return res.data.length;
55
+ }
56
+ return undefined;
57
+ }
58
+ function getResponseTimeNs(req, res) {
59
+ if (!req._startAt || !res._startAt) {
60
+ return undefined;
61
+ }
62
+ const ns = (res._startAt[0] - req._startAt[0]) * 1e9 +
63
+ (res._startAt[1] - req._startAt[1]);
64
+ return ns;
65
+ }
66
+ function getIp(req) {
67
+ const remoteAddress = req.connection ? req.connection.remoteAddress : undefined;
68
+ return req.ip || remoteAddress;
69
+ }
70
+ function getLogLevel(req, res) {
71
+ const statusCode = res.statusCode;
72
+ if (statusCode >= 499) {
73
+ return logger_1.Logger.Error;
74
+ }
75
+ return logger_1.Logger.Info;
76
+ }
77
+ const defaultHandlers = [
78
+ (req) => ({ method: req.method }),
79
+ (req) => ({ path: getBaseUrl(req) }),
80
+ (req) => ({ params: getQueryParams(req) }),
81
+ (req, res) => ({ "response-size": getResponseSize(res) }),
82
+ (req, res) => ({ "response-time": getResponseTimeNs(req, res) }),
83
+ (req, res) => ({ "status-code": res.statusCode }),
84
+ (req) => ({ ip: getIp(req) }),
85
+ () => ({ via: "kayvee-middleware" }),
86
+ (req, res) => ({ level: getLogLevel(req, res) }),
87
+ () => ({ title: "request-finished" }),
88
+ ];
89
+ const defaultContextHandlers = [];
90
+ function handlerData(handlers, req, res) {
91
+ const data = {};
92
+ handlers.forEach((h) => {
93
+ try {
94
+ const handler_data = h(req, res);
95
+ if (handler_data !== null &&
96
+ typeof handler_data === "object" &&
97
+ !Array.isArray(handler_data)) {
98
+ Object.assign(data, handler_data);
99
+ }
100
+ }
101
+ catch (e) {
102
+ // swallow invalid handler
103
+ }
104
+ });
105
+ return data;
106
+ }
107
+ class ContextLogger {
108
+ logger;
109
+ handlers;
110
+ req;
111
+ res;
112
+ constructor(logger, handlers, req, res) {
113
+ this.logger = logger;
114
+ this.handlers = handlers;
115
+ this.req = req;
116
+ this.res = res;
117
+ }
118
+ _contextualData(data) {
119
+ return Object.assign(handlerData(this.handlers, this.req, this.res), data);
120
+ }
121
+ }
122
+ exports.ContextLogger = ContextLogger;
123
+ for (const func of logger_1.Logger.LEVELS) {
124
+ ContextLogger.prototype[func] = function (title) {
125
+ this[`${func}D`](title, {});
126
+ };
127
+ ContextLogger.prototype[`${func}D`] = function (title, data) {
128
+ this.logger[`${func}D`](title, this._contextualData(data));
129
+ };
130
+ }
131
+ for (const func of logger_1.Logger.METRICS) {
132
+ ContextLogger.prototype[func] = function (title, value) {
133
+ this[`${func}D`](title, value, {});
134
+ };
135
+ ContextLogger.prototype[`${func}D`] = function (title, value, data) {
136
+ this.logger[`${func}D`](title, value, this._contextualData(data));
137
+ };
138
+ }
139
+ const formatLine = (options_arg) => {
140
+ const options = options_arg || {};
141
+ if (!options.source) {
142
+ throw Error("Missing required config for 'source' in Kayvee middleware 'options'");
143
+ }
144
+ const router = (0, logger_1.getGlobalRouter)();
145
+ return (_tokens, req, res) => {
146
+ const data = {};
147
+ const custom_headers = options.headers || [];
148
+ const header_data = {};
149
+ custom_headers.forEach((h) => {
150
+ const lc = h.toLowerCase();
151
+ header_data[lc] = req.headers[lc];
152
+ });
153
+ Object.assign(data, header_data);
154
+ const custom_handlers = options.handlers || [];
155
+ let base_handlers = options.base_handlers || defaultHandlers;
156
+ base_handlers = base_handlers.concat([() => ({ source: options.source })]);
157
+ const all_handlers = custom_handlers.concat(base_handlers);
158
+ Object.assign(data, handlerData(all_handlers, req, res));
159
+ if (router) {
160
+ data._kvmeta = router.route(data);
161
+ }
162
+ return (0, kayvee_1.format)(data);
163
+ };
164
+ };
165
+ const defaultContextLoggerOpts = {
166
+ enabled: true,
167
+ handlers: defaultContextHandlers,
168
+ };
169
+ function middleware(clever_options, secondOpt) {
170
+ if (process.env.NODE_ENV === "test") {
171
+ const morgan_options = secondOpt || { skip: null };
172
+ if (clever_options.ignore_dir) {
173
+ morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
174
+ }
175
+ return (0, morgan_1.default)(formatLine(clever_options), morgan_options);
176
+ }
177
+ if (!clever_options.source) {
178
+ throw new Error("Missing required config for 'source' in Kayvee middleware 'options'");
179
+ }
180
+ const context_logger_options = secondOpt || defaultContextLoggerOpts;
181
+ const logger = new logger_1.Logger(clever_options.source);
182
+ const morgan_options = {
183
+ stream: process.stderr,
184
+ skip: null,
185
+ };
186
+ if (clever_options.ignore_dir) {
187
+ morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
188
+ }
189
+ const morgan_logger = (0, morgan_1.default)(formatLine(clever_options), morgan_options);
190
+ return (req, res, next) => {
191
+ if (context_logger_options.enabled) {
192
+ req.log = new ContextLogger(logger, context_logger_options.handlers, req);
193
+ }
194
+ morgan_logger(req, res, next);
195
+ };
196
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "kayvee",
3
+ "description": "Write data to key=val pairs, for human and machine readability",
4
+ "version": "4.0.0",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./logger": {
14
+ "require": "./dist/logger/logger.js",
15
+ "import": "./dist/logger/logger.js",
16
+ "types": "./dist/logger/logger.d.ts"
17
+ },
18
+ "./middleware": {
19
+ "require": "./dist/middleware.js",
20
+ "import": "./dist/middleware.js",
21
+ "types": "./dist/middleware.d.ts"
22
+ },
23
+ "./router": {
24
+ "require": "./dist/router/index.js",
25
+ "import": "./dist/router/index.js",
26
+ "types": "./dist/router/index.d.ts"
27
+ }
28
+ },
29
+ "typesVersions": {
30
+ "*": {
31
+ "logger": ["dist/logger/logger.d.ts"],
32
+ "middleware": ["dist/middleware.d.ts"],
33
+ "router": ["dist/router/index.d.ts"]
34
+ }
35
+ },
36
+ "files": [
37
+ "dist/**/*",
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git://github.com/Clever/kayvee-js"
44
+ },
45
+ "dependencies": {
46
+ "js-yaml": "^4.1.0",
47
+ "jsonschema": "^1.5.0",
48
+ "morgan": "^1.10.0",
49
+ "qs": "^6.13.0"
50
+ },
51
+ "devDependencies": {
52
+ "@clever/prettier-config": "1.0.0",
53
+ "@types/express": "^4.17.23",
54
+ "@types/js-yaml": "^4.0.9",
55
+ "@types/jsonschema": "^1.1.1",
56
+ "@types/mocha": "^10.0.6",
57
+ "@types/morgan": "^1.9.10",
58
+ "@types/node": "^20.11.0",
59
+ "@types/qs": "^6.9.11",
60
+ "@typescript-eslint/eslint-plugin": "^6.19.0",
61
+ "@typescript-eslint/parser": "^6.19.0",
62
+ "benchmark": "^2.1.1",
63
+ "eslint": "^8.56.0",
64
+ "eslint-config-airbnb": "^19.0.4",
65
+ "eslint-config-prettier": "^9.1.0",
66
+ "eslint-formatter-summary": "^1.1.0",
67
+ "express": "^4.18.2",
68
+ "mocha": "^10.2.0",
69
+ "prettier": "^3.2.5",
70
+ "sinon": "^17.0.1",
71
+ "split": "^1.0.0",
72
+ "supertest": "^6.3.4",
73
+ "ts-node": "^10.9.2",
74
+ "typescript": "^5.3.0",
75
+ "underscore": "^1.8.3"
76
+ },
77
+ "scripts": {
78
+ "test": "make -Br test",
79
+ "prepublishOnly": "make build"
80
+ },
81
+ "author": "Clever <tech-notify@clever.com>",
82
+ "license": "BSD-2-Clause",
83
+ "bugs": {
84
+ "url": "https://github.com/Clever/kayvee-js/issues"
85
+ },
86
+ "publishConfig": {
87
+ "registry": "https://registry.npmjs.org"
88
+ }
89
+ }
@@ -0,0 +1,23 @@
1
+ export declare class Rule {
2
+ name: string;
3
+ matchers: Record<string, string[]>;
4
+ output: Record<string, unknown>;
5
+ constructor(name: string, matchers: Record<string, string[]>, output: Record<string, unknown>);
6
+ matches(msg: Record<string, unknown>): boolean;
7
+ outputFor(msg: Record<string, unknown>): Record<string, unknown>;
8
+ }
9
+ interface RouteResult {
10
+ team: string;
11
+ kv_version: string;
12
+ kv_language: string;
13
+ routes: Record<string, unknown>[];
14
+ }
15
+ export declare class Router {
16
+ rules: Rule[];
17
+ constructor(rules?: Rule[]);
18
+ loadConfig(filename: string): void;
19
+ _loadConfigString(configStr: string): void;
20
+ route(msg: Record<string, unknown>): RouteResult;
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/router/index.ts"],"names":[],"mappings":"AA2EA,qBAAa,IAAI;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEpB,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkC7F,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAS9C,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAsBjE;AA4CD,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACnC;AAED,qBAAa,MAAM;IACjB,KAAK,EAAE,IAAI,EAAE,CAAC;gBAEF,KAAK,CAAC,EAAE,IAAI,EAAE;IAI1B,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKlC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ1C,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW;CAgBjD"}