From e8274a4e306f1f9fe29087936cbcd4d736d11611 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Aug 2026 03:11:31 +0000 Subject: [PATCH] Remove redundant Capy API functions. --- docs/capy-capability-manifest.md | 10 +- docs/setup.md | 4 +- docs/wasm-runtime-architecture.md | 2 +- docs/work/api-surface-2.md | 38 ++ scripts/api_coverage_manifest.py | 12 +- scripts/capy_artifact_golden.sha256 | 478 +++++++++--------- scripts/test_capy_native.sh | 4 +- scripts/test_capy_native_compiler.cpp | 5 +- scripts/test_capy_phase1.sh | 31 +- scripts/test_capy_reference.sh | 6 +- scripts/test_password_hashing.sh | 6 +- site/doc/areas/memcache.txt | 1 - site/doc/areas/noise.txt | 4 +- site/doc/areas/ob.txt | 1 - site/doc/areas/string.txt | 1 - site/doc/areas/sys.txt | 1 - site/doc/components/all.capy | 8 +- site/doc/components/index.capy | 8 +- site/doc/components/search.capy | 40 +- site/doc/content/api/ascii-safe-name.capy | 3 - site/doc/content/api/component-exists.capy | 4 - site/doc/content/api/component-render.capy | 2 +- site/doc/content/api/component-resolve.capy | 4 +- site/doc/content/api/component.capy | 6 +- site/doc/content/api/crypto-equal.capy | 2 +- site/doc/content/api/gen-sha1.capy | 2 +- site/doc/content/api/hex.capy | 3 + site/doc/content/api/hmac-sha256-hex.capy | 3 - site/doc/content/api/hmac-sha256.capy | 2 +- site/doc/content/api/job-await.capy | 2 +- site/doc/content/api/job-cancel.capy | 2 +- site/doc/content/api/job-result.capy | 2 +- site/doc/content/api/job-status.capy | 2 +- site/doc/content/api/memcache-command.capy | 2 +- site/doc/content/api/memcache-connect.capy | 2 +- site/doc/content/api/memcache-delete.capy | 2 +- site/doc/content/api/memcache-escape-key.capy | 3 - .../content/api/memcache-get-multiple.capy | 2 +- site/doc/content/api/memcache-get.capy | 2 +- site/doc/content/api/memcache-set.capy | 2 +- site/doc/content/api/password-hash.capy | 2 +- .../content/api/password-needs-rehash.capy | 3 - site/doc/content/api/password-verify.capy | 2 +- site/doc/content/api/sha256-hex.capy | 3 - site/doc/content/api/sha256.capy | 2 +- site/doc/content/api/shell-exec.capy | 3 +- site/doc/content/api/shell-spawn.capy | 3 - site/doc/content/api/upper.capy | 2 +- site/doc/content/guide/tasks-and-jobs.capy | 8 +- site/doc/content/handler/component.capy | 4 +- site/doc/lib/capy_signatures.generated.h | 11 +- site/doc/source/api/ascii_safe_name.txt | 19 - site/doc/source/api/component.txt | 7 +- site/doc/source/api/component_exists.txt | 45 -- site/doc/source/api/component_render.txt | 1 - site/doc/source/api/component_resolve.txt | 11 +- site/doc/source/api/crypto_equal.txt | 6 +- site/doc/source/api/gen_sha1.txt | 14 +- site/doc/source/api/hex.txt | 21 + site/doc/source/api/hmac_sha256.txt | 4 +- site/doc/source/api/hmac_sha256_hex.txt | 20 - site/doc/source/api/job_await.txt | 2 +- site/doc/source/api/job_cancel.txt | 2 +- site/doc/source/api/job_result.txt | 4 +- site/doc/source/api/job_status.txt | 2 +- site/doc/source/api/memcache_command.txt | 4 + site/doc/source/api/memcache_connect.txt | 2 + site/doc/source/api/memcache_delete.txt | 4 +- site/doc/source/api/memcache_escape_key.txt | 20 - site/doc/source/api/memcache_get.txt | 4 +- site/doc/source/api/memcache_get_multiple.txt | 4 +- site/doc/source/api/memcache_set.txt | 4 +- site/doc/source/api/password_hash.txt | 3 +- site/doc/source/api/password_needs_rehash.txt | 21 - site/doc/source/api/password_verify.txt | 1 - site/doc/source/api/sha256.txt | 7 +- site/doc/source/api/sha256_hex.txt | 11 - site/doc/source/api/shell_exec.txt | 29 +- site/doc/source/api/shell_spawn.txt | 12 - site/doc/source/api/upper.txt | 1 - site/doc/source/guide/11-tasks-and-jobs.txt | 6 +- site/doc/source/handler/component.txt | 4 +- site/tests/capy-component-props.capy | 3 +- site/tests/capy-coreutil.capy | 2 +- site/tests/capy-crypto-random.capy | 2 +- site/tests/capy-jobs.capy | 8 +- site/tests/capy-memcache.capy | 25 +- .../capy-shell-exec-background-type-trap.capy | 1 + site/tests/capy-shell-exec-env-list-trap.capy | 1 + .../tests/capy-shell-exec-env-value-trap.capy | 1 + site/tests/capy-shell-exec-flags-trap.capy | 1 + .../capy-shell-exec-stdin-type-trap.capy | 1 + .../capy-shell-exec-timeout-type-trap.capy | 1 + .../capy-shell-exec-timeout-value-trap.capy | 1 + src/capy/compiler.cpp | 7 + src/capy/parity_manifest.h | 10 +- src/capy/stdlib.capy | 59 +-- src/capy/stdlib.embedded.h | 4 +- src/lib/compiler.cpp | 15 +- src/lib/compiler.h | 1 - src/lib/functionlib.cpp | 5 - src/lib/functionlib.h | 1 - src/lib/hash.cpp | 41 +- src/lib/hash.h | 7 +- src/lib/sys.cpp | 61 +-- src/lib/sys.h | 7 +- src/lib/uri.cpp | 7 +- src/wasm/abi.h | 2 +- src/wasm/core.cpp | 119 +++-- src/wasm/core_hostcalls.syms | 5 +- src/wasm/worker.cpp | 66 +-- 111 files changed, 721 insertions(+), 795 deletions(-) create mode 100644 docs/work/api-surface-2.md delete mode 100644 site/doc/content/api/ascii-safe-name.capy delete mode 100644 site/doc/content/api/component-exists.capy create mode 100644 site/doc/content/api/hex.capy delete mode 100644 site/doc/content/api/hmac-sha256-hex.capy delete mode 100644 site/doc/content/api/memcache-escape-key.capy delete mode 100644 site/doc/content/api/password-needs-rehash.capy delete mode 100644 site/doc/content/api/sha256-hex.capy delete mode 100644 site/doc/content/api/shell-spawn.capy delete mode 100644 site/doc/source/api/ascii_safe_name.txt delete mode 100644 site/doc/source/api/component_exists.txt create mode 100644 site/doc/source/api/hex.txt delete mode 100644 site/doc/source/api/hmac_sha256_hex.txt delete mode 100644 site/doc/source/api/memcache_escape_key.txt delete mode 100644 site/doc/source/api/password_needs_rehash.txt delete mode 100644 site/doc/source/api/sha256_hex.txt delete mode 100644 site/doc/source/api/shell_spawn.txt create mode 100644 site/tests/capy-shell-exec-background-type-trap.capy create mode 100644 site/tests/capy-shell-exec-env-list-trap.capy create mode 100644 site/tests/capy-shell-exec-env-value-trap.capy create mode 100644 site/tests/capy-shell-exec-flags-trap.capy create mode 100644 site/tests/capy-shell-exec-stdin-type-trap.capy create mode 100644 site/tests/capy-shell-exec-timeout-type-trap.capy create mode 100644 site/tests/capy-shell-exec-timeout-value-trap.capy diff --git a/docs/capy-capability-manifest.md b/docs/capy-capability-manifest.md index 2f5ba739..f080ab80 100644 --- a/docs/capy-capability-manifest.md +++ b/docs/capy-capability-manifest.md @@ -3,7 +3,7 @@ Generated by `capyc --parity-manifest` from `site/doc/source/`. This inventory is a progress boundary: `partial`, `export-only`, and `missing` are not parity. -Documented pages: **225**. supported: **225** +Documented pages: **219**. supported: **219** ## Binding boundary @@ -16,7 +16,6 @@ Documented pages: **225**. supported: **225** | Documented capability | Category | Status | Evidence/remaining work | |---|---|---|---| | `array_merge` | core utility | **supported** | Runtime evidence: `site/tests/capy-dval-merge.capy`. | -| `ascii_safe_name` | core utility | **supported** | Runtime evidence: `site/tests/capy-coreutil.capy`. | | `backtrace_capture` | core utility | **supported** | Runtime evidence: `site/tests/capy-coreutil.capy`. | | `backtrace_get_frames` | core utility | **supported** | Runtime evidence: `site/tests/capy-backtrace.capy`. | | `base64_decode` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-codecs.capy`. | @@ -29,7 +28,6 @@ Documented pages: **225**. supported: **225** | `clear` | structured values | **supported** | Runtime evidence: `site/doc/source/api/clear.txt`. | | `clone` | core utility | **supported** | Runtime evidence: `site/doc/source/api/clone.txt`. | | `component` | unit/component | **supported** | Runtime evidence: `site/tests/capy-component-parity.capy`. | -| `component_exists` | unit/component | **supported** | Runtime evidence: `site/tests/capy-component-props.capy`. | | `component_render` | unit/component | **supported** | Runtime evidence: `site/tests/capy-component-parity.capy`. | | `component_resolve` | unit/component | **supported** | Runtime evidence: `site/tests/capy-component-props.capy`. | | `contains` | core utility | **supported** | Runtime evidence: `site/tests/capy-strings.capy`. | @@ -96,8 +94,8 @@ Documented pages: **225**. supported: **225** | `handler/render` | handler/lifecycle | **supported** | Runtime evidence: `site/tests/capy-request-context.capy`. | | `handler/ws` | handler/lifecycle | **supported** | Runtime evidence: `site/tests/capy-websocket.capy`. | | `has` | structured values | **supported** | Runtime evidence: `site/doc/source/api/has.txt`. | +| `hex` | core utility | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | | `hmac_sha256` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | -| `hmac_sha256_hex` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | | `html_escape` | codecs/text | **supported** | Runtime evidence: `site/tests/capy-codecs-text.capy`. | | `http_request` | network/websocket | **supported** | Runtime evidence: `site/tests/capy-network-parity.capy`. | | `http_request_async` | network/websocket | **supported** | Runtime evidence: `site/tests/capy-network-parity.capy`. | @@ -122,7 +120,6 @@ Documented pages: **225**. supported: **225** | `memcache_command` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | | `memcache_connect` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | | `memcache_delete` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | -| `memcache_escape_key` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | | `memcache_get` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | | `memcache_get_multiple` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | | `memcache_set` | data/cache | **supported** | Runtime evidence: `site/tests/capy-memcache.capy`. | @@ -140,7 +137,6 @@ Documented pages: **225**. supported: **225** | `parse_query` | core utility | **supported** | Runtime evidence: `site/tests/capy-coreutil.capy`. | | `parse_uri` | core utility | **supported** | Runtime evidence: `site/tests/capy-coreutil.capy`. | | `password_hash` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | -| `password_needs_rehash` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | | `password_verify` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | | `path_is_within` | filesystem | **supported** | Runtime evidence: `site/tests/capy-files2.capy`. | | `path_join` | filesystem | **supported** | Runtime evidence: `site/tests/capy-files2.capy`. | @@ -176,10 +172,8 @@ Documented pages: **225**. supported: **225** | `session_start` | request/response | **supported** | Runtime evidence: `site/tests/capy-session.capy`. | | `set` | structured values | **supported** | Runtime evidence: `site/doc/source/api/set.txt`. | | `sha256` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | -| `sha256_hex` | crypto/random | **supported** | Runtime evidence: `site/tests/capy-crypto-random.capy`. | | `shell_escape` | jobs/process | **supported** | Runtime evidence: `site/tests/capy-jobs.capy`. | | `shell_exec` | jobs/process | **supported** | Runtime evidence: `site/tests/capy-jobs.capy`. | -| `shell_spawn` | jobs/process | **supported** | Runtime evidence: `site/tests/capy-jobs.capy`. | | `socket_close` | network/websocket | **supported** | Runtime evidence: `site/tests/capy-network-parity.capy`. | | `socket_connect` | network/websocket | **supported** | Runtime evidence: `site/tests/capy-network-parity.capy`. | | `socket_read` | network/websocket | **supported** | Runtime evidence: `site/tests/capy-network-parity.capy`. | diff --git a/docs/setup.md b/docs/setup.md index 2325e29b..a22d2b65 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -719,11 +719,11 @@ if(encoded == "") // fail the write; native hashing did not complete bool valid = password_verify(candidate, encoded); -if(valid && password_needs_rehash(encoded)) +if(valid && encoded.rfind("$bearer$scrypt$65536$8$1$", 0) != 0) encoded = password_hash(candidate); ``` -`password_hash()` returns a self-contained `$bearer$scrypt$...` encoding with a random 16-byte salt and the bounded scrypt parameters `N=65536`, `r=8`, `p=1`. `password_verify()` accepts only structurally valid encodings with bounded cost parameters and compares the derived key in constant time. `password_needs_rehash()` reports malformed, legacy, or non-current parameters so applications can upgrade a credential after a successful legacy verification. Treat an empty hash as an operational failure and never store it. Application-level password length policy, rate limiting, and legacy-format verification remain the application's responsibility. +`password_hash()` returns a self-contained `$bearer$scrypt$...` encoding with a random 16-byte salt and the bounded scrypt parameters `N=65536`, `r=8`, `p=1`. `password_verify()` accepts only structurally valid encodings with bounded cost parameters and compares the derived key in constant time. After successful verification, compare the stored parameter prefix with the parameters you require. Rehash the known password when the prefixes differ. Treat an empty hash as an operational failure and never store it. Application-level password length policy, rate limiting, and legacy-format verification remain the application's responsibility. ## Operational footguns diff --git a/docs/wasm-runtime-architecture.md b/docs/wasm-runtime-architecture.md index d40cef6c..cee4b659 100644 --- a/docs/wasm-runtime-architecture.md +++ b/docs/wasm-runtime-architecture.md @@ -129,7 +129,7 @@ __bearer_[_] | `component:CARD` | `__bearer_component_CARD` | | `exists` | probe only — resolves the unit, loads nothing | -`sanitize_symbol_suffix()` keeps `[A-Za-z0-9_]` (mirrors `ascii_safe_name`). +`sanitize_symbol_suffix()` keeps `[A-Za-z0-9_]` (mirrors `safe_name()`). Unit code is hidden by default so the linker can discard loaded helpers that the unit does not use. Handler macros and the explicit `EXPORT` directive are the only application symbols promoted to default visibility; generated request diff --git a/docs/work/api-surface-2.md b/docs/work/api-surface-2.md new file mode 100644 index 00000000..d9aa016e --- /dev/null +++ b/docs/work/api-surface-2.md @@ -0,0 +1,38 @@ +# Capy API surface removals + +## Objective and invariants + +Remove redundant or misleading Capy APIs without aliases or compatibility shims. + +- Keep `safe_name`. Remove `ascii_safe_name` and its duplicate host operation. +- Replace every `component_exists` call with `length(component_resolve(name)) > 0`. +- Normalize memcache keys at the host boundary. Document key collisions. +- Make all digest functions return raw bytes. Use lowercase `hex()` for text. +- Keep the one-argument `shell_exec` behavior. Add a strict two-argument background overload. +- Remove the Capy `password_needs_rehash` surface. Preserve required host behavior. +- Regenerate the artifact golden file after all other changes and gates. + +## Success criteria + +- [x] Removed symbols fail compilation and have no pages, manifests, or call sites. +- [x] Replacement behavior has focused runtime tests. +- [x] All required acceptance gates return zero. +- [x] The artifact golden write and plain check are the final validation steps. + +## Current state + +- Status: complete +- Source/runtime: `/root/mount_ssh/capy-bearer`, `root@10.4.2.122:/Code/capy-bearer` + +## Goal tree + +- [x] G1: Implement runtime and standard-library changes. +- [x] G2: Port callers and add focused tests. +- [x] G3: Remove and update authored documentation. +- [x] G4: Regenerate generated documentation and manifests. +- [x] G5: Run acceptance gates and regenerate the golden file last. + +## Decisions + +- `memcache_command` needs protocol-aware key normalization. It must not replace whitespace in the complete command. +- Public BRRB and callable dynamic-value behavior from the preceding task must remain unchanged. diff --git a/scripts/api_coverage_manifest.py b/scripts/api_coverage_manifest.py index 89c35020..e8c652df 100644 --- a/scripts/api_coverage_manifest.py +++ b/scripts/api_coverage_manifest.py @@ -52,7 +52,7 @@ DOC_PAGE_ALIASES = { # name, needs_doc, status. status: public | internal | integration PUBLIC_APIS = [ ("http_request", True, "public"), ("http_request_async", True, "public"), - ("shell_exec", True, "public"), ("shell_escape", True, "public"), ("shell_spawn", True, "public"), + ("shell_exec", True, "public"), ("shell_escape", True, "public"), ("job_status", True, "public"), ("job_result", True, "public"), ("job_await", True, "public"), ("job_cancel", True, "public"), # The frozen historical task pages describe the removed callback/PID API; # current task coverage is runtime fixtures until their replacement lands. @@ -67,16 +67,16 @@ PUBLIC_APIS = [ ("runtime_perf", True, "public"), ("time_format_local", True, "public"), ("time_format_relative", True, "public"), ("time_parse", True, "public"), ("backtrace_get_frames", False, "public"), ("backtrace_capture", False, "public"), - ("signal_name", False, "public"), ("memcache_escape_key", True, "public"), + ("signal_name", False, "public"), ("memcache_command", True, "public"), ("memcache_get_multiple", True, "public"), ("runtime_safe_key", True, "public"), ("nibble", True, "public"), ("json_consume_space", False, "internal"), - ("array_merge", True, "public"), ("safe_name", True, "public"), ("ascii_safe_name", True, "public"), + ("array_merge", True, "public"), ("safe_name", True, "public"), ("remove", False, "public"), ("clear", False, "public"), - ("gen_sha1", True, "public"), ("sha256", True, "public"), ("sha256_hex", True, "public"), - ("hmac_sha256", True, "public"), ("hmac_sha256_hex", True, "public"), ("random_bytes", True, "public"), + ("gen_sha1", True, "public"), ("sha256", True, "public"), ("hex", True, "public"), + ("hmac_sha256", True, "public"), ("random_bytes", True, "public"), ("crypto_equal", True, "public"), ("password_hash", True, "public"), - ("password_verify", True, "public"), ("password_needs_rehash", True, "public"), + ("password_verify", True, "public"), ("gen_noise32", True, "public"), ("gen_noise64", True, "public"), ("gen_noise01", True, "public"), ("gen_int", True, "public"), ("gen_float", True, "public"), ("draw_int", True, "public"), ("draw_float", True, "public"), diff --git a/scripts/capy_artifact_golden.sha256 b/scripts/capy_artifact_golden.sha256 index bfe5af68..d66cfeda 100644 --- a/scripts/capy_artifact_golden.sha256 +++ b/scripts/capy_artifact_golden.sha256 @@ -1,240 +1,244 @@ -213580ee1ca056c42f19a580b7c02a5e3dec1c0678975644bec32bb92abad9ec site_tests_api_coverage.capy.wasm -5d47ea8191f3e7f296bd0e3945e131a613e5953343c2f4a865d2523d3f888909 site_tests_api_coverage.capy.wasm.source-map -99bd87f3578e444c246ac919c816f08743d53c094fb318587a8b560fce9f2c19 site_tests_call_helpers.capy.wasm -7a28c3d4cf112aa1787ef387dbe2bbb921b8b979dd2005098042d714a2ae69aa site_tests_call_helpers.capy.wasm.source-map -f074210b72ca8f3c92f3cb459a08aa32ae2b1b7b071abc750ca27b6e10c7908c site_tests_capy-arc.capy.wasm -12d5cfdd7179e62bebc08338bb9910a8bebbc361211e8d00aab75c7b37444d7c site_tests_capy-arc.capy.wasm.source-map -0377bf8caeca7f5f7d4d84df30362871599e667d3f3425bdad1e5ec1f7e252ba site_tests_capy-archive-trap.capy.wasm -c1d549a6eea789b247d1d0e2d05c33dfca959348764280888961a0270c84b09c site_tests_capy-archive-trap.capy.wasm.source-map -23286fca0aba2506cf19a40e01e576a5bcd43684aeff4bf36b7fe6bbd377886c site_tests_capy-arc-trap.capy.wasm +c771e9cb8b0725d783cedfbb0eedf24da30575fc10cd69de129310ceccaa1fdf site_tests_api_coverage.capy.wasm +568548f0f2d6764d836ef5b82622992d9c2885c68ec13e8e73606d1abded66d7 site_tests_api_coverage.capy.wasm.source-map +3d52842939a8d88563f40baf106ad0f081b142184eb47721c73ec1f01dcf5527 site_tests_call_helpers.capy.wasm +5802def7601d3f08747f9336efbb5f4189ab146540795794103181485449a953 site_tests_call_helpers.capy.wasm.source-map +db08c93ed43488e3601c7c38b27217841934e9e9993ddeb3ce42bea35c5b4e0a site_tests_capy-arc.capy.wasm +25bd0938ee7cac45c5e33ae6ca53e82ae8c6a6777e9fc311d2969e1189a38443 site_tests_capy-arc.capy.wasm.source-map +d115e75e8f3609219afbcd2760220c1954c1bb1f5cc341082554c6670b25059a site_tests_capy-archive-trap.capy.wasm +b186a8f34cf0da57437cf04f83f8ecac3dc687ef47e334e8e030da8113932562 site_tests_capy-archive-trap.capy.wasm.source-map +467c060978f21175cb47f2366478986a0f79a3cff3ec19a9c6e76548894fd240 site_tests_capy-arc-trap.capy.wasm 2167403689ea01fb767b19f5fec808beec40f181ac713643d1e4d3d42591de61 site_tests_capy-arc-trap.capy.wasm.source-map -8466ae7e51513262c1f808fbbaa7e07d77fe3ef5cbb880f7c07859b9ed9a46e9 site_tests_capy-array-negative-trap.capy.wasm -a298b94aef0b61a6642478429c2d3093ce0e8f389d2a79395b9ad25ad3a7110e site_tests_capy-array-negative-trap.capy.wasm.source-map -a425c4e8834e648109064949018012ef00118a5c3bac33baad8387a6ab16ea37 site_tests_capy-array-trap.capy.wasm -dff8ca5d567b8cb8a419f6d86dec45cca0841a2f5293d25b7875fab24b4e67ab site_tests_capy-array-trap.capy.wasm.source-map -f26c66358eaac597de916b44d1c1c9a626d81836555b011f1ce2aa061a5ead4f site_tests_capy-backtrace.capy.wasm -73b27d224aa7a92b616eebdcf88d4ce1617dbbd8b320f27e1e83951983c2f174 site_tests_capy-backtrace.capy.wasm.source-map -cdb3728078f3d5090d320755d2f93dddefe0db443ada0a10eab94dbc43107e29 site_tests_capy-closures.capy.wasm -36e4d876fcc118d2a547416b1075f490ad9b91364fb15bb1639a934a8c5ae3b7 site_tests_capy-closures.capy.wasm.source-map -f49fcbbe9d653a6c1fa8157ae5e7fb521c2a888d74bd990ce1a5e6d376c0c123 site_tests_capy-codecs.capy.wasm -6b3df161def75f37520e7e0ec5143de1085f60344e422001138374a77242bfa7 site_tests_capy-codecs.capy.wasm.source-map -efe5b40bbe115007c3d44c8d3b852a58020c52329bb49434e44b595b3bf28437 site_tests_capy-codecs-text.capy.wasm -faa066682dcf1451c27d30d98bed9a745e8daa8e268a7fd541b3566b3307c788 site_tests_capy-codecs-text.capy.wasm.source-map -c2b284b73b87168424b21f16ce74ba33e8e5c355301d53ce2024b504607217f0 site_tests_capy-codecs-text-trap.capy.wasm -5a27b5901a32672c376960a3b4c9caa73b205277d2f22e57dcca8bd8827828ed site_tests_capy-codecs-text-trap.capy.wasm.source-map -3848fbf4f177821880041ca145fb652c06669b29f5d82abbcfb5710b074c5eb9 site_tests_capy-coercion.capy.wasm -c4ff23525ef2c9ace41751897b3fd053ae9f927c3fde52d7dafcd1c1cc433859 site_tests_capy-coercion.capy.wasm.source-map -52645e0951db0a5f880a72755de51d3c3d21a30ff191f5d24e19243ebdceea1f site_tests_capy-component-parity.capy.wasm -8304ceca55bf1e54f4a96aa82527b15c8c18e6f083688bcb69718344280784ec site_tests_capy-component-parity.capy.wasm.source-map -bba67e4162a7069f826187c0199f7bf005845d7f214581369efc227aefbab69f site_tests_capy-component-props.capy.wasm -e4f70c9801ebb887cb269f20e606463736a37bcb296e6140dc24ab64d5e7fc2c site_tests_capy-component-props.capy.wasm.source-map -fd2e20c627643f772b8e6482ce6c214d9e35ef34e13dceb8745e40a95b891217 site_tests_capy-component-render-result.capy.wasm -c4398175f641e8bafd8d853423439591d4f321b771c0c5d7501c6a02e6c54cb0 site_tests_capy-component-render-result.capy.wasm.source-map -6c68b3828be6b4e4a43046c5342ada89752bb14a34c8061f3cc44ff5ab6b2ea3 site_tests_capy-condition-coercion.capy.wasm -705c9c051aa8f8a385c695d3ba2087944aa37483328058afe256f07f388a40a0 site_tests_capy-condition-coercion.capy.wasm.source-map -917f7944b40a4e1cb359d16a27832d07fa0c711b45730909ae637edb6d5a39dc site_tests_capy-coreutil.capy.wasm -bfa14949dcdaeca5de41df4c21d7fe5052aa3fce086fb2cdb63472f82248d69f site_tests_capy-coreutil.capy.wasm.source-map -6cacfcec25780489bd943856f13392636fe982b6370cfcda3be0195bf2e1c370 site_tests_capy-coreutil-trap.capy.wasm -7f6a0767c992d7f8958c9d316a1aa1240f0d2e3c947d0a7f34b092cd7bf8688c site_tests_capy-coreutil-trap.capy.wasm.source-map -bf09f8241c20882c3a37a0dfd93dcb13edc4f44bbc91df61020750566c323bc7 site_tests_capy-cross-caller.capy.wasm -6f8a7608d446d7572af0df45e05d544d6b7020d67bfecf50d9267cbdeaca945d site_tests_capy-cross-caller.capy.wasm.source-map -2c2a6c78c5f27eac7e976e3251fe4ef70ee2cccee7225ecc9687bc369cbfeb92 site_tests_capy-cross.capy.wasm -045b435ea8f788d355f5124b612033c61ba27842f25f04311442e1653e0fa8b7 site_tests_capy-cross.capy.wasm.source-map -664934e6c6e45198db39dabc4eeef071ec3abdf3f5e747afd8f972f3bf6628e2 site_tests_capy-cross-target.capy.wasm -2be8b0320d2f91437d7bbaf4929ff873ef30f186314535d10453f04f6b22803a site_tests_capy-cross-target.capy.wasm.source-map -571bdcf5c997b93a28fa33716b5b30f64051dd51ac50f55555c9eba839a7110d site_tests_capy-crypto-random.capy.wasm -42b030117069ae1f4af9b5dcc35c917fd80801f89373453357f74ea6b3421513 site_tests_capy-crypto-random.capy.wasm.source-map -3b66a6779e8255054fdf2b764c643542da7c8345e21a2875d295f451708b8dd7 site_tests_capy-csrf.capy.wasm -ba21ff4ede39c14c1a48fda3aa079502cfa1918a34f988958975fec2abe12d4b site_tests_capy-csrf.capy.wasm.source-map -36c0711bf06dcf8b319f9e11cf6ee85be6d013b0d52469335e8b281eec4b1a67 site_tests_capy-dval-api.capy.wasm -f2dc2535b0a4202c1f749aa25505c0e93f7ffdeb59d4b2971be5b3debbb88073 site_tests_capy-dval-api.capy.wasm.source-map -6e12d4d4c701cc1dedeff152fece94d1c72174bb3ad1d5e5c6746985441ce52c site_tests_capy-dval-assign-list-trap.capy.wasm +4cbd5be15e1c6d5224dc4b9fde099851e120486b10995659c19a58550e5411b1 site_tests_capy-array-negative-trap.capy.wasm +ac2214f8e877ce5ebcbafe475c664720587343bb77562be5724da5f69f9f180f site_tests_capy-array-negative-trap.capy.wasm.source-map +e66d75d5e1b51787ba0f94a22e783724b3d592ea0ff44237f72d52d70137a947 site_tests_capy-array-trap.capy.wasm +80dff2278d571015586bd8038629df9ec2b063d9f6377be505d35fae278efcfc site_tests_capy-array-trap.capy.wasm.source-map +d437f1b3a92bb8a033435158519124d792b25e018f3e4a1cb5f5d9c6c922fa28 site_tests_capy-backtrace.capy.wasm +620123dc8637eee9ef3febd30ed286c2de9b5bab7b04fd1a6cc5ea699a6570e9 site_tests_capy-backtrace.capy.wasm.source-map +1d3a02f2ce4eff351cc1b678fc95d4d083651692343f6e7ad2e08a2328f3afc8 site_tests_capy-closures.capy.wasm +50cda93f70f4db39da800ce3ecffe0f25d4e351351a7be9eb957ab96e85fd7da site_tests_capy-closures.capy.wasm.source-map +1e161da7735e7ef748344e10cac8a731446d7162b184ee54c7a650f7c1a3154e site_tests_capy-codecs.capy.wasm +3b6dc38a26176fccd0437a88deba21aa018a3af505493b9113184c7ae2f0d31a site_tests_capy-codecs.capy.wasm.source-map +d9ea519ff7b5ab384cc8bd40bd4571b24a05adcca07e1aeffa853efe5c10d6a0 site_tests_capy-codecs-text.capy.wasm +89e0c326627d654c3b8335105138b9e9555f6134a315de7bde655e29d9db0ea4 site_tests_capy-codecs-text.capy.wasm.source-map +f3cb4bdcdc02135192cac382ea7903087e4bfd24aec580e673d4eefc504bd871 site_tests_capy-codecs-text-trap.capy.wasm +9bee564a000f46a093720ff9a8474b9078a7a7e0fbfd735e33713ec21072bd2c site_tests_capy-codecs-text-trap.capy.wasm.source-map +d6c774b7131baae07dffd3fcb4b82c46617c1b96ae50972d353be1179825e884 site_tests_capy-coercion.capy.wasm +078da811d63ca9d9d1b6cd59578282a23cc807582335e5b0942faab4dab7ba60 site_tests_capy-coercion.capy.wasm.source-map +f8ae4a0b58e49646393b4c659e658a6fc5069e6ef30e4ac7172d10fc72672906 site_tests_capy-component-parity.capy.wasm +211bdd844b1d4a711513ff0f797a5f394216e41ac9fc7a5d259fe4671dc0fe67 site_tests_capy-component-parity.capy.wasm.source-map +f7652046c035b354e2d2219536f49d869a406c9d75b51e5fedf446f8f7ce2fa6 site_tests_capy-component-props.capy.wasm +ea20e393411abfafcd3e6112429b57a6f10d31099d49dc1034301a6927cab393 site_tests_capy-component-props.capy.wasm.source-map +2189d4cc1209147a67d279de979c6a1edaaaac6b21e08c4b7cafc35eed291e1a site_tests_capy-component-render-result.capy.wasm +420d1883e1a81e141d8230be14ec1d7fd0a7d370956ef984b7c446f51a97fa2a site_tests_capy-component-render-result.capy.wasm.source-map +0e319bfd7e569f31f9ac5ed22ea3edcac6628ede5ab328938ec0b63f1355319a site_tests_capy-condition-coercion.capy.wasm +d4592ebaf32dc003910a4082590c32538c1e5681f699c9a7ae543c3b435ebe60 site_tests_capy-condition-coercion.capy.wasm.source-map +df33e0745bc08ad2f669a751e4c046cd9749dff87bbb06b6576f1cc10db08583 site_tests_capy-coreutil.capy.wasm +e7d9b75fb74e06620c0f8b4f5888eac412e7b63226d647243368a369aaea815b site_tests_capy-coreutil.capy.wasm.source-map +ef6c6d46ceb0aa2dc39edbab1af689a766d6c879a6b25816883cfa2426130daa site_tests_capy-coreutil-trap.capy.wasm +fa6ac7b0013e59c9718d4427d8fb2aaff9f6cff8acc5c44dc232b7d38b831583 site_tests_capy-coreutil-trap.capy.wasm.source-map +ca72531db39de2a608b02f061e87aa62725c4771d6422f95150cc691a952089d site_tests_capy-cross-caller.capy.wasm +294c063742653dae4448a0abeb334ee9fa9830bf93d64519368a8e2000e346e2 site_tests_capy-cross-caller.capy.wasm.source-map +d9ff89f11e454e7fc9c470be3937d965ae200a9ad93f727c258dd8969d4a52f1 site_tests_capy-cross.capy.wasm +c9c5f771d70f0a1afed48f04680d49ea7ad8bc649f1394aaea431d90467f4c81 site_tests_capy-cross.capy.wasm.source-map +2e036da92bbf965cf75ccef253addf9adae89d3322f429907c92fbf355fd60b5 site_tests_capy-cross-target.capy.wasm +798b167e9ad8230fdf05c9c5d06374639ce3eacf96234b0f3f331c3eee4f423a site_tests_capy-cross-target.capy.wasm.source-map +7d63a35fc41701092b9a49141c8c56376ff1d2add5ced98e6a79aa60726eca0b site_tests_capy-crypto-random.capy.wasm +33afd8f31cfd558ab26e2a8cb51d87503b5d16ffcd2a0564d454fa646c2815d1 site_tests_capy-crypto-random.capy.wasm.source-map +acc25f828c26956f4dd900d6d2365391a54535e84a28db5f66d616fbbeef4d35 site_tests_capy-csrf.capy.wasm +3eb00c2053b0b8014a6966219ca357d11c33bf275a7df4747559c982754f72bb site_tests_capy-csrf.capy.wasm.source-map +ab209de8390db08dd90e80088a44cac09fd1d1a658deeba8d62be1f209e073dd site_tests_capy-dval-api.capy.wasm +49a6299f008e6bdd219ff23233a079b133dd50be1bd897be6a8920b5f3123ebe site_tests_capy-dval-api.capy.wasm.source-map +610d5004f6252168b171021d5a07329bcf4ca359b10a5e5486cdfd5506dddd68 site_tests_capy-dval-assign-list-trap.capy.wasm f3fded712a14869c3b23bcf3eff2d95d0786b3627440b5226bfdf48cf3526765 site_tests_capy-dval-assign-list-trap.capy.wasm.source-map -56bd71e60bff473e4e7a9946d357b07f0c0647c075d8befdd95c3824f0da3072 site_tests_capy-dval-f64-trap.capy.wasm -700fddd5beaf1abdba4f54d0dea089e93f960fb28442777379ff1450a2294ed1 site_tests_capy-dval-f64-trap.capy.wasm.source-map -41e192757699ecfb7e815fec8f1810222117603b74f88cdd33ba5495f958125f site_tests_capy-dval-identity.capy.wasm -53b41c537a3cdb5a29f6fb79be9cb5230e3efb4e9f887961bc9a40e1562d559f site_tests_capy-dval-identity.capy.wasm.source-map -d19ecc3d1a76282a88b13139e0a0386769f9e170ec7432c01bee58d29e8a7ed1 site_tests_capy-dval-merge.capy.wasm -32a69bf5d86e599cf34fb888aa69d0b767f424ae778ee34aa106b22d8ac46da1 site_tests_capy-dval-merge.capy.wasm.source-map -e60f5448a2273a4259ef008fe14bb99f19abd6821e546edebfdb95c822c53d2d site_tests_capy-dval-none.capy.wasm -ed9437ae4484a8fe6ab4ce0aeee78df79dcdfccbd5e2bec04aa4e08c876661a9 site_tests_capy-dval-none.capy.wasm.source-map -87c2d99b38f97ff48a2553fd96f9615b7898c304f0bdfb59c40bb001338b83d6 site_tests_capy-dval-return.capy.wasm -37ad939dc15e351c48ab3156192efb0ec37f717a026f557171e4296188bea48c site_tests_capy-dval-return.capy.wasm.source-map -2d81626c35d6d4f02b41252f8b892487cbb54052e24bbd4810ac2a13fbd37f8a site_tests_capy-dval-rich-caller.capy.wasm -b39c4e28bf66e3af11d0a78705206f78058cdafa65ce03cb10ef03e6713c39ef site_tests_capy-dval-rich-caller.capy.wasm.source-map -f6d386b4991e9f0ec36c71a80a80434db41a004bb4417e69dca1e1669cbcd1cc site_tests_capy-dval-rich.capy.wasm -e13c043a18e8e8fac8fa2e86d6e8fe0d4a7a9873bb923b0bb56284cc592a3f6e site_tests_capy-dval-rich.capy.wasm.source-map -a9a691be8a55b6873015eee0ac02050da84e4cc7596307646ed532e521cf36fb site_tests_capy-files2.capy.wasm -0eabf95299dc64ba924159bba53cde5e4610918aabcc59ceb43064530ec83532 site_tests_capy-files2.capy.wasm.source-map -2c695efd7316ad8750382708ce495eb0d79f57a4b8cf9d35b547f446f2250438 site_tests_capy-files.capy.wasm -e1b13a1ba8a2617bf85d7ec13920ffbd12c6e1efb9afd30091c57b8db0634519 site_tests_capy-files.capy.wasm.source-map -df38153fa4f650ae182475b50edd43764bdc3a2762ac83ac653671154cb4df63 site_tests_capy-final-parity.capy.wasm -af712add2859353f353869dc9e28000f8ac5cad9bc4742ab0afbdfac5dd430de site_tests_capy-final-parity.capy.wasm.source-map -b7e3fce1d69ba7516796a937a547cce832384d933f1cf5ecc785c8bf47f11913 site_tests_capy-first-empty.capy.wasm -8695235b48ecb7e87588c847fd6a011b901fed6b0c442564460eaf3942eedbd9 site_tests_capy-first-empty.capy.wasm.source-map -92468645908f10e546201607f601fa05558889a19608754c5eac73c732917e65 site_tests_capy-jobs.capy.wasm -7eec1be4f77b9b78c3d8bbaed28a7437850c8a20bf3c0961101477609092454d site_tests_capy-jobs.capy.wasm.source-map -0825825ea5c92aa2e776364da3af361c54a7b5e960853602970affbf72eb73ea site_tests_capy-language.capy.wasm -42bc51e4e97f830c41855a30f559989da0bb2e1a278851057fc428db2abfdede site_tests_capy-language.capy.wasm.source-map -f3ef12c1ca7d7925208dbb669c0f50b303cc65af3b9750cf6a793c0073b1049c site_tests_capy-language-consistency.capy.wasm -e87aa2bff1cef0108e596a3cd28a2677285b3f405728efbadbbd1e6be3339e8f site_tests_capy-language-consistency.capy.wasm.source-map -8e66322f2f271308253bdcfb201ba3132682908e79814ff5103108fe5a0a3ff7 site_tests_capy-lifecycle-child.capy.wasm -d637a9f4e0980d6489dedd3fe0400916fbce104544bee21debaa6a48ca8cbcb9 site_tests_capy-lifecycle-child.capy.wasm.source-map -16232c09090f9545f60c622e1f4b70fa7e6ba57562e36fd41901ef2fc0994dba site_tests_capy-lifecycle-parity.capy.wasm -094f8bc7185937d0f0a0b4d085785351e4d30c2bf141b9421fdcf6ae23aa539d site_tests_capy-lifecycle-parity.capy.wasm.source-map -6239c0bd29605097c47b7a58b2b9726708b2742e69322f1bd7094ecabc83144d site_tests_capy-loop-control.capy.wasm -90cbb5d3a1c458685e3d719008647d2195ce7c0c8c90634ca7525e041e5e5caf site_tests_capy-loop-control.capy.wasm.source-map -16bf5688d0fd33b024bf5255ca39a662f35730bf555a7b7253c651969f9b6339 site_tests_capy-managed-parameter-rebind.capy.wasm -691260771d63641329414765f0ef397f1eca9fb14d20704d8d500bba2253bfcb site_tests_capy-managed-parameter-rebind.capy.wasm.source-map -94dbfd8059c1ccd9c0f78f0545b17b3dc8749e5fd3c7ae4f8c3a2e1d6340eaaf site_tests_capy-map-arc.capy.wasm -151fe6ee0bc40b256199759b75e5af7ee88dd14718062e76a3e75dfd6ef1bfcb site_tests_capy-map-arc.capy.wasm.source-map -26d9b63ec3dec5c055b7b75ba5215289bc4e60e5cd6ccb699b40841f2aec6650 site_tests_capy-markup.capy.wasm -6eec3db45b6566a5ce94f091906e48d167f9d442a8a0ea41e5768f98370c3003 site_tests_capy-markup.capy.wasm.source-map -eca4a12a3683d44fb0a6f8fbd5b0d31e0daa926b7086c15cf6b29a5df383cb30 site_tests_capy-markup-context.capy.wasm -57e91e8305d12a43b84570b40e57e324d3d322d0b7718d45e3d82b46afeb6735 site_tests_capy-markup-context.capy.wasm.source-map -a4fa97351528c539d301b3d6b825ae5104a67ab7d0d03ad1a6d0cbaa48d5f546 site_tests_capy-memcache.capy.wasm -b99064ab42c329f60e1150608952102bbf3892bdaff88d1041a5216e7fadb90c site_tests_capy-memcache.capy.wasm.source-map -7788f2e07ca34d45b3566b6212ea9b29ea34cae5d1b873045b0b6a2031ab4619 site_tests_capy-methods.capy.wasm -274585ea0314ff424940072aabf1d48ba100032a1043cb121462fc5c32bdf242 site_tests_capy-methods.capy.wasm.source-map -b1216f13f015eb70ba78d9a8a20c68bdab0215dbce7e84ea32b65f4a0ecb7759 site_tests_capy-module-caller.capy.wasm -51a2b760b884dd5fae18eed0d46a22ce7408becc045c34e3df7f269ce521e695 site_tests_capy-module-caller.capy.wasm.source-map -7608a094fbc6e8ff399603129205f02b96ac0bd0fea0c634f92cbd98c8a5cc35 site_tests_capy-module-target.capy.wasm -9a234970be69aa60fa2b6526b780b27262a808d6cfc1f60f49c824828cc38325 site_tests_capy-module-target.capy.wasm.source-map -76be6c31fccbacd56e069d259685253b7547723a442642e9dcc4cb81ceec4f88 site_tests_capy-mutable-array-struct.capy.wasm -5c44e58672448e18060789a388ed30d6f0771cd31b2f8a1093c0b20080f37a9d site_tests_capy-mutable-array-struct.capy.wasm.source-map -dd7df12f46638258a88ec9ae4ea7c1e8e706174965b3c63e717f9b97e9cdd84f site_tests_capy-mysql.capy.wasm -89b9790340be18c4013461c61d24ddc8beae88f2400fdcaa31619616e1141448 site_tests_capy-mysql.capy.wasm.source-map -c9a61b5400da6e2494dcbca6215cd4292cb29c65e033d4e2f584db80c4c3489b site_tests_capy-mysql-info-trap.capy.wasm -7ec27bb5bf055c79aa3f6503447dc060ef0f9661c26e3ae531f154de51ad71f9 site_tests_capy-mysql-info-trap.capy.wasm.source-map -c837ca80d97c35cc34f5df20044de8e798ae39cbf9469ba3fdae0adf2c86a294 site_tests_capy-network-parity.capy.wasm -ae1a024616f0ab28feeb626ca013dcd9db765f72783a6c29fdfb4c197dfbe477 site_tests_capy-network-parity.capy.wasm.source-map -738f36b6964c44b458c052f588cfac31c04162c7acbf9c2e3eddfe83feb13a3c site_tests_capy-operators.capy.wasm -9de5d3cebc6a8a63d4411dbf34b0e5ad3f8d1fcb16f6a1a38cfb0c81b3db7d84 site_tests_capy-operators.capy.wasm.source-map -76204738ad6c73c96b397e40210abe574e6bba362655521e36b03847a35846c7 site_tests_capy-phase1.capy.wasm -b57749d5199df347f72bcea33af87889a73aa1b71e360e3e86f1cb9584bde95f site_tests_capy-phase1.capy.wasm.source-map -170d743d9cee218036deac82cb9193c6ea31ca974b8e9c34ce2f23ccd753d4d1 site_tests_capy-phase3.capy.wasm -e84db6371baae8c3c9bcd9152e404baf2d25626117df95f1e189ebd54d8a09e6 site_tests_capy-phase3.capy.wasm.source-map -66c21c62652c6073e6064b797ab93db43883c45991af7d99df8dc240ab839062 site_tests_capy-posix-info-trap.capy.wasm -2175ebc324012d82089df6202c81ecf0b6e5099f78a7d14c6178091643fc7776 site_tests_capy-posix-info-trap.capy.wasm.source-map -d508bbaa92a978ffe9597f3ea78ad9e14fece4144635ee9eac5df05317ffc56b site_tests_capy-redirect.capy.wasm -609f9c5514a996859822f647d40a0afda7eaadc60742037ff5c305644fce1d94 site_tests_capy-redirect.capy.wasm.source-map -e4d6b45c646efa3d56af282c5bbef72f8e3207b6e49a1d650485bc5fe10a0184 site_tests_capy-regex.capy.wasm -309e3fed52c8a3a17165188143b3f826580077105fc4394728324f6b3ec8d847 site_tests_capy-regex.capy.wasm.source-map -715f41de44f8b555405b909852436288717e04ec7c5a89c37d6e5dc72bec2d73 site_tests_capy-regex-flag-trap.capy.wasm -a0b8da7d0bf774522ba82d3ed97cde1efc22b674ef009a015b22f883a32fb377 site_tests_capy-regex-flag-trap.capy.wasm.source-map -6dfcf6fde455bc606e1b64e742dae4793b61d6381a0b926073ce4dc16ed1203c site_tests_capy-regex-replace-trap.capy.wasm -90c6c32bc06ce9b68fcb447f869940ba54494a5c9a0413b4b71fc98ff04bcc57 site_tests_capy-regex-replace-trap.capy.wasm.source-map -5c41c998946bb9ad98abe55e7374e6d2d5a16a33ed223e97f218cbb64e37a729 site_tests_capy-regex-trap.capy.wasm -14e7331b02ea89fd435ee6e6e6d59303eac330dcf7ac093283964bca6e720db1 site_tests_capy-regex-trap.capy.wasm.source-map -a77924f6d74a6244c3a211d20baf9b91fda3b8e9e52386d0de973dc7a3cd0b4d site_tests_capy-render.capy.wasm -3a306b272e4b2f112b5a86f1776d9de99a9887421902b8ef513c4e3e7eb1c03b site_tests_capy-render.capy.wasm.source-map -a2c9b49d55b11d81fde4ac5a0e2db464e0bd1a43f1b81ebf3b5b8f7217f2b336 site_tests_capy-request-context-caller.capy.wasm -b81152f758c0d251bb7a8515307a12408b37356a3e4d9c3fc8b0245b0d390966 site_tests_capy-request-context-caller.capy.wasm.source-map -9d6a7214887df9daf8f2b10345200a6817ed94c6838c72f763fb44c3c9d3cd30 site_tests_capy-request-context.capy.wasm -ecf816d5c37c8eefe98dfb7c94f84996a7d59ed2240d15603b133da5270d2c9d site_tests_capy-request-context.capy.wasm.source-map -2d736b588ba1177db948c62d2ecd388c9e80bfeaf6179a46d0e7f6c1c03d544b site_tests_capy-request-parity.capy.wasm -9b5a53917aacd8cb38ef4897179d389860113c3610babd4e5678029b38da1741 site_tests_capy-request-parity.capy.wasm.source-map -4f38ca361230ffd29a0348367c0b3ffdbbb90d98519796d439f4ef5a0342bea3 site_tests_capy-request-writeback.capy.wasm -238efc3641569625489e17d831d08f1d00ce77b5973c87888dc7e6f02f25abaf site_tests_capy-request-writeback.capy.wasm.source-map -495ad315f15a95dfc91dc3d0ad7bb9571be29f97d8a06f6a90ae1e5cbfc437ee site_tests_capy-response-header-trap.capy.wasm -bfc7e2150c473fbaf4b7f560b594a7e09b3ed1933b8af40e64392a4e1bfe9eba site_tests_capy-response-header-trap.capy.wasm.source-map -ac98d0a46df237f5e813d969d15fcbe39ac7a62cfc4b761240f0af9399d28ad8 site_tests_capy-response-status-trap.capy.wasm +d9e6eddb2f855b97d596e43a19a566e700435a4cd5db25c5240dae753b2b6772 site_tests_capy-dval-callable.capy.wasm +133a3a496a833550ad8f04fbd5d1f71324700412434c3bfbdd554cf3f79ba060 site_tests_capy-dval-callable.capy.wasm.source-map +9c9b785d20b532d30b540e0c9f7a5601f02b47e2192f274eed5f526c5fbfd9be site_tests_capy-dval-callable-signature-trap.capy.wasm +a15b50d1982dbab3816584c2834e644cec4c146d5fe21dd29a4f3a9028d1821b site_tests_capy-dval-callable-signature-trap.capy.wasm.source-map +476ab41a943afba8a0b27f5b939e4c978ec9490206e009fe68e9c240fc0c982b site_tests_capy-dval-f64-trap.capy.wasm +7a484795673f18d405a2891c018c2d83ceb42e47a5d661609885907e2190c12e site_tests_capy-dval-f64-trap.capy.wasm.source-map +9b2882ed1d78c4d21705d1263ee433545cad74439c70c652cce1c5fee5fabf4d site_tests_capy-dval-identity.capy.wasm +7528eb50bb0105d609073af8240e00cb6b6d56baff4580a6dad64242fe7084dc site_tests_capy-dval-identity.capy.wasm.source-map +ae5615951fca8b23391bcdd37a4cd86bc034b876ae1d83da582125118cea61c5 site_tests_capy-dval-merge.capy.wasm +d3fd894db74824d1b49da9547ea92e4c7ed39710faa6eba2c63b5138d918ad29 site_tests_capy-dval-merge.capy.wasm.source-map +2afca7727ea17fde79b11844dd5df531ceda450aaa923546fc94ef5cfa6484ca site_tests_capy-dval-none.capy.wasm +a2709b820388fbf5ea4d1d8ed710beb38ce59883fa85fce8fb9d26d707e8258e site_tests_capy-dval-none.capy.wasm.source-map +e4d55fe844f756bc4995ecff09a317d69a788605d90f55aaa6dbb7f5b7e424c8 site_tests_capy-dval-return.capy.wasm +968b5c860193af94a49f443c68c3430bec275d9fbf71efcda8f389aeaa3d5b13 site_tests_capy-dval-return.capy.wasm.source-map +95f4c1cc9f4590d153b2b08eea483e059d4c3b4355d59dcdb9c795859a472c47 site_tests_capy-dval-rich-caller.capy.wasm +5184b2ba1e2e358d38c7c308d10b148b11236e004da52453217902b5331e5166 site_tests_capy-dval-rich-caller.capy.wasm.source-map +3e768aab406d471d82161ae03b6e25e0ee0c7d56663646893806ca7e4ac80288 site_tests_capy-dval-rich.capy.wasm +6a90d3512d260f5d89e9583675a096e76efecfc85a4e2894f059cf02ec161bf3 site_tests_capy-dval-rich.capy.wasm.source-map +b3a00f1d31088631823e5fc98f5085411f18f53c96bc1b7766906e246a5cec8a site_tests_capy-files2.capy.wasm +855fba57c95f217e5bc0703d0d579779d9aa857298cedb8c9e947d86f73eb2fc site_tests_capy-files2.capy.wasm.source-map +317a9a0dbc8247065eb112ddb10dcf1c756e4b1dd5d38160239a40737e27b661 site_tests_capy-files.capy.wasm +bb781b3e5b72a6a58935cc8d4ac5bdaaf772a6fc1707c71e1028fcbc0982a55e site_tests_capy-files.capy.wasm.source-map +5ff1cfd438b7fa2bd2abe2bba47c1bee7e63901ff668c12f702a185e64742cc4 site_tests_capy-final-parity.capy.wasm +6c0cb915bcae015447a570be38fa575380547ec9a0e15fa40df4d2063423c5a4 site_tests_capy-final-parity.capy.wasm.source-map +84608e3c63c919ae6dee0b2c98896e2a39b8292a7c2b65f398b7790e9e9b1b15 site_tests_capy-first-empty.capy.wasm +09685195e963c40e9cff09a74534bdbf532c0125d2d1d99ef43247d471bf3dc3 site_tests_capy-first-empty.capy.wasm.source-map +b2ff17a2804b42d7f73ebb0bf9bac79bd11fd7308667101965ae06c268319bf4 site_tests_capy-jobs.capy.wasm +2096f153d3ecdc5ba64a561ead7e66b262434d7b1593c7aeda1ec1b1d4fd8301 site_tests_capy-jobs.capy.wasm.source-map +6011547bf1844c492f704f486f7d5fbc56f9305d483e6f92fcfe594666fed1c2 site_tests_capy-language.capy.wasm +56818c1dd2f682f2e8b4a9d1efcb0fa3faf3ffecf4f04266b6e38d9667577ef4 site_tests_capy-language.capy.wasm.source-map +86d973ffee890d2eee95b488096131e2674d71b61535d5559fce118b8ad1e2a7 site_tests_capy-language-consistency.capy.wasm +497f2e57761e44a7fe2917eb3761fceb17dc29b23ce841dfd052b70f58621888 site_tests_capy-language-consistency.capy.wasm.source-map +0da7d6f407eef66e374f933ebc2deb6bf221b9241220670f14107e93e4687d7f site_tests_capy-lifecycle-child.capy.wasm +89c68bba4145c3ce94a27f6232a74e1962abcc69dadec7dea347fe139293673f site_tests_capy-lifecycle-child.capy.wasm.source-map +140ea821583b3130ec686fddc2beb53322bd6a99fb9c80c52f5f4d3476f46560 site_tests_capy-lifecycle-parity.capy.wasm +51aab70c89361905eb523609ed72b1376ca3868b2f015df475a82ca4784e2190 site_tests_capy-lifecycle-parity.capy.wasm.source-map +557bfcb0fb80302e0eb6a98a7e2fd42624226fdc7577237381d582db325f84d7 site_tests_capy-loop-control.capy.wasm +3e03ea3a4bdec760eb0ad3b370af5c453a9682b376bf79721c2d793b78557bb0 site_tests_capy-loop-control.capy.wasm.source-map +b24e45af99ea751b57f58e73e5fb024237bcc4c914c4e1531be77e84a99a5e0a site_tests_capy-managed-parameter-rebind.capy.wasm +111a303dd9c8e45ff109e7f62c42f8706dab1d28b470e506d81e0783d7bde7ae site_tests_capy-managed-parameter-rebind.capy.wasm.source-map +dfecf0e2894cc08bfd9b05d5a5cd42a4603221dff490382657959e2d75ff7de9 site_tests_capy-map-arc.capy.wasm +e1fdb71d445bdceef1b387bce2c38f42b4d5c23cd064afc22b4dc8b558d2ab3a site_tests_capy-map-arc.capy.wasm.source-map +2923d087eccd2795905fa475fa9863c70099f6583550efde3926da516d1db571 site_tests_capy-markup.capy.wasm +6de79fc3e4351369438c52c2a777aaa94873b4fd67b672102162a543740955ff site_tests_capy-markup.capy.wasm.source-map +1d3d6f2874ca099526b2fcc854089e649baef127a03f22f0adf5b6282933f38f site_tests_capy-markup-context.capy.wasm +4e4b4d1c76420993e1abe63194b0cc3b096f6760446cc331a77d01249b0a07c6 site_tests_capy-markup-context.capy.wasm.source-map +35f316558ed9aa7235afb4ce19bb05a856df91611f41c298c1a19a6b250d2811 site_tests_capy-memcache.capy.wasm +d9ff69790b2c8dd12309f62350ad2417eeab89cf0713674624a35c9d2f1c082b site_tests_capy-memcache.capy.wasm.source-map +da546aa790381b92112c6bcc66eac8ac49d0edf2f4cbb477b8e6b072012cd561 site_tests_capy-methods.capy.wasm +930c8b75332335658e1ef6dfec39db72c9c6682c593402f22d0796815fceadf7 site_tests_capy-methods.capy.wasm.source-map +b573b1b91c5b773d662250a4ab3e88f4ba09f341f3ed8820c055a0a3e1fbbe28 site_tests_capy-module-caller.capy.wasm +7e271d2f646f7982ef98d623ff42f61e3c482487d6675b7b22177c7393008a92 site_tests_capy-module-caller.capy.wasm.source-map +19f77a97449971beba5e7656bcb6b51090c2dfb224a95ce726204761383d0708 site_tests_capy-module-target.capy.wasm +7431cfdab1f6778a78315c99312bd6f5356536e9b73f8fa80109d20f40633197 site_tests_capy-module-target.capy.wasm.source-map +f1c8ef7edd8fb72910ff251ab9a7b52d5b60c30b32252e3daabef6676a466330 site_tests_capy-mutable-array-struct.capy.wasm +f5460e650ede28273e333503d0df03281e7817438f46a90f40c3f281276ace28 site_tests_capy-mutable-array-struct.capy.wasm.source-map +b1026b949b821e2fa69ba6d546a01f6a8a056f2dc0fcfabac5a2a4c630655cc0 site_tests_capy-mysql.capy.wasm +ddbf28d66cfede0198abb0c7450edb4a9bc1a3d65be95e6e71db0d15c211ac40 site_tests_capy-mysql.capy.wasm.source-map +31b85de9da21e105f7c1b2d71cb946343fa962d9b9b919393915b90b3daea6da site_tests_capy-mysql-info-trap.capy.wasm +4f6894818035cd3772aa673cf65e1c438dc0a89f5c6d0f3495ecabc795967861 site_tests_capy-mysql-info-trap.capy.wasm.source-map +f0ad46ea0f832c81894dd956abce71dd760e7ab00b5189b4c108d0bd2acf89b0 site_tests_capy-network-parity.capy.wasm +3a3bcb2ca1795ffec736eb1d197af4dd7be747527d19d007a4a069419e449b64 site_tests_capy-network-parity.capy.wasm.source-map +e797cb78fa574b06aaff6b86d47c9a0556aa7f79e20a72cc5e6e431304fe0596 site_tests_capy-operators.capy.wasm +38a07dc4ffca69e2ec23c1b94799155b9e73d12aee7b64061ac301e97009ba12 site_tests_capy-operators.capy.wasm.source-map +d36f98327ac2c96edc6aad6cedc2446635d75a7d50c8179b1d502710ef2fb7b2 site_tests_capy-phase1.capy.wasm +4be42f846b24e74c75ddf8d4529d19d80c193e54b50401380bc7ec8b031a235a site_tests_capy-phase1.capy.wasm.source-map +f703d00fa844204a7d58c69764f39731bfa6d2fbe312cc29f24155109d2970d8 site_tests_capy-phase3.capy.wasm +86e00530a7804860a87765ff703ec337f8721155f5d474676787affb938108cb site_tests_capy-phase3.capy.wasm.source-map +e6530bde3221d13eea81f0fa7b364478fbefde6b3f9f8ee9ee05c0ae69de4c95 site_tests_capy-posix-info-trap.capy.wasm +6297a7d0d70f250bb2be1cb28886eea192dfc5cea1bb3c7ed7ec6533c17a5723 site_tests_capy-posix-info-trap.capy.wasm.source-map +568dc276d451fde4d81a388d3f8dbcdb0de2038121c42426a83d385f90fd5212 site_tests_capy-redirect.capy.wasm +5648860f5481114b1d623b4196c7b7becb9459277c19605c61337e8efcffdb84 site_tests_capy-redirect.capy.wasm.source-map +90a3e2883c16a895614cf769593e6e89d8a3044f7517821f0085dd72ce65b2e7 site_tests_capy-regex.capy.wasm +83ebca077511e084197ecc900160205ddd691768b6b8616477d2c8b3232e2839 site_tests_capy-regex.capy.wasm.source-map +facf9a2ab018bdbba3de1e93c3b88a404b658c3c3e220b616e41c422ee9353a5 site_tests_capy-regex-flag-trap.capy.wasm +2903a2670358e72cf4800b51fb903067c42ec8c345f67ee26be4a84fb135d15a site_tests_capy-regex-flag-trap.capy.wasm.source-map +381c0261db6d6da2ac4e9cd5ec2f4dded73e0b57c3d9348478e011c197f09818 site_tests_capy-regex-replace-trap.capy.wasm +e3babe459a9f225fc2632fc38511eef7475a3b73bd13a51d5cf676f910898251 site_tests_capy-regex-replace-trap.capy.wasm.source-map +b547ea03f999869ff188077d10b2e052c2582d008e93d2df9731a078d334b4fe site_tests_capy-regex-trap.capy.wasm +e831df78d565d028bd30f7c027379633d2d478e2bb155ded0c868d61b020efde site_tests_capy-regex-trap.capy.wasm.source-map +fbfaba5819bf794b8ea3adff39684b832a3cbca5a76048552a616fbfe5671734 site_tests_capy-render.capy.wasm +1a605a00da923fd338041b3ac42b412e400d31a1ac93382c71fabd1cc68e8715 site_tests_capy-render.capy.wasm.source-map +db090decaf4045bc07f1a65e99382210c10c403a6aa2c758ccbcac01bee331fe site_tests_capy-request-context-caller.capy.wasm +c51680fcdab6b2cc1c2123d339f1c2b803212ba8780b5bad03c467812f7e243a site_tests_capy-request-context-caller.capy.wasm.source-map +254fac39db2e96c64f994dbb34b033885ad3a6277876285135af4e390df23dfe site_tests_capy-request-context.capy.wasm +6edd4c9547d7b1a6dc289ccf80ebe944985d57cbb780463bd36ca7dba32690ac site_tests_capy-request-context.capy.wasm.source-map +94a34113cf682939d3a30fe5273b41bd6e92601a04dc0437e00e750c4b076acd site_tests_capy-request-parity.capy.wasm +017636b70a9b370f0746639cb8c209885a3aaf3dc8290ca68e5ff87a78200bad site_tests_capy-request-parity.capy.wasm.source-map +e9e91c4617e0c00acd1f0b25aaaee0405224b613306f2c2853517d97e6230aad site_tests_capy-request-writeback.capy.wasm +7521df60795064f87df7ab495f6900019aa544198f56967fc4126c472288b00c site_tests_capy-request-writeback.capy.wasm.source-map +40f5ee35986dfd344dcdd32f32ffc35bd9ae0171afbd660a8fbc00d03df3f385 site_tests_capy-response-header-trap.capy.wasm +0a255a730714f86deac7d879f451ccdf36968853cc533a0bacfe005ceb43d2cd site_tests_capy-response-header-trap.capy.wasm.source-map +0531fc05eb4f844402c9d0edf6702bf980888d9ab81bddce0332595b17b2e4ec site_tests_capy-response-status-trap.capy.wasm dd95a4df961f7ee45cee32e8efccf6520d95009dbe6be9c69abdc143d56d8a7e site_tests_capy-response-status-trap.capy.wasm.source-map -49ab0a9b4b66380590218c7e51e39ed7b84a22940028b40360c0eb0e60452865 site_tests_capy-serve-http-caller.capy.wasm -64232df89a4e622294bbad9691c24d3cf8b301eb2859966378aa58d95a007d7a site_tests_capy-serve-http-caller.capy.wasm.source-map -ec2c2e3d0bb89aa505c542c5a74b644896cf87da583c34359f3b26b8278406ac site_tests_capy-serve-http.capy.wasm -3cc578df4cbbf6d712d7ac14a34561cde01ce80c7d396e76d32d2c1aaf6f29ea site_tests_capy-serve-http.capy.wasm.source-map -e2f676565179f9a9a4b2a76c1b0c3bc3b040c748c0d5a1c9e247a864adfa7478 site_tests_capy-session.capy.wasm -0c26c8bd69de00769546fbe56e15cb61ed8e4f9e3d4cdf110a3925c4955ce81b site_tests_capy-session.capy.wasm.source-map -ec22a3a9a46334c775880cfb455df87e49df4fc901f77d7f67b45a56e886e3a3 site_tests_capy-sqlite.capy.wasm -22e4235a72eb9ad7ef5b8fb21e326c5f07948fe1f8f45b304e6ae81b5552c86a site_tests_capy-sqlite.capy.wasm.source-map -e5656989afaa243e0991d298670b5ae2dd773cd26f800c331ff2a1b044cbbbac site_tests_capy-sqlite-failed.capy.wasm -77937e1f9ed2cfa20fc27af595719e60a91f41e27414287a7b828f3060c23d03 site_tests_capy-sqlite-failed.capy.wasm.source-map -71c247bbc45d2889ba359829c7126f3263bc0801f0e2d1e1c78c3c2e6d31d3c3 site_tests_capy-sqlite-handle-trap.capy.wasm -aafcf38cb79fb953f82cf91fe8984a9940786040c1ad63bdc415a7b8cb2c27ca site_tests_capy-sqlite-handle-trap.capy.wasm.source-map -092d5cafc4801513915a8c18127cc4abc89d3930eefb6290b36ec737abe407c7 site_tests_capy-sqlite-info-trap.capy.wasm -89a3b0b45317458d64109e87dbe496de020844291b5c40eb48ca206a237667a1 site_tests_capy-sqlite-info-trap.capy.wasm.source-map -37fdccd2975499cba36095d60f7fe917384e988178593e6f18a94905c018af24 site_tests_capy-sqlite-params-trap.capy.wasm -62d3ddbf9259e67b845af1111db864ed342835941421efcb1c0f1e3d8b2f2d41 site_tests_capy-sqlite-params-trap.capy.wasm.source-map -cd073eff86078a5e4251a7ccd39ce89ba4420e7ce163982e5ffb2a8aaa0d65a6 site_tests_capy-sqlite-sized-host-trap.capy.wasm -3d92e08392b79909e1b8d07e1141fb2e47b9edbb9f20917f5f8bacf9250d83a4 site_tests_capy-sqlite-sized-host-trap.capy.wasm.source-map -9da83e49e393c52cfa2f650c6b89937e41efe00e25a3dadf30ffab499cd04d6d site_tests_capy-sqlite-zero-trap.capy.wasm -f49d1747ae3d68116e721fbcee547bf34c00f5d88cf95871d1cd7a441c6bf830 site_tests_capy-sqlite-zero-trap.capy.wasm.source-map -012cfa5a98387dced09293257065f5a659541edd8dfba5361a5d8f67fc1e2f5d site_tests_capy-string-concat-only.capy.wasm -a10015a9a81a07c30f9a5119bef848781ae609bf93bcd57b74b0751bf8e4a5a1 site_tests_capy-string-concat-only.capy.wasm.source-map -e5086931831a44a5d1144cb8e9af6609ce631d466d7097427109d9bc979bfec5 site_tests_capy-string-list-scalar-trap.capy.wasm -0035640401b57556a0b1472b29c21ef17fad2ef1d4abeb224fb54e2e7b517c96 site_tests_capy-string-list-scalar-trap.capy.wasm.source-map -4121f2dd9239b42ac86d84ad2298d07b1b6b818ca6ba155eccfdbc9291ee0c07 site_tests_capy-string-lists.capy.wasm -09138e325560aa833e84d3b8a2d18b79918d923673497f701826f53b78990edb site_tests_capy-string-lists.capy.wasm.source-map -09fa317992ad0e10ae909134f93b94ae85af70d8bf299ef6c3bfad17d87a5639 site_tests_capy-string-list-trap.capy.wasm -fe2fbefdfd9a5750ad4d4c46e677d6fa3be6bedc63bf38484ab9637855ebea90 site_tests_capy-string-list-trap.capy.wasm.source-map -89a102dc5083d756bb72a5dff6210832e26d25b3e0649fd68abb12ac21fc5f35 site_tests_capy-strings.capy.wasm -78bb8191833f11743a7e84c5f525e69db6ce356e80d5db692d4375ed29098ec7 site_tests_capy-strings.capy.wasm.source-map -0d31c29d1803c6de722640ff5643f704fe2cc88e3dd203e941c07952fe54b91a site_tests_capy-task-concurrency.capy.wasm -b4cf2377ce1151804448c0a3c56888be13c3272004b5faf81a29655758e010c0 site_tests_capy-task-concurrency.capy.wasm.source-map -1529deba14654f36fe112189f6b99328c98f1e915f627170a46fea242e1a6086 site_tests_capy-task-overflow.capy.wasm -ce3d635f2bbf416a13fa547596856e5fc0c5cbc52dfc81a8597fbc7f258afbf9 site_tests_capy-task-overflow.capy.wasm.source-map -17731491266c849334909787be7cd1f621d6b6dc5f86f015dc43e287d66f5178 site_tests_capy-task-runtime.capy.wasm -acc9d97b3fe07b9b2ad8a016b54720925f91305617cf0fee60e26b7eee6cae52 site_tests_capy-task-runtime.capy.wasm.source-map -f2bc864b6ab489e1858f5b1404a7cebaa890c6ecba81b5cae1b7149151820b62 site_tests_capy-task-timeout.capy.wasm -23d746c5c7b20980917d92572119c087ce611a73d0b732bcb440b922de9b58dc site_tests_capy-task-timeout.capy.wasm.source-map -5aadc2995422f768e065e274470ef360dcccaf214efe47c696c92e1d5b39fd0e site_tests_capy-time-parity.capy.wasm -62eaf5b4c5e9d416b27983376f27aa5d935dbed91ae63e50e10fac5136209a6a site_tests_capy-time-parity.capy.wasm.source-map -fe6014ad9f36727939391ecf53c8b28ebe40a840885a7a49724c41a9449c29dc site_tests_capy-unit-admin.capy.wasm -44df4b5bd5f48eb56c845c4691c7f6ebff7a4f10684ceaeaaf6436a8beeca431 site_tests_capy-unit-admin.capy.wasm.source-map -70f0efd6172d200a273ce51178228705f3714d912593975ae65ecc633e046458 site_tests_capy-variable-expressions.capy.wasm -77c1663b290ab1c94886f90fad97e762f5670db15b2c432d075989df7540d4dd site_tests_capy-variable-expressions.capy.wasm.source-map -f339e8d898f5fb82daff2559d610e3e156c223112ba3fd8d7906f051dd2905c5 site_tests_capy-vector-variadic.capy.wasm -eb54712650d6b43ca25b203c837b4f8021801deae75d0be10257dae1e7364738 site_tests_capy-vector-variadic.capy.wasm.source-map -afb566fc96219b29d27ca906edeaab0fd8b520d1101a58ea78cc7f02b1f932cf site_tests_capy-websocket.capy.wasm -3a1adb776fa22d15ad015626f31d2d87cd676e6285bd9180a458b47e988b760f site_tests_capy-websocket.capy.wasm.source-map -0fe39e9245d3a25e7eee9242577b7f4e5814c7a3463af17259ee2f073b8c473e site_tests_capy-whitespace.capy.wasm -309cfc84db6b082290d7ffadef399cf6b2af660fc834b4414cae339df6037819 site_tests_capy-whitespace.capy.wasm.source-map -2403b2a18baa4f0800ceaa49a5e5e8715878f0417adbc300915d8fc7cf2be21d site_tests_capy-wide-conversion-trap.capy.wasm -c995638e7d5d7e2ff5dcfb0683012a7d72fd8ac3941a2016b82f3c7bcb78f32e site_tests_capy-wide-conversion-trap.capy.wasm.source-map -b26549031126445163516d8be7006a346fa02a18b6a8412afaa99be33dabbc3c site_tests_capy-wide-scalars.capy.wasm -f492539782da095e4de702cc91f6b084fab937a8fc431e202081a983c520a5b9 site_tests_capy-wide-scalars.capy.wasm.source-map -82dd02d0cb41f5a9357d7f60c3073de83a0426b7e529c5d6036781635390e8eb site_tests_cli.capy.wasm -6f77b096a8aadf05c8982e7658a2e18248e3324b66b6d7ae1ec180f148f339e7 site_tests_cli.capy.wasm.source-map -d5840c2892a0070d6b78144a263da3ccb8a2b23852f2902ecd972feb431183b2 site_tests_cli_runner.capy.wasm -3203fda7a14cde4ccd8ddebabfb64460642891373295c91b6587afa573654b57 site_tests_cli_runner.capy.wasm.source-map -2e45ff9cef49cdfd7570f01b76b5bd5c5de74c0ce925327f15506cd94f08d90c site_tests_component_failure.capy.wasm -4b9352cb8a12097c8d990036a77b169f98b80a38fd38b6fc77fb0fd9a2490bc4 site_tests_component_failure.capy.wasm.source-map -c6df4e218cde4eb2eb740d68537243a0187f83b125ee5424ddc66214c161bf9e site_tests_components.capy.wasm -ec15b6d0027f1b40f37ea865f3f3d27d0170df1814de55c8befa8238c79a2201 site_tests_components.capy.wasm.source-map -04f5270ab37f17aaeafed34e75877d484eca6a08edf58d4cb99bf515dab348bb site_tests_components_page.capy.wasm -4be484d1ed9374646b25e2df46111bc50ce23214e91de06e177833bf261641da site_tests_components_page.capy.wasm.source-map -01d26729f655d9c2a328c91ffdd8dbaa71678ff3f8e4fbe5177b1e1fcc18bf66 site_tests_core.capy.wasm -ca21fc3346cd3d03e3607ce7ed97f0bd0438078d00dcfc0aa8d0d264180bb337 site_tests_core.capy.wasm.source-map -c53977de530d263e7f762013901ae0503c698fed101fd74081293704736cb2f1 site_tests_http.capy.wasm -c56217839b4ec0f2d7cceee7558b4a223ec11565fb5bf4a8f5942e54aaa3dd3e site_tests_http.capy.wasm.source-map -a017516727fe250f25aed92924d659a555826b142f689f341ef307a8d5b781b5 site_tests_index.capy.wasm -f3b9ebe54015b3e90fe73873b6c6381a2ea317f6fdef93681ad3591e60b0eeb4 site_tests_index.capy.wasm.source-map -093980a993189c0ed5e039ec356b556897867d4eb380ac3614e8f914d5ea488b site_tests_io.capy.wasm -7c337ac5ed88f76d178c82a447f4a574bc8a56bd0bf5440bcc932c5ac8f7415f site_tests_io.capy.wasm.source-map -20413cabfb6c15fb068d06b62b455ef7f09a5b09740af3b37a2fd51c1d29457d site_tests_markdown.capy.wasm -8ff6c7a1ac6acbcc1ad8180f1f6358d608669cbadb0c15f29c314221caca085d site_tests_markdown.capy.wasm.source-map -571b61f4cc949743ccc30eef4dd5dfff7e34852b20f99c1bddb6b8e44767d516 site_tests_pool-isolation.capy.wasm -1e19724083caf07785f161561ec4b072161584c99e5844fefddfc0985ba5fa2c site_tests_pool-isolation.capy.wasm.source-map -8c0fa1a57a5679079922a8ccfeeb9404fd62013fd246a1d420a48b1678ed858b site_tests_preprocessor.capy.wasm -44c0cfd58e9329f03d8e529ed1422e6226ab511bc61158a4e296912080042887 site_tests_preprocessor.capy.wasm.source-map -194340ba674cd8a564fc4d8018f944c87f0520b2a28e42d753312a2448b5789d site_tests_security_headers.capy.wasm -70120a3c74b1cdc8f9f3a5ac05e1ed163cf4dfc50841e335da4adf2153dd3c63 site_tests_security_headers.capy.wasm.source-map -6759e6bf546c2b8384f0951c98b56bbb4a97ffba23b71fb5669ae0bd4a818348 site_tests_servers_http.capy.wasm -7adfe514dcf9bb73332b03543dab9cfe9e6c2544cf2846106364161b4d22164c site_tests_servers_http.capy.wasm.source-map -5f1270257e02bcf30a5d2ae4f0374cfbbd5c86020c06d7b4d144634d7ab1ef98 site_tests_services.capy.wasm -78eabf0fec4e3e35eaf5c8c3826ec4747ad4506c47f498334993ef19d9f484b2 site_tests_services.capy.wasm.source-map -e846e9a929a625967449f6beb58b28079a5c48c09c33ae9cc0d715231a5ba219 site_tests_sqlite.capy.wasm -9d9739a965761d046fa6d5992c681d2d646eadbf9c5135234a727c21b93647ff site_tests_sqlite.capy.wasm.source-map -e33c8e043b7dcc7d634c385afb38977d175d0b66664d983542d9d403244b83a6 site_tests_task-handlers.capy.wasm -279bedcc4d4611717f937171cd0d0ba6a3b5849dacfacf059afe495a6119b67b site_tests_task-handlers.capy.wasm.source-map -03450a6dac1eed0642d6a45b277c6c2309aaa0dc320bb7f7e75c2bd39806023a site_tests_tasks.capy.wasm -3e1ef6d830698905e4f352915eda6c5a5c1366a69f8b0b8de39add4742ddee0b site_tests_tasks.capy.wasm.source-map -7de2ca109495b5292855dda0e8ed181948a7ed82fc6955a5a4a358831eef8491 site_tests_unit_failure.capy.wasm -470d752c8ca176c887f0ca9eec2ae6ce41ca6499c4e590c2747a80311a6ea73e site_tests_unit_failure.capy.wasm.source-map -16aac62c9b83a9a3f93462d99285565a2ed5ae8e3e749b151e63d860d308523a site_tests_units.capy.wasm -8a7940c954c575e801a0d0b009c3b9469624d4ae8599aa8a7c1ec1c102d545e6 site_tests_units.capy.wasm.source-map -0a6bfaefef934b6994a24179a94f178c90a8c8d564b43cbe3cecc2b87f349e8f site_tests_websockets.ws.capy.wasm -5724f6c9c581e643eb7bf44f9295294a225e220d92576d3698e342a601223ffc site_tests_websockets.ws.capy.wasm.source-map -ec0de01f2f0a7457ac2ca1180c1fa191f79298d4ae891145de1d9ad3dbf51331 site_tests_zip.capy.wasm -9997534a36a7dfce979d9260227b02ef7071f1eb2374b166d4f051517217714f site_tests_zip.capy.wasm.source-map +ec1694ed1555fd7394de0d294d1a5a3524ce2d2358bf2a69e45d79d7329b87a3 site_tests_capy-serve-http-caller.capy.wasm +2b6d95c85c535c1509cef5cee00d361271564634dbfa8fcee17deaeefed67393 site_tests_capy-serve-http-caller.capy.wasm.source-map +6f6d87d2ebc9d41835c5ee2f49d0aed32548dfa5f61a97d6780e84c0aaf1f698 site_tests_capy-serve-http.capy.wasm +198947a8af688c10f422c545b389f66bf59438c72d877f9bc54ab28455cf404b site_tests_capy-serve-http.capy.wasm.source-map +695d51a4f5d08f1b10742972eda2602ba271eef7705cec568819b490b4709bc8 site_tests_capy-session.capy.wasm +6878e41f19d132d91b309925ee1912869460eec4fa4553aac62d30f27920e891 site_tests_capy-session.capy.wasm.source-map +dc0f0a55610c97b2b1fbf513731df77c838ac46a63abbc07b05dcf82f5ef1e9a site_tests_capy-sqlite.capy.wasm +b7ce5b8d0468da2693f821cb89e1876c50ae50daeda0c1ba1f180f068db44fca site_tests_capy-sqlite.capy.wasm.source-map +723bd2c9f8af345a0d3a29bc1614594554002b3e3be76331e6643fc346182d59 site_tests_capy-sqlite-failed.capy.wasm +6bebdf09b0973f4e6d6888372a8d73e8c9dabc8efc202b9a17c3a6beb3886213 site_tests_capy-sqlite-failed.capy.wasm.source-map +14509827d66795d705bb13f2e3c8997d9c27bd0980dc1dd90176285a55b01a91 site_tests_capy-sqlite-handle-trap.capy.wasm +367667152775471300f60e57f1fccc63aefcfbe57abf9ed0fd5fbaa708d6bc14 site_tests_capy-sqlite-handle-trap.capy.wasm.source-map +2d9df61b7f68487a1d4c38e8b1b43bfdf3bb85df4591bff3158db3e2e27893b5 site_tests_capy-sqlite-info-trap.capy.wasm +c08bd4230f1a37391e23c82ac3a1cdbb097f1f456f69218c68a4d997de5a5ab4 site_tests_capy-sqlite-info-trap.capy.wasm.source-map +5b6c435c3a18eea20eef4310640817a9a8d7d89e04beccfdd883cdd898d2664d site_tests_capy-sqlite-params-trap.capy.wasm +7616aa9f791363e9c9c3a82829b6924bc3b2083dfca35c62c0d1a233baecec40 site_tests_capy-sqlite-params-trap.capy.wasm.source-map +4fc8f854b36477a5a9a941e49e22cc5a3af5072ea061ae2d1f097e13aa5647b4 site_tests_capy-sqlite-sized-host-trap.capy.wasm +29df2d49f0ff74e65c98345adaac74f01ac610cf10cc5e6438520c1e487372c0 site_tests_capy-sqlite-sized-host-trap.capy.wasm.source-map +4318ebb81a0efff4ea8257c79b9f92cf4b5f06ea646a078cd7dbc370d223fc1c site_tests_capy-sqlite-zero-trap.capy.wasm +b9c09e3a40764da05d94851f88b84917c837f39d6c3258b0666b592e59a6a9f2 site_tests_capy-sqlite-zero-trap.capy.wasm.source-map +0dd34e33795b27fe3bff5da7ff5b228f2eabc20ef322014cb521b05dca02aa15 site_tests_capy-string-concat-only.capy.wasm +47549bc3f0746875abef1c8654834e9430b664eb512479ca6f1c2176a43b4580 site_tests_capy-string-concat-only.capy.wasm.source-map +4de0d186f7376bd057d0cce90faecf6c410242e55211bcb2fc77305cfc10dc7d site_tests_capy-string-list-scalar-trap.capy.wasm +017e140bea1660c2f0a73e69055b134f0eb6331f0f705a1ab13fd966c54a9b44 site_tests_capy-string-list-scalar-trap.capy.wasm.source-map +8f0b44bc5df2b9febf1f84ced10f3f7b7f1588b6639d426df2a18a589bc8ea6d site_tests_capy-string-lists.capy.wasm +b506407a6478849cbb9d1ec9292223aa21c7b60ef55789fd58d7a90d2ac37be7 site_tests_capy-string-lists.capy.wasm.source-map +178e4529072eda76afacb40514ee843e636bda216c4b141bf4ac774bfda7f28f site_tests_capy-string-list-trap.capy.wasm +aa53246a64b5239a2e0c968ff43a6d58095848d46c001634dff29b6ab2faece2 site_tests_capy-string-list-trap.capy.wasm.source-map +2efb30b1ace196747524aa2e18c5c8801f5d5e2d34f0fcd46b42a5d5f6cecbbb site_tests_capy-strings.capy.wasm +97ddb65a84abd489055dbb369b99b38f29681fb81c760b81909efc4065ccb0c6 site_tests_capy-strings.capy.wasm.source-map +6a717e0aca414f95f76268442dec24e7bf806cc68bfbfeb947ceff4f4a1d2176 site_tests_capy-task-concurrency.capy.wasm +c2131d7f70fa5ae23ba6f4a6591317c2c08365e1d01d6fd7c4a8fa1a56303f0e site_tests_capy-task-concurrency.capy.wasm.source-map +f64edabb721cc2ae0a39fa3e371212cf5c4bcce2af82b83578917018ff878de5 site_tests_capy-task-overflow.capy.wasm +b8703ce7d2ed509a56c8cd161e57728e2420ad73200ba371c5c43514705ecb05 site_tests_capy-task-overflow.capy.wasm.source-map +9b91bdbf9878d683a6665b305f0684743859d83c1f33dd8c204232a5d4a01f0e site_tests_capy-task-runtime.capy.wasm +e9eb8a5801115a0cf5f68d78fb140130586a48b2f487ca9c502ef802bafcaa44 site_tests_capy-task-runtime.capy.wasm.source-map +bb68acef1f285a1aae3464b7c2b9331bf5f69e5a991510f7a7e04724dc55d65b site_tests_capy-task-timeout.capy.wasm +f2e394c6f7735d4f6316a90618650d3a8b424355642c1d5243c8855caff89161 site_tests_capy-task-timeout.capy.wasm.source-map +dc0f2aa7c9de951aa3e2ff306082978c5eb281adf99b48dd07c571be03befeaf site_tests_capy-time-parity.capy.wasm +d418041b67ff9f720040d0c74cd55e1c21c1b98657db57d584fb6a4d6ffc3fde site_tests_capy-time-parity.capy.wasm.source-map +87abbfcbf06db85dc5f6a5f2e39722f5e8ae3a4a1a8cca080e08f6ce41f3af87 site_tests_capy-unit-admin.capy.wasm +a77c1a4ff27c4c087098e6c793be95ace4c5211f449f768a52e36fcce099dc60 site_tests_capy-unit-admin.capy.wasm.source-map +4ab016a26095af88311bd23ed6ecd1013c100efe5488fa8692e40aa297e9cdbb site_tests_capy-variable-expressions.capy.wasm +fd11593291ac5249fa361ac694dcda80cb8a966409a5a33ddc943542094060dd site_tests_capy-variable-expressions.capy.wasm.source-map +4a1d64e7f48267cd930ef8880d9186fab62aa13eb7150419131d41ba0819a74c site_tests_capy-vector-variadic.capy.wasm +48525338bc7fdafbc2b4e2a75a7f81f08345036337a4d5ed5391ee40fb36e90d site_tests_capy-vector-variadic.capy.wasm.source-map +4dd04dbd723356c28b2fa42440f71b46cb6368ecd6fad2d92b1c68d5e6a5e874 site_tests_capy-websocket.capy.wasm +635ea2379ee4ae229296e277fa8eefb211a2d02ae6d373abd001b601ae26ccc0 site_tests_capy-websocket.capy.wasm.source-map +9bedea27412928ae73beeb9f07385161abeab84096e4a995e759f0fbfad1f5aa site_tests_capy-whitespace.capy.wasm +e9579c338d08b346cbde577c5d3e04cd2b41e768bd83955769033e15c8b0083b site_tests_capy-whitespace.capy.wasm.source-map +5050a6adb07a9f025554580596a8e378a9a6abf98058d627c96546e1211b3d0f site_tests_capy-wide-conversion-trap.capy.wasm +1e9422b4b1d0c2210013ed0daadd216af47813dae12a52797740e6cdaa285b43 site_tests_capy-wide-conversion-trap.capy.wasm.source-map +6f24e8064f6b7778f7a0e21b8c7ff26f45453dd9040b4123fcabde93a79d9084 site_tests_capy-wide-scalars.capy.wasm +a1f3660b436bfd754dbfa02b6a51b462756341fb1e1cbcd703167f86064ad703 site_tests_capy-wide-scalars.capy.wasm.source-map +aaba93e22059e930a9eccac1c5de22c2bb437f7ae1eef3ac51f0156b040df7ea site_tests_cli.capy.wasm +039c2e580530276614f1625be67475920ecfac88b1f4d1f40c2f396fc4a3481d site_tests_cli.capy.wasm.source-map +1ca02b1bf69de7a42fee41a7dce7e6c7c2bfceb8fac8c4014048b984ed7347a0 site_tests_cli_runner.capy.wasm +3689cabaca03be0ebdc2f6edbac80f7b9c40e1340276cd69bde9899b3211a836 site_tests_cli_runner.capy.wasm.source-map +1d5f7caf62ad86d40fb2036922c4459902038833d6d2673bb4e0bec7a130d771 site_tests_component_failure.capy.wasm +1b70bd051a6b44e3fc185edb082f069900f144a2e83ff5eefd930c8e189fd5c6 site_tests_component_failure.capy.wasm.source-map +94173a7ef0480ac417b5dacde25890894123cfcef3ead21a325824b63c6e2604 site_tests_components.capy.wasm +1ef7b6b61613601a20135bfe71e7f058545ae3a393cd8156b31e301ed3247640 site_tests_components.capy.wasm.source-map +77ea510b60b16b4bde3f2275c21acd3e13d820471b20232f50aeb0739a04dde5 site_tests_components_page.capy.wasm +7ef14acc32cb57981e1263c8c74c3d89e49622d09ade71318a8843c10e2c27b5 site_tests_components_page.capy.wasm.source-map +4696a85258bb31719f14cb1afad383db65f91d45f5e50699fd88b348206257dd site_tests_core.capy.wasm +1f318fefaa43507770606221412bd56702da0303c1f27193cab990d54413aec8 site_tests_core.capy.wasm.source-map +076443c873142acbcd06a9126bcbac6395632a95765e1ecbe44e2248cb794e7f site_tests_http.capy.wasm +dcb4f5332c6c1b4f5c8a2f30a352721a0d44a82c8334cf96e71d477490edcc2f site_tests_http.capy.wasm.source-map +630d2a1dee78fc0bedd1beb77b57002c33e6899030972b94dbca7f2c05607c3c site_tests_index.capy.wasm +9c375e2d2070fceda767766c725d0221634c7fa7133b15a03aeb5f2fe1f7f756 site_tests_index.capy.wasm.source-map +f3537c327f84084e1ffe5faf6a179acb53f2f7f8897eab2fee1ca900e7887e00 site_tests_io.capy.wasm +006800c7eda14d03a3d10a12fdd128b7bdd7b3073fcf9319ee6b531ed90712c8 site_tests_io.capy.wasm.source-map +be40c9f1c28a10476bace59bf3ae56c59e651b91747313e9145c048e81339f65 site_tests_markdown.capy.wasm +24f6e4d94e144adeea6a11063761957e01b244b4351f4bb3d51cadf1f0198331 site_tests_markdown.capy.wasm.source-map +7068ac3a916819cfde62b601798450202914a147c9b4d55f85db6df84d62ea9d site_tests_pool-isolation.capy.wasm +abe54aecc6b205f3da77981b2300cf0940b6e4e60900f9c51d0aab30b138ad73 site_tests_pool-isolation.capy.wasm.source-map +58dc55a51ed4fd2f16cf09d21493e72974cbd66440ddfae15e2d2315d05fe81c site_tests_preprocessor.capy.wasm +8c5b685fb72cfc64022642b05a936534731e9357d4c0894cb6db5d06464b0bdd site_tests_preprocessor.capy.wasm.source-map +f625b45859fb0d13931d417071d18f860b670b50be1b02fcf4889fe4644cdbed site_tests_security_headers.capy.wasm +61f7bac8a72c5a404f66834c1cbf7b6ec2f5da3afa0f968c255b8832c3f7472e site_tests_security_headers.capy.wasm.source-map +9c1dc4c5e4ec4ff582f31da4dd4014f1a0f59f4d4d90bb5e3ae8245b8264600d site_tests_servers_http.capy.wasm +d2ef3199f95fed7424f4ac85e382bfc5ddd7c04dbabb5ef20025f66d64c7570e site_tests_servers_http.capy.wasm.source-map +a688297d307f2e3ce6130f256143baebb69a4d68238b8ab81467e76a3f6baf87 site_tests_services.capy.wasm +84ad37809f324a00bee6af175e2095c60b340b9f934ed8613f390569a7f8b0c0 site_tests_services.capy.wasm.source-map +b1cd7f94f00281f5d2f7cfc5be6d54fe50b460afdd681f752c03ddee76ecdd38 site_tests_sqlite.capy.wasm +f31c16d7845ce748ccf5e88b611d1ef21fc365f53424d5f5500402b2db67d0f2 site_tests_sqlite.capy.wasm.source-map +0c8c168d6c7359416ae069604d7acb8b929b464897a3128311a2dc0801f388b8 site_tests_task-handlers.capy.wasm +7137d225337776f4da5113f53bed30413ed38b21cea14331ac4e2bfa1e153f14 site_tests_task-handlers.capy.wasm.source-map +b7daf02f69b8ff7a8057f945c50b4e210980e5bdb2b76bf55029b6aabcdf892c site_tests_tasks.capy.wasm +8a40ae3c3f62f4564078c1e3278c6e8553bb7b0178ad78e45536087cadfc6228 site_tests_tasks.capy.wasm.source-map +9bf5e58b3d3da7dd91ae8b576cfff9824bd969bc3ff0d4067a5c7c8465d6e698 site_tests_unit_failure.capy.wasm +8d1f59d2f3065acfb7f70f8fffe7535ad3a01f190172dcda3cf309c1c6cbfdb5 site_tests_unit_failure.capy.wasm.source-map +d64cba567cff7db3eb8e9cec001129a1486d71e8b3923556959130572ff75ca7 site_tests_units.capy.wasm +e1de3f4ce3811c63d458495bb222e6a78ba7cce17ea8db3132ae36839e7e89e9 site_tests_units.capy.wasm.source-map +abe7af256812645f125ffcf4f09c07be2151039d687067ae1a1d6bb588dd5c35 site_tests_websockets.ws.capy.wasm +a90a517e59510587fed2ad9e9a8aeb97fcfb3a005fa1066bb877cb3012221c73 site_tests_websockets.ws.capy.wasm.source-map +e0fe59e52843075fd6a81bc9c681ca68ee7dae6cc0c2d08c76b5c1ee400b9947 site_tests_zip.capy.wasm +fa231171291728604cad95dc84bf1945d52bea4d437d0796864d93f3840fa762 site_tests_zip.capy.wasm.source-map diff --git a/scripts/test_capy_native.sh b/scripts/test_capy_native.sh index 44b70b18..e90e8adf 100755 --- a/scripts/test_capy_native.sh +++ b/scripts/test_capy_native.sh @@ -22,7 +22,7 @@ python3 - <<'STATIC_GATE' from pathlib import Path import re handlers = re.compile(r'^\s*function\s+(?:RENDER|COMPONENT(?:\s*:\s*[A-Za-z_][A-Za-z0-9_]*)?|CLI|WS|TASK(?:\s*:\s*[A-Za-z_][A-Za-z0-9_]*)?|INIT|ONCE|SERVE_HTTP(?:\s*:\s*[A-Za-z_][A-Za-z0-9_]*)?)\s*(?:\(([^)]*)\))?\s*\{', re.M) -removed = re.compile(r'\b(?:request_context|request_param|request_get|request_post|request_cookie|request_session|request_body|request_base_url|request_script_url|request_query_path|request_query_route|cli_input|cli_arg|ws_message|ws_connection_id|ws_scope|ws_opcode|ws_is_binary|ws_connections|ws_connection_count|to_bool|to_f64|to_s64|to_u64|to_lower|to_upper|dval_to_json|dval_to_stringmap|request_route_from_raw_path|request_perf)\s*\(') +removed = re.compile(r'\b(?:request_context|request_param|request_get|request_post|request_cookie|request_session|request_body|request_base_url|request_script_url|request_query_path|request_query_route|cli_input|cli_arg|ws_message|ws_connection_id|ws_scope|ws_opcode|ws_is_binary|ws_connections|ws_connection_count|to_bool|to_f64|to_s64|to_u64|to_lower|to_upper|dval_to_json|dval_to_stringmap|request_route_from_raw_path|request_perf|password_needs_rehash|ascii_safe_name|component_exists|memcache_escape_key|sha256_hex|hmac_sha256_hex|shell_spawn)\s*\(') paths = [path for line in __import__('subprocess').check_output(['git', 'ls-files', '*.capy'], text=True).splitlines() if (path := Path(line)).is_file()] errors = [] for path in paths: @@ -170,6 +170,4 @@ wasm-objdump -x "$BUILD_DIR/site_tests_capy-request-context.capy.wasm" >"$BUILD_ grep -q 'env.bearer_handler_input_brrb' "$BUILD_DIR/request-context.objdump" ! grep -q 'env.bearer_request_context_brrb\|env.bearer_request_context_for_brrb\|env.bearer_request_value\|env.bearer_request_body' "$BUILD_DIR/request-context.objdump" ! grep -q 'env.bearer_response_set_status\|env.bearer_response_set_header' "$BUILD_DIR/request-context.objdump" -CAPYC="$BUILD_DIR/capyc" scripts/test_capy_artifact_golden.sh - echo "native Capy frontend, Wasm, compiler, CLI, and tracked fixture checks passed" diff --git a/scripts/test_capy_native_compiler.cpp b/scripts/test_capy_native_compiler.cpp index 8b225625..c8618b1d 100644 --- a/scripts/test_capy_native_compiler.cpp +++ b/scripts/test_capy_native_compiler.cpp @@ -227,7 +227,7 @@ int main() for (const char* old_name : {"dval_string", "dval_bool", "dval_s32", "dval_f64", "dval_to_string", "dval_to_bool", "dval_to_f64", "dval_to_s64", "dval_to_u64"}) try { capy::compile_bearer_unit(std::string("function CLI(request : dval) { ") + old_name + "(dval(\"x\")) }\n", options); assert(false); } catch (const capy::Error& error) { assert(error.message.find("no overload") != std::string::npos); } - for (const char* old_name : {"request_context", "request_param", "request_get", "request_post", "request_cookie", "request_session", "request_body", "request_base_url", "request_script_url", "request_query_path", "request_query_route", "cli_input", "cli_arg", "ws_message", "ws_connection_id", "ws_scope", "ws_opcode", "ws_is_binary", "ws_connections", "ws_connection_count", "to_bool", "to_f64", "to_s64", "to_u64", "to_lower", "to_upper", "dval_to_json", "dval_to_stringmap"}) + for (const char* old_name : {"request_context", "request_param", "request_get", "request_post", "request_cookie", "request_session", "request_body", "request_base_url", "request_script_url", "request_query_path", "request_query_route", "cli_input", "cli_arg", "ws_message", "ws_connection_id", "ws_scope", "ws_opcode", "ws_is_binary", "ws_connections", "ws_connection_count", "to_bool", "to_f64", "to_s64", "to_u64", "to_lower", "to_upper", "dval_to_json", "dval_to_stringmap", "password_needs_rehash", "ascii_safe_name", "component_exists", "memcache_escape_key", "sha256_hex", "hmac_sha256_hex", "shell_spawn"}) try { capy::compile_bearer_unit(std::string("function CLI(request : dval) { ") + old_name + "() }\n", options); assert(false); } catch (const capy::Error& error) { assert(error.message.find("was removed") != std::string::npos); } for (const auto& [old_name, arguments] : {std::pair{"request_route_from_raw_path", "(\"path\")"}, std::pair{"request_perf", "()"}}) @@ -687,7 +687,7 @@ int main() "request_param", "request_get", "request_post", "request_cookie", "request_session", "request_body", "request_context", "session_start", "session_set", "session_remove", "session_destroy", "session_id_create", "redirect", "csrf_token", "csrf_valid", "csrf_rotate", "csrf_field", "ws_message", "ws_connection_id", "ws_scope", "ws_opcode", "ws_is_binary", "ws_send", "ws_send_to", "ws_close", "component", "component_render", - "component_exists", "component_resolve", "unit_render", "unit_call", "unit_info", "units_list", "unit_compile", "regex_match", "regex_search", "regex_search_all", "regex_replace", + "component_resolve", "unit_render", "unit_call", "unit_info", "units_list", "unit_compile", "regex_match", "regex_search", "regex_search_all", "regex_replace", "regex_split", "base64_encode", "base64_decode", "uri_encode", "uri_decode", "json_encode", "json_decode", "html_escape", "strpos", "file_open", "file_read", "file_write", "file_seek", "file_tell", "file_fsync", "file_close", "file_temp", "file_unlink", "time", "time_precise"}) assert(compiler_text.find("named->value == \"" + std::string(public_name) + "\"") == std::string::npos); @@ -716,7 +716,6 @@ int main() assert(function_value.wasm == parsed_result.wasm && function_value.source_map == parsed_result.source_map); const auto scoped_stdlib_parameter = capy::compile_bearer_unit( "function CLI(request : dval) { print(encode_query(dval({\"name\": \"Ada\"}))) }\n", options); - assert(scoped_stdlib_parameter.source_map.find("\t340\t") == std::string::npos); const auto bare_stdlib_function_value = capy::compile_bearer_unit("function CLI(request : dval) { map(dval([\"X\"]), lower) }\n", options); assert(capy::wasm::validate_bearer_unit(bare_stdlib_function_value.wasm, {.bearer_abi_version = "11"}).valid); assert(std::string(bare_stdlib_function_value.wasm.begin(), bare_stdlib_function_value.wasm.end()).find("bearer_string_lower") != std::string::npos); diff --git a/scripts/test_capy_phase1.sh b/scripts/test_capy_phase1.sh index 030fbe13..4e207617 100755 --- a/scripts/test_capy_phase1.sh +++ b/scripts/test_capy_phase1.sh @@ -239,8 +239,27 @@ set -e [[ $archive_trap_status -ne 0 && "$archive_trap_output" == *"capy-archive-trap.capy:1:38"* && "$archive_trap_output" != *"capy://stdlib.capy"* ]] expect_equal "archive recovery" "3|heXYZ|Ada:admin|archive data|true2truetruetrue|9|0|true" "$(scripts/bearer-cli /tests/capy-final-parity.capy)" expect_equal "live MySQL stdlib adapters" "truetrue|'a\\'b'|7|true|0:0|truetruetrue|true|truetruetrue|0" "$(scripts/bearer-cli /tests/capy-mysql.capy)" -expect_equal "memcache stdlib adapters" "a_b|line_key|down|live|0" "$(scripts/bearer-cli /tests/capy-memcache.capy)" +expect_equal "memcache key normalization" "down|collision|0" "$(scripts/bearer-cli /tests/capy-memcache.capy)" expect_equal "job/process stdlib adapters" "shell|spawned|done|done|done|cancel|cancelled|tasks|cwd|server|0" "$(scripts/bearer-cli /tests/capy-jobs.capy)" +for shell_exec_case in \ + "capy-shell-exec-flags-trap|shell_exec: unknown key 'unknown'. Valid keys: stdin, env, timeout_ms, background" \ + "capy-shell-exec-background-type-trap|shell_exec: background must be a bool" \ + "capy-shell-exec-timeout-type-trap|shell_exec: timeout_ms must be a positive number" \ + "capy-shell-exec-timeout-value-trap|shell_exec: timeout_ms must be a positive number" \ + "capy-shell-exec-stdin-type-trap|shell_exec: stdin must be a string" \ + "capy-shell-exec-env-list-trap|shell_exec: env must be a map with string values" \ + "capy-shell-exec-env-value-trap|shell_exec: env must be a map with string values"; do + shell_exec_fixture=${shell_exec_case%%|*} + shell_exec_message=${shell_exec_case#*|} + set +e + shell_exec_flags_output=$(scripts/bearer-cli "/tests/$shell_exec_fixture.capy" 2>&1) + shell_exec_flags_status=$? + set -e + [[ $shell_exec_flags_status -ne 0 && "$shell_exec_flags_output" == *"$shell_exec_message"* ]] || { + echo "Capy $shell_exec_fixture diagnostic mismatch: $shell_exec_flags_output" >&2 + exit 1 + } +done expect_equal "named task worker cancellation/failure/recovery and copied props" "canceled|stopped|failed:handler_trap|failed:missing_handler|succeeded:none|succeeded:before" "$(scripts/bearer-cli /tests/capy-task-runtime.capy)" expect_equal "unit administration" "true|true|true|2|0" "$(scripts/bearer-cli /tests/capy-unit-admin.capy)" expect_equal "DValue array merge" "rightyesnewright|abcd|valueitem|right|value|z|oddkeep|map|unicode|9|0" "$(scripts/bearer-cli /tests/capy-dval-merge.capy)" @@ -306,7 +325,7 @@ set -e exit 1 } crypto_output=$(scripts/bearer-cli /tests/capy-crypto-random.capy) -[[ "$crypto_output" =~ ^A9993E364706816ABA3E25717850C26C9CD0D89D\|20\|32\|ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\|32\|6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a\|truefalse\|16\|truefalsefalse\|1198951227\|9546680768582587775\|true\|7\|true\|true\|true\|[0-9]+\|0$ ]] || { +[[ "$crypto_output" =~ ^a9993e364706816aba3e25717850c26c9cd0d89d\|20\|32\|ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\|32\|6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a\|414243\|truefalse\|16\|truefalse\|1198951227\|9546680768582587775\|true\|7\|true\|true\|true\|[0-9]+\|0$ ]] || { echo "Capy crypto/random adapter mismatch: $crypto_output" >&2 exit 1 } @@ -347,7 +366,7 @@ string_list_trap_status=$? set -e [[ $string_list_trap_status -ne 0 && "$string_list_trap_output" == *"capy-string-list-scalar-trap.capy:2:11"* ]] expect_equal "split/join recovery" "$string_list_output" "$(scripts/bearer-cli /tests/capy-string-lists.capy)" -expect_equal "core utility value adapters" "falsetruefalseBETA,ALPHA,BETA|alpha|beta,alpha|truetrue|alpha|0,1,2|bearer:BEARER|Caffile1:Caffile1:core|0:255:truetrue|1.5:-9:42|truetrue|a=one&b=last&flag=:last:example.test:docs:two|docs/index:true:|one,two,three:A,é:example.test|alpha,beta,beta:true:SIGSEGV:0:true:40|0" "$(scripts/bearer-cli /tests/capy-coreutil.capy)" +expect_equal "core utility value adapters" "falsetruefalseBETA,ALPHA,BETA|alpha|beta,alpha|truetrue|alpha|0,1,2|bearer:BEARER|Caffile1:core|0:255:truetrue|1.5:-9:42|truetrue|a=one&b=last&flag=:last:example.test:docs:two|docs/index:true:|one,two,three:A,é:example.test|alpha,beta,beta:true:SIGSEGV:0:true:40|0" "$(scripts/bearer-cli /tests/capy-coreutil.capy)" set +e coreutil_trap_output=$(scripts/bearer-cli /tests/capy-coreutil-trap.capy 2>&1) coreutil_trap_status=$? @@ -417,7 +436,7 @@ request_component_output=$(scripts/bearer-cli /tests/capy-request-context-caller exit 1 } component_props_output=$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=FromCapy') -[[ "$component_props_output" == "truetruetrue|FromCapy|false|1|FromCapy|false|1|FromCapy|FromCapy|3" ]] || { +[[ "$component_props_output" == "truefalsefalse|FromCapy|false|1|FromCapy|false|1|FromCapy|FromCapy|3" ]] || { echo "Capy component props dispatch mismatch: $component_props_output" >&2 exit 1 } @@ -425,7 +444,7 @@ component_trap_body=$(mktemp) component_trap_status=$(curl -sS --max-time 30 -o "$component_trap_body" -w '%{http_code}' -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=FromCapy&trap=1') [[ "$component_trap_status" == "500" ]] && ! grep -q 'must-not-leak' "$component_trap_body" rm -f "$component_trap_body" -[[ "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=Recovered')" == "truetruetrue|Recovered|false|1|Recovered|false|1|Recovered|Recovered|3" ]] +[[ "$(curl -fsS --max-time 30 -H 'Host: bearer.openfu.com' 'http://127.0.0.1/tests/capy-component-props.capy?name=Recovered')" == "truefalsefalse|Recovered|false|1|Recovered|false|1|Recovered|Recovered|3" ]] ( component_cache_dir=$(mktemp -d "$site_directory/tests/capy-component-cache.XXXXXX") chmod 755 "$component_cache_dir" @@ -433,7 +452,7 @@ rm -f "$component_trap_body" component_cache_name=${component_cache_dir##*/} cat >"$component_cache_dir/parent.capy" <<'EOF' function RENDER(request : dval) { - print(component_exists("child")) + print(length(component_resolve("child")) > 0) } EOF printf '%s\n' 'function COMPONENT(request : dval) { print("child") }' >"$component_cache_dir/child.capy" diff --git a/scripts/test_capy_reference.sh b/scripts/test_capy_reference.sh index 38500b67..5423a869 100755 --- a/scripts/test_capy_reference.sh +++ b/scripts/test_capy_reference.sh @@ -16,7 +16,6 @@ for index in "${!pages[@]}"; do done doc_base="${BEARER_TEST_HTTP_BASE:-http://127.0.0.1}/doc/" -! grep -q 'component_exists' site/doc/index.capy || { echo "Documentation route probes before rendering" >&2; exit 1; } python3 - <<'PY' from pathlib import Path @@ -43,15 +42,14 @@ if 'class=\\\"search-kind\\\"' not in search: raise SystemExit("Documentation search does not label result kinds") PY status() { curl -sS --max-time 60 -o /dev/null -w '%{http_code}' -H "Host: $host" "$1"; } -for path in api/zzzznotreal/ how-to/zzzznotreal/ api/component-2/ api/string-2/ '?''p=0''_String'; do +for path in api/zzzznotreal/ how-to/zzzznotreal/ api/component-exists/ api/component-2/ api/string-2/ '?''p=0''_String'; do [[ "$(status "$doc_base$path")" == 404 ]] || { echo "Old or unknown documentation URL did not return 404: $path" >&2; exit 1; } done for path in api/component/ api/string/ type/string/ type/dvalue/ type/request/ handler/render/ handler/component/ handler/cli/ how-to/read-request-context/; do [[ "$(status "$doc_base$path")" == 200 ]] || { echo "Canonical documentation URL did not return 200: $path" >&2; exit 1; } done component_page=$(curl -fsS --max-time 60 -H "Host: $host" "${doc_base}api/component/") -component_exists_page=$(curl -fsS --max-time 60 -H "Host: $host" "${doc_base}api/component-exists/") -[[ "$component_page" == *">component"* && "$component_exists_page" == *">component_exists"* ]] || { echo "Documentation pages with a shared eight-character prefix did not resolve independently" >&2; exit 1; } +[[ "$component_page" == *">component"* ]] || { echo "Component documentation page did not render" >&2; exit 1; } route_gate="site/doc/content/how-to/route-file-gate.capy" trap 'rm -f "$route_gate"' EXIT cat >"$route_gate" <<'EOF' diff --git a/scripts/test_password_hashing.sh b/scripts/test_password_hashing.sh index 7fcf60e1..bb1d756d 100755 --- a/scripts/test_password_hashing.sh +++ b/scripts/test_password_hashing.sh @@ -32,14 +32,12 @@ cat >"$source_dir/test.capy" <<'EOF' function CLI(request : dval) { var encoded := password_hash("correct horse battery staple") var second := password_hash("correct horse battery staple") - var weaker := "$bearer$scrypt$16384$8$1$00112233445566778899aabbccddeeff$29fdfb3d991961e926a19c1136a07e252afa5fdb8d3a0fb74cdcfa5016956f34" - var excessive := "$bearer$scrypt$131072$8$1$00112233445566778899aabbccddeeff$0000000000000000000000000000000000000000000000000000000000000000" - print(encoded, "\n", if encoded != second { -> "randomized" } else { -> "reused" }, "\n", if password_verify("correct horse battery staple", encoded) { -> "valid" } else { -> "invalid" }, "\n", if password_verify("wrong password", encoded) { -> "wrong-valid" } else { -> "wrong-rejected" }, "\n", if password_needs_rehash(encoded) { -> "rehash" } else { -> "current" }, "\n", if password_verify("legacy password", weaker) && password_needs_rehash(weaker) { -> "legacy-valid-rehash" } else { -> "legacy-failed" }, "\n", if !password_verify("password", excessive) && password_needs_rehash(excessive) { -> "excessive-rejected" } else { -> "excessive-accepted" }, "\n", if !password_verify("password", "$bearer$scrypt$65536$8$1$zz$00") && password_needs_rehash("malformed") { -> "malformed-rejected" } else { -> "malformed-valid" }) + print(encoded, "\n", if encoded != second { -> "randomized" } else { -> "reused" }, "\n", if password_verify("correct horse battery staple", encoded) { -> "valid" } else { -> "invalid" }, "\n", if password_verify("wrong password", encoded) { -> "wrong-valid" } else { -> "wrong-rejected" }) } EOF output=$(scripts/bearer-cli "/$test_name/test.capy") -if [[ "$output" != *'$bearer$scrypt$65536$8$1$'* || "$output" != *$'\nrandomized\nvalid\nwrong-rejected\ncurrent\nlegacy-valid-rehash\nexcessive-rejected\nmalformed-rejected'* ]]; then +if [[ "$output" != *'$bearer$scrypt$65536$8$1$'* || "$output" != *$'\nrandomized\nvalid\nwrong-rejected' ]]; then echo "native password hashing failed: $output" >&2 exit 1 fi diff --git a/site/doc/areas/memcache.txt b/site/doc/areas/memcache.txt index c5cf4b8e..58e52fa3 100644 --- a/site/doc/areas/memcache.txt +++ b/site/doc/areas/memcache.txt @@ -7,4 +7,3 @@ memcache_delete memcache_get memcache_get_multiple memcache_set -memcache_escape_key diff --git a/site/doc/areas/noise.txt b/site/doc/areas/noise.txt index e195b50b..43da262d 100644 --- a/site/doc/areas/noise.txt +++ b/site/doc/areas/noise.txt @@ -10,11 +10,9 @@ gen_float gen_int gen_sha1 sha256 -sha256_hex +hex hmac_sha256 -hmac_sha256_hex random_bytes crypto_equal password_hash password_verify -password_needs_rehash diff --git a/site/doc/areas/ob.txt b/site/doc/areas/ob.txt index de7a98e9..d96a7fa5 100644 --- a/site/doc/areas/ob.txt +++ b/site/doc/areas/ob.txt @@ -6,7 +6,6 @@ handler/render handler/cli unit_call component -component_exists component_resolve ob_close ob_get diff --git a/site/doc/areas/string.txt b/site/doc/areas/string.txt index 56fac54c..2bcf9806 100644 --- a/site/doc/areas/string.txt +++ b/site/doc/areas/string.txt @@ -4,7 +4,6 @@ String Functions string length clone -ascii_safe_name base64_decode base64_encode contains diff --git a/site/doc/areas/sys.txt b/site/doc/areas/sys.txt index d3e77a2a..f2f2ccbc 100644 --- a/site/doc/areas/sys.txt +++ b/site/doc/areas/sys.txt @@ -16,7 +16,6 @@ path_join cwd_set shell_escape shell_exec -shell_spawn job_status job_result job_await diff --git a/site/doc/components/all.capy b/site/doc/components/all.capy index 1e6f937d..8744e248 100644 --- a/site/doc/components/all.capy +++ b/site/doc/components/all.capy @@ -2,7 +2,6 @@ function COMPONENT(request : dval) { print("

All documentation

") print("

API Functions

") print("") - print("") print("") print("") print("") @@ -15,7 +14,6 @@ function COMPONENT(request : dval) { print("") print("") print("") - print("") print("") print("") print("") @@ -76,8 +74,8 @@ function COMPONENT(request : dval) { print("") print("") print("") + print("") print("") - print("") print("") print("") print("") @@ -102,7 +100,6 @@ function COMPONENT(request : dval) { print("") print("") print("") - print("") print("") print("") print("") @@ -120,7 +117,6 @@ function COMPONENT(request : dval) { print("") print("") print("") - print("") print("") print("") print("") @@ -156,10 +152,8 @@ function COMPONENT(request : dval) { print("") print("") print("") - print("") print("") print("") - print("") print("") print("") print("") diff --git a/site/doc/components/index.capy b/site/doc/components/index.capy index b8cee315..33391f6b 100644 --- a/site/doc/components/index.capy +++ b/site/doc/components/index.capy @@ -9,7 +9,6 @@ function COMPONENT(request : dval) { print("
") print("

API Functions

") print("
"); link("/doc/api/array-merge/", "array_merge", "api"); print("
") - print("
"); link("/doc/api/ascii-safe-name/", "ascii_safe_name", "api"); print("
") print("
"); link("/doc/api/backtrace-capture/", "backtrace_capture", "api"); print("
") print("
"); link("/doc/api/backtrace-get-frames/", "backtrace_get_frames", "api"); print("
") print("
"); link("/doc/api/base64-decode/", "base64_decode", "api"); print("
") @@ -22,7 +21,6 @@ function COMPONENT(request : dval) { print("
"); link("/doc/api/clear/", "clear", "api"); print("
") print("
"); link("/doc/api/clone/", "clone", "api"); print("
") print("
"); link("/doc/api/component/", "component", "api"); print("
") - print("
"); link("/doc/api/component-exists/", "component_exists", "api"); print("
") print("
"); link("/doc/api/component-render/", "component_render", "api"); print("
") print("
"); link("/doc/api/component-resolve/", "component_resolve", "api"); print("
") print("
"); link("/doc/api/contains/", "contains", "api"); print("
") @@ -83,8 +81,8 @@ function COMPONENT(request : dval) { print("
"); link("/doc/api/gz-compress/", "gz_compress", "api"); print("
") print("
"); link("/doc/api/gz-uncompress/", "gz_uncompress", "api"); print("
") print("
"); link("/doc/api/has/", "has", "api"); print("
") + print("
"); link("/doc/api/hex/", "hex", "api"); print("
") print("
"); link("/doc/api/hmac-sha256/", "hmac_sha256", "api"); print("
") - print("
"); link("/doc/api/hmac-sha256-hex/", "hmac_sha256_hex", "api"); print("
") print("
"); link("/doc/api/html-escape/", "html_escape", "api"); print("
") print("
"); link("/doc/api/http-request/", "http_request", "api"); print("
") print("
"); link("/doc/api/http-request-async/", "http_request_async", "api"); print("
") @@ -109,7 +107,6 @@ function COMPONENT(request : dval) { print("
"); link("/doc/api/memcache-command/", "memcache_command", "api"); print("
") print("
"); link("/doc/api/memcache-connect/", "memcache_connect", "api"); print("
") print("
"); link("/doc/api/memcache-delete/", "memcache_delete", "api"); print("
") - print("
"); link("/doc/api/memcache-escape-key/", "memcache_escape_key", "api"); print("
") print("
"); link("/doc/api/memcache-get/", "memcache_get", "api"); print("
") print("
"); link("/doc/api/memcache-get-multiple/", "memcache_get_multiple", "api"); print("
") print("
"); link("/doc/api/memcache-set/", "memcache_set", "api"); print("
") @@ -127,7 +124,6 @@ function COMPONENT(request : dval) { print("
"); link("/doc/api/parse-query/", "parse_query", "api"); print("
") print("
"); link("/doc/api/parse-uri/", "parse_uri", "api"); print("
") print("
"); link("/doc/api/password-hash/", "password_hash", "api"); print("
") - print("
"); link("/doc/api/password-needs-rehash/", "password_needs_rehash", "api"); print("
") print("
"); link("/doc/api/password-verify/", "password_verify", "api"); print("
") print("
"); link("/doc/api/path-is-within/", "path_is_within", "api"); print("
") print("
"); link("/doc/api/path-join/", "path_join", "api"); print("
") @@ -163,10 +159,8 @@ function COMPONENT(request : dval) { print("
"); link("/doc/api/session-start/", "session_start", "api"); print("
") print("
"); link("/doc/api/set/", "set", "api"); print("
") print("
"); link("/doc/api/sha256/", "sha256", "api"); print("
") - print("
"); link("/doc/api/sha256-hex/", "sha256_hex", "api"); print("
") print("
"); link("/doc/api/shell-escape/", "shell_escape", "api"); print("
") print("
"); link("/doc/api/shell-exec/", "shell_exec", "api"); print("
") - print("
"); link("/doc/api/shell-spawn/", "shell_spawn", "api"); print("
") print("
"); link("/doc/api/socket-close/", "socket_close", "api"); print("
") print("
"); link("/doc/api/socket-connect/", "socket_connect", "api"); print("
") print("
"); link("/doc/api/socket-read/", "socket_read", "api"); print("
") diff --git a/site/doc/components/search.capy b/site/doc/components/search.capy index 6125e7c4..0cebede8 100644 --- a/site/doc/components/search.capy +++ b/site/doc/components/search.capy @@ -32,7 +32,6 @@ function COMPONENT(request : dval) { var found := false print("

API Functions

") if consider(tokens, "/doc/api/array-merge/", "array_merge", "API Functions", "array_merge\n`array_merge` combines two `dval` values. It returns a new value.\n\nFor maps, values from `right` replace matching values from `left`. The function also merges lists.\n\nleft : first value\nright : second value\na merged `dval` value") { found = true } - if consider(tokens, "/doc/api/ascii-safe-name/", "ascii_safe_name", "API Functions", "ascii_safe_name\n`ascii_safe_name` converts text to an ASCII-safe name.\n\nUse it when a target accepts ASCII names only.\n\nraw : source text\nan ASCII-safe name") { found = true } if consider(tokens, "/doc/api/backtrace-capture/", "backtrace_capture", "API Functions", "backtrace_capture\n`backtrace_capture` gets a backtrace for the current call stack.\n\nCall it with no arguments. You can also set the maximum frame count and skip count.\n\nmax_frames : maximum number of frames\nskip_frames : number of newest frames to omit\na backtrace string") { found = true } if consider(tokens, "/doc/api/backtrace-get-frames/", "backtrace_get_frames", "API Functions", "backtrace_get_frames\n`backtrace_get_frames` gets source-mapped frames for the current Capy call stack.\n\nSet `max_frames` to limit the result. Set `skip_frames` to omit the newest frames.\n\nmax_frames : maximum number of frames\nskip_frames : number of newest frames to omit\na backtrace string") { found = true } if consider(tokens, "/doc/api/base64-decode/", "base64_decode", "API Functions", "base64_decode\n`base64_decode` decodes Base64 text into a string.\n\nInvalid Base64 text returns an empty string.\n\nvalue : Base64 text\nthe decoded string") { found = true } @@ -44,10 +43,9 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/call/", "call", "API Functions", "call\n`call()` calls an exported function in a loaded unit. It returns the result as `dval`.\n\nUse `unit_load()` once when several calls use the same unit. The two-argument form passes an empty `dval`.\n\nhandle : a value from `unit_load()`\nname : an exported function name\ninput : optional `dval` input\nThe exported function result.") { found = true } if consider(tokens, "/doc/api/clear/", "clear", "API Functions", "Clear a dynamic value\n`clear(value)` removes all children and makes `value` an empty map.\n\nvalue : target value\nThe cleared target value.") { found = true } if consider(tokens, "/doc/api/clone/", "clone", "API Functions", "clone\n`clone()` copies a string.\n\nMost Capy code does not need an explicit copy. Use `clone()` when a fresh string value is required.\n\nvalue : a source string\nA separate string copy.") { found = true } - if consider(tokens, "/doc/api/component/", "component", "API Functions", "component\n`component()` renders a component and returns everything it printed as a string.\n\nIt collects the output into a buffer, which costs something. Reach for `component_render()` instead when you are writing the fragment straight into the current response and never look at the string — it skips the buffer entirely, so `component_render(\"card\")` does less work than `print(component(\"card\"))`.\n\nCapture the string when the string is the goal: wrapping the fragment in surrounding markup, checking whether it produced anything before emitting a container, storing it in a `dval` beside other values, or emitting the same fragment more than once from one call.\n\n## How a name resolves\n\nA name is a path with an optional `:HANDLER` suffix. Bearer appends `.capy` when the path has no suffix, so `\"card\"` and `\"card.capy\"` mean the same file.\n\nA path that starts with `/` is tried first as a real filesystem path and then as a site-root path, so `\"/tests/capy-request-context.capy\"` means that file under the site root.\n\nA relative path is tried against three directories, in order:\n\n1. the directory of the entry unit that is handling the request\n2. the directory of the unit calling `component()`, when that differs\n3. the site root\n\nThe first match wins. A resolved path that escapes the site root is rejected. Use `component_resolve()` to see which file a name reached, and `component_exists()` to test a name before rendering it.\n\n## Named handlers\n\n`\"lib/widgets.capy:CARD\"` calls the `COMPONENT:CARD` handler in that file. A name that is only `\":CARD\"` calls `COMPONENT:CARD` in the file that is currently rendering, which lets one file hold several related fragments.\n\nA file with no named handler must define a plain `COMPONENT` handler.\n\n## What the component sees\n\n`props` arrives as `request.props`. It is swapped in for the duration of the call and restored when the component returns, so a component cannot disturb its caller's props, and nested components each read their own.\n\nRelative paths inside the component resolve against the component's own file, not the caller's — a component in `lib/` can call `component(\"sibling\")` and reach `lib/sibling.capy`.\n\nThe target unit's `ONCE` handler runs before the component handler the first time that unit is used in the request.\n\nname : a component path, optionally followed by `:HANDLER`\nprops : optional input, readable inside the component as `request.props`\nThe component output as a string.\nAn unresolvable component does not raise an error. Bearer sets the response status to `500`, returns a banner element describing the failure in place of the component output, and continues rendering the rest of the page. Guard optional components with `component_exists()` when a missing file should not be an error.") { found = true } - if consider(tokens, "/doc/api/component-exists/", "component_exists", "API Functions", "component_exists\n`component_exists()` runs the same name resolution that `component()` and `component_render()` use, and reports whether it found a file. It renders nothing and runs no handler.\n\nUse it to make a component optional. Without the guard, a missing component sets the response status to `500` and writes a banner element into your page; with it, you choose the fallback.\n\n## What the check does and does not cover\n\nIt resolves the **file**. A `:HANDLER` suffix is ignored for the purpose of this check, so `component_exists(\"widgets.capy:CARD\")` answers \"does `widgets.capy` exist\", not \"does it define `COMPONENT:CARD`\". A name whose file exists but whose named handler does not will pass this check and then fail at render time.\n\nIt also does not compile the component. A file that exists but does not compile returns `true` here and reports its compile error when it is rendered.\n\nResolution is unchanged from `component()`: `.capy` is appended when absent, a leading `/` is tried as a real path and then as a site-root path, and a relative name is tried against the entry unit's directory, the calling unit's directory, and the site root, in that order.\n\nname : a component path, optionally followed by `:HANDLER`\n`true` when Bearer resolves the name to a component source file, otherwise `false`.") { found = true } + if consider(tokens, "/doc/api/component/", "component", "API Functions", "component\n`component()` renders a component and returns everything it printed as a string.\n\nIt collects the output into a buffer, which costs something. Reach for `component_render()` instead when you are writing the fragment straight into the current response and never look at the string — it skips the buffer entirely, so `component_render(\"card\")` does less work than `print(component(\"card\"))`.\n\nCapture the string when the string is the goal: wrapping the fragment in surrounding markup, checking whether it produced anything before emitting a container, storing it in a `dval` beside other values, or emitting the same fragment more than once from one call.\n\n## How a name resolves\n\nA name is a path with an optional `:HANDLER` suffix. Bearer appends `.capy` when the path has no suffix, so `\"card\"` and `\"card.capy\"` mean the same file.\n\nA path that starts with `/` is tried first as a real filesystem path and then as a site-root path, so `\"/tests/capy-request-context.capy\"` means that file under the site root.\n\nA relative path is tried against three directories, in order:\n\n1. the directory of the entry unit that is handling the request\n2. the directory of the unit calling `component()`, when that differs\n3. the site root\n\nThe first match wins. A resolved path that escapes the site root is rejected. Use `component_resolve()` to see which file a name reached. Test an optional name with `length(component_resolve(name)) > 0` before you render it.\n\n## Named handlers\n\n`\"lib/widgets.capy:CARD\"` calls the `COMPONENT:CARD` handler in that file. A name that is only `\":CARD\"` calls `COMPONENT:CARD` in the file that is currently rendering, which lets one file hold several related fragments.\n\nA file with no named handler must define a plain `COMPONENT` handler.\n\n## What the component sees\n\n`props` arrives as `request.props`. It is swapped in for the duration of the call and restored when the component returns, so a component cannot disturb its caller's props, and nested components each read their own.\n\nRelative paths inside the component resolve against the component's own file, not the caller's — a component in `lib/` can call `component(\"sibling\")` and reach `lib/sibling.capy`.\n\nThe target unit's `ONCE` handler runs before the component handler the first time that unit is used in the request.\n\nname : a component path, optionally followed by `:HANDLER`\nprops : optional input, readable inside the component as `request.props`\nThe component output as a string.\nAn unresolvable component does not raise an error. Bearer sets the response status to `500`, returns a banner element that describes the failure, and continues to render the page. Guard optional components with `length(component_resolve(name)) > 0` when a missing file should not be an error.") { found = true } if consider(tokens, "/doc/api/component-render/", "component_render", "API Functions", "component_render\n`component_render()` renders a component and writes its output straight into the current response. It returns true when it renders the component. It returns false when it cannot resolve the component.\n\nThis is the form to reach for in page layouts. `component()` opens a capture buffer, collects everything the component prints, and hands you a string; `component_render()` skips that buffer entirely. When you are only going to print the result anyway, `component_render(\"card\")` does less work than `print(component(\"card\"))`.\n\nUse a capturing call instead when you need the output as a value — to measure it, wrap it, store it, or decide whether to emit it at all.\n\nName resolution, `:HANDLER` suffixes, props scoping, and `ONCE` behaviour are identical to `component()`; that page documents the rules in full.\n\nname : a component path, optionally followed by `:HANDLER`\nprops : optional input, readable inside the component as `request.props`\nAn unresolvable component does not raise an error. Bearer sets the response status to `500`, writes a banner element describing the failure, and returns false. Rendering continues.") { found = true } - if consider(tokens, "/doc/api/component-resolve/", "component_resolve", "API Functions", "component_resolve\n`component_resolve()` answers \"which file would `component()` actually load for this name?\". It renders nothing and runs no handler.\n\nThis is the tool for debugging resolution. Because a relative name is tried against several directories in turn, the same string can mean different files depending on which unit is calling it, and the failure that follows is usually reported against the wrong place. Printing the resolved path shows you which candidate won.\n\n## The order it searches\n\n`.capy` is appended when the name has no suffix. A `:HANDLER` suffix does not affect the returned path.\n\nA name starting with `/` is tried as a real filesystem path first, then as a path under the site root.\n\nA relative name is tried against, in order:\n\n1. the directory of the entry unit handling the request\n2. the directory of the unit calling `component_resolve()`, when that differs\n3. the site root\n\nThe first candidate that exists is returned. A candidate that resolves outside the site root is rejected, and the result is an empty string.\n\nAn empty return means the same thing as `component_exists()` returning `false` — the two functions run the same lookup and differ only in what they report.\n\nname : a component path, optionally followed by `:HANDLER`\nThe absolute source path the name resolves to, or an empty string when nothing matches.") { found = true } + if consider(tokens, "/doc/api/component-resolve/", "component_resolve", "API Functions", "component_resolve\n`component_resolve()` answers \"which file would `component()` actually load for this name?\". It renders nothing and runs no handler.\n\nThis is the tool for debugging resolution. Because a relative name is tried against several directories in turn, the same string can mean different files depending on which unit is calling it, and the failure that follows is usually reported against the wrong place. Printing the resolved path shows you which candidate won.\n\n## The order it searches\n\n`.capy` is appended when the name has no suffix. A `:HANDLER` suffix does not affect the returned path.\n\nA name starting with `/` is tried as a real filesystem path first, then as a path under the site root.\n\nA relative name is tried against, in order:\n\n1. the directory of the entry unit handling the request\n2. the directory of the unit calling `component_resolve()`, when that differs\n3. the site root\n\nThe first candidate that exists is returned. A candidate that resolves outside the site root is rejected, and the result is an empty string.\n\nAn empty return means that no component source file matches the name.\n\n## Check whether a component exists\n\nWarning: `if component_resolve(...)` is always false. Conditions parse strings as boolean words, so a resolved filesystem path is false.\n\nUse this exact test:\n\n if length(component_resolve(name)) > 0 { ... }\n\nname : a component path, optionally followed by `:HANDLER`\nThe absolute source path the name resolves to, or an empty string when nothing matches.") { found = true } if consider(tokens, "/doc/api/contains/", "contains", "API Functions", "contains\n`contains()` checks for a substring.\n\nhaystack : the string to search\nneedle : the substring to find\n`true` if `needle` occurs in `haystack`. An empty `needle` matches.") { found = true } if consider(tokens, "/doc/api/crypto-equal/", "crypto_equal", "API Functions", "crypto_equal\n`crypto_equal()` compares byte strings in constant time.\n\nUse it to compare secrets such as HMACs and tokens. Do not use `==` to compare secrets.\n\nleft : the expected byte string\nright : the submitted byte string\n`true` if both byte strings are equal.") { found = true } if consider(tokens, "/doc/api/csrf-field/", "csrf_field", "API Functions", "csrf_field\n`csrf_field()` returns a hidden form input with the active CSRF token.\n\nUse it in a form that changes state. Check the submitted value with `csrf_valid()` before you change state.\n\nsession_name : the session and cookie name\ntoken_name : the token namespace\nfield_name : the form field name. The default is `token_name`.\nAn HTML hidden input with the active CSRF token.") { found = true } @@ -98,7 +96,7 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/gen-noise01/", "gen_noise01", "API Functions", "gen_noise01\n`gen_noise01()` returns normalized noise for an index and seed.\n\nUse the same inputs to reproduce a value.\n\nindex : deterministic input position\nseed : deterministic input seed\nA deterministic `f64` value from `0` to `1`.") { found = true } if consider(tokens, "/doc/api/gen-noise32/", "gen_noise32", "API Functions", "gen_noise32\n`gen_noise32()` returns deterministic integer noise for an index and seed.\n\nUse the same inputs to reproduce a value.\n\nindex : deterministic input position\nseed : deterministic input seed\nA deterministic `u64` value.") { found = true } if consider(tokens, "/doc/api/gen-noise64/", "gen_noise64", "API Functions", "gen_noise64\n`gen_noise64()` returns deterministic integer noise for an index and seed.\n\nUse the same inputs to reproduce a value.\n\nindex : deterministic input position\nseed : deterministic input seed\nA deterministic `u64` value.") { found = true } - if consider(tokens, "/doc/api/gen-sha1/", "gen_sha1", "API Functions", "gen_sha1\n`gen_sha1()` returns the SHA-1 digest of a string.\n\nIt returns hexadecimal text by default. Set `as_binary` to `true` for raw digest bytes.\n\nUse it only for SHA-1 compatibility.\n\nvalue : bytes to hash\nas_binary : `false` for hexadecimal text, `true` for raw digest bytes\nA SHA-1 digest string.") { found = true } + if consider(tokens, "/doc/api/gen-sha1/", "gen_sha1", "API Functions", "gen_sha1\n`gen_sha1()` returns 20 raw SHA-1 bytes. Use `hex(gen_sha1(value))` when you need lowercase hexadecimal text.\n\nUse it only for SHA-1 compatibility.\n\nvalue : bytes to hash\nRaw 20-byte SHA-1 digest.") { found = true } if consider(tokens, "/doc/api/get/", "get", "API Functions", "Get a named child\n`get(value, key)` reads a named child without creating it. It returns `none` for a missing key or a scalar.\n\nvalue : source value\nkey : child key\nThe copied child, or `none`.") { found = true } if consider(tokens, "/doc/api/get-by-path/", "get_by_path", "API Functions", "Get a child by path\n`get_by_path(value, path)` reads a nested child without creating nodes. Use a slash between path segments.\n\nvalue : source value\npath : slash-separated child path\nThe copied child, or an empty string value when the path fails.") { found = true } if consider(tokens, "/doc/api/get-or-create/", "get_or_create", "API Functions", "Get or create a child\n`get_or_create(value, key, default)` stores `default` when `key` is missing. It changes and returns `value`.\n\nvalue : target value\nkey : child key\ndefault : value to store when the child is missing\nThe target value.") { found = true } @@ -106,8 +104,8 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/gz-compress/", "gz_compress", "API Functions", "gz_compress\n`gz_compress()` compresses a string with gzip.\n\nThe result contains binary data. Pass it to `gz_uncompress()` to restore the source.\n\nsource : uncompressed bytes\nGzip-compressed bytes as a string.") { found = true } if consider(tokens, "/doc/api/gz-uncompress/", "gz_uncompress", "API Functions", "gz_uncompress\n`gz_uncompress()` uncompresses gzip data from a string.\n\nUse it with data from `gz_compress()`.\n\nsource : gzip-compressed bytes\nUncompressed bytes as a string.") { found = true } if consider(tokens, "/doc/api/has/", "has", "API Functions", "Test for a child\n`has(value, key)` tests for a child without creating it. It returns `false` for a missing key or a scalar.\n\nvalue : value to test\nkey : child key\n`true` when the key exists.") { found = true } - if consider(tokens, "/doc/api/hmac-sha256/", "hmac_sha256", "API Functions", "hmac_sha256\n`hmac_sha256()` returns a raw binary HMAC-SHA256 value. Use `hmac_sha256_hex()` when you need hexadecimal text.\n\nkey : secret key bytes\nvalue : message bytes\nA raw 32-byte HMAC-SHA256 value.") { found = true } - if consider(tokens, "/doc/api/hmac-sha256-hex/", "hmac_sha256_hex", "API Functions", "hmac_sha256_hex\n`hmac_sha256_hex()` returns an HMAC-SHA256 value as hexadecimal text. Use `crypto_equal()` to compare received signatures.\n\nkey : secret key bytes\nvalue : message bytes\nA 64-character lowercase hexadecimal HMAC-SHA256 value.") { found = true } + if consider(tokens, "/doc/api/hex/", "hex", "API Functions", "hex\n`hex()` converts each input byte to two lowercase hexadecimal characters.\n\nUse it to make digest bytes printable. For example, `hex(sha256(value))` returns a SHA-256 digest as lowercase hexadecimal text.\n\nvalue : bytes to encode\nLowercase hexadecimal text.") { found = true } + if consider(tokens, "/doc/api/hmac-sha256/", "hmac_sha256", "API Functions", "hmac_sha256\n`hmac_sha256()` returns 32 raw HMAC-SHA256 bytes. Use `hex(hmac_sha256(key, value))` when you need lowercase hexadecimal text.\n\nkey : secret key bytes\nvalue : message bytes\nA raw 32-byte HMAC-SHA256 value.") { found = true } if consider(tokens, "/doc/api/html-escape/", "html_escape", "API Functions", "html_escape\n`html_escape()` escapes text for an HTML text position. It escapes ampersands, angle brackets, and double quotes.\n\nvalue : text to use in HTML\nText with HTML-sensitive characters replaced by entities.") { found = true } if consider(tokens, "/doc/api/http-request/", "http_request", "API Functions", "http_request\n`http_request()` sends an outbound HTTP or HTTPS request. Set `method`, `url`, `headers`, `body`, `timeout_ms`, and `follow_redirects` as needed.\n\nWhen you set a `security` field, set `https_only`, `public_dns_only`, `pin_dns`, `isolated_curl`, and `no_redirects` to `true`.\n\nrequest : a map that describes an outbound request\nA map with `status`, `headers`, `body`, and `error`.\nThe result can report `invalid_request`, `unsafe_dns`, `timeout`, `response_too_large`, `redirect_not_allowed`, `http_status`, or `network_failure`.") { found = true } if consider(tokens, "/doc/api/http-request-async/", "http_request_async", "API Functions", "http_request_async\n`http_request_async()` starts an outbound request and returns its job ID. Use `job_await()` or `job_result()` to get the response map.\n\nThe request map follows the `http_request()` rules.\n\nrequest : a map that describes an outbound request\nA job ID.") { found = true } @@ -116,7 +114,7 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/is-list/", "is_list", "API Functions", "Test for a list\n`is_list(value)` tests whether a value is a list.\n\nvalue : value to test\n`true` for a list-shaped value.") { found = true } if consider(tokens, "/doc/api/job-await/", "job_await", "API Functions", "job_await\n`job_await()` waits for a job until the timeout expires. It returns the current status when the timeout expires.\n\njob : a job ID as `dval`\ntimeout_ms : maximum wait time in milliseconds\nA job status map. A completed job includes `result`.") { found = true } if consider(tokens, "/doc/api/job-cancel/", "job_cancel", "API Functions", "job_cancel\n`job_cancel()` requests cancellation of a job. A canceled job reports the `cancelled` state.\n\njob : a job ID as `dval`\n`true` when the system cancels an active job. Otherwise, `false`.") { found = true } - if consider(tokens, "/doc/api/job-result/", "job_result", "API Functions", "job_result\n`job_result()` checks a job with a short bounded wait. Use it to poll a job after `shell_spawn()` or `http_request_async()`.\n\njob : a job ID as `dval`\nA job status map. A completed job includes `result`.") { found = true } + if consider(tokens, "/doc/api/job-result/", "job_result", "API Functions", "job_result\n`job_result()` checks a job with a short bounded wait. Use it to poll a job after `shell_exec(command, flags)` or `http_request_async()`.\n\njob : a job ID as `dval`\nA job status map. A completed job includes `result`.") { found = true } if consider(tokens, "/doc/api/job-status/", "job_status", "API Functions", "job_status\n`job_status()` checks a job without waiting. The map can include `state`, `done`, `kind`, `pid`, and `job_id`.\n\nThe `state` value can be `pending`, `running`, `done`, `failed`, `cancelled`, or `missing`.\n\njob : a job ID as `dval`\nA job status map.") { found = true } if consider(tokens, "/doc/api/join/", "join", "API Functions", "join\n`join()` reads each list value as text. It uses a newline when you omit the delimiter.\n\nitems : a `dval` list\ndelimiter : text between values\nOne string with the values separated by `delimiter`.") { found = true } if consider(tokens, "/doc/api/json-consume-space/", "json_consume_space", "API Functions", "json_consume_space\n`json_consume_space()` skips JSON whitespace from `index`. Use `json_decode()` for normal JSON parsing.\n\nsource : JSON source text\nindex : byte offset where the scan starts\nThe byte offset after JSON whitespace.") { found = true } @@ -129,13 +127,12 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/map/", "map", "API Functions", "map\n`map()` calls `mapper` for each item in `items`.\n\nIt converts each item to a string before it calls `mapper`. The function returns a new `dval` list.\n\nitems : the input list\nmapper : the function that transforms each item\na new list of transformed strings") { found = true } if consider(tokens, "/doc/api/markdown-to-ast/", "markdown_to_ast", "API Functions", "markdown_to_ast\n`markdown_to_ast()` parses Markdown into a `dval` document tree.\n\nThe root node contains a `children` list. Nodes contain a `type` field and fields for their content. The default options support GitHub-flavored Markdown.\n\nSet `gfm` to control GitHub-flavored extensions. Set `allow_html` to retain raw HTML nodes.\n\nsource : the Markdown source text\noptions : parser options\nthe Markdown document tree") { found = true } if consider(tokens, "/doc/api/markdown-to-html/", "markdown_to_html", "API Functions", "markdown_to_html\n`markdown_to_html()` renders Markdown source as HTML.\n\nRaw HTML stays escaped unless `options[\"allow_html\"]` is true. Only enable it for trusted source.\n\nsource : the Markdown source text\noptions : render options\nthe HTML text") { found = true } - if consider(tokens, "/doc/api/memcache-command/", "memcache_command", "API Functions", "memcache_command\n`memcache_command()` sends `command` to the server and returns one bounded response read.\n\nUse a dedicated Memcache function when one is available. This function does not guarantee a complete multi-part response.\n\nconnection : the connection handle\ncommand : the Memcache command text\none server response read") { found = true } - if consider(tokens, "/doc/api/memcache-connect/", "memcache_connect", "API Functions", "memcache_connect\n`memcache_connect()` opens a connection to a Memcache server.\n\nDo not pass a zero handle to another Memcache function.\n\nhost : the server host name\nport : the server port\na connection handle, or zero on failure") { found = true } - if consider(tokens, "/doc/api/memcache-delete/", "memcache_delete", "API Functions", "memcache_delete\n`memcache_delete()` deletes the entry for `key`.\n\nIt returns `true` only when the server returns `DELETED`.\n\nconnection : the connection handle\nkey : the entry key\n`true` when the server deletes the entry") { found = true } - if consider(tokens, "/doc/api/memcache-escape-key/", "memcache_escape_key", "API Functions", "memcache_escape_key\n`memcache_escape_key()` replaces whitespace characters in a key with underscores.\n\nIt does not validate every Memcache protocol byte.\n\nThe dedicated Memcache operations escape keys before they send requests.\n\nkey : the key text\nthe key with whitespace replaced by underscores") { found = true } - if consider(tokens, "/doc/api/memcache-get/", "memcache_get", "API Functions", "memcache_get\n`memcache_get()` reads the value for `key`.\n\nIt returns `default_value` for a missing key or an incomplete response. It escapes the key before it sends the request.\n\nconnection : the connection handle\nkey : the entry key\ndefault_value : the value for a missing or invalid response\nthe stored value or `default_value`") { found = true } - if consider(tokens, "/doc/api/memcache-get-multiple/", "memcache_get_multiple", "API Functions", "memcache_get_multiple\n`memcache_get_multiple()` reads several keys through one connection.\n\nMissing keys do not occur in the returned map. It escapes each key before it sends the request.\n\nconnection : the connection handle\nkeys : the entry keys\na map of returned entries") { found = true } - if consider(tokens, "/doc/api/memcache-set/", "memcache_set", "API Functions", "memcache_set\n`memcache_set()` stores `value` under `key`.\n\nIt returns `true` only when the server returns `STORED`. It escapes the key before it sends the request.\n\nconnection : the connection handle\nkey : the entry key\nvalue : the value text\nexpires_in : the lifetime in seconds\n`true` when the server stores the entry") { found = true } + if consider(tokens, "/doc/api/memcache-command/", "memcache_command", "API Functions", "memcache_command\n`memcache_command()` sends `command` to the server and returns one bounded response read.\n\nUse a dedicated Memcache function when one is available. This function does not guarantee a complete multi-part response.\n\nFor `get` and `gets`, each protocol key token starts at token 1. For `gat` and `gats`, the protocol key token is token 2. For storage and single-key commands, the protocol key token is token 1.\n\nThe function normalizes whitespace in these protocol key tokens to underscores. It does not normalize command names, expiration tokens, metadata tokens, or payload text.\n\nconnection : the connection handle\ncommand : the Memcache command text\none server response read") { found = true } + if consider(tokens, "/doc/api/memcache-connect/", "memcache_connect", "API Functions", "memcache_connect\n`memcache_connect()` opens a connection to a Memcache server.\n\nDo not pass a zero handle to another Memcache function.\n\nThe key operations normalize whitespace to underscores. This normalization is transparent. The keys `\"a b\"` and `\"a_b\"` address the same entry.\n\nhost : the server host name\nport : the server port\na connection handle, or zero on failure") { found = true } + if consider(tokens, "/doc/api/memcache-delete/", "memcache_delete", "API Functions", "memcache_delete\n`memcache_delete()` deletes the entry for `key`.\n\nIt returns `true` only when the server returns `DELETED`. It normalizes whitespace in keys to underscores before it sends the request.\n\nThis normalization is transparent. The keys `\"a b\"` and `\"a_b\"` address the same entry.\n\nconnection : the connection handle\nkey : the entry key\n`true` when the server deletes the entry") { found = true } + if consider(tokens, "/doc/api/memcache-get/", "memcache_get", "API Functions", "memcache_get\n`memcache_get()` reads the value for `key`.\n\nIt returns `default_value` for a missing key or an incomplete response. It normalizes whitespace in keys to underscores before it sends the request.\n\nThis normalization is transparent. The keys `\"a b\"` and `\"a_b\"` address the same entry.\n\nconnection : the connection handle\nkey : the entry key\ndefault_value : the value for a missing or invalid response\nthe stored value or `default_value`") { found = true } + if consider(tokens, "/doc/api/memcache-get-multiple/", "memcache_get_multiple", "API Functions", "memcache_get_multiple\n`memcache_get_multiple()` reads several keys through one connection.\n\nMissing keys do not occur in the returned map. It normalizes whitespace in each key to underscores before it sends the request.\n\nThis normalization is transparent. The keys `\"a b\"` and `\"a_b\"` address the same entry.\n\nconnection : the connection handle\nkeys : the entry keys\na map of returned entries") { found = true } + if consider(tokens, "/doc/api/memcache-set/", "memcache_set", "API Functions", "memcache_set\n`memcache_set()` stores `value` under `key`.\n\nIt returns `true` only when the server returns `STORED`. It normalizes whitespace in keys to underscores before it sends the request.\n\nThis normalization is transparent. The keys `\"a b\"` and `\"a_b\"` address the same entry.\n\nconnection : the connection handle\nkey : the entry key\nvalue : the value text\nexpires_in : the lifetime in seconds\n`true` when the server stores the entry") { found = true } if consider(tokens, "/doc/api/mkdir/", "mkdir", "API Functions", "mkdir\n`mkdir()` creates one directory at `path`.\n\nThe parent directory must exist. This function does not create parent directories.\n\npath : the directory path\n`true` when the API creates the directory") { found = true } if consider(tokens, "/doc/api/mysql-connect/", "mysql_connect", "API Functions", "mysql_connect\n`mysql_connect()` creates a MySQL connection lease and returns its handle.\n\nUse `mysql_info(database, \"connection\")` before database work. Call `mysql_disconnect()` after use. A failed connection can return a nonzero handle.\n\nhost : the MySQL server host\nusername : the MySQL user name\npassword : the MySQL password\ndatabase : the initial database name\na request-local MySQL connection handle") { found = true } if consider(tokens, "/doc/api/mysql-disconnect/", "mysql_disconnect", "API Functions", "mysql_disconnect\n`mysql_disconnect()` releases the MySQL connection lease.\n\nDo not use the handle after this call.\n\nhandle : the MySQL connection handle") { found = true } @@ -149,8 +146,7 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/ob-start/", "ob_start", "API Functions", "Start an output buffer\n`ob_start()` starts an output buffer for the active request.\n\nOutput after this call goes to the buffer. Use `ob_get`, `ob_get_close`, or `ob_close` to read or close it.\n\nThis function returns no value.") { found = true } if consider(tokens, "/doc/api/parse-query/", "parse_query", "API Functions", "parse_query\n`parse_query()` decodes URL query text into a map-shaped `dval`.\n\nAn ampersand separates pairs. The first equals sign separates a key and value. A key without an equals sign has an empty value. The last repeated key wins.\n\nquery : the URL query text\nthe decoded parameters") { found = true } if consider(tokens, "/doc/api/parse-uri/", "parse_uri", "API Functions", "parse_uri\n`parse_uri()` returns URI parts as a `dval`.\n\nRead the `parts` and `query` maps from the result. Use `parse_query()` when you only have query text.\n\nuri : the URI or URL text\nthe URI data") { found = true } - if consider(tokens, "/doc/api/password-hash/", "password_hash", "API Functions", "password_hash\n`password_hash()` creates a password encoding with a random salt and current scrypt parameters.\n\nStore the returned value exactly. Do not store an empty result.\n\npassword : the password to hash\na self-contained password encoding, or an empty string on failure") { found = true } - if consider(tokens, "/doc/api/password-needs-rehash/", "password_needs_rehash", "API Functions", "password_needs_rehash\n`password_needs_rehash()` returns `true` for malformed encodings and older Bearer password parameters.\n\nCall it after `password_verify()` succeeds. Hash the known password again and replace the stored encoding.\n\nencoded : the stored password encoding\n`true` when the encoding needs replacement") { found = true } + if consider(tokens, "/doc/api/password-hash/", "password_hash", "API Functions", "password_hash\n`password_hash()` creates a password encoding with a random salt and current scrypt parameters.\n\nStore the returned value exactly. Do not store an empty result.\n\nThe encoding includes its scrypt parameters. Its current parameter prefix is `$bearer$scrypt$65536$8$1$`. After a successful verification, compare the prefix with the parameters you require. Rehash the known password when the prefixes differ.\n\npassword : the password to hash\na self-contained password encoding, or an empty string on failure") { found = true } if consider(tokens, "/doc/api/password-verify/", "password_verify", "API Functions", "password_verify\n`password_verify()` tests a password against a stored encoding.\n\nIt rejects malformed encodings and parameters above the Bearer limits. Set password length and sign-in rate limits in public handlers.\n\npassword : the candidate password\nencoded : the stored password encoding\n`true` when the password matches a valid encoding") { found = true } if consider(tokens, "/doc/api/path-is-within/", "path_is_within", "API Functions", "path_is_within\n`path_is_within()` resolves both paths and tests whether `root` contains `path`.\n\nBoth paths must exist. Resolution follows symbolic links and removes dot segments.\n\npath : the path to test\nroot : the containing directory\n`true` when `root` contains `path`") { found = true } if consider(tokens, "/doc/api/path-join/", "path_join", "API Functions", "path_join\n`path_join()` joins `base` and `child` with one slash when needed.\n\nAn absolute `child` replaces `base`. This function does not resolve dot segments.\n\nbase : the base path\nchild : the path to append\nthe joined path") { found = true } @@ -185,11 +181,9 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/api/session-set/", "session_set", "API Functions", "session_set\nCall `session_start()` before you store a session field.\n\nkey : session field name\nvalue : value to store\nThe updated session state.") { found = true } if consider(tokens, "/doc/api/session-start/", "session_start", "API Functions", "session_start\n`session_start()` restores the named session or creates one.\n\nname : session cookie name\nThe current session state.") { found = true } if consider(tokens, "/doc/api/set/", "set", "API Functions", "Set a named child\n`set(dest, key, value)` stores `value` at `key`. It changes and returns `dest`.\n\ndest : target value\nkey : child key\nvalue : value to store\nThe changed target value.") { found = true } - if consider(tokens, "/doc/api/sha256/", "sha256", "API Functions", "sha256\nUse `sha256` to create a raw SHA-256 digest. Use `sha256_hex` when you need hexadecimal text.\n\nRaw 32-byte SHA-256 digest.") { found = true } - if consider(tokens, "/doc/api/sha256-hex/", "sha256_hex", "API Functions", "sha256_hex\nUse `sha256_hex` to create a printable SHA-256 digest.\n\nLowercase hexadecimal SHA-256 digest.") { found = true } + if consider(tokens, "/doc/api/sha256/", "sha256", "API Functions", "sha256\n`sha256()` returns 32 raw SHA-256 bytes. Use `hex(sha256(value))` when you need lowercase hexadecimal text.\n\nRaw 32-byte SHA-256 digest.") { found = true } if consider(tokens, "/doc/api/shell-escape/", "shell_escape", "API Functions", "shell_escape\nUse `shell_escape` for one value in a shell command. Do not use it for shell syntax or a complete command.\n\nA shell-escaped word.") { found = true } - if consider(tokens, "/doc/api/shell-exec/", "shell_exec", "API Functions", "shell_exec\nUse `shell_exec` to run a shell command and get its output. Escape external values with `shell_escape` before you add them to the command.\n\nCommand output.") { found = true } - if consider(tokens, "/doc/api/shell-spawn/", "shell_spawn", "API Functions", "shell_spawn\nUse `shell_spawn` to start a background shell job. The `cmd` value is a shell command.\n\nJob identifier value.") { found = true } + if consider(tokens, "/doc/api/shell-exec/", "shell_exec", "API Functions", "shell_exec\nUse the one-argument form to run a shell command and get its output. Escape external values with `shell_escape` before you add them to the command.\n\nUse the two-argument form with `background: true` to start a background job. Use `background: false`, or omit it, to wait for the command. The synchronous result map has `exit_code`, `stdout`, `stderr`, `timed_out`, and `output_truncated`.\n\nThe valid flag keys are `stdin`, `env`, `timeout_ms`, and `background`. `stdin` must be a string. `env` must be a non-list map with string values. `timeout_ms` must be a positive number. `background` must be a bool. An unrecognized key causes a hard error that lists all valid keys.\n\nUse `job_status`, `job_result`, `job_await`, and `job_cancel` with a background job identifier. Validate the final state before you read result data.\n\nThe shell interprets `command`. Do not build it from request data or other untrusted input.\n\ncommand : the shell command\nflags : execution options\nThe one-argument form returns command output. With `background: true`, the two-argument form returns a job identifier. With `background: false` or no `background` key, it returns an execution result map.") { found = true } if consider(tokens, "/doc/api/socket-close/", "socket_close", "API Functions", "socket_close\nUse `socket_close` after socket work. Do not use the handle after this call.\n") { found = true } if consider(tokens, "/doc/api/socket-connect/", "socket_connect", "API Functions", "socket_connect\nUse `socket_connect` to open a socket to an IPv4 address and port. Pass a nonzero handle to the socket functions.\n\nSocket handle, or zero when the connection fails.") { found = true } if consider(tokens, "/doc/api/socket-read/", "socket_read", "API Functions", "socket_read\nUse `socket_read` to read data from a socket. It can return an empty string when no data is available.\n\nData read from the socket.") { found = true } @@ -255,7 +249,7 @@ function COMPONENT(request : dval) { print("
") print("

Handlers

") if consider(tokens, "/doc/handler/cli/", "cli", "Handlers", "CLI\n`CLI` defines the local command entrypoint.\n\nThe handler has one parameter named `request` with type `dval`. Read command data from the request snapshot. Use `print` to write command output.\n") { found = true } - if consider(tokens, "/doc/handler/component/", "component", "Handlers", "COMPONENT\n`COMPONENT` marks a function as a renderable fragment. Another unit reaches it with `component()` or `component_render()`; it is never routed to directly by a URL.\n\nThe handler takes one parameter, `request`, of type `dval`, and returns nothing. Everything it `print`s becomes the fragment's output.\n\n## Plain and named handlers\n\nA file with a single fragment defines `COMPONENT`. Callers name just the file:\n\n component_render(\"lib/card.capy\")\n\nA file that holds several related fragments gives each one a name, and callers select it with a `:` suffix:\n\n component_render(\"lib/widgets.capy:CARD\")\n\nA caller inside that same file can use the bare suffix form, `component_render(\":CARD\")`, which resolves to the current file.\n\nNames are matched exactly and are conventionally uppercase.\n\n## Reading input\n\nCaller-supplied props arrive as `request.props`. Read them through `string()`, `s64()`, and the other converters so a missing key has a defined value:\n\n var title := string(request.props.title, \"Untitled\")\n\n`request.props` is swapped in for the duration of the call and restored when the handler returns, so a component never disturbs its caller's props, and nested components each read their own. The rest of `request` — query, form, headers, session — is the live request and is shared with the caller.\n\n## Lifecycle\n\nThe first time a unit is used in a request, its `ONCE` handler runs before the component handler. A component may render other components; each nested call resolves relative paths against its own file.\n\nA caller that names a component Bearer cannot resolve gets a `500` status and a banner element in place of the fragment; the handler in this file never runs. Callers that treat a fragment as optional should guard with `component_exists()`.") { found = true } + if consider(tokens, "/doc/handler/component/", "component", "Handlers", "COMPONENT\n`COMPONENT` marks a function as a renderable fragment. Another unit reaches it with `component()` or `component_render()`; it is never routed to directly by a URL.\n\nThe handler takes one parameter, `request`, of type `dval`, and returns nothing. Everything it `print`s becomes the fragment's output.\n\n## Plain and named handlers\n\nA file with a single fragment defines `COMPONENT`. Callers name just the file:\n\n component_render(\"lib/card.capy\")\n\nA file that holds several related fragments gives each one a name, and callers select it with a `:` suffix:\n\n component_render(\"lib/widgets.capy:CARD\")\n\nA caller inside that same file can use the bare suffix form, `component_render(\":CARD\")`, which resolves to the current file.\n\nNames are matched exactly and are conventionally uppercase.\n\n## Reading input\n\nCaller-supplied props arrive as `request.props`. Read them through `string()`, `s64()`, and the other converters so a missing key has a defined value:\n\n var title := string(request.props.title, \"Untitled\")\n\n`request.props` is swapped in for the duration of the call and restored when the handler returns, so a component never disturbs its caller's props, and nested components each read their own. The rest of `request` — query, form, headers, session — is the live request and is shared with the caller.\n\n## Lifecycle\n\nThe first time a unit is used in a request, its `ONCE` handler runs before the component handler. A component may render other components; each nested call resolves relative paths against its own file.\n\nA caller that names a component Bearer cannot resolve gets a `500` status and a banner element in place of the fragment. The handler in this file never runs. Callers that treat a fragment as optional should guard with `length(component_resolve(name)) > 0`.") { found = true } if consider(tokens, "/doc/handler/init/", "init", "Handlers", "INIT\n`INIT` defines the unit materialization hook.\n\nBearer runs this hook before dispatch in a request workspace. The handler has one parameter named `request` with type `dval`.\n") { found = true } if consider(tokens, "/doc/handler/once/", "once", "Handlers", "ONCE\n`ONCE` defines the request-local unit hook.\n\nBearer runs this hook before the first unit entry or component call. The handler has one parameter named `request` with type `dval`.\n") { found = true } if consider(tokens, "/doc/handler/render/", "render", "Handlers", "RENDER\n`RENDER` is the HTTP entrypoint of a unit. When a request routes to a `.capy` file, Bearer calls that file's `RENDER` handler.\n\nThe handler takes one parameter, `request`, of type `dval`, and returns nothing. Everything it `print`s becomes the response body.\n\n## A minimal page\n\n function RENDER(request : dval) {\n print(\"

Hello

\")\n }\n\nRead input from the request snapshot with a converter and a fallback, so a missing parameter has a defined value:\n\n var name := string(request.query.name, \"guest\")\n\n## Response control\n\n`print()` writes the body. Set status, headers, and cookies in `request.out`:\n\n request.out.status = 404\n request.out.headers[\"Cache-Control\"] = \"no-store\"\n request.out.cookies[\"visited\"] = \"1\"\n\n`redirect()` sets the status and `Location` header together. A handler may `return` early at any point; whatever it printed so far is still sent.\n\n## Named handlers\n\n`RENDER:NAME` declares an additional named entrypoint in the same file, selected by the caller rather than by the URL path. A file's unnamed `RENDER` remains the one that plain routing reaches.\n\n## What runs around it\n\nThe unit's `ONCE` handler runs before `RENDER` the first time the unit is used in a request. Fragments are pulled in with `component_render()` or `component()`; another unit's exported functions are reached with `unit_load()` or `unit_call()`.\n\nEvery Capy unit must export at least one handler — `RENDER`, `CLI`, `COMPONENT`, `WS`, `ONCE`, or `INIT` — or metadata via `#exports`. A file with none fails to compile.\n") { found = true } @@ -275,7 +269,7 @@ function COMPONENT(request : dval) { if consider(tokens, "/doc/guide/dynamic-values/", "8. Dynamic values", "Learn Capy", "8. Dynamic values\nA `dval` holds data whose shape is known only at run time. JSON, YAML, request data, task props, and unit calls use `dval` values.\n\n## Read decoded data\n\n```capy\nfunction RENDER(request : dval) {\n var profile := json_decode(\"{\\\"name\\\":\\\"Ada\\\"}\")\n print(profile.name, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nAda\n\n```\n\n`json_decode` returns a `dval`. Member syntax reads a map key. Bracket syntax also works:\n\n```capy\nfunction RENDER(request : dval) {\n var profile := {name: \"Ada\"}\n print(profile[\"name\"], \"\\n\")\n}\n\n```\n\n\nUse brackets for a dynamic key, a key that is not an identifier, or a list index.\n\n## Missing data\n\nA missing read returns `none` instead of changing the map or trapping:\n\n```capy\nfunction RENDER(request : dval) {\n var profile := {name: \"Ada\"}\n var nickname := profile.nickname\n if nickname? {\n print(nickname)\n } else {\n print(\"guest\")\n }\n}\n\n```\n\n\n`value?` is false only when the `dval` is `none`. An empty string, `false`, an empty map, and an empty list are present values.\n\nA key can exist and contain `none`. Use `has(profile, \"nickname\")` when that distinction matters.\n\n## Convert a scalar\n\nScalar constructors convert a `dval` to a static Capy type:\n\n```capy\nfunction RENDER(request : dval) {\n var profile := {name: \"Ada\"}\n var name := string(profile.name)\n var visits := s32(profile.visits, 0)\n print(name, \" \", visits, \"\\n\")\n}\n\n```\n\n\nThe second argument is a fallback. Capy uses it when the value is `none` or cannot convert to the requested type.\n\nUse `has(profile, \"name\")` before `get(profile, \"name\")` when a missing value is an error.\n\n## Create dynamic data\n\nA map literal creates a `dval` map:\n\n```capy\nfunction RENDER(request : dval) {\n var user := {name: \"Ada\", active: true}\n var empty := {:}\n print(user.name, \" \", empty?, \"\\n\")\n}\n\n```\n\n\nA bare list is a typed array. Wrap it with `dval` when it must be a dynamic list. `length(value)` returns the number of entries in a `dval` map or list. It traps if the `dval` is a scalar:\n\n```capy\nfunction RENDER(request : dval) {\n var tags := dval([\"math\", \"logic\"])\n print(tags[0], \"\\n\")\n}\n\n```\n\n\n## Mutate a dval\n\nA `dval` is a mutable reference value inside one workspace. Assignment, parameters, returns, and captures share its identity:\n\n```capy\nfunction set_email(profile : dval) {\n profile.contact.email = \"ada@example.test\"\n}\n\nfunction RENDER(request : dval) {\n var profile := {:}\n var alias := profile\n set_email(alias)\n print(profile.contact.email, \"\\n\")\n}\n\n```\n\n\nContent mutation through the parameter affects the caller. The parameter binding remains immutable, so `profile = {:}` is invalid.\n\nNested assignment mutates its target and returns the same identity. The root must be a named local, parameter, or captured `dval` binding. Temporary, call, member, array-item, and loop-item roots are invalid. Nested assignment creates missing maps. An existing list accepts only an in-range nonnegative index. Capy does not create sparse lists.\n\nThe `set`, `push`, `pop`, `delete`, `clear`, and `get_or_create` functions mutate their target. Each function returns that same identity. Reassignment remains valid:\n\n```capy\nfunction RENDER(request : dval) {\n var profile := {:}\n profile = set(profile, \"active\", true)\n print(profile.active, \"\\n\")\n}\n\n```\n\n\nMember and index reads return copied child values. Pure transformations return copies when their API specifies a copy.\n\n## Iterate a dval\n\nUse the value-first loop forms:\n\n```capy\nfunction show(values : dval) {\n for item := values { print(item, \"\\n\") }\n for item, key := values { print(key, \": \", item, \"\\n\") }\n}\n\nfunction RENDER(request : dval) {\n show({name: \"Ada\"})\n}\n\n```\n\n\nThe key has type `string`. `dval` list keys are decimal strings. Each item is a copied `dval`. The loop uses a live view and rechecks the current count. A loop that keeps growing its iterable can continue.\n\n## Boundaries\n\nA `dval` keeps identity only inside one workspace. Bearer, module, component, task, custom export, codec, request, and serialization boundaries copy BRRB. Identity never crosses a boundary. A `dval` can hold a named function or closure only in its current workspace. A typed read requires the exact function signature. A mismatch traps. Public BRRB, JSON, YAML, and XML replace callable entries with `none`. Maps keep keys. Lists keep indexes. JSON and YAML preserve `none` as `null`. XML writes `none` as empty text and cannot recover the distinction.\n") { found = true } if consider(tokens, "/doc/guide/web-handlers-and-requests/", "9. Handling a web request", "Learn Capy", "9. Handling a web request\nA Capy Bearer handler receives one copied request snapshot. Declare every handler with `request : dval`.\n\n## Read the request snapshot\n\n```capy\nfunction RENDER(request : dval) {\n var name := string(request.query.name, \"guest\")\n request.out.headers[\"Content-Type\"] = \"text/plain; charset=utf-8\"\n print(\"Hello, \", name, \"!\\n\")\n}\n\n```\n\n**Output**\n\n```text\nHello, guest!\n\n```\n\nThe snapshot contains `method`, `query`, `form`, `params`, `headers`, `cookies`, `body`, `files`, `route`, `url`, `server`, `session`, `props`, `config`, `call`, `connection`, `unit`, `websocket`, and `out`.\n\n`route` contains `path`, `page`, `raw_path`, and `valid`. `url` contains `script` and `base`. `session` contains `id`, `name`, and `values`. `websocket` contains `connection_id`, `scope`, `opcode`, `binary`, and current-scope `connections`.\n\nMissing members are `none`. Use normal conversions for scalar values. For example, use `string(request.form.email, \"\")`, `s32(request.websocket.opcode, 0)`, and `bool(request.websocket.binary, false)`.\n\n## Form a response\n\nUse `print`, `request.out.status`, `request.out.headers`, `request.out.cookies`, and `redirect` to change the response. Use a redirect after a successful state change so the user can refresh the page safely.\n\nUse `ws_send`, `ws_send_to`, and `ws_close` for WebSocket effects. Use `request.websocket.connections` to select current-scope clients.\n\n## Handle a form\n\nA handler normally uses one route for both the form and the POST result. Read `request.method` first. Read submitted fields from `request.form`.\n\nThis example shows the complete control flow. A GET request prints the form. A POST request validates the email, stores it in the session, queues a cookie, and redirects. Use `print` for every markup value that the handler must send. The documentation renderer runs the GET path.\n\n```capy\nfunction RENDER(request : dval) {\n request.out.headers[\"Content-Type\"] = \"text/html; charset=utf-8\"\n var method := string(request.method, \"GET\")\n\n if method == \"POST\" {\n var email := string(request.form.email, \"\")\n if email == \"\" {\n request.out.status = 422\n print(<>

Email is required.

)\n return\n }\n\n var session := session_start(\"account\")\n session = session_set(\"email\", email)\n request.out.cookies[\"has_account\"] = \"1\"\n redirect(\"/account\")\n return\n }\n\n print(<>\n
\n \n \n
\n )\n}\n\n```\n\n\n## Read uploaded files\n\nUploaded files appear in `request.files`. Each entry is a copied `dval` with the metadata that Bearer accepted for the request. Treat the original filename as user input.\n\nUse the generated request page for the exact file fields. Validate the file count, size, and type before you store anything.\n\n```capy\nfunction RENDER(request : dval) {\n var files := request.files\n print(\"files=\", length(files), \"\\n\")\n}\n\n```\n\n\n## Sessions\n\nSession effects return a state map with `id`, `name`, and `values`. Keep the returned value when later code needs changed session data. The handler request snapshot does not change.\n\n```capy\nfunction RENDER(request : dval) {\n var session := session_start(\"account\")\n session = session_set(\"theme\", \"dark\")\n print(string(session.values.theme, \"\"), \"\\n\")\n}\n\n```\n\n\n## CLI and WebSocket handlers\n\nUse `CLI` for a local command through Bearer's private CLI socket. Read command input from the copied request snapshot:\n\n```capy\nfunction CLI(request : dval) {\n print(string(request.body, \"\"))\n}\n\n```\n\n\nUse `WS` for each WebSocket message. Read the message from `request.body`. Read the connection ID, scope, opcode, binary flag, and current-scope connections from `request.websocket`:\n\n```capy\nfunction WS(request : dval) {\n ws_send(string(request.body, \"\"), false)\n}\n\n```\n\n\n`RENDER`, named `RENDER`, `COMPONENT`, named `COMPONENT`, `CLI`, `WS`, `TASK`, named `TASK`, `INIT`, `ONCE`, and custom HTTP handlers use `request : dval`. Handlers do not return application values.\n") { found = true } if consider(tokens, "/doc/guide/units-components-and-exports/", "10. Units and components", "Learn Capy", "10. Units and components\nEach Capy source file is an independent unit. A unit can expose functions and type metadata to other units. It can also render named components.\n\n## Export a function\n\n`#exports` lists the functions and types that another unit can inspect. A callable `(dval) dval` function can also be called through a module handle:\n\n```capy\n#exports echo\n\nfunction echo(input : dval) dval {\n -> input\n}\n\nfunction RENDER(request : dval) {\n var result := echo({message: \"ready\"})\n print(result.message, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nready\n\n```\n\nA module-callable function has the exact signature `(dval) dval`. Private helper functions do not appear in `#exports`.\n\n## Call another unit\n\nA separate service unit can expose a data function:\n\n```capy\n#exports version\n\nfunction version(input : dval) dval {\n -> {name: \"Capy\"}\n}\n\n```\n\n\nLoad and call it from a neighboring page:\n\n```capy\nfunction RENDER(request : dval) {\n var service := unit_load(\"/doc/examples/call_target.capy\")\n var version := service.default_input()\n print(string(version), \"\\n\")\n}\n\n```\n\n\n`unit_load` returns a request-local `module` handle. Module member calls are dynamic. `service.default_input()` calls the exported function named `default_input` on that loaded unit. Module calls copy input and result `dval` values as BRRB. `unit_call(path, name, input)` performs the same operation without keeping a handle.\n\nRelative paths resolve from the calling unit. Use an absolute site path when the target must not depend on the caller directory.\n\n## Module handles\n\nA module handle is a verified request-local capability. It can pass through typed locals, parameters, and results during that request. It cannot enter a `dval`, aggregate, closure, condition, or serialized boundary.\n\n## Static type imports\n\nUse `#import \"path\" as name` when the compiler must see exported Capy types from another unit. For example, `#import \"/doc/examples/call_target.capy\" as example` makes `example.VersionInfo` valid in type positions.\n\nA static import reads type metadata at compile time. It does not create a runtime module handle. Use `unit_load()` when the target unit must be selected at runtime.\n\nDo not retain a module handle for another request. A later request can load a newer valid source generation.\n\n## Components\n\nA component writes reusable response content through output functions such as `print`. A named component uses a handler name:\n\n```capy\nfunction COMPONENT:CARD(request : dval) {\n var props := request.props\n print(<>
)\n}\n\n```\n\n\nRender it into the response:\n\n```capy\nfunction RENDER(request : dval) {\n component_render(\"/doc/examples/card.capy:CARD\", {title: \"News\"})\n}\n\n```\n\n\nUse `component()` when the caller needs the component output as a string. Bearer copies props into the component request context and restores the earlier props after the call.\n\n## Boundary rules\n\nBearer copies `dval` values at module, component, task, export, codec, request, and serialization boundaries. A target cannot mutate the caller's value through a boundary. The dynamic-values guide defines the identity rule.\n\nMissing units, missing exports, and incompatible exported signatures are errors.\n\n## Choose a boundary\n\nUse a component when the result is markup for the current page. Use an exported function when the result is data. Use a direct helper function only inside one source file.\n\nA module loaded with `unit_load()` lives only for the current request. Store data in a session, a file, a database, or a task result when it must outlive the request.\n\nKeep component props narrow. Pass only the values the component needs. This makes examples, tests, and future replacement easier.\n") { found = true } - if consider(tokens, "/doc/guide/tasks-and-jobs/", "11. Tasks and jobs", "Learn Capy", "11. Tasks and jobs\nA task runs a Capy handler outside the current request. A job runs an operating-system command. Both return immediately with a handle that the caller can inspect later.\n\n## Read status data\n\nTask status is a `dval` because fields can vary with the state:\n\n```capy\nfunction state_label(status : dval) string {\n -> string(status.state, \"missing\")\n}\n\nfunction RENDER(request : dval) {\n print(state_label({state: \"queued\"}), \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nqueued\n\n```\n\nReal task states are `queued`, `running`, `succeeded`, `failed`, `canceled`, or `missing`.\n\n## Define a task handler\n\nA named task handler receives one request value:\n\n```capy\nfunction TASK:STORE(request : dval) {\n var props := request.props\n var key := string(props.key, \"\")\n if key == \"\" {\n trap()\n }\n // Store the application result under key.\n}\n\nfunction RENDER(request : dval) {\n print(\"task handler ready\\n\")\n}\n\n```\n\n\nThe task boundary copies props as BRRB. `dval` identity does not cross it. The worker does not receive the caller's request, session, connections, open handles, or memory state.\n\n## Submit a task\n\n`task` returns an opaque string ID after Bearer admits the task:\n\n```capy\nfunction RENDER(request : dval) {\n var id := task(\"/tasks/store.capy:STORE\", {key: \"report-42\"})\n print(id, \"\\n\")\n}\n\n```\n\n\nThe call traps if Bearer cannot admit the task. Use `task_status(id)` to poll. Use `task_await(id, timeout_ms)` to wait for a state:\n\n```capy\nfunction show_failure(id : string) {\n var status := task_await(id, 5000)\n if string(status.state, \"\") == \"failed\" {\n print(string(status.failure_code, \"unknown\"))\n }\n}\n\nfunction RENDER(request : dval) {\n print(\"failure helper ready\\n\")\n}\n\n```\n\n\nA wait timeout does not cancel active work. `task_cancel(id)` requests cancellation, but a running task can finish first. Cancellation does not undo an external effect.\n\nA successful task means that its handler finished. Task status does not carry an application result. Store results in application-owned persistent storage.\n\n## Run a command\n\n`shell_spawn` starts a bounded operating-system job:\n\n```capy\nfunction RENDER(request : dval) {\n var job := shell_spawn({cmd: \"printf ready\", timeout_ms: 1000})\n var status := job_await(job, 3000)\n print(string(status.state, \"missing\"), \"\\n\")\n}\n\n```\n\n\nUse `job_status`, `job_await`, `job_result`, and `job_cancel` with the returned handle. Always set a deliberate command timeout. Validate the final state before reading result data.\n\nThe shell interprets `cmd`. Do not build it from request data or other untrusted input.\n\n## Failure and retries\n\nBearer does not retry a failed task automatically. Submit a new task only when the application can repeat the operation safely. Use an application idempotency key for work that changes external state.\n\nDo not wait for long work in a page request unless the response requires it. Treat task IDs and job handles as opaque values.\n\n## Keep task input small\n\nPass a `dval` that contains only stable identifiers and simple options. Do not pass a full request snapshot to a task. Request data can contain cookies, headers, and uploaded-file metadata that the task does not need.\n\nUse a database row, file path, or application key when work needs large input. Validate that reference again inside the task. A task can run after the user request has ended.\n\nUse a visible status page for long work. It should show queued, running, done, failed, and canceled states in user terms.\n") { found = true } + if consider(tokens, "/doc/guide/tasks-and-jobs/", "11. Tasks and jobs", "Learn Capy", "11. Tasks and jobs\nA task runs a Capy handler outside the current request. A job runs an operating-system command. Both return immediately with a handle that the caller can inspect later.\n\n## Read status data\n\nTask status is a `dval` because fields can vary with the state:\n\n```capy\nfunction state_label(status : dval) string {\n -> string(status.state, \"missing\")\n}\n\nfunction RENDER(request : dval) {\n print(state_label({state: \"queued\"}), \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nqueued\n\n```\n\nReal task states are `queued`, `running`, `succeeded`, `failed`, `canceled`, or `missing`.\n\n## Define a task handler\n\nA named task handler receives one request value:\n\n```capy\nfunction TASK:STORE(request : dval) {\n var props := request.props\n var key := string(props.key, \"\")\n if key == \"\" {\n trap()\n }\n // Store the application result under key.\n}\n\nfunction RENDER(request : dval) {\n print(\"task handler ready\\n\")\n}\n\n```\n\n\nThe task boundary copies props as BRRB. `dval` identity does not cross it. The worker does not receive the caller's request, session, connections, open handles, or memory state.\n\n## Submit a task\n\n`task` returns an opaque string ID after Bearer admits the task:\n\n```capy\nfunction RENDER(request : dval) {\n var id := task(\"/tasks/store.capy:STORE\", {key: \"report-42\"})\n print(id, \"\\n\")\n}\n\n```\n\n\nThe call traps if Bearer cannot admit the task. Use `task_status(id)` to poll. Use `task_await(id, timeout_ms)` to wait for a state:\n\n```capy\nfunction show_failure(id : string) {\n var status := task_await(id, 5000)\n if string(status.state, \"\") == \"failed\" {\n print(string(status.failure_code, \"unknown\"))\n }\n}\n\nfunction RENDER(request : dval) {\n print(\"failure helper ready\\n\")\n}\n\n```\n\n\nA wait timeout does not cancel active work. `task_cancel(id)` requests cancellation, but a running task can finish first. Cancellation does not undo an external effect.\n\nA successful task means that its handler finished. Task status does not carry an application result. Store results in application-owned persistent storage.\n\n## Run a command\n\nThe two-argument `shell_exec` form starts a bounded background operating-system job:\n\n```capy\nfunction RENDER(request : dval) {\n var job := shell_exec(\"printf ready\", {background: true, timeout_ms: 1000})\n var status := job_await(job, 3000)\n print(string(status.state, \"missing\"), \"\\n\")\n}\n\n```\n\n\nUse `job_status`, `job_await`, `job_result`, and `job_cancel` with the returned handle. Always set a deliberate command timeout. Validate the final state before reading result data.\n\nThe shell interprets `cmd`. Do not build it from request data or other untrusted input.\n\n## Failure and retries\n\nBearer does not retry a failed task automatically. Submit a new task only when the application can repeat the operation safely. Use an application idempotency key for work that changes external state.\n\nDo not wait for long work in a page request unless the response requires it. Treat task IDs and job handles as opaque values.\n\n## Keep task input small\n\nPass a `dval` that contains only stable identifiers and simple options. Do not pass a full request snapshot to a task. Request data can contain cookies, headers, and uploaded-file metadata that the task does not need.\n\nUse a database row, file path, or application key when work needs large input. Validate that reference again inside the task. A task can run after the user request has ended.\n\nUse a visible status page for long work. It should show queued, running, done, failed, and canceled states in user terms.\n") { found = true } if consider(tokens, "/doc/guide/errors-testing-and-style/", "12. Errors and testing", "Learn Capy", "12. Errors and testing\nCapy reports type and syntax errors before a unit runs. Runtime failures include the original Capy source location.\n\n## Handle expected missing data\n\nUse a fallback when absence is valid:\n\n```capy\nfunction display_name(profile : dval) string {\n -> string(profile.name, \"guest\")\n}\n\nfunction RENDER(request : dval) {\n print(display_name({:}), \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nguest\n\n```\n\nThe fallback handles both `none` and failed string conversion. It does not hide a compiler error or an unrelated runtime trap.\n\n## Compiler errors\n\nThe compiler rejects invalid syntax, unknown names, and incompatible types. For example, this assignment is invalid:\n\n```capy-error\nfunction RENDER(request : dval) {\n var count := 1\n count = \"one\"\n}\n```\n\n`count` has type `s32`. Assignment cannot change its type to `string`.\n\nRead the first diagnostic and its source location. Later messages can be consequences of the first error.\n\n## Runtime traps\n\nUse strict access when missing data violates the program contract:\n\n```capy\nfunction RENDER(request : dval) {\n var profile := {:}\n if !has(profile, \"name\") { trap() }\n var name := get(profile, \"name\")\n print(name)\n}\n\n```\n\n\nThis traps if `name` is missing or the access path is unusable. Other traps include division by zero, invalid typed-array indexes, failed host operations, and an explicit `trap()`.\n\nDo not use a fallback for data that the program requires. A clear trap at the boundary is safer than incorrect work with a fabricated value.\n\n## Test through Bearer\n\nRun one page through the local CLI socket:\n\n```text\nscripts/bearer-cli /path/to/page.capy\n```\n\nThe CLI helper exposes the response body and runtime errors. Use an HTTP client or a repository HTTP test helper when a test must verify status and headers. Include failure cases for missing input, invalid conversions, and boundary errors.\n\nThe repository test suites exercise the compiler, Wasm runtime, source maps, components, units, tasks, and documentation examples:\n\n```text\nscripts/test_capy_native.sh\nscripts/test_capy_phase1.sh\nscripts/test_capy_reference.sh\n```\n\nRun the focused test while editing. Run the broader gate before deployment.\n\n## Keep code direct\n\nPrefer a small typed helper over repeated dynamic conversion. Keep request parsing near the request boundary. Convert a `dval` to a static type once the required shape is known.\n\nUse one name for one thing. Remove wrappers that only rename another function. Keep comments for behavior that the code cannot make clear.\n\n## Find API details\n\nThe language guide explains how Capy code fits together. The API reference gives exact standard-library signatures and failure behavior. Use the generated Capy signature on each API page.\n\n## Read failures as contracts\n\nA compile error usually means the source does not match the type contract. Fix that error before you inspect later messages.\n\nA runtime trap usually means the input did not match the application contract. Test required data with `has()` before you call `get()`. Use constructors with fallbacks when absence is valid.\n\nWrite tests for both paths. A success test proves the expected shape works. A failure test proves bad input cannot silently continue.\n") { found = true } if consider(tokens, "/doc/guide/coming-from-react/", "13. Coming from React", "Learn Capy", "13. Coming from React\nIf you have written React, most of what you know transfers — the parts that change are where rendering happens and what a component is allowed to hold.\n\nCapy renders on the server. A unit is a `.capy` file, a page is a `function RENDER`, and the output is HTML written with `print`. There is no virtual DOM, no client bundle, and no file-system router unless you write one.\n\n## The mapping\n\n| React | Capy |\n| --- | --- |\n| a page component | `function RENDER(request : dval)` |\n| a reusable component | `function COMPONENT(request : dval)` |\n| several components in one file | `function COMPONENT:NAME(request : dval)` |\n| `props` | `request.props` |\n| `return
…
` | `print(…)` |\n| rendering a child | `component_render(\"card\")` or `component(\"card\")` |\n\nA handler returns nothing. Whatever it prints becomes the response, so the React habit of building a tree and returning it becomes writing output in order:\n\n```capy\nfunction RENDER(request : dval) {\n var name := string(request.query.name, \"guest\")\n print(\"

Hello, \", name, \"

\")\n print(\"

Rendered on the server.

\", \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\n

Hello, guest

Rendered on the server.

\n\n```\n\n\n## Components take explicit props\n\nA React component receives props as an object and can render children. A Capy component receives `request.props` and has no children or slots — if a fragment needs inner content, pass it as a prop or call another component yourself.\n\n```capy\nfunction COMPONENT(request : dval) {\n var title := string(request.props.title, \"Untitled\")\n print(\"

\", title, \"

\")\n}\n\n```\n\n\nThe caller decides how the result is used. `component_render()` writes the fragment straight into the response, which is the common case in a layout. `component()` returns it as a string when you need to wrap, measure, or conditionally emit it.\n\nProps are scoped to the call and restored when it returns, so a component cannot disturb its caller's props and nested components each read their own.\n\n## There is no client state\n\nThis is the biggest adjustment. There is no `useState`, no effect hook, and no re-render — a handler runs once per request and produces final HTML.\n\nWhat replaces them:\n\n- **per-request shared state** — `request.call`, readable by every handler in the request\n- **work that runs once before a unit's handlers** — `function ONCE(request : dval)`\n- **work that runs once when a worker loads a unit** — `function INIT(request : dval)`\n- **state that outlives the request** — a session, a file, a database, or a task\n\nA module handle from `unit_load()` lives only for the current request; do not stash one for later.\n\n## Escaping\n\nMarkup literals escape interpolated values for you, which is the equivalent of React escaping `{value}` by default:\n\n```capy\nfunction RENDER(request : dval) {\n var supplied := string(request.query.q, \"