Skip to content

Commit 9e85d59

Browse files
icecrasher321claude
andcommitted
fix(scripts): type the replay dump against BlockState instead of any
The dump and focus simulator described blocks and subblocks as `Record<string, any>`, so a wrong assumption about workflow shape would have compiled — in the one tool whose whole job is to be trusted about workflow shape. Uses `BlockState`/`SubBlockState` throughout; the single remaining cast narrows a jsonb `providerConfig` value to `SubBlockState['value']`. Also corrects the usage docstring, which still described the pre-`--out` stdout form, and records why `DATABASE_URL` must not carry `sslrootcert`: postgres.js forwards unrecognized query params as session parameters, so a libpq-style URL fails every query with 42704. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d927513 commit 9e85d59

1 file changed

Lines changed: 23 additions & 17 deletions

File tree

apps/sim/scripts/dump-change-detection-states.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@
1010
* either of those in SQL would be a second spelling of the loaders — the exact
1111
* mistake the change this validates exists to remove.
1212
*
13-
* Usage (from apps/sim, with DATABASE_URL pointing at a read replica):
13+
* Usage (from apps/sim, with DATABASE_URL pointing at a read replica). Note that
14+
* `DATABASE_URL` must not carry libpq-only SSL params: postgres.js forwards any
15+
* query param it does not recognize as a session parameter, so `sslrootcert`
16+
* fails every query with `42704`. `?sslmode=verify-full` alone keeps full
17+
* verification.
1418
*
15-
* bun run scripts/dump-change-detection-states.ts --limit 500 > dump.jsonl
16-
* bun run scripts/dump-change-detection-states.ts --limit 500 --raw > dump.jsonl # keep secrets
19+
* bun run scripts/dump-change-detection-states.ts --out dump.jsonl --limit 500
20+
* bun run scripts/dump-change-detection-states.ts --out dump.jsonl --webhooks-only \
21+
* --simulate-focus # reproduce the panel-focus read-back
22+
* bun run scripts/dump-change-detection-states.ts --out dump.jsonl --raw
23+
* # keep credential values verbatim
1724
*
1825
* Values under credential-shaped keys are replaced with a deterministic hash by
1926
* default, so equality is preserved on both sides while the plaintext is not
@@ -31,6 +38,7 @@ import {
3138
loadWorkflowDeploymentSnapshot,
3239
materializeDeploymentState,
3340
} from '@/lib/workflows/persistence/utils'
41+
import type { BlockState, SubBlockState } from '@/stores/workflows/workflow/types'
3442
import { getTrigger, isTriggerValid } from '@/triggers'
3543
import { SYSTEM_SUBBLOCK_IDS } from '@/triggers/constants'
3644
import { resolveBlockTriggerId } from '@/triggers/webhook-url'
@@ -41,15 +49,13 @@ function hashValue(value: string): string {
4149
return `scrubbed:${createHash('sha256').update(value).digest('hex').slice(0, 16)}`
4250
}
4351

44-
function scrubBlocks(blocks: Record<string, any> | undefined): Record<string, any> {
45-
const out: Record<string, any> = {}
52+
function scrubBlocks(blocks: Record<string, BlockState>): Record<string, BlockState> {
53+
const out: Record<string, BlockState> = {}
4654

47-
for (const [blockId, block] of Object.entries(blocks ?? {})) {
48-
const subBlocks: Record<string, any> = {}
49-
for (const [subId, subBlock] of Object.entries(
50-
(block?.subBlocks ?? {}) as Record<string, any>
51-
)) {
52-
const value = subBlock?.value
55+
for (const [blockId, block] of Object.entries(blocks)) {
56+
const subBlocks: Record<string, SubBlockState> = {}
57+
for (const [subId, subBlock] of Object.entries(block.subBlocks ?? {})) {
58+
const value = subBlock.value
5359
subBlocks[subId] =
5460
SECRET_KEY_PATTERN.test(subId) && typeof value === 'string' && value.length > 0
5561
? { ...subBlock, value: hashValue(value) }
@@ -74,12 +80,12 @@ function scrubBlocks(blocks: Record<string, any> | undefined): Record<string, an
7480
* misreports it.
7581
*/
7682
function simulateFocus(
77-
blocks: Record<string, any>,
83+
blocks: Record<string, BlockState>,
7884
providerConfigByBlockId: Map<string, Record<string, unknown>>
79-
): Record<string, any> {
80-
const out: Record<string, any> = {}
85+
): Record<string, BlockState> {
86+
const out: Record<string, BlockState> = {}
8187

82-
for (const [blockId, block] of Object.entries(blocks ?? {})) {
88+
for (const [blockId, block] of Object.entries(blocks)) {
8389
const providerConfig = providerConfigByBlockId.get(blockId)
8490
const triggerId = providerConfig ? resolveBlockTriggerId(block) : undefined
8591

@@ -88,7 +94,7 @@ function simulateFocus(
8894
continue
8995
}
9096

91-
const subBlocks: Record<string, any> = { ...(block.subBlocks ?? {}) }
97+
const subBlocks: Record<string, SubBlockState> = { ...(block.subBlocks ?? {}) }
9298
for (const subBlock of getTrigger(triggerId).subBlocks) {
9399
if (subBlock.mode !== 'trigger' && subBlock.mode !== 'trigger-advanced') continue
94100
if (SYSTEM_SUBBLOCK_IDS.includes(subBlock.id)) continue
@@ -102,7 +108,7 @@ function simulateFocus(
102108
subBlocks[subBlock.id] = {
103109
id: subBlock.id,
104110
type: subBlocks[subBlock.id]?.type ?? 'short-input',
105-
value: configValue,
111+
value: configValue as SubBlockState['value'],
106112
}
107113
}
108114

0 commit comments

Comments
 (0)