summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--package.json13
-rw-r--r--pnpm-lock.yaml629
-rw-r--r--src/lang/ks-lang/index.ts3
-rw-r--r--test/test.ts19
-rw-r--r--tests/type-consistency/generateAll.ts5
-rw-r--r--tests/type-consistency/harness.ts85
-rw-r--r--tests/type-consistency/spec/array.ts17
-rw-r--r--tests/type-consistency/spec/function.ts26
-rw-r--r--tests/type-consistency/spec/index.ts4
10 files changed, 778 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
index f882c7a..807a81b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.vscode
node_modules
-dist \ No newline at end of file
+dist
+tests/**/generated \ No newline at end of file
diff --git a/package.json b/package.json
index 86261db..da58a1a 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,9 @@
"url": "git+https://git.aberrantflux.xyz/kai-script.git/"
},
"scripts": {
- "build": "tsc"
+ "build": "tsc",
+ "generate-tests": "rm -f tests/type-consistency/generated/*.test.ts && tsx tests/type-consistency/generateAll.ts",
+ "test": "pnpm run generate-tests && vitest run --reporter verbose"
},
"exports": {
"types": "./dist/index.d.ts",
@@ -21,9 +23,14 @@
"pnpm-lock.yaml",
"tsconfig.json"
],
+ "dependencies": {
+ "typescript": "5.9.3",
+ "node": "^25.1.0"
+ },
"devDependencies": {
- "typescript": "^5.9.3",
- "tsx": "^4.19.2"
+ "tsx": "^4.19.2",
+ "vitest": "^4.0.8",
+ "@types/node": "^24.10.0"
},
"publishConfig": {
"access": "public"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 42f4476..a65d3de 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,13 +7,23 @@ settings:
importers:
.:
+ dependencies:
+ node:
+ specifier: ^25.1.0
+ version: 25.1.0
+ typescript:
+ specifier: 5.9.3
+ version: 5.9.3
devDependencies:
+ '@types/node':
+ specifier: ^24.10.0
+ version: 24.10.0
tsx:
specifier: ^4.19.2
version: 4.20.6
- typescript:
- specifier: ^5.9.3
- version: 5.9.3
+ vitest:
+ specifier: ^4.0.8
+ version: 4.0.8(@types/node@24.10.0)(tsx@4.20.6)
packages:
@@ -173,11 +183,204 @@ packages:
cpu: [x64]
os: [win32]
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@rollup/rollup-android-arm-eabi@4.53.1':
+ resolution: {integrity: sha512-bxZtughE4VNVJlL1RdoSE545kc4JxL7op57KKoi59/gwuU5rV6jLWFXXc8jwgFoT6vtj+ZjO+Z2C5nrY0Cl6wA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.53.1':
+ resolution: {integrity: sha512-44a1hreb02cAAfAKmZfXVercPFaDjqXCK+iKeVOlJ9ltvnO6QqsBHgKVPTu+MJHSLLeMEUbeG2qiDYgbFPU48g==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.53.1':
+ resolution: {integrity: sha512-usmzIgD0rf1syoOZ2WZvy8YpXK5G1V3btm3QZddoGSa6mOgfXWkkv+642bfUUldomgrbiLQGrPryb7DXLovPWQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.53.1':
+ resolution: {integrity: sha512-is3r/k4vig2Gt8mKtTlzzyaSQ+hd87kDxiN3uDSDwggJLUV56Umli6OoL+/YZa/KvtdrdyNfMKHzL/P4siOOmg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.53.1':
+ resolution: {integrity: sha512-QJ1ksgp/bDJkZB4daldVmHaEQkG4r8PUXitCOC2WRmRaSaHx5RwPoI3DHVfXKwDkB+Sk6auFI/+JHacTekPRSw==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.53.1':
+ resolution: {integrity: sha512-J6ma5xgAzvqsnU6a0+jgGX/gvoGokqpkx6zY4cWizRrm0ffhHDpJKQgC8dtDb3+MqfZDIqs64REbfHDMzxLMqQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.53.1':
+ resolution: {integrity: sha512-JzWRR41o2U3/KMNKRuZNsDUAcAVUYhsPuMlx5RUldw0E4lvSIXFUwejtYz1HJXohUmqs/M6BBJAUBzKXZVddbg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.53.1':
+ resolution: {integrity: sha512-L8kRIrnfMrEoHLHtHn+4uYA52fiLDEDyezgxZtGUTiII/yb04Krq+vk3P2Try+Vya9LeCE9ZHU8CXD6J9EhzHQ==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.53.1':
+ resolution: {integrity: sha512-ysAc0MFRV+WtQ8li8hi3EoFi7us6d1UzaS/+Dp7FYZfg3NdDljGMoVyiIp6Ucz7uhlYDBZ/zt6XI0YEZbUO11Q==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.53.1':
+ resolution: {integrity: sha512-UV6l9MJpDbDZZ/fJvqNcvO1PcivGEf1AvKuTcHoLjVZVFeAMygnamCTDikCVMRnA+qJe+B3pSbgX2+lBMqgBhA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.53.1':
+ resolution: {integrity: sha512-UDUtelEprkA85g95Q+nj3Xf0M4hHa4DiJ+3P3h4BuGliY4NReYYqwlc0Y8ICLjN4+uIgCEvaygYlpf0hUj90Yg==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.53.1':
+ resolution: {integrity: sha512-vrRn+BYhEtNOte/zbc2wAUQReJXxEx2URfTol6OEfY2zFEUK92pkFBSXRylDM7aHi+YqEPJt9/ABYzmcrS4SgQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.53.1':
+ resolution: {integrity: sha512-gto/1CxHyi4A7YqZZNznQYrVlPSaodOBPKM+6xcDSCMVZN/Fzb4K+AIkNz/1yAYz9h3Ng+e2fY9H6bgawVq17w==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.53.1':
+ resolution: {integrity: sha512-KZ6Vx7jAw3aLNjFR8eYVcQVdFa/cvBzDNRFM3z7XhNNunWjA03eUrEwJYPk0G8V7Gs08IThFKcAPS4WY/ybIrQ==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.53.1':
+ resolution: {integrity: sha512-HvEixy2s/rWNgpwyKpXJcHmE7om1M89hxBTBi9Fs6zVuLU4gOrEMQNbNsN/tBVIMbLyysz/iwNiGtMOpLAOlvA==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.53.1':
+ resolution: {integrity: sha512-E/n8x2MSjAQgjj9IixO4UeEUeqXLtiA7pyoXCFYLuXpBA/t2hnbIdxHfA7kK9BFsYAoNU4st1rHYdldl8dTqGA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.53.1':
+ resolution: {integrity: sha512-IhJ087PbLOQXCN6Ui/3FUkI9pWNZe/Z7rEIVOzMsOs1/HSAECCvSZ7PkIbkNqL/AZn6WbZvnoVZw/qwqYMo4/w==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openharmony-arm64@4.53.1':
+ resolution: {integrity: sha512-0++oPNgLJHBblreu0SFM7b3mAsBJBTY0Ksrmu9N6ZVrPiTkRgda52mWR7TKhHAsUb9noCjFvAw9l6ZO1yzaVbA==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.53.1':
+ resolution: {integrity: sha512-VJXivz61c5uVdbmitLkDlbcTk9Or43YC2QVLRkqp86QoeFSqI81bNgjhttqhKNMKnQMWnecOCm7lZz4s+WLGpQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.53.1':
+ resolution: {integrity: sha512-NmZPVTUOitCXUH6erJDzTQ/jotYw4CnkMDjCYRxNHVD9bNyfrGoIse684F9okwzKCV4AIHRbUkeTBc9F2OOH5Q==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.53.1':
+ resolution: {integrity: sha512-2SNj7COIdAf6yliSpLdLG8BEsp5lgzRehgfkP0Av8zKfQFKku6JcvbobvHASPJu4f3BFxej5g+HuQPvqPhHvpQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.53.1':
+ resolution: {integrity: sha512-rLarc1Ofcs3DHtgSzFO31pZsCh8g05R2azN1q3fF+H423Co87My0R+tazOEvYVKXSLh8C4LerMK41/K7wlklcg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@standard-schema/spec@1.0.0':
+ resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/node@24.10.0':
+ resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==}
+
+ '@vitest/expect@4.0.8':
+ resolution: {integrity: sha512-Rv0eabdP/xjAHQGr8cjBm+NnLHNoL268lMDK85w2aAGLFoVKLd8QGnVon5lLtkXQCoYaNL0wg04EGnyKkkKhPA==}
+
+ '@vitest/mocker@4.0.8':
+ resolution: {integrity: sha512-9FRM3MZCedXH3+pIh+ME5Up2NBBHDq0wqwhOKkN4VnvCiKbVxddqH9mSGPZeawjd12pCOGnl+lo/ZGHt0/dQSg==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0-0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@4.0.8':
+ resolution: {integrity: sha512-qRrjdRkINi9DaZHAimV+8ia9Gq6LeGz2CgIEmMLz3sBDYV53EsnLZbJMR1q84z1HZCMsf7s0orDgZn7ScXsZKg==}
+
+ '@vitest/runner@4.0.8':
+ resolution: {integrity: sha512-mdY8Sf1gsM8hKJUQfiPT3pn1n8RF4QBcJYFslgWh41JTfrK1cbqY8whpGCFzBl45LN028g0njLCYm0d7XxSaQQ==}
+
+ '@vitest/snapshot@4.0.8':
+ resolution: {integrity: sha512-Nar9OTU03KGiubrIOFhcfHg8FYaRaNT+bh5VUlNz8stFhCZPNrJvmZkhsr1jtaYvuefYFwK2Hwrq026u4uPWCw==}
+
+ '@vitest/spy@4.0.8':
+ resolution: {integrity: sha512-nvGVqUunyCgZH7kmo+Ord4WgZ7lN0sOULYXUOYuHr55dvg9YvMz3izfB189Pgp28w0vWFbEEfNc/c3VTrqrXeA==}
+
+ '@vitest/utils@4.0.8':
+ resolution: {integrity: sha512-pdk2phO5NDvEFfUTxcTP8RFYjVj/kfLSPIN5ebP2Mu9kcIMeAQTbknqcFEyBcC4z2pJlJI9aS5UQjcYfhmKAow==}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ chai@6.2.0:
+ resolution: {integrity: sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==}
+ engines: {node: '>=18'}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ es-module-lexer@1.7.0:
+ resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
+
esbuild@0.25.12:
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
engines: {node: '>=18'}
hasBin: true
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ expect-type@1.2.2:
+ resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
+ engines: {node: '>=12.0.0'}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -186,9 +389,74 @@ packages:
get-tsconfig@4.13.0:
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node-bin-setup@1.1.4:
+ resolution: {integrity: sha512-vWNHOne0ZUavArqPP5LJta50+S8R261Fr5SvGul37HbEDcowvLjwdvd0ZeSr0r2lTSrPxl6okq9QUw8BFGiAxA==}
+
+ node@25.1.0:
+ resolution: {integrity: sha512-nYC3Zsz3ZQHGbBQrU8OAf63Qwhgptf352vQLGXVES2dL22QRrwjGzkuGS+C4FJ1b0awisMEe2tuPU87MDwj61A==}
+ engines: {npm: '>=5.0.0'}
+ hasBin: true
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.3:
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
+ engines: {node: '>=12'}
+
+ postcss@8.5.6:
+ resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
+ engines: {node: ^10 || ^12 || >=14}
+
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+ rollup@4.53.1:
+ resolution: {integrity: sha512-n2I0V0lN3E9cxxMqBCT3opWOiQBzRN7UG60z/WDKqdX2zHUS/39lezBcsckZFsV6fUTSnfqI7kHf60jDAPGKug==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@3.10.0:
+ resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyglobby@0.2.15:
+ resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
+ engines: {node: '>=12.0.0'}
+
+ tinyrainbow@3.0.3:
+ resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
+ engines: {node: '>=14.0.0'}
+
tsx@4.20.6:
resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==}
engines: {node: '>=18.0.0'}
@@ -199,6 +467,88 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ undici-types@7.16.0:
+ resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
+
+ vite@7.2.2:
+ resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@4.0.8:
+ resolution: {integrity: sha512-urzu3NCEV0Qa0Y2PwvBtRgmNtxhj5t5ULw7cuKhIHh3OrkKTLlut0lnBOv9qe5OvbkMH2g38G7KPDCTpIytBVg==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@types/debug': ^4.1.12
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.0.8
+ '@vitest/browser-preview': 4.0.8
+ '@vitest/browser-webdriverio': 4.0.8
+ '@vitest/ui': 4.0.8
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@types/debug':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
snapshots:
'@esbuild/aix-ppc64@0.25.12':
@@ -279,6 +629,138 @@ snapshots:
'@esbuild/win32-x64@0.25.12':
optional: true
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@rollup/rollup-android-arm-eabi@4.53.1':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.53.1':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.53.1':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.53.1':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.53.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.53.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.53.1':
+ optional: true
+
+ '@standard-schema/spec@1.0.0': {}
+
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/estree@1.0.8': {}
+
+ '@types/node@24.10.0':
+ dependencies:
+ undici-types: 7.16.0
+
+ '@vitest/expect@4.0.8':
+ dependencies:
+ '@standard-schema/spec': 1.0.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.0.8
+ '@vitest/utils': 4.0.8
+ chai: 6.2.0
+ tinyrainbow: 3.0.3
+
+ '@vitest/mocker@4.0.8(vite@7.2.2(@types/node@24.10.0)(tsx@4.20.6))':
+ dependencies:
+ '@vitest/spy': 4.0.8
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.2.2(@types/node@24.10.0)(tsx@4.20.6)
+
+ '@vitest/pretty-format@4.0.8':
+ dependencies:
+ tinyrainbow: 3.0.3
+
+ '@vitest/runner@4.0.8':
+ dependencies:
+ '@vitest/utils': 4.0.8
+ pathe: 2.0.3
+
+ '@vitest/snapshot@4.0.8':
+ dependencies:
+ '@vitest/pretty-format': 4.0.8
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@4.0.8': {}
+
+ '@vitest/utils@4.0.8':
+ dependencies:
+ '@vitest/pretty-format': 4.0.8
+ tinyrainbow: 3.0.3
+
+ assertion-error@2.0.1: {}
+
+ chai@6.2.0: {}
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ es-module-lexer@1.7.0: {}
+
esbuild@0.25.12:
optionalDependencies:
'@esbuild/aix-ppc64': 0.25.12
@@ -308,6 +790,16 @@ snapshots:
'@esbuild/win32-ia32': 0.25.12
'@esbuild/win32-x64': 0.25.12
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.8
+
+ expect-type@1.2.2: {}
+
+ fdir@6.5.0(picomatch@4.0.3):
+ optionalDependencies:
+ picomatch: 4.0.3
+
fsevents@2.3.3:
optional: true
@@ -315,8 +807,81 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.11: {}
+
+ node-bin-setup@1.1.4: {}
+
+ node@25.1.0:
+ dependencies:
+ node-bin-setup: 1.1.4
+
+ pathe@2.0.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.3: {}
+
+ postcss@8.5.6:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
resolve-pkg-maps@1.0.0: {}
+ rollup@4.53.1:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.53.1
+ '@rollup/rollup-android-arm64': 4.53.1
+ '@rollup/rollup-darwin-arm64': 4.53.1
+ '@rollup/rollup-darwin-x64': 4.53.1
+ '@rollup/rollup-freebsd-arm64': 4.53.1
+ '@rollup/rollup-freebsd-x64': 4.53.1
+ '@rollup/rollup-linux-arm-gnueabihf': 4.53.1
+ '@rollup/rollup-linux-arm-musleabihf': 4.53.1
+ '@rollup/rollup-linux-arm64-gnu': 4.53.1
+ '@rollup/rollup-linux-arm64-musl': 4.53.1
+ '@rollup/rollup-linux-loong64-gnu': 4.53.1
+ '@rollup/rollup-linux-ppc64-gnu': 4.53.1
+ '@rollup/rollup-linux-riscv64-gnu': 4.53.1
+ '@rollup/rollup-linux-riscv64-musl': 4.53.1
+ '@rollup/rollup-linux-s390x-gnu': 4.53.1
+ '@rollup/rollup-linux-x64-gnu': 4.53.1
+ '@rollup/rollup-linux-x64-musl': 4.53.1
+ '@rollup/rollup-openharmony-arm64': 4.53.1
+ '@rollup/rollup-win32-arm64-msvc': 4.53.1
+ '@rollup/rollup-win32-ia32-msvc': 4.53.1
+ '@rollup/rollup-win32-x64-gnu': 4.53.1
+ '@rollup/rollup-win32-x64-msvc': 4.53.1
+ fsevents: 2.3.3
+
+ siginfo@2.0.0: {}
+
+ source-map-js@1.2.1: {}
+
+ stackback@0.0.2: {}
+
+ std-env@3.10.0: {}
+
+ tinybench@2.9.0: {}
+
+ tinyexec@0.3.2: {}
+
+ tinyglobby@0.2.15:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+
+ tinyrainbow@3.0.3: {}
+
tsx@4.20.6:
dependencies:
esbuild: 0.25.12
@@ -325,3 +890,61 @@ snapshots:
fsevents: 2.3.3
typescript@5.9.3: {}
+
+ undici-types@7.16.0: {}
+
+ vite@7.2.2(@types/node@24.10.0)(tsx@4.20.6):
+ dependencies:
+ esbuild: 0.25.12
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+ postcss: 8.5.6
+ rollup: 4.53.1
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ '@types/node': 24.10.0
+ fsevents: 2.3.3
+ tsx: 4.20.6
+
+ vitest@4.0.8(@types/node@24.10.0)(tsx@4.20.6):
+ dependencies:
+ '@vitest/expect': 4.0.8
+ '@vitest/mocker': 4.0.8(vite@7.2.2(@types/node@24.10.0)(tsx@4.20.6))
+ '@vitest/pretty-format': 4.0.8
+ '@vitest/runner': 4.0.8
+ '@vitest/snapshot': 4.0.8
+ '@vitest/spy': 4.0.8
+ '@vitest/utils': 4.0.8
+ debug: 4.4.3
+ es-module-lexer: 1.7.0
+ expect-type: 1.2.2
+ magic-string: 0.30.21
+ pathe: 2.0.3
+ picomatch: 4.0.3
+ std-env: 3.10.0
+ tinybench: 2.9.0
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.15
+ tinyrainbow: 3.0.3
+ vite: 7.2.2(@types/node@24.10.0)(tsx@4.20.6)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 24.10.0
+ transitivePeerDependencies:
+ - jiti
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - yaml
+
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
diff --git a/src/lang/ks-lang/index.ts b/src/lang/ks-lang/index.ts
index 633d9b9..160c1ef 100644
--- a/src/lang/ks-lang/index.ts
+++ b/src/lang/ks-lang/index.ts
@@ -11,6 +11,9 @@ import {
StackFrame,
} from "../ts-lang";
+export const evaluateProgram = <Program extends string>(program: Program) =>
+ evaluate(parse(lex(program)));
+
export type TransformArgs<Args extends readonly ASTNode[]> = {
[Idx in keyof Args]: any;
};
diff --git a/test/test.ts b/test/test.ts
deleted file mode 100644
index 4e0bad4..0000000
--- a/test/test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { _Evaluate, createFn } from "../src";
-
-const KS_boolToBin = "fn(b, ?(b, 1, 0))";
-
-const boolArrToBinaryArr = createFn<[boolean[]]>()(
- `fn(boolArr, map(boolArr, ${KS_boolToBin}))`
-);
-
-const factorial = createFn<[number]>()(
- `bind(fac,fn(n,?(eq(n, 1),n,mul(n,call(fac,sub(n,1))))))`
-);
-
-const factRes = factorial(6);
-console.log(factRes);
-
-const closureTest = createFn<[number]>()(`fn(n, call(fn(m, add(m,n)), n))`);
-
-const closureRes = closureTest(6);
-console.log(closureRes);
diff --git a/tests/type-consistency/generateAll.ts b/tests/type-consistency/generateAll.ts
new file mode 100644
index 0000000..15464ae
--- /dev/null
+++ b/tests/type-consistency/generateAll.ts
@@ -0,0 +1,5 @@
+import harnesses from "./spec/index";
+
+Promise.all(harnesses.map((harness) => harness.writeTests())).catch(
+ (e) => `Failed to generate tests: ${e}`
+);
diff --git a/tests/type-consistency/harness.ts b/tests/type-consistency/harness.ts
new file mode 100644
index 0000000..a08e397
--- /dev/null
+++ b/tests/type-consistency/harness.ts
@@ -0,0 +1,85 @@
+import fs from "fs/promises";
+import path from "path";
+
+const convertName = (name: string) => name.replace(" ", "-").toLowerCase();
+
+export const createTestHarness = ({
+ harnessName,
+ generatedPath,
+}: {
+ harnessName: string;
+ generatedPath: string;
+}) => {
+ const tests: string[] = [];
+
+ return {
+ async writeTests() {
+ const file = `import { evaluateProgram, createFn } from "../../../src";
+import { describe, expect, expectTypeOf, test } from "vitest";
+
+describe(\`${harnessName}\`, () => {
+ ${tests.join("\n")}
+ });`;
+
+ await fs.mkdir(generatedPath, { recursive: true });
+
+ await fs.writeFile(
+ path.join(generatedPath, `${convertName(harnessName)}.test.ts`),
+ file,
+ "utf-8"
+ );
+
+ console.log(`Wrote ${tests.length} test(s) for "${harnessName}"!`);
+ },
+
+ createProgramTest({
+ name,
+ program,
+ expected,
+ }: {
+ name: string;
+ program: string;
+ expected: any;
+ }) {
+ tests.push(`test(\`${name}\`, () => {
+ const PROGRAM = \`${program}\` as const;
+ const expected: ${JSON.stringify(expected)} = ${JSON.stringify(expected)};
+ const result = evaluateProgram(PROGRAM);
+
+ expect(result).toStrictEqual(expected);
+ expectTypeOf<typeof result>().toEqualTypeOf<typeof expected>();
+ });`);
+
+ return this;
+ },
+
+ createFunctionTest({
+ name,
+ program,
+ cases,
+ }: {
+ name: string;
+ program: string;
+ cases: Array<{ input: any; output: any }>;
+ }) {
+ tests.push(`describe(\`${name}\`, () => {
+ const PROGRAM = \`${program}\` as const;
+ ${cases.map(
+ ({ input, output }) => `test(\`${JSON.stringify(
+ input
+ )} -> ${JSON.stringify(output)}\`, () => {
+ const input: ${JSON.stringify(input)} = ${JSON.stringify(input)};
+ const expected: ${JSON.stringify(output)} = ${JSON.stringify(output)};
+ const fn = createFn()(PROGRAM)
+ const result = fn(input)
+
+ expect(result).toStrictEqual(expected);
+ expectTypeOf<typeof result>().toEqualTypeOf<typeof expected>();
+ })
+ `
+ )}});`);
+
+ return this;
+ },
+ };
+};
diff --git a/tests/type-consistency/spec/array.ts b/tests/type-consistency/spec/array.ts
new file mode 100644
index 0000000..778a49f
--- /dev/null
+++ b/tests/type-consistency/spec/array.ts
@@ -0,0 +1,17 @@
+import path from "path";
+import { createTestHarness } from "../harness";
+
+export default createTestHarness({
+ harnessName: "Array",
+ generatedPath: path.join(__dirname, "..", "generated"),
+})
+ .createProgramTest({
+ name: "Number array",
+ program: "arr(1,2,3)",
+ expected: [[1, 2, 3]],
+ })
+ .createProgramTest({
+ name: "String array",
+ program: `arr("1","2","3")`,
+ expected: [["1", "2", "3"]],
+ });
diff --git a/tests/type-consistency/spec/function.ts b/tests/type-consistency/spec/function.ts
new file mode 100644
index 0000000..ffd069d
--- /dev/null
+++ b/tests/type-consistency/spec/function.ts
@@ -0,0 +1,26 @@
+import path from "path";
+import { createTestHarness } from "../harness";
+
+export default createTestHarness({
+ harnessName: "Function",
+ generatedPath: path.join(__dirname, "..", "generated"),
+})
+ .createFunctionTest({
+ name: "f(x) = x",
+ program: "fn(x, x)",
+ cases: [
+ { input: "hello", output: "hello" },
+ { input: 1, output: 1 },
+ { input: [1, 2, 3], output: [1, 2, 3] },
+ { input: true, output: true },
+ ],
+ })
+ .createFunctionTest({
+ name: "f(x) = x + 5",
+ program: "fn(x, add(x,5))",
+ cases: [
+ { input: 0, output: 5 },
+ { input: 5, output: 10 },
+ { input: 500, output: 505 },
+ ],
+ });
diff --git a/tests/type-consistency/spec/index.ts b/tests/type-consistency/spec/index.ts
new file mode 100644
index 0000000..9ef825f
--- /dev/null
+++ b/tests/type-consistency/spec/index.ts
@@ -0,0 +1,4 @@
+import array from "./array";
+import functions from "./function";
+
+export default [array, functions];