From d9c7ef7ebd888c2fbb7e50ae02100e439761dfed Mon Sep 17 00:00:00 2001 From: Peter Leonov Date: Sat, 27 Jun 2026 21:44:23 +0200 Subject: [PATCH 1/3] Standalone datatype-parser as a workspace package + RowBinary header compiler prototype (#893) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Brings the standalone ClickHouse data-type parser into the npm workspace and prototypes a compiler that turns a `RowBinaryWithNamesAndTypes` header into a stream reader. ### Workspace integration - Link `@clickhouse/datatype-parser` into the npm workspace (shared root install/lockfile, `lint`/`typecheck`/`build` scripts, eslint config matching the other packages). - Relocate the TS parser to `packages/datatype-parser` alongside the other packages; the C++ source it was ported from now lives at `packages/datatype-parser/reference-cpp-extracted-parser`. - Fix path references (README link, `repository.directory`) and exclude the C++ reference dir from ESLint (its CMake `build/` tree emits `compiler_depend.ts` files). ### RowBinary header compiler (prototype) - New `src/compile.ts` in the rowbinary skill: read the `RowBinaryWithNamesAndTypes` header, parse each column type string into an AST via `@clickhouse/datatype-parser`, **fold the AST into a tree of combinator calls** (`readArray(readNullable(readUInt32))`, `readMap(...)`, `readTupleNamed(...)`, …), and return a reader for the rest of the stream. - No codegen/monomorphization yet — just the faithful AST → combinator fold, mirroring `readDynamicType`'s type→Reader mapping. - Offline tests with a tiny `RowBinaryWithNamesAndTypes` encoder (no server needed). ### Notes - The parser is wired into the skill as a **local `file:` dependency** (prototype-grade — the parser is not yet published to npm; this can't publish as-is). - Variant alternative ordering relies on the server normalizing alternatives to sorted-type-name order in the header type string. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- .../tests-skill-rowbinary-parser.yml | 30 + CHANGELOG.md | 5 + package-lock.json | 534 ++++++++++++++++ packages/client-common/src/index.ts | 4 +- .../client-common/src/parse/column_types.ts | 32 +- packages/client-node/src/index.ts | 2 + packages/client-web/src/index.ts | 2 + .../datatype-parser}/.gitignore | 0 .../datatype-parser}/LICENSE | 0 .../datatype-parser}/README.md | 315 +++++++++- packages/datatype-parser/bench/parse.bench.ts | 56 ++ packages/datatype-parser/eslint.config.mjs | 42 ++ .../datatype-parser}/package.json | 26 +- .../.gitignore | 0 .../CMakeLists.txt | 0 .../reference-cpp-extracted-parser}/README.md | 0 .../include/chdt/ast.h | 0 .../include/chdt/parser.h | 0 .../src/json.cpp | 0 .../src/lexer.cpp | 0 .../src/lexer.h | 0 .../src/parser.cpp | 23 +- .../test/CMakeLists.txt | 0 .../test/cases.txt | 0 .../test/cases_unsupported.txt | 0 .../test/check_unsupported.py | 0 .../test/oracle_compare.py | 0 .../tool/main.cpp | 0 .../datatype-parser}/src/ast.ts | 23 +- .../datatype-parser}/src/index.ts | 14 +- .../datatype-parser}/src/json.ts | 13 +- .../datatype-parser}/src/lexer.ts | 32 +- .../datatype-parser}/src/parser.ts | 35 +- .../datatype-parser}/test/candidates.txt | 0 .../datatype-parser}/test/cases.ts | 0 .../datatype-parser}/test/cases.txt | 0 .../test/cases_unsupported.txt | 6 + .../test/check_unsupported.ts | 0 .../test/non_instantiable.txt | 0 .../datatype-parser}/test/oracle.ts | 0 .../datatype-parser}/test/oracle_compare.ts | 0 packages/datatype-parser/test/parser.test.ts | 160 +++++ .../datatype-parser}/test/snapshot.test.ts | 40 +- .../datatype-parser}/test/snapshots.ts | 0 .../test/snapshots/00b95dd2fc4a3cb1.json | 0 .../test/snapshots/00ce7d22d518eb3d.json | 0 .../test/snapshots/01dc6abd5a2822d1.json | 0 .../test/snapshots/0282a2e2726b5fdb.json | 0 .../test/snapshots/02bdf07c09cc39a9.json | 0 .../test/snapshots/03f2221a84fa9cb6.json | 0 .../test/snapshots/05b87974a3b9b844.json | 0 .../test/snapshots/06083c5d1e0fb4b0.json | 0 .../test/snapshots/0630ca3355f050df.json | 0 .../test/snapshots/069c4db0034b51e1.json | 0 .../test/snapshots/07a4cee5695b7794.json | 0 .../test/snapshots/07a608893061fe06.json | 0 .../test/snapshots/08512f086f95145c.json | 0 .../test/snapshots/097274c5c7abaa17.json | 0 .../test/snapshots/0a450823c46ccbe3.json | 0 .../test/snapshots/0aeb95282860cfdf.json | 0 .../test/snapshots/0bed42cd6332cc16.json | 0 .../test/snapshots/0db54c89682d17c4.json | 0 .../test/snapshots/0dc646c154d2103e.json | 0 .../test/snapshots/0ee669b87ea0b36a.json | 0 .../test/snapshots/0ef4e25fc70c78ee.json | 0 .../test/snapshots/0f07cff3e8006379.json | 0 .../test/snapshots/0fe37e40e5dab3ac.json | 0 .../test/snapshots/10997dcfa0b17169.json | 0 .../test/snapshots/11d240952f22547e.json | 0 .../test/snapshots/1269b7d5dc9faecd.json | 0 .../test/snapshots/128519da85d4b5b8.json | 0 .../test/snapshots/133ca8ecd29f3663.json | 0 .../test/snapshots/156e367c7969e103.json | 0 .../test/snapshots/15ac3a2fa148ab10.json | 0 .../test/snapshots/16b2e8523343d5f3.json | 0 .../test/snapshots/16d4d882e66fffc1.json | 0 .../test/snapshots/174711b74c597654.json | 0 .../test/snapshots/1800cfa6f2c5cb5c.json | 0 .../test/snapshots/180fcbe698d0f2c4.json | 0 .../test/snapshots/183de27e0bac77a1.json | 0 .../test/snapshots/19c537c1c1730b4d.json | 0 .../test/snapshots/19e4439f2f9c5c0d.json | 0 .../test/snapshots/1a8c9516519ad655.json | 0 .../test/snapshots/1ab3503a837a8b33.json | 0 .../test/snapshots/1af429358d8dc4cc.json | 0 .../test/snapshots/1b1855ddfe121c06.json | 0 .../test/snapshots/1bd2dfcbd0545dd9.json | 0 .../test/snapshots/1c0e4bc11b79399b.json | 0 .../test/snapshots/1c6d137de6e9cce4.json | 0 .../test/snapshots/1ce04f29dadb9973.json | 0 .../test/snapshots/1d0146114b4a4362.json | 0 .../test/snapshots/1d2e38577d2a158e.json | 0 .../test/snapshots/1dc79a25ff699c42.json | 0 .../test/snapshots/1e16f998c6447325.json | 0 .../test/snapshots/20fd836cdfc11886.json | 0 .../test/snapshots/21bf75a5255af008.json | 0 .../test/snapshots/2208b0f5d5d2aea7.json | 0 .../test/snapshots/22aaa82db55ed6cb.json | 0 .../test/snapshots/22ecac851cfb07e9.json | 0 .../test/snapshots/23b36b23f947874d.json | 0 .../test/snapshots/2451237b00b13cd7.json | 0 .../test/snapshots/261b6d70eaf74bf4.json | 0 .../test/snapshots/26b32b5b966f2a05.json | 0 .../test/snapshots/283e861dc1341e3c.json | 0 .../test/snapshots/292209387fe87cb3.json | 0 .../test/snapshots/292c7af4fff95bcd.json | 0 .../test/snapshots/2a2dd538a651992b.json | 0 .../test/snapshots/2a93a144ad9458ad.json | 0 .../test/snapshots/2b759bb1ca791e18.json | 0 .../test/snapshots/2b92c8c85daf51e6.json | 0 .../test/snapshots/2bb1b10e295da6ba.json | 0 .../test/snapshots/2cad1f5221666485.json | 0 .../test/snapshots/2d0fe684054a5388.json | 0 .../test/snapshots/2d50b2d54d49e844.json | 0 .../test/snapshots/2ecf89a293cd698f.json | 0 .../test/snapshots/2f058b0d7c8ff211.json | 0 .../test/snapshots/2f446fedbc924375.json | 0 .../test/snapshots/2f76fee2db93cfc2.json | 0 .../test/snapshots/2ffb7489d68e87c9.json | 0 .../test/snapshots/30a77c9b71a45749.json | 0 .../test/snapshots/314040aa10c72b02.json | 0 .../test/snapshots/33888e8184bce3d1.json | 0 .../test/snapshots/343587b20a4bf691.json | 0 .../test/snapshots/35d5fb175bed4093.json | 0 .../test/snapshots/36af8609901f12c8.json | 0 .../test/snapshots/36c3682fea89a80a.json | 0 .../test/snapshots/3720deb1bdd5e553.json | 0 .../test/snapshots/387bc74e5d2ed508.json | 0 .../test/snapshots/388c0a082cfd7817.json | 0 .../test/snapshots/3967d5ba8569635b.json | 0 .../test/snapshots/3a8bb11d808ae810.json | 0 .../test/snapshots/3ae9dd8952516f33.json | 0 .../test/snapshots/3b330731a188b19f.json | 0 .../test/snapshots/3b7f131c8d41638e.json | 0 .../test/snapshots/3badd67bde55d4f2.json | 0 .../test/snapshots/3c4d1905119c3883.json | 0 .../test/snapshots/3ce40017fe0513c0.json | 0 .../test/snapshots/3d0564f65e2951d7.json | 0 .../test/snapshots/3d40c376159dc070.json | 0 .../test/snapshots/3df63b7acb0522da.json | 0 .../test/snapshots/3e2d739f398d42c7.json | 0 .../test/snapshots/3eb94c999f391ca9.json | 0 .../test/snapshots/401053f5f7236705.json | 0 .../test/snapshots/406c62c428cea57a.json | 0 .../test/snapshots/435de109befc994a.json | 0 .../test/snapshots/44af40134bf9392d.json | 0 .../test/snapshots/44b693037c5f8e61.json | 0 .../test/snapshots/454656691c92b81b.json | 0 .../test/snapshots/45e2c84f9ca77549.json | 0 .../test/snapshots/46e27f45db2bf7c7.json | 0 .../test/snapshots/46f8ab7c0cff9df7.json | 0 .../test/snapshots/4736033ecebeb570.json | 0 .../test/snapshots/49101d78947d3702.json | 0 .../test/snapshots/49279edf04879138.json | 0 .../test/snapshots/49718b649da090b8.json | 0 .../test/snapshots/49f72ed44502ec22.json | 0 .../test/snapshots/4b1c0b5b55c6eeae.json | 0 .../test/snapshots/4b2e0d29c996e5d4.json | 0 .../test/snapshots/4c5840cb7dad0940.json | 0 .../test/snapshots/4c7aa27b65521bcf.json | 0 .../test/snapshots/4d0c622ecdd58854.json | 0 .../test/snapshots/4dc8e18720867887.json | 0 .../test/snapshots/4e5e15828b576fc3.json | 0 .../test/snapshots/4f2b2ad192957150.json | 0 .../test/snapshots/4fe5a3682f802978.json | 0 .../test/snapshots/501529315784089e.json | 0 .../test/snapshots/503d0c06e75dd73f.json | 0 .../test/snapshots/50876ef35975fe08.json | 0 .../test/snapshots/508ec6552e77fe7d.json | 0 .../test/snapshots/5094f81299f4d418.json | 0 .../test/snapshots/51b1bf12f2eef86f.json | 0 .../test/snapshots/51db33fb52b4c790.json | 0 .../test/snapshots/52708f106b39ca6d.json | 0 .../test/snapshots/54b047d7967410c4.json | 0 .../test/snapshots/55042c80818a5432.json | 0 .../test/snapshots/55c5d81017a30edf.json | 0 .../test/snapshots/5913df984e01b049.json | 0 .../test/snapshots/5a84a5824366cfdf.json | 0 .../test/snapshots/5bee16b592d3087c.json | 0 .../test/snapshots/5c52b39b56c50f56.json | 0 .../test/snapshots/5c89edcac2811a6a.json | 0 .../test/snapshots/5e990ab2800482f2.json | 0 .../test/snapshots/6000a28977e029d9.json | 0 .../test/snapshots/620e6c17af0fec3f.json | 0 .../test/snapshots/625a100e21847dcf.json | 0 .../test/snapshots/63a53953382e5a76.json | 0 .../test/snapshots/64269f9bd268bf28.json | 0 .../test/snapshots/648be8a9b20b4068.json | 0 .../test/snapshots/64edc28811344047.json | 0 .../test/snapshots/6529f695ef6bea2b.json | 0 .../test/snapshots/65d2d849e33bbb9f.json | 0 .../test/snapshots/663699edbe8d32d0.json | 0 .../test/snapshots/663ad5af89c48643.json | 0 .../test/snapshots/66c7fbd08eb194f8.json | 0 .../test/snapshots/6760521bb1b6d98f.json | 0 .../test/snapshots/67ab5f4c86e061d7.json | 0 .../test/snapshots/6932c015a8c3a3ef.json | 0 .../test/snapshots/69a99906f5a06ea1.json | 0 .../test/snapshots/69ddba4964a41534.json | 0 .../test/snapshots/6b09d0c1e764f23a.json | 0 .../test/snapshots/6c43115b5c24bfa0.json | 0 .../test/snapshots/6c82e6dd86807ee3.json | 0 .../test/snapshots/6ddeb86eb863afac.json | 0 .../test/snapshots/6e25d9b9f79612fd.json | 0 .../test/snapshots/6e53b6c5a0f31021.json | 0 .../test/snapshots/6e5f2d68fd260298.json | 0 .../test/snapshots/6e823ebb2984559d.json | 0 .../test/snapshots/6e85b5501433e087.json | 0 .../test/snapshots/6f2851997db0584b.json | 0 .../test/snapshots/707890c2d6dfa724.json | 0 .../test/snapshots/707ef63b9e074824.json | 0 .../test/snapshots/70b4bb2684c3f896.json | 0 .../test/snapshots/710d7120fc63672d.json | 0 .../test/snapshots/711cbcac68f895ff.json | 0 .../test/snapshots/71bf56ec603bc142.json | 0 .../test/snapshots/720b7e5e0ae2603c.json | 0 .../test/snapshots/74219cbd9de3b122.json | 0 .../test/snapshots/742ae2179d57f271.json | 0 .../test/snapshots/7438a826f1a6e96c.json | 0 .../test/snapshots/75233122af88843e.json | 0 .../test/snapshots/7583403b47298bc7.json | 0 .../test/snapshots/7588be2bc0c71c3a.json | 0 .../test/snapshots/76a9f9e4cb330396.json | 0 .../test/snapshots/76b87a32829da0e0.json | 0 .../test/snapshots/76f142be038f6aaf.json | 0 .../test/snapshots/77dac08f7a014269.json | 0 .../test/snapshots/78de9c05192768a1.json | 0 .../test/snapshots/793985cddb68d46e.json | 0 .../test/snapshots/7982e8c08d84551a.json | 0 .../test/snapshots/7b2d79ca937a8cbb.json | 0 .../test/snapshots/7b35b7bce86754a4.json | 0 .../test/snapshots/7b617dda062bb685.json | 0 .../test/snapshots/7bb7347a7172ad9e.json | 0 .../test/snapshots/7bd969148ace5e13.json | 0 .../test/snapshots/7c42711aeccef61a.json | 0 .../test/snapshots/7d144c8134ca1b4f.json | 0 .../test/snapshots/7d4e42ef9d04a046.json | 0 .../test/snapshots/7d6f05e0471d0acd.json | 0 .../test/snapshots/7ee1ece2d69e227b.json | 0 .../test/snapshots/820a070e69cbeff5.json | 0 .../test/snapshots/84bafac21a924872.json | 0 .../test/snapshots/84c79425e23a4926.json | 0 .../test/snapshots/85066b2ca9c0c348.json | 0 .../test/snapshots/857895ede54a4ad7.json | 0 .../test/snapshots/85e93d199ff62047.json | 0 .../test/snapshots/863545b36296dfca.json | 0 .../test/snapshots/863c2dcdff8db25e.json | 0 .../test/snapshots/8658478ee33a4992.json | 0 .../test/snapshots/8659297c152d065c.json | 0 .../test/snapshots/88228a7e519d90de.json | 0 .../test/snapshots/88c06ce9a212e3c3.json | 0 .../test/snapshots/8911b9163c7d34f3.json | 0 .../test/snapshots/8969693adfe3e927.json | 0 .../test/snapshots/89a8eec911b3dcd7.json | 0 .../test/snapshots/8a4d871957c7159e.json | 0 .../test/snapshots/8bad118235abbed4.json | 0 .../test/snapshots/8d08253fa3dc6ea7.json | 0 .../test/snapshots/8e194457987b0af1.json | 0 .../test/snapshots/8e8232cd6a0e42ec.json | 0 .../test/snapshots/8f1113085b02958c.json | 0 .../test/snapshots/8f535b0aee7ff306.json | 0 .../test/snapshots/8fe0c11dbe0aca49.json | 0 .../test/snapshots/90885de55fed9053.json | 0 .../test/snapshots/913001e7931e5222.json | 0 .../test/snapshots/91b51f022dd84872.json | 0 .../test/snapshots/92d47d12e6852d3f.json | 0 .../test/snapshots/9430d1f0cb6846cf.json | 0 .../test/snapshots/9434ca86a34b5ff2.json | 0 .../test/snapshots/95bf560a0bb0375a.json | 0 .../test/snapshots/96ddaccf581f483c.json | 0 .../test/snapshots/98cc0e810e27c9bf.json | 0 .../test/snapshots/998fe0ecccd6998c.json | 0 .../test/snapshots/9993d2e1f4dbe182.json | 0 .../test/snapshots/9a52f34a0fcbb1da.json | 0 .../test/snapshots/9cbddfd4afa15219.json | 0 .../test/snapshots/9d618df2b0f244f4.json | 0 .../test/snapshots/9e170c7c7025a1a5.json | 0 .../test/snapshots/9f561ebcb560c871.json | 0 .../test/snapshots/9fbbc9c6e35de50d.json | 0 .../test/snapshots/a148b5c78eff3afa.json | 0 .../test/snapshots/a1b36e70b213ab9a.json | 0 .../test/snapshots/a314e0179bfc11f0.json | 0 .../test/snapshots/a3bd1284c7e4a6ab.json | 0 .../test/snapshots/a5215edb17e53ed3.json | 0 .../test/snapshots/a55e385aa7e8d7ec.json | 0 .../test/snapshots/a8b536b58d6a8ca7.json | 0 .../test/snapshots/a8dbffb1eb0d1d99.json | 0 .../test/snapshots/a95e6ce38f4ca609.json | 0 .../test/snapshots/a96d87d7c8b3dcfb.json | 0 .../test/snapshots/aa7c18e52c6fe0c3.json | 0 .../test/snapshots/ab56a84eb0f06b84.json | 0 .../test/snapshots/ab68d8e893a82cff.json | 0 .../test/snapshots/ab7266122e1f020a.json | 0 .../test/snapshots/adcc2a14fead7cd8.json | 0 .../test/snapshots/afc75d45f651500f.json | 0 .../test/snapshots/b1017bf1dd9b0fe4.json | 0 .../test/snapshots/b306956d40529bf3.json | 0 .../test/snapshots/b321ed35f3d53336.json | 0 .../test/snapshots/b4aa451e69c80088.json | 0 .../test/snapshots/b4c5e2b4273fdc60.json | 0 .../test/snapshots/b60cb032709a29a6.json | 0 .../test/snapshots/b70cb7df11aa9094.json | 0 .../test/snapshots/b734564dc378b7bd.json | 0 .../test/snapshots/b8cee90b794bb4f1.json | 0 .../test/snapshots/b96269387d602df2.json | 0 .../test/snapshots/ba328c5fc345c0f2.json | 0 .../test/snapshots/ba5c9413b0237a0c.json | 0 .../test/snapshots/bad418ae7c592db2.json | 0 .../test/snapshots/bb588ee05a3b285f.json | 0 .../test/snapshots/bbaa27c010a10469.json | 0 .../test/snapshots/bbdddd4971d19599.json | 0 .../test/snapshots/bc45bad0c8791d60.json | 0 .../test/snapshots/bd226d3d4f21c323.json | 0 .../test/snapshots/bd92f5ce619c26da.json | 0 .../test/snapshots/be25137f16c1f587.json | 0 .../test/snapshots/bf23ba5bb47b8e4e.json | 0 .../test/snapshots/c0e76a72cd8b87eb.json | 0 .../test/snapshots/c0f0cadca0773416.json | 0 .../test/snapshots/c1543d88719671aa.json | 0 .../test/snapshots/c271016d67dd8d54.json | 0 .../test/snapshots/c2ca3c43a16ca245.json | 0 .../test/snapshots/c3dc913b07d28a5b.json | 0 .../test/snapshots/c45aaac1573d8a07.json | 0 .../test/snapshots/c4605abe1a663a47.json | 0 .../test/snapshots/c4904982bc938507.json | 0 .../test/snapshots/c5a8be2409ab2f1d.json | 0 .../test/snapshots/c643b487ea6dfd72.json | 0 .../test/snapshots/c78c17175a5c0e87.json | 0 .../test/snapshots/c8093b3c6d44d486.json | 0 .../test/snapshots/c861c5ff0886a0f9.json | 0 .../test/snapshots/c86fdaa691b98f8b.json | 0 .../test/snapshots/c901bde075754bb0.json | 0 .../test/snapshots/c9f338bf38999cef.json | 0 .../test/snapshots/ca7b55d1b3b969de.json | 0 .../test/snapshots/cb3651f0a9fbe7c0.json | 0 .../test/snapshots/cbad8c51a3e1d032.json | 0 .../test/snapshots/cd98ae36981ee80a.json | 0 .../test/snapshots/cda2841ab393e45d.json | 0 .../test/snapshots/ce3bb6ac91e15082.json | 0 .../test/snapshots/ceb02f409a78f4ef.json | 0 .../test/snapshots/ceb739dfaa883916.json | 0 .../test/snapshots/cf31903898d06426.json | 0 .../test/snapshots/cf640c0ceb20ff34.json | 0 .../test/snapshots/d05fb01e0b399387.json | 0 .../test/snapshots/d3a3854ba98eb85d.json | 0 .../test/snapshots/d3e90af2aefe399f.json | 0 .../test/snapshots/d41324ffd6eed6b3.json | 0 .../test/snapshots/d62cec53886ff651.json | 0 .../test/snapshots/d64027e56b998e7c.json | 0 .../test/snapshots/d669ea9cedaeb679.json | 0 .../test/snapshots/d701a37b6e4cf4e9.json | 0 .../test/snapshots/d712296f71e49233.json | 0 .../test/snapshots/d773faf0b86ac88b.json | 0 .../test/snapshots/d8367e8f5ce1f2ca.json | 0 .../test/snapshots/d9c0ea6152fbf443.json | 0 .../test/snapshots/da0fdc28c11b5812.json | 0 .../test/snapshots/daf760a167a8047c.json | 0 .../test/snapshots/db09a2734af421e6.json | 0 .../test/snapshots/dc1e8f7f69dcbc15.json | 0 .../test/snapshots/dd0748912e59ec25.json | 0 .../test/snapshots/dd6fa4122e474566.json | 0 .../test/snapshots/de785c721705dbba.json | 0 .../test/snapshots/de86a870104fb0a5.json | 0 .../test/snapshots/dec8ddb4c2e278d9.json | 0 .../test/snapshots/df0e5006b34734de.json | 0 .../test/snapshots/df6b4430f3a214bb.json | 0 .../test/snapshots/e2102781550b6a87.json | 0 .../test/snapshots/e2227d1f14c97584.json | 0 .../test/snapshots/e227de9f1df532c1.json | 0 .../test/snapshots/e3b6ce3dbb8f6886.json | 0 .../test/snapshots/e56ae18058a93567.json | 0 .../test/snapshots/e5fa045b9b25e6db.json | 0 .../test/snapshots/e64cdc56ad4c4e02.json | 0 .../test/snapshots/e71e7bc3fe9e9f3c.json | 0 .../test/snapshots/e7eb51047d99b420.json | 0 .../test/snapshots/e83319c6c4642871.json | 0 .../test/snapshots/e89762d9c1f07a3d.json | 0 .../test/snapshots/e927c2b90a4679c4.json | 0 .../test/snapshots/e9ca4b2541b01556.json | 0 .../test/snapshots/eb0071b65f67691e.json | 0 .../test/snapshots/eb4afc85d92c38ea.json | 0 .../test/snapshots/eb9a4bc1c0c153e4.json | 0 .../test/snapshots/ed4a033a0e470779.json | 0 .../test/snapshots/ed61428e81d608b3.json | 0 .../test/snapshots/ef1ea9269b9833d2.json | 0 .../test/snapshots/effc93c8668219e9.json | 0 .../test/snapshots/f1124b0079db9585.json | 0 .../test/snapshots/f161ebdfdf2494e6.json | 0 .../test/snapshots/f1e5baf5ecc35896.json | 0 .../test/snapshots/f4753a4dee54ee10.json | 0 .../test/snapshots/f47ef5f8d16849a5.json | 0 .../test/snapshots/f4f033a85ce688b6.json | 0 .../test/snapshots/f79a28423ed1ae02.json | 0 .../test/snapshots/f8a4e52fe170a6b8.json | 0 .../test/snapshots/f9874bb3d8034d65.json | 0 .../test/snapshots/fb533649ca2f9e73.json | 0 .../test/snapshots/fca4d8d6e1593c6b.json | 0 .../test/snapshots/fcb1a5ad1920b1d8.json | 0 .../test/snapshots/fcf6d8ffa4297b9e.json | 0 .../test/snapshots/fedf5fb1af8c725d.json | 0 .../datatype-parser}/test/update_snapshots.ts | 0 .../test/validate_types_live.ts | 0 packages/datatype-parser/tsconfig.build.json | 8 + .../datatype-parser}/tsconfig.json | 10 +- packages/datatype-parser/vitest.config.ts | 12 + .../README.md | 7 + .../SKILL.md | 16 + .../package-lock.json | 15 + .../package.json | 3 + .../src/compile.ts | 318 ++++++++++ .../src/header.ts | 29 + .../src/reader.ts | 17 + .../src/rowBinaryWithNamesAndTypes.ts | 155 +++++ .../tests/compile.test.ts | 114 ++++ .../tests/readHeader.test.ts | 22 + .../rowBinaryWithNamesAndTypes.order.test.ts | 66 ++ .../tests/rowBinaryWithNamesAndTypes.test.ts | 588 ++++++++++++++++++ type-parser/mini-parser-ts/package-lock.json | 551 ---------------- .../mini-parser-ts/test/parser.test.ts | 132 ---- type-parser/mini-parser-ts/tool/main.ts | 47 -- .../mini-parser-ts/tsconfig.build.json | 5 - 421 files changed, 2674 insertions(+), 835 deletions(-) rename {type-parser/mini-parser-ts => packages/datatype-parser}/.gitignore (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/LICENSE (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/README.md (57%) create mode 100644 packages/datatype-parser/bench/parse.bench.ts create mode 100644 packages/datatype-parser/eslint.config.mjs rename {type-parser/mini-parser-ts => packages/datatype-parser}/package.json (70%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/.gitignore (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/CMakeLists.txt (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/README.md (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/include/chdt/ast.h (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/include/chdt/parser.h (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/src/json.cpp (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/src/lexer.cpp (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/src/lexer.h (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/src/parser.cpp (93%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/test/CMakeLists.txt (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/test/cases.txt (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/test/cases_unsupported.txt (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/test/check_unsupported.py (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/test/oracle_compare.py (100%) rename {type-parser/mini-parser-extracted => packages/datatype-parser/reference-cpp-extracted-parser}/tool/main.cpp (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/src/ast.ts (74%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/src/index.ts (57%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/src/json.ts (91%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/src/lexer.ts (89%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/src/parser.ts (89%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/candidates.txt (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/cases.ts (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/cases.txt (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/cases_unsupported.txt (54%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/check_unsupported.ts (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/non_instantiable.txt (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/oracle.ts (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/oracle_compare.ts (100%) create mode 100644 packages/datatype-parser/test/parser.test.ts rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshot.test.ts (53%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots.ts (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/00b95dd2fc4a3cb1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/00ce7d22d518eb3d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/01dc6abd5a2822d1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0282a2e2726b5fdb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/02bdf07c09cc39a9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/03f2221a84fa9cb6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/05b87974a3b9b844.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/06083c5d1e0fb4b0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0630ca3355f050df.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/069c4db0034b51e1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/07a4cee5695b7794.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/07a608893061fe06.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/08512f086f95145c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/097274c5c7abaa17.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0a450823c46ccbe3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0aeb95282860cfdf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0bed42cd6332cc16.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0db54c89682d17c4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0dc646c154d2103e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0ee669b87ea0b36a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0ef4e25fc70c78ee.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0f07cff3e8006379.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/0fe37e40e5dab3ac.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/10997dcfa0b17169.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/11d240952f22547e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1269b7d5dc9faecd.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/128519da85d4b5b8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/133ca8ecd29f3663.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/156e367c7969e103.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/15ac3a2fa148ab10.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/16b2e8523343d5f3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/16d4d882e66fffc1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/174711b74c597654.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1800cfa6f2c5cb5c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/180fcbe698d0f2c4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/183de27e0bac77a1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/19c537c1c1730b4d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/19e4439f2f9c5c0d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1a8c9516519ad655.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1ab3503a837a8b33.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1af429358d8dc4cc.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1b1855ddfe121c06.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1bd2dfcbd0545dd9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1c0e4bc11b79399b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1c6d137de6e9cce4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1ce04f29dadb9973.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1d0146114b4a4362.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1d2e38577d2a158e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1dc79a25ff699c42.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/1e16f998c6447325.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/20fd836cdfc11886.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/21bf75a5255af008.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2208b0f5d5d2aea7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/22aaa82db55ed6cb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/22ecac851cfb07e9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/23b36b23f947874d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2451237b00b13cd7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/261b6d70eaf74bf4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/26b32b5b966f2a05.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/283e861dc1341e3c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/292209387fe87cb3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/292c7af4fff95bcd.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2a2dd538a651992b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2a93a144ad9458ad.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2b759bb1ca791e18.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2b92c8c85daf51e6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2bb1b10e295da6ba.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2cad1f5221666485.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2d0fe684054a5388.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2d50b2d54d49e844.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2ecf89a293cd698f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2f058b0d7c8ff211.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2f446fedbc924375.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2f76fee2db93cfc2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/2ffb7489d68e87c9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/30a77c9b71a45749.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/314040aa10c72b02.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/33888e8184bce3d1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/343587b20a4bf691.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/35d5fb175bed4093.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/36af8609901f12c8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/36c3682fea89a80a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3720deb1bdd5e553.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/387bc74e5d2ed508.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/388c0a082cfd7817.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3967d5ba8569635b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3a8bb11d808ae810.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3ae9dd8952516f33.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3b330731a188b19f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3b7f131c8d41638e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3badd67bde55d4f2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3c4d1905119c3883.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3ce40017fe0513c0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3d0564f65e2951d7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3d40c376159dc070.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3df63b7acb0522da.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3e2d739f398d42c7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/3eb94c999f391ca9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/401053f5f7236705.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/406c62c428cea57a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/435de109befc994a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/44af40134bf9392d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/44b693037c5f8e61.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/454656691c92b81b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/45e2c84f9ca77549.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/46e27f45db2bf7c7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/46f8ab7c0cff9df7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4736033ecebeb570.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/49101d78947d3702.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/49279edf04879138.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/49718b649da090b8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/49f72ed44502ec22.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4b1c0b5b55c6eeae.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4b2e0d29c996e5d4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4c5840cb7dad0940.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4c7aa27b65521bcf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4d0c622ecdd58854.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4dc8e18720867887.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4e5e15828b576fc3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4f2b2ad192957150.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/4fe5a3682f802978.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/501529315784089e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/503d0c06e75dd73f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/50876ef35975fe08.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/508ec6552e77fe7d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5094f81299f4d418.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/51b1bf12f2eef86f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/51db33fb52b4c790.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/52708f106b39ca6d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/54b047d7967410c4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/55042c80818a5432.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/55c5d81017a30edf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5913df984e01b049.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5a84a5824366cfdf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5bee16b592d3087c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5c52b39b56c50f56.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5c89edcac2811a6a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/5e990ab2800482f2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6000a28977e029d9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/620e6c17af0fec3f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/625a100e21847dcf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/63a53953382e5a76.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/64269f9bd268bf28.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/648be8a9b20b4068.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/64edc28811344047.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6529f695ef6bea2b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/65d2d849e33bbb9f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/663699edbe8d32d0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/663ad5af89c48643.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/66c7fbd08eb194f8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6760521bb1b6d98f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/67ab5f4c86e061d7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6932c015a8c3a3ef.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/69a99906f5a06ea1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/69ddba4964a41534.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6b09d0c1e764f23a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6c43115b5c24bfa0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6c82e6dd86807ee3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6ddeb86eb863afac.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6e25d9b9f79612fd.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6e53b6c5a0f31021.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6e5f2d68fd260298.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6e823ebb2984559d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6e85b5501433e087.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/6f2851997db0584b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/707890c2d6dfa724.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/707ef63b9e074824.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/70b4bb2684c3f896.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/710d7120fc63672d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/711cbcac68f895ff.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/71bf56ec603bc142.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/720b7e5e0ae2603c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/74219cbd9de3b122.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/742ae2179d57f271.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7438a826f1a6e96c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/75233122af88843e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7583403b47298bc7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7588be2bc0c71c3a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/76a9f9e4cb330396.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/76b87a32829da0e0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/76f142be038f6aaf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/77dac08f7a014269.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/78de9c05192768a1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/793985cddb68d46e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7982e8c08d84551a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7b2d79ca937a8cbb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7b35b7bce86754a4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7b617dda062bb685.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7bb7347a7172ad9e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7bd969148ace5e13.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7c42711aeccef61a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7d144c8134ca1b4f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7d4e42ef9d04a046.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7d6f05e0471d0acd.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/7ee1ece2d69e227b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/820a070e69cbeff5.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/84bafac21a924872.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/84c79425e23a4926.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/85066b2ca9c0c348.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/857895ede54a4ad7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/85e93d199ff62047.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/863545b36296dfca.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/863c2dcdff8db25e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8658478ee33a4992.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8659297c152d065c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/88228a7e519d90de.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/88c06ce9a212e3c3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8911b9163c7d34f3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8969693adfe3e927.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/89a8eec911b3dcd7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8a4d871957c7159e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8bad118235abbed4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8d08253fa3dc6ea7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8e194457987b0af1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8e8232cd6a0e42ec.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8f1113085b02958c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8f535b0aee7ff306.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/8fe0c11dbe0aca49.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/90885de55fed9053.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/913001e7931e5222.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/91b51f022dd84872.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/92d47d12e6852d3f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9430d1f0cb6846cf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9434ca86a34b5ff2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/95bf560a0bb0375a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/96ddaccf581f483c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/98cc0e810e27c9bf.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/998fe0ecccd6998c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9993d2e1f4dbe182.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9a52f34a0fcbb1da.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9cbddfd4afa15219.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9d618df2b0f244f4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9e170c7c7025a1a5.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9f561ebcb560c871.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/9fbbc9c6e35de50d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a148b5c78eff3afa.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a1b36e70b213ab9a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a314e0179bfc11f0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a3bd1284c7e4a6ab.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a5215edb17e53ed3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a55e385aa7e8d7ec.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a8b536b58d6a8ca7.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a8dbffb1eb0d1d99.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a95e6ce38f4ca609.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/a96d87d7c8b3dcfb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/aa7c18e52c6fe0c3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ab56a84eb0f06b84.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ab68d8e893a82cff.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ab7266122e1f020a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/adcc2a14fead7cd8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/afc75d45f651500f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b1017bf1dd9b0fe4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b306956d40529bf3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b321ed35f3d53336.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b4aa451e69c80088.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b4c5e2b4273fdc60.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b60cb032709a29a6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b70cb7df11aa9094.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b734564dc378b7bd.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b8cee90b794bb4f1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/b96269387d602df2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ba328c5fc345c0f2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ba5c9413b0237a0c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bad418ae7c592db2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bb588ee05a3b285f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bbaa27c010a10469.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bbdddd4971d19599.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bc45bad0c8791d60.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bd226d3d4f21c323.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bd92f5ce619c26da.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/be25137f16c1f587.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/bf23ba5bb47b8e4e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c0e76a72cd8b87eb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c0f0cadca0773416.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c1543d88719671aa.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c271016d67dd8d54.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c2ca3c43a16ca245.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c3dc913b07d28a5b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c45aaac1573d8a07.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c4605abe1a663a47.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c4904982bc938507.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c5a8be2409ab2f1d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c643b487ea6dfd72.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c78c17175a5c0e87.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c8093b3c6d44d486.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c861c5ff0886a0f9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c86fdaa691b98f8b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c901bde075754bb0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/c9f338bf38999cef.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ca7b55d1b3b969de.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cb3651f0a9fbe7c0.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cbad8c51a3e1d032.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cd98ae36981ee80a.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cda2841ab393e45d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ce3bb6ac91e15082.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ceb02f409a78f4ef.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ceb739dfaa883916.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cf31903898d06426.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/cf640c0ceb20ff34.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d05fb01e0b399387.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d3a3854ba98eb85d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d3e90af2aefe399f.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d41324ffd6eed6b3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d62cec53886ff651.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d64027e56b998e7c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d669ea9cedaeb679.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d701a37b6e4cf4e9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d712296f71e49233.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d773faf0b86ac88b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d8367e8f5ce1f2ca.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/d9c0ea6152fbf443.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/da0fdc28c11b5812.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/daf760a167a8047c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/db09a2734af421e6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/dc1e8f7f69dcbc15.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/dd0748912e59ec25.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/dd6fa4122e474566.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/de785c721705dbba.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/de86a870104fb0a5.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/dec8ddb4c2e278d9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/df0e5006b34734de.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/df6b4430f3a214bb.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e2102781550b6a87.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e2227d1f14c97584.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e227de9f1df532c1.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e3b6ce3dbb8f6886.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e56ae18058a93567.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e5fa045b9b25e6db.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e64cdc56ad4c4e02.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e71e7bc3fe9e9f3c.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e7eb51047d99b420.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e83319c6c4642871.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e89762d9c1f07a3d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e927c2b90a4679c4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/e9ca4b2541b01556.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/eb0071b65f67691e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/eb4afc85d92c38ea.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/eb9a4bc1c0c153e4.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ed4a033a0e470779.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ed61428e81d608b3.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/ef1ea9269b9833d2.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/effc93c8668219e9.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f1124b0079db9585.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f161ebdfdf2494e6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f1e5baf5ecc35896.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f4753a4dee54ee10.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f47ef5f8d16849a5.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f4f033a85ce688b6.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f79a28423ed1ae02.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f8a4e52fe170a6b8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/f9874bb3d8034d65.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/fb533649ca2f9e73.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/fca4d8d6e1593c6b.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/fcb1a5ad1920b1d8.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/fcf6d8ffa4297b9e.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/snapshots/fedf5fb1af8c725d.json (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/update_snapshots.ts (100%) rename {type-parser/mini-parser-ts => packages/datatype-parser}/test/validate_types_live.ts (100%) create mode 100644 packages/datatype-parser/tsconfig.build.json rename {type-parser/mini-parser-ts => packages/datatype-parser}/tsconfig.json (66%) create mode 100644 packages/datatype-parser/vitest.config.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/src/compile.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/src/header.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/src/rowBinaryWithNamesAndTypes.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/tests/compile.test.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/tests/readHeader.test.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.order.test.ts create mode 100644 skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.test.ts delete mode 100644 type-parser/mini-parser-ts/package-lock.json delete mode 100644 type-parser/mini-parser-ts/test/parser.test.ts delete mode 100644 type-parser/mini-parser-ts/tool/main.ts delete mode 100644 type-parser/mini-parser-ts/tsconfig.build.json diff --git a/.github/workflows/tests-skill-rowbinary-parser.yml b/.github/workflows/tests-skill-rowbinary-parser.yml index 16aaccd26..3d73384a2 100644 --- a/.github/workflows/tests-skill-rowbinary-parser.yml +++ b/.github/workflows/tests-skill-rowbinary-parser.yml @@ -9,10 +9,14 @@ on: paths: - .github/workflows/tests-skill-rowbinary-parser.yml - skills/clickhouse-js-node-rowbinary-parser/** + # The skill depends on @clickhouse/datatype-parser; rerun against local + # parser changes so a parser regression cannot pass this suite unnoticed. + - packages/datatype-parser/** pull_request: paths: - .github/workflows/tests-skill-rowbinary-parser.yml - skills/clickhouse-js-node-rowbinary-parser/** + - packages/datatype-parser/** concurrency: group: "${{ github.workflow }}-${{ github.ref }}" @@ -33,9 +37,22 @@ jobs: with: node-version: 24 + # Build + pack the in-repo @clickhouse/datatype-parser so the skill is + # exercised against THIS checkout, not the version published to npm. The + # committed package.json keeps a published range for end users; we only + # override node_modules below (`npm install --no-save`). + - name: Pack local @clickhouse/datatype-parser + working-directory: ${{ github.workspace }} + run: | + npm ci + npm pack --workspace @clickhouse/datatype-parser --pack-destination "${{ runner.temp }}" + - name: Install dependencies run: npm ci + - name: Use the local datatype-parser build + run: npm install "${{ runner.temp }}"/clickhouse-datatype-parser-*.tgz --no-save + - name: Typecheck run: npm run typecheck @@ -68,8 +85,21 @@ jobs: with: node-version: ${{ matrix.node }} + # Build + pack the in-repo @clickhouse/datatype-parser so the skill is + # exercised against THIS checkout, not the version published to npm. The + # committed package.json keeps a published range for end users; we only + # override node_modules below (`npm install --no-save`). + - name: Pack local @clickhouse/datatype-parser + working-directory: ${{ github.workspace }} + run: | + npm ci + npm pack --workspace @clickhouse/datatype-parser --pack-destination "${{ runner.temp }}" + - name: Install dependencies run: npm ci + - name: Use the local datatype-parser build + run: npm install "${{ runner.temp }}"/clickhouse-datatype-parser-*.tgz --no-save + - name: Run unit tests run: npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index ccdeac5f2..096ef7c1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,14 @@ - The `@clickhouse/client-common` package is deprecated. `@clickhouse/client` (Node.js) and `@clickhouse/client-web` (Web) no longer depend on it; the shared code is now bundled into each client package. Everything previously importable from `@clickhouse/client-common` should be imported from `@clickhouse/client` or `@clickhouse/client-web` instead. The `@clickhouse/client-common` package itself will no longer receive updates. ([#845]) +- The `parseColumnType` function and its `SimpleColumnTypes` companion (exported from `@clickhouse/client`, `@clickhouse/client-web`, and `@clickhouse/client-common`) are deprecated and slated for removal in a future major version. They are superseded by the new standalone [`@clickhouse/datatype-parser`](https://www.npmjs.com/package/@clickhouse/datatype-parser) package (`parseDataType` plus its `Node` AST), which parses the full ClickHouse data-type grammar and emits an AST that mirrors the server's. ([#893]) + ## New features - (Node.js) Added a RowBinary reader library and agent skill under [`skills/clickhouse-js-node-rowbinary-parser`](./skills/clickhouse-js-node-rowbinary-parser). It ships type-specific, monomorphizable building blocks for decoding `RowBinary` / `RowBinaryWithNames` / `RowBinaryWithNamesAndTypes` streams (full-buffer and chunked), plus a skill that guides an agent to generate bespoke high-performance parsers from a query's column types. The skill is bundled into `@clickhouse/client` (registered in `agents.skills`) and is also published independently as the [`@clickhouse/rowbinary`](https://www.npmjs.com/package/@clickhouse/rowbinary) package. A matching RowBinary writer is planned. ([#864]) +- Published the [`@clickhouse/datatype-parser`](https://www.npmjs.com/package/@clickhouse/datatype-parser) package: a small, dependency-free standalone parser for ClickHouse data-type strings (the kind sent in the types row of `RowBinaryWithNamesAndTypes`, e.g. `Array(Nullable(UInt64))`, `Tuple(a UInt8, b String)`, `Enum8('a' = 1)`). It is a faithful port of the server's `ParserDataType` and emits a JSON AST that is byte-identical to the server's `EXPLAIN AST json = 1` data-type subtree. It supersedes the deprecated `parseColumnType` (see Migration Notes). ([#893]) + - (Node.js, `@experimental`) Added an additive `connection?: Connection` option to `createClient` that lets a caller plug an externally-built backend `Connection`-like object in place of the default HTTP(S) factory. Only supposed to be used for testing the `chDB` integration. ([#879]) - Added `ClickHouseSettingsInterface`, a package-neutral structural counterpart to `ClickHouseSettings`, exported from `@clickhouse/client`, `@clickhouse/client-web`, and `@clickhouse/client-common`. It is identical to `ClickHouseSettings` except that its index signature omits `SettingsMap` (a class with a private member, which TypeScript compares nominally). Because each client package now bundles its own copy of the common module, their `ClickHouseSettings` types are mutually unassignable; `ClickHouseSettingsInterface` is structurally identical across all three packages and assignable into each package's `ClickHouseSettings`, so a consumer that shares a single settings-producing helper across both the Node.js and Web clients can type it against this one type without casts. Values typed as `SettingsMap` cannot be carried through it — use `ClickHouseSettings` if you need them. ([#889]) @@ -81,6 +85,7 @@ await client.query({ [#845]: https://github.com/ClickHouse/clickhouse-js/pull/845 [#864]: https://github.com/ClickHouse/clickhouse-js/pull/864 [#889]: https://github.com/ClickHouse/clickhouse-js/pull/889 +[#893]: https://github.com/ClickHouse/clickhouse-js/pull/893 ## Bug Fixes diff --git a/package-lock.json b/package-lock.json index eb4e6e5f0..2451c96c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -343,6 +343,10 @@ "resolved": "packages/client-web", "link": true }, + "node_modules/@clickhouse/datatype-parser": { + "resolved": "packages/datatype-parser", + "link": true + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -377,6 +381,448 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -3957,6 +4403,48 @@ "dev": true, "license": "MIT" }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6528,6 +7016,25 @@ "dev": true, "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz", + "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7211,6 +7718,33 @@ "version": "1.23.0", "license": "Apache-2.0" }, + "packages/datatype-parser": { + "name": "@clickhouse/datatype-parser", + "version": "0.1.1", + "license": "Apache-2.0", + "devDependencies": { + "tsx": "^4.22.4", + "typescript": "^5.6.0", + "vitest": "^4.0.16" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "packages/datatype-parser/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "tests/clickhouse-test-runner": { "name": "@clickhouse/clickhouse-test-runner", "version": "1.23.0", diff --git a/packages/client-common/src/index.ts b/packages/client-common/src/index.ts index 14859b37b..2a751ae7c 100644 --- a/packages/client-common/src/index.ts +++ b/packages/client-common/src/index.ts @@ -117,9 +117,9 @@ export type { JSONHandling, } from "./parse"; export { - /** @deprecated Import `SimpleColumnTypes` from `@clickhouse/client` (Node.js) or `@clickhouse/client-web` (Web) instead. Importing it from `@clickhouse/client-common` is deprecated. */ + /** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. (Also: import client APIs from `@clickhouse/client`/`@clickhouse/client-web`, not `@clickhouse/client-common`.) */ SimpleColumnTypes, - /** @deprecated Import `parseColumnType` from `@clickhouse/client` (Node.js) or `@clickhouse/client-web` (Web) instead. Importing it from `@clickhouse/client-common` is deprecated. */ + /** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. (Also: import client APIs from `@clickhouse/client`/`@clickhouse/client-web`, not `@clickhouse/client-common`.) */ parseColumnType, /** @deprecated Import `defaultJSONHandling` from `@clickhouse/client` (Node.js) or `@clickhouse/client-web` (Web) instead. Importing it from `@clickhouse/client-common` is deprecated. */ defaultJSONHandling, diff --git a/packages/client-common/src/parse/column_types.ts b/packages/client-common/src/parse/column_types.ts index 264c18558..f5de59d98 100644 --- a/packages/client-common/src/parse/column_types.ts +++ b/packages/client-common/src/parse/column_types.ts @@ -1,3 +1,4 @@ +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export class ColumnTypeParseError extends Error { readonly args: Record; constructor(message: string, args?: Record) { @@ -10,6 +11,7 @@ export class ColumnTypeParseError extends Error { } } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export const SimpleColumnTypes = [ "Bool", "UInt8", @@ -33,8 +35,10 @@ export const SimpleColumnTypes = [ "IPv4", "IPv6", ] as const; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export type SimpleColumnType = (typeof SimpleColumnTypes)[number]; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnSimple { type: "Simple"; /** Without LowCardinality and Nullable. For example: @@ -45,18 +49,21 @@ export interface ParsedColumnSimple { sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnFixedString { type: "FixedString"; sizeBytes: number; sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnDateTime { type: "DateTime"; timezone: string | null; sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnDateTime64 { type: "DateTime64"; timezone: string | null; @@ -65,6 +72,7 @@ export interface ParsedColumnDateTime64 { sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnEnum { type: "Enum"; /** Index to name */ @@ -79,19 +87,26 @@ export interface ParsedColumnEnum { * * 64 bits for precision < 19 * * 128 bits for precision < 39 * * 256 bits for precision >= 39 + * + * @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface DecimalParams { precision: number; scale: number; intSize: 32 | 64 | 128 | 256; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnDecimal { type: "Decimal"; params: DecimalParams; sourceType: string; } -/** Tuple, Array or Map itself cannot be Nullable */ +/** + * Tuple, Array or Map itself cannot be Nullable + * + * @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. + */ export interface ParsedColumnNullable { type: "Nullable"; value: @@ -107,6 +122,8 @@ export interface ParsedColumnNullable { /** Array cannot be Nullable or LowCardinality, but its value type can be. * Arrays can be multidimensional, e.g. Array(Array(Array(T))). * Arrays are allowed to have a Map as the value type. + * + * @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnArray { type: "Array"; @@ -125,7 +142,10 @@ export interface ParsedColumnArray { sourceType: string; } -/** @see https://clickhouse.com/docs/en/sql-reference/data-types/map */ +/** + * @see https://clickhouse.com/docs/en/sql-reference/data-types/map + * @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. + */ export interface ParsedColumnMap { type: "Map"; /** Possible key types: @@ -144,6 +164,7 @@ export interface ParsedColumnMap { sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export interface ParsedColumnTuple { type: "Tuple"; /** Element types are arbitrary, including Map, Array, and Tuple. */ @@ -151,6 +172,7 @@ export interface ParsedColumnTuple { sourceType: string; } +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export type ParsedColumnType = | ParsedColumnSimple | ParsedColumnEnum @@ -164,6 +186,12 @@ export type ParsedColumnType = | ParsedColumnMap; /** + * @deprecated Superseded by the standalone `@clickhouse/datatype-parser` package + * — use `parseDataType` and its `Node` AST instead. That parser is + * server-faithful and already handles the source types listed below as + * unsupported here (Geo, (Simple)AggregateFunction, Nested, JSON, Dynamic, + * Variant). Slated for removal in a future major version. + * * @experimental - incomplete, unstable API; * originally intended to be used for RowBinary/Native header parsing internally. * Currently unsupported source types: diff --git a/packages/client-node/src/index.ts b/packages/client-node/src/index.ts index 2122e1feb..638f85035 100644 --- a/packages/client-node/src/index.ts +++ b/packages/client-node/src/index.ts @@ -108,7 +108,9 @@ export const StreamableFormats = StreamableFormats_; export const StreamableJSONFormats = StreamableJSONFormats_; export const SingleDocumentJSONFormats = SingleDocumentJSONFormats_; export const RecordsJSONFormats = RecordsJSONFormats_; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export const parseColumnType = parseColumnType_; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export const SimpleColumnTypes = SimpleColumnTypes_; export const isProgressRow = isProgressRow_; export const isRow = isRow_; diff --git a/packages/client-web/src/index.ts b/packages/client-web/src/index.ts index 47c45e2ee..958bdd1da 100644 --- a/packages/client-web/src/index.ts +++ b/packages/client-web/src/index.ts @@ -107,7 +107,9 @@ export const StreamableFormats = StreamableFormats_; export const StreamableJSONFormats = StreamableJSONFormats_; export const SingleDocumentJSONFormats = SingleDocumentJSONFormats_; export const RecordsJSONFormats = RecordsJSONFormats_; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export const parseColumnType = parseColumnType_; +/** @deprecated Superseded by the `@clickhouse/datatype-parser` package (`parseDataType` + its `Node` AST); slated for removal in a future major version. */ export const SimpleColumnTypes = SimpleColumnTypes_; export const isProgressRow = isProgressRow_; export const isRow = isRow_; diff --git a/type-parser/mini-parser-ts/.gitignore b/packages/datatype-parser/.gitignore similarity index 100% rename from type-parser/mini-parser-ts/.gitignore rename to packages/datatype-parser/.gitignore diff --git a/type-parser/mini-parser-ts/LICENSE b/packages/datatype-parser/LICENSE similarity index 100% rename from type-parser/mini-parser-ts/LICENSE rename to packages/datatype-parser/LICENSE diff --git a/type-parser/mini-parser-ts/README.md b/packages/datatype-parser/README.md similarity index 57% rename from type-parser/mini-parser-ts/README.md rename to packages/datatype-parser/README.md index 1252772cc..fbee14fcc 100644 --- a/type-parser/mini-parser-ts/README.md +++ b/packages/datatype-parser/README.md @@ -1,11 +1,11 @@ -# chdt-ts — standalone ClickHouse data-type parser (TypeScript) +# @clickhouse/datatype-parser A small, self-contained TypeScript library that parses a ClickHouse **data-type string** (the kind sent in the types row of `RowBinaryWithNamesAndTypes`, e.g. `Array(Nullable(UInt64))`, `Tuple(a UInt8, b String)`, `Enum8('a' = 1)`, `Decimal(10, 2)`) into a JSON AST. -It is a faithful port of the C++ `chdt` library (see `../mini-parser-extracted`), +It is a faithful port of the C++ `chdt` library (see `./reference-cpp-extracted-parser`), which is itself extracted from the server's `ParserDataType` (`src/Parsers/ParserDataType.cpp`). It has **no runtime dependencies** — only the Node.js standard library. The JSON it emits mirrors the data-type subtree of the @@ -13,30 +13,10 @@ frozen `EXPLAIN AST json = 1` document (format **version 2**), so its output is drop-in match for what the server produces — and is **byte-identical** to the C++ parser's output across the full test corpus. -## Layout - -The module structure tracks the C++ sources one-to-one: - -| TypeScript | ported from (C++) | role | -| --------------- | ----------------------------- | --------------------------------------- | -| `src/ast.ts` | `include/chdt/ast.h` | the AST node shape + `makeNode` factory | -| `src/lexer.ts` | `src/lexer.{h,cpp}` | the purpose-built tokenizer | -| `src/parser.ts` | `src/parser.cpp` + `parser.h` | the `ParserDataType::parseImpl` port | -| `src/json.ts` | `src/json.cpp` | the byte-faithful JSON serializer | -| `src/index.ts` | — | public barrel | -| `tool/main.ts` | `tool/main.cpp` | the `chdt-parse` CLI | - -The lexer and parser deliberately preserve the original control flow, branch -ordering, helper names, and `pos` save/restore points. A few signatures changed -where C++ used out-parameters (`std::string &`): `parseIdentifier` and -`decodeQuoted` return small result objects instead. - ## Install & build ```bash -npm install -npm run build # emits dist/ (JS + .d.ts) -npm run typecheck # tsc --noEmit +npm install @clickhouse/datatype-parser ``` ## Usage @@ -55,14 +35,291 @@ if (r.ok()) { } ``` -CLI (no build step needed — runs via `tsx`): +## AST + +```sql +Tuple( + id UInt64, + name LowCardinality(String), + price Decimal(18, 4), + ts DateTime64(9, 'UTC'), + tags Array(LowCardinality(Nullable(String))), + attrs Map(String, Array(Nullable(Int32))), + status Enum8('active' = 1, 'closed' = -2), + coords Array(Tuple(Float64, Float64)), + meta Nested(k String, v UInt32), + fixed FixedString(16), + dyn Dynamic(max_types = 8), + variant Variant(UInt64, String, Array(UInt8)), + raw Object('json') +) +``` -```bash -npm run parse -- "Array(Nullable(UInt64))" -echo "Enum8('a' = 1, 'b' = 2)" | npm run parse +```json +{ + "type": "TupleDataType", + "name": "Tuple", + "arguments": [ + { + "type": "DataType", + "name": "UInt64" + }, + { + "type": "DataType", + "name": "LowCardinality", + "arguments": [ + { + "type": "DataType", + "name": "String" + } + ] + }, + { + "type": "DataType", + "name": "Decimal", + "arguments": [ + { + "type": "Literal", + "value_type": "UInt64", + "value": "18" + }, + { + "type": "Literal", + "value_type": "UInt64", + "value": "4" + } + ] + }, + { + "type": "DataType", + "name": "DateTime64", + "arguments": [ + { + "type": "Literal", + "value_type": "UInt64", + "value": "9" + }, + { + "type": "Literal", + "value_type": "String", + "value": "UTC" + } + ] + }, + { + "type": "DataType", + "name": "Array", + "arguments": [ + { + "type": "DataType", + "name": "LowCardinality", + "arguments": [ + { + "type": "DataType", + "name": "Nullable", + "arguments": [ + { + "type": "DataType", + "name": "String" + } + ] + } + ] + } + ] + }, + { + "type": "DataType", + "name": "Map", + "arguments": [ + { + "type": "DataType", + "name": "String" + }, + { + "type": "DataType", + "name": "Array", + "arguments": [ + { + "type": "DataType", + "name": "Nullable", + "arguments": [ + { + "type": "DataType", + "name": "Int32" + } + ] + } + ] + } + ] + }, + { + "type": "EnumDataType", + "name": "Enum8", + "values": [ + { + "name": "active", + "value": 1 + }, + { + "name": "closed", + "value": -2 + } + ] + }, + { + "type": "DataType", + "name": "Array", + "arguments": [ + { + "type": "TupleDataType", + "name": "Tuple", + "arguments": [ + { + "type": "DataType", + "name": "Float64" + }, + { + "type": "DataType", + "name": "Float64" + } + ] + } + ] + }, + { + "type": "DataType", + "name": "Nested", + "arguments": [ + { + "type": "NameTypePair", + "name": "k", + "data_type": { + "type": "DataType", + "name": "String" + } + }, + { + "type": "NameTypePair", + "name": "v", + "data_type": { + "type": "DataType", + "name": "UInt32" + } + } + ] + }, + { + "type": "DataType", + "name": "FixedString", + "arguments": [ + { + "type": "Literal", + "value_type": "UInt64", + "value": "16" + } + ] + }, + { + "type": "DataType", + "name": "Dynamic", + "arguments": [ + { + "type": "Function", + "name": "equals", + "is_operator": true, + "arguments": [ + { + "type": "Identifier", + "name": "max_types" + }, + { + "type": "Literal", + "value_type": "UInt64", + "value": "8" + } + ] + } + ] + }, + { + "type": "DataType", + "name": "Variant", + "arguments": [ + { + "type": "DataType", + "name": "UInt64" + }, + { + "type": "DataType", + "name": "String" + }, + { + "type": "DataType", + "name": "Array", + "arguments": [ + { + "type": "DataType", + "name": "UInt8" + } + ] + } + ] + }, + { + "type": "DataType", + "name": "Object", + "arguments": [ + { + "type": "Literal", + "value_type": "String", + "value": "json" + } + ] + } + ], + "element_names": [ + "id", + "name", + "price", + "ts", + "tags", + "attrs", + "status", + "coords", + "meta", + "fixed", + "dyn", + "variant", + "raw" + ] +} +``` + +## Layout -# or, after `npm run build`: -node dist/tool/main.js "Tuple(a UInt8, b String)" +The module structure tracks the C++ sources one-to-one: + +| TypeScript | ported from (C++) | role | +| --------------- | ----------------------------- | --------------------------------------- | +| `src/ast.ts` | `include/chdt/ast.h` | the AST node shape + `makeNode` factory | +| `src/lexer.ts` | `src/lexer.{h,cpp}` | the purpose-built tokenizer | +| `src/parser.ts` | `src/parser.cpp` + `parser.h` | the `ParserDataType::parseImpl` port | +| `src/json.ts` | `src/json.cpp` | the byte-faithful JSON serializer | +| `src/index.ts` | — | public barrel | + +The lexer and parser deliberately preserve the original control flow, branch +ordering, helper names, and `pos` save/restore points. A few signatures changed +where C++ used out-parameters (`std::string &`): `parseIdentifier` and +`decodeQuoted` return small result objects instead. + +## Development + +```bash +npm install +npm run build # emits dist/ (JS + .d.ts) +npm run typecheck # tsc --noEmit ``` ## Output shape diff --git a/packages/datatype-parser/bench/parse.bench.ts b/packages/datatype-parser/bench/parse.bench.ts new file mode 100644 index 000000000..45aba6fde --- /dev/null +++ b/packages/datatype-parser/bench/parse.bench.ts @@ -0,0 +1,56 @@ +/** + * Vitest benchmark for {@link parseDataType}: how fast does the parser turn a + * ClickHouse type STRING into an AST? + * + * This is the cost a `RowBinaryWithNamesAndTypes` consumer pays ONCE per column + * when it compiles a reader from the header — so the numbers are "per + * column-type", not per row. Vitest/tinybench handles warmup, sampling, and the + * hz / mean / p99 reporting; each case below is one representative column shape, + * simplest → most involved. + * + * Run with `npm run bench` (`vitest bench --run`). + */ + +import { bench, describe } from "vitest"; + +import { parseDataType, toJSON } from "../src/index.ts"; + +/** Representative column types, simplest → most involved. */ +const CASES: ReadonlyArray<{ label: string; type: string; typical?: boolean }> = + [ + { label: "scalar", type: "UInt64" }, + { label: "enum", type: "Enum8('a' = 1, 'b' = 2, 'c' = 3)" }, + { label: "parametric", type: "DateTime64(3, 'UTC')" }, + { label: "low-cardinality", type: "LowCardinality(String)" }, + // A very common real-world column shape, used as the headline "typical" row. + { + label: "nullable array", + type: "Array(LowCardinality(Nullable(String)))", + typical: true, + }, + { label: "map", type: "Map(String, Array(UInt64))" }, + { + label: "wide tuple", + type: "Tuple(id UInt64, name LowCardinality(String), price Decimal(18, 4), ts DateTime64(9, 'UTC'), tags Array(LowCardinality(Nullable(String))), attrs Map(String, Array(Nullable(Int32))))", + }, + ]; + +describe("parseDataType — string → AST", () => { + for (const { label, type, typical } of CASES) { + // Guard inside the timed fn doubles as a correctness check and keeps the + // optimizer from eliding the parse (the result is observed). + bench(typical ? `${label} (typical)` : label, () => { + if (!parseDataType(type).ok()) throw new Error(`failed to parse ${type}`); + }); + } +}); + +describe("round-trip — parse + toJSON", () => { + // The full string → AST → JSON path. A header compiler does NOT do this (it + // folds the AST straight into readers), but it shows what toJSON adds. + const typical = CASES.find((c) => c.typical)!; + bench(typical.type, () => { + const r = parseDataType(typical.type); + if (r.ast) toJSON(r.ast, -1); + }); +}); diff --git a/packages/datatype-parser/eslint.config.mjs b/packages/datatype-parser/eslint.config.mjs new file mode 100644 index 000000000..844b25488 --- /dev/null +++ b/packages/datatype-parser/eslint.config.mjs @@ -0,0 +1,42 @@ +import { defineConfig } from "eslint/config"; +import { + recommendedWarnConfigs, + typescriptEslintConfig, + testFilesOverrides, +} from "../../eslint.config.base.mjs"; + +export default defineConfig( + // Recommended rule sets, downgraded to warnings (only tsc reports errors) + ...recommendedWarnConfigs, + typescriptEslintConfig(import.meta.dirname), + testFilesOverrides(), + { + // src/ is a faithful, line-by-line port of the C++ `chdt` library whose + // control flow deliberately tracks the original (see the header comment in + // src/parser.ts). Index-based loops are intentional parity with the C++ + // sources, not something to rewrite into for-of. + files: ["src/**/*.ts"], + rules: { + "@typescript-eslint/prefer-for-of": "off", + }, + }, + { + // The CLI entry point and the test/snapshot/oracle/bench harnesses are + // scripts that legitimately write to stdout/stderr. + files: ["tool/**/*.ts", "test/**/*.ts", "bench/**/*.ts"], + rules: { + "no-console": "off", + }, + }, + { + // reference-cpp-extracted-parser is the C++ source this library was ported + // from; it has no lintable TypeScript, and its CMake build/ tree generates + // `compiler_depend.ts` timestamp files that are not real TS. + ignores: [ + "dist", + "node_modules", + "eslint.config.mjs", + "reference-cpp-extracted-parser", + ], + }, +); diff --git a/type-parser/mini-parser-ts/package.json b/packages/datatype-parser/package.json similarity index 70% rename from type-parser/mini-parser-ts/package.json rename to packages/datatype-parser/package.json index a5186597a..e4fc83130 100644 --- a/type-parser/mini-parser-ts/package.json +++ b/packages/datatype-parser/package.json @@ -1,20 +1,17 @@ { "name": "@clickhouse/datatype-parser", - "version": "0.1.0", + "version": "0.1.1", "description": "Standalone ClickHouse data-type string parser — a TypeScript port of the chdt C++ library.", "license": "Apache-2.0", "type": "module", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", "exports": { ".": { - "types": "./dist/src/index.d.ts", - "import": "./dist/src/index.js" + "types": "./dist/index.d.ts", + "import": "./dist/index.js" } }, - "bin": { - "chdt-parse": "dist/tool/main.js" - }, "files": [ "dist", "README.md", @@ -27,7 +24,7 @@ "repository": { "type": "git", "url": "git+https://github.com/ClickHouse/clickhouse-js.git", - "directory": "type-parser/mini-parser-ts" + "directory": "packages/datatype-parser" }, "keywords": [ "clickhouse", @@ -42,9 +39,13 @@ "scripts": { "build": "tsc -p tsconfig.build.json", "typecheck": "tsc -p tsconfig.json --noEmit", + "lint": "eslint --max-warnings=0 .", + "lint:fix": "eslint . --fix", + "pack": "npm pack", "prepack": "npm run build", - "parse": "tsx tool/main.ts", - "test": "node --import tsx --test test/*.test.ts", + "bench": "vitest bench --run", + "test": "vitest run", + "test:watch": "vitest", "test:oracle": "tsx test/oracle_compare.ts", "test:unsupported": "tsx test/check_unsupported.ts", "snapshot:update": "tsx test/update_snapshots.ts", @@ -52,6 +53,7 @@ }, "devDependencies": { "tsx": "^4.22.4", - "typescript": "^5.6.0" + "typescript": "^5.6.0", + "vitest": "^4.0.16" } } diff --git a/type-parser/mini-parser-extracted/.gitignore b/packages/datatype-parser/reference-cpp-extracted-parser/.gitignore similarity index 100% rename from type-parser/mini-parser-extracted/.gitignore rename to packages/datatype-parser/reference-cpp-extracted-parser/.gitignore diff --git a/type-parser/mini-parser-extracted/CMakeLists.txt b/packages/datatype-parser/reference-cpp-extracted-parser/CMakeLists.txt similarity index 100% rename from type-parser/mini-parser-extracted/CMakeLists.txt rename to packages/datatype-parser/reference-cpp-extracted-parser/CMakeLists.txt diff --git a/type-parser/mini-parser-extracted/README.md b/packages/datatype-parser/reference-cpp-extracted-parser/README.md similarity index 100% rename from type-parser/mini-parser-extracted/README.md rename to packages/datatype-parser/reference-cpp-extracted-parser/README.md diff --git a/type-parser/mini-parser-extracted/include/chdt/ast.h b/packages/datatype-parser/reference-cpp-extracted-parser/include/chdt/ast.h similarity index 100% rename from type-parser/mini-parser-extracted/include/chdt/ast.h rename to packages/datatype-parser/reference-cpp-extracted-parser/include/chdt/ast.h diff --git a/type-parser/mini-parser-extracted/include/chdt/parser.h b/packages/datatype-parser/reference-cpp-extracted-parser/include/chdt/parser.h similarity index 100% rename from type-parser/mini-parser-extracted/include/chdt/parser.h rename to packages/datatype-parser/reference-cpp-extracted-parser/include/chdt/parser.h diff --git a/type-parser/mini-parser-extracted/src/json.cpp b/packages/datatype-parser/reference-cpp-extracted-parser/src/json.cpp similarity index 100% rename from type-parser/mini-parser-extracted/src/json.cpp rename to packages/datatype-parser/reference-cpp-extracted-parser/src/json.cpp diff --git a/type-parser/mini-parser-extracted/src/lexer.cpp b/packages/datatype-parser/reference-cpp-extracted-parser/src/lexer.cpp similarity index 100% rename from type-parser/mini-parser-extracted/src/lexer.cpp rename to packages/datatype-parser/reference-cpp-extracted-parser/src/lexer.cpp diff --git a/type-parser/mini-parser-extracted/src/lexer.h b/packages/datatype-parser/reference-cpp-extracted-parser/src/lexer.h similarity index 100% rename from type-parser/mini-parser-extracted/src/lexer.h rename to packages/datatype-parser/reference-cpp-extracted-parser/src/lexer.h diff --git a/type-parser/mini-parser-extracted/src/parser.cpp b/packages/datatype-parser/reference-cpp-extracted-parser/src/parser.cpp similarity index 93% rename from type-parser/mini-parser-extracted/src/parser.cpp rename to packages/datatype-parser/reference-cpp-extracted-parser/src/parser.cpp index 08f370cb8..fffb56a29 100644 --- a/type-parser/mini-parser-extracted/src/parser.cpp +++ b/packages/datatype-parser/reference-cpp-extracted-parser/src/parser.cpp @@ -474,9 +474,30 @@ class Parser } if (type() != TokenType::Number) return nullptr; + + /// The lexer only skips over a number without checking correctness (the + /// server's `Lexer` does the same: "not to parse a number or check + /// correctness, but only to skip it"). The server then rejects a + /// malformed literal when it converts the token text into a `Field`; we + /// have no such stage, so we validate here by parsing the lexeme in + /// full. Without this, a bare exponent like `1e` would be emitted + /// verbatim into a `Float64` literal's JSON `value`, yielding invalid + /// JSON (`"value":1e`). Fail loudly instead. + const std::string & text = cur().text; + char * end_ptr = nullptr; + if (cur().is_float) + std::strtod(text.c_str(), &end_ptr); + else + std::strtoull(text.c_str(), &end_ptr, 10); + if (end_ptr != text.c_str() + text.size()) + { + setHardError(cur().begin, "malformed numeric literal: '" + text + "'"); + return nullptr; + } + auto node = Node::make(NodeKind::Literal); node->value_type = cur().is_float ? "Float64" : (negative ? "Int64" : "UInt64"); - node->value = (negative ? "-" : "") + cur().text; + node->value = (negative ? "-" : "") + text; advance(); return node; } diff --git a/type-parser/mini-parser-extracted/test/CMakeLists.txt b/packages/datatype-parser/reference-cpp-extracted-parser/test/CMakeLists.txt similarity index 100% rename from type-parser/mini-parser-extracted/test/CMakeLists.txt rename to packages/datatype-parser/reference-cpp-extracted-parser/test/CMakeLists.txt diff --git a/type-parser/mini-parser-extracted/test/cases.txt b/packages/datatype-parser/reference-cpp-extracted-parser/test/cases.txt similarity index 100% rename from type-parser/mini-parser-extracted/test/cases.txt rename to packages/datatype-parser/reference-cpp-extracted-parser/test/cases.txt diff --git a/type-parser/mini-parser-extracted/test/cases_unsupported.txt b/packages/datatype-parser/reference-cpp-extracted-parser/test/cases_unsupported.txt similarity index 100% rename from type-parser/mini-parser-extracted/test/cases_unsupported.txt rename to packages/datatype-parser/reference-cpp-extracted-parser/test/cases_unsupported.txt diff --git a/type-parser/mini-parser-extracted/test/check_unsupported.py b/packages/datatype-parser/reference-cpp-extracted-parser/test/check_unsupported.py similarity index 100% rename from type-parser/mini-parser-extracted/test/check_unsupported.py rename to packages/datatype-parser/reference-cpp-extracted-parser/test/check_unsupported.py diff --git a/type-parser/mini-parser-extracted/test/oracle_compare.py b/packages/datatype-parser/reference-cpp-extracted-parser/test/oracle_compare.py similarity index 100% rename from type-parser/mini-parser-extracted/test/oracle_compare.py rename to packages/datatype-parser/reference-cpp-extracted-parser/test/oracle_compare.py diff --git a/type-parser/mini-parser-extracted/tool/main.cpp b/packages/datatype-parser/reference-cpp-extracted-parser/tool/main.cpp similarity index 100% rename from type-parser/mini-parser-extracted/tool/main.cpp rename to packages/datatype-parser/reference-cpp-extracted-parser/tool/main.cpp diff --git a/type-parser/mini-parser-ts/src/ast.ts b/packages/datatype-parser/src/ast.ts similarity index 74% rename from type-parser/mini-parser-ts/src/ast.ts rename to packages/datatype-parser/src/ast.ts index 62524bec0..a77ba6cac 100644 --- a/type-parser/mini-parser-ts/src/ast.ts +++ b/packages/datatype-parser/src/ast.ts @@ -11,15 +11,20 @@ /// to that kind populated; we mirror that exactly (rather than a discriminated /// union) so the parser port stays line-for-line faithful to the original. -export enum NodeKind { - DataType = "DataType", /// generic type: name + optional argument list - EnumDataType = "EnumDataType", /// Enum / Enum8 / Enum16 with fully explicit values - TupleDataType = "TupleDataType", /// Tuple, with optional element names - NameTypePair = "NameTypePair", /// `name Type` element of a Nested(...) - Literal = "Literal", /// numeric / string argument (e.g. Decimal(10, 2)) - Function = "Function", /// operator/function argument (e.g. `max_types = 5`) - Identifier = "Identifier", /// bare identifier argument -} +/// A plain `const` object rather than a TS `enum`, so the source is erasable +/// and runs under Node's native type-stripping (which rejects `enum`). The +/// companion type below makes `NodeKind` usable as both a value and a type, +/// exactly as the enum was. +export const NodeKind = { + DataType: "DataType", /// generic type: name + optional argument list + EnumDataType: "EnumDataType", /// Enum / Enum8 / Enum16 with fully explicit values + TupleDataType: "TupleDataType", /// Tuple, with optional element names + NameTypePair: "NameTypePair", /// `name Type` element of a Nested(...) + Literal: "Literal", /// numeric / string argument (e.g. Decimal(10, 2)) + Function: "Function", /// operator/function argument (e.g. `max_types = 5`) + Identifier: "Identifier", /// bare identifier argument +} as const; +export type NodeKind = (typeof NodeKind)[keyof typeof NodeKind]; export interface EnumValue { name: string; diff --git a/type-parser/mini-parser-ts/src/index.ts b/packages/datatype-parser/src/index.ts similarity index 57% rename from type-parser/mini-parser-ts/src/index.ts rename to packages/datatype-parser/src/index.ts index 9b725d4fe..977ea3049 100644 --- a/type-parser/mini-parser-ts/src/index.ts +++ b/packages/datatype-parser/src/index.ts @@ -6,13 +6,13 @@ /// into a JSON-serializable AST that mirrors the server's `EXPLAIN AST json = 1` /// data-type subtree (format version 2). -export { parseDataType } from "./parser.js"; -export type { ParseError, ParseResult } from "./parser.js"; +export { parseDataType } from "./parser.ts"; +export type { ParseError, ParseResult } from "./parser.ts"; -export { toJSON } from "./json.js"; +export { toJSON } from "./json.ts"; -export { NodeKind, makeNode } from "./ast.js"; -export type { Node, EnumValue } from "./ast.js"; +export { NodeKind, makeNode } from "./ast.ts"; +export type { Node, EnumValue } from "./ast.ts"; -export { tokenize, TokenType } from "./lexer.js"; -export type { Token } from "./lexer.js"; +export { tokenize, TokenType } from "./lexer.ts"; +export type { Token } from "./lexer.ts"; diff --git a/type-parser/mini-parser-ts/src/json.ts b/packages/datatype-parser/src/json.ts similarity index 91% rename from type-parser/mini-parser-ts/src/json.ts rename to packages/datatype-parser/src/json.ts index e84e59e05..a9fe3d40c 100644 --- a/type-parser/mini-parser-ts/src/json.ts +++ b/packages/datatype-parser/src/json.ts @@ -11,7 +11,18 @@ /// the `\u%04x` fallback). All bytes >= 0x20 are pushed through verbatim. At /// the end we decode the buffer back to a (byte-identical) JS string. -import { NodeKind, type Node } from "./ast.js"; +import { NodeKind, type Node } from "./ast.ts"; + +/// `TextEncoder` / `TextDecoder` are runtime globals in every environment this +/// library supports (Node >= 18 and all modern browsers), but they are not part +/// of the `ES2022` lib this package compiles against. Declare just the slice we +/// use here, rather than pulling in the whole `DOM` lib (which would leak +/// `window`/`name`/… globals into every file and could mask typos) or adding an +/// `@types/node` devDependency to an otherwise dependency-free package. +declare const TextEncoder: new () => { encode(input: string): Uint8Array }; +declare const TextDecoder: new (label?: string) => { + decode(input?: Uint8Array): string; +}; const encoder = new TextEncoder(); const decoder = new TextDecoder("utf-8"); diff --git a/type-parser/mini-parser-ts/src/lexer.ts b/packages/datatype-parser/src/lexer.ts similarity index 89% rename from type-parser/mini-parser-ts/src/lexer.ts rename to packages/datatype-parser/src/lexer.ts index 60fd50118..7b7240c56 100644 --- a/type-parser/mini-parser-ts/src/lexer.ts +++ b/packages/datatype-parser/src/lexer.ts @@ -8,20 +8,24 @@ /// /// This is a faithful TypeScript port of the original C++ lexer. -export enum TokenType { - End = "End", /// end of input - Word = "Word", /// bare identifier / keyword, e.g. UInt8, Array, SIGNED - QuotedIdent = "QuotedIdent", /// `backtick` or "double"-quoted identifier (decoded) - Number = "Number", /// numeric literal (raw text, no sign) - String = "String", /// single-quoted string literal (decoded) - OpeningParen = "OpeningParen", /// ( - ClosingParen = "ClosingParen", /// ) - Comma = "Comma", /// , - Equals = "Equals", /// = - Minus = "Minus", /// - - Dot = "Dot", /// . - Error = "Error", /// malformed token; `text` holds the message -} +/// A plain `const` object rather than a TS `enum`, so the source is erasable +/// and runs under Node's native type-stripping (which rejects `enum`). The +/// companion type below makes `TokenType` usable as both a value and a type. +export const TokenType = { + End: "End", /// end of input + Word: "Word", /// bare identifier / keyword, e.g. UInt8, Array, SIGNED + QuotedIdent: "QuotedIdent", /// `backtick` or "double"-quoted identifier (decoded) + Number: "Number", /// numeric literal (raw text, no sign) + String: "String", /// single-quoted string literal (decoded) + OpeningParen: "OpeningParen", /// ( + ClosingParen: "ClosingParen", /// ) + Comma: "Comma", /// , + Equals: "Equals", /// = + Minus: "Minus", /// - + Dot: "Dot", /// . + Error: "Error", /// malformed token; `text` holds the message +} as const; +export type TokenType = (typeof TokenType)[keyof typeof TokenType]; export interface Token { type: TokenType; diff --git a/type-parser/mini-parser-ts/src/parser.ts b/packages/datatype-parser/src/parser.ts similarity index 89% rename from type-parser/mini-parser-ts/src/parser.ts rename to packages/datatype-parser/src/parser.ts index 0a87a3af6..99b784a17 100644 --- a/type-parser/mini-parser-ts/src/parser.ts +++ b/packages/datatype-parser/src/parser.ts @@ -7,8 +7,8 @@ /// /// This is the TypeScript port of the C++ `chdt/parser.cpp`. -import { EnumValue, makeNode, Node, NodeKind } from "./ast.js"; -import { Token, tokenize, TokenType } from "./lexer.js"; +import { type EnumValue, makeNode, type Node, NodeKind } from "./ast.ts"; +import { type Token, tokenize, TokenType } from "./lexer.ts"; /// Public entry point types (ported from parser.h). export interface ParseError { @@ -62,6 +62,17 @@ function isEnumTypeUpper(u: string): boolean { return u === "ENUM" || u === "ENUM8" || u === "ENUM16"; } +/// Does `text` parse in FULL as a numeric literal — the TS equivalent of the +/// C++ `strtod` (float) / `strtoull` (integer) + end-pointer check? The lexer +/// is deliberately lenient and can hand back a half-formed lexeme such as `1e` +/// (an exponent with no digits); those must be rejected. Integer lexemes the +/// lexer emits are pure digit runs (so always valid); floats may carry a +/// malformed exponent, so the optional exponent here requires >= 1 digit. +function isFullyParsedNumber(text: string, isFloat: boolean): boolean { + if (isFloat) return /^(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/.test(text); + return /^\d+$/.test(text); +} + class Parser { private tokens: Token[]; private pos = 0; @@ -466,13 +477,31 @@ class Parser { this.advance(); } if (this.type() !== TokenType.Number) return null; + + /// The lexer only SKIPS over a number without checking correctness (the + /// server's `Lexer` does the same: "not to parse a number or check + /// correctness, but only to skip it"). The server then rejects a malformed + /// literal when it converts the token text into a `Field`; this port has no + /// such stage, so validate here by parsing the lexeme in full. Without it a + /// bare exponent like `1e` would be emitted verbatim into a `Float64` + /// literal's JSON `value`, yielding invalid JSON (`"value":1e`). Mirrors the + /// C++ `strtod` / `strtoull` + end-pointer check in `parser.cpp`. + const text = this.cur().text; + if (!isFullyParsedNumber(text, this.cur().is_float)) { + this.setHardError( + this.cur().begin, + `malformed numeric literal: '${text}'`, + ); + return null; + } + const node = makeNode(NodeKind.Literal); node.value_type = this.cur().is_float ? "Float64" : negative ? "Int64" : "UInt64"; - node.value = (negative ? "-" : "") + this.cur().text; + node.value = (negative ? "-" : "") + text; this.advance(); return node; } diff --git a/type-parser/mini-parser-ts/test/candidates.txt b/packages/datatype-parser/test/candidates.txt similarity index 100% rename from type-parser/mini-parser-ts/test/candidates.txt rename to packages/datatype-parser/test/candidates.txt diff --git a/type-parser/mini-parser-ts/test/cases.ts b/packages/datatype-parser/test/cases.ts similarity index 100% rename from type-parser/mini-parser-ts/test/cases.ts rename to packages/datatype-parser/test/cases.ts diff --git a/type-parser/mini-parser-ts/test/cases.txt b/packages/datatype-parser/test/cases.txt similarity index 100% rename from type-parser/mini-parser-ts/test/cases.txt rename to packages/datatype-parser/test/cases.txt diff --git a/type-parser/mini-parser-ts/test/cases_unsupported.txt b/packages/datatype-parser/test/cases_unsupported.txt similarity index 54% rename from type-parser/mini-parser-ts/test/cases_unsupported.txt rename to packages/datatype-parser/test/cases_unsupported.txt index cf6064272..49d01330c 100644 --- a/type-parser/mini-parser-ts/test/cases_unsupported.txt +++ b/packages/datatype-parser/test/cases_unsupported.txt @@ -5,3 +5,9 @@ AggregateFunction(1, quantiles(0.5), Float64) SimpleAggregateFunction(sum, UInt64) JSON(max_dynamic_paths = 16) JSON(a.b UInt32, SKIP x) +# Malformed numeric literals: the lexer skips over them without checking +# correctness, so they must be rejected when the lexeme is parsed into a value +# (see parseNumberLiteral). A bare exponent has no digits. +Decimal(1e, 2) +DateTime64(1e+) +Enum8('a' = 1e) diff --git a/type-parser/mini-parser-ts/test/check_unsupported.ts b/packages/datatype-parser/test/check_unsupported.ts similarity index 100% rename from type-parser/mini-parser-ts/test/check_unsupported.ts rename to packages/datatype-parser/test/check_unsupported.ts diff --git a/type-parser/mini-parser-ts/test/non_instantiable.txt b/packages/datatype-parser/test/non_instantiable.txt similarity index 100% rename from type-parser/mini-parser-ts/test/non_instantiable.txt rename to packages/datatype-parser/test/non_instantiable.txt diff --git a/type-parser/mini-parser-ts/test/oracle.ts b/packages/datatype-parser/test/oracle.ts similarity index 100% rename from type-parser/mini-parser-ts/test/oracle.ts rename to packages/datatype-parser/test/oracle.ts diff --git a/type-parser/mini-parser-ts/test/oracle_compare.ts b/packages/datatype-parser/test/oracle_compare.ts similarity index 100% rename from type-parser/mini-parser-ts/test/oracle_compare.ts rename to packages/datatype-parser/test/oracle_compare.ts diff --git a/packages/datatype-parser/test/parser.test.ts b/packages/datatype-parser/test/parser.test.ts new file mode 100644 index 000000000..bc48d1caf --- /dev/null +++ b/packages/datatype-parser/test/parser.test.ts @@ -0,0 +1,160 @@ +/// Dependency-free unit tests (no ClickHouse binary required). +/// Run with: npm test (vitest run) +/// +/// The exhaustive server-equivalence check lives in oracle_compare.ts; these +/// pin a few representative shapes and all the deliberate rejections so `npm +/// test` is meaningful on its own. + +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; + +import { describe, expect, it } from "vitest"; + +import { parseDataType, toJSON } from "../src/index.js"; +import { readCases } from "./cases.js"; + +const here = dirname(fileURLToPath(import.meta.url)); + +function json(typeStr: string): unknown { + const r = parseDataType(typeStr); + expect(r.ok(), `expected ${typeStr} to parse: ${r.error?.message}`).toBe( + true, + ); + return JSON.parse(toJSON(r.ast!)); +} + +describe("parseDataType", () => { + it("scalar type omits the arguments slot", () => { + expect(json("UInt8")).toEqual({ type: "DataType", name: "UInt8" }); + }); + + it("nested parametric type", () => { + expect(json("Array(Nullable(UInt64))")).toEqual({ + type: "DataType", + name: "Array", + arguments: [ + { + type: "DataType", + name: "Nullable", + arguments: [{ type: "DataType", name: "UInt64" }], + }, + ], + }); + }); + + it("literal arguments: 64-bit ints are JSON strings, scale is a string too", () => { + expect(json("Decimal(10, 2)")).toEqual({ + type: "DataType", + name: "Decimal", + arguments: [ + { type: "Literal", value_type: "UInt64", value: "10" }, + { type: "Literal", value_type: "UInt64", value: "2" }, + ], + }); + }); + + it("explicit enum becomes EnumDataType with numeric values", () => { + expect(json("Enum16('x' = -1, 'y' = 100)")).toEqual({ + type: "EnumDataType", + name: "Enum16", + values: [ + { name: "x", value: -1 }, + { name: "y", value: 100 }, + ], + }); + }); + + it("auto-assigned enum falls back to a generic DataType (not EnumDataType)", () => { + const v = json("Enum8('a', 'b')") as { type: string }; + expect(v.type).toBe("DataType"); + }); + + it("named tuple carries element_names", () => { + expect(json("Tuple(a UInt8, b String)")).toEqual({ + type: "TupleDataType", + name: "Tuple", + arguments: [ + { type: "DataType", name: "UInt8" }, + { type: "DataType", name: "String" }, + ], + element_names: ["a", "b"], + }); + }); + + it("unnamed tuple omits element_names", () => { + const v = json("Tuple(UInt8, String)") as Record; + expect("element_names" in v).toBe(false); + }); + + it("Dynamic(max_types = 5) parses to an equals Function argument", () => { + expect(json("Dynamic(max_types = 5)")).toEqual({ + type: "DataType", + name: "Dynamic", + arguments: [ + { + type: "Function", + name: "equals", + is_operator: true, + arguments: [ + { type: "Identifier", name: "max_types" }, + { type: "Literal", value_type: "UInt64", value: "5" }, + ], + }, + ], + }); + }); + + it("SQL-standard multi-word alias", () => { + expect(json("DOUBLE PRECISION")).toEqual({ + type: "DataType", + name: "DOUBLE PRECISION", + }); + }); + + it("compact output has no whitespace", () => { + const r = parseDataType("Array(String)"); + expect(r.ok()).toBe(true); + expect(toJSON(r.ast!, -1)).toBe( + '{"type":"DataType","name":"Array","arguments":[{"type":"DataType","name":"String"}]}', + ); + }); + + it("deliberately-unsupported types are rejected with a hard error", () => { + for (const typeStr of readCases(join(here, "cases_unsupported.txt"))) { + const r = parseDataType(typeStr); + expect(r.ok(), `expected ${typeStr} to be rejected`).toBe(false); + expect(r.error && r.error.message.length > 0).toBeTruthy(); + } + }); + + it("trailing input after a complete type is an error", () => { + const r = parseDataType("UInt8 garbage"); + expect(r.ok()).toBe(false); + expect(r.error!.message).toMatch(/trailing input/); + }); + + it("rejects a malformed numeric literal and never emits invalid JSON", () => { + /// The lexer is lenient and only skips over a number; a bare exponent + /// (`e`/`E` with no following digits) is rejected later, when + /// `parseNumberLiteral` parses the lexeme in full. Otherwise it would land + /// in a Float64 literal whose raw text is written verbatim into the JSON + /// `value`, producing invalid JSON such as `"value":1e`. + for (const typeStr of [ + "Decimal(1e, 2)", + "Decimal(1e+, 2)", + "FixedString(1e)", + ]) { + const r = parseDataType(typeStr); + expect(r.ok(), `expected ${typeStr} to be rejected`).toBe(false); + expect(r.error!.message).toMatch(/malformed numeric literal/); + } + + /// A well-formed exponent still parses, and its Float64 literal serializes + /// to valid JSON. + const good = parseDataType("Decimal(1e3, 2)"); + expect(good.ok()).toBe(true); + const out = toJSON(good.ast!); + expect(() => JSON.parse(out)).not.toThrow(); + expect(out).toContain('"value": 1e3'); + }); +}); diff --git a/type-parser/mini-parser-ts/test/snapshot.test.ts b/packages/datatype-parser/test/snapshot.test.ts similarity index 53% rename from type-parser/mini-parser-ts/test/snapshot.test.ts rename to packages/datatype-parser/test/snapshot.test.ts index 83489d708..f27a74d4a 100644 --- a/type-parser/mini-parser-ts/test/snapshot.test.ts +++ b/packages/datatype-parser/test/snapshot.test.ts @@ -6,14 +6,14 @@ /// only written when the server accepted the type AND the parser matched it, /// "parser output equals snapshot" is equivalent to "parser equals server". /// -/// Run with: npm test (node --import tsx --test test/*.test.ts) +/// Run with: npm test (vitest run) -import { strict as assert } from "node:assert"; import { existsSync, readFileSync } from "node:fs"; -import { test } from "node:test"; import { fileURLToPath } from "node:url"; import { dirname, join } from "node:path"; +import { describe, expect, it } from "vitest"; + import { canon, readCases } from "./cases.js"; import { toolDataType } from "./oracle.js"; import { snapshotPath, type Snapshot } from "./snapshots.js"; @@ -21,20 +21,22 @@ import { snapshotPath, type Snapshot } from "./snapshots.js"; const here = dirname(fileURLToPath(import.meta.url)); const cases = readCases(join(here, "cases.txt")); -test(`snapshot corpus is non-empty`, () => { - assert.ok(cases.length > 0, "cases.txt has no cases"); -}); - -for (const typeStr of cases) { - test(`matches server snapshot: ${typeStr}`, () => { - const path = snapshotPath(typeStr); - assert.ok( - existsSync(path), - `missing snapshot for ${JSON.stringify(typeStr)} — run: npm run snapshot:update -- --clickhouse `, - ); - const snap = JSON.parse(readFileSync(path, "utf8")) as Snapshot; - const expected = canon(snap.data_type); - const actual = canon(toolDataType(typeStr)); - assert.deepEqual(actual, expected); +describe("snapshot corpus", () => { + it("is non-empty", () => { + expect(cases.length, "cases.txt has no cases").toBeGreaterThan(0); }); -} + + for (const typeStr of cases) { + it(`matches server snapshot: ${typeStr}`, () => { + const path = snapshotPath(typeStr); + expect( + existsSync(path), + `missing snapshot for ${JSON.stringify(typeStr)} — run: npm run snapshot:update -- --clickhouse `, + ).toBe(true); + const snap = JSON.parse(readFileSync(path, "utf8")) as Snapshot; + const expected = canon(snap.data_type); + const actual = canon(toolDataType(typeStr)); + expect(actual).toEqual(expected); + }); + } +}); diff --git a/type-parser/mini-parser-ts/test/snapshots.ts b/packages/datatype-parser/test/snapshots.ts similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots.ts rename to packages/datatype-parser/test/snapshots.ts diff --git a/type-parser/mini-parser-ts/test/snapshots/00b95dd2fc4a3cb1.json b/packages/datatype-parser/test/snapshots/00b95dd2fc4a3cb1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/00b95dd2fc4a3cb1.json rename to packages/datatype-parser/test/snapshots/00b95dd2fc4a3cb1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/00ce7d22d518eb3d.json b/packages/datatype-parser/test/snapshots/00ce7d22d518eb3d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/00ce7d22d518eb3d.json rename to packages/datatype-parser/test/snapshots/00ce7d22d518eb3d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/01dc6abd5a2822d1.json b/packages/datatype-parser/test/snapshots/01dc6abd5a2822d1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/01dc6abd5a2822d1.json rename to packages/datatype-parser/test/snapshots/01dc6abd5a2822d1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0282a2e2726b5fdb.json b/packages/datatype-parser/test/snapshots/0282a2e2726b5fdb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0282a2e2726b5fdb.json rename to packages/datatype-parser/test/snapshots/0282a2e2726b5fdb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/02bdf07c09cc39a9.json b/packages/datatype-parser/test/snapshots/02bdf07c09cc39a9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/02bdf07c09cc39a9.json rename to packages/datatype-parser/test/snapshots/02bdf07c09cc39a9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/03f2221a84fa9cb6.json b/packages/datatype-parser/test/snapshots/03f2221a84fa9cb6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/03f2221a84fa9cb6.json rename to packages/datatype-parser/test/snapshots/03f2221a84fa9cb6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/05b87974a3b9b844.json b/packages/datatype-parser/test/snapshots/05b87974a3b9b844.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/05b87974a3b9b844.json rename to packages/datatype-parser/test/snapshots/05b87974a3b9b844.json diff --git a/type-parser/mini-parser-ts/test/snapshots/06083c5d1e0fb4b0.json b/packages/datatype-parser/test/snapshots/06083c5d1e0fb4b0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/06083c5d1e0fb4b0.json rename to packages/datatype-parser/test/snapshots/06083c5d1e0fb4b0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0630ca3355f050df.json b/packages/datatype-parser/test/snapshots/0630ca3355f050df.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0630ca3355f050df.json rename to packages/datatype-parser/test/snapshots/0630ca3355f050df.json diff --git a/type-parser/mini-parser-ts/test/snapshots/069c4db0034b51e1.json b/packages/datatype-parser/test/snapshots/069c4db0034b51e1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/069c4db0034b51e1.json rename to packages/datatype-parser/test/snapshots/069c4db0034b51e1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/07a4cee5695b7794.json b/packages/datatype-parser/test/snapshots/07a4cee5695b7794.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/07a4cee5695b7794.json rename to packages/datatype-parser/test/snapshots/07a4cee5695b7794.json diff --git a/type-parser/mini-parser-ts/test/snapshots/07a608893061fe06.json b/packages/datatype-parser/test/snapshots/07a608893061fe06.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/07a608893061fe06.json rename to packages/datatype-parser/test/snapshots/07a608893061fe06.json diff --git a/type-parser/mini-parser-ts/test/snapshots/08512f086f95145c.json b/packages/datatype-parser/test/snapshots/08512f086f95145c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/08512f086f95145c.json rename to packages/datatype-parser/test/snapshots/08512f086f95145c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/097274c5c7abaa17.json b/packages/datatype-parser/test/snapshots/097274c5c7abaa17.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/097274c5c7abaa17.json rename to packages/datatype-parser/test/snapshots/097274c5c7abaa17.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0a450823c46ccbe3.json b/packages/datatype-parser/test/snapshots/0a450823c46ccbe3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0a450823c46ccbe3.json rename to packages/datatype-parser/test/snapshots/0a450823c46ccbe3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0aeb95282860cfdf.json b/packages/datatype-parser/test/snapshots/0aeb95282860cfdf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0aeb95282860cfdf.json rename to packages/datatype-parser/test/snapshots/0aeb95282860cfdf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0bed42cd6332cc16.json b/packages/datatype-parser/test/snapshots/0bed42cd6332cc16.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0bed42cd6332cc16.json rename to packages/datatype-parser/test/snapshots/0bed42cd6332cc16.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0db54c89682d17c4.json b/packages/datatype-parser/test/snapshots/0db54c89682d17c4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0db54c89682d17c4.json rename to packages/datatype-parser/test/snapshots/0db54c89682d17c4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0dc646c154d2103e.json b/packages/datatype-parser/test/snapshots/0dc646c154d2103e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0dc646c154d2103e.json rename to packages/datatype-parser/test/snapshots/0dc646c154d2103e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0ee669b87ea0b36a.json b/packages/datatype-parser/test/snapshots/0ee669b87ea0b36a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0ee669b87ea0b36a.json rename to packages/datatype-parser/test/snapshots/0ee669b87ea0b36a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0ef4e25fc70c78ee.json b/packages/datatype-parser/test/snapshots/0ef4e25fc70c78ee.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0ef4e25fc70c78ee.json rename to packages/datatype-parser/test/snapshots/0ef4e25fc70c78ee.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0f07cff3e8006379.json b/packages/datatype-parser/test/snapshots/0f07cff3e8006379.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0f07cff3e8006379.json rename to packages/datatype-parser/test/snapshots/0f07cff3e8006379.json diff --git a/type-parser/mini-parser-ts/test/snapshots/0fe37e40e5dab3ac.json b/packages/datatype-parser/test/snapshots/0fe37e40e5dab3ac.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/0fe37e40e5dab3ac.json rename to packages/datatype-parser/test/snapshots/0fe37e40e5dab3ac.json diff --git a/type-parser/mini-parser-ts/test/snapshots/10997dcfa0b17169.json b/packages/datatype-parser/test/snapshots/10997dcfa0b17169.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/10997dcfa0b17169.json rename to packages/datatype-parser/test/snapshots/10997dcfa0b17169.json diff --git a/type-parser/mini-parser-ts/test/snapshots/11d240952f22547e.json b/packages/datatype-parser/test/snapshots/11d240952f22547e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/11d240952f22547e.json rename to packages/datatype-parser/test/snapshots/11d240952f22547e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1269b7d5dc9faecd.json b/packages/datatype-parser/test/snapshots/1269b7d5dc9faecd.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1269b7d5dc9faecd.json rename to packages/datatype-parser/test/snapshots/1269b7d5dc9faecd.json diff --git a/type-parser/mini-parser-ts/test/snapshots/128519da85d4b5b8.json b/packages/datatype-parser/test/snapshots/128519da85d4b5b8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/128519da85d4b5b8.json rename to packages/datatype-parser/test/snapshots/128519da85d4b5b8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/133ca8ecd29f3663.json b/packages/datatype-parser/test/snapshots/133ca8ecd29f3663.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/133ca8ecd29f3663.json rename to packages/datatype-parser/test/snapshots/133ca8ecd29f3663.json diff --git a/type-parser/mini-parser-ts/test/snapshots/156e367c7969e103.json b/packages/datatype-parser/test/snapshots/156e367c7969e103.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/156e367c7969e103.json rename to packages/datatype-parser/test/snapshots/156e367c7969e103.json diff --git a/type-parser/mini-parser-ts/test/snapshots/15ac3a2fa148ab10.json b/packages/datatype-parser/test/snapshots/15ac3a2fa148ab10.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/15ac3a2fa148ab10.json rename to packages/datatype-parser/test/snapshots/15ac3a2fa148ab10.json diff --git a/type-parser/mini-parser-ts/test/snapshots/16b2e8523343d5f3.json b/packages/datatype-parser/test/snapshots/16b2e8523343d5f3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/16b2e8523343d5f3.json rename to packages/datatype-parser/test/snapshots/16b2e8523343d5f3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/16d4d882e66fffc1.json b/packages/datatype-parser/test/snapshots/16d4d882e66fffc1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/16d4d882e66fffc1.json rename to packages/datatype-parser/test/snapshots/16d4d882e66fffc1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/174711b74c597654.json b/packages/datatype-parser/test/snapshots/174711b74c597654.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/174711b74c597654.json rename to packages/datatype-parser/test/snapshots/174711b74c597654.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1800cfa6f2c5cb5c.json b/packages/datatype-parser/test/snapshots/1800cfa6f2c5cb5c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1800cfa6f2c5cb5c.json rename to packages/datatype-parser/test/snapshots/1800cfa6f2c5cb5c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/180fcbe698d0f2c4.json b/packages/datatype-parser/test/snapshots/180fcbe698d0f2c4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/180fcbe698d0f2c4.json rename to packages/datatype-parser/test/snapshots/180fcbe698d0f2c4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/183de27e0bac77a1.json b/packages/datatype-parser/test/snapshots/183de27e0bac77a1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/183de27e0bac77a1.json rename to packages/datatype-parser/test/snapshots/183de27e0bac77a1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/19c537c1c1730b4d.json b/packages/datatype-parser/test/snapshots/19c537c1c1730b4d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/19c537c1c1730b4d.json rename to packages/datatype-parser/test/snapshots/19c537c1c1730b4d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/19e4439f2f9c5c0d.json b/packages/datatype-parser/test/snapshots/19e4439f2f9c5c0d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/19e4439f2f9c5c0d.json rename to packages/datatype-parser/test/snapshots/19e4439f2f9c5c0d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1a8c9516519ad655.json b/packages/datatype-parser/test/snapshots/1a8c9516519ad655.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1a8c9516519ad655.json rename to packages/datatype-parser/test/snapshots/1a8c9516519ad655.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1ab3503a837a8b33.json b/packages/datatype-parser/test/snapshots/1ab3503a837a8b33.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1ab3503a837a8b33.json rename to packages/datatype-parser/test/snapshots/1ab3503a837a8b33.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1af429358d8dc4cc.json b/packages/datatype-parser/test/snapshots/1af429358d8dc4cc.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1af429358d8dc4cc.json rename to packages/datatype-parser/test/snapshots/1af429358d8dc4cc.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1b1855ddfe121c06.json b/packages/datatype-parser/test/snapshots/1b1855ddfe121c06.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1b1855ddfe121c06.json rename to packages/datatype-parser/test/snapshots/1b1855ddfe121c06.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1bd2dfcbd0545dd9.json b/packages/datatype-parser/test/snapshots/1bd2dfcbd0545dd9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1bd2dfcbd0545dd9.json rename to packages/datatype-parser/test/snapshots/1bd2dfcbd0545dd9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1c0e4bc11b79399b.json b/packages/datatype-parser/test/snapshots/1c0e4bc11b79399b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1c0e4bc11b79399b.json rename to packages/datatype-parser/test/snapshots/1c0e4bc11b79399b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1c6d137de6e9cce4.json b/packages/datatype-parser/test/snapshots/1c6d137de6e9cce4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1c6d137de6e9cce4.json rename to packages/datatype-parser/test/snapshots/1c6d137de6e9cce4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1ce04f29dadb9973.json b/packages/datatype-parser/test/snapshots/1ce04f29dadb9973.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1ce04f29dadb9973.json rename to packages/datatype-parser/test/snapshots/1ce04f29dadb9973.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1d0146114b4a4362.json b/packages/datatype-parser/test/snapshots/1d0146114b4a4362.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1d0146114b4a4362.json rename to packages/datatype-parser/test/snapshots/1d0146114b4a4362.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1d2e38577d2a158e.json b/packages/datatype-parser/test/snapshots/1d2e38577d2a158e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1d2e38577d2a158e.json rename to packages/datatype-parser/test/snapshots/1d2e38577d2a158e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1dc79a25ff699c42.json b/packages/datatype-parser/test/snapshots/1dc79a25ff699c42.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1dc79a25ff699c42.json rename to packages/datatype-parser/test/snapshots/1dc79a25ff699c42.json diff --git a/type-parser/mini-parser-ts/test/snapshots/1e16f998c6447325.json b/packages/datatype-parser/test/snapshots/1e16f998c6447325.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/1e16f998c6447325.json rename to packages/datatype-parser/test/snapshots/1e16f998c6447325.json diff --git a/type-parser/mini-parser-ts/test/snapshots/20fd836cdfc11886.json b/packages/datatype-parser/test/snapshots/20fd836cdfc11886.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/20fd836cdfc11886.json rename to packages/datatype-parser/test/snapshots/20fd836cdfc11886.json diff --git a/type-parser/mini-parser-ts/test/snapshots/21bf75a5255af008.json b/packages/datatype-parser/test/snapshots/21bf75a5255af008.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/21bf75a5255af008.json rename to packages/datatype-parser/test/snapshots/21bf75a5255af008.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2208b0f5d5d2aea7.json b/packages/datatype-parser/test/snapshots/2208b0f5d5d2aea7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2208b0f5d5d2aea7.json rename to packages/datatype-parser/test/snapshots/2208b0f5d5d2aea7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/22aaa82db55ed6cb.json b/packages/datatype-parser/test/snapshots/22aaa82db55ed6cb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/22aaa82db55ed6cb.json rename to packages/datatype-parser/test/snapshots/22aaa82db55ed6cb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/22ecac851cfb07e9.json b/packages/datatype-parser/test/snapshots/22ecac851cfb07e9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/22ecac851cfb07e9.json rename to packages/datatype-parser/test/snapshots/22ecac851cfb07e9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/23b36b23f947874d.json b/packages/datatype-parser/test/snapshots/23b36b23f947874d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/23b36b23f947874d.json rename to packages/datatype-parser/test/snapshots/23b36b23f947874d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2451237b00b13cd7.json b/packages/datatype-parser/test/snapshots/2451237b00b13cd7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2451237b00b13cd7.json rename to packages/datatype-parser/test/snapshots/2451237b00b13cd7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/261b6d70eaf74bf4.json b/packages/datatype-parser/test/snapshots/261b6d70eaf74bf4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/261b6d70eaf74bf4.json rename to packages/datatype-parser/test/snapshots/261b6d70eaf74bf4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/26b32b5b966f2a05.json b/packages/datatype-parser/test/snapshots/26b32b5b966f2a05.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/26b32b5b966f2a05.json rename to packages/datatype-parser/test/snapshots/26b32b5b966f2a05.json diff --git a/type-parser/mini-parser-ts/test/snapshots/283e861dc1341e3c.json b/packages/datatype-parser/test/snapshots/283e861dc1341e3c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/283e861dc1341e3c.json rename to packages/datatype-parser/test/snapshots/283e861dc1341e3c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/292209387fe87cb3.json b/packages/datatype-parser/test/snapshots/292209387fe87cb3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/292209387fe87cb3.json rename to packages/datatype-parser/test/snapshots/292209387fe87cb3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/292c7af4fff95bcd.json b/packages/datatype-parser/test/snapshots/292c7af4fff95bcd.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/292c7af4fff95bcd.json rename to packages/datatype-parser/test/snapshots/292c7af4fff95bcd.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2a2dd538a651992b.json b/packages/datatype-parser/test/snapshots/2a2dd538a651992b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2a2dd538a651992b.json rename to packages/datatype-parser/test/snapshots/2a2dd538a651992b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2a93a144ad9458ad.json b/packages/datatype-parser/test/snapshots/2a93a144ad9458ad.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2a93a144ad9458ad.json rename to packages/datatype-parser/test/snapshots/2a93a144ad9458ad.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2b759bb1ca791e18.json b/packages/datatype-parser/test/snapshots/2b759bb1ca791e18.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2b759bb1ca791e18.json rename to packages/datatype-parser/test/snapshots/2b759bb1ca791e18.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2b92c8c85daf51e6.json b/packages/datatype-parser/test/snapshots/2b92c8c85daf51e6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2b92c8c85daf51e6.json rename to packages/datatype-parser/test/snapshots/2b92c8c85daf51e6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2bb1b10e295da6ba.json b/packages/datatype-parser/test/snapshots/2bb1b10e295da6ba.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2bb1b10e295da6ba.json rename to packages/datatype-parser/test/snapshots/2bb1b10e295da6ba.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2cad1f5221666485.json b/packages/datatype-parser/test/snapshots/2cad1f5221666485.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2cad1f5221666485.json rename to packages/datatype-parser/test/snapshots/2cad1f5221666485.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2d0fe684054a5388.json b/packages/datatype-parser/test/snapshots/2d0fe684054a5388.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2d0fe684054a5388.json rename to packages/datatype-parser/test/snapshots/2d0fe684054a5388.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2d50b2d54d49e844.json b/packages/datatype-parser/test/snapshots/2d50b2d54d49e844.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2d50b2d54d49e844.json rename to packages/datatype-parser/test/snapshots/2d50b2d54d49e844.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2ecf89a293cd698f.json b/packages/datatype-parser/test/snapshots/2ecf89a293cd698f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2ecf89a293cd698f.json rename to packages/datatype-parser/test/snapshots/2ecf89a293cd698f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2f058b0d7c8ff211.json b/packages/datatype-parser/test/snapshots/2f058b0d7c8ff211.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2f058b0d7c8ff211.json rename to packages/datatype-parser/test/snapshots/2f058b0d7c8ff211.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2f446fedbc924375.json b/packages/datatype-parser/test/snapshots/2f446fedbc924375.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2f446fedbc924375.json rename to packages/datatype-parser/test/snapshots/2f446fedbc924375.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2f76fee2db93cfc2.json b/packages/datatype-parser/test/snapshots/2f76fee2db93cfc2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2f76fee2db93cfc2.json rename to packages/datatype-parser/test/snapshots/2f76fee2db93cfc2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/2ffb7489d68e87c9.json b/packages/datatype-parser/test/snapshots/2ffb7489d68e87c9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/2ffb7489d68e87c9.json rename to packages/datatype-parser/test/snapshots/2ffb7489d68e87c9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/30a77c9b71a45749.json b/packages/datatype-parser/test/snapshots/30a77c9b71a45749.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/30a77c9b71a45749.json rename to packages/datatype-parser/test/snapshots/30a77c9b71a45749.json diff --git a/type-parser/mini-parser-ts/test/snapshots/314040aa10c72b02.json b/packages/datatype-parser/test/snapshots/314040aa10c72b02.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/314040aa10c72b02.json rename to packages/datatype-parser/test/snapshots/314040aa10c72b02.json diff --git a/type-parser/mini-parser-ts/test/snapshots/33888e8184bce3d1.json b/packages/datatype-parser/test/snapshots/33888e8184bce3d1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/33888e8184bce3d1.json rename to packages/datatype-parser/test/snapshots/33888e8184bce3d1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/343587b20a4bf691.json b/packages/datatype-parser/test/snapshots/343587b20a4bf691.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/343587b20a4bf691.json rename to packages/datatype-parser/test/snapshots/343587b20a4bf691.json diff --git a/type-parser/mini-parser-ts/test/snapshots/35d5fb175bed4093.json b/packages/datatype-parser/test/snapshots/35d5fb175bed4093.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/35d5fb175bed4093.json rename to packages/datatype-parser/test/snapshots/35d5fb175bed4093.json diff --git a/type-parser/mini-parser-ts/test/snapshots/36af8609901f12c8.json b/packages/datatype-parser/test/snapshots/36af8609901f12c8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/36af8609901f12c8.json rename to packages/datatype-parser/test/snapshots/36af8609901f12c8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/36c3682fea89a80a.json b/packages/datatype-parser/test/snapshots/36c3682fea89a80a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/36c3682fea89a80a.json rename to packages/datatype-parser/test/snapshots/36c3682fea89a80a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3720deb1bdd5e553.json b/packages/datatype-parser/test/snapshots/3720deb1bdd5e553.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3720deb1bdd5e553.json rename to packages/datatype-parser/test/snapshots/3720deb1bdd5e553.json diff --git a/type-parser/mini-parser-ts/test/snapshots/387bc74e5d2ed508.json b/packages/datatype-parser/test/snapshots/387bc74e5d2ed508.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/387bc74e5d2ed508.json rename to packages/datatype-parser/test/snapshots/387bc74e5d2ed508.json diff --git a/type-parser/mini-parser-ts/test/snapshots/388c0a082cfd7817.json b/packages/datatype-parser/test/snapshots/388c0a082cfd7817.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/388c0a082cfd7817.json rename to packages/datatype-parser/test/snapshots/388c0a082cfd7817.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3967d5ba8569635b.json b/packages/datatype-parser/test/snapshots/3967d5ba8569635b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3967d5ba8569635b.json rename to packages/datatype-parser/test/snapshots/3967d5ba8569635b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3a8bb11d808ae810.json b/packages/datatype-parser/test/snapshots/3a8bb11d808ae810.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3a8bb11d808ae810.json rename to packages/datatype-parser/test/snapshots/3a8bb11d808ae810.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3ae9dd8952516f33.json b/packages/datatype-parser/test/snapshots/3ae9dd8952516f33.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3ae9dd8952516f33.json rename to packages/datatype-parser/test/snapshots/3ae9dd8952516f33.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3b330731a188b19f.json b/packages/datatype-parser/test/snapshots/3b330731a188b19f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3b330731a188b19f.json rename to packages/datatype-parser/test/snapshots/3b330731a188b19f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3b7f131c8d41638e.json b/packages/datatype-parser/test/snapshots/3b7f131c8d41638e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3b7f131c8d41638e.json rename to packages/datatype-parser/test/snapshots/3b7f131c8d41638e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3badd67bde55d4f2.json b/packages/datatype-parser/test/snapshots/3badd67bde55d4f2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3badd67bde55d4f2.json rename to packages/datatype-parser/test/snapshots/3badd67bde55d4f2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3c4d1905119c3883.json b/packages/datatype-parser/test/snapshots/3c4d1905119c3883.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3c4d1905119c3883.json rename to packages/datatype-parser/test/snapshots/3c4d1905119c3883.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3ce40017fe0513c0.json b/packages/datatype-parser/test/snapshots/3ce40017fe0513c0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3ce40017fe0513c0.json rename to packages/datatype-parser/test/snapshots/3ce40017fe0513c0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3d0564f65e2951d7.json b/packages/datatype-parser/test/snapshots/3d0564f65e2951d7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3d0564f65e2951d7.json rename to packages/datatype-parser/test/snapshots/3d0564f65e2951d7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3d40c376159dc070.json b/packages/datatype-parser/test/snapshots/3d40c376159dc070.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3d40c376159dc070.json rename to packages/datatype-parser/test/snapshots/3d40c376159dc070.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3df63b7acb0522da.json b/packages/datatype-parser/test/snapshots/3df63b7acb0522da.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3df63b7acb0522da.json rename to packages/datatype-parser/test/snapshots/3df63b7acb0522da.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3e2d739f398d42c7.json b/packages/datatype-parser/test/snapshots/3e2d739f398d42c7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3e2d739f398d42c7.json rename to packages/datatype-parser/test/snapshots/3e2d739f398d42c7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/3eb94c999f391ca9.json b/packages/datatype-parser/test/snapshots/3eb94c999f391ca9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/3eb94c999f391ca9.json rename to packages/datatype-parser/test/snapshots/3eb94c999f391ca9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/401053f5f7236705.json b/packages/datatype-parser/test/snapshots/401053f5f7236705.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/401053f5f7236705.json rename to packages/datatype-parser/test/snapshots/401053f5f7236705.json diff --git a/type-parser/mini-parser-ts/test/snapshots/406c62c428cea57a.json b/packages/datatype-parser/test/snapshots/406c62c428cea57a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/406c62c428cea57a.json rename to packages/datatype-parser/test/snapshots/406c62c428cea57a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/435de109befc994a.json b/packages/datatype-parser/test/snapshots/435de109befc994a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/435de109befc994a.json rename to packages/datatype-parser/test/snapshots/435de109befc994a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/44af40134bf9392d.json b/packages/datatype-parser/test/snapshots/44af40134bf9392d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/44af40134bf9392d.json rename to packages/datatype-parser/test/snapshots/44af40134bf9392d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/44b693037c5f8e61.json b/packages/datatype-parser/test/snapshots/44b693037c5f8e61.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/44b693037c5f8e61.json rename to packages/datatype-parser/test/snapshots/44b693037c5f8e61.json diff --git a/type-parser/mini-parser-ts/test/snapshots/454656691c92b81b.json b/packages/datatype-parser/test/snapshots/454656691c92b81b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/454656691c92b81b.json rename to packages/datatype-parser/test/snapshots/454656691c92b81b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/45e2c84f9ca77549.json b/packages/datatype-parser/test/snapshots/45e2c84f9ca77549.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/45e2c84f9ca77549.json rename to packages/datatype-parser/test/snapshots/45e2c84f9ca77549.json diff --git a/type-parser/mini-parser-ts/test/snapshots/46e27f45db2bf7c7.json b/packages/datatype-parser/test/snapshots/46e27f45db2bf7c7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/46e27f45db2bf7c7.json rename to packages/datatype-parser/test/snapshots/46e27f45db2bf7c7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/46f8ab7c0cff9df7.json b/packages/datatype-parser/test/snapshots/46f8ab7c0cff9df7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/46f8ab7c0cff9df7.json rename to packages/datatype-parser/test/snapshots/46f8ab7c0cff9df7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4736033ecebeb570.json b/packages/datatype-parser/test/snapshots/4736033ecebeb570.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4736033ecebeb570.json rename to packages/datatype-parser/test/snapshots/4736033ecebeb570.json diff --git a/type-parser/mini-parser-ts/test/snapshots/49101d78947d3702.json b/packages/datatype-parser/test/snapshots/49101d78947d3702.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/49101d78947d3702.json rename to packages/datatype-parser/test/snapshots/49101d78947d3702.json diff --git a/type-parser/mini-parser-ts/test/snapshots/49279edf04879138.json b/packages/datatype-parser/test/snapshots/49279edf04879138.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/49279edf04879138.json rename to packages/datatype-parser/test/snapshots/49279edf04879138.json diff --git a/type-parser/mini-parser-ts/test/snapshots/49718b649da090b8.json b/packages/datatype-parser/test/snapshots/49718b649da090b8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/49718b649da090b8.json rename to packages/datatype-parser/test/snapshots/49718b649da090b8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/49f72ed44502ec22.json b/packages/datatype-parser/test/snapshots/49f72ed44502ec22.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/49f72ed44502ec22.json rename to packages/datatype-parser/test/snapshots/49f72ed44502ec22.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4b1c0b5b55c6eeae.json b/packages/datatype-parser/test/snapshots/4b1c0b5b55c6eeae.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4b1c0b5b55c6eeae.json rename to packages/datatype-parser/test/snapshots/4b1c0b5b55c6eeae.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4b2e0d29c996e5d4.json b/packages/datatype-parser/test/snapshots/4b2e0d29c996e5d4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4b2e0d29c996e5d4.json rename to packages/datatype-parser/test/snapshots/4b2e0d29c996e5d4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4c5840cb7dad0940.json b/packages/datatype-parser/test/snapshots/4c5840cb7dad0940.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4c5840cb7dad0940.json rename to packages/datatype-parser/test/snapshots/4c5840cb7dad0940.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4c7aa27b65521bcf.json b/packages/datatype-parser/test/snapshots/4c7aa27b65521bcf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4c7aa27b65521bcf.json rename to packages/datatype-parser/test/snapshots/4c7aa27b65521bcf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4d0c622ecdd58854.json b/packages/datatype-parser/test/snapshots/4d0c622ecdd58854.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4d0c622ecdd58854.json rename to packages/datatype-parser/test/snapshots/4d0c622ecdd58854.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4dc8e18720867887.json b/packages/datatype-parser/test/snapshots/4dc8e18720867887.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4dc8e18720867887.json rename to packages/datatype-parser/test/snapshots/4dc8e18720867887.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4e5e15828b576fc3.json b/packages/datatype-parser/test/snapshots/4e5e15828b576fc3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4e5e15828b576fc3.json rename to packages/datatype-parser/test/snapshots/4e5e15828b576fc3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4f2b2ad192957150.json b/packages/datatype-parser/test/snapshots/4f2b2ad192957150.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4f2b2ad192957150.json rename to packages/datatype-parser/test/snapshots/4f2b2ad192957150.json diff --git a/type-parser/mini-parser-ts/test/snapshots/4fe5a3682f802978.json b/packages/datatype-parser/test/snapshots/4fe5a3682f802978.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/4fe5a3682f802978.json rename to packages/datatype-parser/test/snapshots/4fe5a3682f802978.json diff --git a/type-parser/mini-parser-ts/test/snapshots/501529315784089e.json b/packages/datatype-parser/test/snapshots/501529315784089e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/501529315784089e.json rename to packages/datatype-parser/test/snapshots/501529315784089e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/503d0c06e75dd73f.json b/packages/datatype-parser/test/snapshots/503d0c06e75dd73f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/503d0c06e75dd73f.json rename to packages/datatype-parser/test/snapshots/503d0c06e75dd73f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/50876ef35975fe08.json b/packages/datatype-parser/test/snapshots/50876ef35975fe08.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/50876ef35975fe08.json rename to packages/datatype-parser/test/snapshots/50876ef35975fe08.json diff --git a/type-parser/mini-parser-ts/test/snapshots/508ec6552e77fe7d.json b/packages/datatype-parser/test/snapshots/508ec6552e77fe7d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/508ec6552e77fe7d.json rename to packages/datatype-parser/test/snapshots/508ec6552e77fe7d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5094f81299f4d418.json b/packages/datatype-parser/test/snapshots/5094f81299f4d418.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5094f81299f4d418.json rename to packages/datatype-parser/test/snapshots/5094f81299f4d418.json diff --git a/type-parser/mini-parser-ts/test/snapshots/51b1bf12f2eef86f.json b/packages/datatype-parser/test/snapshots/51b1bf12f2eef86f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/51b1bf12f2eef86f.json rename to packages/datatype-parser/test/snapshots/51b1bf12f2eef86f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/51db33fb52b4c790.json b/packages/datatype-parser/test/snapshots/51db33fb52b4c790.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/51db33fb52b4c790.json rename to packages/datatype-parser/test/snapshots/51db33fb52b4c790.json diff --git a/type-parser/mini-parser-ts/test/snapshots/52708f106b39ca6d.json b/packages/datatype-parser/test/snapshots/52708f106b39ca6d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/52708f106b39ca6d.json rename to packages/datatype-parser/test/snapshots/52708f106b39ca6d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/54b047d7967410c4.json b/packages/datatype-parser/test/snapshots/54b047d7967410c4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/54b047d7967410c4.json rename to packages/datatype-parser/test/snapshots/54b047d7967410c4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/55042c80818a5432.json b/packages/datatype-parser/test/snapshots/55042c80818a5432.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/55042c80818a5432.json rename to packages/datatype-parser/test/snapshots/55042c80818a5432.json diff --git a/type-parser/mini-parser-ts/test/snapshots/55c5d81017a30edf.json b/packages/datatype-parser/test/snapshots/55c5d81017a30edf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/55c5d81017a30edf.json rename to packages/datatype-parser/test/snapshots/55c5d81017a30edf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5913df984e01b049.json b/packages/datatype-parser/test/snapshots/5913df984e01b049.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5913df984e01b049.json rename to packages/datatype-parser/test/snapshots/5913df984e01b049.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5a84a5824366cfdf.json b/packages/datatype-parser/test/snapshots/5a84a5824366cfdf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5a84a5824366cfdf.json rename to packages/datatype-parser/test/snapshots/5a84a5824366cfdf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5bee16b592d3087c.json b/packages/datatype-parser/test/snapshots/5bee16b592d3087c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5bee16b592d3087c.json rename to packages/datatype-parser/test/snapshots/5bee16b592d3087c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5c52b39b56c50f56.json b/packages/datatype-parser/test/snapshots/5c52b39b56c50f56.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5c52b39b56c50f56.json rename to packages/datatype-parser/test/snapshots/5c52b39b56c50f56.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5c89edcac2811a6a.json b/packages/datatype-parser/test/snapshots/5c89edcac2811a6a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5c89edcac2811a6a.json rename to packages/datatype-parser/test/snapshots/5c89edcac2811a6a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/5e990ab2800482f2.json b/packages/datatype-parser/test/snapshots/5e990ab2800482f2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/5e990ab2800482f2.json rename to packages/datatype-parser/test/snapshots/5e990ab2800482f2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6000a28977e029d9.json b/packages/datatype-parser/test/snapshots/6000a28977e029d9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6000a28977e029d9.json rename to packages/datatype-parser/test/snapshots/6000a28977e029d9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/620e6c17af0fec3f.json b/packages/datatype-parser/test/snapshots/620e6c17af0fec3f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/620e6c17af0fec3f.json rename to packages/datatype-parser/test/snapshots/620e6c17af0fec3f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/625a100e21847dcf.json b/packages/datatype-parser/test/snapshots/625a100e21847dcf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/625a100e21847dcf.json rename to packages/datatype-parser/test/snapshots/625a100e21847dcf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/63a53953382e5a76.json b/packages/datatype-parser/test/snapshots/63a53953382e5a76.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/63a53953382e5a76.json rename to packages/datatype-parser/test/snapshots/63a53953382e5a76.json diff --git a/type-parser/mini-parser-ts/test/snapshots/64269f9bd268bf28.json b/packages/datatype-parser/test/snapshots/64269f9bd268bf28.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/64269f9bd268bf28.json rename to packages/datatype-parser/test/snapshots/64269f9bd268bf28.json diff --git a/type-parser/mini-parser-ts/test/snapshots/648be8a9b20b4068.json b/packages/datatype-parser/test/snapshots/648be8a9b20b4068.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/648be8a9b20b4068.json rename to packages/datatype-parser/test/snapshots/648be8a9b20b4068.json diff --git a/type-parser/mini-parser-ts/test/snapshots/64edc28811344047.json b/packages/datatype-parser/test/snapshots/64edc28811344047.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/64edc28811344047.json rename to packages/datatype-parser/test/snapshots/64edc28811344047.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6529f695ef6bea2b.json b/packages/datatype-parser/test/snapshots/6529f695ef6bea2b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6529f695ef6bea2b.json rename to packages/datatype-parser/test/snapshots/6529f695ef6bea2b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/65d2d849e33bbb9f.json b/packages/datatype-parser/test/snapshots/65d2d849e33bbb9f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/65d2d849e33bbb9f.json rename to packages/datatype-parser/test/snapshots/65d2d849e33bbb9f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/663699edbe8d32d0.json b/packages/datatype-parser/test/snapshots/663699edbe8d32d0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/663699edbe8d32d0.json rename to packages/datatype-parser/test/snapshots/663699edbe8d32d0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/663ad5af89c48643.json b/packages/datatype-parser/test/snapshots/663ad5af89c48643.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/663ad5af89c48643.json rename to packages/datatype-parser/test/snapshots/663ad5af89c48643.json diff --git a/type-parser/mini-parser-ts/test/snapshots/66c7fbd08eb194f8.json b/packages/datatype-parser/test/snapshots/66c7fbd08eb194f8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/66c7fbd08eb194f8.json rename to packages/datatype-parser/test/snapshots/66c7fbd08eb194f8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6760521bb1b6d98f.json b/packages/datatype-parser/test/snapshots/6760521bb1b6d98f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6760521bb1b6d98f.json rename to packages/datatype-parser/test/snapshots/6760521bb1b6d98f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/67ab5f4c86e061d7.json b/packages/datatype-parser/test/snapshots/67ab5f4c86e061d7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/67ab5f4c86e061d7.json rename to packages/datatype-parser/test/snapshots/67ab5f4c86e061d7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6932c015a8c3a3ef.json b/packages/datatype-parser/test/snapshots/6932c015a8c3a3ef.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6932c015a8c3a3ef.json rename to packages/datatype-parser/test/snapshots/6932c015a8c3a3ef.json diff --git a/type-parser/mini-parser-ts/test/snapshots/69a99906f5a06ea1.json b/packages/datatype-parser/test/snapshots/69a99906f5a06ea1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/69a99906f5a06ea1.json rename to packages/datatype-parser/test/snapshots/69a99906f5a06ea1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/69ddba4964a41534.json b/packages/datatype-parser/test/snapshots/69ddba4964a41534.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/69ddba4964a41534.json rename to packages/datatype-parser/test/snapshots/69ddba4964a41534.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6b09d0c1e764f23a.json b/packages/datatype-parser/test/snapshots/6b09d0c1e764f23a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6b09d0c1e764f23a.json rename to packages/datatype-parser/test/snapshots/6b09d0c1e764f23a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6c43115b5c24bfa0.json b/packages/datatype-parser/test/snapshots/6c43115b5c24bfa0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6c43115b5c24bfa0.json rename to packages/datatype-parser/test/snapshots/6c43115b5c24bfa0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6c82e6dd86807ee3.json b/packages/datatype-parser/test/snapshots/6c82e6dd86807ee3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6c82e6dd86807ee3.json rename to packages/datatype-parser/test/snapshots/6c82e6dd86807ee3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6ddeb86eb863afac.json b/packages/datatype-parser/test/snapshots/6ddeb86eb863afac.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6ddeb86eb863afac.json rename to packages/datatype-parser/test/snapshots/6ddeb86eb863afac.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6e25d9b9f79612fd.json b/packages/datatype-parser/test/snapshots/6e25d9b9f79612fd.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6e25d9b9f79612fd.json rename to packages/datatype-parser/test/snapshots/6e25d9b9f79612fd.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6e53b6c5a0f31021.json b/packages/datatype-parser/test/snapshots/6e53b6c5a0f31021.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6e53b6c5a0f31021.json rename to packages/datatype-parser/test/snapshots/6e53b6c5a0f31021.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6e5f2d68fd260298.json b/packages/datatype-parser/test/snapshots/6e5f2d68fd260298.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6e5f2d68fd260298.json rename to packages/datatype-parser/test/snapshots/6e5f2d68fd260298.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6e823ebb2984559d.json b/packages/datatype-parser/test/snapshots/6e823ebb2984559d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6e823ebb2984559d.json rename to packages/datatype-parser/test/snapshots/6e823ebb2984559d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6e85b5501433e087.json b/packages/datatype-parser/test/snapshots/6e85b5501433e087.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6e85b5501433e087.json rename to packages/datatype-parser/test/snapshots/6e85b5501433e087.json diff --git a/type-parser/mini-parser-ts/test/snapshots/6f2851997db0584b.json b/packages/datatype-parser/test/snapshots/6f2851997db0584b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/6f2851997db0584b.json rename to packages/datatype-parser/test/snapshots/6f2851997db0584b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/707890c2d6dfa724.json b/packages/datatype-parser/test/snapshots/707890c2d6dfa724.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/707890c2d6dfa724.json rename to packages/datatype-parser/test/snapshots/707890c2d6dfa724.json diff --git a/type-parser/mini-parser-ts/test/snapshots/707ef63b9e074824.json b/packages/datatype-parser/test/snapshots/707ef63b9e074824.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/707ef63b9e074824.json rename to packages/datatype-parser/test/snapshots/707ef63b9e074824.json diff --git a/type-parser/mini-parser-ts/test/snapshots/70b4bb2684c3f896.json b/packages/datatype-parser/test/snapshots/70b4bb2684c3f896.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/70b4bb2684c3f896.json rename to packages/datatype-parser/test/snapshots/70b4bb2684c3f896.json diff --git a/type-parser/mini-parser-ts/test/snapshots/710d7120fc63672d.json b/packages/datatype-parser/test/snapshots/710d7120fc63672d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/710d7120fc63672d.json rename to packages/datatype-parser/test/snapshots/710d7120fc63672d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/711cbcac68f895ff.json b/packages/datatype-parser/test/snapshots/711cbcac68f895ff.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/711cbcac68f895ff.json rename to packages/datatype-parser/test/snapshots/711cbcac68f895ff.json diff --git a/type-parser/mini-parser-ts/test/snapshots/71bf56ec603bc142.json b/packages/datatype-parser/test/snapshots/71bf56ec603bc142.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/71bf56ec603bc142.json rename to packages/datatype-parser/test/snapshots/71bf56ec603bc142.json diff --git a/type-parser/mini-parser-ts/test/snapshots/720b7e5e0ae2603c.json b/packages/datatype-parser/test/snapshots/720b7e5e0ae2603c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/720b7e5e0ae2603c.json rename to packages/datatype-parser/test/snapshots/720b7e5e0ae2603c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/74219cbd9de3b122.json b/packages/datatype-parser/test/snapshots/74219cbd9de3b122.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/74219cbd9de3b122.json rename to packages/datatype-parser/test/snapshots/74219cbd9de3b122.json diff --git a/type-parser/mini-parser-ts/test/snapshots/742ae2179d57f271.json b/packages/datatype-parser/test/snapshots/742ae2179d57f271.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/742ae2179d57f271.json rename to packages/datatype-parser/test/snapshots/742ae2179d57f271.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7438a826f1a6e96c.json b/packages/datatype-parser/test/snapshots/7438a826f1a6e96c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7438a826f1a6e96c.json rename to packages/datatype-parser/test/snapshots/7438a826f1a6e96c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/75233122af88843e.json b/packages/datatype-parser/test/snapshots/75233122af88843e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/75233122af88843e.json rename to packages/datatype-parser/test/snapshots/75233122af88843e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7583403b47298bc7.json b/packages/datatype-parser/test/snapshots/7583403b47298bc7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7583403b47298bc7.json rename to packages/datatype-parser/test/snapshots/7583403b47298bc7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7588be2bc0c71c3a.json b/packages/datatype-parser/test/snapshots/7588be2bc0c71c3a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7588be2bc0c71c3a.json rename to packages/datatype-parser/test/snapshots/7588be2bc0c71c3a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/76a9f9e4cb330396.json b/packages/datatype-parser/test/snapshots/76a9f9e4cb330396.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/76a9f9e4cb330396.json rename to packages/datatype-parser/test/snapshots/76a9f9e4cb330396.json diff --git a/type-parser/mini-parser-ts/test/snapshots/76b87a32829da0e0.json b/packages/datatype-parser/test/snapshots/76b87a32829da0e0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/76b87a32829da0e0.json rename to packages/datatype-parser/test/snapshots/76b87a32829da0e0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/76f142be038f6aaf.json b/packages/datatype-parser/test/snapshots/76f142be038f6aaf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/76f142be038f6aaf.json rename to packages/datatype-parser/test/snapshots/76f142be038f6aaf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/77dac08f7a014269.json b/packages/datatype-parser/test/snapshots/77dac08f7a014269.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/77dac08f7a014269.json rename to packages/datatype-parser/test/snapshots/77dac08f7a014269.json diff --git a/type-parser/mini-parser-ts/test/snapshots/78de9c05192768a1.json b/packages/datatype-parser/test/snapshots/78de9c05192768a1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/78de9c05192768a1.json rename to packages/datatype-parser/test/snapshots/78de9c05192768a1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/793985cddb68d46e.json b/packages/datatype-parser/test/snapshots/793985cddb68d46e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/793985cddb68d46e.json rename to packages/datatype-parser/test/snapshots/793985cddb68d46e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7982e8c08d84551a.json b/packages/datatype-parser/test/snapshots/7982e8c08d84551a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7982e8c08d84551a.json rename to packages/datatype-parser/test/snapshots/7982e8c08d84551a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7b2d79ca937a8cbb.json b/packages/datatype-parser/test/snapshots/7b2d79ca937a8cbb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7b2d79ca937a8cbb.json rename to packages/datatype-parser/test/snapshots/7b2d79ca937a8cbb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7b35b7bce86754a4.json b/packages/datatype-parser/test/snapshots/7b35b7bce86754a4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7b35b7bce86754a4.json rename to packages/datatype-parser/test/snapshots/7b35b7bce86754a4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7b617dda062bb685.json b/packages/datatype-parser/test/snapshots/7b617dda062bb685.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7b617dda062bb685.json rename to packages/datatype-parser/test/snapshots/7b617dda062bb685.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7bb7347a7172ad9e.json b/packages/datatype-parser/test/snapshots/7bb7347a7172ad9e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7bb7347a7172ad9e.json rename to packages/datatype-parser/test/snapshots/7bb7347a7172ad9e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7bd969148ace5e13.json b/packages/datatype-parser/test/snapshots/7bd969148ace5e13.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7bd969148ace5e13.json rename to packages/datatype-parser/test/snapshots/7bd969148ace5e13.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7c42711aeccef61a.json b/packages/datatype-parser/test/snapshots/7c42711aeccef61a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7c42711aeccef61a.json rename to packages/datatype-parser/test/snapshots/7c42711aeccef61a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7d144c8134ca1b4f.json b/packages/datatype-parser/test/snapshots/7d144c8134ca1b4f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7d144c8134ca1b4f.json rename to packages/datatype-parser/test/snapshots/7d144c8134ca1b4f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7d4e42ef9d04a046.json b/packages/datatype-parser/test/snapshots/7d4e42ef9d04a046.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7d4e42ef9d04a046.json rename to packages/datatype-parser/test/snapshots/7d4e42ef9d04a046.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7d6f05e0471d0acd.json b/packages/datatype-parser/test/snapshots/7d6f05e0471d0acd.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7d6f05e0471d0acd.json rename to packages/datatype-parser/test/snapshots/7d6f05e0471d0acd.json diff --git a/type-parser/mini-parser-ts/test/snapshots/7ee1ece2d69e227b.json b/packages/datatype-parser/test/snapshots/7ee1ece2d69e227b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/7ee1ece2d69e227b.json rename to packages/datatype-parser/test/snapshots/7ee1ece2d69e227b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/820a070e69cbeff5.json b/packages/datatype-parser/test/snapshots/820a070e69cbeff5.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/820a070e69cbeff5.json rename to packages/datatype-parser/test/snapshots/820a070e69cbeff5.json diff --git a/type-parser/mini-parser-ts/test/snapshots/84bafac21a924872.json b/packages/datatype-parser/test/snapshots/84bafac21a924872.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/84bafac21a924872.json rename to packages/datatype-parser/test/snapshots/84bafac21a924872.json diff --git a/type-parser/mini-parser-ts/test/snapshots/84c79425e23a4926.json b/packages/datatype-parser/test/snapshots/84c79425e23a4926.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/84c79425e23a4926.json rename to packages/datatype-parser/test/snapshots/84c79425e23a4926.json diff --git a/type-parser/mini-parser-ts/test/snapshots/85066b2ca9c0c348.json b/packages/datatype-parser/test/snapshots/85066b2ca9c0c348.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/85066b2ca9c0c348.json rename to packages/datatype-parser/test/snapshots/85066b2ca9c0c348.json diff --git a/type-parser/mini-parser-ts/test/snapshots/857895ede54a4ad7.json b/packages/datatype-parser/test/snapshots/857895ede54a4ad7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/857895ede54a4ad7.json rename to packages/datatype-parser/test/snapshots/857895ede54a4ad7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/85e93d199ff62047.json b/packages/datatype-parser/test/snapshots/85e93d199ff62047.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/85e93d199ff62047.json rename to packages/datatype-parser/test/snapshots/85e93d199ff62047.json diff --git a/type-parser/mini-parser-ts/test/snapshots/863545b36296dfca.json b/packages/datatype-parser/test/snapshots/863545b36296dfca.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/863545b36296dfca.json rename to packages/datatype-parser/test/snapshots/863545b36296dfca.json diff --git a/type-parser/mini-parser-ts/test/snapshots/863c2dcdff8db25e.json b/packages/datatype-parser/test/snapshots/863c2dcdff8db25e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/863c2dcdff8db25e.json rename to packages/datatype-parser/test/snapshots/863c2dcdff8db25e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8658478ee33a4992.json b/packages/datatype-parser/test/snapshots/8658478ee33a4992.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8658478ee33a4992.json rename to packages/datatype-parser/test/snapshots/8658478ee33a4992.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8659297c152d065c.json b/packages/datatype-parser/test/snapshots/8659297c152d065c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8659297c152d065c.json rename to packages/datatype-parser/test/snapshots/8659297c152d065c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/88228a7e519d90de.json b/packages/datatype-parser/test/snapshots/88228a7e519d90de.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/88228a7e519d90de.json rename to packages/datatype-parser/test/snapshots/88228a7e519d90de.json diff --git a/type-parser/mini-parser-ts/test/snapshots/88c06ce9a212e3c3.json b/packages/datatype-parser/test/snapshots/88c06ce9a212e3c3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/88c06ce9a212e3c3.json rename to packages/datatype-parser/test/snapshots/88c06ce9a212e3c3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8911b9163c7d34f3.json b/packages/datatype-parser/test/snapshots/8911b9163c7d34f3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8911b9163c7d34f3.json rename to packages/datatype-parser/test/snapshots/8911b9163c7d34f3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8969693adfe3e927.json b/packages/datatype-parser/test/snapshots/8969693adfe3e927.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8969693adfe3e927.json rename to packages/datatype-parser/test/snapshots/8969693adfe3e927.json diff --git a/type-parser/mini-parser-ts/test/snapshots/89a8eec911b3dcd7.json b/packages/datatype-parser/test/snapshots/89a8eec911b3dcd7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/89a8eec911b3dcd7.json rename to packages/datatype-parser/test/snapshots/89a8eec911b3dcd7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8a4d871957c7159e.json b/packages/datatype-parser/test/snapshots/8a4d871957c7159e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8a4d871957c7159e.json rename to packages/datatype-parser/test/snapshots/8a4d871957c7159e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8bad118235abbed4.json b/packages/datatype-parser/test/snapshots/8bad118235abbed4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8bad118235abbed4.json rename to packages/datatype-parser/test/snapshots/8bad118235abbed4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8d08253fa3dc6ea7.json b/packages/datatype-parser/test/snapshots/8d08253fa3dc6ea7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8d08253fa3dc6ea7.json rename to packages/datatype-parser/test/snapshots/8d08253fa3dc6ea7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8e194457987b0af1.json b/packages/datatype-parser/test/snapshots/8e194457987b0af1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8e194457987b0af1.json rename to packages/datatype-parser/test/snapshots/8e194457987b0af1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8e8232cd6a0e42ec.json b/packages/datatype-parser/test/snapshots/8e8232cd6a0e42ec.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8e8232cd6a0e42ec.json rename to packages/datatype-parser/test/snapshots/8e8232cd6a0e42ec.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8f1113085b02958c.json b/packages/datatype-parser/test/snapshots/8f1113085b02958c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8f1113085b02958c.json rename to packages/datatype-parser/test/snapshots/8f1113085b02958c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8f535b0aee7ff306.json b/packages/datatype-parser/test/snapshots/8f535b0aee7ff306.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8f535b0aee7ff306.json rename to packages/datatype-parser/test/snapshots/8f535b0aee7ff306.json diff --git a/type-parser/mini-parser-ts/test/snapshots/8fe0c11dbe0aca49.json b/packages/datatype-parser/test/snapshots/8fe0c11dbe0aca49.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/8fe0c11dbe0aca49.json rename to packages/datatype-parser/test/snapshots/8fe0c11dbe0aca49.json diff --git a/type-parser/mini-parser-ts/test/snapshots/90885de55fed9053.json b/packages/datatype-parser/test/snapshots/90885de55fed9053.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/90885de55fed9053.json rename to packages/datatype-parser/test/snapshots/90885de55fed9053.json diff --git a/type-parser/mini-parser-ts/test/snapshots/913001e7931e5222.json b/packages/datatype-parser/test/snapshots/913001e7931e5222.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/913001e7931e5222.json rename to packages/datatype-parser/test/snapshots/913001e7931e5222.json diff --git a/type-parser/mini-parser-ts/test/snapshots/91b51f022dd84872.json b/packages/datatype-parser/test/snapshots/91b51f022dd84872.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/91b51f022dd84872.json rename to packages/datatype-parser/test/snapshots/91b51f022dd84872.json diff --git a/type-parser/mini-parser-ts/test/snapshots/92d47d12e6852d3f.json b/packages/datatype-parser/test/snapshots/92d47d12e6852d3f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/92d47d12e6852d3f.json rename to packages/datatype-parser/test/snapshots/92d47d12e6852d3f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9430d1f0cb6846cf.json b/packages/datatype-parser/test/snapshots/9430d1f0cb6846cf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9430d1f0cb6846cf.json rename to packages/datatype-parser/test/snapshots/9430d1f0cb6846cf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9434ca86a34b5ff2.json b/packages/datatype-parser/test/snapshots/9434ca86a34b5ff2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9434ca86a34b5ff2.json rename to packages/datatype-parser/test/snapshots/9434ca86a34b5ff2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/95bf560a0bb0375a.json b/packages/datatype-parser/test/snapshots/95bf560a0bb0375a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/95bf560a0bb0375a.json rename to packages/datatype-parser/test/snapshots/95bf560a0bb0375a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/96ddaccf581f483c.json b/packages/datatype-parser/test/snapshots/96ddaccf581f483c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/96ddaccf581f483c.json rename to packages/datatype-parser/test/snapshots/96ddaccf581f483c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/98cc0e810e27c9bf.json b/packages/datatype-parser/test/snapshots/98cc0e810e27c9bf.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/98cc0e810e27c9bf.json rename to packages/datatype-parser/test/snapshots/98cc0e810e27c9bf.json diff --git a/type-parser/mini-parser-ts/test/snapshots/998fe0ecccd6998c.json b/packages/datatype-parser/test/snapshots/998fe0ecccd6998c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/998fe0ecccd6998c.json rename to packages/datatype-parser/test/snapshots/998fe0ecccd6998c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9993d2e1f4dbe182.json b/packages/datatype-parser/test/snapshots/9993d2e1f4dbe182.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9993d2e1f4dbe182.json rename to packages/datatype-parser/test/snapshots/9993d2e1f4dbe182.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9a52f34a0fcbb1da.json b/packages/datatype-parser/test/snapshots/9a52f34a0fcbb1da.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9a52f34a0fcbb1da.json rename to packages/datatype-parser/test/snapshots/9a52f34a0fcbb1da.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9cbddfd4afa15219.json b/packages/datatype-parser/test/snapshots/9cbddfd4afa15219.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9cbddfd4afa15219.json rename to packages/datatype-parser/test/snapshots/9cbddfd4afa15219.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9d618df2b0f244f4.json b/packages/datatype-parser/test/snapshots/9d618df2b0f244f4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9d618df2b0f244f4.json rename to packages/datatype-parser/test/snapshots/9d618df2b0f244f4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9e170c7c7025a1a5.json b/packages/datatype-parser/test/snapshots/9e170c7c7025a1a5.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9e170c7c7025a1a5.json rename to packages/datatype-parser/test/snapshots/9e170c7c7025a1a5.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9f561ebcb560c871.json b/packages/datatype-parser/test/snapshots/9f561ebcb560c871.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9f561ebcb560c871.json rename to packages/datatype-parser/test/snapshots/9f561ebcb560c871.json diff --git a/type-parser/mini-parser-ts/test/snapshots/9fbbc9c6e35de50d.json b/packages/datatype-parser/test/snapshots/9fbbc9c6e35de50d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/9fbbc9c6e35de50d.json rename to packages/datatype-parser/test/snapshots/9fbbc9c6e35de50d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a148b5c78eff3afa.json b/packages/datatype-parser/test/snapshots/a148b5c78eff3afa.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a148b5c78eff3afa.json rename to packages/datatype-parser/test/snapshots/a148b5c78eff3afa.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a1b36e70b213ab9a.json b/packages/datatype-parser/test/snapshots/a1b36e70b213ab9a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a1b36e70b213ab9a.json rename to packages/datatype-parser/test/snapshots/a1b36e70b213ab9a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a314e0179bfc11f0.json b/packages/datatype-parser/test/snapshots/a314e0179bfc11f0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a314e0179bfc11f0.json rename to packages/datatype-parser/test/snapshots/a314e0179bfc11f0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a3bd1284c7e4a6ab.json b/packages/datatype-parser/test/snapshots/a3bd1284c7e4a6ab.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a3bd1284c7e4a6ab.json rename to packages/datatype-parser/test/snapshots/a3bd1284c7e4a6ab.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a5215edb17e53ed3.json b/packages/datatype-parser/test/snapshots/a5215edb17e53ed3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a5215edb17e53ed3.json rename to packages/datatype-parser/test/snapshots/a5215edb17e53ed3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a55e385aa7e8d7ec.json b/packages/datatype-parser/test/snapshots/a55e385aa7e8d7ec.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a55e385aa7e8d7ec.json rename to packages/datatype-parser/test/snapshots/a55e385aa7e8d7ec.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a8b536b58d6a8ca7.json b/packages/datatype-parser/test/snapshots/a8b536b58d6a8ca7.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a8b536b58d6a8ca7.json rename to packages/datatype-parser/test/snapshots/a8b536b58d6a8ca7.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a8dbffb1eb0d1d99.json b/packages/datatype-parser/test/snapshots/a8dbffb1eb0d1d99.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a8dbffb1eb0d1d99.json rename to packages/datatype-parser/test/snapshots/a8dbffb1eb0d1d99.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a95e6ce38f4ca609.json b/packages/datatype-parser/test/snapshots/a95e6ce38f4ca609.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a95e6ce38f4ca609.json rename to packages/datatype-parser/test/snapshots/a95e6ce38f4ca609.json diff --git a/type-parser/mini-parser-ts/test/snapshots/a96d87d7c8b3dcfb.json b/packages/datatype-parser/test/snapshots/a96d87d7c8b3dcfb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/a96d87d7c8b3dcfb.json rename to packages/datatype-parser/test/snapshots/a96d87d7c8b3dcfb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/aa7c18e52c6fe0c3.json b/packages/datatype-parser/test/snapshots/aa7c18e52c6fe0c3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/aa7c18e52c6fe0c3.json rename to packages/datatype-parser/test/snapshots/aa7c18e52c6fe0c3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ab56a84eb0f06b84.json b/packages/datatype-parser/test/snapshots/ab56a84eb0f06b84.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ab56a84eb0f06b84.json rename to packages/datatype-parser/test/snapshots/ab56a84eb0f06b84.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ab68d8e893a82cff.json b/packages/datatype-parser/test/snapshots/ab68d8e893a82cff.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ab68d8e893a82cff.json rename to packages/datatype-parser/test/snapshots/ab68d8e893a82cff.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ab7266122e1f020a.json b/packages/datatype-parser/test/snapshots/ab7266122e1f020a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ab7266122e1f020a.json rename to packages/datatype-parser/test/snapshots/ab7266122e1f020a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/adcc2a14fead7cd8.json b/packages/datatype-parser/test/snapshots/adcc2a14fead7cd8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/adcc2a14fead7cd8.json rename to packages/datatype-parser/test/snapshots/adcc2a14fead7cd8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/afc75d45f651500f.json b/packages/datatype-parser/test/snapshots/afc75d45f651500f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/afc75d45f651500f.json rename to packages/datatype-parser/test/snapshots/afc75d45f651500f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b1017bf1dd9b0fe4.json b/packages/datatype-parser/test/snapshots/b1017bf1dd9b0fe4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b1017bf1dd9b0fe4.json rename to packages/datatype-parser/test/snapshots/b1017bf1dd9b0fe4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b306956d40529bf3.json b/packages/datatype-parser/test/snapshots/b306956d40529bf3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b306956d40529bf3.json rename to packages/datatype-parser/test/snapshots/b306956d40529bf3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b321ed35f3d53336.json b/packages/datatype-parser/test/snapshots/b321ed35f3d53336.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b321ed35f3d53336.json rename to packages/datatype-parser/test/snapshots/b321ed35f3d53336.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b4aa451e69c80088.json b/packages/datatype-parser/test/snapshots/b4aa451e69c80088.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b4aa451e69c80088.json rename to packages/datatype-parser/test/snapshots/b4aa451e69c80088.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b4c5e2b4273fdc60.json b/packages/datatype-parser/test/snapshots/b4c5e2b4273fdc60.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b4c5e2b4273fdc60.json rename to packages/datatype-parser/test/snapshots/b4c5e2b4273fdc60.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b60cb032709a29a6.json b/packages/datatype-parser/test/snapshots/b60cb032709a29a6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b60cb032709a29a6.json rename to packages/datatype-parser/test/snapshots/b60cb032709a29a6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b70cb7df11aa9094.json b/packages/datatype-parser/test/snapshots/b70cb7df11aa9094.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b70cb7df11aa9094.json rename to packages/datatype-parser/test/snapshots/b70cb7df11aa9094.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b734564dc378b7bd.json b/packages/datatype-parser/test/snapshots/b734564dc378b7bd.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b734564dc378b7bd.json rename to packages/datatype-parser/test/snapshots/b734564dc378b7bd.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b8cee90b794bb4f1.json b/packages/datatype-parser/test/snapshots/b8cee90b794bb4f1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b8cee90b794bb4f1.json rename to packages/datatype-parser/test/snapshots/b8cee90b794bb4f1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/b96269387d602df2.json b/packages/datatype-parser/test/snapshots/b96269387d602df2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/b96269387d602df2.json rename to packages/datatype-parser/test/snapshots/b96269387d602df2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ba328c5fc345c0f2.json b/packages/datatype-parser/test/snapshots/ba328c5fc345c0f2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ba328c5fc345c0f2.json rename to packages/datatype-parser/test/snapshots/ba328c5fc345c0f2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ba5c9413b0237a0c.json b/packages/datatype-parser/test/snapshots/ba5c9413b0237a0c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ba5c9413b0237a0c.json rename to packages/datatype-parser/test/snapshots/ba5c9413b0237a0c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bad418ae7c592db2.json b/packages/datatype-parser/test/snapshots/bad418ae7c592db2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bad418ae7c592db2.json rename to packages/datatype-parser/test/snapshots/bad418ae7c592db2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bb588ee05a3b285f.json b/packages/datatype-parser/test/snapshots/bb588ee05a3b285f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bb588ee05a3b285f.json rename to packages/datatype-parser/test/snapshots/bb588ee05a3b285f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bbaa27c010a10469.json b/packages/datatype-parser/test/snapshots/bbaa27c010a10469.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bbaa27c010a10469.json rename to packages/datatype-parser/test/snapshots/bbaa27c010a10469.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bbdddd4971d19599.json b/packages/datatype-parser/test/snapshots/bbdddd4971d19599.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bbdddd4971d19599.json rename to packages/datatype-parser/test/snapshots/bbdddd4971d19599.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bc45bad0c8791d60.json b/packages/datatype-parser/test/snapshots/bc45bad0c8791d60.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bc45bad0c8791d60.json rename to packages/datatype-parser/test/snapshots/bc45bad0c8791d60.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bd226d3d4f21c323.json b/packages/datatype-parser/test/snapshots/bd226d3d4f21c323.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bd226d3d4f21c323.json rename to packages/datatype-parser/test/snapshots/bd226d3d4f21c323.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bd92f5ce619c26da.json b/packages/datatype-parser/test/snapshots/bd92f5ce619c26da.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bd92f5ce619c26da.json rename to packages/datatype-parser/test/snapshots/bd92f5ce619c26da.json diff --git a/type-parser/mini-parser-ts/test/snapshots/be25137f16c1f587.json b/packages/datatype-parser/test/snapshots/be25137f16c1f587.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/be25137f16c1f587.json rename to packages/datatype-parser/test/snapshots/be25137f16c1f587.json diff --git a/type-parser/mini-parser-ts/test/snapshots/bf23ba5bb47b8e4e.json b/packages/datatype-parser/test/snapshots/bf23ba5bb47b8e4e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/bf23ba5bb47b8e4e.json rename to packages/datatype-parser/test/snapshots/bf23ba5bb47b8e4e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c0e76a72cd8b87eb.json b/packages/datatype-parser/test/snapshots/c0e76a72cd8b87eb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c0e76a72cd8b87eb.json rename to packages/datatype-parser/test/snapshots/c0e76a72cd8b87eb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c0f0cadca0773416.json b/packages/datatype-parser/test/snapshots/c0f0cadca0773416.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c0f0cadca0773416.json rename to packages/datatype-parser/test/snapshots/c0f0cadca0773416.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c1543d88719671aa.json b/packages/datatype-parser/test/snapshots/c1543d88719671aa.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c1543d88719671aa.json rename to packages/datatype-parser/test/snapshots/c1543d88719671aa.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c271016d67dd8d54.json b/packages/datatype-parser/test/snapshots/c271016d67dd8d54.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c271016d67dd8d54.json rename to packages/datatype-parser/test/snapshots/c271016d67dd8d54.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c2ca3c43a16ca245.json b/packages/datatype-parser/test/snapshots/c2ca3c43a16ca245.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c2ca3c43a16ca245.json rename to packages/datatype-parser/test/snapshots/c2ca3c43a16ca245.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c3dc913b07d28a5b.json b/packages/datatype-parser/test/snapshots/c3dc913b07d28a5b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c3dc913b07d28a5b.json rename to packages/datatype-parser/test/snapshots/c3dc913b07d28a5b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c45aaac1573d8a07.json b/packages/datatype-parser/test/snapshots/c45aaac1573d8a07.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c45aaac1573d8a07.json rename to packages/datatype-parser/test/snapshots/c45aaac1573d8a07.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c4605abe1a663a47.json b/packages/datatype-parser/test/snapshots/c4605abe1a663a47.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c4605abe1a663a47.json rename to packages/datatype-parser/test/snapshots/c4605abe1a663a47.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c4904982bc938507.json b/packages/datatype-parser/test/snapshots/c4904982bc938507.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c4904982bc938507.json rename to packages/datatype-parser/test/snapshots/c4904982bc938507.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c5a8be2409ab2f1d.json b/packages/datatype-parser/test/snapshots/c5a8be2409ab2f1d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c5a8be2409ab2f1d.json rename to packages/datatype-parser/test/snapshots/c5a8be2409ab2f1d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c643b487ea6dfd72.json b/packages/datatype-parser/test/snapshots/c643b487ea6dfd72.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c643b487ea6dfd72.json rename to packages/datatype-parser/test/snapshots/c643b487ea6dfd72.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c78c17175a5c0e87.json b/packages/datatype-parser/test/snapshots/c78c17175a5c0e87.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c78c17175a5c0e87.json rename to packages/datatype-parser/test/snapshots/c78c17175a5c0e87.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c8093b3c6d44d486.json b/packages/datatype-parser/test/snapshots/c8093b3c6d44d486.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c8093b3c6d44d486.json rename to packages/datatype-parser/test/snapshots/c8093b3c6d44d486.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c861c5ff0886a0f9.json b/packages/datatype-parser/test/snapshots/c861c5ff0886a0f9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c861c5ff0886a0f9.json rename to packages/datatype-parser/test/snapshots/c861c5ff0886a0f9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c86fdaa691b98f8b.json b/packages/datatype-parser/test/snapshots/c86fdaa691b98f8b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c86fdaa691b98f8b.json rename to packages/datatype-parser/test/snapshots/c86fdaa691b98f8b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c901bde075754bb0.json b/packages/datatype-parser/test/snapshots/c901bde075754bb0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c901bde075754bb0.json rename to packages/datatype-parser/test/snapshots/c901bde075754bb0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/c9f338bf38999cef.json b/packages/datatype-parser/test/snapshots/c9f338bf38999cef.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/c9f338bf38999cef.json rename to packages/datatype-parser/test/snapshots/c9f338bf38999cef.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ca7b55d1b3b969de.json b/packages/datatype-parser/test/snapshots/ca7b55d1b3b969de.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ca7b55d1b3b969de.json rename to packages/datatype-parser/test/snapshots/ca7b55d1b3b969de.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cb3651f0a9fbe7c0.json b/packages/datatype-parser/test/snapshots/cb3651f0a9fbe7c0.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cb3651f0a9fbe7c0.json rename to packages/datatype-parser/test/snapshots/cb3651f0a9fbe7c0.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cbad8c51a3e1d032.json b/packages/datatype-parser/test/snapshots/cbad8c51a3e1d032.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cbad8c51a3e1d032.json rename to packages/datatype-parser/test/snapshots/cbad8c51a3e1d032.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cd98ae36981ee80a.json b/packages/datatype-parser/test/snapshots/cd98ae36981ee80a.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cd98ae36981ee80a.json rename to packages/datatype-parser/test/snapshots/cd98ae36981ee80a.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cda2841ab393e45d.json b/packages/datatype-parser/test/snapshots/cda2841ab393e45d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cda2841ab393e45d.json rename to packages/datatype-parser/test/snapshots/cda2841ab393e45d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ce3bb6ac91e15082.json b/packages/datatype-parser/test/snapshots/ce3bb6ac91e15082.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ce3bb6ac91e15082.json rename to packages/datatype-parser/test/snapshots/ce3bb6ac91e15082.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ceb02f409a78f4ef.json b/packages/datatype-parser/test/snapshots/ceb02f409a78f4ef.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ceb02f409a78f4ef.json rename to packages/datatype-parser/test/snapshots/ceb02f409a78f4ef.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ceb739dfaa883916.json b/packages/datatype-parser/test/snapshots/ceb739dfaa883916.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ceb739dfaa883916.json rename to packages/datatype-parser/test/snapshots/ceb739dfaa883916.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cf31903898d06426.json b/packages/datatype-parser/test/snapshots/cf31903898d06426.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cf31903898d06426.json rename to packages/datatype-parser/test/snapshots/cf31903898d06426.json diff --git a/type-parser/mini-parser-ts/test/snapshots/cf640c0ceb20ff34.json b/packages/datatype-parser/test/snapshots/cf640c0ceb20ff34.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/cf640c0ceb20ff34.json rename to packages/datatype-parser/test/snapshots/cf640c0ceb20ff34.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d05fb01e0b399387.json b/packages/datatype-parser/test/snapshots/d05fb01e0b399387.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d05fb01e0b399387.json rename to packages/datatype-parser/test/snapshots/d05fb01e0b399387.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d3a3854ba98eb85d.json b/packages/datatype-parser/test/snapshots/d3a3854ba98eb85d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d3a3854ba98eb85d.json rename to packages/datatype-parser/test/snapshots/d3a3854ba98eb85d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d3e90af2aefe399f.json b/packages/datatype-parser/test/snapshots/d3e90af2aefe399f.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d3e90af2aefe399f.json rename to packages/datatype-parser/test/snapshots/d3e90af2aefe399f.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d41324ffd6eed6b3.json b/packages/datatype-parser/test/snapshots/d41324ffd6eed6b3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d41324ffd6eed6b3.json rename to packages/datatype-parser/test/snapshots/d41324ffd6eed6b3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d62cec53886ff651.json b/packages/datatype-parser/test/snapshots/d62cec53886ff651.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d62cec53886ff651.json rename to packages/datatype-parser/test/snapshots/d62cec53886ff651.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d64027e56b998e7c.json b/packages/datatype-parser/test/snapshots/d64027e56b998e7c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d64027e56b998e7c.json rename to packages/datatype-parser/test/snapshots/d64027e56b998e7c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d669ea9cedaeb679.json b/packages/datatype-parser/test/snapshots/d669ea9cedaeb679.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d669ea9cedaeb679.json rename to packages/datatype-parser/test/snapshots/d669ea9cedaeb679.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d701a37b6e4cf4e9.json b/packages/datatype-parser/test/snapshots/d701a37b6e4cf4e9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d701a37b6e4cf4e9.json rename to packages/datatype-parser/test/snapshots/d701a37b6e4cf4e9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d712296f71e49233.json b/packages/datatype-parser/test/snapshots/d712296f71e49233.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d712296f71e49233.json rename to packages/datatype-parser/test/snapshots/d712296f71e49233.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d773faf0b86ac88b.json b/packages/datatype-parser/test/snapshots/d773faf0b86ac88b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d773faf0b86ac88b.json rename to packages/datatype-parser/test/snapshots/d773faf0b86ac88b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d8367e8f5ce1f2ca.json b/packages/datatype-parser/test/snapshots/d8367e8f5ce1f2ca.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d8367e8f5ce1f2ca.json rename to packages/datatype-parser/test/snapshots/d8367e8f5ce1f2ca.json diff --git a/type-parser/mini-parser-ts/test/snapshots/d9c0ea6152fbf443.json b/packages/datatype-parser/test/snapshots/d9c0ea6152fbf443.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/d9c0ea6152fbf443.json rename to packages/datatype-parser/test/snapshots/d9c0ea6152fbf443.json diff --git a/type-parser/mini-parser-ts/test/snapshots/da0fdc28c11b5812.json b/packages/datatype-parser/test/snapshots/da0fdc28c11b5812.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/da0fdc28c11b5812.json rename to packages/datatype-parser/test/snapshots/da0fdc28c11b5812.json diff --git a/type-parser/mini-parser-ts/test/snapshots/daf760a167a8047c.json b/packages/datatype-parser/test/snapshots/daf760a167a8047c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/daf760a167a8047c.json rename to packages/datatype-parser/test/snapshots/daf760a167a8047c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/db09a2734af421e6.json b/packages/datatype-parser/test/snapshots/db09a2734af421e6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/db09a2734af421e6.json rename to packages/datatype-parser/test/snapshots/db09a2734af421e6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/dc1e8f7f69dcbc15.json b/packages/datatype-parser/test/snapshots/dc1e8f7f69dcbc15.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/dc1e8f7f69dcbc15.json rename to packages/datatype-parser/test/snapshots/dc1e8f7f69dcbc15.json diff --git a/type-parser/mini-parser-ts/test/snapshots/dd0748912e59ec25.json b/packages/datatype-parser/test/snapshots/dd0748912e59ec25.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/dd0748912e59ec25.json rename to packages/datatype-parser/test/snapshots/dd0748912e59ec25.json diff --git a/type-parser/mini-parser-ts/test/snapshots/dd6fa4122e474566.json b/packages/datatype-parser/test/snapshots/dd6fa4122e474566.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/dd6fa4122e474566.json rename to packages/datatype-parser/test/snapshots/dd6fa4122e474566.json diff --git a/type-parser/mini-parser-ts/test/snapshots/de785c721705dbba.json b/packages/datatype-parser/test/snapshots/de785c721705dbba.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/de785c721705dbba.json rename to packages/datatype-parser/test/snapshots/de785c721705dbba.json diff --git a/type-parser/mini-parser-ts/test/snapshots/de86a870104fb0a5.json b/packages/datatype-parser/test/snapshots/de86a870104fb0a5.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/de86a870104fb0a5.json rename to packages/datatype-parser/test/snapshots/de86a870104fb0a5.json diff --git a/type-parser/mini-parser-ts/test/snapshots/dec8ddb4c2e278d9.json b/packages/datatype-parser/test/snapshots/dec8ddb4c2e278d9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/dec8ddb4c2e278d9.json rename to packages/datatype-parser/test/snapshots/dec8ddb4c2e278d9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/df0e5006b34734de.json b/packages/datatype-parser/test/snapshots/df0e5006b34734de.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/df0e5006b34734de.json rename to packages/datatype-parser/test/snapshots/df0e5006b34734de.json diff --git a/type-parser/mini-parser-ts/test/snapshots/df6b4430f3a214bb.json b/packages/datatype-parser/test/snapshots/df6b4430f3a214bb.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/df6b4430f3a214bb.json rename to packages/datatype-parser/test/snapshots/df6b4430f3a214bb.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e2102781550b6a87.json b/packages/datatype-parser/test/snapshots/e2102781550b6a87.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e2102781550b6a87.json rename to packages/datatype-parser/test/snapshots/e2102781550b6a87.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e2227d1f14c97584.json b/packages/datatype-parser/test/snapshots/e2227d1f14c97584.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e2227d1f14c97584.json rename to packages/datatype-parser/test/snapshots/e2227d1f14c97584.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e227de9f1df532c1.json b/packages/datatype-parser/test/snapshots/e227de9f1df532c1.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e227de9f1df532c1.json rename to packages/datatype-parser/test/snapshots/e227de9f1df532c1.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e3b6ce3dbb8f6886.json b/packages/datatype-parser/test/snapshots/e3b6ce3dbb8f6886.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e3b6ce3dbb8f6886.json rename to packages/datatype-parser/test/snapshots/e3b6ce3dbb8f6886.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e56ae18058a93567.json b/packages/datatype-parser/test/snapshots/e56ae18058a93567.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e56ae18058a93567.json rename to packages/datatype-parser/test/snapshots/e56ae18058a93567.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e5fa045b9b25e6db.json b/packages/datatype-parser/test/snapshots/e5fa045b9b25e6db.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e5fa045b9b25e6db.json rename to packages/datatype-parser/test/snapshots/e5fa045b9b25e6db.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e64cdc56ad4c4e02.json b/packages/datatype-parser/test/snapshots/e64cdc56ad4c4e02.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e64cdc56ad4c4e02.json rename to packages/datatype-parser/test/snapshots/e64cdc56ad4c4e02.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e71e7bc3fe9e9f3c.json b/packages/datatype-parser/test/snapshots/e71e7bc3fe9e9f3c.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e71e7bc3fe9e9f3c.json rename to packages/datatype-parser/test/snapshots/e71e7bc3fe9e9f3c.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e7eb51047d99b420.json b/packages/datatype-parser/test/snapshots/e7eb51047d99b420.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e7eb51047d99b420.json rename to packages/datatype-parser/test/snapshots/e7eb51047d99b420.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e83319c6c4642871.json b/packages/datatype-parser/test/snapshots/e83319c6c4642871.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e83319c6c4642871.json rename to packages/datatype-parser/test/snapshots/e83319c6c4642871.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e89762d9c1f07a3d.json b/packages/datatype-parser/test/snapshots/e89762d9c1f07a3d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e89762d9c1f07a3d.json rename to packages/datatype-parser/test/snapshots/e89762d9c1f07a3d.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e927c2b90a4679c4.json b/packages/datatype-parser/test/snapshots/e927c2b90a4679c4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e927c2b90a4679c4.json rename to packages/datatype-parser/test/snapshots/e927c2b90a4679c4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/e9ca4b2541b01556.json b/packages/datatype-parser/test/snapshots/e9ca4b2541b01556.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/e9ca4b2541b01556.json rename to packages/datatype-parser/test/snapshots/e9ca4b2541b01556.json diff --git a/type-parser/mini-parser-ts/test/snapshots/eb0071b65f67691e.json b/packages/datatype-parser/test/snapshots/eb0071b65f67691e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/eb0071b65f67691e.json rename to packages/datatype-parser/test/snapshots/eb0071b65f67691e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/eb4afc85d92c38ea.json b/packages/datatype-parser/test/snapshots/eb4afc85d92c38ea.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/eb4afc85d92c38ea.json rename to packages/datatype-parser/test/snapshots/eb4afc85d92c38ea.json diff --git a/type-parser/mini-parser-ts/test/snapshots/eb9a4bc1c0c153e4.json b/packages/datatype-parser/test/snapshots/eb9a4bc1c0c153e4.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/eb9a4bc1c0c153e4.json rename to packages/datatype-parser/test/snapshots/eb9a4bc1c0c153e4.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ed4a033a0e470779.json b/packages/datatype-parser/test/snapshots/ed4a033a0e470779.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ed4a033a0e470779.json rename to packages/datatype-parser/test/snapshots/ed4a033a0e470779.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ed61428e81d608b3.json b/packages/datatype-parser/test/snapshots/ed61428e81d608b3.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ed61428e81d608b3.json rename to packages/datatype-parser/test/snapshots/ed61428e81d608b3.json diff --git a/type-parser/mini-parser-ts/test/snapshots/ef1ea9269b9833d2.json b/packages/datatype-parser/test/snapshots/ef1ea9269b9833d2.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/ef1ea9269b9833d2.json rename to packages/datatype-parser/test/snapshots/ef1ea9269b9833d2.json diff --git a/type-parser/mini-parser-ts/test/snapshots/effc93c8668219e9.json b/packages/datatype-parser/test/snapshots/effc93c8668219e9.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/effc93c8668219e9.json rename to packages/datatype-parser/test/snapshots/effc93c8668219e9.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f1124b0079db9585.json b/packages/datatype-parser/test/snapshots/f1124b0079db9585.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f1124b0079db9585.json rename to packages/datatype-parser/test/snapshots/f1124b0079db9585.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f161ebdfdf2494e6.json b/packages/datatype-parser/test/snapshots/f161ebdfdf2494e6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f161ebdfdf2494e6.json rename to packages/datatype-parser/test/snapshots/f161ebdfdf2494e6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f1e5baf5ecc35896.json b/packages/datatype-parser/test/snapshots/f1e5baf5ecc35896.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f1e5baf5ecc35896.json rename to packages/datatype-parser/test/snapshots/f1e5baf5ecc35896.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f4753a4dee54ee10.json b/packages/datatype-parser/test/snapshots/f4753a4dee54ee10.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f4753a4dee54ee10.json rename to packages/datatype-parser/test/snapshots/f4753a4dee54ee10.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f47ef5f8d16849a5.json b/packages/datatype-parser/test/snapshots/f47ef5f8d16849a5.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f47ef5f8d16849a5.json rename to packages/datatype-parser/test/snapshots/f47ef5f8d16849a5.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f4f033a85ce688b6.json b/packages/datatype-parser/test/snapshots/f4f033a85ce688b6.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f4f033a85ce688b6.json rename to packages/datatype-parser/test/snapshots/f4f033a85ce688b6.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f79a28423ed1ae02.json b/packages/datatype-parser/test/snapshots/f79a28423ed1ae02.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f79a28423ed1ae02.json rename to packages/datatype-parser/test/snapshots/f79a28423ed1ae02.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f8a4e52fe170a6b8.json b/packages/datatype-parser/test/snapshots/f8a4e52fe170a6b8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f8a4e52fe170a6b8.json rename to packages/datatype-parser/test/snapshots/f8a4e52fe170a6b8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/f9874bb3d8034d65.json b/packages/datatype-parser/test/snapshots/f9874bb3d8034d65.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/f9874bb3d8034d65.json rename to packages/datatype-parser/test/snapshots/f9874bb3d8034d65.json diff --git a/type-parser/mini-parser-ts/test/snapshots/fb533649ca2f9e73.json b/packages/datatype-parser/test/snapshots/fb533649ca2f9e73.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/fb533649ca2f9e73.json rename to packages/datatype-parser/test/snapshots/fb533649ca2f9e73.json diff --git a/type-parser/mini-parser-ts/test/snapshots/fca4d8d6e1593c6b.json b/packages/datatype-parser/test/snapshots/fca4d8d6e1593c6b.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/fca4d8d6e1593c6b.json rename to packages/datatype-parser/test/snapshots/fca4d8d6e1593c6b.json diff --git a/type-parser/mini-parser-ts/test/snapshots/fcb1a5ad1920b1d8.json b/packages/datatype-parser/test/snapshots/fcb1a5ad1920b1d8.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/fcb1a5ad1920b1d8.json rename to packages/datatype-parser/test/snapshots/fcb1a5ad1920b1d8.json diff --git a/type-parser/mini-parser-ts/test/snapshots/fcf6d8ffa4297b9e.json b/packages/datatype-parser/test/snapshots/fcf6d8ffa4297b9e.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/fcf6d8ffa4297b9e.json rename to packages/datatype-parser/test/snapshots/fcf6d8ffa4297b9e.json diff --git a/type-parser/mini-parser-ts/test/snapshots/fedf5fb1af8c725d.json b/packages/datatype-parser/test/snapshots/fedf5fb1af8c725d.json similarity index 100% rename from type-parser/mini-parser-ts/test/snapshots/fedf5fb1af8c725d.json rename to packages/datatype-parser/test/snapshots/fedf5fb1af8c725d.json diff --git a/type-parser/mini-parser-ts/test/update_snapshots.ts b/packages/datatype-parser/test/update_snapshots.ts similarity index 100% rename from type-parser/mini-parser-ts/test/update_snapshots.ts rename to packages/datatype-parser/test/update_snapshots.ts diff --git a/type-parser/mini-parser-ts/test/validate_types_live.ts b/packages/datatype-parser/test/validate_types_live.ts similarity index 100% rename from type-parser/mini-parser-ts/test/validate_types_live.ts rename to packages/datatype-parser/test/validate_types_live.ts diff --git a/packages/datatype-parser/tsconfig.build.json b/packages/datatype-parser/tsconfig.build.json new file mode 100644 index 000000000..8626c165e --- /dev/null +++ b/packages/datatype-parser/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "comment": "Build config for publishing: emits only the library (src) into dist/, never the CLI or test harness.", + "compilerOptions": { + "rootDir": "src" + }, + "include": ["src/**/*.ts"] +} diff --git a/type-parser/mini-parser-ts/tsconfig.json b/packages/datatype-parser/tsconfig.json similarity index 66% rename from type-parser/mini-parser-ts/tsconfig.json rename to packages/datatype-parser/tsconfig.json index eb23792e0..e9bbe61f0 100644 --- a/type-parser/mini-parser-ts/tsconfig.json +++ b/packages/datatype-parser/tsconfig.json @@ -3,6 +3,9 @@ "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "erasableSyntaxOnly": true, "lib": ["ES2022"], "declaration": true, "outDir": "dist", @@ -15,5 +18,10 @@ "esModuleInterop": true, "skipLibCheck": true }, - "include": ["src/**/*.ts", "tool/**/*.ts", "test/**/*.ts"] + "include": [ + "src/**/*.ts", + "test/**/*.ts", + "bench/**/*.ts", + "vitest.config.ts" + ] } diff --git a/packages/datatype-parser/vitest.config.ts b/packages/datatype-parser/vitest.config.ts new file mode 100644 index 000000000..c5704ae4d --- /dev/null +++ b/packages/datatype-parser/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + // Unit + snapshot suite (the `test:*`/`snapshot:*` tsx scripts in + // package.json are separate live-server tools, not vitest specs). + include: ["test/**/*.test.ts"], + benchmark: { + include: ["bench/**/*.bench.ts"], + }, + }, +}); diff --git a/skills/clickhouse-js-node-rowbinary-parser/README.md b/skills/clickhouse-js-node-rowbinary-parser/README.md index 441c5de10..6910f48c2 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/README.md +++ b/skills/clickhouse-js-node-rowbinary-parser/README.md @@ -129,6 +129,13 @@ than shipping a generic, runtime-driven decoder, it emits straight-line code that reads each column in order, so the parser only contains the logic the specific result shape needs. +**Schema only known at runtime?** `compileRowBinaryWithNamesAndTypes(cursor)` +reads the `RowBinaryWithNamesAndTypes` header and folds each column type into a +reader on the fly (type strings parsed by `@clickhouse/datatype-parser`), +returning a `readRows` driver for the rest of the stream — a generic, no-codegen +path for dynamic schemas. The specialized codegen above stays the fast path when +the types are fixed. + ## Correctness on the gotcha-heavy types For a plain `UInt64, String, DateTime` result a strong model already writes fast, diff --git a/skills/clickhouse-js-node-rowbinary-parser/SKILL.md b/skills/clickhouse-js-node-rowbinary-parser/SKILL.md index f424cd5e4..1fb41fb38 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/SKILL.md +++ b/skills/clickhouse-js-node-rowbinary-parser/SKILL.md @@ -84,6 +84,19 @@ bandwidth). Measured in `tests/iot.columnar.bench.ts`; rationale in - **Hybrid:** store columnar, expose a lazy `rowAt(i)` accessor that builds an object only for rows actually touched (see `iotRowAt` in `src/examples/iot.ts`). +## Fourth: are the column types known ahead of time? + +- **Known (the default).** Generate a straight-line reader specialized to those + types — everything below. +- **Only at runtime** (the schema varies, or you just want to decode an arbitrary + `RowBinaryWithNamesAndTypes` stream). Call + `compileRowBinaryWithNamesAndTypes(cursor)` (`src/rowBinaryWithNamesAndTypes.ts`): + it reads the header, folds each column type's AST into a `Reader` + (`astToReader`, `src/compile.ts`; type strings parsed by + `@clickhouse/datatype-parser`), and returns a `readRows` driver for the rest of + the stream. Generic and unoptimized (no codegen), so prefer the specialized + path whenever the types are fixed. + ## Core guidance When generating a parser, follow these: @@ -165,6 +178,9 @@ The readers live as real code under `src/`, split by type family. | `JSON` | `src/json.ts` | | The whole result — loop rows to EOF (`readRows`) | `src/rows.ts` | | A chunked HTTP response — `streamRowBatches`, `coalesceChunks` | `src/stream.ts` | +| The `RowBinaryWithNamesAndTypes` header — column names + type strings (`readHeader`) | `src/header.ts` | +| Fold one parsed type AST into a `Reader` (`astToReader`) — AST in, reader out | `src/compile.ts` | +| **Types known only at runtime** — compile a whole header into a row reader (`compileRowBinaryWithNamesAndTypes`, `typeStringToReader`) | `src/rowBinaryWithNamesAndTypes.ts` | | **Numeric/fixed-width result read column-wise** (aggregate/scan/plot, hand to a Worker/WASM) → decode into typed arrays, not row objects (~4x) | `src/columnar.ts` (`streamSensorColumns` — streaming, yields transferable typed-array batches); `decodeIotColumnar` in `src/examples/iot.ts` is the whole-buffer form | | `LowCardinality(T)` — transparent, decode as `T` | `src/lowCardinality.ts` | | `SimpleAggregateFunction(f, T)` — transparent, decode as `T` | `src/simpleAggregateFunction.ts` | diff --git a/skills/clickhouse-js-node-rowbinary-parser/package-lock.json b/skills/clickhouse-js-node-rowbinary-parser/package-lock.json index 334a4d8d8..09a2bf693 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/package-lock.json +++ b/skills/clickhouse-js-node-rowbinary-parser/package-lock.json @@ -8,10 +8,25 @@ "name": "@clickhouse/rowbinary", "version": "0.1.1", "license": "Apache-2.0", + "dependencies": { + "@clickhouse/datatype-parser": "^0.1.1" + }, "devDependencies": { "@types/node": "^26.0.0", "typescript": "^6.0.3", "vitest": "^4.1.9" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@clickhouse/datatype-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@clickhouse/datatype-parser/-/datatype-parser-0.1.1.tgz", + "integrity": "sha512-G4QzkEJ1k27rM8x71pX5ZQVh0HhPcaU+bj2PYOGbvLsVGOIDk5Ky09GpC7OzLYxA9WiSCMd6f9kT/yc/CySZJA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" } }, "node_modules/@emnapi/core": { diff --git a/skills/clickhouse-js-node-rowbinary-parser/package.json b/skills/clickhouse-js-node-rowbinary-parser/package.json index 8966ce9f6..984cb0b67 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/package.json +++ b/skills/clickhouse-js-node-rowbinary-parser/package.json @@ -61,6 +61,9 @@ "typecheck": "tsc --noEmit", "prepack": "cp ../../LICENSE . && npm run build" }, + "dependencies": { + "@clickhouse/datatype-parser": "^0.1.1" + }, "devDependencies": { "@types/node": "^26.0.0", "typescript": "^6.0.3", diff --git a/skills/clickhouse-js-node-rowbinary-parser/src/compile.ts b/skills/clickhouse-js-node-rowbinary-parser/src/compile.ts new file mode 100644 index 000000000..8e647a896 --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/src/compile.ts @@ -0,0 +1,318 @@ +/** + * The fold: turn a parsed ClickHouse data-type AST (from + * `@clickhouse/datatype-parser`) into a RowBinary value {@link Reader}. + * + * AST in, reader out — nothing else. Reading the `RowBinaryWithNamesAndTypes` + * header, parsing type strings, and assembling a row reader live in + * `rowBinaryWithNamesAndTypes.ts`; this module is just the type-to-reader + * mapping. + * + * It composes the existing GENERIC curried combinators at runtime, exactly as a + * hand-written reader would — no code generation and no monomorphization (those + * are the deliberate next step; see the `MONOMORPHIZE` notes throughout the + * combinator modules). The shape mirrors {@link readDynamicType} in + * `dynamic.ts`, which performs the same "type → Reader" mapping but driven by + * ClickHouse's BINARY type encoding rather than the textual type's AST. + */ + +import { NodeKind, type Node } from "@clickhouse/datatype-parser"; + +import type { Reader } from "./core.js"; +import { + readInt8, + readInt16, + readInt32, + readInt64, + readInt128, + readInt256, + readUInt8, + readUInt16, + readUInt32, + readUInt64, + readUInt128, + readUInt256, +} from "./integers.js"; +import { readFloat32, readFloat64, readBFloat16 } from "./floats.js"; +import { readBool } from "./bool.js"; +import { readString, readFixedString } from "./strings.js"; +import { readUUID } from "./uuid.js"; +import { readIPv4, readIPv6 } from "./ip.js"; +import { + readDate, + readDate32, + readDateTime, + readDateTime64, +} from "./datetime.js"; +import { readTime, readTime64 } from "./time.js"; +import { readInterval } from "./interval.js"; +import { + readDecimal32, + readDecimal64, + readDecimal128, + readDecimal256, +} from "./decimals.js"; +import { readEnum8, readEnum16 } from "./enums.js"; +import { + readArray, + readMap, + readNullable, + readTuple, + readTupleNamed, + readVariant, + readQBit, +} from "./composite.js"; +import { readLowCardinality } from "./lowCardinality.js"; +import { readNested } from "./nested.js"; +import { readNothing } from "./nothing.js"; +import { + readPoint, + readRing, + readLineString, + readPolygon, + readMultiLineString, + readMultiPolygon, + readGeometry, +} from "./geo.js"; +import { readJSON } from "./json.js"; +import { readDynamic } from "./dynamic.js"; + +/** + * Thrown when a ClickHouse type cannot be turned into a RowBinary reader — + * either the type string did not parse, or the parsed type is unsupported or + * malformed for RowBinary decoding (`AggregateFunction`, a missing argument, a + * malformed `Nested(...)`, …). + * + * A dedicated class so callers can `catch (e) { if (e instanceof + * RowBinaryTypeError) … }` and branch on a bad-type error specifically rather + * than string-matching a generic `Error`. Note the standalone + * `@clickhouse/datatype-parser` is itself NON-throwing (it returns a + * `ParseResult`); this is the error the compile layer raises on top of it. + */ +export class RowBinaryTypeError extends Error { + /** The full ClickHouse type string being compiled, when the throw site knows it. */ + readonly typeString?: string; + /** + * Byte offset into `typeString` where parsing stopped — set for PARSE + * failures (from the underlying parser), undefined for fold-time errors. + */ + readonly position?: number; + + constructor( + message: string, + options: { typeString?: string; position?: number } = {}, + ) { + super(message); + this.name = "RowBinaryTypeError"; + this.typeString = options.typeString; + this.position = options.position; + } +} + +/** + * The fold itself: turn a parsed type-AST node into a value {@link Reader}, + * recursing into element / key / field types for composites. The shape mirrors + * the server's `EXPLAIN AST` data-type subtree (see the parser's `ast.ts`). + */ +export function astToReader(node: Node): Reader { + switch (node.kind) { + case NodeKind.EnumDataType: + // Explicit-value enum: the wire value is the underlying int; the + // name<->value map is metadata we don't need to decode. + return node.name === "Enum16" ? readEnum16 : readEnum8; + case NodeKind.TupleDataType: + return tupleReader(node); + case NodeKind.DataType: + return dataTypeReader(node); + default: + // Literal / Function / Identifier / NameTypePair are argument nodes, + // consumed by their parent — never a standalone column type. + throw new RowBinaryTypeError( + `cannot build a column reader for a ${node.kind} node (${node.name || "?"})`, + ); + } +} + +/** + * Fold a generic `DataType` node (`name` + optional `arguments`) — the bulk of + * the type system: scalars, the parameterized types, and the + * wrappers/composites that recurse through {@link astToReader}. + */ +function dataTypeReader(node: Node): Reader { + switch (node.name) { + // --- wrappers & composites (recurse into argument types) --- + case "Nullable": + return readNullable(astToReader(requireArg(node, 0))); + case "LowCardinality": + // Transparent in RowBinary: just the inner type's reader. + return readLowCardinality(astToReader(requireArg(node, 0))); + case "Array": + return readArray(astToReader(requireArg(node, 0))); + case "QBit": + // QBit(element_type, dimension): wire-identical to Array(element_type); + // the dimension (arg 1) is metadata, not in the value stream. + return readQBit(astToReader(requireArg(node, 0))); + case "Map": + return readMap( + astToReader(requireArg(node, 0)), + astToReader(requireArg(node, 1)), + ); + case "Variant": + return variantReader(node); + case "Nested": + return nestedReader(node); + + // --- parameterized scalars --- + case "FixedString": + return readFixedString(literalInt(requireArg(node, 0))); + case "DateTime": + case "DateTime32": + // An optional timezone argument is metadata; the value wire is the same. + return readDateTime; + case "DateTime64": + // DateTime64(P [, 'tz']); default precision 3 if somehow omitted. + return readDateTime64( + node.arguments.length > 0 ? literalInt(node.arguments[0]!) : 3, + ); + case "Time64": + return readTime64(literalInt(requireArg(node, 0))); + case "Decimal": + return decimalReader(node); + case "Decimal32": + return readDecimal32(literalInt(requireArg(node, 0))); + case "Decimal64": + return readDecimal64(literalInt(requireArg(node, 0))); + case "Decimal128": + return readDecimal128(literalInt(requireArg(node, 0))); + case "Decimal256": + return readDecimal256(literalInt(requireArg(node, 0))); + // Auto-assigned enums arrive as a plain DataType (no explicit values); the + // wire value is still the underlying int. + case "Enum8": + return readEnum8; + case "Enum16": + return readEnum16; + + default: { + // Interval (IntervalSecond, IntervalDay, …): all decode to the + // signed Int64 count; the unit lives in the type name, not the wire. + if (node.name.startsWith("Interval")) return readInterval; + const leaf = NULLARY[node.name]; + if (leaf !== undefined) return leaf; + throw new RowBinaryTypeError(`unsupported RowBinary type: ${node.name}`); + } + } +} + +/** Folds a `Tuple(...)` — named (object) when every element is named, else positional (array). */ +function tupleReader(node: Node): Reader { + const readers = node.arguments.map(astToReader); + const names = node.element_names; + const named = + names.length === readers.length && names.every((n) => n.length > 0); + if (named) { + const fields: Record> = {}; + for (let i = 0; i < names.length; i++) fields[names[i]!] = readers[i]!; + return readTupleNamed(fields); + } + return readTuple(readers); +} + +/** + * Folds a `Variant(...)`. The 1-byte discriminant indexes the alternatives + * sorted by type NAME (ClickHouse's global ordering), and the server writes the + * type string with alternatives ALREADY in that sorted order — so for a + * header-sourced type the AST argument order is the discriminant order and we + * pass them straight through. (A hand-written, non-normalized `Variant(...)` + * string would need sorting first.) + */ +function variantReader(node: Node): Reader { + return readVariant(node.arguments.map(astToReader)); +} + +/** + * Folds a `Nested(name Type, …)`: on the wire it IS `Array(Tuple(...))` with + * the field names, so we compose {@link readNested} (= `readArray(readTupleNamed)`) + * over the `NameTypePair` children. + */ +function nestedReader(node: Node): Reader { + const fields: Record> = {}; + for (const child of node.arguments) { + if (child.kind !== NodeKind.NameTypePair || child.data_type === null) { + throw new RowBinaryTypeError( + "malformed Nested(...): expected name/type pairs", + ); + } + fields[child.name] = astToReader(child.data_type); + } + return readNested(fields); +} + +/** Folds `Decimal(P, S)` to the right width by precision P; scale S drives decoding. */ +function decimalReader(node: Node): Reader { + const precision = literalInt(requireArg(node, 0)); + const scale = literalInt(requireArg(node, 1)); + if (precision <= 9) return readDecimal32(scale); + if (precision <= 18) return readDecimal64(scale); + if (precision <= 38) return readDecimal128(scale); + return readDecimal256(scale); +} + +/** The nullary (no-argument) scalar types, mapped to their leaf readers. */ +const NULLARY: Record> = { + UInt8: readUInt8, + UInt16: readUInt16, + UInt32: readUInt32, + UInt64: readUInt64, + UInt128: readUInt128, + UInt256: readUInt256, + Int8: readInt8, + Int16: readInt16, + Int32: readInt32, + Int64: readInt64, + Int128: readInt128, + Int256: readInt256, + Float32: readFloat32, + Float64: readFloat64, + BFloat16: readBFloat16, + Bool: readBool, + String: readString, + UUID: readUUID, + IPv4: readIPv4, + IPv6: readIPv6, + Date: readDate, + Date32: readDate32, + Time: readTime, + Nothing: readNothing, + // Geo types. + Point: readPoint, + Ring: readRing, + LineString: readLineString, + Polygon: readPolygon, + MultiLineString: readMultiLineString, + MultiPolygon: readMultiPolygon, + Geometry: readGeometry as Reader, + // Self-describing types: bare `JSON` / `Dynamic` (any args are metadata). + JSON: readJSON, + Dynamic: readDynamic, +}; + +/** Argument accessor that fails loudly instead of returning `undefined`. */ +function requireArg(node: Node, index: number): Node { + const arg = node.arguments[index]; + if (arg === undefined) { + throw new RowBinaryTypeError( + `type ${node.name} is missing argument ${index}`, + ); + } + return arg; +} + +/** Reads an integer out of a `Literal` argument node (e.g. the N in FixedString(N)). */ +function literalInt(node: Node): number { + if (node.kind !== NodeKind.Literal) { + throw new RowBinaryTypeError( + `expected a literal argument, got a ${node.kind} node`, + ); + } + return Number(node.value); +} diff --git a/skills/clickhouse-js-node-rowbinary-parser/src/header.ts b/skills/clickhouse-js-node-rowbinary-parser/src/header.ts new file mode 100644 index 000000000..9e866ffca --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/src/header.ts @@ -0,0 +1,29 @@ +/** + * The `RowBinaryWithNamesAndTypes` HEADER: the column names and their type + * strings the server writes before the row data. Parsing the type strings into + * readers lives in `compile.ts`; this module is just the wire read. + */ + +import type { Cursor } from "./core.js"; +import { readUVarint } from "./varint.js"; +import { readString } from "./strings.js"; + +/** Column names and their type strings, in stream order. */ +export interface RowBinaryHeader { + names: string[]; + types: string[]; +} + +/** + * Read the `RowBinaryWithNamesAndTypes` header off the cursor: a LEB128 column + * count, then that many column-name `String`s, then that many type-string + * `String`s. Leaves the cursor at the first row's bytes. + */ +export function readHeader(state: Cursor): RowBinaryHeader { + const count = readUVarint(state); + const names: string[] = new Array(count); + for (let i = 0; i < count; i++) names[i] = readString(state); + const types: string[] = new Array(count); + for (let i = 0; i < count; i++) types[i] = readString(state); + return { names, types }; +} diff --git a/skills/clickhouse-js-node-rowbinary-parser/src/reader.ts b/skills/clickhouse-js-node-rowbinary-parser/src/reader.ts index bc20844cb..83bf57c33 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/src/reader.ts +++ b/skills/clickhouse-js-node-rowbinary-parser/src/reader.ts @@ -24,6 +24,20 @@ * lowCardinality (readLowCardinality), simpleAggregateFunction * (readSimpleAggregateFunction), nested (readNested), nothing (readNothing), * aggregateFunction (readAggregateFunction) + * + * Runtime schema path — compile a reader from the type STRINGS rather than + * hand-/code-generating one. Use this when the column types are not known until + * the response arrives (or you just want a generic decoder); for a fixed, + * known schema the specialized straight-line reader is faster. + * - header — readHeader: the RowBinaryWithNamesAndTypes preamble (column + * names + type strings) off the cursor + * - compile — astToReader: fold one parsed type AST (from + * `@clickhouse/datatype-parser`) into a value Reader. AST in, + * reader out — the type-to-combinator mapping, nothing else + * - rowBinaryWithNamesAndTypes — typeStringToReader (parse a type string + + * fold) and compileRowBinaryWithNamesAndTypes (read the header, + * compile every column, return a `readRows` driver for the rest of + * the stream): the end-to-end runtime entry point */ export * from "./core.js"; export * from "./varint.js"; @@ -49,3 +63,6 @@ export * from "./simpleAggregateFunction.js"; export * from "./nested.js"; export * from "./nothing.js"; export * from "./aggregateFunction.js"; +export * from "./header.js"; +export * from "./compile.js"; +export * from "./rowBinaryWithNamesAndTypes.js"; diff --git a/skills/clickhouse-js-node-rowbinary-parser/src/rowBinaryWithNamesAndTypes.ts b/skills/clickhouse-js-node-rowbinary-parser/src/rowBinaryWithNamesAndTypes.ts new file mode 100644 index 000000000..1965b4be1 --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/src/rowBinaryWithNamesAndTypes.ts @@ -0,0 +1,155 @@ +/** + * The `RowBinaryWithNamesAndTypes` entry point: read the header off a cursor, + * compile each column's type string into a reader, and hand back a driver that + * decodes the rest of the stream. + * + * This ties together the pieces: {@link readHeader} (wire), the parser + * (`@clickhouse/datatype-parser`), and {@link astToReader} (the AST → reader + * fold in `compile.ts`), then assembles a named-tuple row reader over the + * columns and a {@link readRows} driver for the row data. + */ + +import { parseDataType } from "@clickhouse/datatype-parser"; + +import type { Reader, Cursor } from "./core.js"; +import { readHeader } from "./header.js"; +import { readRows } from "./rows.js"; +import { astToReader, RowBinaryTypeError } from "./compile.js"; + +/** One decoded row, keyed by column name. */ +export type Row = Record; + +/** + * The product of compiling a `RowBinaryWithNamesAndTypes` header: the column + * metadata, the per-column readers, and — the headline — `readRows`, the + * {@link Reader} that decodes every remaining row of the stream. + */ +export interface CompiledStream { + /** Column names, in stream order (from the header). */ + names: string[]; + /** Column type strings, in stream order (from the header). */ + types: string[]; + /** One folded reader per column, in stream order. */ + columnReaders: Reader[]; + /** Reads exactly one row into a `{ [name]: value }` object. */ + readRow: Reader; + /** + * Reads the REST of the stream (all rows after the header) into an array. + * Streaming-aware via {@link readRows}: on a partial trailing row it rewinds + * to the last complete row and returns what it has. + */ + readRows: Reader; +} + +/** + * Parse one ClickHouse type string and fold it into a {@link Reader}. Throws a + * {@link RowBinaryTypeError} if the parser rejects the string (e.g. the + * deliberately unsupported `AggregateFunction` / `SimpleAggregateFunction`) — + * carrying the `typeString` and the parse `position`. + */ +export function typeStringToReader(typeStr: string): Reader { + const result = parseDataType(typeStr); + if (!result.ok()) { + const err = result.error!; + throw new RowBinaryTypeError( + `cannot compile type ${JSON.stringify(typeStr)}: ${err.message}`, + { typeString: typeStr, position: err.position }, + ); + } + return astToReader(result.ast!); +} + +/** Resolves a ClickHouse type string to a reader — `typeStringToReader` or a cache wrapping it. */ +export type TypeReaderResolver = (typeStr: string) => Reader; + +/** + * Build an LRU-cached {@link typeStringToReader}. The full ClickHouse type + * STRING is a perfect cache key: two columns of the same type compile to the + * same reader, and a reader is stateless (it only ever touches the cursor it is + * handed), so one instance is safe to share across columns and across streams — + * a cache hit skips the parse + AST fold entirely. + * + * Worth it when you decode many `RowBinaryWithNamesAndTypes` responses whose + * schemas overlap (e.g. the same query run repeatedly): keep one cache and pass + * it to {@link compileRowBinaryWithNamesAndTypes}, so a recurring type is + * compiled once rather than once per response. A single response rarely repeats + * a type across its own columns, so the win is across calls, not within one. + * + * Classic Map-based LRU: a `Map` iterates in insertion order, so on a HIT we + * delete + re-set the entry to move it to the most-recently-used end, and on + * overflow we evict the oldest key (the first the `Map` yields). `maxSize` caps + * memory. A parse FAILURE is never cached — {@link typeStringToReader} throws + * before anything is stored — so fixing a bad type is not shadowed by a cached + * error. + */ +export function createTypeReaderCache(maxSize = 256): TypeReaderResolver { + const cache = new Map>(); + return (typeStr) => { + const cached = cache.get(typeStr); + if (cached !== undefined) { + // Touch on hit. A Map iterates in INSERTION order, not usage order — so on + // its own `keys().next()` would give the oldest-added key, not the + // least-recently-USED one. Deleting and re-inserting moves this key to the + // tail, which is what turns insertion order INTO recency order: every + // access (hit here, or miss below) lands the key at the tail, leaving the + // head as the genuine least-recently-used entry. + cache.delete(typeStr); + cache.set(typeStr, cached); + return cached; + } + const reader = typeStringToReader(typeStr); // may throw — then nothing is cached + cache.set(typeStr, reader); + if (cache.size > maxSize) { + // The head is the least-recently-used key (see touch-on-hit above), so it + // is the correct one to evict. + const lru = cache.keys().next().value; + if (lru !== undefined) cache.delete(lru); + } + return reader; + }; +} + +/** + * The headline entry point. Reads the `RowBinaryWithNamesAndTypes` header off + * `state`, compiles each column type into a combinator reader, and returns the + * column metadata plus the readers — including `readRows`, the reader for the + * REST of the stream. After this call the cursor sits at the first row, so: + * + * const s = new Cursor(buf); + * const { names, readRows } = compileRowBinaryWithNamesAndTypes(s); + * const rows = readRows(s); // decode every remaining row + * + * Pass `resolveType` to reuse readers across calls — e.g. a shared + * {@link createTypeReaderCache}. It defaults to {@link typeStringToReader} + * (compile every column afresh). + */ +export function compileRowBinaryWithNamesAndTypes( + state: Cursor, + resolveType: TypeReaderResolver = typeStringToReader, +): CompiledStream { + const { names, types } = readHeader(state); + const columnReaders = types.map((t) => resolveType(t)); + + // Build the row reader POSITIONALLY — by column index, NOT by keying the + // readers on column name and handing them to `readTupleNamed`. The header is + // an ordered list and RowBinary has no row delimiter, so every row MUST read + // exactly these readers, in exactly this order. Keying readers by name first + // would corrupt the stream on legal-but-awkward headers: + // - duplicate column names (e.g. two `SELECT 1 AS x, 2 AS x`) collapse to a + // single entry in a `Record`, so fewer readers run than there are columns; + // - integer-like names (`0`, `1`, …) are reordered ahead of string keys by + // `Object.keys()`, so the readers would run out of header order. + // Either desyncs the cursor and misreads every subsequent row. Reading by + // index sidesteps both. The row OBJECT is still keyed by name; on a duplicate + // name the last column with that name wins in the object, but every column is + // still consumed off the wire in order, so the cursor stays in sync. + const readRow: Reader = (s) => { + const row: Row = {}; + for (let i = 0; i < columnReaders.length; i++) { + row[names[i]!] = columnReaders[i]!(s); + } + return row; + }; + + return { names, types, columnReaders, readRow, readRows: readRows(readRow) }; +} diff --git a/skills/clickhouse-js-node-rowbinary-parser/tests/compile.test.ts b/skills/clickhouse-js-node-rowbinary-parser/tests/compile.test.ts new file mode 100644 index 000000000..2c5e598ab --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/tests/compile.test.ts @@ -0,0 +1,114 @@ +import { describe, expect, it } from "vitest"; +import { parseDataType } from "@clickhouse/datatype-parser"; +import { query } from "./clickhouse.js"; +import { Cursor } from "../src/core.js"; +import { astToReader, RowBinaryTypeError } from "../src/compile.js"; + +// compile.ts is AST in, reader out. These tests exercise that fold directly: +// parse a type string, fold it to a Reader, and decode plain RowBinary value +// bytes (no header) from the server. The end-to-end header/stream path is +// covered in rowBinaryWithNamesAndTypes.test.ts. + +/** Parse a type string and fold its AST into a reader. */ +function reader(type: string) { + const result = parseDataType(type); + if (!result.ok()) throw new Error(`parse failed: ${result.error!.message}`); + return astToReader(result.ast!); +} + +/** Fold `type` to a reader and decode one `expr` value (`FORMAT RowBinary`). */ +async function fold(type: string, expr: string): Promise { + const read = reader(type); + const s = new Cursor(await query(`SELECT ${expr} FORMAT RowBinary`)); + const out = read(s); + expect(s.pos).toBe(s.buf.length); // the fold framed the bytes exactly + return out; +} + +describe("astToReader (AST -> Reader fold)", () => { + it("folds a scalar type", async () => { + expect(await fold("UInt32", "toUInt32(7)")).toEqual(7); + }); + + it("folds Nullable into a null-flag reader", async () => { + expect( + await fold("Nullable(UInt64)", "CAST(NULL AS Nullable(UInt64))"), + ).toEqual(null); + }); + + it("folds a nested composite (Array of Nullable)", async () => { + expect( + await fold( + "Array(Nullable(UInt32))", + "CAST([1, NULL, 3] AS Array(Nullable(UInt32)))", + ), + ).toEqual([1, null, 3]); + }); + + it("folds Map by recursing into key and value readers", async () => { + expect( + await fold( + "Map(String, UInt8)", + "CAST(map('a', 1) AS Map(String, UInt8))", + ), + ).toEqual(new Map([["a", 1]])); + }); + + it("folds an unnamed Tuple to a positional array", async () => { + expect( + await fold( + "Tuple(UInt8, String)", + "CAST((7, 'x') AS Tuple(UInt8, String))", + ), + ).toEqual([7, "x"]); + }); + + it("folds a named Tuple to an object", async () => { + expect( + await fold( + "Tuple(a UInt8, b String)", + "CAST((7, 'x') AS Tuple(a UInt8, b String))", + ), + ).toEqual({ a: 7, b: "x" }); + }); + + it("picks the Decimal width by precision (P=20 -> Decimal128)", async () => { + expect(await fold("Decimal(20, 4)", "CAST(1.5 AS Decimal(20, 4))")).toEqual( + [15000n, 4], + ); + }); + + it("folds Nested into Array(Tuple) of objects", async () => { + expect( + await fold( + "Nested(a UInt8, b String)", + "CAST([(1, 'a'), (2, 'b')] AS Nested(a UInt8, b String))", + ), + ).toEqual([ + { a: 1, b: "a" }, + { a: 2, b: "b" }, + ]); + }); + + it("folds Variant in sorted-by-name (discriminant) order", async () => { + // The wire discriminant indexes alternatives sorted by type name, so the + // reader must be folded from that sorted order — here Variant(String, UInt8). + // The server normalizes the column type to the same sorted form. + expect( + await fold( + "Variant(String, UInt8)", + "CAST(42 AS Variant(UInt8, String)) SETTINGS allow_experimental_variant_type=1", + ), + ).toEqual(42); + }); + + it("throws a typed RowBinaryTypeError for a non-type AST node (a Literal argument)", () => { + // FixedString(16)'s argument is a Literal — not a standalone column type. + const ast = parseDataType("FixedString(16)"); + const literalArg = ast.ast!.arguments[0]!; + expect(() => astToReader(literalArg)).toThrow(RowBinaryTypeError); + expect(() => astToReader(literalArg)).toThrow( + /cannot build a column reader/, + ); + }); +}); diff --git a/skills/clickhouse-js-node-rowbinary-parser/tests/readHeader.test.ts b/skills/clickhouse-js-node-rowbinary-parser/tests/readHeader.test.ts new file mode 100644 index 000000000..ab5a171d5 --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/tests/readHeader.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from "vitest"; +import { query } from "./clickhouse.js"; +import { Cursor } from "../src/core.js"; +import { readHeader } from "../src/header.js"; + +/** Fetch a `RowBinaryWithNamesAndTypes` response (header + rows) as a cursor. */ +async function withNamesAndTypes(select: string): Promise { + return new Cursor(await query(`${select} FORMAT RowBinaryWithNamesAndTypes`)); +} + +describe("readHeader", () => { + it("reads column count, names, then types and stops at the first row", async () => { + const s = await withNamesAndTypes("SELECT toUInt32(7) AS id, 'x' AS name"); + + expect(readHeader(s)).toEqual({ + names: ["id", "name"], + types: ["UInt32", "String"], + }); + // Cursor now points at the row payload (the first column's UInt32). + expect(s.buf.readUInt32LE(s.pos)).toBe(7); + }); +}); diff --git a/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.order.test.ts b/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.order.test.ts new file mode 100644 index 000000000..748cc6222 --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.order.test.ts @@ -0,0 +1,66 @@ +import { describe, expect, it } from "vitest"; +import { Cursor } from "../src/core.js"; +import { compileRowBinaryWithNamesAndTypes } from "../src/rowBinaryWithNamesAndTypes.js"; + +// Offline regression tests (no server) for the wire-order guarantee of the +// row reader: every row must read EXACTLY one reader per header column, in +// header order, regardless of the column NAMES. These pin the two legal +// headers that a name-keyed reader (Record + Object.keys) would +// mis-decode: duplicate names and integer-like names. + +/** LEB128-encode a non-negative integer. */ +function uvarint(n: number): number[] { + const out: number[] = []; + do { + let b = n & 0x7f; + n = Math.floor(n / 128); + if (n > 0) b |= 0x80; + out.push(b); + } while (n > 0); + return out; +} + +/** Encode a RowBinary `String` (LEB128 length + UTF-8 bytes). */ +function str(s: string): number[] { + const bytes = [...Buffer.from(s, "utf8")]; + return [...uvarint(bytes.length), ...bytes]; +} + +/** + * Build a full `RowBinaryWithNamesAndTypes` buffer by hand: the header (column + * count, names, type strings) followed by the raw row bytes. + */ +function stream(names: string[], types: string[], rowBytes: number[]): Cursor { + const header = [...uvarint(names.length)]; + for (const n of names) header.push(...str(n)); + for (const t of types) header.push(...str(t)); + return new Cursor(Buffer.from([...header, ...rowBytes])); +} + +describe("compileRowBinaryWithNamesAndTypes wire order", () => { + it("reads one reader per column even when column names collide", () => { + // Two UInt8 columns both named "x" (legal: `SELECT 1 AS x, 2 AS x`). A + // name-keyed reader would collapse to a single "x" reader and decode the + // 4 row bytes as FOUR one-column rows; reading by index gives two rows of + // two columns, last-name-wins in each object. + const s = stream(["x", "x"], ["UInt8", "UInt8"], [1, 2, 3, 4]); + const compiled = compileRowBinaryWithNamesAndTypes(s); + const rows = compiled.readRows(s); + + expect(rows).toEqual([{ x: 2 }, { x: 4 }]); + expect(s.pos).toBe(s.buf.length); // consumed exactly — no desync + }); + + it("reads columns in header order even when names are integer-like", () => { + // Columns named "1" (UInt8) then "0" (UInt16). `Object.keys()` would yield + // ["0", "1"] (numeric keys sort ascending), flipping the read order and + // mis-framing the bytes. Reading by index keeps header order. + // Row bytes: UInt8 = 0xAA (170), then UInt16 LE = 0x0102 (258). + const s = stream(["1", "0"], ["UInt8", "UInt16"], [0xaa, 0x02, 0x01]); + const compiled = compileRowBinaryWithNamesAndTypes(s); + const rows = compiled.readRows(s); + + expect(rows).toEqual([{ "1": 170, "0": 258 }]); + expect(s.pos).toBe(s.buf.length); // consumed exactly — no mis-framing + }); +}); diff --git a/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.test.ts b/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.test.ts new file mode 100644 index 000000000..a745d5466 --- /dev/null +++ b/skills/clickhouse-js-node-rowbinary-parser/tests/rowBinaryWithNamesAndTypes.test.ts @@ -0,0 +1,588 @@ +import { describe, expect, it } from "vitest"; +import { query } from "./clickhouse.js"; +import { Cursor } from "../src/core.js"; +import { + compileRowBinaryWithNamesAndTypes, + createTypeReaderCache, + typeStringToReader, + type Row, +} from "../src/rowBinaryWithNamesAndTypes.js"; +import { RowBinaryTypeError } from "../src/compile.js"; + +/** Raw value bytes for one expression (`FORMAT RowBinary`, no header). */ +async function rowBinary(expr: string): Promise { + return new Cursor(await query(`SELECT ${expr} FORMAT RowBinary`)); +} + +/** A full `RowBinaryWithNamesAndTypes` response (header + rows) as a cursor. */ +async function withNamesAndTypes(select: string): Promise { + return new Cursor(await query(`${select} FORMAT RowBinaryWithNamesAndTypes`)); +} + +/** + * Compile a `SELECT ... FORMAT RowBinaryWithNamesAndTypes` response and decode + * every row. Asserts the stream is consumed EXACTLY — the strongest single + * check that the fold picked the right reader for each column and framed the + * bytes correctly. Returns the header type strings and the decoded rows. + */ +async function decode( + select: string, +): Promise<{ types: string[]; rows: Row[] }> { + const s = await withNamesAndTypes(select); + const compiled = compileRowBinaryWithNamesAndTypes(s); + const rows = compiled.readRows(s); + expect(s.pos).toBe(s.buf.length); // consumed exactly — no under/over-read + return { types: compiled.types, rows }; +} + +/** Decode a single-column, single-row `... AS v` SELECT down to its value. */ +async function value(select: string): Promise { + const { rows } = await decode(select); + expect(rows).toHaveLength(1); + return rows[0]!.v; +} + +describe("typeStringToReader (AST -> combinator fold)", () => { + it("folds a nested composite type into a working reader", async () => { + const s = await rowBinary("CAST([1, NULL, 3] AS Array(Nullable(UInt32)))"); + expect(typeStringToReader("Array(Nullable(UInt32))")(s)).toEqual([ + 1, + null, + 3, + ]); + }); + + it("throws a typed RowBinaryTypeError (with typeString + position) for an unsupported type", () => { + const type = "AggregateFunction(sum, UInt64)"; + let err: unknown; + try { + typeStringToReader(type); + } catch (e) { + err = e; + } + expect(err).toBeInstanceOf(RowBinaryTypeError); + const typed = err as RowBinaryTypeError; + expect(typed.message).toMatch(/cannot compile type/); + expect(typed.typeString).toBe(type); + expect(typeof typed.position).toBe("number"); + }); +}); + +// The corpus below mirrors the parser's test/cases.txt, one it() per type or +// combination. Each value is the actual decode of a server-produced stream. +describe("scalars", () => { + it("UInt8", async () => { + expect(await value("SELECT toUInt8(255) AS v")).toEqual(255); + }); + it("UInt16", async () => { + expect(await value("SELECT toUInt16(65535) AS v")).toEqual(65535); + }); + it("UInt32", async () => { + expect(await value("SELECT toUInt32(4294967295) AS v")).toEqual(4294967295); + }); + it("UInt64", async () => { + expect(await value("SELECT toUInt64('18446744073709551615') AS v")).toEqual( + 18446744073709551615n, + ); + }); + it("UInt128", async () => { + expect( + await value( + "SELECT toUInt128('340282366920938463463374607431768211455') AS v", + ), + ).toEqual(340282366920938463463374607431768211455n); + }); + it("UInt256", async () => { + expect( + await value("SELECT toUInt256('123456789012345678901234567890') AS v"), + ).toEqual(123456789012345678901234567890n); + }); + it("Int8", async () => { + expect(await value("SELECT toInt8(-128) AS v")).toEqual(-128); + }); + it("Int16", async () => { + expect(await value("SELECT toInt16(-32768) AS v")).toEqual(-32768); + }); + it("Int32", async () => { + expect(await value("SELECT toInt32(-2147483648) AS v")).toEqual( + -2147483648, + ); + }); + it("Int64", async () => { + expect(await value("SELECT toInt64('-9223372036854775808') AS v")).toEqual( + -9223372036854775808n, + ); + }); + it("Int128", async () => { + expect( + await value( + "SELECT toInt128('-170141183460469231731687303715884105728') AS v", + ), + ).toEqual(-170141183460469231731687303715884105728n); + }); + it("Int256", async () => { + expect( + await value("SELECT toInt256('-123456789012345678901234567890') AS v"), + ).toEqual(-123456789012345678901234567890n); + }); + it("Float32", async () => { + expect(await value("SELECT toFloat32(1.5) AS v")).toEqual(1.5); + }); + it("Float64", async () => { + expect(await value("SELECT toFloat64(1.5) AS v")).toEqual(1.5); + }); + it("BFloat16", async () => { + expect(await value("SELECT CAST(1.5 AS BFloat16) AS v")).toEqual(1.5); + }); + it("Bool", async () => { + expect(await value("SELECT true AS v")).toEqual(true); + }); + it("String", async () => { + expect(await value("SELECT 'hello' AS v")).toEqual("hello"); + }); + it("FixedString(N)", async () => { + expect(await value("SELECT CAST('abcde' AS FixedString(5)) AS v")).toEqual( + "abcde", + ); + }); + it("UUID", async () => { + expect( + await value("SELECT toUUID('61f0c404-5cb3-11e7-907b-a6006ad3dba0') AS v"), + ).toEqual( + Buffer.from([ + 231, 17, 179, 92, 4, 196, 240, 97, 160, 219, 211, 106, 0, 166, 123, 144, + ]), + ); + }); + it("IPv4", async () => { + expect(await value("SELECT toIPv4('1.2.3.4') AS v")).toEqual(16909060); + }); + it("IPv6", async () => { + expect(await value("SELECT toIPv6('2001:db8::1') AS v")).toEqual( + Buffer.from([32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + ); + }); + it("Date", async () => { + expect(await value("SELECT toDate('2020-01-02') AS v")).toEqual( + new Date(1577923200000), + ); + }); + it("Date32", async () => { + expect(await value("SELECT toDate32('2020-01-02') AS v")).toEqual( + new Date(1577923200000), + ); + }); + it("DateTime", async () => { + expect( + await value("SELECT toDateTime('2020-01-02 03:04:05', 'UTC') AS v"), + ).toEqual(new Date(1577934245000)); + }); + it("DateTime64(3) -> [Date, nanoseconds]", async () => { + expect( + await value( + "SELECT toDateTime64('2020-01-02 03:04:05.123', 3, 'UTC') AS v", + ), + ).toEqual([new Date(1577934245000), 123000000]); + }); + it("DateTime64(9) -> [Date, nanoseconds]", async () => { + expect( + await value( + "SELECT toDateTime64('2020-01-02 03:04:05.123456789', 9, 'UTC') AS v", + ), + ).toEqual([new Date(1577934245000), 123456789]); + }); + it("Time -> seconds", async () => { + expect( + await value( + "SELECT CAST(3661 AS Time) AS v SETTINGS enable_time_time64_type=1", + ), + ).toEqual(3661); + }); + it("Time64(3) -> [ticks, precision]", async () => { + expect( + await value( + "SELECT CAST(3661.5 AS Time64(3)) AS v SETTINGS enable_time_time64_type=1", + ), + ).toEqual([3661500n, 3]); + }); +}); + +describe("decimals (width chosen by precision)", () => { + it("Decimal(10, 2) -> Decimal32 width, [unscaled, scale]", async () => { + const { types, rows } = await decode( + "SELECT CAST(1.5 AS Decimal(10, 2)) AS v", + ); + expect(types).toEqual(["Decimal(10, 2)"]); + expect(rows[0]!.v).toEqual([150n, 2]); + }); + it("Decimal(38, 10) -> Decimal128 width", async () => { + expect(await value("SELECT CAST(1.5 AS Decimal(38, 10)) AS v")).toEqual([ + 15000000000n, + 10, + ]); + }); + it("Decimal32(4) (header: Decimal(9, 4))", async () => { + const { types, rows } = await decode( + "SELECT CAST(1.5 AS Decimal32(4)) AS v", + ); + expect(types).toEqual(["Decimal(9, 4)"]); + expect(rows[0]!.v).toEqual([15000n, 4]); + }); + it("Decimal64(4) (header: Decimal(18, 4))", async () => { + expect(await value("SELECT CAST(1.5 AS Decimal64(4)) AS v")).toEqual([ + 15000n, + 4, + ]); + }); + it("Decimal128(10) (header: Decimal(38, 10))", async () => { + expect(await value("SELECT CAST(1.5 AS Decimal128(10)) AS v")).toEqual([ + 15000000000n, + 10, + ]); + }); + it("Decimal256(20) (header: Decimal(76, 20))", async () => { + expect(await value("SELECT CAST(1.5 AS Decimal256(20)) AS v")).toEqual([ + 150000000000000000000n, + 20, + ]); + }); +}); + +describe("enums (value is the underlying int)", () => { + it("Enum8", async () => { + expect( + await value("SELECT CAST('b' AS Enum8('a' = 1, 'b' = 2)) AS v"), + ).toEqual(2); + }); + it("Enum16", async () => { + expect( + await value("SELECT CAST('y' AS Enum16('x' = -1, 'y' = 100)) AS v"), + ).toEqual(100); + }); +}); + +describe("intervals (count as bigint; unit lives in the type name)", () => { + it("IntervalSecond", async () => { + expect(await value("SELECT INTERVAL 5 SECOND AS v")).toEqual(5n); + }); + it("IntervalDay", async () => { + expect(await value("SELECT INTERVAL 3 DAY AS v")).toEqual(3n); + }); +}); + +describe("geo", () => { + it("Point", async () => { + expect(await value("SELECT CAST((1.5, 2.5) AS Point) AS v")).toEqual([ + 1.5, 2.5, + ]); + }); + it("Ring", async () => { + expect( + await value("SELECT CAST([(0, 0), (1, 0), (1, 1)] AS Ring) AS v"), + ).toEqual([ + [0, 0], + [1, 0], + [1, 1], + ]); + }); + it("LineString", async () => { + expect( + await value("SELECT CAST([(0, 0), (1, 1)] AS LineString) AS v"), + ).toEqual([ + [0, 0], + [1, 1], + ]); + }); + it("Polygon", async () => { + expect( + await value("SELECT CAST([[(0, 0), (1, 0), (1, 1)]] AS Polygon) AS v"), + ).toEqual([ + [ + [0, 0], + [1, 0], + [1, 1], + ], + ]); + }); + it("MultiLineString", async () => { + expect( + await value("SELECT CAST([[(0, 0), (1, 1)]] AS MultiLineString) AS v"), + ).toEqual([ + [ + [0, 0], + [1, 1], + ], + ]); + }); + it("MultiPolygon", async () => { + expect( + await value( + "SELECT CAST([[[(0, 0), (1, 0), (1, 1)]]] AS MultiPolygon) AS v", + ), + ).toEqual([ + [ + [ + [0, 0], + [1, 0], + [1, 1], + ], + ], + ]); + }); +}); + +describe("composites (recurse into element/key/field readers)", () => { + it("Nullable(UInt64) — present", async () => { + expect(await value("SELECT CAST(7 AS Nullable(UInt64)) AS v")).toEqual(7n); + }); + it("Nullable(UInt64) — NULL", async () => { + expect(await value("SELECT CAST(NULL AS Nullable(UInt64)) AS v")).toEqual( + null, + ); + }); + it("Array(String)", async () => { + expect( + await value("SELECT CAST(['a', 'bb'] AS Array(String)) AS v"), + ).toEqual(["a", "bb"]); + }); + it("Array(Array(Int32))", async () => { + expect( + await value("SELECT CAST([[1], [2, 3]] AS Array(Array(Int32))) AS v"), + ).toEqual([[1], [2, 3]]); + }); + it("Array(Nullable(UInt64))", async () => { + expect( + await value("SELECT CAST([1, NULL, 3] AS Array(Nullable(UInt64))) AS v"), + ).toEqual([1n, null, 3n]); + }); + it("Map(String, UInt64)", async () => { + expect( + await value( + "SELECT CAST(map('a', 1, 'b', 2) AS Map(String, UInt64)) AS v", + ), + ).toEqual( + new Map([ + ["a", 1n], + ["b", 2n], + ]), + ); + }); + it("Map(String, Array(UInt8))", async () => { + expect( + await value( + "SELECT CAST(map('a', [1, 2]) AS Map(String, Array(UInt8))) AS v", + ), + ).toEqual(new Map([["a", [1, 2]]])); + }); + it("LowCardinality(String) — transparent", async () => { + expect( + await value("SELECT CAST('x' AS LowCardinality(String)) AS v"), + ).toEqual("x"); + }); + it("LowCardinality(Nullable(String)) — NULL", async () => { + expect( + await value("SELECT CAST(NULL AS LowCardinality(Nullable(String))) AS v"), + ).toEqual(null); + }); + it("Array(Tuple(Float64, Float64))", async () => { + expect( + await value( + "SELECT CAST([(1, 2), (3, 4)] AS Array(Tuple(Float64, Float64))) AS v", + ), + ).toEqual([ + [1, 2], + [3, 4], + ]); + }); + it("Tuple(UInt8, String) — positional array", async () => { + expect( + await value("SELECT CAST((7, 'x') AS Tuple(UInt8, String)) AS v"), + ).toEqual([7, "x"]); + }); + it("Tuple(a UInt8, b String) — named object", async () => { + expect( + await value("SELECT CAST((7, 'x') AS Tuple(a UInt8, b String)) AS v"), + ).toEqual({ a: 7, b: "x" }); + }); + it("Tuple(Decimal(10, 2), Nullable(String))", async () => { + expect( + await value( + "SELECT CAST((1.5, NULL) AS Tuple(Decimal(10, 2), Nullable(String))) AS v", + ), + ).toEqual([[150n, 2], null]); + }); + it("Nested(a UInt8, b String) — Array(Tuple) of objects", async () => { + expect( + await value( + "SELECT CAST([(1, 'a'), (2, 'b')] AS Nested(a UInt8, b String)) AS v", + ), + ).toEqual([ + { a: 1, b: "a" }, + { a: 2, b: "b" }, + ]); + }); + it("Variant(UInt8, String) — int alternative", async () => { + expect( + await value( + "SELECT CAST(42 AS Variant(UInt8, String)) AS v SETTINGS allow_experimental_variant_type=1", + ), + ).toEqual(42); + }); + it("Variant(UInt8, String) — string alternative", async () => { + expect( + await value( + "SELECT CAST('hi' AS Variant(UInt8, String)) AS v SETTINGS allow_experimental_variant_type=1", + ), + ).toEqual("hi"); + }); +}); + +describe("self-describing types", () => { + it("Dynamic", async () => { + expect( + await value( + "SELECT CAST(42 AS Dynamic) AS v SETTINGS allow_experimental_dynamic_type=1", + ), + ).toEqual(42); + }); + it("JSON", async () => { + expect( + await value( + `SELECT CAST('{"a":1}' AS JSON) AS v SETTINGS allow_experimental_json_type=1`, + ), + ).toEqual(new Map([["a", 1n]])); + }); +}); + +describe("SQL-standard aliases normalize to canonical types in the header", () => { + it("DOUBLE PRECISION -> Float64", async () => { + const { types, rows } = await decode( + "SELECT CAST(1.5 AS DOUBLE PRECISION) AS v", + ); + expect(types).toEqual(["Float64"]); + expect(rows[0]!.v).toEqual(1.5); + }); + it("REAL -> Float32", async () => { + const { types } = await decode("SELECT CAST(1.5 AS REAL) AS v"); + expect(types).toEqual(["Float32"]); + }); + it("VARCHAR -> String", async () => { + const { types, rows } = await decode( + "SELECT CAST('x' AS VARCHAR(10)) AS v", + ); + expect(types).toEqual(["String"]); + expect(rows[0]!.v).toEqual("x"); + }); + it("BIGINT -> Int64", async () => { + const { types } = await decode("SELECT CAST(1 AS BIGINT) AS v"); + expect(types).toEqual(["Int64"]); + }); + it("NUMERIC(10, 2) -> Decimal(10, 2)", async () => { + const { types, rows } = await decode( + "SELECT CAST(1.5 AS NUMERIC(10, 2)) AS v", + ); + expect(types).toEqual(["Decimal(10, 2)"]); + expect(rows[0]!.v).toEqual([150n, 2]); + }); + it("BINARY(4) -> FixedString(4)", async () => { + const { types, rows } = await decode( + "SELECT CAST('abcd' AS BINARY(4)) AS v", + ); + expect(types).toEqual(["FixedString(4)"]); + expect(rows[0]!.v).toEqual("abcd"); + }); +}); + +describe("compileRowBinaryWithNamesAndTypes", () => { + it("compiles a header and decodes the rest of the stream into rows", async () => { + const { names, types, rows } = await (async () => { + const s = await withNamesAndTypes(` + SELECT id, name, score FROM ( + SELECT toUInt32(1) AS id, CAST('alice' AS Nullable(String)) AS name, toFloat64(1.5) AS score + UNION ALL + SELECT toUInt32(2) AS id, CAST(NULL AS Nullable(String)) AS name, toFloat64(2.5) AS score + ) ORDER BY id + `); + const compiled = compileRowBinaryWithNamesAndTypes(s); + const decoded = compiled.readRows(s); + expect(s.pos).toBe(s.buf.length); + return { names: compiled.names, types: compiled.types, rows: decoded }; + })(); + + expect(names).toEqual(["id", "name", "score"]); + expect(types).toEqual(["UInt32", "Nullable(String)", "Float64"]); + expect(rows).toEqual([ + { id: 1, name: "alice", score: 1.5 }, + { id: 2, name: null, score: 2.5 }, + ]); + }); + + it("handles a named Tuple and a Map column", async () => { + const { rows } = await decode(` + SELECT + CAST((10, 20) AS Tuple(a UInt32, b UInt32)) AS pair, + CAST(map('x', toUInt32(1), 'y', toUInt32(2)) AS Map(String, UInt32)) AS counts + `); + + expect(rows).toHaveLength(1); + // A named Tuple folds to readTupleNamed -> an object keyed by field name. + expect(rows[0]!.pair).toEqual({ a: 10, b: 20 }); + expect(rows[0]!.counts).toEqual( + new Map([ + ["x", 1], + ["y", 2], + ]), + ); + }); + + it("accepts a custom resolver (a shared reader cache)", async () => { + const cache = createTypeReaderCache(); + let calls = 0; + const resolve = (t: string) => { + calls++; + return cache(t); + }; + + const s = await withNamesAndTypes("SELECT toUInt32(1) AS id, 'x' AS name"); + const compiled = compileRowBinaryWithNamesAndTypes(s, resolve); + expect(compiled.readRows(s)).toEqual([{ id: 1, name: "x" }]); + expect(calls).toBe(2); // resolver consulted once per column + }); +}); + +describe("createTypeReaderCache (LRU, keyed by type string)", () => { + it("returns the same reader instance for a repeated type, distinct for others", () => { + const cache = createTypeReaderCache(); + const a = cache("Array(UInt8)"); + expect(cache("Array(UInt8)")).toBe(a); // hit -> same instance + expect(cache("Array(UInt16)")).not.toBe(a); // different type -> different reader + }); + + it("evicts least-recently-used past maxSize, but a hit refreshes recency", () => { + // Use composite types: each compile of e.g. `Array(UInt8)` allocates a FRESH + // closure (readArray(...)), so instance identity actually reflects the cache. + // (A nullary scalar like `UInt8` returns the shared module-level readUInt8 + // singleton every time, so it could never show an eviction.) + const cache = createTypeReaderCache(2); + const a1 = cache("Array(UInt8)"); // [A8] + const b1 = cache("Array(UInt16)"); // [A8, A16] + expect(cache("Array(UInt8)")).toBe(a1); // hit -> refresh -> [A16, A8] + + cache("Array(UInt32)"); // insert -> size 3 -> evict LRU (A16) -> [A8, A32] + + // Array(UInt8) was refreshed by the hit above, so it survived (same closure). + expect(cache("Array(UInt8)")).toBe(a1); + // Array(UInt16) was the least-recently-used, so it was evicted and now + // recompiles to a DIFFERENT closure — this is what proves eviction happened. + expect(cache("Array(UInt16)")).not.toBe(b1); + }); + + it("does not cache a parse failure", () => { + const cache = createTypeReaderCache(); + expect(() => cache("AggregateFunction(sum, UInt64)")).toThrow( + /cannot compile type/, + ); + // A valid type still resolves afterwards (the failure left no poisoned entry). + expect(typeof cache("UInt8")).toBe("function"); + }); +}); diff --git a/type-parser/mini-parser-ts/package-lock.json b/type-parser/mini-parser-ts/package-lock.json deleted file mode 100644 index d2ed1934d..000000000 --- a/type-parser/mini-parser-ts/package-lock.json +++ /dev/null @@ -1,551 +0,0 @@ -{ - "name": "chdt-datatype-parser", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "chdt-datatype-parser", - "version": "0.1.0", - "bin": { - "chdt-parse": "dist/tool/main.js" - }, - "devDependencies": { - "tsx": "^4.22.4", - "typescript": "^5.6.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/tsx": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz", - "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.28.0" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - } - } -} diff --git a/type-parser/mini-parser-ts/test/parser.test.ts b/type-parser/mini-parser-ts/test/parser.test.ts deleted file mode 100644 index d68753bb7..000000000 --- a/type-parser/mini-parser-ts/test/parser.test.ts +++ /dev/null @@ -1,132 +0,0 @@ -/// Dependency-free unit tests (no ClickHouse binary required). -/// Run with: npm test (node --import tsx --test test/*.test.ts) -/// -/// The exhaustive server-equivalence check lives in oracle_compare.ts; these -/// pin a few representative shapes and all the deliberate rejections so `npm -/// test` is meaningful on its own. - -import { strict as assert } from "node:assert"; -import { test } from "node:test"; -import { fileURLToPath } from "node:url"; -import { dirname, join } from "node:path"; - -import { parseDataType, toJSON } from "../src/index.js"; -import { readCases } from "./cases.js"; - -const here = dirname(fileURLToPath(import.meta.url)); - -function json(typeStr: string): unknown { - const r = parseDataType(typeStr); - assert.ok(r.ok(), `expected ${typeStr} to parse: ${r.error?.message}`); - return JSON.parse(toJSON(r.ast!)); -} - -test("scalar type omits the arguments slot", () => { - assert.deepEqual(json("UInt8"), { type: "DataType", name: "UInt8" }); -}); - -test("nested parametric type", () => { - assert.deepEqual(json("Array(Nullable(UInt64))"), { - type: "DataType", - name: "Array", - arguments: [ - { - type: "DataType", - name: "Nullable", - arguments: [{ type: "DataType", name: "UInt64" }], - }, - ], - }); -}); - -test("literal arguments: 64-bit ints are JSON strings, scale is a string too", () => { - assert.deepEqual(json("Decimal(10, 2)"), { - type: "DataType", - name: "Decimal", - arguments: [ - { type: "Literal", value_type: "UInt64", value: "10" }, - { type: "Literal", value_type: "UInt64", value: "2" }, - ], - }); -}); - -test("explicit enum becomes EnumDataType with numeric values", () => { - assert.deepEqual(json("Enum16('x' = -1, 'y' = 100)"), { - type: "EnumDataType", - name: "Enum16", - values: [ - { name: "x", value: -1 }, - { name: "y", value: 100 }, - ], - }); -}); - -test("auto-assigned enum falls back to a generic DataType (not EnumDataType)", () => { - const v = json("Enum8('a', 'b')") as { type: string }; - assert.equal(v.type, "DataType"); -}); - -test("named tuple carries element_names", () => { - assert.deepEqual(json("Tuple(a UInt8, b String)"), { - type: "TupleDataType", - name: "Tuple", - arguments: [ - { type: "DataType", name: "UInt8" }, - { type: "DataType", name: "String" }, - ], - element_names: ["a", "b"], - }); -}); - -test("unnamed tuple omits element_names", () => { - const v = json("Tuple(UInt8, String)") as Record; - assert.equal("element_names" in v, false); -}); - -test("Dynamic(max_types = 5) parses to an equals Function argument", () => { - assert.deepEqual(json("Dynamic(max_types = 5)"), { - type: "DataType", - name: "Dynamic", - arguments: [ - { - type: "Function", - name: "equals", - is_operator: true, - arguments: [ - { type: "Identifier", name: "max_types" }, - { type: "Literal", value_type: "UInt64", value: "5" }, - ], - }, - ], - }); -}); - -test("SQL-standard multi-word alias", () => { - assert.deepEqual(json("DOUBLE PRECISION"), { - type: "DataType", - name: "DOUBLE PRECISION", - }); -}); - -test("compact output has no whitespace", () => { - const r = parseDataType("Array(String)"); - assert.ok(r.ok()); - assert.equal( - toJSON(r.ast!, -1), - '{"type":"DataType","name":"Array","arguments":[{"type":"DataType","name":"String"}]}', - ); -}); - -test("deliberately-unsupported types are rejected with a hard error", () => { - for (const typeStr of readCases(join(here, "cases_unsupported.txt"))) { - const r = parseDataType(typeStr); - assert.equal(r.ok(), false, `expected ${typeStr} to be rejected`); - assert.ok(r.error && r.error.message.length > 0); - } -}); - -test("trailing input after a complete type is an error", () => { - const r = parseDataType("UInt8 garbage"); - assert.equal(r.ok(), false); - assert.match(r.error!.message, /trailing input/); -}); diff --git a/type-parser/mini-parser-ts/tool/main.ts b/type-parser/mini-parser-ts/tool/main.ts deleted file mode 100644 index 3453bc7b4..000000000 --- a/type-parser/mini-parser-ts/tool/main.ts +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env node -/// chdt-parse: read a ClickHouse data-type string and print its JSON AST. -/// -/// chdt-parse "Array(Nullable(UInt64))" # type from arguments -/// echo "Tuple(a UInt8, b String)" | chdt-parse # type from stdin -/// -/// Prints the JSON AST and exits 0 on success. On a parse error, prints -/// "error: (at byte N)" to stderr and exits 1. -/// -/// A TypeScript port of the C++ `tool/main.cpp`. - -import { readFileSync } from "node:fs"; - -import { parseDataType, toJSON } from "../src/index.js"; - -function readStdin(): string { - try { - /// fd 0 = stdin. Read synchronously so the CLI behaves like the C++ one. - return readFileSync(0, "utf8"); - } catch { - return ""; - } -} - -function main(argv: string[]): number { - let input: string; - if (argv.length > 0) { - input = argv.join(" "); - } else { - input = readStdin(); - } - - /// Trim trailing newline/whitespace from stdin. - input = input.replace(/[\n\r \t]+$/, ""); - - const result = parseDataType(input); - if (!result.ok()) { - const err = result.error!; - process.stderr.write(`error: ${err.message} (at byte ${err.position})\n`); - return 1; - } - - process.stdout.write(toJSON(result.ast!) + "\n"); - return 0; -} - -process.exit(main(process.argv.slice(2))); diff --git a/type-parser/mini-parser-ts/tsconfig.build.json b/type-parser/mini-parser-ts/tsconfig.build.json deleted file mode 100644 index f41ec42b7..000000000 --- a/type-parser/mini-parser-ts/tsconfig.build.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "comment": "Build config for publishing: emits only the library (src) + CLI (tool), never the test harness.", - "include": ["src/**/*.ts", "tool/**/*.ts"] -} From c2f3ae0b6330a393316e7602c1ce5b15a5c657fa Mon Sep 17 00:00:00 2001 From: Peter Leonov Date: Sat, 27 Jun 2026 21:52:59 +0200 Subject: [PATCH 2/3] ci: add publish workflow for @clickhouse/datatype-parser (#894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Adds `.github/workflows/publish-datatype-parser.yml`, an independent manual publish + release workflow for the standalone `@clickhouse/datatype-parser` package. It's a clone of `publish-skill-rowbinary-parser.yml` adapted for the new package. Like the rowbinary workflow, this is **not** part of the lockstep workspace release (`publish.yml`): the package carries its own version in `packages/datatype-parser/package.json` and ships on its own cadence, dispatched manually from the protected `release` branch. ## Changes vs. the rowbinary clone - **Working dir**: `packages/datatype-parser` - **Smoke tests**: this package has only a `.` export (no subpaths), so the pre-publish and e2e smoke tests import `@clickhouse/datatype-parser` and assert `parseDataType` is a function (dropped the `/integers` / `readUInt8` / `readRows` checks) - **Git tag prefix**: `datatype-parser-v*` - Header comment updated; dropped the rowbinary-specific "copies repo-root LICENSE" note (this package ships its own `LICENSE`) Unchanged: release-branch guard, npm OIDC + provenance, Node 24 build / 20·22·24 e2e matrix, registry poll. ## Notes As with the rowbinary workflow, this assumes the version in `package.json` is bumped manually before dispatching, and that it's run from the `release` branch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- .github/workflows/publish-datatype-parser.yml | 176 ++++++++++++++++++ package-lock.json | 2 +- packages/datatype-parser/package.json | 2 +- 3 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish-datatype-parser.yml diff --git a/.github/workflows/publish-datatype-parser.yml b/.github/workflows/publish-datatype-parser.yml new file mode 100644 index 000000000..4dc7fdead --- /dev/null +++ b/.github/workflows/publish-datatype-parser.yml @@ -0,0 +1,176 @@ +name: "publish: datatype parser" + +# Independent publish + release for the standalone @clickhouse/datatype-parser +# package (the data-type string parser). It is NOT part of the npm workspace +# lockstep release driven by publish.yml — it carries its own version in +# packages/datatype-parser/package.json and ships on its own cadence. Triggered +# manually, and — like publish.yml — must be dispatched from the `release` +# branch: the npm-publish environment is protected so only that branch may +# deploy (the repo's human-in-the-loop release gate). Dispatches from any other +# ref are skipped by the job-level `if` guard below. +# +# The release branch is itself protected, so the unit suite is not re-run here. +# The `publish` job instead builds, packs the tarball, installs that exact +# tarball into a throwaway project and smoke-tests its imports, and only then +# publishes the same tarball with the "latest" tag (npm OIDC + provenance) and +# pushes a matching git tag. The `e2e` job then repeats the smoke test against +# the freshly published version on the registry across the supported Node +# versions. + +permissions: + contents: read + id-token: write # Required for npm OIDC authentication and provenance + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +on: + workflow_dispatch: + +jobs: + publish: + # The npm-publish environment only permits the release branch to deploy; + # skip cleanly on any other ref instead of failing the protection check. + if: github.ref == 'refs/heads/release' + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: npm-publish + permissions: + contents: write # Required to push the release git tag + id-token: write # Required for npm OIDC authentication and provenance + defaults: + run: + working-directory: packages/datatype-parser + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Node.js + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: 24 + registry-url: "https://registry.npmjs.org" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Get the release version + id: version + run: | + VERSION=$(node -p "require('./package.json').version") + echo "Publishing @clickhouse/datatype-parser@$VERSION" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Pack the tarball + id: pack + # prepack rebuilds dist before packing. + run: | + set -euo pipefail + TARBALL=$(npm pack --pack-destination "$RUNNER_TEMP" | tail -1) + echo "Packed: $TARBALL" + echo "tarball=$RUNNER_TEMP/$TARBALL" >> "$GITHUB_OUTPUT" + + - name: Pre-publish smoke test (install the packed tarball) + env: + TARBALL: ${{ steps.pack.outputs.tarball }} + run: | + set -euo pipefail + work="$(mktemp -d)" + cd "$work" + npm init -y >/dev/null 2>&1 + npm install "$TARBALL" + # Verify the main barrel entry resolves and exposes the parser, from + # the exact artifact we are about to publish. + node --input-type=module -e " + import * as dt from '@clickhouse/datatype-parser'; + if (typeof dt.parseDataType !== 'function') throw new Error('parseDataType missing from main export'); + console.log('OK: packed tarball imports cleanly'); + " + + - name: Publish to npm + # Publish the exact tarball that passed the pre-publish smoke test. + env: + TARBALL: ${{ steps.pack.outputs.tarball }} + run: npm publish "$TARBALL" --access public --provenance + + - name: Create and push release git tag + env: + RELEASE_TAG: datatype-parser-v${{ steps.version.outputs.version }} + RELEASE_VERSION: ${{ steps.version.outputs.version }} + run: | + if git ls-remote --exit-code --tags origin "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then + echo "Tag ${RELEASE_TAG} already exists on origin; skipping." + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git tag -a "${RELEASE_TAG}" -m "Release @clickhouse/datatype-parser ${RELEASE_VERSION}" + git push origin "refs/tags/${RELEASE_TAG}" + + e2e: + name: e2e (node ${{ matrix.node }}) + needs: publish + if: needs.publish.result == 'success' + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: true + matrix: + node: [20, 22, 24] + env: + PUBLISHED_VERSION: ${{ needs.publish.outputs.version }} + steps: + - name: Setup NodeJS ${{ matrix.node }} + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: ${{ matrix.node }} + registry-url: "https://registry.npmjs.org" + + - name: Wait for @clickhouse/datatype-parser@${{ needs.publish.outputs.version }} on npm + run: | + set -euo pipefail + if [ -z "${PUBLISHED_VERSION}" ]; then + echo "PUBLISHED_VERSION is empty; cannot wait for npm publication." >&2 + exit 1 + fi + pkg="@clickhouse/datatype-parser" + # Poll the registry for up to ~5 minutes. New versions usually surface + # in seconds, but the registry CDN can lag. + max_attempts=60 + sleep_seconds=5 + attempt=1 + echo "Waiting for ${pkg}@${PUBLISHED_VERSION} to be available on npm..." + while true; do + if npm view "${pkg}@${PUBLISHED_VERSION}" version >/dev/null 2>&1; then + echo " ${pkg}@${PUBLISHED_VERSION} is available." + break + fi + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Timed out waiting for ${pkg}@${PUBLISHED_VERSION} on npm" >&2 + exit 1 + fi + echo " attempt ${attempt}/${max_attempts}: not available yet, sleeping ${sleep_seconds}s..." + attempt=$((attempt + 1)) + sleep "$sleep_seconds" + done + + - name: Install and import the published package + run: | + set -euo pipefail + work="$(mktemp -d)" + cd "$work" + npm init -y >/dev/null 2>&1 + npm install "@clickhouse/datatype-parser@${PUBLISHED_VERSION}" + # Verify the main barrel entry resolves and exposes the parser to a + # downstream consumer. + node --input-type=module -e " + import * as dt from '@clickhouse/datatype-parser'; + if (typeof dt.parseDataType !== 'function') throw new Error('parseDataType missing from main export'); + console.log('OK: @clickhouse/datatype-parser@${PUBLISHED_VERSION} imports cleanly'); + " diff --git a/package-lock.json b/package-lock.json index 2451c96c1..20dbe4381 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7720,7 +7720,7 @@ }, "packages/datatype-parser": { "name": "@clickhouse/datatype-parser", - "version": "0.1.1", + "version": "0.1.2", "license": "Apache-2.0", "devDependencies": { "tsx": "^4.22.4", diff --git a/packages/datatype-parser/package.json b/packages/datatype-parser/package.json index e4fc83130..d410cacc7 100644 --- a/packages/datatype-parser/package.json +++ b/packages/datatype-parser/package.json @@ -1,6 +1,6 @@ { "name": "@clickhouse/datatype-parser", - "version": "0.1.1", + "version": "0.1.2", "description": "Standalone ClickHouse data-type string parser — a TypeScript port of the chdt C++ library.", "license": "Apache-2.0", "type": "module", From c85f0666a9700bd316cc471a73571157e7bcc062 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Jun 2026 20:05:36 +0000 Subject: [PATCH 3/3] Bump @clickhouse/datatype-parser to 0.1.2 in the rowbinary skill (#895) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Updates the `@clickhouse/datatype-parser` dependency in the `clickhouse-js-node-rowbinary-parser` skill from `^0.1.1` to `^0.1.2`, matching the current in-repo `packages/datatype-parser` version. - **`package.json`** — dependency range `^0.1.1` → `^0.1.2`. - **`package-lock.json`** — root requirement plus the `@clickhouse/datatype-parser` entry (`version`, `resolved`, `integrity`) updated to 0.1.2. Integrity derived from an `npm pack` of the in-repo workspace on Node 24 (matching the publish workflow), so it should match the registry publish. Note: `0.1.2` is not yet on npm — this is intended to land alongside the datatype-parser publish workflow run, consistent with the standalone-package release flow. The skill's CI exercises the parser via a locally-packed tarball (`npm install --no-save`), which verifies against this checkout. ## Checklist - [ ] A human-readable description of the changes was provided to include in CHANGELOG Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- .../clickhouse-js-node-rowbinary-parser/package-lock.json | 8 ++++---- skills/clickhouse-js-node-rowbinary-parser/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/skills/clickhouse-js-node-rowbinary-parser/package-lock.json b/skills/clickhouse-js-node-rowbinary-parser/package-lock.json index 09a2bf693..4a8e49dd2 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/package-lock.json +++ b/skills/clickhouse-js-node-rowbinary-parser/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.1", "license": "Apache-2.0", "dependencies": { - "@clickhouse/datatype-parser": "^0.1.1" + "@clickhouse/datatype-parser": "^0.1.2" }, "devDependencies": { "@types/node": "^26.0.0", @@ -21,9 +21,9 @@ } }, "node_modules/@clickhouse/datatype-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@clickhouse/datatype-parser/-/datatype-parser-0.1.1.tgz", - "integrity": "sha512-G4QzkEJ1k27rM8x71pX5ZQVh0HhPcaU+bj2PYOGbvLsVGOIDk5Ky09GpC7OzLYxA9WiSCMd6f9kT/yc/CySZJA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@clickhouse/datatype-parser/-/datatype-parser-0.1.2.tgz", + "integrity": "sha512-gYYRfOQ8nNahrhTZAiJn+RZR0ud3bTzkCWDaiRe6GvdlnPkq3Ew+gAAS2QK8NJ5XBp5mpybiPvKWSs0C0rNFBA==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" diff --git a/skills/clickhouse-js-node-rowbinary-parser/package.json b/skills/clickhouse-js-node-rowbinary-parser/package.json index 984cb0b67..ecc8c6476 100644 --- a/skills/clickhouse-js-node-rowbinary-parser/package.json +++ b/skills/clickhouse-js-node-rowbinary-parser/package.json @@ -62,7 +62,7 @@ "prepack": "cp ../../LICENSE . && npm run build" }, "dependencies": { - "@clickhouse/datatype-parser": "^0.1.1" + "@clickhouse/datatype-parser": "^0.1.2" }, "devDependencies": { "@types/node": "^26.0.0",