keri-ts 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -61,6 +61,14 @@ tufa annotate --qb2 --in <binary.qb2> --out <annotation.txt>
61
61
  - `--out <path>`: output file path (defaults to stdout)
62
62
  - `--qb2`: parse input as qb2 binary
63
63
  - `--pretty`: pretty-print annotation output
64
+ - `--colored`: colorize annotation output on stdout only (ignored with `--out`)
65
+
66
+ Optional color overrides:
67
+
68
+ - File: `$HOME/.tufa/annot-color.yaml` or `$HOME/.tufa/annot-color.yml`
69
+ - Keys: `counter`, `group`, `body`, `signature`, `said`, `opaque`, `comment`
70
+ - Values: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`,
71
+ or bright variants (`brightBlack` ... `brightWhite`)
64
72
 
65
73
  ## Package entrypoints
66
74
 
@@ -72,3 +80,8 @@ npx tufa --help
72
80
  deno task tufa --help
73
81
  deno task tufa version
74
82
  ```
83
+
84
+ ## License
85
+
86
+ Licensed under the Apache License, Version 2.0 (`Apache-2.0`). See the
87
+ top-level `LICENSE` file in this repository.
@@ -0,0 +1,215 @@
1
+ import * as dntShim from "../../_dnt.shims.js";
2
+ const ANSI_CODES = {
3
+ black: "\x1b[30m",
4
+ red: "\x1b[31m",
5
+ green: "\x1b[32m",
6
+ yellow: "\x1b[33m",
7
+ blue: "\x1b[34m",
8
+ magenta: "\x1b[35m",
9
+ cyan: "\x1b[36m",
10
+ white: "\x1b[37m",
11
+ brightBlack: "\x1b[90m",
12
+ brightRed: "\x1b[91m",
13
+ brightGreen: "\x1b[92m",
14
+ brightYellow: "\x1b[93m",
15
+ brightBlue: "\x1b[94m",
16
+ brightMagenta: "\x1b[95m",
17
+ brightCyan: "\x1b[96m",
18
+ brightWhite: "\x1b[97m",
19
+ };
20
+ const RESET = "\x1b[0m";
21
+ const COLOR_KEYS = [
22
+ "counter",
23
+ "group",
24
+ "body",
25
+ "signature",
26
+ "said",
27
+ "opaque",
28
+ "comment",
29
+ ];
30
+ const DEFAULT_COLORS = {
31
+ counter: "cyan",
32
+ group: "magenta",
33
+ body: "green",
34
+ signature: "yellow",
35
+ said: "brightBlue",
36
+ opaque: "brightRed",
37
+ comment: "brightBlack",
38
+ };
39
+ const SAID_CAPTURE = /(said=)(\S+)/g;
40
+ const COMMENT_DELIM = " # ";
41
+ function isColorName(value) {
42
+ return typeof value === "string" && value in ANSI_CODES;
43
+ }
44
+ function parseColorConfig(raw) {
45
+ const parsed = {};
46
+ const lines = raw.split(/\r?\n/);
47
+ for (const line of lines) {
48
+ const trimmed = line.trim();
49
+ if (!trimmed || trimmed.startsWith("#"))
50
+ continue;
51
+ const match = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.+?)\s*$/.exec(trimmed);
52
+ if (!match)
53
+ return null;
54
+ const key = match[1];
55
+ let value = match[2];
56
+ if ((value.startsWith('"') && value.endsWith('"')) ||
57
+ (value.startsWith("'") && value.endsWith("'"))) {
58
+ value = value.slice(1, -1);
59
+ }
60
+ parsed[key] = value;
61
+ }
62
+ const config = {};
63
+ for (const key of COLOR_KEYS) {
64
+ const value = parsed[key];
65
+ if (value === undefined)
66
+ continue;
67
+ if (!isColorName(value))
68
+ return null;
69
+ config[key] = value;
70
+ }
71
+ return config;
72
+ }
73
+ function resolveConfigPath(homeDir) {
74
+ const basePath = `${homeDir}/.tufa`;
75
+ const yamlPath = `${basePath}/annot-color.yaml`;
76
+ const ymlPath = `${basePath}/annot-color.yml`;
77
+ try {
78
+ const stat = dntShim.Deno.statSync(yamlPath);
79
+ if (stat.isFile)
80
+ return yamlPath;
81
+ }
82
+ catch {
83
+ // Continue to .yml fallback
84
+ }
85
+ try {
86
+ const stat = dntShim.Deno.statSync(ymlPath);
87
+ if (stat.isFile)
88
+ return ymlPath;
89
+ }
90
+ catch {
91
+ // No config file, use defaults
92
+ }
93
+ return null;
94
+ }
95
+ function readUserColorConfig() {
96
+ const homeDir = dntShim.Deno.env.get("HOME");
97
+ if (!homeDir)
98
+ return null;
99
+ const configPath = resolveConfigPath(homeDir);
100
+ if (!configPath)
101
+ return null;
102
+ try {
103
+ return parseColorConfig(dntShim.Deno.readTextFileSync(configPath));
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ function toAnsiColors(userConfig) {
110
+ const names = { ...DEFAULT_COLORS };
111
+ if (userConfig) {
112
+ for (const key of COLOR_KEYS) {
113
+ const value = userConfig[key];
114
+ if (value)
115
+ names[key] = value;
116
+ }
117
+ }
118
+ return {
119
+ counter: ANSI_CODES[names.counter],
120
+ group: ANSI_CODES[names.group],
121
+ body: ANSI_CODES[names.body],
122
+ signature: ANSI_CODES[names.signature],
123
+ said: ANSI_CODES[names.said],
124
+ opaque: ANSI_CODES[names.opaque],
125
+ comment: ANSI_CODES[names.comment],
126
+ };
127
+ }
128
+ function color(text, ansiCode) {
129
+ if (!text)
130
+ return text;
131
+ return `${ansiCode}${text}${RESET}`;
132
+ }
133
+ function colorizeComment(comment, colors) {
134
+ const saidTinted = comment.replace(SAID_CAPTURE, (_whole, prefix, said) => `${prefix}${color(said, colors.said)}`);
135
+ return color(saidTinted, colors.comment);
136
+ }
137
+ function colorizeValue(value, comment, colors) {
138
+ const text = value.trim();
139
+ if (!text)
140
+ return value;
141
+ if (comment && /opaque/i.test(comment)) {
142
+ return color(value, colors.opaque);
143
+ }
144
+ if (comment && /(Indexer|Sig|Sigs|Signature)/.test(comment)) {
145
+ return color(value, colors.signature);
146
+ }
147
+ if (comment && /(Group|count=|counter)/.test(comment)) {
148
+ return color(value, colors.group);
149
+ }
150
+ if (comment && /SERDER/.test(comment)) {
151
+ return color(value, colors.body);
152
+ }
153
+ if (/^[\[{]/.test(text)) {
154
+ return color(value, colors.body);
155
+ }
156
+ if (/^-[A-Za-z0-9_-]+$/.test(text)) {
157
+ return color(value, colors.counter);
158
+ }
159
+ return value;
160
+ }
161
+ function colorizeLine(line, colors) {
162
+ const trimmed = line.trimStart();
163
+ if (trimmed.startsWith("#")) {
164
+ return color(line, colors.comment);
165
+ }
166
+ const idx = line.indexOf(COMMENT_DELIM);
167
+ if (idx === -1) {
168
+ return colorizeValue(line, null, colors);
169
+ }
170
+ const value = line.slice(0, idx);
171
+ const comment = line.slice(idx + COMMENT_DELIM.length);
172
+ const valueTinted = colorizeValue(value, comment, colors);
173
+ const commentTinted = colorizeComment(comment, colors);
174
+ return `${valueTinted}${COMMENT_DELIM}${commentTinted}`;
175
+ }
176
+ /**
177
+ * Apply ANSI styling for CLI-only CESR annotation display.
178
+ * This is intentionally presentation-only and must not alter persisted output.
179
+ */
180
+ export function colorizeAnnotatedOutput(annotated) {
181
+ const colors = toAnsiColors(readUserColorConfig());
182
+ const lines = annotated.split("\n");
183
+ const out = [];
184
+ let inPrettyJsonBody = false;
185
+ // support colorizing lines even with --pretty arg
186
+ for (const line of lines) {
187
+ const idx = line.indexOf(COMMENT_DELIM);
188
+ const value = idx === -1 ? line : line.slice(0, idx);
189
+ const comment = idx === -1 ? null : line.slice(idx + COMMENT_DELIM.length);
190
+ const trimmed = value.trim();
191
+ if (comment && /SERDER/.test(comment)) {
192
+ if (trimmed === "}" || trimmed === "]") {
193
+ const valueTinted = color(value, colors.body);
194
+ const commentTinted = colorizeComment(comment, colors);
195
+ out.push(`${valueTinted}${COMMENT_DELIM}${commentTinted}`);
196
+ inPrettyJsonBody = false;
197
+ continue;
198
+ }
199
+ out.push(colorizeLine(line, colors));
200
+ inPrettyJsonBody = false;
201
+ continue;
202
+ }
203
+ if (inPrettyJsonBody && idx === -1) {
204
+ out.push(color(line, colors.body));
205
+ continue;
206
+ }
207
+ if (idx === -1 && (trimmed === "{" || trimmed === "[")) {
208
+ inPrettyJsonBody = true;
209
+ out.push(color(line, colors.body));
210
+ continue;
211
+ }
212
+ out.push(colorizeLine(line, colors));
213
+ }
214
+ return out.join("\n");
215
+ }
@@ -1,5 +1,6 @@
1
1
  import * as dntShim from "../../_dnt.shims.js";
2
2
  import { annotate } from "cesr-ts";
3
+ import { colorizeAnnotatedOutput } from "./annotate-color.js";
3
4
  const TEXT_DECODER = new TextDecoder();
4
5
  /**
5
6
  * Reads bytes from stdin in chunks of 64KB and returns them as a single Uint8Array
@@ -34,6 +35,7 @@ export function* annotateCommand(args) {
34
35
  outPath: args.outPath,
35
36
  qb2: args.qb2,
36
37
  pretty: args.pretty,
38
+ colored: args.colored,
37
39
  };
38
40
  const inputBytes = options.inPath
39
41
  ? dntShim.Deno.readFileSync(options.inPath)
@@ -48,5 +50,8 @@ export function* annotateCommand(args) {
48
50
  dntShim.Deno.writeTextFileSync(options.outPath, annotated);
49
51
  return;
50
52
  }
51
- console.log(annotated);
53
+ const output = options.colored
54
+ ? colorizeAnnotatedOutput(annotated)
55
+ : annotated;
56
+ console.log(output);
52
57
  }
@@ -199,6 +199,7 @@ function regAnnotateCmd(program, dispatch) {
199
199
  .option("--out <path>", "Output file path (defaults to stdout)")
200
200
  .option("--qb2", "Treat input as qb2 binary instead of text CESR")
201
201
  .option("--pretty", "Pretty-print annotation output")
202
+ .option("--colored", "Colorize annotation output (stdout only)")
202
203
  .action((options) => {
203
204
  dispatch({
204
205
  name: "annotate",
@@ -207,6 +208,7 @@ function regAnnotateCmd(program, dispatch) {
207
208
  outPath: options.out,
208
209
  qb2: options.qb2 || false,
209
210
  pretty: options.pretty || false,
211
+ colored: options.colored || false,
210
212
  },
211
213
  });
212
214
  return Promise.resolve();
@@ -2,8 +2,8 @@
2
2
  * Generated by scripts/generate_versions.ts.
3
3
  * Do not edit by hand.
4
4
  */
5
- export const PACKAGE_VERSION = "0.3.0";
6
- export const BUILD_METADATA = "build.3.9b643722";
5
+ export const PACKAGE_VERSION = "0.3.1";
6
+ export const BUILD_METADATA = "build.4.f47c821b";
7
7
  export const DISPLAY_VERSION = BUILD_METADATA
8
8
  ? `${PACKAGE_VERSION}+${BUILD_METADATA}`
9
9
  : PACKAGE_VERSION;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keri-ts",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "KERI TypeScript package with database primitives and CLI runtime",
5
5
  "homepage": "https://github.com/kentbull/keri-ts",
6
6
  "repository": {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Apply ANSI styling for CLI-only CESR annotation display.
3
+ * This is intentionally presentation-only and must not alter persisted output.
4
+ */
5
+ export declare function colorizeAnnotatedOutput(annotated: string): string;
6
+ //# sourceMappingURL=annotate-color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotate-color.d.ts","sourceRoot":"","sources":["../../../src/app/cli/annotate-color.ts"],"names":[],"mappings":"AAyOA;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAyCjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"annotate.d.ts","sourceRoot":"","sources":["../../../src/app/cli/annotate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAuD3C,wBAAiB,eAAe,CAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,SAAS,CAAC,IAAI,CAAC,CAyBjB"}
1
+ {"version":3,"file":"annotate.d.ts","sourceRoot":"","sources":["../../../src/app/cli/annotate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AA4D3C,wBAAiB,eAAe,CAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,SAAS,CAAC,IAAI,CAAC,CA6BjB"}
@@ -2,7 +2,7 @@
2
2
  * Generated by scripts/generate_versions.ts.
3
3
  * Do not edit by hand.
4
4
  */
5
- export declare const PACKAGE_VERSION = "0.3.0";
6
- export declare const BUILD_METADATA = "build.3.9b643722";
5
+ export declare const PACKAGE_VERSION = "0.3.1";
6
+ export declare const BUILD_METADATA = "build.4.f47c821b";
7
7
  export declare const DISPLAY_VERSION: string;
8
8
  //# sourceMappingURL=version.d.ts.map