diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52193b406..d468d345c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -676,6 +676,43 @@ importers: specifier: 'catalog:' version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + samples/livr-emitter: + dependencies: + '@alloy-js/core': + specifier: workspace:~ + version: link:../../packages/core + '@alloy-js/java': + specifier: workspace:~ + version: link:../../packages/java + '@alloy-js/json': + specifier: workspace:~ + version: link:../../packages/json + '@alloy-js/typescript': + specifier: workspace:~ + version: link:../../packages/typescript + devDependencies: + '@alloy-js/cli': + specifier: workspace:~ + version: link:../../packages/cli + '@alloy-js/rollup-plugin': + specifier: workspace:~ + version: link:../../packages/rollup-plugin + '@rollup/plugin-typescript': + specifier: 'catalog:' + version: 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.3) + '@types/node': + specifier: 'catalog:' + version: 20.17.30 + concurrently: + specifier: 'catalog:' + version: 9.1.2 + typescript: + specifier: 'catalog:' + version: 5.8.3 + vitest: + specifier: 'catalog:' + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.30)(tsx@4.19.3)(yaml@2.7.1) + packages: '@actions/github@6.0.0': @@ -919,152 +956,102 @@ packages: '@esbuild/aix-ppc64@0.25.2': resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] '@esbuild/android-arm64@0.25.2': resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} - cpu: [arm64] - os: [android] '@esbuild/android-arm@0.25.2': resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} - cpu: [arm] - os: [android] '@esbuild/android-x64@0.25.2': resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} - cpu: [x64] - os: [android] '@esbuild/darwin-arm64@0.25.2': resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] '@esbuild/darwin-x64@0.25.2': resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} - cpu: [x64] - os: [darwin] '@esbuild/freebsd-arm64@0.25.2': resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] '@esbuild/freebsd-x64@0.25.2': resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] '@esbuild/linux-arm64@0.25.2': resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} - cpu: [arm64] - os: [linux] '@esbuild/linux-arm@0.25.2': resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} - cpu: [arm] - os: [linux] '@esbuild/linux-ia32@0.25.2': resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} - cpu: [ia32] - os: [linux] '@esbuild/linux-loong64@0.25.2': resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} - cpu: [loong64] - os: [linux] '@esbuild/linux-mips64el@0.25.2': resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] '@esbuild/linux-ppc64@0.25.2': resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] '@esbuild/linux-riscv64@0.25.2': resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] '@esbuild/linux-s390x@0.25.2': resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} - cpu: [s390x] - os: [linux] '@esbuild/linux-x64@0.25.2': resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} - cpu: [x64] - os: [linux] '@esbuild/netbsd-arm64@0.25.2': resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] '@esbuild/netbsd-x64@0.25.2': resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] '@esbuild/openbsd-arm64@0.25.2': resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] '@esbuild/openbsd-x64@0.25.2': resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] '@esbuild/sunos-x64@0.25.2': resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} - cpu: [x64] - os: [sunos] '@esbuild/win32-arm64@0.25.2': resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} - cpu: [arm64] - os: [win32] '@esbuild/win32-ia32@0.25.2': resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} - cpu: [ia32] - os: [win32] '@esbuild/win32-x64@0.25.2': resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} - cpu: [x64] - os: [win32] '@eslint-community/eslint-utils@4.5.1': resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} @@ -1150,217 +1137,141 @@ packages: '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] '@img/sharp-darwin-arm64@0.34.1': resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] '@img/sharp-darwin-x64@0.33.5': resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] '@img/sharp-darwin-x64@0.34.1': resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] '@img/sharp-libvips-darwin-arm64@1.0.4': resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] '@img/sharp-libvips-darwin-arm64@1.1.0': resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} - cpu: [arm64] - os: [darwin] '@img/sharp-libvips-darwin-x64@1.0.4': resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] '@img/sharp-libvips-darwin-x64@1.1.0': resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} - cpu: [x64] - os: [darwin] '@img/sharp-libvips-linux-arm64@1.0.4': resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] '@img/sharp-libvips-linux-arm64@1.1.0': resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} - cpu: [arm64] - os: [linux] '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] '@img/sharp-libvips-linux-arm@1.1.0': resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} - cpu: [arm] - os: [linux] '@img/sharp-libvips-linux-ppc64@1.1.0': resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} - cpu: [ppc64] - os: [linux] '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] '@img/sharp-libvips-linux-s390x@1.1.0': resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} - cpu: [s390x] - os: [linux] '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] '@img/sharp-libvips-linux-x64@1.1.0': resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} - cpu: [x64] - os: [linux] '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] '@img/sharp-libvips-linuxmusl-arm64@1.1.0': resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} - cpu: [arm64] - os: [linux] '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] '@img/sharp-libvips-linuxmusl-x64@1.1.0': resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} - cpu: [x64] - os: [linux] '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] '@img/sharp-linux-arm64@0.34.1': resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] '@img/sharp-linux-arm@0.34.1': resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] '@img/sharp-linux-s390x@0.34.1': resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] '@img/sharp-linux-x64@0.34.1': resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] '@img/sharp-linuxmusl-arm64@0.34.1': resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] '@img/sharp-linuxmusl-x64@0.34.1': resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] '@img/sharp-wasm32@0.34.1': resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] '@img/sharp-win32-ia32@0.33.5': resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] '@img/sharp-win32-ia32@0.34.1': resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] '@img/sharp-win32-x64@0.33.5': resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] '@img/sharp-win32-x64@0.34.1': resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -1635,31 +1546,21 @@ packages: '@pagefind/darwin-arm64@1.3.0': resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==} - cpu: [arm64] - os: [darwin] '@pagefind/darwin-x64@1.3.0': resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==} - cpu: [x64] - os: [darwin] '@pagefind/default-ui@1.3.0': resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==} '@pagefind/linux-arm64@1.3.0': resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==} - cpu: [arm64] - os: [linux] '@pagefind/linux-x64@1.3.0': resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==} - cpu: [x64] - os: [linux] '@pagefind/windows-x64@1.3.0': resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==} - cpu: [x64] - os: [win32] '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -1711,103 +1612,63 @@ packages: '@rollup/rollup-android-arm-eabi@4.39.0': resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} - cpu: [arm] - os: [android] '@rollup/rollup-android-arm64@4.39.0': resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} - cpu: [arm64] - os: [android] '@rollup/rollup-darwin-arm64@4.39.0': resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} - cpu: [arm64] - os: [darwin] '@rollup/rollup-darwin-x64@4.39.0': resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} - cpu: [x64] - os: [darwin] '@rollup/rollup-freebsd-arm64@4.39.0': resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} - cpu: [arm64] - os: [freebsd] '@rollup/rollup-freebsd-x64@4.39.0': resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} - cpu: [x64] - os: [freebsd] '@rollup/rollup-linux-arm-gnueabihf@4.39.0': resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} - cpu: [arm] - os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.39.0': resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} - cpu: [arm] - os: [linux] '@rollup/rollup-linux-arm64-gnu@4.39.0': resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} - cpu: [arm64] - os: [linux] '@rollup/rollup-linux-arm64-musl@4.39.0': resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} - cpu: [arm64] - os: [linux] '@rollup/rollup-linux-loongarch64-gnu@4.39.0': resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} - cpu: [loong64] - os: [linux] '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} - cpu: [ppc64] - os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.39.0': resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} - cpu: [riscv64] - os: [linux] '@rollup/rollup-linux-riscv64-musl@4.39.0': resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} - cpu: [riscv64] - os: [linux] '@rollup/rollup-linux-s390x-gnu@4.39.0': resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} - cpu: [s390x] - os: [linux] '@rollup/rollup-linux-x64-gnu@4.39.0': resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} - cpu: [x64] - os: [linux] '@rollup/rollup-linux-x64-musl@4.39.0': resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} - cpu: [x64] - os: [linux] '@rollup/rollup-win32-arm64-msvc@4.39.0': resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} - cpu: [arm64] - os: [win32] '@rollup/rollup-win32-ia32-msvc@4.39.0': resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} - cpu: [ia32] - os: [win32] '@rollup/rollup-win32-x64-msvc@4.39.0': resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} - cpu: [x64] - os: [win32] '@rushstack/node-core-library@5.10.0': resolution: {integrity: sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==} @@ -2683,7 +2544,6 @@ packages: fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -6014,7 +5874,7 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 17.0.45 + '@types/node': 20.17.30 '@types/unist@2.0.11': {} diff --git a/samples/livr-emitter/alloy-output/rules.json b/samples/livr-emitter/alloy-output/rules.json new file mode 100644 index 000000000..c2874bb74 --- /dev/null +++ b/samples/livr-emitter/alloy-output/rules.json @@ -0,0 +1,105 @@ +{ + "name": [ + "required", + "string", + { + "max_length": 50 + } + ], + "lastName": [ + "string", + { + "length_between": [2, 50] + } + ], + "email": [ + "required", + "email" + ], + "age": [ + "integer", + { + "min_number": 18 + }, + { + "max_number": 99 + } + ], + "address": [ + "required", + { + "nested_object": { + "street": "string", + "city": "required", + "zip": [ + "required", + "positive_integer" + ], + "geo": { + "nested_object": { + "lat": "decimal", + "lng": "decimal" + } + } + } + } + ], + "phones": [ + { + "list_of": [ + "string", + { + "max_length": 15 + } + ] + } + ], + "preferences": { + "variable_object": [ + "type", + { + "email": { + "frequency": { + "one_of": ["daily", "weekly", "monthly"] + } + }, + "sms": { + "time": "string" + } + } + ] + }, + "tags": [ + { + "list_of": "string" + } + ], + "website": "url", + "created_at": "iso_date", + "status": { + "one_of": ["active", "inactive", "pending"] + }, + "password": [ + "required", + { + "min_length": 8 + } + ], + "confirm_password": [ + "required", + { + "equal_to_field": "password" + } + ], + "contact": { + "or": [ + ["email"], + [ + "string", + { + "max_length": 15 + } + ] + ] + } +} \ No newline at end of file diff --git a/samples/livr-emitter/package.json b/samples/livr-emitter/package.json new file mode 100644 index 000000000..3aefc258f --- /dev/null +++ b/samples/livr-emitter/package.json @@ -0,0 +1,31 @@ +{ + "name": "@alloy-js/sample-livr-emitter", + "private": "true", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "alloy build", + "clean": "rimraf dist/ .temp/", + "watch": "alloy build --watch" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@alloy-js/core": "workspace:~", + "@alloy-js/json": "workspace:~", + "@alloy-js/typescript": "workspace:~", + "@alloy-js/java": "workspace:~" + }, + "devDependencies": { + "@alloy-js/cli": "workspace:~", + "@alloy-js/rollup-plugin": "workspace:~", + "@rollup/plugin-typescript": "catalog:", + "@types/node": "catalog:", + "concurrently": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" + }, + "type": "module" +} diff --git a/samples/livr-emitter/src/component/Rule.tsx b/samples/livr-emitter/src/component/Rule.tsx new file mode 100644 index 000000000..a65ce592d --- /dev/null +++ b/samples/livr-emitter/src/component/Rule.tsx @@ -0,0 +1,29 @@ +// src/component/Rule.tsx +import { For } from "@alloy-js/core"; +import * as jsn from "@alloy-js/json"; +import { LIVRFieldRules } from "../schema.js"; +import { RuleProperty } from "./RuleProperty.jsx"; + +interface RuleProps { + rule: LIVRFieldRules; +} + +export function Rule(props: RuleProps) { + const { rule } = props; + + if (Array.isArray(rule)) { + // Array of rules: output as array of processed rules, with commas + return ( + + + {(r) => } + + + ); + } + if (typeof rule === "object" && rule !== null && "rule" in rule) { + return ; + } + // Fallback: output as JSON + return ; +} diff --git a/samples/livr-emitter/src/component/RuleProperty.tsx b/samples/livr-emitter/src/component/RuleProperty.tsx new file mode 100644 index 000000000..baa7fe5c6 --- /dev/null +++ b/samples/livr-emitter/src/component/RuleProperty.tsx @@ -0,0 +1,177 @@ +// RuleProperty.tsx +import { For } from "@alloy-js/core"; +import * as jsn from "@alloy-js/json"; +import { + ListOfDifferentObjectsRule, + ListOfObjectsRule, + ListOfRule, + LIVRRule, + LIVRSchema, + NestedObjectRule, + OrRule, + VariableObjectRule, +} from "../schema.js"; +import { Rule } from "./Rule.jsx"; // for recursion + +interface RulePropertyProps { + rule: LIVRRule; +} + +function renderSimpleRule(rule: LIVRRule) { + // Render simple rules as string literals + return ; +} + +function renderSimpleObjectRule(name: string, jsValue: any) { + // Render simple object rules as { rule: value } + return ( + + + + + + ); +} + +function renderSchema(schema: LIVRSchema) { + return ( + + + {([field, fieldRules]) => ( + + + + )} + + + ); +} + +function renderNestedObjectRule(rule: NestedObjectRule) { + // Render nested object rules as { nested_object: { ... } } + return ( + + + {renderSchema(rule.schema)} + + + ); +} + +function renderOrRule(rule: OrRule) { + // Render OR rules as { or: [ ... ] } + return ( + + + + + {(alt) => } + + + + + ); +} + +function renderSelectorBasedRules( + rule: VariableObjectRule | ListOfDifferentObjectsRule, +) { + return ( + + + + + + + {([field, schema]) => ( + + {renderSchema(schema)} + + )} + + + + + + ); +} + +function renderListOfRule(rule: ListOfRule) { + return ( + + + + + + ); +} + +function renderListOfObjectsRule(rule: ListOfObjectsRule) { + return ( + + + {renderSchema(rule.schema)} + + + ); +} + +export function RuleProperty(props: RulePropertyProps) { + const { rule } = props; + + switch (rule.rule) { + case "required": + case "not_empty": + case "not_empty_list": + case "any_object": + case "string": + case "integer": + case "positive_integer": + case "decimal": + case "positive_decimal": + case "email": + case "url": + case "iso_date": + case "trim": + case "to_lc": + case "to_uc": + return renderSimpleRule(rule); + case "nested_object": + return renderNestedObjectRule(rule); + case "or": + return renderOrRule(rule); + case "variable_object": + return renderSelectorBasedRules(rule); + case "list_of": + return renderListOfRule(rule); + case "list_of_objects": + return renderListOfObjectsRule(rule); + case "list_of_different_objects": + return renderSelectorBasedRules(rule); + case "max_length": + case "min_length": + case "length_equal": + return renderSimpleObjectRule(rule.rule, rule.length); + case "length_between": + return renderSimpleObjectRule(rule.rule, rule.range); + case "max_number": + case "min_number": + case "eq": + return renderSimpleObjectRule(rule.rule, rule.value); + case "number_between": + return renderSimpleObjectRule(rule.rule, rule.range); + case "equal_to_field": + return renderSimpleObjectRule(rule.rule, rule.field); + case "one_of": + return renderSimpleObjectRule(rule.rule, rule.values); + case "like": + return renderSimpleObjectRule(rule.rule, rule.pattern); + case "remove": + case "leave_only": + return renderSimpleObjectRule(rule.rule, rule.characters); + case "default": + return renderSimpleObjectRule(rule.rule, rule.value); + default: + return ; + } +} diff --git a/samples/livr-emitter/src/context/livr.ts b/samples/livr-emitter/src/context/livr.ts new file mode 100644 index 000000000..40c323b3a --- /dev/null +++ b/samples/livr-emitter/src/context/livr.ts @@ -0,0 +1,22 @@ +import { + createContext, + useContext, + type ComponentContext, +} from "@alloy-js/core"; +import { LIVRSchema } from "../schema.js"; + +interface LIVRContext { + schema: LIVRSchema; +} + +// Add explicit return type annotation +export const LIVRContext: ComponentContext = + createContext(); + +export function useLivr(): LIVRContext { + return useContext(LIVRContext)!; +} + +export function createLIVRContext(schema: LIVRSchema): LIVRContext { + return { schema }; +} diff --git a/samples/livr-emitter/src/index.tsx b/samples/livr-emitter/src/index.tsx new file mode 100644 index 000000000..a003b3370 --- /dev/null +++ b/samples/livr-emitter/src/index.tsx @@ -0,0 +1,27 @@ +import { For, Output, render, writeOutput } from "@alloy-js/core"; +import * as jsn from "@alloy-js/json"; +import { Rule } from "./component/Rule.js"; +import { LIVRContext, createLIVRContext } from "./context/livr.js"; +import { livrApi } from "./schema.js"; + +// Main function to emit LIVR schema as JSON +const output = render( + + + + + + {([fieldName, rules]) => ( + + + + )} + + + + + , +); + +// Write the output to disk +writeOutput(output, "./alloy-output"); diff --git a/samples/livr-emitter/src/schema.ts b/samples/livr-emitter/src/schema.ts new file mode 100644 index 000000000..9ce511c1f --- /dev/null +++ b/samples/livr-emitter/src/schema.ts @@ -0,0 +1,290 @@ +/** + * Base interface for all LIVR rules. + * Extend and discriminate with `rule` property. + */ +interface LIVRRuleBase { + rule: string; + error_code?: string; +} + +// --- Common rules --- +export interface RequiredRule extends LIVRRuleBase { + rule: "required"; + error_code?: "REQUIRED"; +} +export interface NotEmptyRule extends LIVRRuleBase { + rule: "not_empty"; + error_code?: "CANNOT_BE_EMPTY"; +} +export interface NotEmptyList extends LIVRRuleBase { + rule: "not_empty_list"; + error_code?: "CANNOT_BE_EMPTY" | "FORMAT_ERROR"; +} +export interface AnyObject extends LIVRRuleBase { + rule: "any_object"; + error_code?: "FORMAT_ERROR"; +} + +// --- String rules --- +export interface StringRule extends LIVRRuleBase { + rule: "string"; +} +export interface EqRule extends LIVRRuleBase { + rule: "eq"; + value: string; + error_code?: "NOT_ALLOWED_VALUE"; +} +export interface OneOfRule extends LIVRRuleBase { + rule: "one_of"; + values: string[]; + error_code?: "NOT_ALLOWED_VALUE"; +} +export interface MinLengthRule extends LIVRRuleBase { + rule: "min_length"; + length: number; + error_code?: "TOO_SHORT"; +} +export interface MaxLengthRule extends LIVRRuleBase { + rule: "max_length"; + length: number; + error_code?: "TOO_LONG"; +} +export interface LengthBetweenRule extends LIVRRuleBase { + rule: "length_between"; + range: [number, number]; // [min, max] + error_code?: "TOO_SHORT" | "TOO_LONG"; +} +export interface LengthEqualRule extends LIVRRuleBase { + rule: "length_equal"; + length: number; + error_code?: "TOO_SHORT" | "TOO_LONG"; +} +export interface LikeRule extends LIVRRuleBase { + rule: "like"; + pattern: string; + error_code?: "WRONG_FORMAT"; +} + +// --- Numeric rules --- +export interface IntegerRule extends LIVRRuleBase { + rule: "integer"; + error_code?: "NOT_INTEGER"; +} +export interface PositiveIntegerRule extends LIVRRuleBase { + rule: "positive_integer"; + error_code?: "NOT_POSITIVE_INTEGER"; +} +export interface DecimalRule extends LIVRRuleBase { + rule: "decimal"; + error_code?: "NOT_DECIMAL"; +} +export interface PositiveDecimalRule extends LIVRRuleBase { + rule: "positive_decimal"; + error_code?: "NOT_POSITIVE_DECIMAL"; +} +export interface MaxNumberRule extends LIVRRuleBase { + rule: "max_number"; + value: number; + error_code?: "TOO_HIGH" | "NOT_NUMBER"; +} +export interface MinNumberRule extends LIVRRuleBase { + rule: "min_number"; + value: number; + error_code?: "TOO_LOW" | "NOT_NUMBER"; +} +export interface NumberBetweenRule extends LIVRRuleBase { + rule: "number_between"; + range: [number, number]; // [min, max] + error_code?: "TOO_LOW" | "TOO_HIGH" | "NOT_NUMBER"; +} + +// --- Special rules --- +export interface EmailRule extends LIVRRuleBase { + rule: "email"; + error_code?: "WRONG_EMAIL"; +} +export interface UrlRule extends LIVRRuleBase { + rule: "url"; + error_code?: "WRONG_URL"; +} +export interface IsoDateRule extends LIVRRuleBase { + rule: "iso_date"; + error_code?: "WRONG_DATE"; +} +export interface EqualToFieldRule extends LIVRRuleBase { + rule: "equal_to_field"; + field: string; + error_code?: "FIELDS_NOT_EQUAL"; +} +// --- Meta rules --- +export interface NestedObjectRule extends LIVRRuleBase { + rule: "nested_object"; + schema: LIVRSchema; + error_code?: "FORMAT_ERROR"; +} +export interface VariableObjectRule extends LIVRRuleBase { + rule: "variable_object"; + selectorField: string; + cases: { [key: string]: LIVRSchema }; + error_code?: "FORMAT_ERROR"; +} +export interface ListOfRule extends LIVRRuleBase { + rule: "list_of"; + rules: LIVRFieldRules; +} +export interface ListOfObjectsRule extends LIVRRuleBase { + rule: "list_of_objects"; + schema: LIVRSchema; +} +export interface ListOfDifferentObjectsRule extends LIVRRuleBase { + rule: "list_of_different_objects"; + selectorField: string; + cases: { [key: string]: LIVRSchema }; +} +export interface OrRule extends LIVRRuleBase { + rule: "or"; + /** + * Each alternative is either: + * - a single rule (as an object) + * - or an array of rules (if several in a chain) + */ + alternatives: (LIVRRule | LIVRRule[])[]; +} + +// --- Modifier rules --- +export interface TrimRule extends LIVRRuleBase { + rule: "trim"; +} +export interface ToLowerCaseRule extends LIVRRuleBase { + rule: "to_lc"; +} +export interface ToUpperCaseRule extends LIVRRuleBase { + rule: "to_uc"; +} +export interface RemoveRule extends LIVRRuleBase { + rule: "remove"; + characters: string; +} +export interface LeaveOnlyRule extends LIVRRuleBase { + rule: "leave_only"; + characters: string; +} +export interface DefaultRule extends LIVRRuleBase { + rule: "default"; + value: string | number | boolean; +} +// --- Main rule type: union of all rule interfaces --- + +export type LIVRRule = + | RequiredRule + | NotEmptyRule + | NotEmptyList + | AnyObject + | StringRule + | EqRule + | OneOfRule + | MinLengthRule + | MaxLengthRule + | LengthBetweenRule + | LengthEqualRule + | LikeRule + | IntegerRule + | PositiveIntegerRule + | DecimalRule + | PositiveDecimalRule + | MaxNumberRule + | MinNumberRule + | NumberBetweenRule + | EmailRule + | UrlRule + | IsoDateRule + | EqualToFieldRule + | NestedObjectRule + | VariableObjectRule + | ListOfRule + | ListOfObjectsRule + | ListOfDifferentObjectsRule + | OrRule + | TrimRule + | ToLowerCaseRule + | ToUpperCaseRule + | RemoveRule + | LeaveOnlyRule + | DefaultRule; + +// LIVR field rules: typically an array, but can be a single rule. +export type LIVRFieldRules = LIVRRule | LIVRRule[]; + +// A LIVR validation schema: field name -> rules +export interface LIVRSchema { + [field: string]: LIVRFieldRules; +} + +// Define a complete sample LIVR schema +export const livrApi: LIVRSchema = { + name: [ + { rule: "required" }, + { rule: "string" }, + { rule: "max_length", length: 50 }, + ], + lastName: [{ rule: "string" }, { rule: "length_between", range: [2, 50] }], + email: [{ rule: "required" }, { rule: "email" }], + age: [ + { rule: "integer" }, + { rule: "min_number", value: 18 }, + { rule: "max_number", value: 99 }, + ], + address: [ + { rule: "required" }, + { + rule: "nested_object", + schema: { + street: { rule: "string" }, + city: { rule: "required" }, + zip: [{ rule: "required" }, { rule: "positive_integer" }], + geo: { + rule: "nested_object", + schema: { + lat: { rule: "decimal" }, + lng: { rule: "decimal" }, + }, + }, + }, + }, + ], + phones: [ + { + rule: "list_of", + rules: [{ rule: "string" }, { rule: "max_length", length: 15 }], + }, + ], + preferences: { + rule: "variable_object", + selectorField: "type", + cases: { + email: { + frequency: { rule: "one_of", values: ["daily", "weekly", "monthly"] }, + }, + sms: { + time: { rule: "string" }, + }, + }, + }, + tags: [{ rule: "list_of", rules: { rule: "string" } }], + website: { rule: "url" }, + created_at: { rule: "iso_date" }, + status: { rule: "one_of", values: ["active", "inactive", "pending"] }, + password: [{ rule: "required" }, { rule: "min_length", length: 8 }], + confirm_password: [ + { rule: "required" }, + { rule: "equal_to_field", field: "password" }, + ], + // Example of the "or" rule + contact: { + rule: "or", + alternatives: [ + [{ rule: "email" }], + [{ rule: "string" }, { rule: "max_length", length: 15 }], + ], + }, +}; diff --git a/samples/livr-emitter/tsconfig.json b/samples/livr-emitter/tsconfig.json new file mode 100644 index 000000000..ec994c238 --- /dev/null +++ b/samples/livr-emitter/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "declaration": true, + "outDir": "dist" + }, + "references": [ + { "path": "../../packages/core" }, + { "path": "../../packages/typescript" } + ], + "include": ["src/**/*.ts", "src/**/*.tsx", "test/**/*.ts", "test/**/*.tsx"], + "exclude": ["node_modules", "dist"] +} diff --git a/samples/livr-emitter/vitest.config.ts b/samples/livr-emitter/vitest.config.ts new file mode 100644 index 000000000..f05f0ab40 --- /dev/null +++ b/samples/livr-emitter/vitest.config.ts @@ -0,0 +1,14 @@ +import alloyPlugin from "@alloy-js/rollup-plugin"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["test/**/*.ts", "test/**/*.tsx"], + exclude: ["test/**/*.util.ts", "test/**/*.d.ts"], + }, + esbuild: { + jsx: "preserve", + sourcemap: "both", + }, + plugins: [alloyPlugin()], +});