diff --git a/generator/gen.bin.ts b/generator/gen.bin.ts index c21c2a3..a7a1292 100755 --- a/generator/gen.bin.ts +++ b/generator/gen.bin.ts @@ -1,27 +1,37 @@ #!/usr/bin/env node import yargs from 'yargs'; -// @ts-ignore import { hideBin } from 'yargs/helpers'; import gen from './gen'; import { glob } from 'glob'; +import { watcher } from './watcher'; yargs(hideBin(process.argv)) - .command<{ files: string }>( + .command( 'gen [files]', 'Generates json schemas next to corresponding ts files', - (yargs) => { + (yargs) => yargs .positional('files', { describe: 'glob pattern of files', type: 'string', demandOption: true, }) - .demandOption(['files']); - }, + .option('watch', { + alias: 'w', + type: 'boolean', + description: 'Watch files for changes', + }) + .demandOption(['files']), async (argv) => { - const files = await glob(argv.files); + if (argv.watch) { + console.log('Watching for changes...'); + watcher(argv.files); + return; + } + console.log('Generating schemas...'); + const files = await glob(argv.files); await gen({ files }); }, ) diff --git a/generator/watcher.ts b/generator/watcher.ts new file mode 100644 index 0000000..e58e3cb --- /dev/null +++ b/generator/watcher.ts @@ -0,0 +1,30 @@ +import chokidar from 'chokidar'; +import gen from './gen'; +import path from 'node:path'; +import fsp from 'node:fs/promises'; + +export function watcher(files: string | string[]) { + const watcher = chokidar.watch(files); + watcher.on('change', async (file: string) => { + await gen({ files: [file] }); + }); + watcher.on('add', async (file: string) => { + await gen({ files: [file] }); + }); + watcher.on('unlink', async (file: string) => { + const jsonFile = path.parse(file); + const schema = path.format({ + ...jsonFile, + base: path.basename(jsonFile.base, jsonFile.ext) + '.gen.json', + ext: '.json', + }); + const exists = await fsp + .stat(schema) + .then(() => true) + .catch(() => false); + + if (exists) { + await fsp.rm(schema); + } + }); +} diff --git a/package.json b/package.json index 29fe4d1..c2b456c 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@types/json-schema": "^7.0.13", + "chokidar": "3.5.3", "crypto-js": "^4.1.1", "glob": "^10.3.4", "json-schema-merge-allof": "^0.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 767d001..dcf773e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@types/json-schema': specifier: ^7.0.13 version: 7.0.13 + chokidar: + specifier: 3.5.3 + version: 3.5.3 crypto-js: specifier: ^4.1.1 version: 4.2.0 @@ -759,7 +762,6 @@ packages: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true /append-transform@2.0.0: resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} @@ -854,7 +856,6 @@ packages: /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - dev: true /bind-obj-methods@3.0.0: resolution: {integrity: sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==} @@ -885,7 +886,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true /browserslist@4.21.10: resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} @@ -994,7 +994,6 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.2 - dev: true /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} @@ -1494,7 +1493,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} @@ -1576,7 +1574,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind@1.1.1: @@ -1617,7 +1614,6 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob@10.3.4: resolution: {integrity: sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==} @@ -1832,7 +1828,6 @@ packages: engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 - dev: true /is-core-module@2.12.1: resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} @@ -1843,7 +1838,6 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -1859,7 +1853,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} @@ -1869,7 +1862,6 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} @@ -2428,7 +2420,6 @@ packages: /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - dev: true /npm-package-arg@10.1.0: resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} @@ -2654,7 +2645,6 @@ packages: /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true /pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} @@ -2875,7 +2865,6 @@ packages: engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 - dev: true /real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} @@ -3431,7 +3420,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: true /toad-cache@3.2.0: resolution: {integrity: sha512-Hj5zSqBS6OHbZoQk9IU8VqIr+0JUpwzunnwSlFJhG8aJSInYUMEuzItl3kJsGteTPd1qtflafdRHlRtUazYeqg==}