Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .rush/temp/shrinkwrap-deps.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"../../node": "../../node:hnTERTpEMb2w8HOm+aqGL5QPvYaFE1ypPQ9z8hteNMo=:",
"../../node": "../../node:T9AEHYRQ22jknBJL2JzA1IWbgqqvke1gidVuQnOkgE8=:",
"/@babel/code-frame/7.29.0": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
"/@babel/compat-data/7.29.0": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
"/@babel/core/7.29.0": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
Expand Down Expand Up @@ -118,7 +118,7 @@
"/@socket.io/component-emitter/3.1.2": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"/@tootallnate/once/2.0.0": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"/@tootallnate/quickjs-emscripten/0.23.0": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
"/@trpc/client/11.0.0-rc.660_dec9ab05b59cfcb251b83d88cde10054": "sha512-bNpkZEfyMGKHynYFxdLpY8nJ1n7E3JHKcd4Pe2cagmpkzOEF9tFT3kzNf+eLI8XMG8196lTRR0J0W2/1Q8/cug==",
"/@trpc/client/11.0.0-rc.660_@trpc+server@11.0.0-rc.660": "sha512-bNpkZEfyMGKHynYFxdLpY8nJ1n7E3JHKcd4Pe2cagmpkzOEF9tFT3kzNf+eLI8XMG8196lTRR0J0W2/1Q8/cug==",
"/@trpc/server/11.0.0-rc.660": "sha512-QUapcZCNOpHT7ng9LceGc9ImkboWd0Go9ryrduZpL+p4jdfaC6409AQ3x4XEW6Wu3yBmZAn4CywCsDrDhjDy/w==",
"/@types/babel__core/7.20.5": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"/@types/babel__generator/7.27.0": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
Expand Down Expand Up @@ -389,6 +389,7 @@
"/find-up/5.0.0": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"/flat-cache/3.2.0": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
"/flatted/3.3.3": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"/follow-redirects/1.15.11": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"/follow-redirects/1.15.11_debug@4.3.4": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"/for-each/0.3.5": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"/form-data-encoder/1.7.2": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
Expand Down
4 changes: 2 additions & 2 deletions ANALYSIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Core Node SDK/runtime utility package for Arken protocol, data handling, and gam
- `.erb/`: documentation/scaffolding branding assets (currently `img/logo.png`) with low runtime risk but potential UX drift if assets are changed ad hoc.
- `coverage/`: generated LCOV/Clover/JSON coverage artifacts; useful diagnostics but should remain generated-only to avoid noisy/manual drift (now documented with local `coverage/{README.md,ANALYSIS.md}`).
- `websocket.ts`: lightweight socket helper exposing `emitAll`/`emitDirect` and `getClientSocket`; currently uses untyped emitter params and no explicit reconnect/backoff policy controls at this utility boundary.
- `api.ts`: query-to-Mongo filter adapter (`getFilter`) and HTTP POST helper (`fetch`) used for dynamic filtering and remote query dispatch; id-field normalization applies consistently across `equals`/`contains`/`in` operators, scalar shorthand field values map to equality filters (root + nested logical nodes), non-plain object values (e.g., `Date`, ObjectId-like values) are preserved as equality filters, plain-object values without operator keys are now preserved as direct equality filters (instead of being silently dropped), logical nesting preserves child `OR` groups inside parent `AND` clauses, singleton-object shorthand for logical groups (`OR`/`AND` as object instead of array) is normalized for resilient filter parsing, empty `in: []` clauses are now treated as no-op fragments (avoids accidental always-empty result filters in mixed logical queries), and the HTTP helper now fail-fast validates URL/query payload shape, trims validated URL input before dispatch, and applies a deterministic axios timeout to avoid unbounded hangs.
- `util.ts`: currently re-exports from `'.'`, creating a circular/umbrella alias surface that can obscure intended subpath ownership.
- `api.ts`: query-to-Mongo filter adapter (`getFilter`) and HTTP POST helper (`fetch`) used for dynamic filtering and remote query dispatch; id-field normalization applies consistently across `equals`/`contains`/`in` operators, scalar shorthand field values map to equality filters (root + nested logical nodes), non-plain object values (e.g., `Date`, ObjectId-like values) are preserved as equality filters, plain-object values without operator keys are now preserved as direct equality filters (instead of being silently dropped), logical nesting preserves child `OR` groups inside parent `AND` clauses, singleton-object shorthand for logical groups (`OR`/`AND` as object instead of array) is normalized for resilient filter parsing, root-level array-shaped `where` payloads are now rejected as invalid/no-op filter input (prevents accidental numeric-key filter generation), empty `in: []` and `equals: undefined` clauses are now treated as no-op fragments (avoids malformed/noisy filters in mixed logical queries), and the HTTP helper now fail-fast validates URL/query payload shape, trims validated URL input before dispatch, enforces http(s)-only absolute URL protocols, and applies a deterministic axios timeout to avoid unbounded hangs.
- `util.ts`: now explicitly re-exports utility bridges from `util/api` and `util/rpc`, removing prior package-root circular aliasing and clarifying subpath ownership.
- root build/test config (`package.json`, `tsconfig*.json`, `jest.unit.config.js`): defines compile/test pipeline, export surface, and strictness defaults for the whole package.

## Omniverse architecture perspective
Expand Down
14 changes: 13 additions & 1 deletion api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function escapeRegExp(s: string) {

export function getFilter(query: any): Record<string, any> {
const where = query?.where;
if (!where || typeof where !== 'object') return {};
if (!where || typeof where !== 'object' || Array.isArray(where)) return {};

// Helper to turn a single field condition into a Mongo filter fragment
const buildField = (field: string, cond: any) => {
Expand All @@ -34,6 +34,7 @@ export function getFilter(query: any): Record<string, any> {
}

if ('equals' in cond) {
if (cond.equals === undefined) return undefined;
return { [normalizedField]: cond.equals };
}

Expand Down Expand Up @@ -108,6 +109,17 @@ export async function fetch(url: string, query: FetchQuery): Promise<any> {
}

const normalizedUrl = url.trim();
let parsedUrl: URL;

try {
parsedUrl = new URL(normalizedUrl);
} catch {
throw new Error('Invalid fetch URL');
}

if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
throw new Error('Invalid fetch URL');
}

const res = await axios.post(normalizedUrl, query, {
timeout: DEFAULT_FETCH_TIMEOUT_MS,
Expand Down
7 changes: 5 additions & 2 deletions binary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ export function decodePayload(msg) {

return json;
} catch (err) {
// ...
console.log(err, msg);
const raw = typeof msg === 'string' ? msg : String(msg ?? '');
const preview = raw.length > 40 ? `${raw.slice(0, 40)}...` : raw;
const errorMessage = err instanceof Error ? err.message : String(err);
console.warn(`decodePayload failed: ${errorMessage}; payloadPreview=${preview}`);
return undefined;
}
}
9 changes: 7 additions & 2 deletions test/ANALYSIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,10 @@
- Added malformed-network-response regression coverage for `httpProvider` to ensure non-Fetch-like response objects (including non-finite status metadata) are rejected with deterministic provider errors before runtime method access faults or invalid status propagation.
- Added fetch-rejection normalization coverage for `httpProvider` because runtime fetch implementations may throw primitives or non-standard errors; tests now lock deterministic `RequestError` envelopes for both primitive and Error-like rejection paths.
- Added response-body read-failure regression coverage for `httpProvider` because some runtimes can throw on `response.text()` stream reads; tests now lock deterministic `Invalid provider response` envelope normalization.
- Added `api/getFilter` regression coverage to ensure `id` criteria normalize to `_id` across `equals`/`in`/`contains` operators, scalar shorthand conditions (e.g., `{ id: 'abc' }`) are treated as equality checks in both root and nested logical nodes, singleton-object `OR`/`AND` shorthand is normalized into logical clauses, plain-object values without operator keys are preserved as equality filters (instead of being dropped), empty `contains` clauses remain no-op within logical groups, empty `in: []` clauses are also treated as no-op fragments (preventing accidental always-empty filters), and nested logical groups (e.g., `AND` containing `OR`) are preserved in generated Mongo filters.
- Added `api/fetch` regression coverage because helper calls can fail non-deterministically without envelope validation/timeouts; tests now lock fail-fast rejection for blank URL and non-object query payloads, verify URL inputs are trimmed before dispatch, and verify axios requests always include deterministic timeout (`10000ms`).
- Added cache-write failure regression coverage for `httpProvider` because Cache API persistence can fail at runtime even when read paths exist; tests now lock best-effort behavior so transport success is not coupled to cache `put` availability.
- Added constructor-URL validation regression coverage for `httpProvider` because malformed endpoint strings previously surfaced raw runtime URL parsing exceptions; tests now lock deterministic `RequestError` metadata (`-32602`, `Invalid provider URL`) for safer upstream error handling.
- Added constructor protocol-guard regression coverage for `httpProvider` because non-http URL schemes (for example `ws:`) are incompatible with the helper’s HTTP fetch transport path; tests now lock deterministic early rejection (`-32602`) instead of deferred runtime failures.
- Added `api/getFilter` regression coverage to ensure `id` criteria normalize to `_id` across `equals`/`in`/`contains` operators, scalar shorthand conditions (e.g., `{ id: 'abc' }`) are treated as equality checks in both root and nested logical nodes, singleton-object `OR`/`AND` shorthand is normalized into logical clauses, plain-object values without operator keys are preserved as equality filters (instead of being dropped), root array-shaped `where` payloads are now rejected as no-op filters to avoid accidental index-key query fragments, empty `contains` clauses remain no-op within logical groups, empty `in: []` clauses are also treated as no-op fragments (preventing accidental always-empty filters), `equals: undefined` fragments are ignored as no-op filters (preventing malformed `{ field: undefined }` predicates), and nested logical groups (e.g., `AND` containing `OR`) are preserved in generated Mongo filters.
- Added `api/fetch` regression coverage because helper calls can fail non-deterministically without envelope validation/timeouts; tests now lock fail-fast rejection for blank/malformed/non-http(s) URL values and non-object query payloads, verify URL inputs are trimmed before dispatch, and verify axios requests always include deterministic timeout (`10000ms`).
- Added `binary/decodePayload` regression coverage to lock deterministic behavior for malformed binary payloads: decode failures now return `undefined` and log only a short payload preview (instead of dumping the full raw payload), reducing accidental sensitive-data exposure in routine logs while preserving troubleshooting context.
- Added `util` subpath export regression coverage (`test/util.spec.ts`) to verify API/RPC helpers remain available without depending on circular `util.ts -> '.'` package-root re-export coupling.
6 changes: 4 additions & 2 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Protocol-focused tests for `@arken/node` socket tRPC wrappers.
## Files
- `socketLink.spec.ts`: client transport routing, callback lifecycle, duplicate-delivery idempotency, unsubscribe/teardown-vs-late-response no-op behavior (link + proxy), timeout-vs-late-response race handling, single-terminal-settlement guards for resolve/error permutations (link + proxy paths), callback-boundary resolve-throw fallback behavior for mixed `error`/`result` envelopes, ID-collision guardrails, timeout reqId metadata checks, late response handling, malformed payload permutations, strict response-id handling (non-string/blank IDs), own-property callback matching/prototype-key safety (including inherited and `__proto__` ids), deserialize-failure propagation, immediate same-tick response handling, backend-only path rejection (missing method segment), alternate response IDs, server-push malformed-param resilience (for both `trpc` and `trpcResponse` fallback paths), malformed push-method filtering, and `onAny` support including non-response filtering + fallback/teardown edge paths.
- `socketServer.spec.ts`: server dispatch, malformed payload handling (including invalid binary-string decode paths and decoded non-string/blank-string method payloads), response-id normalization checks (trimmed IDs on success; non-string/blank IDs dropped on error paths), whitespace-trimmed valid-method dispatch behavior, prototype/constructor path traversal rejection (including surrounding-whitespace, exact `constructor`, `prototype` segment, nested-segment variants, inherited built-in prototype paths like `core.toString`, inherited array-prototype method paths like `core.list.map`, and expanded inherited typed-array prototype methods like `core.bytes.map` and `core.floats.map`), empty-segment and whitespace-segment method-path rejection (`core..ping`, `core. ping`), missing method behavior, invalid/undecodable `params` payload behavior, listener attach/detach wiring, and safe no-op behavior when sockets do not expose `on`/`off` hooks.
- `httpProvider.spec.ts`: verifies `web3/httpProvider` honors explicit constructor URLs, rejects malformed non-object JSON-RPC payloads with deterministic `-32600` invalid-request errors, normalizes whitespace-padded JSON-RPC method names before network submission, preserves caller-provided JSON-RPC IDs (including explicit `null`, with fallback `56` only when `id` is absent), keeps caller-owned request objects immutable while applying defaults internally, degrades safely to network-only flow when Cache API globals are unavailable, ignores malformed cache hits by refetching from network, rejects hung requests once provider timeout budget is exceeded, aborts in-flight fetches on timeout when abort signaling is available, normalizes abort-triggered fetch rejections into timeout-shaped `RequestError` envelopes, fails closed on 403 when no alternate providers are configured (no unbounded retry recursion), normalizes non-object JSON response envelopes (for example `null`) without runtime `TypeError` crashes, coerces malformed RPC error envelopes into deterministic numeric-code/message fallbacks, rejects malformed non-Fetch-like network response objects (including non-finite status values) with a deterministic provider error envelope, normalizes `response.text()` read/stream failures into deterministic provider errors, and normalizes both primitive and Error-like fetch rejections into stable provider `RequestError` envelopes.
- `api.spec.ts`: verifies `getFilter` maps `id` operator variants (`equals`/`in`/`contains`) to `_id` consistently, supports scalar shorthand equality inputs at root and nested logical nodes (e.g., `{ id: 'abc' }`), normalizes singleton-object logical shorthand (`OR`/`AND` as objects) into valid clauses, preserves non-plain object equality values (e.g., `Date`, `ObjectId`) instead of dropping them, preserves plain-object equality filters when no operator keys are present, drops no-op empty `contains` fragments inside logical OR/AND clauses, drops no-op empty `in: []` fragments inside logical OR/AND clauses, and preserves nested logical composition (e.g., `AND` entries containing `OR` groups). Also covers `api/fetch` fail-fast validation for blank URL/non-object query payloads, validates URL-trimming before dispatch, and validates deterministic axios timeout configuration (`10000ms`).
- `httpProvider.spec.ts`: verifies `web3/httpProvider` honors explicit constructor URLs (including whitespace-padded URL input trimming), rejects malformed/non-http(s) constructor URL values with deterministic `-32602` envelopes, rejects malformed non-object JSON-RPC payloads with deterministic `-32600` invalid-request errors, normalizes whitespace-padded JSON-RPC method names before network submission, preserves caller-provided JSON-RPC IDs (including explicit `null`, with fallback `56` only when `id` is absent), keeps caller-owned request objects immutable while applying defaults internally, degrades safely to network-only flow when Cache API globals are unavailable, ignores malformed cache hits by refetching from network, treats cache-write failures as best-effort (request still resolves), rejects hung requests once provider timeout budget is exceeded, aborts in-flight fetches on timeout when abort signaling is available, normalizes abort-triggered fetch rejections into timeout-shaped `RequestError` envelopes, fails closed on 403 when no alternate providers are configured (no unbounded retry recursion), normalizes non-object JSON response envelopes (for example `null`) without runtime `TypeError` crashes, coerces malformed RPC error envelopes into deterministic numeric-code/message fallbacks, rejects malformed non-Fetch-like network response objects (including non-finite status values) with a deterministic provider error envelope, normalizes `response.text()` read/stream failures into deterministic provider errors, and normalizes both primitive and Error-like fetch rejections into stable provider `RequestError` envelopes.
- `api.spec.ts`: verifies `getFilter` maps `id` operator variants (`equals`/`in`/`contains`) to `_id` consistently, supports scalar shorthand equality inputs at root and nested logical nodes (e.g., `{ id: 'abc' }`), normalizes singleton-object logical shorthand (`OR`/`AND` as objects) into valid clauses, preserves non-plain object equality values (e.g., `Date`, `ObjectId`) instead of dropping them, preserves plain-object equality filters when no operator keys are present, rejects array-shaped root `where` payloads as empty/no-op filters (avoids accidental numeric-key fragments), drops no-op empty `contains` fragments inside logical OR/AND clauses, drops no-op empty `in: []` fragments inside logical OR/AND clauses, and preserves nested logical composition (e.g., `AND` entries containing `OR` groups). Also covers `api/fetch` fail-fast validation for blank/malformed/non-http(s) URLs and non-object query payloads, validates URL-trimming before dispatch, and validates deterministic axios timeout configuration (`10000ms`).
- `binary.spec.ts`: validates `binary/decodePayload` happy-path JSON decode from binary strings and failure-path behavior that returns `undefined` while logging only a short payload preview (reduces raw payload leakage in logs).
- `util.spec.ts`: verifies `@arken/node/util` subpath exports expose API/RPC helpers (`getFilter`, `serialize`, `deserialize`) without relying on circular package-root re-export behavior.
- `NOTES.md`: tracking notes for additional test coverage.
Loading