deepline 0.3.287 → 0.3.288
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/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +17 -12
- package/dist/bundling-sources/shared_libs/play-runtime/docflow-node-io.ts +22 -54
- package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +7 -26
- package/dist/bundling-sources/shared_libs/play-runtime/secret-redaction.ts +47 -1
- package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +1 -89
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.mjs +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
|
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
|
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
202
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
203
|
-
version: '0.3.
|
|
203
|
+
version: '0.3.288',
|
|
204
204
|
updateSummary:
|
|
205
205
|
'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
|
|
206
206
|
packageCapabilities: {
|
|
@@ -371,6 +371,7 @@ import {
|
|
|
371
371
|
type PlayExecutionSuspension,
|
|
372
372
|
} from './suspension';
|
|
373
373
|
import {
|
|
374
|
+
createRequestHeaderSecretRedactionContext,
|
|
374
375
|
createSecretRedactionContext,
|
|
375
376
|
type SecretRedactionContext,
|
|
376
377
|
} from './secret-redaction';
|
|
@@ -14669,6 +14670,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
14669
14670
|
if (headers['user-agent'] === undefined) {
|
|
14670
14671
|
headers['user-agent'] = 'Deepline Play Runtime';
|
|
14671
14672
|
}
|
|
14673
|
+
const requestRedactor = createRequestHeaderSecretRedactionContext(
|
|
14674
|
+
headers,
|
|
14675
|
+
Object.keys(secretHeaderMarkers),
|
|
14676
|
+
);
|
|
14672
14677
|
const fetchInit = { ...init, headers };
|
|
14673
14678
|
delete fetchInit.auth;
|
|
14674
14679
|
const boundaryId = this.durableBoundaryId(
|
|
@@ -14755,18 +14760,18 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
14755
14760
|
log: (message) => this.runtimeLog(message),
|
|
14756
14761
|
});
|
|
14757
14762
|
const rawJson = parseJsonOrNull(bodyText);
|
|
14758
|
-
const
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
|
|
14763
|
+
const output: PlayFetchResponse =
|
|
14764
|
+
this.secretRedactor.redactKnownSecrets(
|
|
14765
|
+
requestRedactor.redactKnownSecrets({
|
|
14766
|
+
ok: response.ok,
|
|
14767
|
+
status: response.status,
|
|
14768
|
+
statusText: response.statusText,
|
|
14769
|
+
url: response.url,
|
|
14770
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
14771
|
+
bodyText,
|
|
14772
|
+
json: rawJson,
|
|
14773
|
+
}),
|
|
14774
|
+
);
|
|
14770
14775
|
|
|
14771
14776
|
if (!output.ok) {
|
|
14772
14777
|
this.logCtxFetchHttpFailure({
|
|
@@ -73,7 +73,7 @@ export type PlayDocflowNodeIoState = {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
type PreviewOptions = {
|
|
76
|
-
redactor?: SecretRedactionContext
|
|
76
|
+
redactor?: Pick<SecretRedactionContext, 'redactRegisteredSecrets'>;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
const utf8Encoder = new TextEncoder();
|
|
@@ -132,26 +132,13 @@ function truncateUtf8(value: string, maxBytes: number): string {
|
|
|
132
132
|
return `${output}…`;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function redactString(
|
|
136
|
-
redactor: SecretRedactionContext,
|
|
137
|
-
value: string,
|
|
138
|
-
key?: string,
|
|
139
|
-
): string {
|
|
140
|
-
if (!key) return redactor.redactString(value);
|
|
141
|
-
const wrapped = redactor.redact({ [key]: value }) as Record<string, unknown>;
|
|
142
|
-
return typeof wrapped[key] === 'string'
|
|
143
|
-
? wrapped[key]
|
|
144
|
-
: redactor.redactString(value);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
135
|
function safeString(
|
|
148
136
|
value: unknown,
|
|
149
|
-
redactor
|
|
150
|
-
key?: string,
|
|
137
|
+
redactor?: PreviewOptions['redactor'],
|
|
151
138
|
): string | undefined {
|
|
152
139
|
if (typeof value !== 'string') return undefined;
|
|
153
140
|
return truncateUtf8(
|
|
154
|
-
|
|
141
|
+
redactor?.redactRegisteredSecrets(value) ?? value,
|
|
155
142
|
DOCFLOW_NODE_IO_LIMITS.maxStringBytes,
|
|
156
143
|
);
|
|
157
144
|
}
|
|
@@ -161,8 +148,7 @@ function previewValue(
|
|
|
161
148
|
input: {
|
|
162
149
|
depth: number;
|
|
163
150
|
ancestors: WeakSet<object>;
|
|
164
|
-
redactor
|
|
165
|
-
key?: string;
|
|
151
|
+
redactor?: PreviewOptions['redactor'];
|
|
166
152
|
},
|
|
167
153
|
): PlayDocflowNodeValuePreview {
|
|
168
154
|
if (value === null) return { kind: 'null' };
|
|
@@ -170,7 +156,7 @@ function previewValue(
|
|
|
170
156
|
if (typeof value === 'string') {
|
|
171
157
|
return {
|
|
172
158
|
kind: 'scalar',
|
|
173
|
-
value: safeString(value, input.redactor
|
|
159
|
+
value: safeString(value, input.redactor) ?? '',
|
|
174
160
|
};
|
|
175
161
|
}
|
|
176
162
|
if (typeof value === 'number') {
|
|
@@ -207,18 +193,13 @@ function previewValue(
|
|
|
207
193
|
) {
|
|
208
194
|
return {
|
|
209
195
|
kind: 'dataset',
|
|
210
|
-
datasetId:
|
|
211
|
-
safeString(datasetId.value, input.redactor, 'datasetId') ?? 'dataset',
|
|
196
|
+
datasetId: safeString(datasetId.value, input.redactor) ?? 'dataset',
|
|
212
197
|
datasetKind: datasetKind.value,
|
|
213
198
|
tableNamespace:
|
|
214
199
|
tableNamespace.ok && tableNamespace.value === null
|
|
215
200
|
? null
|
|
216
201
|
: tableNamespace.ok
|
|
217
|
-
? safeString(
|
|
218
|
-
tableNamespace.value,
|
|
219
|
-
input.redactor,
|
|
220
|
-
'tableNamespace',
|
|
221
|
-
)
|
|
202
|
+
? safeString(tableNamespace.value, input.redactor)
|
|
222
203
|
: undefined,
|
|
223
204
|
};
|
|
224
205
|
}
|
|
@@ -239,18 +220,13 @@ function previewValue(
|
|
|
239
220
|
) {
|
|
240
221
|
return {
|
|
241
222
|
kind: 'dataset',
|
|
242
|
-
datasetId:
|
|
243
|
-
safeString(datasetId.value, input.redactor, 'datasetId') ?? 'dataset',
|
|
223
|
+
datasetId: safeString(datasetId.value, input.redactor) ?? 'dataset',
|
|
244
224
|
datasetKind: datasetKind.value,
|
|
245
225
|
tableNamespace:
|
|
246
226
|
tableNamespace.ok && tableNamespace.value === null
|
|
247
227
|
? null
|
|
248
228
|
: tableNamespace.ok
|
|
249
|
-
? safeString(
|
|
250
|
-
tableNamespace.value,
|
|
251
|
-
input.redactor,
|
|
252
|
-
'tableNamespace',
|
|
253
|
-
)
|
|
229
|
+
? safeString(tableNamespace.value, input.redactor)
|
|
254
230
|
: undefined,
|
|
255
231
|
rowCount: Math.max(0, Math.floor(count.value)),
|
|
256
232
|
};
|
|
@@ -309,7 +285,9 @@ function previewValue(
|
|
|
309
285
|
const fields: Record<string, PlayDocflowNodeValuePreview> = {};
|
|
310
286
|
for (const [key, descriptor] of selected) {
|
|
311
287
|
const safeKey = truncateUtf8(
|
|
312
|
-
ledgerSafeDocflowPreviewKey(
|
|
288
|
+
ledgerSafeDocflowPreviewKey(
|
|
289
|
+
input.redactor?.redactRegisteredSecrets(key) ?? key,
|
|
290
|
+
),
|
|
313
291
|
DOCFLOW_NODE_IO_LIMITS.maxStringBytes,
|
|
314
292
|
);
|
|
315
293
|
fields[safeKey] =
|
|
@@ -317,7 +295,6 @@ function previewValue(
|
|
|
317
295
|
? previewValue(descriptor.value, {
|
|
318
296
|
...input,
|
|
319
297
|
depth: input.depth + 1,
|
|
320
|
-
key,
|
|
321
298
|
})
|
|
322
299
|
: { kind: 'unavailable', reason: 'access_error' };
|
|
323
300
|
}
|
|
@@ -338,7 +315,6 @@ export function buildPlayDocflowNodeIoPreviewMap(
|
|
|
338
315
|
values: Record<string, unknown>,
|
|
339
316
|
options: PreviewOptions = {},
|
|
340
317
|
): { values: PlayDocflowNodeIoPreviewMap; truncated: boolean } {
|
|
341
|
-
const redactor = options.redactor ?? createSecretRedactionContext();
|
|
342
318
|
const previews: PlayDocflowNodeIoPreviewMap = {};
|
|
343
319
|
let truncated = false;
|
|
344
320
|
let entries: Array<[string, unknown]>;
|
|
@@ -356,14 +332,15 @@ export function buildPlayDocflowNodeIoPreviewMap(
|
|
|
356
332
|
break;
|
|
357
333
|
}
|
|
358
334
|
const safePath = truncateUtf8(
|
|
359
|
-
ledgerSafeDocflowPreviewKey(
|
|
335
|
+
ledgerSafeDocflowPreviewKey(
|
|
336
|
+
options.redactor?.redactRegisteredSecrets(path) ?? path,
|
|
337
|
+
),
|
|
360
338
|
DOCFLOW_NODE_IO_LIMITS.maxStringBytes,
|
|
361
339
|
);
|
|
362
340
|
const preview = previewValue(value, {
|
|
363
341
|
depth: 0,
|
|
364
342
|
ancestors: new WeakSet(),
|
|
365
|
-
redactor,
|
|
366
|
-
key: path.split('.').at(-1),
|
|
343
|
+
redactor: options.redactor,
|
|
367
344
|
});
|
|
368
345
|
const candidate = { ...previews, [safePath]: preview };
|
|
369
346
|
if (
|
|
@@ -413,7 +390,6 @@ export function buildPlayDocflowNodeInputPreviewMap(
|
|
|
413
390
|
captures: readonly PlayDocflowNodeInputCapture[],
|
|
414
391
|
options: PreviewOptions = {},
|
|
415
392
|
): { values: PlayDocflowNodeIoPreviewMap; truncated: boolean } {
|
|
416
|
-
const redactor = options.redactor ?? createSecretRedactionContext();
|
|
417
393
|
const values: PlayDocflowNodeIoPreviewMap = {};
|
|
418
394
|
let truncated = false;
|
|
419
395
|
for (const capture of captures.slice(0, DOCFLOW_NODE_IO_LIMITS.maxPaths)) {
|
|
@@ -435,15 +411,16 @@ export function buildPlayDocflowNodeInputPreviewMap(
|
|
|
435
411
|
}
|
|
436
412
|
}
|
|
437
413
|
const safePath = truncateUtf8(
|
|
438
|
-
ledgerSafeDocflowPreviewKey(
|
|
414
|
+
ledgerSafeDocflowPreviewKey(
|
|
415
|
+
options.redactor?.redactRegisteredSecrets(capture.path) ?? capture.path,
|
|
416
|
+
),
|
|
439
417
|
DOCFLOW_NODE_IO_LIMITS.maxStringBytes,
|
|
440
418
|
);
|
|
441
419
|
const preview: PlayDocflowNodeValuePreview = available
|
|
442
420
|
? previewValue(current, {
|
|
443
421
|
depth: 0,
|
|
444
422
|
ancestors: new WeakSet(),
|
|
445
|
-
redactor,
|
|
446
|
-
key: capture.properties.at(-1) ?? capture.path,
|
|
423
|
+
redactor: options.redactor,
|
|
447
424
|
})
|
|
448
425
|
: { kind: 'unavailable', reason: 'access_error' };
|
|
449
426
|
const candidate = { ...values, [safePath]: preview };
|
|
@@ -494,7 +471,6 @@ function normalizePreview(
|
|
|
494
471
|
return previewValue(value.value, {
|
|
495
472
|
depth: 0,
|
|
496
473
|
ancestors: new WeakSet(),
|
|
497
|
-
redactor: createSecretRedactionContext(),
|
|
498
474
|
});
|
|
499
475
|
}
|
|
500
476
|
return null;
|
|
@@ -523,11 +499,7 @@ function normalizePreview(
|
|
|
523
499
|
: null;
|
|
524
500
|
}
|
|
525
501
|
if (value.kind === 'dataset') {
|
|
526
|
-
const datasetId = safeString(
|
|
527
|
-
value.datasetId,
|
|
528
|
-
createSecretRedactionContext(),
|
|
529
|
-
'datasetId',
|
|
530
|
-
);
|
|
502
|
+
const datasetId = safeString(value.datasetId);
|
|
531
503
|
if (
|
|
532
504
|
!datasetId ||
|
|
533
505
|
(value.datasetKind !== 'csv' && value.datasetKind !== 'map')
|
|
@@ -542,11 +514,7 @@ function normalizePreview(
|
|
|
542
514
|
? { tableNamespace: null }
|
|
543
515
|
: typeof value.tableNamespace === 'string'
|
|
544
516
|
? {
|
|
545
|
-
tableNamespace: safeString(
|
|
546
|
-
value.tableNamespace,
|
|
547
|
-
createSecretRedactionContext(),
|
|
548
|
-
'tableNamespace',
|
|
549
|
-
),
|
|
517
|
+
tableNamespace: safeString(value.tableNamespace),
|
|
550
518
|
}
|
|
551
519
|
: {}),
|
|
552
520
|
...(typeof value.rowCount === 'number' && Number.isFinite(value.rowCount)
|
|
@@ -59,52 +59,33 @@ export function sanitizeOpaqueLedgerPayload(value: unknown): unknown {
|
|
|
59
59
|
return redactedIssue ? opaqueLedgerPayloadSummary(redactedIssue) : redacted;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
/** A receipt
|
|
62
|
+
/** A customer receipt value serialized once and measured from the stored text. */
|
|
63
63
|
export type SanitizedRuntimeReceiptPayload = {
|
|
64
|
-
/** The redacted value. Callers return or re-project this, never the source. */
|
|
65
64
|
value: unknown;
|
|
66
|
-
/**
|
|
67
|
-
* Canonical Postgres JSON text for `value`, byte-identical to what
|
|
68
|
-
* `stringifyPostgresJson(value ?? null)` produces. `jsonb` accepts this text
|
|
69
|
-
* directly, so the completion path never re-serializes the same output.
|
|
70
|
-
*/
|
|
65
|
+
/** Canonical Postgres JSON text, passed directly to the jsonb completion write. */
|
|
71
66
|
serialized: string;
|
|
72
|
-
/** UTF-8 byte length of `serialized
|
|
67
|
+
/** UTF-8 byte length of `serialized`. */
|
|
73
68
|
bytes: number;
|
|
74
69
|
};
|
|
75
70
|
|
|
76
|
-
/**
|
|
77
|
-
* Secret-redact a receipt payload without coupling its 10 MiB cell limit to the
|
|
78
|
-
* ledger, and serialize it exactly once.
|
|
79
|
-
*
|
|
80
|
-
* The limit is enforced on the redacted, serialized value that is actually
|
|
81
|
-
* persisted. Redaction normally shrinks credential-shaped values but can expand
|
|
82
|
-
* short matched strings, so measuring the source instead would be wrong in both
|
|
83
|
-
* directions.
|
|
84
|
-
*
|
|
85
|
-
* Redaction is identity-preserving: a payload carrying no credential comes back
|
|
86
|
-
* as the very object that was passed in, with no deep clone, and is serialized
|
|
87
|
-
* exactly once. Only a payload that actually redacts pays for a rebuilt value.
|
|
88
|
-
*/
|
|
89
71
|
export function sanitizeRuntimeReceiptPayloadForStorage(
|
|
90
72
|
value: unknown,
|
|
91
73
|
): SanitizedRuntimeReceiptPayload {
|
|
92
|
-
const redacted = ledgerIngressRedactor.redact(value);
|
|
93
74
|
// `undefined` is not JSON. The receipt contract stores it as jsonb `null`,
|
|
94
75
|
// which is exactly what the previous `stringifyPostgresJson(output ?? null)`
|
|
95
76
|
// parameter produced.
|
|
96
|
-
const serialized = stringifyPostgresJson(
|
|
77
|
+
const serialized = stringifyPostgresJson(value ?? null);
|
|
97
78
|
if (serialized === undefined) {
|
|
98
79
|
throw new TypeError('Runtime receipt output is not JSON-serializable.');
|
|
99
80
|
}
|
|
100
81
|
const bytes = assertSerializedRuntimeReceiptOutputWithinLimit({
|
|
101
82
|
serialized,
|
|
102
|
-
path: 'runtime receipt output
|
|
83
|
+
path: 'runtime receipt output',
|
|
103
84
|
});
|
|
104
|
-
return { value
|
|
85
|
+
return { value, serialized, bytes };
|
|
105
86
|
}
|
|
106
87
|
|
|
107
|
-
/**
|
|
88
|
+
/** Enforce the customer receipt byte limit without altering its values. */
|
|
108
89
|
export function sanitizeRuntimeReceiptPayload(value: unknown): unknown {
|
|
109
90
|
return sanitizeRuntimeReceiptPayloadForStorage(value).value;
|
|
110
91
|
}
|
|
@@ -188,6 +188,7 @@ export type SecretRedactionContext = {
|
|
|
188
188
|
/** Redacts only values registered by the secret resolver, preserving safe diagnostics. */
|
|
189
189
|
redactRegisteredSecrets(value: string): string;
|
|
190
190
|
redactString(value: string): string;
|
|
191
|
+
/** Redacts registered credential values recursively, without guessing from field names or patterns. */
|
|
191
192
|
redactKnownSecrets<T>(value: T): T;
|
|
192
193
|
redact<T>(value: T): T;
|
|
193
194
|
};
|
|
@@ -335,7 +336,7 @@ export function createSecretRedactionContext(
|
|
|
335
336
|
}
|
|
336
337
|
|
|
337
338
|
function redactKnownSecrets<T>(value: T): T {
|
|
338
|
-
if (typeof value === 'string') return
|
|
339
|
+
if (typeof value === 'string') return redactRegisteredSecrets(value) as T;
|
|
339
340
|
if (Array.isArray(value)) {
|
|
340
341
|
return value.map((entry) => redactKnownSecrets(entry)) as T;
|
|
341
342
|
}
|
|
@@ -360,3 +361,48 @@ export function createSecretRedactionContext(
|
|
|
360
361
|
redact,
|
|
361
362
|
};
|
|
362
363
|
}
|
|
364
|
+
|
|
365
|
+
const REQUEST_CREDENTIAL_HEADER_NAMES = new Set([
|
|
366
|
+
'authorization',
|
|
367
|
+
'cookie',
|
|
368
|
+
'proxy-authorization',
|
|
369
|
+
'x-api-key',
|
|
370
|
+
'api-key',
|
|
371
|
+
'apikey',
|
|
372
|
+
'x-auth',
|
|
373
|
+
'auth-token',
|
|
374
|
+
'access-token',
|
|
375
|
+
'refresh-token',
|
|
376
|
+
'session-token',
|
|
377
|
+
'x-auth-token',
|
|
378
|
+
'x-access-token',
|
|
379
|
+
'x-refresh-token',
|
|
380
|
+
'x-session-token',
|
|
381
|
+
]);
|
|
382
|
+
|
|
383
|
+
export function createRequestHeaderSecretRedactionContext(
|
|
384
|
+
headers: Readonly<Record<string, string>>,
|
|
385
|
+
sensitiveHeaders: readonly string[] = [],
|
|
386
|
+
): SecretRedactionContext {
|
|
387
|
+
const redactor = createSecretRedactionContext();
|
|
388
|
+
const declared = new Set(sensitiveHeaders.map((name) => name.toLowerCase()));
|
|
389
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
390
|
+
const normalizedName = name.toLowerCase();
|
|
391
|
+
if (
|
|
392
|
+
!REQUEST_CREDENTIAL_HEADER_NAMES.has(normalizedName) &&
|
|
393
|
+
!declared.has(normalizedName)
|
|
394
|
+
) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
redactor.register(value);
|
|
398
|
+
const auth = /^(?:bearer|basic)\s+(.+)$/i.exec(value.trim());
|
|
399
|
+
if (auth?.[1]) redactor.register(auth[1]);
|
|
400
|
+
if (normalizedName === 'cookie') {
|
|
401
|
+
for (const pair of value.split(';')) {
|
|
402
|
+
const separator = pair.indexOf('=');
|
|
403
|
+
if (separator > 0) redactor.register(pair.slice(separator + 1).trim());
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return redactor;
|
|
408
|
+
}
|
|
@@ -6,7 +6,6 @@ type SecretRedactionOptions = {
|
|
|
6
6
|
keyPolicy?: 'strict' | 'public-result';
|
|
7
7
|
/** Replace sample cursor values with a non-capability-bearing placeholder. */
|
|
8
8
|
placeholderContinuationValues?: boolean;
|
|
9
|
-
redactJsonStrings?: boolean;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
const SENSITIVE_KEY_PATTERNS = [
|
|
@@ -400,83 +399,12 @@ function maybeRedactString(value: string, options: SecretRedactionOptions) {
|
|
|
400
399
|
: redacted.replace(HIGH_ENTROPY_VALUE_PATTERN, REDACTED_VALUE);
|
|
401
400
|
}
|
|
402
401
|
|
|
403
|
-
function parseJsonContainerText(value: unknown): unknown {
|
|
404
|
-
if (typeof value !== 'string') return value;
|
|
405
|
-
const trimmed = value.trim();
|
|
406
|
-
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return value;
|
|
407
|
-
try {
|
|
408
|
-
return JSON.parse(value);
|
|
409
|
-
} catch {
|
|
410
|
-
return value;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
function jsonStringContainsSecrets(
|
|
415
|
-
value: string,
|
|
416
|
-
options: SecretRedactionOptions,
|
|
417
|
-
parentKey?: string,
|
|
418
|
-
path: readonly string[] = [],
|
|
419
|
-
): boolean {
|
|
420
|
-
// Inspect parsed values, but never reserialize SQL text and round its numeric literals.
|
|
421
|
-
const parsed = parseJsonContainerText(value);
|
|
422
|
-
if (!parsed || typeof parsed !== 'object') return false;
|
|
423
|
-
const pending = [
|
|
424
|
-
{
|
|
425
|
-
value: parsed,
|
|
426
|
-
parentKey,
|
|
427
|
-
path: [...path],
|
|
428
|
-
},
|
|
429
|
-
];
|
|
430
|
-
const textOptions = { ...options, redactJsonStrings: false };
|
|
431
|
-
while (pending.length > 0) {
|
|
432
|
-
const current = pending.pop()!;
|
|
433
|
-
const sourceIsArray = Array.isArray(current.value);
|
|
434
|
-
for (const [key, rawItem] of Object.entries(current.value)) {
|
|
435
|
-
const item = parseJsonContainerText(rawItem);
|
|
436
|
-
const parentKey = sourceIsArray ? current.parentKey : key;
|
|
437
|
-
if (
|
|
438
|
-
!sourceIsArray &&
|
|
439
|
-
options.keyPolicy === 'public-result' &&
|
|
440
|
-
isPublicResultSafeTokenKey(key, current.path, item) &&
|
|
441
|
-
(!item || typeof item !== 'object')
|
|
442
|
-
) {
|
|
443
|
-
if (
|
|
444
|
-
typeof item === 'string' &&
|
|
445
|
-
maybeRedactString(item, textOptions) !== item
|
|
446
|
-
)
|
|
447
|
-
return true;
|
|
448
|
-
continue;
|
|
449
|
-
}
|
|
450
|
-
if (!sourceIsArray && shouldRedactKey(key)) return true;
|
|
451
|
-
if (item && typeof item === 'object') {
|
|
452
|
-
pending.push({
|
|
453
|
-
value: item,
|
|
454
|
-
parentKey,
|
|
455
|
-
path: sourceIsArray ? current.path : [...current.path, key],
|
|
456
|
-
});
|
|
457
|
-
} else if (
|
|
458
|
-
typeof item === 'string' &&
|
|
459
|
-
redactSecretsInValue(item, parentKey, textOptions) !== item
|
|
460
|
-
) {
|
|
461
|
-
return true;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return false;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
402
|
export function redactSecretsInValue<T>(
|
|
469
403
|
value: T,
|
|
470
404
|
parentKey?: string,
|
|
471
405
|
options: SecretRedactionOptions = {},
|
|
472
406
|
): T {
|
|
473
407
|
if (typeof value === 'string') {
|
|
474
|
-
if (
|
|
475
|
-
options.redactJsonStrings &&
|
|
476
|
-
jsonStringContainsSecrets(value, options, parentKey)
|
|
477
|
-
) {
|
|
478
|
-
return REDACTED_VALUE as T;
|
|
479
|
-
}
|
|
480
408
|
if (hasExplicitSecretValue(value, options)) {
|
|
481
409
|
return REDACTED_VALUE as T;
|
|
482
410
|
}
|
|
@@ -519,15 +447,8 @@ export function redactSecretsInValue<T>(
|
|
|
519
447
|
const redactNestedValue = (
|
|
520
448
|
item: unknown,
|
|
521
449
|
itemParentKey: string | undefined,
|
|
522
|
-
path: readonly string[],
|
|
523
450
|
): unknown => {
|
|
524
451
|
if (typeof item !== 'string') return item;
|
|
525
|
-
if (
|
|
526
|
-
options.redactJsonStrings &&
|
|
527
|
-
jsonStringContainsSecrets(item, options, itemParentKey, path)
|
|
528
|
-
) {
|
|
529
|
-
return REDACTED_VALUE;
|
|
530
|
-
}
|
|
531
452
|
if (hasExplicitSecretValue(item, options)) {
|
|
532
453
|
return REDACTED_VALUE;
|
|
533
454
|
}
|
|
@@ -552,15 +473,7 @@ export function redactSecretsInValue<T>(
|
|
|
552
473
|
(!item || typeof item !== 'object')
|
|
553
474
|
) {
|
|
554
475
|
const redacted =
|
|
555
|
-
typeof item === 'string'
|
|
556
|
-
? options.redactJsonStrings &&
|
|
557
|
-
jsonStringContainsSecrets(item, options, itemParentKey, [
|
|
558
|
-
...current.path,
|
|
559
|
-
key,
|
|
560
|
-
])
|
|
561
|
-
? REDACTED_VALUE
|
|
562
|
-
: maybeRedactString(item, options)
|
|
563
|
-
: item;
|
|
476
|
+
typeof item === 'string' ? maybeRedactString(item, options) : item;
|
|
564
477
|
(current.target as Record<string, unknown>)[key] =
|
|
565
478
|
options.placeholderContinuationValues &&
|
|
566
479
|
isPublicResultCursorKey(key, current.path) &&
|
|
@@ -589,7 +502,6 @@ export function redactSecretsInValue<T>(
|
|
|
589
502
|
(current.target as Record<string, unknown>)[key] = redactNestedValue(
|
|
590
503
|
item,
|
|
591
504
|
itemParentKey,
|
|
592
|
-
sourceIsArray ? current.path : [...current.path, key],
|
|
593
505
|
);
|
|
594
506
|
}
|
|
595
507
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -3515,7 +3515,7 @@ var SDK_RELEASE = {
|
|
|
3515
3515
|
// getters keep their established compatibility behavior.
|
|
3516
3516
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3517
3517
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3518
|
-
version: "0.3.
|
|
3518
|
+
version: "0.3.288",
|
|
3519
3519
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3520
3520
|
packageCapabilities: {
|
|
3521
3521
|
updatePreferences: 1
|
|
@@ -5217,7 +5217,7 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
5217
5217
|
return value;
|
|
5218
5218
|
}
|
|
5219
5219
|
function redactKnownSecrets(value) {
|
|
5220
|
-
if (typeof value === "string") return
|
|
5220
|
+
if (typeof value === "string") return redactRegisteredSecrets(value);
|
|
5221
5221
|
if (Array.isArray(value)) {
|
|
5222
5222
|
return value.map((entry) => redactKnownSecrets(entry));
|
|
5223
5223
|
}
|
package/dist/cli/index.mjs
CHANGED
|
@@ -3510,7 +3510,7 @@ var SDK_RELEASE = {
|
|
|
3510
3510
|
// getters keep their established compatibility behavior.
|
|
3511
3511
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3512
3512
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3513
|
-
version: "0.3.
|
|
3513
|
+
version: "0.3.288",
|
|
3514
3514
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3515
3515
|
packageCapabilities: {
|
|
3516
3516
|
updatePreferences: 1
|
|
@@ -5212,7 +5212,7 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
5212
5212
|
return value;
|
|
5213
5213
|
}
|
|
5214
5214
|
function redactKnownSecrets(value) {
|
|
5215
|
-
if (typeof value === "string") return
|
|
5215
|
+
if (typeof value === "string") return redactRegisteredSecrets(value);
|
|
5216
5216
|
if (Array.isArray(value)) {
|
|
5217
5217
|
return value.map((entry) => redactKnownSecrets(entry));
|
|
5218
5218
|
}
|
package/dist/index.js
CHANGED
|
@@ -1328,7 +1328,7 @@ var SDK_RELEASE = {
|
|
|
1328
1328
|
// getters keep their established compatibility behavior.
|
|
1329
1329
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1330
1330
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1331
|
-
version: "0.3.
|
|
1331
|
+
version: "0.3.288",
|
|
1332
1332
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1333
1333
|
packageCapabilities: {
|
|
1334
1334
|
updatePreferences: 1
|
|
@@ -2968,7 +2968,7 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
2968
2968
|
return value;
|
|
2969
2969
|
}
|
|
2970
2970
|
function redactKnownSecrets(value) {
|
|
2971
|
-
if (typeof value === "string") return
|
|
2971
|
+
if (typeof value === "string") return redactRegisteredSecrets(value);
|
|
2972
2972
|
if (Array.isArray(value)) {
|
|
2973
2973
|
return value.map((entry) => redactKnownSecrets(entry));
|
|
2974
2974
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1232,7 +1232,7 @@ var SDK_RELEASE = {
|
|
|
1232
1232
|
// getters keep their established compatibility behavior.
|
|
1233
1233
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1234
1234
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1235
|
-
version: "0.3.
|
|
1235
|
+
version: "0.3.288",
|
|
1236
1236
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1237
1237
|
packageCapabilities: {
|
|
1238
1238
|
updatePreferences: 1
|
|
@@ -2872,7 +2872,7 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
2872
2872
|
return value;
|
|
2873
2873
|
}
|
|
2874
2874
|
function redactKnownSecrets(value) {
|
|
2875
|
-
if (typeof value === "string") return
|
|
2875
|
+
if (typeof value === "string") return redactRegisteredSecrets(value);
|
|
2876
2876
|
if (Array.isArray(value)) {
|
|
2877
2877
|
return value.map((entry) => redactKnownSecrets(entry));
|
|
2878
2878
|
}
|
package/dist/release.d.mts
CHANGED
|
@@ -149,7 +149,7 @@ type SdkRelease = {
|
|
|
149
149
|
supportPolicy: SdkSupportPolicy;
|
|
150
150
|
};
|
|
151
151
|
declare const SDK_RELEASE: {
|
|
152
|
-
readonly version: "0.3.
|
|
152
|
+
readonly version: "0.3.288";
|
|
153
153
|
readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
|
|
154
154
|
readonly packageCapabilities: {
|
|
155
155
|
readonly updatePreferences: 1;
|
package/dist/release.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ type SdkRelease = {
|
|
|
149
149
|
supportPolicy: SdkSupportPolicy;
|
|
150
150
|
};
|
|
151
151
|
declare const SDK_RELEASE: {
|
|
152
|
-
readonly version: "0.3.
|
|
152
|
+
readonly version: "0.3.288";
|
|
153
153
|
readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
|
|
154
154
|
readonly packageCapabilities: {
|
|
155
155
|
readonly updatePreferences: 1;
|
package/dist/release.js
CHANGED
|
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
|
|
|
74
74
|
// getters keep their established compatibility behavior.
|
|
75
75
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
76
76
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
77
|
-
version: "0.3.
|
|
77
|
+
version: "0.3.288",
|
|
78
78
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
79
79
|
packageCapabilities: {
|
|
80
80
|
updatePreferences: 1
|
package/dist/release.mjs
CHANGED
|
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
|
|
|
48
48
|
// getters keep their established compatibility behavior.
|
|
49
49
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
50
50
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
51
|
-
version: "0.3.
|
|
51
|
+
version: "0.3.288",
|
|
52
52
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
53
53
|
packageCapabilities: {
|
|
54
54
|
updatePreferences: 1
|