@commercetools/processors 0.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.
- package/README.md +341 -0
- package/dist/index.d.mts +112 -0
- package/dist/index.d.ts +112 -0
- package/dist/index.js +476 -0
- package/dist/index.mjs +430 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# @commercetools/processors
|
|
2
|
+
|
|
3
|
+
**Output processors** for MCP-style tool payloads and similar JSON: declarative **field filtering** (drop keys) and **redaction** (mask values, including query strings inside URL-shaped strings), plus **transform** helpers that turn structured tool results into **tabular** or **JSON** text for LLMs.
|
|
4
|
+
|
|
5
|
+
The library is **domain-agnostic**: you pass plain objects/arrays/primitives (anything you would normally `JSON.parse`). Rules use **dot paths** from the root of the value you pass into `filterFields`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm add @commercetools/processors
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
or
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
yarn add @commercetools/processors
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You can also use `npm` or `yarn` with the same package name.
|
|
22
|
+
|
|
23
|
+
**Runtime:** Node **≥ 18**.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Package layout (what each area does)
|
|
28
|
+
|
|
29
|
+
| Area | Responsibility |
|
|
30
|
+
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| **`FieldFilteringHandler`** | Walks a value recursively. On **objects**, applies rules per key path; on **arrays**, maps each element (path rules do not add array indices—see below). On **strings**, if the string is a **valid URL**, runs the same rule logic on **query parameter names**; other strings are left as-is. |
|
|
32
|
+
| **`FieldFilteringManagerConfig`** | Declarative lists of rules (`paths`, `properties`, `includes`) plus optional **whitelist** paths and custom **redaction placeholder** strings for JSON vs URL query values. |
|
|
33
|
+
| **`FieldFilteringManager`** | Interface: `filterFields` + `filterUrlFields`. Swap in your own implementation (e.g. remote policy) and use **`isFieldFilteringManager`** at runtime to tell **config** from **instance**. |
|
|
34
|
+
| **`transformToolOutput`** | Converts `data` into a **string**: default **`tabular`** (indented, property names via `transformPropertyName`, booleans as `Yes`/`No`, tables for arrays of objects where applicable); optional **`json`** stringifies JSON. |
|
|
35
|
+
| **`transformPropertyName`** | Turns identifiers like `orderLineId` or `order_line_id` into human-oriented labels (used internally by tabular output and titles). |
|
|
36
|
+
| **`urlHelpers`** | **`isValidUrl`**, **`normaliseUrl`**, **`generateQueryString`** — small utilities shared with URL handling in the handler. |
|
|
37
|
+
| **`defaultFilteringRules`**, **`defaultJsonRedactionText`**, **`defaultUrlRedactionText`** | Defaults for redaction placeholders when you omit them in config (`[REDACTED]` / `REDACTED`). |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Usage overview
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
FieldFilteringHandler,
|
|
46
|
+
type FieldFilteringManagerConfig,
|
|
47
|
+
type FieldFilteringRule,
|
|
48
|
+
type FieldFilteringManager,
|
|
49
|
+
isFieldFilteringManager,
|
|
50
|
+
defaultFilteringRules,
|
|
51
|
+
defaultJsonRedactionText,
|
|
52
|
+
defaultUrlRedactionText,
|
|
53
|
+
transformToolOutput,
|
|
54
|
+
transformPropertyName,
|
|
55
|
+
isValidUrl,
|
|
56
|
+
generateQueryString,
|
|
57
|
+
normaliseUrl,
|
|
58
|
+
} from '@commercetools/processors';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Typical flow: **clone** (or parse fresh JSON) → **`new FieldFilteringHandler(config).filterFields(data)`** → optionally **`transformToolOutput({ data: safe, ... })`** before sending to a model, agent or client.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Field filtering and redaction
|
|
66
|
+
|
|
67
|
+
### Why cloning matters
|
|
68
|
+
|
|
69
|
+
`filterFields` **mutates** object graphs in place (delete keys, replace values). If the same object is referenced elsewhere (cache, logger, retry), those views change too. Always **`structuredClone`**, `JSON.parse(JSON.stringify(x))`, or another **deep copy** before filtering when you need isolation.
|
|
70
|
+
|
|
71
|
+
### How rules are evaluated (mental model)
|
|
72
|
+
|
|
73
|
+
For each object key, the handler builds a **path** like `parent.child.leaf`. Then, for **filter** or **redact** separately:
|
|
74
|
+
|
|
75
|
+
1. **Whitelist** — if the current path matches a whitelist entry, **no** filter/redact on that path from the declarative lists (exact / case rules as in tests).
|
|
76
|
+
2. **`paths`** — full path match; **`filter`** removes that property; **`redact`** replaces the **entire value at that path** with `jsonRedactionText` (the subtree is not traversed further for path-redact in the same way as nested keys—see handler tests for edge cases).
|
|
77
|
+
3. **`properties`** — compares the **last segment** of the path (the key name) to each rule.
|
|
78
|
+
4. **`includes`** — substring match on that **last segment** (e.g. `secret` matches `clientSecret` when case-insensitive).
|
|
79
|
+
|
|
80
|
+
**Arrays:** elements are processed with the **same** `currentPath` as the parent array (no `.0`, `.1` in the path). Rules keyed on **property names** or **`includes`** still apply inside objects **inside** arrays; **full `paths`** rules that assume `items.0.field` will **not** match the stock handler—use **`properties`/`includes`** or a custom **`FieldFilteringManager`**.
|
|
81
|
+
|
|
82
|
+
### `FieldFilteringManagerConfig` (reference)
|
|
83
|
+
|
|
84
|
+
Every top-level field is **optional**; supply only what you need.
|
|
85
|
+
|
|
86
|
+
| Option | Type | Role |
|
|
87
|
+
| ----------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| **`paths`** | `FieldFilteringRule[]` | Match the **full dot-path** from the root of the value passed to `filterFields`. `type: 'filter'` removes the key. `type: 'redact'` replaces that node’s value with `jsonRedactionText` (often a whole object becomes the placeholder string). |
|
|
89
|
+
| **`properties`** | `FieldFilteringRule[]` | Match the **leaf key name** at **any** depth (e.g. every `token` key). |
|
|
90
|
+
| **`includes`** | `FieldFilteringRule[]` | Match when the leaf name **contains** `rule.value` (substring), with optional case folding per rule. |
|
|
91
|
+
| **`whitelistPaths`** | `Omit<FieldFilteringRule, 'type'>[]` | Paths that **suppress** filter/redact from the lists above when the evaluated path matches (see tests for exact vs case-insensitive behaviour). |
|
|
92
|
+
| **`jsonRedactionText`** | `string?` | Replacement for redacted **JSON** values (default **`[REDACTED]`**). |
|
|
93
|
+
| **`urlRedactionText`** | `string?` | Replacement for redacted **URL query** values (default **`REDACTED`**). |
|
|
94
|
+
|
|
95
|
+
### `FieldFilteringRule`
|
|
96
|
+
|
|
97
|
+
| Field | Meaning |
|
|
98
|
+
| ------------------- | -------------------------------------------------------------------------------------------- |
|
|
99
|
+
| **`value`** | Path, leaf name, or substring needle (depending on which array the rule sits in). |
|
|
100
|
+
| **`caseSensitive`** | If `false`, comparisons use case-insensitive matching where implemented. |
|
|
101
|
+
| **`type`** | **`'filter'`** — remove key (or query param). **`'redact'`** — keep key/name, replace value. |
|
|
102
|
+
|
|
103
|
+
### `FieldFilteringManager` and `isFieldFilteringManager`
|
|
104
|
+
|
|
105
|
+
Use a **custom class** that implements `filterFields` / `filterUrlFields` when you need logging, remote policy, or different path semantics than `FieldFilteringHandler`. **`isFieldFilteringManager(x)`** returns true when `x` has both methods (duck typing), so you can accept **either** plain **config** or a ready-made **manager** from configuration:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import {
|
|
109
|
+
FieldFilteringHandler,
|
|
110
|
+
isFieldFilteringManager,
|
|
111
|
+
type FieldFilteringManager,
|
|
112
|
+
type FieldFilteringManagerConfig,
|
|
113
|
+
} from '@commercetools/processors';
|
|
114
|
+
|
|
115
|
+
function getHandler(
|
|
116
|
+
input: FieldFilteringManagerConfig | FieldFilteringManager
|
|
117
|
+
): FieldFilteringManager {
|
|
118
|
+
if (isFieldFilteringManager(input)) {
|
|
119
|
+
return input;
|
|
120
|
+
}
|
|
121
|
+
return new FieldFilteringHandler(input);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const handler = getHandler({
|
|
125
|
+
properties: [{value: 'x', caseSensitive: true, type: 'filter'}],
|
|
126
|
+
});
|
|
127
|
+
const out = handler.filterFields({x: 1, y: 2});
|
|
128
|
+
|
|
129
|
+
// Expected `out`:
|
|
130
|
+
// { y: 2 }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Examples: `FieldFilteringHandler` on JSON
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import {
|
|
139
|
+
FieldFilteringHandler,
|
|
140
|
+
type FieldFilteringManagerConfig,
|
|
141
|
+
} from '@commercetools/processors';
|
|
142
|
+
|
|
143
|
+
const config: FieldFilteringManagerConfig = {
|
|
144
|
+
// Full path: redact only this branch's value (here the string becomes "[REDACTED]")
|
|
145
|
+
paths: [
|
|
146
|
+
{value: 'credentials.accessToken', caseSensitive: true, type: 'redact'},
|
|
147
|
+
],
|
|
148
|
+
// Any key named apiKey (any casing): remove entirely
|
|
149
|
+
properties: [{value: 'apiKey', caseSensitive: false, type: 'filter'}],
|
|
150
|
+
// Any leaf name containing "secret": redact value, keep key
|
|
151
|
+
includes: [{value: 'secret', caseSensitive: false, type: 'redact'}],
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const toolResult = {
|
|
155
|
+
credentials: {accessToken: 'tok', refresh: 'r'},
|
|
156
|
+
apiKey: 'k',
|
|
157
|
+
clientSecret: 's',
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const safe = structuredClone(toolResult);
|
|
161
|
+
new FieldFilteringHandler(config).filterFields(safe);
|
|
162
|
+
|
|
163
|
+
// Expected `safe` (JSON-serialized for clarity):
|
|
164
|
+
// {"credentials":{"accessToken":"[REDACTED]","refresh":"r"},"clientSecret":"[REDACTED]"}
|
|
165
|
+
// - paths: credentials.accessToken value replaced; refresh unchanged
|
|
166
|
+
// - properties: apiKey key removed
|
|
167
|
+
// - includes: clientSecret value redacted (leaf name contains "secret")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Examples: `filterUrlFields` (query string)
|
|
173
|
+
|
|
174
|
+
Rules use the same machinery: **filter** drops a query pair; **redact** keeps the name and sets the value to **`urlRedactionText`**.
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import {FieldFilteringHandler} from '@commercetools/processors';
|
|
178
|
+
|
|
179
|
+
const redacted = new FieldFilteringHandler({
|
|
180
|
+
properties: [{value: 'sig', caseSensitive: false, type: 'redact'}],
|
|
181
|
+
}).filterUrlFields('https://x.example/y?sig=abc123&ok=1');
|
|
182
|
+
|
|
183
|
+
// Expected `redacted`:
|
|
184
|
+
// "https://x.example/y?sig=REDACTED&ok=1"
|
|
185
|
+
|
|
186
|
+
const stripped = new FieldFilteringHandler({
|
|
187
|
+
properties: [{value: 'token', caseSensitive: false, type: 'filter'}],
|
|
188
|
+
}).filterUrlFields('https://api.example.com/callback?token=abc&ok=1');
|
|
189
|
+
|
|
190
|
+
// Expected `stripped`:
|
|
191
|
+
// "https://api.example.com/callback?ok=1"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Examples: `transformToolOutput`
|
|
197
|
+
|
|
198
|
+
`format` defaults to **`'tabular'`**. With a **`title`**, the title is uppercased (after `transformPropertyName`) and used as a heading. Booleans become **`Yes`/`No`**; nested objects get indented lines; empty plain objects yield **`no properties`** (with optional title prefix—see below).
|
|
199
|
+
|
|
200
|
+
### Tabular, with title
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import {transformToolOutput} from '@commercetools/processors';
|
|
204
|
+
|
|
205
|
+
const text = transformToolOutput({
|
|
206
|
+
data: {orderId: '123', total: {currency: 'EUR', centAmount: 4200}},
|
|
207
|
+
title: 'Order summary',
|
|
208
|
+
format: 'tabular',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Expected `text` (string; newlines shown as \n here):
|
|
212
|
+
// "ORDER SUMMARY\nOrder Id: 123\nTotal:\n\tCurrency: EUR\n\tCent Amount: 4200"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Tabular, no title
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
const plain = transformToolOutput({
|
|
219
|
+
data: {a: 1},
|
|
220
|
+
format: 'tabular',
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Expected `plain`:
|
|
224
|
+
// "A: 1"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Tabular, empty object
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
const empty = transformToolOutput({data: {}, format: 'tabular'});
|
|
231
|
+
|
|
232
|
+
// Expected `empty`:
|
|
233
|
+
// "no properties"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Tabular, boolean
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
const stock = transformToolOutput({
|
|
240
|
+
data: {inStock: true},
|
|
241
|
+
format: 'tabular',
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Expected `stock`:
|
|
245
|
+
// "In Stock: Yes"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### JSON format
|
|
249
|
+
|
|
250
|
+
With **`format: 'json'`**, output is `JSON.stringify` of the data (or a single-key object whose key is the transformed title when `title` is set).
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
const json = transformToolOutput({
|
|
254
|
+
data: {orderId: '123', total: {currency: 'EUR', centAmount: 4200}},
|
|
255
|
+
title: 'Order summary',
|
|
256
|
+
format: 'json',
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Expected `json` (parsed shape):
|
|
260
|
+
// {"ORDER SUMMARY":{"orderId":"123","total":{"currency":"EUR","centAmount":4200}}}
|
|
261
|
+
// Exact string spacing follows JSON.stringify.
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Examples: `transformPropertyName`
|
|
267
|
+
|
|
268
|
+
Splits **camelCase**, **PascalCase**, **snake_case**, and **kebab-case** into words and applies light title-style casing (see unit tests for acronym edge cases).
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import {transformPropertyName} from '@commercetools/processors';
|
|
272
|
+
|
|
273
|
+
transformPropertyName('customerId');
|
|
274
|
+
// Expected: "Customer Id"
|
|
275
|
+
|
|
276
|
+
transformPropertyName('order_line_id');
|
|
277
|
+
// Expected: "Order Line Id"
|
|
278
|
+
|
|
279
|
+
transformPropertyName('propertyNameSDK');
|
|
280
|
+
// Expected: "Property Name SDK"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Examples: URL helpers
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
import {
|
|
289
|
+
isValidUrl,
|
|
290
|
+
normaliseUrl,
|
|
291
|
+
generateQueryString,
|
|
292
|
+
} from '@commercetools/processors';
|
|
293
|
+
|
|
294
|
+
isValidUrl('https://example.com/path?q=1');
|
|
295
|
+
// Expected: true
|
|
296
|
+
|
|
297
|
+
isValidUrl('not a url');
|
|
298
|
+
// Expected: false
|
|
299
|
+
|
|
300
|
+
normaliseUrl('https://a.com//b/../c?x=1');
|
|
301
|
+
// Example output (string; normalises slashes/host segment style — see tests for full matrix):
|
|
302
|
+
// "https://a.com/b/../c?x=1"
|
|
303
|
+
|
|
304
|
+
generateQueryString({a: 1, b: [2, 3]});
|
|
305
|
+
// Expected (qs indices format; leading `?`):
|
|
306
|
+
// "?a=1&b[0]=2&b[1]=3"
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
More cases: **`processors/test/field-filtering/urlHelpers.test.ts`**.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Defaults export
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
import {
|
|
317
|
+
defaultFilteringRules,
|
|
318
|
+
defaultJsonRedactionText,
|
|
319
|
+
defaultUrlRedactionText,
|
|
320
|
+
} from '@commercetools/processors';
|
|
321
|
+
|
|
322
|
+
// `defaultFilteringRules` is a FieldFilteringManagerConfig-shaped object with only the default redaction strings set.
|
|
323
|
+
// `defaultJsonRedactionText` === '[REDACTED]'
|
|
324
|
+
// `defaultUrlRedactionText` === 'REDACTED'
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Build from source (monorepo)
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
pnpm --filter @commercetools/processors install
|
|
333
|
+
pnpm --filter @commercetools/processors run build
|
|
334
|
+
pnpm --filter @commercetools/processors run test
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Further reading
|
|
340
|
+
|
|
341
|
+
Behavioural details (whitelist vs paths, URL bracket keys, empty-rule short-circuit, etc.) are covered [here](test/field-filtering/FieldFilteringHandler.test.ts) and [here](test/transform/transformToolOutput.test.ts)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface FieldFilteringManager {
|
|
2
|
+
/**
|
|
3
|
+
* Recursively dives into an object, filtering and redacting specified properties.
|
|
4
|
+
*/
|
|
5
|
+
filterFields<T>(data: T): Partial<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Filters and redacts specified properties from the url query.
|
|
8
|
+
*/
|
|
9
|
+
filterUrlFields(url: string): string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface FieldFilteringRule {
|
|
13
|
+
/**
|
|
14
|
+
* A string representing the property value in which to apply the rule.
|
|
15
|
+
*/
|
|
16
|
+
value: string;
|
|
17
|
+
/**
|
|
18
|
+
* A boolean dictating whether to apply the rule value with case sensitivity.
|
|
19
|
+
*/
|
|
20
|
+
caseSensitive: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* A string of value "filter" or "redact". Specify "filter" to remove the whole key and value,
|
|
23
|
+
* or "redact" to replace the value with the redaction text, leaving the key for context.
|
|
24
|
+
*/
|
|
25
|
+
type: 'filter' | 'redact';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The configuration object to be passed to the default FieldFilteringHandler.
|
|
30
|
+
*/
|
|
31
|
+
interface FieldFilteringManagerConfig {
|
|
32
|
+
/**
|
|
33
|
+
* An optional array of explicit object paths to properties to filter and/or redact. For example "account.users.token".
|
|
34
|
+
*/
|
|
35
|
+
paths?: FieldFilteringRule[];
|
|
36
|
+
/**
|
|
37
|
+
* An optional array of property names to filter and/or redact at any object depth. For example "token".
|
|
38
|
+
*/
|
|
39
|
+
properties?: FieldFilteringRule[];
|
|
40
|
+
/**
|
|
41
|
+
* An optional array of explicit object paths to properties to retain, overriding all other rules. For example "account.users.passwordHint".
|
|
42
|
+
*/
|
|
43
|
+
whitelistPaths?: Omit<FieldFilteringRule, 'type'>[];
|
|
44
|
+
/**
|
|
45
|
+
* An optional array of strings, all properties containing these strings will be filtered and/or redacted. For example, "password" would apply to "password", "oldPassword" if case-insensitive etc...
|
|
46
|
+
*/
|
|
47
|
+
includes?: FieldFilteringRule[];
|
|
48
|
+
/**
|
|
49
|
+
* A string in which to replace redacted properties in JSON objects, default of {@link defaultJsonRedactionText}
|
|
50
|
+
*/
|
|
51
|
+
jsonRedactionText?: string;
|
|
52
|
+
/**
|
|
53
|
+
* A string in which to replace redacted properties in url queries, default of {@link defaultUrlRedactionText}
|
|
54
|
+
*/
|
|
55
|
+
urlRedactionText?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare class FieldFilteringHandler implements FieldFilteringManager {
|
|
59
|
+
filterPaths: FieldFilteringRule[];
|
|
60
|
+
redactPaths: FieldFilteringRule[];
|
|
61
|
+
filterProperties: FieldFilteringRule[];
|
|
62
|
+
redactProperties: FieldFilteringRule[];
|
|
63
|
+
whitelistPaths: Omit<FieldFilteringRule, 'type'>[];
|
|
64
|
+
filterIncludes: FieldFilteringRule[];
|
|
65
|
+
redactIncludes: FieldFilteringRule[];
|
|
66
|
+
jsonRedactionText: string;
|
|
67
|
+
urlRedactionText: string;
|
|
68
|
+
private hasFilteringRules;
|
|
69
|
+
constructor(config: FieldFilteringManagerConfig);
|
|
70
|
+
filterFields<T>(data: T, currentPath?: string): Partial<T>;
|
|
71
|
+
private filterConditionMet;
|
|
72
|
+
private testFilterRules;
|
|
73
|
+
filterUrlFields(inputUrl: string): string;
|
|
74
|
+
private urlQueryKeyToObjectPath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare const defaultJsonRedactionText = "[REDACTED]";
|
|
78
|
+
declare const defaultUrlRedactionText = "REDACTED";
|
|
79
|
+
declare const defaultFilteringRules: FieldFilteringManagerConfig;
|
|
80
|
+
|
|
81
|
+
type BasicTypes = string | number | boolean;
|
|
82
|
+
type AcceptedQueryValueTypes = BasicTypes | AcceptedQueryValueTypes[] | {
|
|
83
|
+
[key: string]: AcceptedQueryValueTypes;
|
|
84
|
+
};
|
|
85
|
+
type AcceptedQueryTypes = {
|
|
86
|
+
[key: string]: AcceptedQueryValueTypes;
|
|
87
|
+
};
|
|
88
|
+
declare const normaliseUrl: (url: string) => string;
|
|
89
|
+
declare const generateQueryString: (query: AcceptedQueryTypes) => string;
|
|
90
|
+
declare const isValidUrl: (urlLike: string) => boolean;
|
|
91
|
+
|
|
92
|
+
declare const isFieldFilteringManager: (config?: FieldFilteringManager | FieldFilteringManagerConfig) => config is FieldFilteringManager;
|
|
93
|
+
|
|
94
|
+
type Format = 'tabular' | 'json';
|
|
95
|
+
/**
|
|
96
|
+
* A method to strigify tool output into a LLM friendly and optimised format.
|
|
97
|
+
*
|
|
98
|
+
* @param {unknown} args.data - The response of a tool's output, in the format of an object.
|
|
99
|
+
* @param {string} [args.title] - An optional string, the title or description to give the data for LLM context.
|
|
100
|
+
* @param {Format} [args.format] - An optional string of either "tabular" or "JSON" defining the format output, default "tabular". Choose "tabular" for chat contexts, "json" for coding
|
|
101
|
+
*
|
|
102
|
+
* @returns {string} The LLM optimised tool string output.
|
|
103
|
+
*/
|
|
104
|
+
declare const transformToolOutput: (args: {
|
|
105
|
+
data: any;
|
|
106
|
+
title?: string;
|
|
107
|
+
format?: Format;
|
|
108
|
+
}) => string;
|
|
109
|
+
|
|
110
|
+
declare const transformPropertyName: (propertyName: string) => string;
|
|
111
|
+
|
|
112
|
+
export { FieldFilteringHandler, type FieldFilteringManager, type FieldFilteringManagerConfig, type FieldFilteringRule, defaultFilteringRules, defaultJsonRedactionText, defaultUrlRedactionText, generateQueryString, isFieldFilteringManager, isValidUrl, normaliseUrl, transformPropertyName, transformToolOutput };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface FieldFilteringManager {
|
|
2
|
+
/**
|
|
3
|
+
* Recursively dives into an object, filtering and redacting specified properties.
|
|
4
|
+
*/
|
|
5
|
+
filterFields<T>(data: T): Partial<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Filters and redacts specified properties from the url query.
|
|
8
|
+
*/
|
|
9
|
+
filterUrlFields(url: string): string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface FieldFilteringRule {
|
|
13
|
+
/**
|
|
14
|
+
* A string representing the property value in which to apply the rule.
|
|
15
|
+
*/
|
|
16
|
+
value: string;
|
|
17
|
+
/**
|
|
18
|
+
* A boolean dictating whether to apply the rule value with case sensitivity.
|
|
19
|
+
*/
|
|
20
|
+
caseSensitive: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* A string of value "filter" or "redact". Specify "filter" to remove the whole key and value,
|
|
23
|
+
* or "redact" to replace the value with the redaction text, leaving the key for context.
|
|
24
|
+
*/
|
|
25
|
+
type: 'filter' | 'redact';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The configuration object to be passed to the default FieldFilteringHandler.
|
|
30
|
+
*/
|
|
31
|
+
interface FieldFilteringManagerConfig {
|
|
32
|
+
/**
|
|
33
|
+
* An optional array of explicit object paths to properties to filter and/or redact. For example "account.users.token".
|
|
34
|
+
*/
|
|
35
|
+
paths?: FieldFilteringRule[];
|
|
36
|
+
/**
|
|
37
|
+
* An optional array of property names to filter and/or redact at any object depth. For example "token".
|
|
38
|
+
*/
|
|
39
|
+
properties?: FieldFilteringRule[];
|
|
40
|
+
/**
|
|
41
|
+
* An optional array of explicit object paths to properties to retain, overriding all other rules. For example "account.users.passwordHint".
|
|
42
|
+
*/
|
|
43
|
+
whitelistPaths?: Omit<FieldFilteringRule, 'type'>[];
|
|
44
|
+
/**
|
|
45
|
+
* An optional array of strings, all properties containing these strings will be filtered and/or redacted. For example, "password" would apply to "password", "oldPassword" if case-insensitive etc...
|
|
46
|
+
*/
|
|
47
|
+
includes?: FieldFilteringRule[];
|
|
48
|
+
/**
|
|
49
|
+
* A string in which to replace redacted properties in JSON objects, default of {@link defaultJsonRedactionText}
|
|
50
|
+
*/
|
|
51
|
+
jsonRedactionText?: string;
|
|
52
|
+
/**
|
|
53
|
+
* A string in which to replace redacted properties in url queries, default of {@link defaultUrlRedactionText}
|
|
54
|
+
*/
|
|
55
|
+
urlRedactionText?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare class FieldFilteringHandler implements FieldFilteringManager {
|
|
59
|
+
filterPaths: FieldFilteringRule[];
|
|
60
|
+
redactPaths: FieldFilteringRule[];
|
|
61
|
+
filterProperties: FieldFilteringRule[];
|
|
62
|
+
redactProperties: FieldFilteringRule[];
|
|
63
|
+
whitelistPaths: Omit<FieldFilteringRule, 'type'>[];
|
|
64
|
+
filterIncludes: FieldFilteringRule[];
|
|
65
|
+
redactIncludes: FieldFilteringRule[];
|
|
66
|
+
jsonRedactionText: string;
|
|
67
|
+
urlRedactionText: string;
|
|
68
|
+
private hasFilteringRules;
|
|
69
|
+
constructor(config: FieldFilteringManagerConfig);
|
|
70
|
+
filterFields<T>(data: T, currentPath?: string): Partial<T>;
|
|
71
|
+
private filterConditionMet;
|
|
72
|
+
private testFilterRules;
|
|
73
|
+
filterUrlFields(inputUrl: string): string;
|
|
74
|
+
private urlQueryKeyToObjectPath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare const defaultJsonRedactionText = "[REDACTED]";
|
|
78
|
+
declare const defaultUrlRedactionText = "REDACTED";
|
|
79
|
+
declare const defaultFilteringRules: FieldFilteringManagerConfig;
|
|
80
|
+
|
|
81
|
+
type BasicTypes = string | number | boolean;
|
|
82
|
+
type AcceptedQueryValueTypes = BasicTypes | AcceptedQueryValueTypes[] | {
|
|
83
|
+
[key: string]: AcceptedQueryValueTypes;
|
|
84
|
+
};
|
|
85
|
+
type AcceptedQueryTypes = {
|
|
86
|
+
[key: string]: AcceptedQueryValueTypes;
|
|
87
|
+
};
|
|
88
|
+
declare const normaliseUrl: (url: string) => string;
|
|
89
|
+
declare const generateQueryString: (query: AcceptedQueryTypes) => string;
|
|
90
|
+
declare const isValidUrl: (urlLike: string) => boolean;
|
|
91
|
+
|
|
92
|
+
declare const isFieldFilteringManager: (config?: FieldFilteringManager | FieldFilteringManagerConfig) => config is FieldFilteringManager;
|
|
93
|
+
|
|
94
|
+
type Format = 'tabular' | 'json';
|
|
95
|
+
/**
|
|
96
|
+
* A method to strigify tool output into a LLM friendly and optimised format.
|
|
97
|
+
*
|
|
98
|
+
* @param {unknown} args.data - The response of a tool's output, in the format of an object.
|
|
99
|
+
* @param {string} [args.title] - An optional string, the title or description to give the data for LLM context.
|
|
100
|
+
* @param {Format} [args.format] - An optional string of either "tabular" or "JSON" defining the format output, default "tabular". Choose "tabular" for chat contexts, "json" for coding
|
|
101
|
+
*
|
|
102
|
+
* @returns {string} The LLM optimised tool string output.
|
|
103
|
+
*/
|
|
104
|
+
declare const transformToolOutput: (args: {
|
|
105
|
+
data: any;
|
|
106
|
+
title?: string;
|
|
107
|
+
format?: Format;
|
|
108
|
+
}) => string;
|
|
109
|
+
|
|
110
|
+
declare const transformPropertyName: (propertyName: string) => string;
|
|
111
|
+
|
|
112
|
+
export { FieldFilteringHandler, type FieldFilteringManager, type FieldFilteringManagerConfig, type FieldFilteringRule, defaultFilteringRules, defaultJsonRedactionText, defaultUrlRedactionText, generateQueryString, isFieldFilteringManager, isValidUrl, normaliseUrl, transformPropertyName, transformToolOutput };
|