Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@datastream/validate

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@datastream/validate - npm Package Compare versions

Comparing version
0.0.42
to
0.1.4
+30
index.d.ts
// Copyright 2026 will Farrell, and datastream contributors.
// SPDX-License-Identifier: MIT
import type { StreamOptions, StreamResult } from "@datastream/core";
export interface ValidateError {
id: string;
keys: string[];
message: string;
idx: number[];
}
export function transpileSchema(
schema: Record<string, unknown>,
ajvOptions?: Record<string, unknown>,
): (data: unknown) => boolean;
export function validateStream(
options: {
schema: Record<string, unknown> | ((data: unknown) => boolean);
idxStart?: number;
onErrorEnqueue?: boolean;
allowCoerceTypes?: boolean;
resultKey?: string;
},
streamOptions?: StreamOptions,
): unknown & {
result: () => StreamResult<Record<string, ValidateError>>;
};
export default validateStream;
<div align="center">
<h1>&lt;datastream&gt; `validate`</h1>
<img alt="datastream logo" src="https://raw.githubusercontent.com/willfarrell/datastream/main/docs/img/datastream-logo.svg"/>
<p><strong>JSON schema validation streams.</strong></p>
<p>
<a href="https://github.com/willfarrell/datastream/actions/workflows/test-unit.yml"><img src="https://github.com/willfarrell/datastream/actions/workflows/test-unit.yml/badge.svg" alt="GitHub Actions unit test status"></a>
<a href="https://github.com/willfarrell/datastream/actions/workflows/test-dast.yml"><img src="https://github.com/willfarrell/datastream/actions/workflows/test-dast.yml/badge.svg" alt="GitHub Actions dast test status"></a>
<a href="https://github.com/willfarrell/datastream/actions/workflows/test-perf.yml"><img src="https://github.com/willfarrell/datastream/actions/workflows/test-perf.yml/badge.svg" alt="GitHub Actions perf test status"></a>
<a href="https://github.com/willfarrell/datastream/actions/workflows/test-sast.yml"><img src="https://github.com/willfarrell/datastream/actions/workflows/test-sast.yml/badge.svg" alt="GitHub Actions SAST test status"></a>
<a href="https://github.com/willfarrell/datastream/actions/workflows/test-lint.yml"><img src="https://github.com/willfarrell/datastream/actions/workflows/test-lint.yml/badge.svg" alt="GitHub Actions lint test status"></a>
<br/>
<a href="https://www.npmjs.com/package/@datastream/validate"><img alt="npm version" src="https://img.shields.io/npm/v/@datastream/validate.svg"></a>
<a href="https://packagephobia.com/result?p=@datastream/validate"><img src="https://packagephobia.com/badge?p=@datastream/validate" alt="npm install size"></a>
<a href="https://www.npmjs.com/package/@datastream/validate">
<img alt="npm weekly downloads" src="https://img.shields.io/npm/dw/@datastream/validate.svg"></a>
<a href="https://www.npmjs.com/package/@datastream/validate#provenance">
<img alt="npm provenance" src="https://img.shields.io/badge/provenance-Yes-brightgreen"></a>
<br/>
<a href="https://scorecard.dev/viewer/?uri=github.com/willfarrell/datastream"><img src="https://api.scorecard.dev/projects/github.com/willfarrell/datastream/badge" alt="Open Source Security Foundation (OpenSSF) Scorecard"></a>
<a href="https://slsa.dev"><img src="https://slsa.dev/images/gh-badge-level3.svg" alt="SLSA 3"></a>
<a href="https://github.com/willfarrell/datastream/blob/main/docs/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg"></a>
<a href="https://biomejs.dev"><img alt="Checked with Biome" src="https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome"></a>
<a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white"></a>
<a href="https://github.com/willfarrell/datastream/blob/main/package.json#L32">
<img alt="code coverage" src="https://img.shields.io/badge/code%20coverage-95%25-brightgreen"></a>
</p>
<p>You can read the documentation at: <a href="https://datastream.js.org">https://datastream.js.org</a></p>
</div>
## Install
To install datastream you can use NPM:
```bash
npm install --save @datastream/validate
```
## Documentation and examples
For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
## Contributing
Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
## License
Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
+2
-3

@@ -24,3 +24,3 @@ import { createTransformStream } from "@datastream/core";

idx += 1;
const data = structuredClone(chunk);
const data = allowCoerceTypes === false ? structuredClone(chunk) : void 0;
const chunkValid = schema(chunk);

@@ -37,4 +37,3 @@ if (!chunkValid) {

if (chunkValid || onErrorEnqueue) {
chunk = allowCoerceTypes ? chunk : data;
enqueue(chunk);
enqueue(data ?? chunk);
}

@@ -41,0 +40,0 @@ };

+2
-2
{
"version": 3,
"sources": ["index.js"],
"sourcesContent": ["import { createTransformStream } from \"@datastream/core\";\nimport { compile } from \"ajv-cmd\";\n\nconst ajvDefaults = {\n\tstrict: true,\n\tcoerceTypes: true,\n\tallErrors: true,\n\tuseDefaults: \"empty\",\n\tmessages: true, // needs to be true to allow multi-locale errorMessage to work\n};\n\n// This is pulled out due to it's performance cost (50-100ms on cold start)\n// Precompile your schema during a build step is recommended.\nexport const transpileSchema = (schema, ajvOptions) => {\n\tconst options = { ...ajvDefaults, ...ajvOptions };\n\treturn compile(schema, options);\n};\n\nexport const validateStream = (\n\t{ schema, idxStart, onErrorEnqueue, allowCoerceTypes, resultKey },\n\tstreamOptions = {},\n) => {\n\tidxStart ??= 0;\n\n\tif (typeof schema !== \"function\") {\n\t\tschema = transpileSchema(schema);\n\t}\n\n\tconst value = {}; // aka errors\n\tlet idx = idxStart - 1;\n\tconst transform = (chunk, enqueue) => {\n\t\tidx += 1;\n\t\tconst data = structuredClone(chunk);\n\t\tconst chunkValid = schema(chunk);\n\t\tif (!chunkValid) {\n\t\t\tfor (const error of schema.errors) {\n\t\t\t\tconst { id, keys, message } = processError(error);\n\n\t\t\t\tif (!value[id]) {\n\t\t\t\t\tvalue[id] = { id, keys, message, idx: [] };\n\t\t\t\t}\n\t\t\t\tvalue[id].idx.push(idx);\n\t\t\t}\n\t\t}\n\t\tif (chunkValid || onErrorEnqueue) {\n\t\t\tchunk = allowCoerceTypes ? chunk : data;\n\t\t\tenqueue(chunk);\n\t\t}\n\t};\n\tconst stream = createTransformStream(transform, streamOptions);\n\tstream.result = () => ({ key: resultKey ?? \"validate\", value });\n\treturn stream;\n};\n\nconst processError = (error) => {\n\tconst message = error.message || \"\";\n\n\tlet id = error.schemaPath;\n\n\tlet keys = [];\n\tif (error.keyword === \"errorMessage\") {\n\t\terror.params.errors.forEach((error) => {\n\t\t\tconst value = makeKeys(error);\n\t\t\tif (value) keys.push(value);\n\t\t});\n\t\tkeys = [...new Set(keys.sort())];\n\t} else {\n\t\tkeys.push(makeKeys(error));\n\t}\n\tif (!error.instancePath && keys.length) {\n\t\tid += `/${keys.join(\"|\")}`;\n\t}\n\treturn { id, keys, message };\n};\n\nconst makeKeys = (error) => {\n\t// deps groups columns that are related in anyOf/oneOf.\n\t/* error.params.deps ?? */\n\treturn (\n\t\terror.params.missingProperty ||\n\t\terror.params.additionalProperty ||\n\t\terror.instancePath.replace(\"/\", \"\")\n\t);\n};\n\nexport default validateStream;\n"],
"mappings": "AAAA,SAAS,6BAA6B;AACtC,SAAS,eAAe;AAExB,MAAM,cAAc;AAAA,EACnB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA;AACX;AAIO,MAAM,kBAAkB,CAAC,QAAQ,eAAe;AACtD,QAAM,UAAU,EAAE,GAAG,aAAa,GAAG,WAAW;AAChD,SAAO,QAAQ,QAAQ,OAAO;AAC/B;AAEO,MAAM,iBAAiB,CAC7B,EAAE,QAAQ,UAAU,gBAAgB,kBAAkB,UAAU,GAChE,gBAAgB,CAAC,MACb;AACJ,eAAa;AAEb,MAAI,OAAO,WAAW,YAAY;AACjC,aAAS,gBAAgB,MAAM;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC;AACf,MAAI,MAAM,WAAW;AACrB,QAAM,YAAY,CAAC,OAAO,YAAY;AACrC,WAAO;AACP,UAAM,OAAO,gBAAgB,KAAK;AAClC,UAAM,aAAa,OAAO,KAAK;AAC/B,QAAI,CAAC,YAAY;AAChB,iBAAW,SAAS,OAAO,QAAQ;AAClC,cAAM,EAAE,IAAI,MAAM,QAAQ,IAAI,aAAa,KAAK;AAEhD,YAAI,CAAC,MAAM,EAAE,GAAG;AACf,gBAAM,EAAE,IAAI,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,QAC1C;AACA,cAAM,EAAE,EAAE,IAAI,KAAK,GAAG;AAAA,MACvB;AAAA,IACD;AACA,QAAI,cAAc,gBAAgB;AACjC,cAAQ,mBAAmB,QAAQ;AACnC,cAAQ,KAAK;AAAA,IACd;AAAA,EACD;AACA,QAAM,SAAS,sBAAsB,WAAW,aAAa;AAC7D,SAAO,SAAS,OAAO,EAAE,KAAK,aAAa,YAAY,MAAM;AAC7D,SAAO;AACR;AAEA,MAAM,eAAe,CAAC,UAAU;AAC/B,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,KAAK,MAAM;AAEf,MAAI,OAAO,CAAC;AACZ,MAAI,MAAM,YAAY,gBAAgB;AACrC,UAAM,OAAO,OAAO,QAAQ,CAACA,WAAU;AACtC,YAAM,QAAQ,SAASA,MAAK;AAC5B,UAAI,MAAO,MAAK,KAAK,KAAK;AAAA,IAC3B,CAAC;AACD,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,EAChC,OAAO;AACN,SAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EAC1B;AACA,MAAI,CAAC,MAAM,gBAAgB,KAAK,QAAQ;AACvC,UAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EACzB;AACA,SAAO,EAAE,IAAI,MAAM,QAAQ;AAC5B;AAEA,MAAM,WAAW,CAAC,UAAU;AAG3B,SACC,MAAM,OAAO,mBACb,MAAM,OAAO,sBACb,MAAM,aAAa,QAAQ,KAAK,EAAE;AAEpC;AAEA,IAAO,gBAAQ;",
"sourcesContent": ["// Copyright 2026 will Farrell, and datastream contributors.\n// SPDX-License-Identifier: MIT\nimport { createTransformStream } from \"@datastream/core\";\nimport { compile } from \"ajv-cmd\";\n\nconst ajvDefaults = {\n\tstrict: true,\n\tcoerceTypes: true,\n\tallErrors: true,\n\tuseDefaults: \"empty\",\n\tmessages: true, // needs to be true to allow multi-locale errorMessage to work\n};\n\n// This is pulled out due to it's performance cost (50-100ms on cold start)\n// Precompile your schema during a build step is recommended.\nexport const transpileSchema = (schema, ajvOptions) => {\n\tconst options = { ...ajvDefaults, ...ajvOptions };\n\treturn compile(schema, options);\n};\n\nexport const validateStream = (\n\t{ schema, idxStart, onErrorEnqueue, allowCoerceTypes, resultKey },\n\tstreamOptions = {},\n) => {\n\tidxStart ??= 0;\n\n\tif (typeof schema !== \"function\") {\n\t\tschema = transpileSchema(schema);\n\t}\n\n\tconst value = {}; // aka errors\n\tlet idx = idxStart - 1;\n\tconst transform = (chunk, enqueue) => {\n\t\tidx += 1;\n\t\tconst data =\n\t\t\tallowCoerceTypes === false ? structuredClone(chunk) : undefined;\n\t\tconst chunkValid = schema(chunk);\n\t\tif (!chunkValid) {\n\t\t\tfor (const error of schema.errors) {\n\t\t\t\tconst { id, keys, message } = processError(error);\n\n\t\t\t\tif (!value[id]) {\n\t\t\t\t\tvalue[id] = { id, keys, message, idx: [] };\n\t\t\t\t}\n\t\t\t\tvalue[id].idx.push(idx);\n\t\t\t}\n\t\t}\n\t\tif (chunkValid || onErrorEnqueue) {\n\t\t\tenqueue(data ?? chunk);\n\t\t}\n\t};\n\tconst stream = createTransformStream(transform, streamOptions);\n\tstream.result = () => ({ key: resultKey ?? \"validate\", value });\n\treturn stream;\n};\n\nconst processError = (error) => {\n\tconst message = error.message || \"\";\n\n\tlet id = error.schemaPath;\n\n\tlet keys = [];\n\tif (error.keyword === \"errorMessage\") {\n\t\terror.params.errors.forEach((error) => {\n\t\t\tconst value = makeKeys(error);\n\t\t\tif (value) keys.push(value);\n\t\t});\n\t\tkeys = [...new Set(keys.sort())];\n\t} else {\n\t\tkeys.push(makeKeys(error));\n\t}\n\tif (!error.instancePath && keys.length) {\n\t\tid += `/${keys.join(\"|\")}`;\n\t}\n\treturn { id, keys, message };\n};\n\nconst makeKeys = (error) => {\n\t// deps groups columns that are related in anyOf/oneOf.\n\t/* error.params.deps ?? */\n\treturn (\n\t\terror.params.missingProperty ||\n\t\terror.params.additionalProperty ||\n\t\terror.instancePath.replace(\"/\", \"\")\n\t);\n};\n\nexport default validateStream;\n"],
"mappings": "AAEA,SAAS,6BAA6B;AACtC,SAAS,eAAe;AAExB,MAAM,cAAc;AAAA,EACnB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA;AACX;AAIO,MAAM,kBAAkB,CAAC,QAAQ,eAAe;AACtD,QAAM,UAAU,EAAE,GAAG,aAAa,GAAG,WAAW;AAChD,SAAO,QAAQ,QAAQ,OAAO;AAC/B;AAEO,MAAM,iBAAiB,CAC7B,EAAE,QAAQ,UAAU,gBAAgB,kBAAkB,UAAU,GAChE,gBAAgB,CAAC,MACb;AACJ,eAAa;AAEb,MAAI,OAAO,WAAW,YAAY;AACjC,aAAS,gBAAgB,MAAM;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC;AACf,MAAI,MAAM,WAAW;AACrB,QAAM,YAAY,CAAC,OAAO,YAAY;AACrC,WAAO;AACP,UAAM,OACL,qBAAqB,QAAQ,gBAAgB,KAAK,IAAI;AACvD,UAAM,aAAa,OAAO,KAAK;AAC/B,QAAI,CAAC,YAAY;AAChB,iBAAW,SAAS,OAAO,QAAQ;AAClC,cAAM,EAAE,IAAI,MAAM,QAAQ,IAAI,aAAa,KAAK;AAEhD,YAAI,CAAC,MAAM,EAAE,GAAG;AACf,gBAAM,EAAE,IAAI,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,QAC1C;AACA,cAAM,EAAE,EAAE,IAAI,KAAK,GAAG;AAAA,MACvB;AAAA,IACD;AACA,QAAI,cAAc,gBAAgB;AACjC,cAAQ,QAAQ,KAAK;AAAA,IACtB;AAAA,EACD;AACA,QAAM,SAAS,sBAAsB,WAAW,aAAa;AAC7D,SAAO,SAAS,OAAO,EAAE,KAAK,aAAa,YAAY,MAAM;AAC7D,SAAO;AACR;AAEA,MAAM,eAAe,CAAC,UAAU;AAC/B,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,KAAK,MAAM;AAEf,MAAI,OAAO,CAAC;AACZ,MAAI,MAAM,YAAY,gBAAgB;AACrC,UAAM,OAAO,OAAO,QAAQ,CAACA,WAAU;AACtC,YAAM,QAAQ,SAASA,MAAK;AAC5B,UAAI,MAAO,MAAK,KAAK,KAAK;AAAA,IAC3B,CAAC;AACD,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,EAChC,OAAO;AACN,SAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EAC1B;AACA,MAAI,CAAC,MAAM,gBAAgB,KAAK,QAAQ;AACvC,UAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EACzB;AACA,SAAO,EAAE,IAAI,MAAM,QAAQ;AAC5B;AAEA,MAAM,WAAW,CAAC,UAAU;AAG3B,SACC,MAAM,OAAO,mBACb,MAAM,OAAO,sBACb,MAAM,aAAa,QAAQ,KAAK,EAAE;AAEpC;AAEA,IAAO,gBAAQ;",
"names": ["error"]
}

@@ -24,3 +24,3 @@ import { createTransformStream } from "@datastream/core";

idx += 1;
const data = structuredClone(chunk);
const data = allowCoerceTypes === false ? structuredClone(chunk) : void 0;
const chunkValid = schema(chunk);

@@ -37,4 +37,3 @@ if (!chunkValid) {

if (chunkValid || onErrorEnqueue) {
chunk = allowCoerceTypes ? chunk : data;
enqueue(chunk);
enqueue(data ?? chunk);
}

@@ -41,0 +40,0 @@ };

{
"version": 3,
"sources": ["index.js"],
"sourcesContent": ["import { createTransformStream } from \"@datastream/core\";\nimport { compile } from \"ajv-cmd\";\n\nconst ajvDefaults = {\n\tstrict: true,\n\tcoerceTypes: true,\n\tallErrors: true,\n\tuseDefaults: \"empty\",\n\tmessages: true, // needs to be true to allow multi-locale errorMessage to work\n};\n\n// This is pulled out due to it's performance cost (50-100ms on cold start)\n// Precompile your schema during a build step is recommended.\nexport const transpileSchema = (schema, ajvOptions) => {\n\tconst options = { ...ajvDefaults, ...ajvOptions };\n\treturn compile(schema, options);\n};\n\nexport const validateStream = (\n\t{ schema, idxStart, onErrorEnqueue, allowCoerceTypes, resultKey },\n\tstreamOptions = {},\n) => {\n\tidxStart ??= 0;\n\n\tif (typeof schema !== \"function\") {\n\t\tschema = transpileSchema(schema);\n\t}\n\n\tconst value = {}; // aka errors\n\tlet idx = idxStart - 1;\n\tconst transform = (chunk, enqueue) => {\n\t\tidx += 1;\n\t\tconst data = structuredClone(chunk);\n\t\tconst chunkValid = schema(chunk);\n\t\tif (!chunkValid) {\n\t\t\tfor (const error of schema.errors) {\n\t\t\t\tconst { id, keys, message } = processError(error);\n\n\t\t\t\tif (!value[id]) {\n\t\t\t\t\tvalue[id] = { id, keys, message, idx: [] };\n\t\t\t\t}\n\t\t\t\tvalue[id].idx.push(idx);\n\t\t\t}\n\t\t}\n\t\tif (chunkValid || onErrorEnqueue) {\n\t\t\tchunk = allowCoerceTypes ? chunk : data;\n\t\t\tenqueue(chunk);\n\t\t}\n\t};\n\tconst stream = createTransformStream(transform, streamOptions);\n\tstream.result = () => ({ key: resultKey ?? \"validate\", value });\n\treturn stream;\n};\n\nconst processError = (error) => {\n\tconst message = error.message || \"\";\n\n\tlet id = error.schemaPath;\n\n\tlet keys = [];\n\tif (error.keyword === \"errorMessage\") {\n\t\terror.params.errors.forEach((error) => {\n\t\t\tconst value = makeKeys(error);\n\t\t\tif (value) keys.push(value);\n\t\t});\n\t\tkeys = [...new Set(keys.sort())];\n\t} else {\n\t\tkeys.push(makeKeys(error));\n\t}\n\tif (!error.instancePath && keys.length) {\n\t\tid += `/${keys.join(\"|\")}`;\n\t}\n\treturn { id, keys, message };\n};\n\nconst makeKeys = (error) => {\n\t// deps groups columns that are related in anyOf/oneOf.\n\t/* error.params.deps ?? */\n\treturn (\n\t\terror.params.missingProperty ||\n\t\terror.params.additionalProperty ||\n\t\terror.instancePath.replace(\"/\", \"\")\n\t);\n};\n\nexport default validateStream;\n"],
"mappings": "AAAA,SAAS,6BAA6B;AACtC,SAAS,eAAe;AAExB,MAAM,cAAc;AAAA,EACnB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA;AACX;AAIO,MAAM,kBAAkB,CAAC,QAAQ,eAAe;AACtD,QAAM,UAAU,EAAE,GAAG,aAAa,GAAG,WAAW;AAChD,SAAO,QAAQ,QAAQ,OAAO;AAC/B;AAEO,MAAM,iBAAiB,CAC7B,EAAE,QAAQ,UAAU,gBAAgB,kBAAkB,UAAU,GAChE,gBAAgB,CAAC,MACb;AACJ,eAAa;AAEb,MAAI,OAAO,WAAW,YAAY;AACjC,aAAS,gBAAgB,MAAM;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC;AACf,MAAI,MAAM,WAAW;AACrB,QAAM,YAAY,CAAC,OAAO,YAAY;AACrC,WAAO;AACP,UAAM,OAAO,gBAAgB,KAAK;AAClC,UAAM,aAAa,OAAO,KAAK;AAC/B,QAAI,CAAC,YAAY;AAChB,iBAAW,SAAS,OAAO,QAAQ;AAClC,cAAM,EAAE,IAAI,MAAM,QAAQ,IAAI,aAAa,KAAK;AAEhD,YAAI,CAAC,MAAM,EAAE,GAAG;AACf,gBAAM,EAAE,IAAI,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,QAC1C;AACA,cAAM,EAAE,EAAE,IAAI,KAAK,GAAG;AAAA,MACvB;AAAA,IACD;AACA,QAAI,cAAc,gBAAgB;AACjC,cAAQ,mBAAmB,QAAQ;AACnC,cAAQ,KAAK;AAAA,IACd;AAAA,EACD;AACA,QAAM,SAAS,sBAAsB,WAAW,aAAa;AAC7D,SAAO,SAAS,OAAO,EAAE,KAAK,aAAa,YAAY,MAAM;AAC7D,SAAO;AACR;AAEA,MAAM,eAAe,CAAC,UAAU;AAC/B,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,KAAK,MAAM;AAEf,MAAI,OAAO,CAAC;AACZ,MAAI,MAAM,YAAY,gBAAgB;AACrC,UAAM,OAAO,OAAO,QAAQ,CAACA,WAAU;AACtC,YAAM,QAAQ,SAASA,MAAK;AAC5B,UAAI,MAAO,MAAK,KAAK,KAAK;AAAA,IAC3B,CAAC;AACD,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,EAChC,OAAO;AACN,SAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EAC1B;AACA,MAAI,CAAC,MAAM,gBAAgB,KAAK,QAAQ;AACvC,UAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EACzB;AACA,SAAO,EAAE,IAAI,MAAM,QAAQ;AAC5B;AAEA,MAAM,WAAW,CAAC,UAAU;AAG3B,SACC,MAAM,OAAO,mBACb,MAAM,OAAO,sBACb,MAAM,aAAa,QAAQ,KAAK,EAAE;AAEpC;AAEA,IAAO,gBAAQ;",
"sourcesContent": ["// Copyright 2026 will Farrell, and datastream contributors.\n// SPDX-License-Identifier: MIT\nimport { createTransformStream } from \"@datastream/core\";\nimport { compile } from \"ajv-cmd\";\n\nconst ajvDefaults = {\n\tstrict: true,\n\tcoerceTypes: true,\n\tallErrors: true,\n\tuseDefaults: \"empty\",\n\tmessages: true, // needs to be true to allow multi-locale errorMessage to work\n};\n\n// This is pulled out due to it's performance cost (50-100ms on cold start)\n// Precompile your schema during a build step is recommended.\nexport const transpileSchema = (schema, ajvOptions) => {\n\tconst options = { ...ajvDefaults, ...ajvOptions };\n\treturn compile(schema, options);\n};\n\nexport const validateStream = (\n\t{ schema, idxStart, onErrorEnqueue, allowCoerceTypes, resultKey },\n\tstreamOptions = {},\n) => {\n\tidxStart ??= 0;\n\n\tif (typeof schema !== \"function\") {\n\t\tschema = transpileSchema(schema);\n\t}\n\n\tconst value = {}; // aka errors\n\tlet idx = idxStart - 1;\n\tconst transform = (chunk, enqueue) => {\n\t\tidx += 1;\n\t\tconst data =\n\t\t\tallowCoerceTypes === false ? structuredClone(chunk) : undefined;\n\t\tconst chunkValid = schema(chunk);\n\t\tif (!chunkValid) {\n\t\t\tfor (const error of schema.errors) {\n\t\t\t\tconst { id, keys, message } = processError(error);\n\n\t\t\t\tif (!value[id]) {\n\t\t\t\t\tvalue[id] = { id, keys, message, idx: [] };\n\t\t\t\t}\n\t\t\t\tvalue[id].idx.push(idx);\n\t\t\t}\n\t\t}\n\t\tif (chunkValid || onErrorEnqueue) {\n\t\t\tenqueue(data ?? chunk);\n\t\t}\n\t};\n\tconst stream = createTransformStream(transform, streamOptions);\n\tstream.result = () => ({ key: resultKey ?? \"validate\", value });\n\treturn stream;\n};\n\nconst processError = (error) => {\n\tconst message = error.message || \"\";\n\n\tlet id = error.schemaPath;\n\n\tlet keys = [];\n\tif (error.keyword === \"errorMessage\") {\n\t\terror.params.errors.forEach((error) => {\n\t\t\tconst value = makeKeys(error);\n\t\t\tif (value) keys.push(value);\n\t\t});\n\t\tkeys = [...new Set(keys.sort())];\n\t} else {\n\t\tkeys.push(makeKeys(error));\n\t}\n\tif (!error.instancePath && keys.length) {\n\t\tid += `/${keys.join(\"|\")}`;\n\t}\n\treturn { id, keys, message };\n};\n\nconst makeKeys = (error) => {\n\t// deps groups columns that are related in anyOf/oneOf.\n\t/* error.params.deps ?? */\n\treturn (\n\t\terror.params.missingProperty ||\n\t\terror.params.additionalProperty ||\n\t\terror.instancePath.replace(\"/\", \"\")\n\t);\n};\n\nexport default validateStream;\n"],
"mappings": "AAEA,SAAS,6BAA6B;AACtC,SAAS,eAAe;AAExB,MAAM,cAAc;AAAA,EACnB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA;AACX;AAIO,MAAM,kBAAkB,CAAC,QAAQ,eAAe;AACtD,QAAM,UAAU,EAAE,GAAG,aAAa,GAAG,WAAW;AAChD,SAAO,QAAQ,QAAQ,OAAO;AAC/B;AAEO,MAAM,iBAAiB,CAC7B,EAAE,QAAQ,UAAU,gBAAgB,kBAAkB,UAAU,GAChE,gBAAgB,CAAC,MACb;AACJ,eAAa;AAEb,MAAI,OAAO,WAAW,YAAY;AACjC,aAAS,gBAAgB,MAAM;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC;AACf,MAAI,MAAM,WAAW;AACrB,QAAM,YAAY,CAAC,OAAO,YAAY;AACrC,WAAO;AACP,UAAM,OACL,qBAAqB,QAAQ,gBAAgB,KAAK,IAAI;AACvD,UAAM,aAAa,OAAO,KAAK;AAC/B,QAAI,CAAC,YAAY;AAChB,iBAAW,SAAS,OAAO,QAAQ;AAClC,cAAM,EAAE,IAAI,MAAM,QAAQ,IAAI,aAAa,KAAK;AAEhD,YAAI,CAAC,MAAM,EAAE,GAAG;AACf,gBAAM,EAAE,IAAI,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC,EAAE;AAAA,QAC1C;AACA,cAAM,EAAE,EAAE,IAAI,KAAK,GAAG;AAAA,MACvB;AAAA,IACD;AACA,QAAI,cAAc,gBAAgB;AACjC,cAAQ,QAAQ,KAAK;AAAA,IACtB;AAAA,EACD;AACA,QAAM,SAAS,sBAAsB,WAAW,aAAa;AAC7D,SAAO,SAAS,OAAO,EAAE,KAAK,aAAa,YAAY,MAAM;AAC7D,SAAO;AACR;AAEA,MAAM,eAAe,CAAC,UAAU;AAC/B,QAAM,UAAU,MAAM,WAAW;AAEjC,MAAI,KAAK,MAAM;AAEf,MAAI,OAAO,CAAC;AACZ,MAAI,MAAM,YAAY,gBAAgB;AACrC,UAAM,OAAO,OAAO,QAAQ,CAACA,WAAU;AACtC,YAAM,QAAQ,SAASA,MAAK;AAC5B,UAAI,MAAO,MAAK,KAAK,KAAK;AAAA,IAC3B,CAAC;AACD,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,EAChC,OAAO;AACN,SAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EAC1B;AACA,MAAI,CAAC,MAAM,gBAAgB,KAAK,QAAQ;AACvC,UAAM,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,EACzB;AACA,SAAO,EAAE,IAAI,MAAM,QAAQ;AAC5B;AAEA,MAAM,WAAW,CAAC,UAAU;AAG3B,SACC,MAAM,OAAO,mBACb,MAAM,OAAO,sBACb,MAAM,aAAa,QAAQ,KAAK,EAAE;AAEpC;AAEA,IAAO,gBAAQ;",
"names": ["error"]
}
{
"name": "@datastream/validate",
"version": "0.0.42",
"description": "",
"version": "0.1.4",
"description": "JSON Schema validation transform streams using Ajv",
"type": "module",

@@ -13,3 +13,3 @@ "engines": {

},
"main": "./index.web.mjs",
"main": "./index.node.mjs",
"module": "./index.web.mjs",

@@ -22,6 +22,2 @@ "exports": {

"default": "./index.node.mjs"
},
"__require": {
"types": "./index.d.ts",
"default": "./index.node.cjs"
}

@@ -42,3 +38,2 @@ },

"*.mjs",
"*.cjs",
"*.map",

@@ -64,3 +59,3 @@ "*.d.ts"

"url": "github:willfarrell/datastream",
"directory": "packages/digest"
"directory": "packages/validate"
},

@@ -72,7 +67,5 @@ "bugs": {

"dependencies": {
"@datastream/core": "0.0.42",
"@datastream/validate": "0.0.42",
"ajv-cmd": "0.8.1"
},
"gitHead": "6ddc0fadabf5f3702a51aebae1fc6b252c6ae8d4"
"@datastream/core": "0.1.4",
"ajv-cmd": "0.8.2"
}
}