@gershy/lilac 0.0.3 → 0.0.4

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/cmp/cjs/main.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import '../sideEffects.js';
2
2
  import { PetalTerraform } from './petal/terraform/terraform.ts';
3
- import Logger from './util/logger.ts';
3
+ import Logger from '@gershy/logger';
4
4
  import { Fact } from '@gershy/disk';
5
5
  export type Context = {
6
6
  name: string;
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PetalTerraform = void 0;
7
7
  const clearing_1 = require("@gershy/clearing");
8
8
  const slashEscape_ts_1 = __importDefault(require("../../util/slashEscape.js"));
9
- const snakeCase_ts_1 = __importDefault(require("../../util/snakeCase.js"));
10
9
  const petal_ts_1 = __importDefault(require("../petal.js"));
10
+ const util_phrasing_1 = __importDefault(require("@gershy/util-phrasing"));
11
11
  var PetalTerraform;
12
12
  (function (PetalTerraform) {
13
13
  class Base extends petal_ts_1.default {
@@ -55,13 +55,13 @@ var PetalTerraform;
55
55
  throw Error('tf key of this form must correspond to object value')[mod]({ k, v });
56
56
  // Resolve to raw string?
57
57
  if (special && (0, clearing_1.isCls)(v, String))
58
- return [(0, snakeCase_ts_1.default)(pcs[0]), ' = ', this.terraformEncode(v[hasHead]('| ') ? v : `| ${v}`)];
58
+ return [(0, util_phrasing_1.default)(pcs[0], 'camel', 'snake'), ' = ', this.terraformEncode(v[hasHead]('| ') ? v : `| ${v}`)];
59
59
  // Resolve to nested block?
60
60
  if (special && (0, clearing_1.isCls)(v, Object))
61
- return [[(0, snakeCase_ts_1.default)(pcs[0]), ...pcs.slice(1)[map](pc => (0, snakeCase_ts_1.default)(pc))].join(' '), ' ', this.terraformEncode(v)];
61
+ return [[(0, util_phrasing_1.default)(pcs[0], 'camel', 'snake'), ...pcs.slice(1)[map](pc => (0, util_phrasing_1.default)(pc, 'camel', 'snake'))].join(' '), ' ', this.terraformEncode(v)];
62
62
  // Resolve anything else to typical property - use the key exactly as provided (to support,
63
63
  // e.g., aws format for keys in policies, any other specific format, etc.)
64
- return [(0, snakeCase_ts_1.default)(pcs[0]), ' = ', this.terraformEncode(v)];
64
+ return [(0, util_phrasing_1.default)(pcs[0], 'camel', 'snake'), ' = ', this.terraformEncode(v)];
65
65
  });
66
66
  const len = entryItems.length;
67
67
  if (len === 0)
@@ -82,9 +82,9 @@ var PetalTerraform;
82
82
  tfRef(props = []) {
83
83
  if (!(0, clearing_1.isCls)(props, Array))
84
84
  props = [props];
85
- const base = `${(0, snakeCase_ts_1.default)(this.getType())}.${(0, snakeCase_ts_1.default)(this.getHandle())}`;
85
+ const base = `${(0, util_phrasing_1.default)(this.getType(), 'camel', 'snake')}.${(0, util_phrasing_1.default)(this.getHandle(), 'camel', 'snake')}`;
86
86
  return props.length
87
- ? `${base}.${props[map](v => (0, snakeCase_ts_1.default)(v)).join('.')}`
87
+ ? `${base}.${props[map](v => (0, util_phrasing_1.default)(v, 'camel', 'snake')).join('.')}`
88
88
  : base;
89
89
  }
90
90
  tfRefp(props = []) {
@@ -130,7 +130,7 @@ var PetalTerraform;
130
130
  getHandle() { return this.handle; }
131
131
  getProps() { return this.props; }
132
132
  async getResultHeader() {
133
- return `resource "${(0, snakeCase_ts_1.default)(this.type)}" "${(0, snakeCase_ts_1.default)(this.handle)}"`;
133
+ return `resource "${(0, util_phrasing_1.default)(this.type, 'camel', 'snake')}" "${(0, util_phrasing_1.default)(this.handle, 'camel', 'snake')}"`;
134
134
  }
135
135
  }
136
136
  PetalTerraform.Resource = Resource;
@@ -145,7 +145,7 @@ var PetalTerraform;
145
145
  }
146
146
  getProps() { return this.props; }
147
147
  async getResultHeader() {
148
- return `provider "${(0, snakeCase_ts_1.default)(this.name)}"`;
148
+ return `provider "${(0, util_phrasing_1.default)(this.name, 'camel', 'snake')}"`;
149
149
  }
150
150
  }
151
151
  PetalTerraform.Provider = Provider;
@@ -164,7 +164,7 @@ var PetalTerraform;
164
164
  getHandle() { return this.handle; }
165
165
  getProps() { return this.props; }
166
166
  async getResultHeader() {
167
- return `data "${(0, snakeCase_ts_1.default)(this.type)}" "${(0, snakeCase_ts_1.default)(this.handle)}"`;
167
+ return `data "${(0, util_phrasing_1.default)(this.type, 'camel', 'snake')}" "${(0, util_phrasing_1.default)(this.handle, 'camel', 'snake')}"`;
168
168
  }
169
169
  tfRef(props = []) {
170
170
  return `data.${super.tfRef(props)}`;
@@ -5,12 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.regions = exports.capitalKeys = void 0;
7
7
  const clearing_1 = require("@gershy/clearing");
8
- const capitalize_ts_1 = __importDefault(require("./capitalize.js"));
8
+ const util_phrasing_1 = __importDefault(require("@gershy/util-phrasing"));
9
9
  const capitalKeys = (v) => {
10
10
  if ((0, clearing_1.isCls)(v, Array))
11
11
  return v[map](v => (0, exports.capitalKeys)(v));
12
12
  if ((0, clearing_1.isCls)(v, Object))
13
- return v[mapk]((val, key) => [(0, capitalize_ts_1.default)(key), (0, exports.capitalKeys)(val)]);
13
+ return v[mapk]((val, key) => [(0, util_phrasing_1.default)(key, 'camel', 'kamel'), (0, exports.capitalKeys)(val)]);
14
14
  return v;
15
15
  };
16
16
  exports.capitalKeys = capitalKeys;
package/cmp/mjs/main.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import '../sideEffects.js';
2
2
  import { PetalTerraform } from './petal/terraform/terraform.ts';
3
- import Logger from './util/logger.ts';
3
+ import Logger from '@gershy/logger';
4
4
  import { Fact } from '@gershy/disk';
5
5
  export type Context = {
6
6
  name: string;
@@ -1,7 +1,7 @@
1
1
  import { getClsName, isCls } from '@gershy/clearing';
2
2
  import slashEscape from "../../util/slashEscape.js";
3
- import snakeCase from "../../util/snakeCase.js";
4
3
  import Petal from "../petal.js";
4
+ import ph from '@gershy/util-phrasing';
5
5
  export var PetalTerraform;
6
6
  (function (PetalTerraform) {
7
7
  class Base extends Petal {
@@ -49,13 +49,13 @@ export var PetalTerraform;
49
49
  throw Error('tf key of this form must correspond to object value')[mod]({ k, v });
50
50
  // Resolve to raw string?
51
51
  if (special && isCls(v, String))
52
- return [snakeCase(pcs[0]), ' = ', this.terraformEncode(v[hasHead]('| ') ? v : `| ${v}`)];
52
+ return [ph(pcs[0], 'camel', 'snake'), ' = ', this.terraformEncode(v[hasHead]('| ') ? v : `| ${v}`)];
53
53
  // Resolve to nested block?
54
54
  if (special && isCls(v, Object))
55
- return [[snakeCase(pcs[0]), ...pcs.slice(1)[map](pc => snakeCase(pc))].join(' '), ' ', this.terraformEncode(v)];
55
+ return [[ph(pcs[0], 'camel', 'snake'), ...pcs.slice(1)[map](pc => ph(pc, 'camel', 'snake'))].join(' '), ' ', this.terraformEncode(v)];
56
56
  // Resolve anything else to typical property - use the key exactly as provided (to support,
57
57
  // e.g., aws format for keys in policies, any other specific format, etc.)
58
- return [snakeCase(pcs[0]), ' = ', this.terraformEncode(v)];
58
+ return [ph(pcs[0], 'camel', 'snake'), ' = ', this.terraformEncode(v)];
59
59
  });
60
60
  const len = entryItems.length;
61
61
  if (len === 0)
@@ -76,9 +76,9 @@ export var PetalTerraform;
76
76
  tfRef(props = []) {
77
77
  if (!isCls(props, Array))
78
78
  props = [props];
79
- const base = `${snakeCase(this.getType())}.${snakeCase(this.getHandle())}`;
79
+ const base = `${ph(this.getType(), 'camel', 'snake')}.${ph(this.getHandle(), 'camel', 'snake')}`;
80
80
  return props.length
81
- ? `${base}.${props[map](v => snakeCase(v)).join('.')}`
81
+ ? `${base}.${props[map](v => ph(v, 'camel', 'snake')).join('.')}`
82
82
  : base;
83
83
  }
84
84
  tfRefp(props = []) {
@@ -124,7 +124,7 @@ export var PetalTerraform;
124
124
  getHandle() { return this.handle; }
125
125
  getProps() { return this.props; }
126
126
  async getResultHeader() {
127
- return `resource "${snakeCase(this.type)}" "${snakeCase(this.handle)}"`;
127
+ return `resource "${ph(this.type, 'camel', 'snake')}" "${ph(this.handle, 'camel', 'snake')}"`;
128
128
  }
129
129
  }
130
130
  PetalTerraform.Resource = Resource;
@@ -139,7 +139,7 @@ export var PetalTerraform;
139
139
  }
140
140
  getProps() { return this.props; }
141
141
  async getResultHeader() {
142
- return `provider "${snakeCase(this.name)}"`;
142
+ return `provider "${ph(this.name, 'camel', 'snake')}"`;
143
143
  }
144
144
  }
145
145
  PetalTerraform.Provider = Provider;
@@ -158,7 +158,7 @@ export var PetalTerraform;
158
158
  getHandle() { return this.handle; }
159
159
  getProps() { return this.props; }
160
160
  async getResultHeader() {
161
- return `data "${snakeCase(this.type)}" "${snakeCase(this.handle)}"`;
161
+ return `data "${ph(this.type, 'camel', 'snake')}" "${ph(this.handle, 'camel', 'snake')}"`;
162
162
  }
163
163
  tfRef(props = []) {
164
164
  return `data.${super.tfRef(props)}`;
@@ -1,10 +1,10 @@
1
1
  import { isCls } from '@gershy/clearing';
2
- import capitalize from "./capitalize.js";
2
+ import ph from '@gershy/util-phrasing';
3
3
  export const capitalKeys = (v) => {
4
4
  if (isCls(v, Array))
5
5
  return v[map](v => capitalKeys(v));
6
6
  if (isCls(v, Object))
7
- return v[mapk]((val, key) => [capitalize(key), capitalKeys(val)]);
7
+ return v[mapk]((val, key) => [ph(key, 'camel', 'kamel'), capitalKeys(val)]);
8
8
  return v;
9
9
  };
10
10
  export const regions = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gershy/lilac",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Luscious infrastructure Living as Code - an opinionated approach to IAC",
5
5
  "keywords": [
6
6
  "lilac",
@@ -50,6 +50,8 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@gershy/disk": "^0.0.9",
53
- "@gershy/util-nodejs-proc": "^0.0.2"
53
+ "@gershy/logger": "^0.0.2",
54
+ "@gershy/util-nodejs-proc": "^0.0.5",
55
+ "@gershy/util-phrasing": "^0.0.2"
54
56
  }
55
57
  }
@@ -1,2 +0,0 @@
1
- declare const capitalize: (v: string | string[]) => string;
2
- export default capitalize;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const clearing_1 = require("@gershy/clearing");
4
- const capitalize = (v) => {
5
- // capitalize('hello') -> "Hello"
6
- // capitalize('heLLo') -> "HeLLo"
7
- // capitalize([ 'my', 'name', 'is', 'bOb' ]) -> "myNameIsBOb"
8
- if ((0, clearing_1.isCls)(v, String))
9
- return v[0][upper]() + v.slice(1);
10
- return [v[0], ...v.slice(1)[map](v => v[0][upper]() + v.slice(1))].join('');
11
- };
12
- exports.default = capitalize;
@@ -1,20 +0,0 @@
1
- type LoggerData = null | boolean | number | string | {
2
- [limn]: (...args: any) => LoggerData;
3
- } | LoggerData[] | {
4
- [k: string]: LoggerData;
5
- };
6
- export default class Logger {
7
- static dummy: Logger;
8
- private format;
9
- private domain;
10
- private ctx;
11
- private write;
12
- private opts;
13
- constructor(domain: string, ctx?: Obj<any>, opts?: typeof this.opts, write?: typeof this.write);
14
- getDomain(): string;
15
- getTraceId(term: string): string;
16
- log(data: LoggerData): void;
17
- kid(domain: string): Logger;
18
- scope<Fn extends (logger: Logger) => any>(domain: string, ctx: Obj<any>, fn: Fn): ReturnType<Fn>;
19
- }
20
- export {};
@@ -1,150 +0,0 @@
1
- "use strict";
2
- // TODO: @gershy/logger (or @gershy/watcher?)
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const clearing_1 = require("@gershy/clearing");
5
- const scrubbed = (val, opts = {}) => {
6
- const { isScrub = (k, _v) => k[0] === '!', doScrub = ((v) => `$scrub(${(0, clearing_1.getClsName)(v)})`), seen = new Map() } = opts ?? {};
7
- if (val === null)
8
- return val;
9
- if ((0, clearing_1.isCls)(val, Boolean))
10
- return val;
11
- if ((0, clearing_1.isCls)(val, Number))
12
- return val;
13
- if ((0, clearing_1.isCls)(val, String))
14
- return val;
15
- if (seen.has(val))
16
- return seen.get(val) ?? null;
17
- if ((0, clearing_1.isCls)(val, Array)) {
18
- const result = [];
19
- seen.set(val, result);
20
- for (const item of val)
21
- result.push(scrubbed(item, { isScrub, doScrub, seen }));
22
- return result;
23
- }
24
- else if ((0, clearing_1.isCls)(val, Object)) {
25
- // Consider using hashes to display scrubbed values? (Makes them correlatable!)
26
- const result = {};
27
- seen.set(val, result);
28
- for (const [k, v] of val)
29
- result[k] = isScrub(k, v) ? doScrub(v) : scrubbed(v, { isScrub, doScrub, seen });
30
- return result;
31
- }
32
- else if ((0, clearing_1.inCls)(val[limn], Function)) {
33
- return scrubbed(val[limn](), { isScrub, doScrub, seen });
34
- }
35
- else {
36
- // Consider processing for other types (sets, maps?)
37
- return val;
38
- }
39
- };
40
- class Logger {
41
- static dummy = {
42
- getTraceId() { return ''; },
43
- log() { },
44
- kid() { return Logger.dummy; },
45
- scope(...args) { return args.at(-1)(Logger.dummy); }
46
- };
47
- format(v /* should not have cycles */, seen = new Map()) {
48
- // Formats any value into json (so that it can be logged)
49
- if (v == null)
50
- return null;
51
- if ((0, clearing_1.isCls)(v, Boolean))
52
- return v;
53
- if ((0, clearing_1.isCls)(v, Number))
54
- return v;
55
- if ((0, clearing_1.isCls)(v, String))
56
- return v.length > this.opts.maxStrLen ? v.slice(0, this.opts.maxStrLen - 1) + '\u2026' : v;
57
- if (seen.has(v))
58
- return `<cyc> ${(0, clearing_1.getClsName)(v)}(...)`;
59
- if ((0, clearing_1.inCls)(v[limn], Function)) {
60
- const formatted = {};
61
- seen.set(v, formatted);
62
- Object.assign(formatted, this.format(v[limn](), seen));
63
- return formatted;
64
- }
65
- if ((0, clearing_1.isCls)(v, Array)) {
66
- const arr = [];
67
- seen.set(v, arr);
68
- for (const vv of v)
69
- arr.push(this.format(vv, seen));
70
- return arr;
71
- }
72
- if ((0, clearing_1.isCls)(v, Object)) {
73
- const obj = {};
74
- seen.set(v, obj);
75
- for (const k in v)
76
- obj[k] = this.format(v[k], seen);
77
- return obj;
78
- }
79
- return `${(0, clearing_1.getClsName)(v)}(...)`;
80
- }
81
- ;
82
- domain;
83
- ctx;
84
- write;
85
- opts;
86
- constructor(domain, ctx = {}, opts, write) {
87
- this.domain = domain;
88
- this.ctx = {
89
- ...ctx,
90
- $: this.domain,
91
- [this.domain.split('.').at(-1)]: Math.random().toString(36).slice(2, 12)[padTail](10, '0'),
92
- };
93
- this.opts = opts ?? { maxStrLen: 250 };
94
- // Note this default `this.write` function produces truncated values (sloppy outputting) in the
95
- // cli, but works perfectly for lambdas with json-style logging configured!
96
- this.write = write ?? ((val) => console.log(val));
97
- }
98
- getDomain() { return this.domain; }
99
- getTraceId(term) {
100
- const traceId = this.ctx[term];
101
- if (!traceId)
102
- throw Error('trace term invalid')[mod]({ term, ctx: this.ctx });
103
- return traceId;
104
- }
105
- log(data) {
106
- // Use-cases:
107
- // 1. logger.log('a basic string')
108
- // - The logged payload is converted to `{ msg: 'a basic string' }`
109
- // 2. logger.log({ msg: 'a basic string' })
110
- // - Logged as-is; equivalent to #1
111
- // 3. logger.log({ $$: 'note', msg: 'a basic string' })
112
- // - Same as #1 and #2, but logger domain has "note" appended to it
113
- // 4. logger.log({ $$: 'noteOnly' })
114
- // - Logged payload will be `{}`; only info is the tag - useful for infinitesimal moments in
115
- // the flamegraph!
116
- // 5. logger.log({ $$: 'context.noteOnly' })
117
- // - Valid way to extend domain with more than 1 component at once!
118
- let dmn = null;
119
- if (data && (0, clearing_1.isCls)(data?.$$, String))
120
- ({ $$: dmn, ...data } = data);
121
- const domain = dmn ? [this.domain, dmn].join('.') : this.domain;
122
- if (!(0, clearing_1.isCls)(data, Object))
123
- data = { msg: data };
124
- this.write({}[merge]({ $: this.ctx })[merge](scrubbed(this.format(data)))[merge]({ $: { $: domain } }));
125
- }
126
- kid(domain) {
127
- const d = [this.domain, domain].filter(Boolean).join('.');
128
- const logger = new Logger(d, this.ctx, this.opts, this.write);
129
- return logger;
130
- }
131
- scope(domain, ctx, fn) {
132
- const ms = Date.now();
133
- const logger = this.kid(domain);
134
- logger.log({ $$: 'launch', ...ctx });
135
- const accept = val => { logger.log({ $$: 'accept', ms: Date.now() - ms }); return val; };
136
- const glitch = err => { logger.log({ $$: err.log?.term ?? 'glitch', ms: Date.now() - ms, err }); throw err; }; // Always throws an error! Note allowing the consumer to override the logged term/domain offers a lot of flexibility!
137
- let v;
138
- try {
139
- v = fn(logger);
140
- }
141
- catch (err) {
142
- glitch(err);
143
- }
144
- return (0, clearing_1.isCls)(v, Promise)
145
- ? v.then(accept, glitch)
146
- : accept(v);
147
- }
148
- }
149
- exports.default = Logger;
150
- ;
@@ -1,2 +0,0 @@
1
- declare const _default: (val: string) => Lowercase<string>;
2
- export default _default;
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = (val) => val.replace(/([A-Z])/g, '_$1')[lower]();
@@ -1,2 +0,0 @@
1
- declare const capitalize: (v: string | string[]) => string;
2
- export default capitalize;
@@ -1,10 +0,0 @@
1
- import { isCls } from '@gershy/clearing';
2
- const capitalize = (v) => {
3
- // capitalize('hello') -> "Hello"
4
- // capitalize('heLLo') -> "HeLLo"
5
- // capitalize([ 'my', 'name', 'is', 'bOb' ]) -> "myNameIsBOb"
6
- if (isCls(v, String))
7
- return v[0][upper]() + v.slice(1);
8
- return [v[0], ...v.slice(1)[map](v => v[0][upper]() + v.slice(1))].join('');
9
- };
10
- export default capitalize;
@@ -1,20 +0,0 @@
1
- type LoggerData = null | boolean | number | string | {
2
- [limn]: (...args: any) => LoggerData;
3
- } | LoggerData[] | {
4
- [k: string]: LoggerData;
5
- };
6
- export default class Logger {
7
- static dummy: Logger;
8
- private format;
9
- private domain;
10
- private ctx;
11
- private write;
12
- private opts;
13
- constructor(domain: string, ctx?: Obj<any>, opts?: typeof this.opts, write?: typeof this.write);
14
- getDomain(): string;
15
- getTraceId(term: string): string;
16
- log(data: LoggerData): void;
17
- kid(domain: string): Logger;
18
- scope<Fn extends (logger: Logger) => any>(domain: string, ctx: Obj<any>, fn: Fn): ReturnType<Fn>;
19
- }
20
- export {};
@@ -1,147 +0,0 @@
1
- // TODO: @gershy/logger (or @gershy/watcher?)
2
- import { getClsName, inCls, isCls } from '@gershy/clearing';
3
- const scrubbed = (val, opts = {}) => {
4
- const { isScrub = (k, _v) => k[0] === '!', doScrub = ((v) => `$scrub(${getClsName(v)})`), seen = new Map() } = opts ?? {};
5
- if (val === null)
6
- return val;
7
- if (isCls(val, Boolean))
8
- return val;
9
- if (isCls(val, Number))
10
- return val;
11
- if (isCls(val, String))
12
- return val;
13
- if (seen.has(val))
14
- return seen.get(val) ?? null;
15
- if (isCls(val, Array)) {
16
- const result = [];
17
- seen.set(val, result);
18
- for (const item of val)
19
- result.push(scrubbed(item, { isScrub, doScrub, seen }));
20
- return result;
21
- }
22
- else if (isCls(val, Object)) {
23
- // Consider using hashes to display scrubbed values? (Makes them correlatable!)
24
- const result = {};
25
- seen.set(val, result);
26
- for (const [k, v] of val)
27
- result[k] = isScrub(k, v) ? doScrub(v) : scrubbed(v, { isScrub, doScrub, seen });
28
- return result;
29
- }
30
- else if (inCls(val[limn], Function)) {
31
- return scrubbed(val[limn](), { isScrub, doScrub, seen });
32
- }
33
- else {
34
- // Consider processing for other types (sets, maps?)
35
- return val;
36
- }
37
- };
38
- export default class Logger {
39
- static dummy = {
40
- getTraceId() { return ''; },
41
- log() { },
42
- kid() { return Logger.dummy; },
43
- scope(...args) { return args.at(-1)(Logger.dummy); }
44
- };
45
- format(v /* should not have cycles */, seen = new Map()) {
46
- // Formats any value into json (so that it can be logged)
47
- if (v == null)
48
- return null;
49
- if (isCls(v, Boolean))
50
- return v;
51
- if (isCls(v, Number))
52
- return v;
53
- if (isCls(v, String))
54
- return v.length > this.opts.maxStrLen ? v.slice(0, this.opts.maxStrLen - 1) + '\u2026' : v;
55
- if (seen.has(v))
56
- return `<cyc> ${getClsName(v)}(...)`;
57
- if (inCls(v[limn], Function)) {
58
- const formatted = {};
59
- seen.set(v, formatted);
60
- Object.assign(formatted, this.format(v[limn](), seen));
61
- return formatted;
62
- }
63
- if (isCls(v, Array)) {
64
- const arr = [];
65
- seen.set(v, arr);
66
- for (const vv of v)
67
- arr.push(this.format(vv, seen));
68
- return arr;
69
- }
70
- if (isCls(v, Object)) {
71
- const obj = {};
72
- seen.set(v, obj);
73
- for (const k in v)
74
- obj[k] = this.format(v[k], seen);
75
- return obj;
76
- }
77
- return `${getClsName(v)}(...)`;
78
- }
79
- ;
80
- domain;
81
- ctx;
82
- write;
83
- opts;
84
- constructor(domain, ctx = {}, opts, write) {
85
- this.domain = domain;
86
- this.ctx = {
87
- ...ctx,
88
- $: this.domain,
89
- [this.domain.split('.').at(-1)]: Math.random().toString(36).slice(2, 12)[padTail](10, '0'),
90
- };
91
- this.opts = opts ?? { maxStrLen: 250 };
92
- // Note this default `this.write` function produces truncated values (sloppy outputting) in the
93
- // cli, but works perfectly for lambdas with json-style logging configured!
94
- this.write = write ?? ((val) => console.log(val));
95
- }
96
- getDomain() { return this.domain; }
97
- getTraceId(term) {
98
- const traceId = this.ctx[term];
99
- if (!traceId)
100
- throw Error('trace term invalid')[mod]({ term, ctx: this.ctx });
101
- return traceId;
102
- }
103
- log(data) {
104
- // Use-cases:
105
- // 1. logger.log('a basic string')
106
- // - The logged payload is converted to `{ msg: 'a basic string' }`
107
- // 2. logger.log({ msg: 'a basic string' })
108
- // - Logged as-is; equivalent to #1
109
- // 3. logger.log({ $$: 'note', msg: 'a basic string' })
110
- // - Same as #1 and #2, but logger domain has "note" appended to it
111
- // 4. logger.log({ $$: 'noteOnly' })
112
- // - Logged payload will be `{}`; only info is the tag - useful for infinitesimal moments in
113
- // the flamegraph!
114
- // 5. logger.log({ $$: 'context.noteOnly' })
115
- // - Valid way to extend domain with more than 1 component at once!
116
- let dmn = null;
117
- if (data && isCls(data?.$$, String))
118
- ({ $$: dmn, ...data } = data);
119
- const domain = dmn ? [this.domain, dmn].join('.') : this.domain;
120
- if (!isCls(data, Object))
121
- data = { msg: data };
122
- this.write({}[merge]({ $: this.ctx })[merge](scrubbed(this.format(data)))[merge]({ $: { $: domain } }));
123
- }
124
- kid(domain) {
125
- const d = [this.domain, domain].filter(Boolean).join('.');
126
- const logger = new Logger(d, this.ctx, this.opts, this.write);
127
- return logger;
128
- }
129
- scope(domain, ctx, fn) {
130
- const ms = Date.now();
131
- const logger = this.kid(domain);
132
- logger.log({ $$: 'launch', ...ctx });
133
- const accept = val => { logger.log({ $$: 'accept', ms: Date.now() - ms }); return val; };
134
- const glitch = err => { logger.log({ $$: err.log?.term ?? 'glitch', ms: Date.now() - ms, err }); throw err; }; // Always throws an error! Note allowing the consumer to override the logged term/domain offers a lot of flexibility!
135
- let v;
136
- try {
137
- v = fn(logger);
138
- }
139
- catch (err) {
140
- glitch(err);
141
- }
142
- return isCls(v, Promise)
143
- ? v.then(accept, glitch)
144
- : accept(v);
145
- }
146
- }
147
- ;
@@ -1,2 +0,0 @@
1
- declare const _default: (val: string) => Lowercase<string>;
2
- export default _default;
@@ -1 +0,0 @@
1
- export default (val) => val.replace(/([A-Z])/g, '_$1')[lower]();