@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 +1 -1
- package/cmp/cjs/petal/terraform/terraform.js +9 -9
- package/cmp/cjs/util/aws.js +2 -2
- package/cmp/mjs/main.d.ts +1 -1
- package/cmp/mjs/petal/terraform/terraform.js +9 -9
- package/cmp/mjs/util/aws.js +2 -2
- package/package.json +4 -2
- package/cmp/cjs/util/capitalize.d.ts +0 -2
- package/cmp/cjs/util/capitalize.js +0 -12
- package/cmp/cjs/util/logger.d.ts +0 -20
- package/cmp/cjs/util/logger.js +0 -150
- package/cmp/cjs/util/snakeCase.d.ts +0 -2
- package/cmp/cjs/util/snakeCase.js +0 -3
- package/cmp/mjs/util/capitalize.d.ts +0 -2
- package/cmp/mjs/util/capitalize.js +0 -10
- package/cmp/mjs/util/logger.d.ts +0 -20
- package/cmp/mjs/util/logger.js +0 -147
- package/cmp/mjs/util/snakeCase.d.ts +0 -2
- package/cmp/mjs/util/snakeCase.js +0 -1
package/cmp/cjs/main.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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)}`;
|
package/cmp/cjs/util/aws.js
CHANGED
|
@@ -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
|
|
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,
|
|
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,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 [
|
|
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 [[
|
|
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 [
|
|
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 = `${
|
|
79
|
+
const base = `${ph(this.getType(), 'camel', 'snake')}.${ph(this.getHandle(), 'camel', 'snake')}`;
|
|
80
80
|
return props.length
|
|
81
|
-
? `${base}.${props[map](v =>
|
|
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 "${
|
|
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 "${
|
|
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 "${
|
|
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)}`;
|
package/cmp/mjs/util/aws.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isCls } from '@gershy/clearing';
|
|
2
|
-
import
|
|
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) => [
|
|
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
|
+
"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/
|
|
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,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;
|
package/cmp/cjs/util/logger.d.ts
DELETED
|
@@ -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 {};
|
package/cmp/cjs/util/logger.js
DELETED
|
@@ -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,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;
|
package/cmp/mjs/util/logger.d.ts
DELETED
|
@@ -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 {};
|
package/cmp/mjs/util/logger.js
DELETED
|
@@ -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 +0,0 @@
|
|
|
1
|
-
export default (val) => val.replace(/([A-Z])/g, '_$1')[lower]();
|