Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
343 commits
Select commit Hold shift + click to select a range
928246a
Fix toExpression for compactColumns and add JS export
claude Feb 1, 2026
4473dca
Fix S.shape case
DZakh Feb 1, 2026
fd29a00
Update the failing tests list
DZakh Feb 7, 2026
bb59a2c
Fix circular reference handling in recursive decoder compilation (#167)
DZakh Feb 7, 2026
08b0391
Fix compactColumns encoding and S.to integration
claude Feb 7, 2026
823a2e6
Fix compactColumns with default S.to behavior
claude Feb 7, 2026
4b41258
Refactor refiner functions to accept only input parameter (#168)
DZakh Feb 7, 2026
cdd2301
Optimize code generation for better variable reuse and elimination (#…
DZakh Feb 7, 2026
599bd4d
Update failing tests snapshot
DZakh Feb 7, 2026
3cc300b
Partially fix Tuple with embeded transformed schema
DZakh Feb 7, 2026
8135d4d
Fix compactColumns with objectDecoder skip logic and TypeScript exports
claude Feb 7, 2026
e375605
Add compiled Sury.res.mjs output
claude Feb 7, 2026
3c0c646
Fix selfReverse for array and dict factories (#170)
DZakh Feb 7, 2026
4bef96f
Fix compactColumns TypeScript exports and toExpression
claude Feb 7, 2026
97d7bab
Add generated files
claude Feb 7, 2026
1be642b
Update IDEAS.md with compactColumns changes, remove generated files
claude Feb 7, 2026
29bdf4e
Fix compactColumns direction detection and add assertCompiledCode tests
claude Feb 7, 2026
c183a1b
Support empty objects and improve non-object schema error message
claude Feb 8, 2026
9e58ee9
Merge branch 'dz/decode-encode' of github.com:DZakh/rescript-struct i…
DZakh Feb 10, 2026
d2d8dd4
Refactor S.refine API from callback-based to boolean-returning (#172)
DZakh Feb 10, 2026
b37f59f
Implement null<->undefined transformation for compactColumns with nul…
claude Feb 10, 2026
a8c532b
Require S.array wrapper for compactColumns target schema
claude Feb 11, 2026
100a3e4
Refactor refine API to use boolean checks instead of callbacks (#173)
DZakh Feb 12, 2026
d60a16f
Merge branch 'dz/decode-encode' of github.com:DZakh/rescript-struct i…
claude Feb 12, 2026
b40092c
Fix test failures and runtime bug after dz/decode-encode merge
claude Feb 12, 2026
b34eb4e
Update generated Sury.res.mjs after bug fix
claude Feb 12, 2026
942d6a4
Address code review feedback for compactColumns implementation
claude Feb 12, 2026
e3beba8
Refactor parse to use while loop instead of recursive call for .to chain
claude Feb 15, 2026
37a1004
A few more refactoring
DZakh Feb 16, 2026
2f4ea52
Track input and output of value during compilation
DZakh Mar 1, 2026
b24d2a3
Remove skipTo
DZakh Mar 2, 2026
5fb2301
Fix a few more cases to fit new architecture
DZakh Mar 4, 2026
60cec25
More fixes
DZakh Mar 6, 2026
ca001b2
More fixes
DZakh Mar 7, 2026
921b303
Fix async transform case
DZakh Mar 16, 2026
dea1881
Expose embedded on function, fix a few tests
DZakh Mar 25, 2026
e64b42a
Fix async object parse logic
DZakh Mar 29, 2026
2d06110
Remove selfSchema arg
DZakh Mar 29, 2026
e6b8a46
Fix union case
DZakh Mar 29, 2026
efd095b
Fix json string encoder
DZakh Mar 29, 2026
7675aad
Remove codeAfterValidation
DZakh Mar 30, 2026
d9bc5f7
Merge dz/decode-encode and adapt compactColumns to new architecture
claude Mar 30, 2026
367dc6b
35 failing tests
DZakh Mar 30, 2026
f346821
Fix JSON serialization with optional fields (34 failing tests left)
DZakh Apr 3, 2026
2a98684
Fix remaining tests for JSON serialize with undefined fields (32 fail…
DZakh Apr 4, 2026
ca29a08
Fix flatten schema cases (30 failing tests left + 12 which didn't run…
DZakh Apr 4, 2026
6400679
Fix flatten of transformed object schemas by merging flattened parse …
claude Apr 4, 2026
2010944
Remove unnecessary guard around flattened code merge
claude Apr 4, 2026
93d6ac2
Fix object discriminant serialization bugs (37 failing tests left)
claude Apr 4, 2026
7a05b4d
Fix all failing fromJSONSchema tests
claude Apr 4, 2026
d70969d
Move enableJson() from fromJSONSchema impl to test file
claude Apr 5, 2026
456097e
Omit default additionalProperties in toJSONSchema, fail on unknown ty…
claude Apr 5, 2026
5493238
Assert error message in unknown type test
claude Apr 5, 2026
2cc2327
Update S_toJSONSchema_test snapshots: remove additionalProperties and…
claude Apr 5, 2026
b4f7edf
Update failing tests snapshot: 42 -> 24 after S_toJSONSchema fix
claude Apr 5, 2026
2e4bba3
Add changelog entry: encoding to JSON now strips undefined fields
claude Apr 5, 2026
1627d7d
Update ReverseConvertToJson snapshot for deeply recursive schema test
claude Apr 5, 2026
4e143db
Replace unclear comment with optimization note
claude Apr 5, 2026
85ab61e
Merge remote-tracking branch 'origin/dz/decode-encode' into claude/re…
DZakh Apr 5, 2026
fa9654b
Revert irrelevant test changes and restore comments in Sury.res
DZakh Apr 6, 2026
834109f
Merge pull request #171 from DZakh/claude/replace-unnest-compactcolum…
DZakh Apr 6, 2026
448bfdf
Add S.date schema for Date instance validation
claude Apr 5, 2026
91a4355
Add S.date to docs and IDEAS changelog
claude Apr 5, 2026
e1ac4db
Add S.string->S.to(S.date) and S.date->S.to(S.string) support
claude Apr 6, 2026
61193e5
Add string-to-date decoding examples to Date documentation
claude Apr 6, 2026
4703f4c
Refactor date decoder to reuse instanceDecoder and extract invalidDat…
claude Apr 6, 2026
31195f0
Pass expected directly to B.next in date encoder
claude Apr 6, 2026
c8faf39
Regenerate Sury.res.mjs after rebase onto dz/decode-encode
claude Apr 6, 2026
b6f1b52
Merge pull request #188 from DZakh/claude/research-datetime-validatio…
DZakh Apr 6, 2026
20926a6
Add string date-time format, improve toJSONSchema with JSON coercion,…
claude Apr 6, 2026
eceb761
Remove S.datetime entirely in favor of S.string->S.to(S.date)
claude Apr 7, 2026
247f65b
Add test for description on string converted to date, add FIXME to em…
claude Apr 7, 2026
9a82213
Address PR review: simplify encodeToJsonSchema to a single .to branch
claude Apr 7, 2026
803cd64
Return None on parse error in encodeToJsonSchema
claude Apr 8, 2026
f33d983
Inline datetime decoder in fromJSONSchema
claude Apr 8, 2026
b9c840d
Use parse on item schema in compactColumns forward decoder
claude Apr 11, 2026
eaf4fef
Move encodeToJsonSchema to top-level check in internalToJSONSchema
claude Apr 11, 2026
4ee0698
Move refinement application to another builder part
DZakh Apr 11, 2026
f0f0f5c
Derive itemSchema from selfSchema in compactColumns forward decoder
claude Apr 11, 2026
280df51
Derive compactColumns itemSchema from input.schema, not selfSchema
claude Apr 11, 2026
500b48a
Add test coverage for compactColumns edge cases
claude Apr 11, 2026
4567559
Remove ~negative flag from validation, emit positive form only
claude Apr 11, 2026
9c38fee
Merge pull request #189 from DZakh/claude/remove-negative-validation-…
DZakh Apr 11, 2026
79cc9bd
Fix error path propagation and async support in compactColumns
claude Apr 11, 2026
9e2e1fa
Add standalone S.isoDateTime with tree-shakeable regex
claude Apr 11, 2026
6e310f4
Refactor val.validation into a structured check list
claude Apr 11, 2026
32be5c4
Remove decorative comment in compactColumns tests
claude Apr 11, 2026
aebdf23
Merge branch 'dz/decode-encode' into claude/schema-parser-undefined-n…
claude Apr 11, 2026
7ddcecb
Use U.assertThrowsMessage in error path test
claude Apr 11, 2026
25c7c74
Make val.validation an optional field (absent when empty)
claude Apr 11, 2026
3c2652e
Improve compactColumns validation with per-field parsing and error paths
DZakh Apr 11, 2026
d46c476
Merge remote-tracking branch 'origin/dz/decode-encode' into claude/ad…
claude Apr 11, 2026
2e47b6d
Replace %raw clearChecks with plain None assignment
claude Apr 11, 2026
a5640e2
Add failing test for refiner-before-type-guard ordering
claude Apr 11, 2026
2468eba
Optimize validation helpers and drop compat wrapper
claude Apr 11, 2026
42ae259
Address review feedback for S.isoDateTime
claude Apr 11, 2026
3569869
Remove dead compactColumns encoder and simplify decoder
claude Apr 11, 2026
fada195
Use TagFlag bitmask for internalToJSONSchema structural-tag check
claude Apr 11, 2026
9206aec
Fix JSON validation chain after compactColumns in reverse direction
claude Apr 11, 2026
a50f383
Drop ~expected from failInvalidType; make it a stable function reference
claude Apr 11, 2026
02bef22
Document why isoDateTime.format = Some(DateTime) is needed
claude Apr 11, 2026
db5489b
Inline compactColumns decoder helper closures
claude Apr 11, 2026
82b49d5
Revert fail field type; keep helper simplification
claude Apr 11, 2026
5b5aa67
Tighten the structural-tag exclusion comment in internalToJSONSchema
claude Apr 11, 2026
682b495
Add FIXME for `received` on refine-chain vals in failInvalidType
claude Apr 11, 2026
49f00eb
Trim comments on the validation refactor
claude Apr 11, 2026
bbadc8c
Merge pull request #191 from DZakh/claude/refactor-compact-columns-dghLe
DZakh Apr 11, 2026
e471623
Merge remote-tracking branch 'origin/dz/decode-encode' into claude/re…
claude Apr 11, 2026
7ff4861
Review follow-ups: factor hoist helper, new tests, IDEAS notes
claude Apr 11, 2026
6ec722d
Skip per-field parse in compactColumns(S.json) and refresh S_test.ts …
claude Apr 11, 2026
69e63a3
Update IDEAS.md: plan to rename ReScript operations to parseOrThrow/d…
claude Apr 12, 2026
1c2c9bd
Derive compactColumns itemSchema from selfSchema, not input.schema
claude Apr 12, 2026
8c01ab6
Fix ReScript operations plan: parseOrThrow only has ~to, async as sep…
claude Apr 12, 2026
2bdd26d
Rename validationCheck → check, val.validation → val.checks, emitVali…
claude Apr 12, 2026
d555bc8
Refine ReScript operations plan: assertOrThrow, ~from required for de…
claude Apr 12, 2026
e1db7c0
Use labeled ~to arg for decodeUnsafeOrThrow
claude Apr 12, 2026
f496d0f
Use B.refine instead of direct input.checks mutation in compactColumn…
claude Apr 12, 2026
03b9add
Chain compactColumns per-field parse through declared source type
claude Apr 12, 2026
246bb86
Rename ~between to ~through (array of schemas), decodeUnsafe to decod…
claude Apr 12, 2026
1dbe84f
Refactor validation from functions to structured check arrays
DZakh Apr 12, 2026
71ac301
Merge dz/decode-encode (validation refactor) into branch
claude Apr 12, 2026
952336f
Remove decodeInputOrThrow, add parser/decoder/decoder1 builder functions
claude Apr 12, 2026
d26f02d
Make decoder ~to required, put ~through before ~to in arg order
claude Apr 12, 2026
753eb9e
Fix decoder1 return type to unknown => 'value
claude Apr 12, 2026
2311cec
Apply per-field reverse transform in compactColumns for typed sources
claude Apr 12, 2026
74cf920
Merge dz/decode-encode and regenerate Sury.res.mjs
claude Apr 12, 2026
a7affe1
Investigate failing tests in S_test.ts
DZakh Apr 12, 2026
f1ff0ad
WIP: Migrate refinements from codeFromPrev to structured checks
claude Apr 12, 2026
f408932
Merge remote-tracking branch 'origin/dz/decode-encode' into claude/re…
claude Apr 12, 2026
43a2bec
Simplify the structural-tag exclusion comment
claude Apr 12, 2026
6c15ea7
Merge remote-tracking branch 'origin/dz/decode-encode' into claude/ad…
claude Apr 12, 2026
98b5632
Add isoDateTime and enableIsoDateTime to Pack.res bundle mapping
claude Apr 12, 2026
999b59b
Implement ReScript API rename: parseOrThrow/decodeOrThrow with labele…
claude Apr 12, 2026
be13198
Update rescript-usage.md with new API documentation
claude Apr 12, 2026
32720cc
Update test snapshots and remove fixed-bug comments
claude Apr 12, 2026
38ab967
Fix decoder1 docs: schema input to output, not unknown to output
claude Apr 12, 2026
59e611b
Guard against empty checks array in parse loop refinement
claude Apr 12, 2026
8f6a303
Replace ~flag with separate async builder functions, add ~through to …
claude Apr 12, 2026
d9bbd9b
Extract B.failCustom helper and hoist urlValidator
claude Apr 12, 2026
139ac97
Add OrThrow links to docs TOC, replace IDEAS plan with changelog table
claude Apr 12, 2026
4acec5c
Set isInput/isOutput after refiner logic, not gated by checks length
claude Apr 12, 2026
522466a
Add compiled code snapshot for isoDateTime and docs nav entries
claude Apr 12, 2026
85a3290
Replace S.datetime with standalone S.isoDateTime schema
DZakh Apr 12, 2026
55619fa
Fix IDEAS.md: use S.compile (main branch name) in Before column
claude Apr 12, 2026
3112ae3
Revert S_union_test.res to base; document union hoist issue in IDEAS.md
claude Apr 12, 2026
996dfce
Merge dz/decode-encode, resolve conflicts, fix new tests to use new API
claude Apr 12, 2026
cebec27
Merge dz/decode-encode; convert isoDateTime refiner to check
claude Apr 12, 2026
9c0f5be
Refactor API: rename conversion functions and introduce builder pattern
DZakh Apr 12, 2026
bb68dc7
Clean up IDEAS.md: remove completed items, keep open TODOs
claude Apr 12, 2026
8d6fb2c
Merge dz/decode-encode; fix snapshot tests for cond||fail pattern
claude Apr 12, 2026
d8d8a91
Update JS API docs to match latest builder pattern API
claude Apr 12, 2026
b44f533
Replace S.unnest with S.compactColumns in JS API docs
claude Apr 12, 2026
e75f544
Restore Alpha.5 changelog section with operation rename tables
claude Apr 12, 2026
56fda4a
Use < > instead of <= >= for int32 bounds; inline length refinements
claude Apr 12, 2026
65098a1
Remove completed items from IDEAS.md
claude Apr 12, 2026
b2479e2
Revert int32FormatValidation to <= >= (cheaper int32 allocation)
claude Apr 12, 2026
4a0f4e2
Fix schema naming consistency and remove unnecessary S.schema wrapper
claude Apr 12, 2026
d2d503f
Reorganize v11 roadmap and ReScript API migration docs
DZakh Apr 12, 2026
32773ac
Update ReScript and PPX docs to match latest API
claude Apr 12, 2026
448f697
Inline refinement values, arrow url validator, assertNumber guard
claude Apr 12, 2026
007245b
Documentation updates and API consistency improvements
DZakh Apr 12, 2026
04cc581
Revert refine test snapshots to expose object-refine regression
claude Apr 12, 2026
fc8ffd2
Merge branch 'dz/decode-encode' into claude/refine-validation-checks-…
DZakh Apr 12, 2026
01641d1
Refactor refinements to use structured checks instead of code strings
DZakh Apr 12, 2026
d603a15
Improve assertNumber error to show actual value instead of type name
claude Apr 12, 2026
365fafc
Improve assertNumber error to show refinement name and actual value
claude Apr 12, 2026
31d70fd
Generalize jsonDecoder to attempt decode to string for non-JSON types
claude Apr 12, 2026
d7dfac9
Merge pull request #199 from DZakh/claude/improve-assertnumber-error-…
DZakh Apr 12, 2026
ca96c81
Remove unnecessary B.Val.scope in jsonDecoder try/catch
claude Apr 12, 2026
588066c
Preserve .to chain when attempting string decode in jsonDecoder
claude Apr 12, 2026
c4129b9
Refactor port, email, uuid, cuid, url into standalone schemas using f…
claude Apr 12, 2026
ecf1d12
Store built-in refinements as JSON Schema fields on the schema
claude Apr 12, 2026
4bb8f68
Move errorMessages to base type, remove empty modules, drop @as on pa…
claude Apr 13, 2026
1e3012f
Update generated S.res.mjs to remove empty module re-exports
claude Apr 13, 2026
e28c9e6
Rename UnsupportedConversion to UnsupportedDecode, unify error message
claude Apr 13, 2026
c09be1d
Add actionable hint to unsupportedDecode error message
claude Apr 13, 2026
467516a
Update error hint to "Use S.to to define a custom decoder"
claude Apr 13, 2026
243993a
Use labeled ~mut arg, add Int32 min/max to JSON Schema, simplify test…
claude Apr 13, 2026
f320667
Keep S.pattern as pipe-based refinement function
claude Apr 13, 2026
e97d035
Fix setErrorMessage mutating original schema's errorMessages dict
claude Apr 13, 2026
7dd0863
Update IDEAS.md changelog with jsonDecoder and error rename changes
claude Apr 13, 2026
cdc91e7
Rename setErrorMessage to getMutErrorMessages, call Dict.set at call …
claude Apr 13, 2026
18861e0
Add compiled code snapshot and jsonString test for date→JSON, fix com…
claude Apr 13, 2026
38f8f4b
Rename unsupported_conversion to unsupported_decode with improved mes…
DZakh Apr 13, 2026
f520cac
Simplify getMutErrorMessages using ternary with X.Dict.copy
claude Apr 13, 2026
2488546
Merge branch 'dz/decode-encode' into claude/document-built-in-refiner…
claude Apr 13, 2026
64aabf1
Refactor constraint validation to use schema properties instead of me…
DZakh Apr 13, 2026
6dad726
Support decoding from JSON/jsonString to Date (jsonToDate)
claude Apr 13, 2026
ddf8b55
Merge dz/decode-encode: use errorMessages with format and pattern keys
claude Apr 13, 2026
ef90ce7
Remove String.Refinement module in favor of schema pattern field
claude Apr 13, 2026
ef8924c
Update generated .mjs files
claude Apr 13, 2026
bfea2da
Generalize jsonEncoder string fallback to all non-union/ref types
claude Apr 13, 2026
7de43ab
Use dict{} for errorMessages, reuse message vars, update docs
claude Apr 13, 2026
1b04b5d
Rename errorMessages to errorMessage
claude Apr 13, 2026
177f7ad
Support custom error messages via S.meta({ errorMessage })
claude Apr 13, 2026
616684f
Add typed errorMessage record instead of dict{}
claude Apr 13, 2026
eed92c9
Add _ catch-all to errorMessage, reuse type internally
claude Apr 13, 2026
e4097c5
Use failWithErrorMessage everywhere, remove failCustom
claude Apr 13, 2026
9d39ff1
Fix test syntax, add errorMessage test coverage, update docs
claude Apr 13, 2026
a6c5ecd
Fix review issues: port custom message, missing tests, style
claude Apr 13, 2026
db5e48c
Port errorMessage uses format key, not type
claude Apr 13, 2026
54d3799
Add test for decoding JSON array of dates
claude Apr 13, 2026
c061c5f
Rename type to schemaErrorMessage, port uses failWithErrorMessage,
claude Apr 13, 2026
92fa3a8
Merge dz/decode-encode (constraint validation refactor)
claude Apr 13, 2026
9583d17
Remove redundant bigint branch from jsonEncoder
claude Apr 13, 2026
55a469c
Fix JSON encoding/decoding for Date types and refactor shaped serializer
DZakh Apr 13, 2026
ecbe6a2
Add Custom error messages to docs table of contents
claude Apr 13, 2026
a797ba4
Docs: mention ~message param for built-in refinements in error messag…
claude Apr 13, 2026
08b784f
Port default message "Expected port", clean up IDEAS.md
claude Apr 13, 2026
4498303
Add errorMessage to every schema variant
claude Apr 14, 2026
287212c
Port default message includes received value
claude Apr 14, 2026
6d0475b
Merge failInvalidTypeWithErrorMessage into failWithErrorMessage
claude Apr 14, 2026
55f1e44
Drop default message for all standalone format schemas
claude Apr 14, 2026
d355b40
Refactor error messages to use structured schema-level configuration
DZakh Apr 14, 2026
a96ee2d
Add failing reproduction for type errorMessage override
claude Apr 14, 2026
963accd
Honor errorMessage type/catchAll on type-check failures
claude Apr 15, 2026
8abe345
Support custom type error messages via S.meta errorMessage
DZakh Apr 15, 2026
1a27d53
Update int32 JSON Schema tests to include minimum/maximum
claude Apr 15, 2026
e6a102f
Merge pull request #205 from DZakh/claude/investigate-failing-errors-…
DZakh Apr 15, 2026
29252ee
Unify duplicated union merge logic into B.merge
claude Apr 15, 2026
8e64e3a
Refactor merge function to support hoisting checks in union codegen
DZakh Apr 16, 2026
94c58b3
Fix shapedSerializer error message showing "unknown" instead of targe…
claude Apr 16, 2026
968da7d
Fix received schema in validation errors to use pre-narrowing type
claude Apr 16, 2026
ac3b08e
Fix received schema in error messages for type mismatches
DZakh Apr 16, 2026
97a00d8
Remove unnecessary reverse call in error message generation
DZakh Apr 16, 2026
01be987
Fix recursive schema crash when transforms follow recursive decoder
claude Apr 16, 2026
772732d
Fix indentation leak in compiled code snapshot for recursive transfor…
claude Apr 16, 2026
da555c1
Fix ReverseConvert snapshot for recursive transform test
claude Apr 16, 2026
b2d7e18
Use ~embedded with dynamic seq to include Node def in ReverseConvert …
claude Apr 16, 2026
e8fa185
Fix recursive schema reuse in transform chains
DZakh Apr 16, 2026
d3c2df4
Add const field to Object and Tuple (Array) schema variants
claude Apr 16, 2026
7db04db
Remove TODO comment for Object and Tuple const
claude Apr 16, 2026
67227ee
Clean up whitespace and remove outdated TODO comment
DZakh Apr 16, 2026
59901e5
Refresh stale recursive test snapshots and fix mis-shaped assertion
claude Apr 16, 2026
a0c441c
Refresh stale recursive test snapshots and fix mis-shaped assertion
DZakh Apr 17, 2026
32db5fc
Force async object fields to materialize as a variable
claude Apr 17, 2026
24eb514
Explain why async var allocation must precede val->merge
claude Apr 17, 2026
9c4fff7
Fix async field handling in object parsing
DZakh Apr 17, 2026
f4145c9
Update e2e package to current sury API
claude Apr 19, 2026
8c9d37c
Use S.url/S.email directly in PPX tests; shim genType import
claude Apr 19, 2026
0486952
Upgrade rescript to 12.2.0
claude Apr 19, 2026
178caa5
Revert rescript upgrade to 12.0.0-beta.5
claude Apr 20, 2026
41e46e2
Re-enable @s.null PPX tests; point shim FIXME at #8375
claude Apr 20, 2026
756d4de
Revert type null -> nullType rename
claude Apr 20, 2026
6c54702
Update API calls to match new Sury schema compilation interface
DZakh Apr 20, 2026
3fb542a
Document union coercion dispatch algorithm in IDEAS.md
claude Apr 20, 2026
6f8e7ae
Rename "dispatch" to "match" in union coercion docs
claude Apr 20, 2026
91ce1d4
Generalize union coercion matching to non-union sources
claude Apr 20, 2026
ef8f237
Clarify derived source tag; drop try/catch mention in tier 3
claude Apr 20, 2026
1e1aab1
Document union coercion algorithm and matching strategy
DZakh Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_response.filePath // .tool_input.file_path' | { read -r f; if [[ \"$f\" == *.res ]]; then npx rescript format \"$f\" > /dev/null; fi; } 2>/dev/null || true",
"statusMessage": "Formatting ReScript..."
}
]
}
]
}
}
8 changes: 8 additions & 0 deletions .cursor/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"wallaby": {
"command": "node",
"args": ["~/.wallaby/mcp/"]
}
}
}
63 changes: 63 additions & 0 deletions .cursor/skills/testing-wallaby/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: testing-wallaby
description: Debug and fix failing tests using Wallaby.js MCP tools. Use when investigating test failures, debugging test errors, inspecting runtime values, checking code coverage, or updating snapshots.
---

# Testing with Wallaby

Use Wallaby MCP tools as the primary way to work with tests. Fall back to terminal only if Wallaby is unavailable.

## Debug Workflow

### 1. Identify failures

- **Broad**: `wallaby_failingTests` — all failing tests in the project
- **By file**: `wallaby_failingTestsForFile` — failures related to a specific source or test file
- **By line**: `wallaby_failingTestsForFileAndLine` — failures covering a specific line

Each returns test name, test ID, errors with stack traces, runtime logs, and coverage percentage.

### 2. Narrow down with coverage

- `wallaby_coveredLinesForFile` — which lines a file has covered, optionally filtered by test ID
- `wallaby_coveredLinesForTest` — all files/lines a specific test covers

Use coverage to find the implementation code a failing test actually executes.

### 3. Inspect runtime values

- `wallaby_runtimeValues` — value of an expression at a file/line across all tests
- `wallaby_runtimeValuesByTest` — value of an expression at a file/line for a specific test

Required params: `file`, `line` (1-based, count blank lines), `lineContent`, `expression`. For `runtimeValuesByTest`, also `testId`.

### 4. Fix the code

Apply the fix based on evidence from steps 1-3.

### 5. Verify the fix

- `wallaby_testById` — re-check a specific test by its ID
- `wallaby_failingTests` — confirm no remaining failures

Iterate steps 3-5 until the test passes.

### 6. Update snapshots (if needed)

- `wallaby_updateTestSnapshots` — update snapshots for one test (by test ID)
- `wallaby_updateFileSnapshots` — update all snapshots in/covering a file
- `wallaby_updateProjectSnapshots` — update every snapshot in the project

## Discovery Tools

Use these when exploring tests, not just debugging failures:

- `wallaby_allTests` — list every test in the project
- `wallaby_allTestsForFile` — tests related to a specific file
- `wallaby_allTestsForFileAndLine` — tests covering a specific file and line

## Principles

- Always cite runtime values and coverage data to justify conclusions.
- Explain reasoning step by step.
- Keep iterating with updated Wallaby data until the test passes.
104 changes: 104 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Sury Architecture

## Schema Input and Output Types

A schema represents two types: Input and Output.

### Example 1: Same Input and Output

```typescript
S.string
// Input: string
// Output: string
```

### Example 2: Different Input and Output

```typescript
S.schema({
foo: S.string.with(S.to, S.number)
})
// Input: { foo: string }
// Output: { foo: number }
```

The input and output differ because nested items have transformations, even though the schema itself does not have a `.to` property.

## Modifying a Schema

When modifying a schema, the modification applies to the output type.

```typescript
S.schema({
foo: S.string.with(S.to, S.number)
}).with(S.refine, () => {...})
```

Since this schema does not have `.to`, `inputRefiner` and `refiner` must be stored separately to support `S.reverse`. Every schema should be reversible from Input→Output to Output→Input, unless explicitly prevented.

For modifications like `name` or built-in refinements that do not affect nested items, they apply to both input and output without differentiation.

## Decode Function

The decode function is created from a single schema and transforms the schema's Input to Output. When multiple schemas are joined by the `.to` property, they are automatically combined into a single transformation pipeline.

## Schema Properties and Execution Order

Schema properties are executed in the following order:

1. **decoder** - If input val differs from the schema, decode it to the schema's input type. May skip directly to schema output if there is no inputRefiner.

2. **inputRefiner** - Custom validations on the input part of the schema value.

3. **decoder** - Decodes input to output for the current schema. Typically required to decode nested items such as object fields.

4. **refiner** - Custom validations on the output part of the schema value.

### If Schema Has `.to` Property

5. **parser** - Custom transformation logic to the `.to` schema. The serializer is the reverse of parser.

### If There Is No Parser

5. **encoder** - Transformation logic from the current schema's output to the `.to` schema's input.

6. **.to.decoder** - Starts the cycle from the beginning with the `.to` schema.

## Reversal with S.reverse

`S.reverse` swaps:

- `inputRefiner` ↔ `refiner`
- `parser` ↔ `serializer`
- Reverses the `.to` chain direction

## Async Support

Every transformation may return an async value. To continue the transformation chain:

1. Append `.then()` and continue the logic in the callback function.
2. For nested items (e.g., object fields, array items), create a promise that collects all inner items with `Promise.all()`.

## Val

The `val` represents a value at a specific point in time during compilation. Each `val` reflects a specific value type at that moment.

Key properties:

- `schema` - The actual type of the value at this point
- `expected` - The schema to build decoder for
- `var` - Returns the variable name in generated code
- `inline` - The value as an inline code expression
- `path` - Current location in the data structure (for error messages)

Transformation tracking (relative to `.prev`):

- `prev` - The previous val in the chain, indicating where this value originated from
- `code` - Generated code describing the transformation from `.prev` to this val
- `validation` - Type check condition from `.prev` (e.g., `typeof x === "string"`). Different from custom refiners.

This design allows tracing back through the transformation history, where each step records what code was generated and what validations were applied to get from the previous state to the current one.

- `B.refine` allows to modify the value, by cloning, while keeping the var allocation link.

- `skipTo` is used to abort the parse after finishing current decoder. Ideally to get rid of it and use `val.expected` instead.
121 changes: 121 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,127 @@ The following steps will get you setup to contribute changes to this repo:
5. Run `pnpm res` to run ReScript compiler
6. Run `pnpm test` for tests or use Wallaby.js

## Architecture

This section describes the internal architecture of Sury to help with understanding and contributing to the codebase.

### Core Concepts

#### Schema (internal type)

The internal representation of a type schema, containing:

- `tag`: Type identifier (e.g., `stringTag`, `objectTag`, `arrayTag`)
- `decoder`: Builder function for input validation (type checking)
- `encoder`: Builder function for converting from different schema types
- `parser`: Builder function for transformations after decoding (used by `S.shape`, `S.to`)
- `serializer`: Builder function for reverse transformations
- `to`: Target schema for transformations (set by `S.shape`, `S.to`)
- `from`: Path array indicating where this value comes from in shaped schemas
- `properties`: For object schemas, a dict of field name to schema
- `items`: For array/tuple schemas, an array of item schemas

#### Builder

A builder is a function with signature `(~input: val, ~selfSchema: internal) => val`. Builders generate JavaScript code at compile time by manipulating `val` objects. They are created using `Builder.make`:

```rescript
let myBuilder = Builder.make((~input, ~selfSchema) => {
// Generate code and return output val
let output = input->B.val(`someTransform(${input.var()})`, ~schema=selfSchema)
output
})
```

#### Val (Value)

A compilation-time representation of a value being processed. Key fields:

- `inline`: The generated code expression (e.g., `i["foo"]`, `v0`)
- `var()`: Function to allocate/retrieve a variable name (use when value is referenced multiple times)
- `schema`: The schema of the current value
- `expected`: The schema we're trying to parse/convert into
- `from`: Link to the input val (for code merging)
- `code`: Generated code statements
- `validation`: Optional validation function to generate type checks
- `skipTo`: When `Some(true)`, prevents `parse` from following the `.to` chain
- `global`: Shared compilation context containing:
- `embeded`: Array of embedded values (functions, constants) accessible as `e[n]`
- `varCounter`: Counter for generating unique variable names

### Compilation Flow

When a schema operation is compiled (e.g., `parseOrThrow`), the following happens:

```
Input Schema
┌─────────────────────────────────────────────────────────┐
│ parse(val) function │
│ │
│ 1. Encoder (if input.schema !== expected) │
│ - Converts between different schema types │
│ │
│ 2. Decoder (always runs) │
│ - Validates input type (e.g., typeof === "string") │
│ - Generates validation code │
│ │
│ 3. Parser (if expected.parser exists) │
│ - Applies transformations (S.transform, S.shape) │
│ │
│ 4. Recursive parse (if expected.to exists) │
│ - Follows transformation chain │
│ - Skipped if val.skipTo === Some(true) │
└─────────────────────────────────────────────────────────┘
Output Val with merged code
B.merge() → JavaScript function string
```

### Code Generation Example

For `S.object(s => s.field("foo", S.string))`:

```javascript
// Generated parse function:
(i) => {
if (typeof i !== "object" || !i) {
e[0](i);
} // Object validation
let v0 = i["foo"]; // Field access
if (typeof v0 !== "string") {
e[1](v0);
} // String validation
return v0; // Return parsed value
};
```

Where:

- `i` is the input argument
- `e` is the embedded values array (error throwers, transformers)
- `v0`, `v1`, etc. are allocated variables

### Key Functions

- `parse(val)`: Main compilation function that walks through encoder → decoder → parser → to chain
- `B.merge(val)`: Collects all generated code from the val chain into a single string
- `B.Val.cleanValFrom(val)`: Creates a clean copy of val for new code generation while preserving variable binding
- `B.embed(val, value)`: Embeds a runtime value (function, object) and returns reference like `e[0]`

### Shaped Schemas (S.shape, S.object with definer)

Shaped schemas use a proxy-based approach to track how values are used:

1. During schema definition, field accesses are tracked via `proxifyShapedSchema`
2. Each accessed field gets `from` set to its path (e.g., `["foo"]` for `s.field("foo", ...)`)
3. During parsing, `shapedParser` traverses the target structure and maps values from input
4. During serialization, `shapedSerializer` builds an accumulator (`acc`) that maps output paths to input vals, then `getShapedSerializerOutput` reconstructs the original structure

## PPX

### With Dune
Expand Down
Loading
Loading