@principles/core 1.177.1 → 1.177.3
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/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts +15 -0
- package/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts.map +1 -0
- package/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js +450 -0
- package/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js.map +1 -0
- package/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts +13 -0
- package/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts.map +1 -0
- package/dist/runtime-v2/feedback/__tests__/render-github-url.test.js +243 -0
- package/dist/runtime-v2/feedback/__tests__/render-github-url.test.js.map +1 -0
- package/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts +12 -0
- package/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts.map +1 -0
- package/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js +172 -0
- package/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js.map +1 -0
- package/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
- package/dist/runtime-v2/pain-signal-observability.js +9 -5
- package/dist/runtime-v2/pain-signal-observability.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redact Sensitive Tests — Feedback Pipeline Privacy Guards
|
|
3
|
+
*
|
|
4
|
+
* Tests the privacy-preserving redaction helpers used by the feedback pipeline.
|
|
5
|
+
* These functions handle sensitive data (tokens, paths, env vars) and must be
|
|
6
|
+
* thoroughly tested to prevent data leaks.
|
|
7
|
+
*
|
|
8
|
+
* ERR checklist:
|
|
9
|
+
* - ERR-001: no `as` casts on untrusted values
|
|
10
|
+
* - ERR-002: never throws; returns safe fallbacks
|
|
11
|
+
* - ERR-003: segment-exact key matching (no substring matches)
|
|
12
|
+
* - ERR-014/016: bounded output
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=redact-sensitive.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact-sensitive.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/redact-sensitive.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redact Sensitive Tests — Feedback Pipeline Privacy Guards
|
|
3
|
+
*
|
|
4
|
+
* Tests the privacy-preserving redaction helpers used by the feedback pipeline.
|
|
5
|
+
* These functions handle sensitive data (tokens, paths, env vars) and must be
|
|
6
|
+
* thoroughly tested to prevent data leaks.
|
|
7
|
+
*
|
|
8
|
+
* ERR checklist:
|
|
9
|
+
* - ERR-001: no `as` casts on untrusted values
|
|
10
|
+
* - ERR-002: never throws; returns safe fallbacks
|
|
11
|
+
* - ERR-003: segment-exact key matching (no substring matches)
|
|
12
|
+
* - ERR-014/016: bounded output
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect } from 'vitest';
|
|
15
|
+
import { redactAbsolutePaths, redactTokenLikeValues, redactEnvLikeValues, redactTelemetryString, redactStackTrace, redactSensitiveFields, REDACTED_PATH, REDACTED_VALUE, NO_STACK, } from '../redact-sensitive.js';
|
|
16
|
+
// ── redactAbsolutePaths ─────────────────────────────────────────────────────
|
|
17
|
+
describe('redactAbsolutePaths', () => {
|
|
18
|
+
it('redacts Windows absolute paths', () => {
|
|
19
|
+
const input = 'Error at C:\\Users\\alice\\project\\src\\index.ts:42';
|
|
20
|
+
const result = redactAbsolutePaths(input);
|
|
21
|
+
expect(result).toBe(`Error at ${REDACTED_PATH}:42`);
|
|
22
|
+
});
|
|
23
|
+
it('redacts multiple Windows paths', () => {
|
|
24
|
+
const input = 'Paths: C:\\foo\\bar and D:\\test\\file.txt';
|
|
25
|
+
const result = redactAbsolutePaths(input);
|
|
26
|
+
expect(result).toBe(`Paths: ${REDACTED_PATH} and ${REDACTED_PATH}`);
|
|
27
|
+
});
|
|
28
|
+
it('redacts POSIX absolute paths', () => {
|
|
29
|
+
const input = 'Error at /home/alice/project/src/index.ts:42';
|
|
30
|
+
const result = redactAbsolutePaths(input);
|
|
31
|
+
expect(result).toBe(`Error at ${REDACTED_PATH}:42`);
|
|
32
|
+
});
|
|
33
|
+
it('redacts /usr paths', () => {
|
|
34
|
+
const input = 'Config: /usr/local/bin/node';
|
|
35
|
+
const result = redactAbsolutePaths(input);
|
|
36
|
+
expect(result).toBe(`Config: ${REDACTED_PATH}`);
|
|
37
|
+
});
|
|
38
|
+
it('redacts /Users paths (macOS)', () => {
|
|
39
|
+
const input = 'File: /Users/wesley/Documents/test.txt';
|
|
40
|
+
const result = redactAbsolutePaths(input);
|
|
41
|
+
expect(result).toBe(`File: ${REDACTED_PATH}`);
|
|
42
|
+
});
|
|
43
|
+
it('preserves relative paths', () => {
|
|
44
|
+
const input = './src/index.ts and ../lib/utils.js';
|
|
45
|
+
const result = redactAbsolutePaths(input);
|
|
46
|
+
expect(result).toBe('./src/index.ts and ../lib/utils.js');
|
|
47
|
+
});
|
|
48
|
+
it('preserves URL paths', () => {
|
|
49
|
+
const input = 'https://example.com/path/to/resource';
|
|
50
|
+
const result = redactAbsolutePaths(input);
|
|
51
|
+
expect(result).toBe('https://example.com/path/to/resource');
|
|
52
|
+
});
|
|
53
|
+
it('returns non-string input unchanged', () => {
|
|
54
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
55
|
+
expect(redactAbsolutePaths(null)).toBe(null);
|
|
56
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
57
|
+
expect(redactAbsolutePaths(undefined)).toBe(undefined);
|
|
58
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
59
|
+
expect(redactAbsolutePaths(42)).toBe(42);
|
|
60
|
+
});
|
|
61
|
+
it('handles empty string', () => {
|
|
62
|
+
expect(redactAbsolutePaths('')).toBe('');
|
|
63
|
+
});
|
|
64
|
+
it('handles string without paths', () => {
|
|
65
|
+
expect(redactAbsolutePaths('no paths here')).toBe('no paths here');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
// ── redactTokenLikeValues ────────────────────────────────────────────────────
|
|
69
|
+
describe('redactTokenLikeValues', () => {
|
|
70
|
+
it('redacts OpenAI tokens (sk-)', () => {
|
|
71
|
+
const input = 'Using sk-proj-abc123def456ghi789jkl012mno345pqr678';
|
|
72
|
+
const result = redactTokenLikeValues(input);
|
|
73
|
+
expect(result).toBe(`Using ${REDACTED_VALUE}`);
|
|
74
|
+
});
|
|
75
|
+
it('redacts OpenAI ant tokens (sk-ant-)', () => {
|
|
76
|
+
const input = 'Key: sk-ant-api03-abc123def456ghi789jkl012mno345pqr678stu901vwx234yz';
|
|
77
|
+
const result = redactTokenLikeValues(input);
|
|
78
|
+
expect(result).toBe(`Key: ${REDACTED_VALUE}`);
|
|
79
|
+
});
|
|
80
|
+
it('redacts GitHub tokens (ghp_, gho_, ghu_, ghs_, ghr_)', () => {
|
|
81
|
+
const input = 'ghp_abc123def456ghi789jkl012mno345pqr678stu';
|
|
82
|
+
const result = redactTokenLikeValues(input);
|
|
83
|
+
expect(result).toBe(REDACTED_VALUE);
|
|
84
|
+
});
|
|
85
|
+
it('redacts Linear tokens (lin_api_)', () => {
|
|
86
|
+
const input = 'lin_api_abc123def456ghi789jkl012mno345pqr678stu';
|
|
87
|
+
const result = redactTokenLikeValues(input);
|
|
88
|
+
expect(result).toBe(REDACTED_VALUE);
|
|
89
|
+
});
|
|
90
|
+
it('redacts Authorization header values', () => {
|
|
91
|
+
const input = 'Authorization: Bearer secret-token-12345';
|
|
92
|
+
const result = redactTokenLikeValues(input);
|
|
93
|
+
expect(result).toBe(`Authorization: Bearer ${REDACTED_VALUE}`);
|
|
94
|
+
});
|
|
95
|
+
it('redacts Authorization header with quotes', () => {
|
|
96
|
+
const input = 'Authorization: "Basic dXNlcjpwYXNz"';
|
|
97
|
+
const result = redactTokenLikeValues(input);
|
|
98
|
+
expect(result).toContain(REDACTED_VALUE);
|
|
99
|
+
});
|
|
100
|
+
it('redacts generic key assignments', () => {
|
|
101
|
+
const input = 'api_key=secret123 token=abc456 password=pass789';
|
|
102
|
+
const result = redactTokenLikeValues(input);
|
|
103
|
+
expect(result).toBe(`api_key=${REDACTED_VALUE} token=${REDACTED_VALUE} password=${REDACTED_VALUE}`);
|
|
104
|
+
});
|
|
105
|
+
it('redacts Bearer tokens', () => {
|
|
106
|
+
const input = 'Bearer abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567';
|
|
107
|
+
const result = redactTokenLikeValues(input);
|
|
108
|
+
expect(result).toBe(REDACTED_VALUE);
|
|
109
|
+
});
|
|
110
|
+
it('preserves non-token strings', () => {
|
|
111
|
+
const input = 'normal text without tokens';
|
|
112
|
+
const result = redactTokenLikeValues(input);
|
|
113
|
+
expect(result).toBe('normal text without tokens');
|
|
114
|
+
});
|
|
115
|
+
it('returns non-string input unchanged', () => {
|
|
116
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
117
|
+
expect(redactTokenLikeValues(null)).toBe(null);
|
|
118
|
+
});
|
|
119
|
+
it('handles empty string', () => {
|
|
120
|
+
expect(redactTokenLikeValues('')).toBe('');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
// ── redactEnvLikeValues ──────────────────────────────────────────────────────
|
|
124
|
+
describe('redactEnvLikeValues', () => {
|
|
125
|
+
it('redacts KEY=value assignments', () => {
|
|
126
|
+
const input = 'API_KEY=secret123';
|
|
127
|
+
const result = redactEnvLikeValues(input);
|
|
128
|
+
expect(result).toBe(`API_KEY=${REDACTED_VALUE}`);
|
|
129
|
+
});
|
|
130
|
+
it('redacts KEY="value with spaces"', () => {
|
|
131
|
+
const input = 'SECRET="value with spaces"';
|
|
132
|
+
const result = redactEnvLikeValues(input);
|
|
133
|
+
expect(result).toBe(`SECRET=${REDACTED_VALUE}`);
|
|
134
|
+
});
|
|
135
|
+
it('redacts KEY=\'value\' (single quotes)', () => {
|
|
136
|
+
const input = 'TOKEN=\'abc123\'';
|
|
137
|
+
const result = redactEnvLikeValues(input);
|
|
138
|
+
expect(result).toBe(`TOKEN=${REDACTED_VALUE}`);
|
|
139
|
+
});
|
|
140
|
+
it('redacts multiple env assignments', () => {
|
|
141
|
+
const input = 'API_KEY=secret1 SECRET=secret2 TOKEN=secret3';
|
|
142
|
+
const result = redactEnvLikeValues(input);
|
|
143
|
+
expect(result).toBe(`API_KEY=${REDACTED_VALUE} SECRET=${REDACTED_VALUE} TOKEN=${REDACTED_VALUE}`);
|
|
144
|
+
});
|
|
145
|
+
it('preserves lowercase key assignments', () => {
|
|
146
|
+
const input = 'name=value';
|
|
147
|
+
const result = redactEnvLikeValues(input);
|
|
148
|
+
expect(result).toBe('name=value');
|
|
149
|
+
});
|
|
150
|
+
it('preserves short key names (< 3 chars)', () => {
|
|
151
|
+
const input = 'AB=value';
|
|
152
|
+
const result = redactEnvLikeValues(input);
|
|
153
|
+
expect(result).toBe('AB=value');
|
|
154
|
+
});
|
|
155
|
+
it('returns non-string input unchanged', () => {
|
|
156
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
157
|
+
expect(redactEnvLikeValues(null)).toBe(null);
|
|
158
|
+
});
|
|
159
|
+
it('handles empty string', () => {
|
|
160
|
+
expect(redactEnvLikeValues('')).toBe('');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
// ── redactTelemetryString ────────────────────────────────────────────────────
|
|
164
|
+
describe('redactTelemetryString', () => {
|
|
165
|
+
it('combines all redactors', () => {
|
|
166
|
+
const input = 'Path: /home/alice/secret Token: sk-abc123def456ghi789jkl012mno345pqr678 Env: API_KEY=secret';
|
|
167
|
+
const result = redactTelemetryString(input);
|
|
168
|
+
expect(result).toBe(`Path: ${REDACTED_PATH} Token=${REDACTED_VALUE} Env: API_KEY=${REDACTED_VALUE}`);
|
|
169
|
+
});
|
|
170
|
+
it('returns non-string input unchanged', () => {
|
|
171
|
+
expect(redactTelemetryString(null)).toBe(null);
|
|
172
|
+
expect(redactTelemetryString(undefined)).toBe(undefined);
|
|
173
|
+
expect(redactTelemetryString(42)).toBe(42);
|
|
174
|
+
});
|
|
175
|
+
it('handles empty string', () => {
|
|
176
|
+
expect(redactTelemetryString('')).toBe('');
|
|
177
|
+
});
|
|
178
|
+
it('handles string without sensitive data', () => {
|
|
179
|
+
expect(redactTelemetryString('normal text')).toBe('normal text');
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
// ── redactStackTrace ──────────────────────────────────────────────────────────
|
|
183
|
+
describe('redactStackTrace', () => {
|
|
184
|
+
it('returns NO_STACK for empty string', () => {
|
|
185
|
+
expect(redactStackTrace('')).toBe(NO_STACK);
|
|
186
|
+
});
|
|
187
|
+
it('returns NO_STACK for non-string', () => {
|
|
188
|
+
// @ts-expect-error - testing non-string input for runtime type guard
|
|
189
|
+
expect(redactStackTrace(null)).toBe(NO_STACK);
|
|
190
|
+
});
|
|
191
|
+
it('preserves error name and first 3 frames by default', () => {
|
|
192
|
+
const stack = `Error: Something went wrong
|
|
193
|
+
at foo (/home/alice/project/src/index.ts:10)
|
|
194
|
+
at bar (/home/alice/project/src/utils.ts:20)
|
|
195
|
+
at baz (/home/alice/project/src/main.ts:30)
|
|
196
|
+
at qux (/home/alice/project/src/extra.ts:40)`;
|
|
197
|
+
const result = redactStackTrace(stack);
|
|
198
|
+
expect(result).toContain('Error: Something went wrong');
|
|
199
|
+
expect(result).toContain(REDACTED_PATH);
|
|
200
|
+
expect(result).not.toContain('/home/alice');
|
|
201
|
+
// Should only have 3 frames
|
|
202
|
+
const frameCount = (result.match(/at\s+/g) || []).length;
|
|
203
|
+
expect(frameCount).toBe(3);
|
|
204
|
+
});
|
|
205
|
+
it('respects custom maxFrames', () => {
|
|
206
|
+
const stack = `Error: Test
|
|
207
|
+
at frame1 (/usr/local/bin/test.ts:1)
|
|
208
|
+
at frame2 (/usr/local/bin/test.ts:2)
|
|
209
|
+
at frame3 (/usr/local/bin/test.ts:3)
|
|
210
|
+
at frame4 (/usr/local/bin/test.ts:4)`;
|
|
211
|
+
const result = redactStackTrace(stack, 2);
|
|
212
|
+
const frameCount = (result.match(/at\s+/g) || []).length;
|
|
213
|
+
expect(frameCount).toBe(2);
|
|
214
|
+
});
|
|
215
|
+
it('redacts Windows paths in stack frames', () => {
|
|
216
|
+
const stack = `Error: Test
|
|
217
|
+
at foo (C:\\Users\\alice\\project\\src\\index.ts:10)`;
|
|
218
|
+
const result = redactStackTrace(stack);
|
|
219
|
+
expect(result).toContain(REDACTED_PATH);
|
|
220
|
+
expect(result).not.toContain('C:\\Users');
|
|
221
|
+
});
|
|
222
|
+
it('handles stack with only error name', () => {
|
|
223
|
+
const stack = 'Error: Something went wrong';
|
|
224
|
+
const result = redactStackTrace(stack);
|
|
225
|
+
expect(result).toBe('Error: Something went wrong');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
// ── redactSensitiveFields ────────────────────────────────────────────────────
|
|
229
|
+
describe('redactSensitiveFields', () => {
|
|
230
|
+
it('returns error for null input', () => {
|
|
231
|
+
const result = redactSensitiveFields(null);
|
|
232
|
+
expect(result.ok).toBe(false);
|
|
233
|
+
if (!result.ok) {
|
|
234
|
+
expect(result.error).toContain('null');
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
it('returns error for undefined input', () => {
|
|
238
|
+
const result = redactSensitiveFields(undefined);
|
|
239
|
+
expect(result.ok).toBe(false);
|
|
240
|
+
if (!result.ok) {
|
|
241
|
+
expect(result.error).toContain('undefined');
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
it('returns error for primitive input', () => {
|
|
245
|
+
const result = redactSensitiveFields('string');
|
|
246
|
+
expect(result.ok).toBe(false);
|
|
247
|
+
if (!result.ok) {
|
|
248
|
+
expect(result.error).toContain('must be an object or array');
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
it('returns error for number input', () => {
|
|
252
|
+
const result = redactSensitiveFields(42);
|
|
253
|
+
expect(result.ok).toBe(false);
|
|
254
|
+
if (!result.ok) {
|
|
255
|
+
expect(result.error).toContain('must be an object or array');
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
it('redacts password field', () => {
|
|
259
|
+
const obj = { username: 'alice', password: 'secret123' };
|
|
260
|
+
const result = redactSensitiveFields(obj);
|
|
261
|
+
expect(result.ok).toBe(true);
|
|
262
|
+
if (result.ok) {
|
|
263
|
+
expect(result.value).toEqual({ username: 'alice', password: REDACTED_VALUE });
|
|
264
|
+
expect(result.notes).toContain('field "password" redacted');
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
it('redacts token field', () => {
|
|
268
|
+
const obj = { id: 1, token: 'abc123' };
|
|
269
|
+
const result = redactSensitiveFields(obj);
|
|
270
|
+
expect(result.ok).toBe(true);
|
|
271
|
+
if (result.ok) {
|
|
272
|
+
expect(result.value).toEqual({ id: 1, token: REDACTED_VALUE });
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
it('redacts api_key field', () => {
|
|
276
|
+
const obj = { name: 'test', api_key: 'key123' };
|
|
277
|
+
const result = redactSensitiveFields(obj);
|
|
278
|
+
expect(result.ok).toBe(true);
|
|
279
|
+
if (result.ok) {
|
|
280
|
+
expect(result.value).toEqual({ name: 'test', api_key: REDACTED_VALUE });
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
it('redacts authorization field', () => {
|
|
284
|
+
const obj = { method: 'GET', authorization: 'Bearer secret' };
|
|
285
|
+
const result = redactSensitiveFields(obj);
|
|
286
|
+
expect(result.ok).toBe(true);
|
|
287
|
+
if (result.ok) {
|
|
288
|
+
expect(result.value).toEqual({ method: 'GET', authorization: REDACTED_VALUE });
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
it('redacts auth_token field', () => {
|
|
292
|
+
const obj = { user: 'bob', auth_token: 'token123' };
|
|
293
|
+
const result = redactSensitiveFields(obj);
|
|
294
|
+
expect(result.ok).toBe(true);
|
|
295
|
+
if (result.ok) {
|
|
296
|
+
expect(result.value).toEqual({ user: 'bob', auth_token: REDACTED_VALUE });
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
it('redacts secret field', () => {
|
|
300
|
+
const obj = { config: 'value', secret: 'hidden' };
|
|
301
|
+
const result = redactSensitiveFields(obj);
|
|
302
|
+
expect(result.ok).toBe(true);
|
|
303
|
+
if (result.ok) {
|
|
304
|
+
expect(result.value).toEqual({ config: 'value', secret: REDACTED_VALUE });
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
it('redacts credentials field', () => {
|
|
308
|
+
const obj = { service: 'api', credentials: { user: 'admin', pass: '123' } };
|
|
309
|
+
const result = redactSensitiveFields(obj);
|
|
310
|
+
expect(result.ok).toBe(true);
|
|
311
|
+
if (result.ok) {
|
|
312
|
+
expect(result.value.credentials).toBe(REDACTED_VALUE);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
it('redacts private_key field', () => {
|
|
316
|
+
const obj = { id: 'key1', private_key: '-----BEGIN RSA PRIVATE KEY-----' };
|
|
317
|
+
const result = redactSensitiveFields(obj);
|
|
318
|
+
expect(result.ok).toBe(true);
|
|
319
|
+
if (result.ok) {
|
|
320
|
+
expect(result.value).toEqual({ id: 'key1', private_key: REDACTED_VALUE });
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
it('redacts nested sensitive fields', () => {
|
|
324
|
+
const obj = { config: { database: { password: 'dbpass' } } };
|
|
325
|
+
const result = redactSensitiveFields(obj);
|
|
326
|
+
expect(result.ok).toBe(true);
|
|
327
|
+
if (result.ok) {
|
|
328
|
+
const config = result.value.config;
|
|
329
|
+
const db = config.database;
|
|
330
|
+
expect(db.password).toBe(REDACTED_VALUE);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
it('handles arrays', () => {
|
|
334
|
+
const arr = [{ user: 'alice', password: 'pass1' }, { user: 'bob', password: 'pass2' }];
|
|
335
|
+
const result = redactSensitiveFields(arr);
|
|
336
|
+
expect(result.ok).toBe(true);
|
|
337
|
+
if (result.ok) {
|
|
338
|
+
const value = result.value;
|
|
339
|
+
expect(value[0]?.password).toBe(REDACTED_VALUE);
|
|
340
|
+
expect(value[1]?.password).toBe(REDACTED_VALUE);
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
it('handles circular references', () => {
|
|
344
|
+
const obj = { name: 'test' };
|
|
345
|
+
obj.self = obj;
|
|
346
|
+
const result = redactSensitiveFields(obj);
|
|
347
|
+
expect(result.ok).toBe(true);
|
|
348
|
+
if (result.ok) {
|
|
349
|
+
expect(result.value.self).toBe('<circular>');
|
|
350
|
+
expect(result.notes.some(n => n.includes('circular'))).toBe(true);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
it('handles deep nesting (depth limit)', () => {
|
|
354
|
+
const deep = { level1: { level2: { level3: { level4: { level5: { level6: { level7: 'deep' } } } } } } };
|
|
355
|
+
const result = redactSensitiveFields(deep);
|
|
356
|
+
expect(result.ok).toBe(true);
|
|
357
|
+
if (result.ok) {
|
|
358
|
+
// Should hit depth limit at level 6
|
|
359
|
+
const value = result.value;
|
|
360
|
+
expect(value).toBeDefined();
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
it('truncates long strings', () => {
|
|
364
|
+
const longString = 'a'.repeat(3000);
|
|
365
|
+
const obj = { data: longString };
|
|
366
|
+
const result = redactSensitiveFields(obj);
|
|
367
|
+
expect(result.ok).toBe(true);
|
|
368
|
+
if (result.ok) {
|
|
369
|
+
const value = result.value.data;
|
|
370
|
+
expect(value.length).toBeLessThanOrEqual(2001); // 2000 + '…'
|
|
371
|
+
expect(value.endsWith('…')).toBe(true);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
it('redacts paths in string values', () => {
|
|
375
|
+
const obj = { cwd: '/home/alice/project', message: 'Error at /usr/local/bin' };
|
|
376
|
+
const result = redactSensitiveFields(obj);
|
|
377
|
+
expect(result.ok).toBe(true);
|
|
378
|
+
if (result.ok) {
|
|
379
|
+
const value = result.value;
|
|
380
|
+
expect(value.cwd).toBe(REDACTED_PATH);
|
|
381
|
+
expect(value.message.includes(REDACTED_PATH)).toBe(true);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
it('redacts tokens in string values', () => {
|
|
385
|
+
const obj = { buildId: 'sk-abc123def456ghi789jkl012mno345pqr678' };
|
|
386
|
+
const result = redactSensitiveFields(obj);
|
|
387
|
+
expect(result.ok).toBe(true);
|
|
388
|
+
if (result.ok) {
|
|
389
|
+
const value = result.value;
|
|
390
|
+
expect(value.buildId).toBe(REDACTED_VALUE);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
it('preserves non-sensitive fields', () => {
|
|
394
|
+
const obj = { name: 'test', count: 42, enabled: true, data: null };
|
|
395
|
+
const result = redactSensitiveFields(obj);
|
|
396
|
+
expect(result.ok).toBe(true);
|
|
397
|
+
if (result.ok) {
|
|
398
|
+
expect(result.value).toEqual({ name: 'test', count: 42, enabled: true, data: null });
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
it('handles BigInt values', () => {
|
|
402
|
+
const obj = { big: BigInt('12345678901234567890') };
|
|
403
|
+
const result = redactSensitiveFields(obj);
|
|
404
|
+
expect(result.ok).toBe(true);
|
|
405
|
+
if (result.ok) {
|
|
406
|
+
const value = result.value.big;
|
|
407
|
+
expect(value).toContain('<bigint:');
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
// ERR-003: segment-exact matching (no substring matches)
|
|
411
|
+
it('does NOT redact "author" (substring of "auth")', () => {
|
|
412
|
+
const obj = { author: 'John Doe', auth: 'secret' };
|
|
413
|
+
const result = redactSensitiveFields(obj);
|
|
414
|
+
expect(result.ok).toBe(true);
|
|
415
|
+
if (result.ok) {
|
|
416
|
+
const value = result.value;
|
|
417
|
+
expect(value.author).toBe('John Doe'); // NOT redacted
|
|
418
|
+
expect(value.auth).toBe(REDACTED_VALUE); // redacted
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
it('does NOT redact "keynote" (substring of "key")', () => {
|
|
422
|
+
const obj = { keynote: 'presentation', key: 'secret' };
|
|
423
|
+
const result = redactSensitiveFields(obj);
|
|
424
|
+
expect(result.ok).toBe(true);
|
|
425
|
+
if (result.ok) {
|
|
426
|
+
const value = result.value;
|
|
427
|
+
expect(value.keynote).toBe('presentation'); // NOT redacted
|
|
428
|
+
expect(value.key).toBe(REDACTED_VALUE); // redacted
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
it('redacts composite key names like "github_token"', () => {
|
|
432
|
+
const obj = { github_token: 'ghp_abc123' };
|
|
433
|
+
const result = redactSensitiveFields(obj);
|
|
434
|
+
expect(result.ok).toBe(true);
|
|
435
|
+
if (result.ok) {
|
|
436
|
+
const value = result.value;
|
|
437
|
+
expect(value.github_token).toBe(REDACTED_VALUE);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
it('redacts composite key names like "db_password"', () => {
|
|
441
|
+
const obj = { db_password: 'pass123' };
|
|
442
|
+
const result = redactSensitiveFields(obj);
|
|
443
|
+
expect(result.ok).toBe(true);
|
|
444
|
+
if (result.ok) {
|
|
445
|
+
const value = result.value;
|
|
446
|
+
expect(value.db_password).toBe(REDACTED_VALUE);
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
//# sourceMappingURL=redact-sensitive.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact-sensitive.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/redact-sensitive.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render GitHub URL Tests — Feedback Pipeline URL Builder
|
|
3
|
+
*
|
|
4
|
+
* Tests the GitHub issue draft URL builder with privacy-preserving redaction.
|
|
5
|
+
* This function is used to create feedback submission URLs.
|
|
6
|
+
*
|
|
7
|
+
* ERR checklist:
|
|
8
|
+
* - ERR-001/005: no `as FeedbackType` cast; use isFeedbackType validator
|
|
9
|
+
* - ERR-009/010: fail loud on invalid input
|
|
10
|
+
* - ERR-014/016: bounded body (MAX_URL_BODY_LENGTH)
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=render-github-url.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-github-url.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/render-github-url.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render GitHub URL Tests — Feedback Pipeline URL Builder
|
|
3
|
+
*
|
|
4
|
+
* Tests the GitHub issue draft URL builder with privacy-preserving redaction.
|
|
5
|
+
* This function is used to create feedback submission URLs.
|
|
6
|
+
*
|
|
7
|
+
* ERR checklist:
|
|
8
|
+
* - ERR-001/005: no `as FeedbackType` cast; use isFeedbackType validator
|
|
9
|
+
* - ERR-009/010: fail loud on invalid input
|
|
10
|
+
* - ERR-014/016: bounded body (MAX_URL_BODY_LENGTH)
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect } from 'vitest';
|
|
13
|
+
import { buildGitHubIssueDraftUrl, MAX_URL_BODY_LENGTH, GITHUB_REPO, } from '../render-github-url.js';
|
|
14
|
+
describe('buildGitHubIssueDraftUrl', () => {
|
|
15
|
+
it('builds valid URL for bug feedback', () => {
|
|
16
|
+
const result = buildGitHubIssueDraftUrl('Test bug', 'bug', 'Short summary');
|
|
17
|
+
expect(result.ok).toBe(true);
|
|
18
|
+
if (result.ok) {
|
|
19
|
+
expect(result.url).toContain('github.com');
|
|
20
|
+
expect(result.url).toContain(GITHUB_REPO);
|
|
21
|
+
expect(result.url).toContain('/issues/new');
|
|
22
|
+
expect(result.url).toContain('title=');
|
|
23
|
+
// URL-encoded version of [bug]
|
|
24
|
+
expect(result.url).toContain('%5Bbug%5D');
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
it('builds valid URL for confusing feedback', () => {
|
|
28
|
+
const result = buildGitHubIssueDraftUrl('Confusing message', 'confusing', 'Summary');
|
|
29
|
+
expect(result.ok).toBe(true);
|
|
30
|
+
if (result.ok) {
|
|
31
|
+
expect(result.url).toContain('%5Bconfusing%5D');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
it('builds valid URL for privacy_concern feedback', () => {
|
|
35
|
+
const result = buildGitHubIssueDraftUrl('Privacy issue', 'privacy_concern', 'Summary');
|
|
36
|
+
expect(result.ok).toBe(true);
|
|
37
|
+
if (result.ok) {
|
|
38
|
+
expect(result.url).toContain('%5Bprivacy_concern%5D');
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
it('builds valid URL for feature_request feedback', () => {
|
|
42
|
+
const result = buildGitHubIssueDraftUrl('New feature', 'feature_request', 'Summary');
|
|
43
|
+
expect(result.ok).toBe(true);
|
|
44
|
+
if (result.ok) {
|
|
45
|
+
expect(result.url).toContain('%5Bfeature_request%5D');
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
it('builds valid URL for other feedback', () => {
|
|
49
|
+
const result = buildGitHubIssueDraftUrl('General feedback', 'other', 'Summary');
|
|
50
|
+
expect(result.ok).toBe(true);
|
|
51
|
+
if (result.ok) {
|
|
52
|
+
expect(result.url).toContain('%5Bother%5D');
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
it('returns error for invalid feedback type', () => {
|
|
56
|
+
const result = buildGitHubIssueDraftUrl('Title', 'invalid_type', 'Summary');
|
|
57
|
+
expect(result.ok).toBe(false);
|
|
58
|
+
if (!result.ok) {
|
|
59
|
+
expect(result.error).toContain('invalid feedback type');
|
|
60
|
+
expect(result.nextAction).toContain('FeedbackType');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
it('returns error for non-string title', () => {
|
|
64
|
+
// @ts-expect-error - testing non-string title for runtime validation
|
|
65
|
+
const result = buildGitHubIssueDraftUrl(null, 'bug', 'Summary');
|
|
66
|
+
expect(result.ok).toBe(false);
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
expect(result.error).toContain('title must be a string');
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
it('returns error for non-string shortSummary', () => {
|
|
72
|
+
// @ts-expect-error - testing non-string shortSummary for runtime validation
|
|
73
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', null);
|
|
74
|
+
expect(result.ok).toBe(false);
|
|
75
|
+
if (!result.ok) {
|
|
76
|
+
expect(result.error).toContain('shortSummary must be a string');
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
it('redacts tokens in title', () => {
|
|
80
|
+
const result = buildGitHubIssueDraftUrl('Bug with sk-abc123def456ghi789jkl012mno345pqr678', 'bug', 'Summary');
|
|
81
|
+
expect(result.ok).toBe(true);
|
|
82
|
+
if (result.ok) {
|
|
83
|
+
// URL-encoded version of [REDACTED]
|
|
84
|
+
expect(result.url).toContain('%5BREDACTED%5D');
|
|
85
|
+
expect(result.url).not.toContain('sk-abc123');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
it('redacts paths in title', () => {
|
|
89
|
+
const result = buildGitHubIssueDraftUrl('Bug at /home/alice/project', 'bug', 'Summary');
|
|
90
|
+
expect(result.ok).toBe(true);
|
|
91
|
+
if (result.ok) {
|
|
92
|
+
// URL-encoded version of <redacted-path>
|
|
93
|
+
expect(result.url).toContain('%3Credacted-path%3E');
|
|
94
|
+
expect(result.url).not.toContain('/home/alice');
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
it('redacts env vars in title', () => {
|
|
98
|
+
const result = buildGitHubIssueDraftUrl('Bug with API_KEY=secret123', 'bug', 'Summary');
|
|
99
|
+
expect(result.ok).toBe(true);
|
|
100
|
+
if (result.ok) {
|
|
101
|
+
// URL-encoded version of [REDACTED]
|
|
102
|
+
expect(result.url).toContain('%5BREDACTED%5D');
|
|
103
|
+
expect(result.url).not.toContain('secret123');
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
it('redacts tokens in shortSummary', () => {
|
|
107
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', 'Summary with sk-abc123def456ghi789jkl012mno345pqr678');
|
|
108
|
+
expect(result.ok).toBe(true);
|
|
109
|
+
if (result.ok) {
|
|
110
|
+
// URL-encoded version of [REDACTED]
|
|
111
|
+
expect(result.url).toContain('%5BREDACTED%5D');
|
|
112
|
+
expect(result.url).not.toContain('sk-abc123');
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
it('truncates title to 200 chars', () => {
|
|
116
|
+
const longTitle = 'a'.repeat(300);
|
|
117
|
+
const result = buildGitHubIssueDraftUrl(longTitle, 'bug', 'Summary');
|
|
118
|
+
expect(result.ok).toBe(true);
|
|
119
|
+
if (result.ok) {
|
|
120
|
+
const decodedTitle = decodeURIComponent(result.url.split('title=')[1]?.split('&')[0] ?? '');
|
|
121
|
+
// [bug] (6 chars) + space (1 char) + 200 chars = 207 chars
|
|
122
|
+
expect(decodedTitle.length).toBeLessThanOrEqual(207);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it('truncates body to MAX_URL_BODY_LENGTH', () => {
|
|
126
|
+
const longSummary = 'a'.repeat(1000);
|
|
127
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', longSummary);
|
|
128
|
+
expect(result.ok).toBe(true);
|
|
129
|
+
if (result.ok) {
|
|
130
|
+
const decodedBody = decodeURIComponent(result.url.split('body=')[1] ?? '');
|
|
131
|
+
expect(decodedBody.length).toBeLessThanOrEqual(MAX_URL_BODY_LENGTH);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
it('URL-encodes title correctly', () => {
|
|
135
|
+
const result = buildGitHubIssueDraftUrl('Bug: test & more', 'bug', 'Summary');
|
|
136
|
+
expect(result.ok).toBe(true);
|
|
137
|
+
if (result.ok) {
|
|
138
|
+
// Check that special characters are encoded
|
|
139
|
+
expect(result.url).not.toContain('Bug: test & more');
|
|
140
|
+
// Check that colon and ampersand are encoded
|
|
141
|
+
expect(result.url).toContain('%3A'); // colon
|
|
142
|
+
expect(result.url).toContain('%26'); // ampersand
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
it('URL-encodes body correctly', () => {
|
|
146
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', 'Summary with\nnewlines');
|
|
147
|
+
expect(result.ok).toBe(true);
|
|
148
|
+
if (result.ok) {
|
|
149
|
+
// Newlines should be encoded as %0A
|
|
150
|
+
expect(result.url).toContain('%0A');
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
it('handles empty title', () => {
|
|
154
|
+
const result = buildGitHubIssueDraftUrl('', 'bug', 'Summary');
|
|
155
|
+
expect(result.ok).toBe(true);
|
|
156
|
+
if (result.ok) {
|
|
157
|
+
// URL-encoded version of [bug]
|
|
158
|
+
expect(result.url).toContain('%5Bbug%5D');
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
it('handles empty shortSummary', () => {
|
|
162
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', '');
|
|
163
|
+
expect(result.ok).toBe(true);
|
|
164
|
+
if (result.ok) {
|
|
165
|
+
expect(result.url).toContain('body=');
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
it('handles special characters in title', () => {
|
|
169
|
+
const result = buildGitHubIssueDraftUrl('Bug <script>alert(1)</script>', 'bug', 'Summary');
|
|
170
|
+
expect(result.ok).toBe(true);
|
|
171
|
+
if (result.ok) {
|
|
172
|
+
// Should be URL-encoded, not raw HTML
|
|
173
|
+
expect(result.url).not.toContain('<script>');
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
it('handles unicode in title', () => {
|
|
177
|
+
const result = buildGitHubIssueDraftUrl('Bug 测试 🎉', 'bug', 'Summary');
|
|
178
|
+
expect(result.ok).toBe(true);
|
|
179
|
+
if (result.ok) {
|
|
180
|
+
expect(result.url).toBeDefined();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
it('handles unicode in shortSummary', () => {
|
|
184
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', 'Summary 测试 🎉');
|
|
185
|
+
expect(result.ok).toBe(true);
|
|
186
|
+
if (result.ok) {
|
|
187
|
+
expect(result.url).toBeDefined();
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
it('constructs correct URL format', () => {
|
|
191
|
+
const result = buildGitHubIssueDraftUrl('Test', 'bug', 'Summary');
|
|
192
|
+
expect(result.ok).toBe(true);
|
|
193
|
+
if (result.ok) {
|
|
194
|
+
const url = result.url;
|
|
195
|
+
expect(url.startsWith('https://github.com/')).toBe(true);
|
|
196
|
+
expect(url).toContain(`${GITHUB_REPO}/issues/new`);
|
|
197
|
+
expect(url).toMatch(/title=[^&]+/);
|
|
198
|
+
expect(url).toMatch(/body=.+/);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
it('preserves markdown structure in body', () => {
|
|
202
|
+
const result = buildGitHubIssueDraftUrl('Title', 'bug', '## Header\n\n- Item 1\n- Item 2');
|
|
203
|
+
expect(result.ok).toBe(true);
|
|
204
|
+
if (result.ok) {
|
|
205
|
+
const decodedBody = decodeURIComponent(result.url.split('body=')[1] ?? '');
|
|
206
|
+
expect(decodedBody).toContain('## Header');
|
|
207
|
+
expect(decodedBody).toContain('- Item 1');
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
it('handles all valid feedback types', () => {
|
|
211
|
+
const types = ['bug', 'confusing', 'privacy_concern', 'feature_request', 'other'];
|
|
212
|
+
for (const type of types) {
|
|
213
|
+
const result = buildGitHubIssueDraftUrl('Title', type, 'Summary');
|
|
214
|
+
expect(result.ok).toBe(true);
|
|
215
|
+
if (result.ok) {
|
|
216
|
+
// URL-encoded version of [type]
|
|
217
|
+
expect(result.url).toContain(`%5B${encodeURIComponent(type)}%5D`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
it('returns error for number feedback type', () => {
|
|
222
|
+
const result = buildGitHubIssueDraftUrl('Title', 42, 'Summary');
|
|
223
|
+
expect(result.ok).toBe(false);
|
|
224
|
+
if (!result.ok) {
|
|
225
|
+
expect(result.error).toContain('invalid feedback type');
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
it('returns error for object feedback type', () => {
|
|
229
|
+
const result = buildGitHubIssueDraftUrl('Title', {}, 'Summary');
|
|
230
|
+
expect(result.ok).toBe(false);
|
|
231
|
+
if (!result.ok) {
|
|
232
|
+
expect(result.error).toContain('invalid feedback type');
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
it('returns error for undefined feedback type', () => {
|
|
236
|
+
const result = buildGitHubIssueDraftUrl('Title', undefined, 'Summary');
|
|
237
|
+
expect(result.ok).toBe(false);
|
|
238
|
+
if (!result.ok) {
|
|
239
|
+
expect(result.error).toContain('invalid feedback type');
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=render-github-url.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-github-url.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/render-github-url.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAEjC,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,MAAM,GAAG,wBAAwB,CAAC,UAAU,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACvC,+BAA+B;YAC/B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,wBAAwB,CAAC,mBAAmB,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACrF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,wBAAwB,CAAC,eAAe,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;QACvF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,wBAAwB,CAAC,aAAa,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;QACrF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,wBAAwB,CAAC,kBAAkB,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACxD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,qEAAqE;QACrE,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,4EAA4E;QAC5E,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,wBAAwB,CAAC,kDAAkD,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC9G,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,oCAAoC;YACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,MAAM,GAAG,wBAAwB,CAAC,4BAA4B,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACxF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,yCAAyC;YACzC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,wBAAwB,CAAC,4BAA4B,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACxF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,oCAAoC;YACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,sDAAsD,CAAC,CAAC;QAChH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,oCAAoC;YACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5F,2DAA2D;YAC3D,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,wBAAwB,CAAC,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,4CAA4C;YAC5C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YACrD,6CAA6C;YAC7C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;YAC7C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,oCAAoC;YACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,MAAM,GAAG,wBAAwB,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,+BAA+B;YAC/B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,wBAAwB,CAAC,+BAA+B,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3F,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,sCAAsC;YACtC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,MAAM,GAAG,wBAAwB,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,WAAW,aAAa,CAAC,CAAC;YACnD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,iCAAiC,CAAC,CAAC;QAC3F,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAClF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YAClE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACd,gCAAgC;gBAChC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe Stringify Tests — Feedback Pipeline Preview Helpers
|
|
3
|
+
*
|
|
4
|
+
* Tests the BigInt-safe + circular-ref-safe JSON-style stringifier.
|
|
5
|
+
* This function is used to safely preview values in feedback reports.
|
|
6
|
+
*
|
|
7
|
+
* ERR checklist:
|
|
8
|
+
* - ERR-017: BigInt-safe + circular-ref-safe
|
|
9
|
+
* - ERR-014/016: bounded output (max 2000 chars)
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=safe-stringify.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-stringify.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/safe-stringify.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe Stringify Tests — Feedback Pipeline Preview Helpers
|
|
3
|
+
*
|
|
4
|
+
* Tests the BigInt-safe + circular-ref-safe JSON-style stringifier.
|
|
5
|
+
* This function is used to safely preview values in feedback reports.
|
|
6
|
+
*
|
|
7
|
+
* ERR checklist:
|
|
8
|
+
* - ERR-017: BigInt-safe + circular-ref-safe
|
|
9
|
+
* - ERR-014/016: bounded output (max 2000 chars)
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect } from 'vitest';
|
|
12
|
+
import { safeStringifyPreview } from '../safe-stringify.js';
|
|
13
|
+
describe('safeStringifyPreview', () => {
|
|
14
|
+
it('stringifies primitive values', () => {
|
|
15
|
+
expect(safeStringifyPreview('hello')).toBe('"hello"');
|
|
16
|
+
expect(safeStringifyPreview(42)).toBe('42');
|
|
17
|
+
expect(safeStringifyPreview(true)).toBe('true');
|
|
18
|
+
expect(safeStringifyPreview(false)).toBe('false');
|
|
19
|
+
expect(safeStringifyPreview(null)).toBe('null');
|
|
20
|
+
expect(safeStringifyPreview(undefined)).toBe('undefined');
|
|
21
|
+
});
|
|
22
|
+
it('stringifies simple objects', () => {
|
|
23
|
+
const obj = { name: 'test', count: 10 };
|
|
24
|
+
const result = safeStringifyPreview(obj);
|
|
25
|
+
expect(result).toBe('{"name":"test","count":10}');
|
|
26
|
+
});
|
|
27
|
+
it('stringifies arrays', () => {
|
|
28
|
+
const arr = [1, 2, 3];
|
|
29
|
+
const result = safeStringifyPreview(arr);
|
|
30
|
+
expect(result).toBe('[1,2,3]');
|
|
31
|
+
});
|
|
32
|
+
it('handles BigInt values', () => {
|
|
33
|
+
const obj = { big: BigInt('12345678901234567890') };
|
|
34
|
+
const result = safeStringifyPreview(obj);
|
|
35
|
+
expect(result).toContain('<bigint:');
|
|
36
|
+
expect(result).toContain('12345678901234567890');
|
|
37
|
+
});
|
|
38
|
+
it('handles circular references', () => {
|
|
39
|
+
const obj = { name: 'test' };
|
|
40
|
+
obj.self = obj;
|
|
41
|
+
const result = safeStringifyPreview(obj);
|
|
42
|
+
expect(result).toContain('<circular>');
|
|
43
|
+
});
|
|
44
|
+
it('handles circular references in arrays', () => {
|
|
45
|
+
const arr = [1, 2];
|
|
46
|
+
arr.push(arr);
|
|
47
|
+
const result = safeStringifyPreview(arr);
|
|
48
|
+
expect(result).toContain('<circular>');
|
|
49
|
+
});
|
|
50
|
+
it('handles nested circular references', () => {
|
|
51
|
+
const inner = { value: 'inner' };
|
|
52
|
+
const outer = { inner };
|
|
53
|
+
inner.outer = outer;
|
|
54
|
+
const result = safeStringifyPreview(outer);
|
|
55
|
+
expect(result).toContain('<circular>');
|
|
56
|
+
});
|
|
57
|
+
it('truncates long strings', () => {
|
|
58
|
+
const longString = 'a'.repeat(300);
|
|
59
|
+
const result = safeStringifyPreview(longString);
|
|
60
|
+
expect(result.length).toBeLessThan(300);
|
|
61
|
+
expect(result).toContain('…');
|
|
62
|
+
});
|
|
63
|
+
it('truncates output to 2000 chars', () => {
|
|
64
|
+
const obj = { data: 'a'.repeat(3000) };
|
|
65
|
+
const result = safeStringifyPreview(obj);
|
|
66
|
+
expect(result.length).toBeLessThanOrEqual(2001); // 2000 + '…'
|
|
67
|
+
});
|
|
68
|
+
it('handles deep nesting (depth limit)', () => {
|
|
69
|
+
const deep = { l1: { l2: { l3: { l4: { l5: { l6: { l7: 'deep' } } } } } } };
|
|
70
|
+
const result = safeStringifyPreview(deep);
|
|
71
|
+
expect(result).toBeDefined();
|
|
72
|
+
});
|
|
73
|
+
it('handles symbols', () => {
|
|
74
|
+
const obj = { sym: Symbol('test') };
|
|
75
|
+
const result = safeStringifyPreview(obj);
|
|
76
|
+
expect(result).toContain('<symbol>');
|
|
77
|
+
});
|
|
78
|
+
it('handles functions', () => {
|
|
79
|
+
const obj = { fn: () => 'test' };
|
|
80
|
+
const result = safeStringifyPreview(obj);
|
|
81
|
+
expect(result).toContain('<function>');
|
|
82
|
+
});
|
|
83
|
+
it('handles NaN', () => {
|
|
84
|
+
const obj = { nan: Number.NaN };
|
|
85
|
+
const result = safeStringifyPreview(obj);
|
|
86
|
+
expect(result).toContain('NaN');
|
|
87
|
+
});
|
|
88
|
+
it('handles Infinity', () => {
|
|
89
|
+
const obj = { inf: Number.POSITIVE_INFINITY };
|
|
90
|
+
const result = safeStringifyPreview(obj);
|
|
91
|
+
expect(result).toContain('NaN');
|
|
92
|
+
});
|
|
93
|
+
it('handles negative Infinity', () => {
|
|
94
|
+
const obj = { inf: Number.NEGATIVE_INFINITY };
|
|
95
|
+
const result = safeStringifyPreview(obj);
|
|
96
|
+
expect(result).toContain('NaN');
|
|
97
|
+
});
|
|
98
|
+
it('limits array length', () => {
|
|
99
|
+
const arr = Array.from({ length: 100 }, (_, i) => i);
|
|
100
|
+
const result = safeStringifyPreview(arr);
|
|
101
|
+
expect(result).toContain('…');
|
|
102
|
+
});
|
|
103
|
+
it('limits object keys', () => {
|
|
104
|
+
const obj = {};
|
|
105
|
+
for (let i = 0; i < 100; i++) {
|
|
106
|
+
obj[`key${i}`] = i;
|
|
107
|
+
}
|
|
108
|
+
const result = safeStringifyPreview(obj);
|
|
109
|
+
expect(result).toContain('…');
|
|
110
|
+
});
|
|
111
|
+
it('handles empty objects', () => {
|
|
112
|
+
expect(safeStringifyPreview({})).toBe('{}');
|
|
113
|
+
});
|
|
114
|
+
it('handles empty arrays', () => {
|
|
115
|
+
expect(safeStringifyPreview([])).toBe('[]');
|
|
116
|
+
});
|
|
117
|
+
it('handles nested objects', () => {
|
|
118
|
+
const obj = { outer: { inner: { value: 'nested' } } };
|
|
119
|
+
const result = safeStringifyPreview(obj);
|
|
120
|
+
expect(result).toBe('{"outer":{"inner":{"value":"nested"}}}');
|
|
121
|
+
});
|
|
122
|
+
it('handles mixed types in arrays', () => {
|
|
123
|
+
const arr = [1, 'two', true, null, { key: 'value' }];
|
|
124
|
+
const result = safeStringifyPreview(arr);
|
|
125
|
+
expect(result).toContain('1');
|
|
126
|
+
expect(result).toContain('two');
|
|
127
|
+
expect(result).toContain('true');
|
|
128
|
+
expect(result).toContain('null');
|
|
129
|
+
expect(result).toContain('key');
|
|
130
|
+
});
|
|
131
|
+
it('handles special characters in strings', () => {
|
|
132
|
+
const obj = { text: 'Hello\nWorld\t"quoted"' };
|
|
133
|
+
const result = safeStringifyPreview(obj);
|
|
134
|
+
expect(result).toContain('Hello');
|
|
135
|
+
expect(result).toContain('World');
|
|
136
|
+
expect(result).toContain('quoted');
|
|
137
|
+
});
|
|
138
|
+
it('handles unserializable objects gracefully', () => {
|
|
139
|
+
// Create an object that throws on property access
|
|
140
|
+
const obj = {};
|
|
141
|
+
Object.defineProperty(obj, 'thrower', {
|
|
142
|
+
get() { throw new Error('Cannot access'); },
|
|
143
|
+
enumerable: true,
|
|
144
|
+
});
|
|
145
|
+
const result = safeStringifyPreview(obj);
|
|
146
|
+
expect(result).toBe('<unserializable>');
|
|
147
|
+
});
|
|
148
|
+
it('handles Date objects', () => {
|
|
149
|
+
const obj = { date: new Date('2026-06-24') };
|
|
150
|
+
const result = safeStringifyPreview(obj);
|
|
151
|
+
// Date objects are treated as regular objects, resulting in "{}"
|
|
152
|
+
expect(result).toContain('date');
|
|
153
|
+
});
|
|
154
|
+
it('handles Map objects', () => {
|
|
155
|
+
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
|
|
156
|
+
const result = safeStringifyPreview(map);
|
|
157
|
+
expect(result).toBeDefined();
|
|
158
|
+
});
|
|
159
|
+
it('handles Set objects', () => {
|
|
160
|
+
const set = new Set([1, 2, 3]);
|
|
161
|
+
const result = safeStringifyPreview(set);
|
|
162
|
+
expect(result).toBeDefined();
|
|
163
|
+
});
|
|
164
|
+
it('handles null prototype objects', () => {
|
|
165
|
+
const obj = Object.create(null);
|
|
166
|
+
obj.key = 'value';
|
|
167
|
+
const result = safeStringifyPreview(obj);
|
|
168
|
+
expect(result).toContain('key');
|
|
169
|
+
expect(result).toContain('value');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=safe-stringify.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-stringify.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/feedback/__tests__/safe-stringify.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-signal-observability.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pain-signal-observability.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,MAAM,WAAW,6BAA6B;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oCAAoC;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC;IACvB,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAkLD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,oCAAoC,GACzC,6BAA6B,CAiE/B"}
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
* Pain signal observability for Runtime v2 entry points.
|
|
3
3
|
*
|
|
4
4
|
* Design intent (PRI-453): This writer serves paths that do NOT have legacy
|
|
5
|
-
* event-log
|
|
5
|
+
* event-log writers — specifically `pd pain record` CLI,
|
|
6
6
|
* `gate-block-helper.ts`, and `lifecycle.ts`. Hook paths that already write
|
|
7
7
|
* via legacy `recordPainSignal` + `recordPainEvent` pass
|
|
8
8
|
* `recordObservability: false` to avoid triple-write.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* `gate-block-helper.ts` has a legacy `recordGateBlock` call but no legacy
|
|
11
|
+
* `recordPainSignal` or `recordPainEvent` for pain events — it relies on
|
|
12
|
+
* this SDK writer for all pain observability (events_*.jsonl + evolution.jsonl
|
|
13
|
+
* + trajectory.db with canonicalPainId).
|
|
14
|
+
*
|
|
15
|
+
* `pd pain record` does not have a WorkspaceContext, so it uses this small
|
|
16
|
+
* core writer to avoid an observability gap while keeping `evolution_tasks`
|
|
17
|
+
* legacy queue disabled.
|
|
14
18
|
*/
|
|
15
19
|
import Database from 'better-sqlite3';
|
|
16
20
|
import * as fs from 'fs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-signal-observability.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pain-signal-observability.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"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"}
|