diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2174d..5181028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## [1.0.4] - 2024-09-08 + ### Fixed -- Handle cases where RLS is already enabled on a table. +- Handle cases where RLS is already enabled on a table, and may potentially already have permissive policies. + +- Fixed missing `WITH CHECK` constraint for `UPDATE` RLS policies. ## [1.0.3] - 2024-08-14 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32f59c4..8906960 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,804 +1,514 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - dotenv: - specifier: ^16.3.1 - version: 16.3.1 - fdir: - specifier: ^6.1.1 - version: 6.1.1(picomatch@3.0.1) - oso: - specifier: ^0.27.0 - version: 0.27.0 - pg: - specifier: ^8.11.3 - version: 8.11.3 - picomatch: - specifier: ^3.0.1 - version: 3.0.1 - yargs: - specifier: ^17.7.2 - version: 17.7.2 - -devDependencies: - '@biomejs/biome': - specifier: ^1.4.1 - version: 1.4.1 - '@jsdevtools/version-bump-prompt': - specifier: ^6.1.0 - version: 6.1.0 - '@swc/core': - specifier: ^1.3.99 - version: 1.3.99 - '@types/node': - specifier: ^20.10.0 - version: 20.10.0 - '@types/pg': - specifier: ^8.10.9 - version: 8.10.9 - '@types/yargs': - specifier: ^17.0.32 - version: 17.0.32 - ts-node: - specifier: ^10.9.1 - version: 10.9.1(@swc/core@1.3.99)(@types/node@20.10.0)(typescript@5.3.2) - typescript: - specifier: ^5.3.2 - version: 5.3.2 +importers: + + .: + dependencies: + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + fdir: + specifier: ^6.1.1 + version: 6.1.1(picomatch@3.0.1) + oso: + specifier: ^0.27.0 + version: 0.27.0 + pg: + specifier: ^8.11.3 + version: 8.11.3 + picomatch: + specifier: ^3.0.1 + version: 3.0.1 + yargs: + specifier: ^17.7.2 + version: 17.7.2 + devDependencies: + '@biomejs/biome': + specifier: ^1.4.1 + version: 1.4.1 + '@jsdevtools/version-bump-prompt': + specifier: ^6.1.0 + version: 6.1.0 + '@swc/core': + specifier: ^1.3.99 + version: 1.3.99 + '@types/node': + specifier: ^20.10.0 + version: 20.10.0 + '@types/pg': + specifier: ^8.10.9 + version: 8.10.9 + '@types/yargs': + specifier: ^17.0.32 + version: 17.0.32 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@swc/core@1.3.99)(@types/node@20.10.0)(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 packages: - /@biomejs/biome@1.4.1: + '@biomejs/biome@1.4.1': resolution: {integrity: sha512-JccVAwPbhi37pdxbAGmaOBjUTKEwEjWAhl7rKkVVuXHo4MLASXJ5HR8BTgrImi4/7rTBsGz1tgVD1Kwv1CHGRg==} engines: {node: '>=14.*'} hasBin: true - requiresBuild: true - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.4.1 - '@biomejs/cli-darwin-x64': 1.4.1 - '@biomejs/cli-linux-arm64': 1.4.1 - '@biomejs/cli-linux-x64': 1.4.1 - '@biomejs/cli-win32-arm64': 1.4.1 - '@biomejs/cli-win32-x64': 1.4.1 - dev: true - /@biomejs/cli-darwin-arm64@1.4.1: + '@biomejs/cli-darwin-arm64@1.4.1': resolution: {integrity: sha512-PZWy2Idndqux38p6AXSDQM2ldRAWi32bvb7bMbTN0ALzpWYMYnxd71ornatumSSJYoNhKmxzDLq+jct7nZJ79w==} engines: {node: '>=14.*'} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@biomejs/cli-darwin-x64@1.4.1: + '@biomejs/cli-darwin-x64@1.4.1': resolution: {integrity: sha512-soj3BWhnsM1M2JlzR09cibUzG1owJqetwj/Oo7yg0foijo9lNH9XWXZfJBYDKgW/6Fomn+CC2EcUS+hisQzt9g==} engines: {node: '>=14.*'} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@biomejs/cli-linux-arm64@1.4.1: + '@biomejs/cli-linux-arm64@1.4.1': resolution: {integrity: sha512-YIZqfJUg4F+fPsBTXxgD7EU2E5OAYbmYSl/snf4PevwfQCWE/omOFZv+NnIQmjYj9I7ParDgcJvanoA3/kO0JQ==} engines: {node: '>=14.*'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@biomejs/cli-linux-x64@1.4.1: + '@biomejs/cli-linux-x64@1.4.1': resolution: {integrity: sha512-9YOZw3qBd/KUj63A6Hn2zZgzGb2nbESM0qNmeMXgmqinVKM//uc4OgY5TuKITuGjMSvcVxxd4dX1IzYjV9qvNQ==} engines: {node: '>=14.*'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@biomejs/cli-win32-arm64@1.4.1: + '@biomejs/cli-win32-arm64@1.4.1': resolution: {integrity: sha512-nWQbvkNKxYn/kCQ0yVF8kCaS3VzaGvtFSmItXiMknU4521LDjJ7tNWH12Gol+pIslrCbd4E1LhJa0a3ThRsBVg==} engines: {node: '>=14.*'} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@biomejs/cli-win32-x64@1.4.1: + '@biomejs/cli-win32-x64@1.4.1': resolution: {integrity: sha512-88fR2CQxQ4YLs2BUDuywWYQpUKgU3A3sTezANFc/4LGKQFFLV2yX+F7QAdZVkMHfA+RD9Xg178HomM/6mnTNPA==} engines: {node: '>=14.*'} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@cspotcode/source-map-support@0.8.1: + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - /@jridgewell/resolve-uri@3.1.1: + '@jridgewell/resolve-uri@3.1.1': resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/sourcemap-codec@1.4.15: + '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - /@jridgewell/trace-mapping@0.3.9: + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@jsdevtools/ez-spawn@3.0.4: + '@jsdevtools/ez-spawn@3.0.4': resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==} engines: {node: '>=10'} - dependencies: - call-me-maybe: 1.0.2 - cross-spawn: 7.0.3 - string-argv: 0.3.2 - type-detect: 4.0.8 - dev: true - /@jsdevtools/version-bump-prompt@6.1.0: + '@jsdevtools/version-bump-prompt@6.1.0': resolution: {integrity: sha512-NJFLJRiD3LLFBgSxAb6B255xhWCGgdtzmh6UjHK2b7SRGX2DDKJH5O4BJ0GTStBu4NnaNgMbkr1TLW3pLOBkOQ==} engines: {node: '>=10'} hasBin: true - dependencies: - '@jsdevtools/ez-spawn': 3.0.4 - command-line-args: 5.2.1 - detect-indent: 6.1.0 - detect-newline: 3.1.0 - globby: 11.1.0 - inquirer: 7.3.3 - log-symbols: 4.1.0 - semver: 7.5.4 - dev: true - /@nodelib/fs.scandir@2.1.5: + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: + '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true - /@nodelib/fs.walk@1.2.8: + '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - dev: true - /@swc/core-darwin-arm64@1.3.99: + '@swc/core-darwin-arm64@1.3.99': resolution: {integrity: sha512-Qj7Jct68q3ZKeuJrjPx7k8SxzWN6PqLh+VFxzA+KwLDpQDPzOlKRZwkIMzuFjLhITO4RHgSnXoDk/Syz0ZeN+Q==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@swc/core-darwin-x64@1.3.99: + '@swc/core-darwin-x64@1.3.99': resolution: {integrity: sha512-wR7m9QVJjgiBu1PSOHy7s66uJPa45Kf9bZExXUL+JAa9OQxt5y+XVzr+n+F045VXQOwdGWplgPnWjgbUUHEVyw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@swc/core-linux-arm64-gnu@1.3.99: + '@swc/core-linux-arm64-gnu@1.3.99': resolution: {integrity: sha512-gcGv1l5t0DScEONmw5OhdVmEI/o49HCe9Ik38zzH0NtDkc+PDYaCcXU5rvfZP2qJFaAAr8cua8iJcOunOSLmnA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@swc/core-linux-arm64-musl@1.3.99: + '@swc/core-linux-arm64-musl@1.3.99': resolution: {integrity: sha512-XL1/eUsTO8BiKsWq9i3iWh7H99iPO61+9HYiWVKhSavknfj4Plbn+XyajDpxsauln5o8t+BRGitymtnAWJM4UQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@swc/core-linux-x64-gnu@1.3.99: + '@swc/core-linux-x64-gnu@1.3.99': resolution: {integrity: sha512-fGrXYE6DbTfGNIGQmBefYxSk3rp/1lgbD0nVg4rl4mfFRQPi7CgGhrrqSuqZ/ezXInUIgoCyvYGWFSwjLXt/Qg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@swc/core-linux-x64-musl@1.3.99: + '@swc/core-linux-x64-musl@1.3.99': resolution: {integrity: sha512-kvgZp/mqf3IJ806gUOL6gN6VU15+DfzM1Zv4Udn8GqgXiUAvbQehrtruid4Snn5pZTLj4PEpSCBbxgxK1jbssA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@swc/core-win32-arm64-msvc@1.3.99: + '@swc/core-win32-arm64-msvc@1.3.99': resolution: {integrity: sha512-yt8RtZ4W/QgFF+JUemOUQAkVW58cCST7mbfKFZ1v16w3pl3NcWd9OrtppFIXpbjU1rrUX2zp2R7HZZzZ2Zk/aQ==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@swc/core-win32-ia32-msvc@1.3.99: + '@swc/core-win32-ia32-msvc@1.3.99': resolution: {integrity: sha512-62p5fWnOJR/rlbmbUIpQEVRconICy5KDScWVuJg1v3GPLBrmacjphyHiJC1mp6dYvvoEWCk/77c/jcQwlXrDXw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - requiresBuild: true - dev: true - optional: true - /@swc/core-win32-x64-msvc@1.3.99: + '@swc/core-win32-x64-msvc@1.3.99': resolution: {integrity: sha512-PdppWhkoS45VGdMBxvClVgF1hVjqamtvYd82Gab1i4IV45OSym2KinoDCKE1b6j3LwBLOn2J9fvChGSgGfDCHQ==} engines: {node: '>=10'} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@swc/core@1.3.99: + '@swc/core@1.3.99': resolution: {integrity: sha512-8O996RfuPC4ieb4zbYMfbyCU9k4gSOpyCNnr7qBQ+o7IEmh8JCV6B8wwu+fT/Om/6Lp34KJe1IpJ/24axKS6TQ==} engines: {node: '>=10'} - requiresBuild: true peerDependencies: '@swc/helpers': ^0.5.0 peerDependenciesMeta: '@swc/helpers': optional: true - dependencies: - '@swc/counter': 0.1.2 - '@swc/types': 0.1.5 - optionalDependencies: - '@swc/core-darwin-arm64': 1.3.99 - '@swc/core-darwin-x64': 1.3.99 - '@swc/core-linux-arm64-gnu': 1.3.99 - '@swc/core-linux-arm64-musl': 1.3.99 - '@swc/core-linux-x64-gnu': 1.3.99 - '@swc/core-linux-x64-musl': 1.3.99 - '@swc/core-win32-arm64-msvc': 1.3.99 - '@swc/core-win32-ia32-msvc': 1.3.99 - '@swc/core-win32-x64-msvc': 1.3.99 - dev: true - /@swc/counter@0.1.2: + '@swc/counter@0.1.2': resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} - dev: true - /@swc/types@0.1.5: + '@swc/types@0.1.5': resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} - dev: true - /@tsconfig/node10@1.0.9: + '@tsconfig/node10@1.0.9': resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - /@tsconfig/node12@1.0.11: + '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - /@tsconfig/node14@1.0.3: + '@tsconfig/node14@1.0.3': resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - /@tsconfig/node16@1.0.4: + '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - /@types/node@20.10.0: + '@types/node@20.10.0': resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==} - dependencies: - undici-types: 5.26.5 - dev: true - /@types/pg@8.10.9: + '@types/pg@8.10.9': resolution: {integrity: sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==} - dependencies: - '@types/node': 20.10.0 - pg-protocol: 1.6.0 - pg-types: 4.0.1 - dev: true - /@types/yargs-parser@21.0.3: + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - dev: true - /@types/yargs@17.0.32: + '@types/yargs@17.0.32': resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} - dependencies: - '@types/yargs-parser': 21.0.3 - dev: true - /acorn-walk@8.3.0: + acorn-walk@8.3.0: resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==} engines: {node: '>=0.4.0'} - dev: true - /acorn@8.11.2: + acorn@8.11.2: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - /ansi-escapes@4.3.2: + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - /ansi-regex@5.0.1: + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - /ansi-styles@4.3.0: + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - /arg@4.1.3: + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - /array-back@3.1.0: + array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} - dev: true - /array-union@2.1.0: + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - dev: true - /braces@3.0.2: + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - /buffer-writer@2.0.0: + buffer-writer@2.0.0: resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==} engines: {node: '>=4'} - dev: false - /call-me-maybe@1.0.2: + call-me-maybe@1.0.2: resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: true - /chalk@4.1.2: + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - /chardet@0.7.0: + chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - /cli-cursor@3.1.0: + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - /cli-width@3.0.0: + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} - dev: true - /cliui@8.0.1: + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: false - /color-convert@2.0.1: + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - /color-name@1.1.4: + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - /command-line-args@5.2.1: + command-line-args@5.2.1: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} - dependencies: - array-back: 3.1.0 - find-replace: 3.0.0 - lodash.camelcase: 4.3.0 - typical: 4.0.0 - dev: true - /create-require@1.1.1: + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - /cross-spawn@7.0.3: + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - /detect-indent@6.1.0: + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} - dev: true - /detect-newline@3.1.0: + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} - dev: true - /diff@4.0.2: + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - dev: true - /dir-glob@3.0.1: + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - /dotenv@16.3.1: + dotenv@16.3.1: resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} engines: {node: '>=12'} - dev: false - /emoji-regex@8.0.0: + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - /escalade@3.1.1: + escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - dev: false - /escape-string-regexp@1.0.5: + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: true - /external-editor@3.1.0: + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - /fast-glob@3.3.2: + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - /fastq@1.15.0: + fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - dev: true - /fdir@6.1.1(picomatch@3.0.1): + fdir@6.1.1: resolution: {integrity: sha512-QfKBVg453Dyn3mr0Q0O+Tkr1r79lOTAKSi9f/Ot4+qVEwxWhav2Z+SudrG9vQjM2aYRMQQZ2/Q1zdA8ACM1pDg==} peerDependencies: picomatch: 3.x peerDependenciesMeta: picomatch: optional: true - dependencies: - picomatch: 3.0.1 - dev: false - /figures@3.2.0: + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: true - /fill-range@7.0.1: + fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - /find-replace@3.0.0: + find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} - dependencies: - array-back: 3.1.0 - dev: true - /get-caller-file@2.0.5: + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - dev: false - /glob-parent@5.1.2: + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - /globby@11.1.0: + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.0 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - /has-flag@4.0.0: + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true - /iconv-lite@0.4.24: + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - /ignore@5.3.0: + ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} - dev: true - /inquirer@7.3.3: + inquirer@7.3.3: resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} engines: {node: '>=8.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - dev: true - /is-extglob@2.1.1: + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true - /is-fullwidth-code-point@3.0.0: + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - /is-glob@4.0.3: + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - /is-number@7.0.0: + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true - /is-unicode-supported@0.1.0: + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - dev: true - /isexe@2.0.0: + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - /lodash.camelcase@4.3.0: + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: true - /lodash.isequal@4.5.0: + lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - dev: false - /lodash@4.17.21: + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - /log-symbols@4.1.0: + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - dev: true - /lru-cache@6.0.0: + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - /make-error@1.3.6: + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - /merge2@1.4.1: + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true - /micromatch@4.0.5: + micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - /mimic-fn@2.1.0: + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true - /mute-stream@0.0.8: + mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - /obuf@1.1.2: + obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - dev: true - /onetime@5.1.2: + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - /os-tmpdir@1.0.2: + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} - dev: true - /oso@0.27.0: + oso@0.27.0: resolution: {integrity: sha512-vGrkKjnyqnHLgU9INYg35paU+gfKWo1l0upISIMWhg1g26nGDVjM6x2CQ/0ZeMpyi+wlmyj5rFQIpO0ziXmDGw==} engines: {node: '>=12.20.0', npm: '>=6.4.1'} hasBin: true - dependencies: - lodash.isequal: 4.5.0 - dev: false - /packet-reader@1.0.0: + packet-reader@1.0.0: resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==} - dev: false - /path-key@3.1.1: + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true - /path-type@4.0.0: + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - dev: true - /pg-cloudflare@1.1.1: + pg-cloudflare@1.1.1: resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} - requiresBuild: true - dev: false - optional: true - /pg-connection-string@2.6.2: + pg-connection-string@2.6.2: resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} - dev: false - /pg-int8@1.0.1: + pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - /pg-numeric@1.0.2: + pg-numeric@1.0.2: resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} engines: {node: '>=4'} - dev: true - /pg-pool@3.6.1(pg@8.11.3): + pg-pool@3.6.1: resolution: {integrity: sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==} peerDependencies: pg: '>=8.0' - dependencies: - pg: 8.11.3 - dev: false - /pg-protocol@1.6.0: + pg-protocol@1.6.0: resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==} - /pg-types@2.2.0: + pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - dev: false - /pg-types@4.0.1: + pg-types@4.0.1: resolution: {integrity: sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==} engines: {node: '>=10'} - dependencies: - pg-int8: 1.0.1 - pg-numeric: 1.0.2 - postgres-array: 3.0.2 - postgres-bytea: 3.0.0 - postgres-date: 2.0.1 - postgres-interval: 3.0.0 - postgres-range: 1.1.3 - dev: true - /pg@8.11.3: + pg@8.11.3: resolution: {integrity: sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==} engines: {node: '>= 8.0.0'} peerDependencies: @@ -806,205 +516,134 @@ packages: peerDependenciesMeta: pg-native: optional: true - dependencies: - buffer-writer: 2.0.0 - packet-reader: 1.0.0 - pg-connection-string: 2.6.2 - pg-pool: 3.6.1(pg@8.11.3) - pg-protocol: 1.6.0 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.1.1 - dev: false - /pgpass@1.0.5: + pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - dependencies: - split2: 4.2.0 - dev: false - /picomatch@2.3.1: + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true - /picomatch@3.0.1: + picomatch@3.0.1: resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} engines: {node: '>=10'} - dev: false - /postgres-array@2.0.0: + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} - dev: false - /postgres-array@3.0.2: + postgres-array@3.0.2: resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} engines: {node: '>=12'} - dev: true - /postgres-bytea@1.0.0: + postgres-bytea@1.0.0: resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} engines: {node: '>=0.10.0'} - dev: false - /postgres-bytea@3.0.0: + postgres-bytea@3.0.0: resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} engines: {node: '>= 6'} - dependencies: - obuf: 1.1.2 - dev: true - /postgres-date@1.0.7: + postgres-date@1.0.7: resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} engines: {node: '>=0.10.0'} - dev: false - /postgres-date@2.0.1: + postgres-date@2.0.1: resolution: {integrity: sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==} engines: {node: '>=12'} - dev: true - /postgres-interval@1.2.0: + postgres-interval@1.2.0: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - dependencies: - xtend: 4.0.2 - dev: false - /postgres-interval@3.0.0: + postgres-interval@3.0.0: resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} engines: {node: '>=12'} - dev: true - /postgres-range@1.1.3: + postgres-range@1.1.3: resolution: {integrity: sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==} - dev: true - /queue-microtask@1.2.3: + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - /require-directory@2.1.1: + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - dev: false - /restore-cursor@3.1.0: + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - /reusify@1.0.4: + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - /run-async@2.4.1: + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} - dev: true - /run-parallel@1.2.0: + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - /rxjs@6.6.7: + rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: true - /safer-buffer@2.1.2: + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - /semver@7.5.4: + semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - /shebang-command@2.0.0: + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - /shebang-regex@3.0.0: + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true - /signal-exit@3.0.7: + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - /slash@3.0.0: + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - dev: true - /split2@4.2.0: + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: false - /string-argv@0.3.2: + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - dev: true - /string-width@4.2.3: + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - /strip-ansi@6.0.1: + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - /supports-color@7.2.0: + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - /through@2.3.8: + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - /tmp@0.0.33: + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - /to-regex-range@5.0.1: + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - /ts-node@10.9.1(@swc/core@1.3.99)(@types/node@20.10.0)(typescript@5.3.2): + ts-node@10.9.1: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -1017,108 +656,626 @@ packages: optional: true '@swc/wasm': optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@swc/core': 1.3.99 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.10.0 - acorn: 8.11.2 - acorn-walk: 8.3.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.3.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - /tslib@1.14.1: + tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - /type-detect@4.0.8: + type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - dev: true - /type-fest@0.21.3: + type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - dev: true - /typescript@5.3.2: - resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true - dev: true - /typical@4.0.0: + typical@4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} - dev: true - /undici-types@5.26.5: + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true - /v8-compile-cache-lib@3.0.1: + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - /which@2.0.2: + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - /wrap-ansi@7.0.0: + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: false - /xtend@4.0.2: + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: false - /y18n@5.0.8: + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: false - /yallist@4.0.0: + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - /yargs-parser@21.1.1: + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: false - /yargs@17.7.2: + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: false - /yn@3.1.1: + yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} - dev: true + +snapshots: + + '@biomejs/biome@1.4.1': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.4.1 + '@biomejs/cli-darwin-x64': 1.4.1 + '@biomejs/cli-linux-arm64': 1.4.1 + '@biomejs/cli-linux-x64': 1.4.1 + '@biomejs/cli-win32-arm64': 1.4.1 + '@biomejs/cli-win32-x64': 1.4.1 + + '@biomejs/cli-darwin-arm64@1.4.1': + optional: true + + '@biomejs/cli-darwin-x64@1.4.1': + optional: true + + '@biomejs/cli-linux-arm64@1.4.1': + optional: true + + '@biomejs/cli-linux-x64@1.4.1': + optional: true + + '@biomejs/cli-win32-arm64@1.4.1': + optional: true + + '@biomejs/cli-win32-x64@1.4.1': + optional: true + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@jridgewell/resolve-uri@3.1.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jsdevtools/ez-spawn@3.0.4': + dependencies: + call-me-maybe: 1.0.2 + cross-spawn: 7.0.3 + string-argv: 0.3.2 + type-detect: 4.0.8 + + '@jsdevtools/version-bump-prompt@6.1.0': + dependencies: + '@jsdevtools/ez-spawn': 3.0.4 + command-line-args: 5.2.1 + detect-indent: 6.1.0 + detect-newline: 3.1.0 + globby: 11.1.0 + inquirer: 7.3.3 + log-symbols: 4.1.0 + semver: 7.5.4 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + + '@swc/core-darwin-arm64@1.3.99': + optional: true + + '@swc/core-darwin-x64@1.3.99': + optional: true + + '@swc/core-linux-arm64-gnu@1.3.99': + optional: true + + '@swc/core-linux-arm64-musl@1.3.99': + optional: true + + '@swc/core-linux-x64-gnu@1.3.99': + optional: true + + '@swc/core-linux-x64-musl@1.3.99': + optional: true + + '@swc/core-win32-arm64-msvc@1.3.99': + optional: true + + '@swc/core-win32-ia32-msvc@1.3.99': + optional: true + + '@swc/core-win32-x64-msvc@1.3.99': + optional: true + + '@swc/core@1.3.99': + dependencies: + '@swc/counter': 0.1.2 + '@swc/types': 0.1.5 + optionalDependencies: + '@swc/core-darwin-arm64': 1.3.99 + '@swc/core-darwin-x64': 1.3.99 + '@swc/core-linux-arm64-gnu': 1.3.99 + '@swc/core-linux-arm64-musl': 1.3.99 + '@swc/core-linux-x64-gnu': 1.3.99 + '@swc/core-linux-x64-musl': 1.3.99 + '@swc/core-win32-arm64-msvc': 1.3.99 + '@swc/core-win32-ia32-msvc': 1.3.99 + '@swc/core-win32-x64-msvc': 1.3.99 + + '@swc/counter@0.1.2': {} + + '@swc/types@0.1.5': {} + + '@tsconfig/node10@1.0.9': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/node@20.10.0': + dependencies: + undici-types: 5.26.5 + + '@types/pg@8.10.9': + dependencies: + '@types/node': 20.10.0 + pg-protocol: 1.6.0 + pg-types: 4.0.1 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.32': + dependencies: + '@types/yargs-parser': 21.0.3 + + acorn-walk@8.3.0: {} + + acorn@8.11.2: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + arg@4.1.3: {} + + array-back@3.1.0: {} + + array-union@2.1.0: {} + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + buffer-writer@2.0.0: {} + + call-me-maybe@1.0.2: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chardet@0.7.0: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-width@3.0.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + detect-indent@6.1.0: {} + + detect-newline@3.1.0: {} + + diff@4.0.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dotenv@16.3.1: {} + + emoji-regex@8.0.0: {} + + escalade@3.1.1: {} + + escape-string-regexp@1.0.5: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fastq@1.15.0: + dependencies: + reusify: 1.0.4 + + fdir@6.1.1(picomatch@3.0.1): + optionalDependencies: + picomatch: 3.0.1 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + + get-caller-file@2.0.5: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.0 + merge2: 1.4.1 + slash: 3.0.0 + + has-flag@4.0.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.0: {} + + inquirer@7.3.3: + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-unicode-supported@0.1.0: {} + + isexe@2.0.0: {} + + lodash.camelcase@4.3.0: {} + + lodash.isequal@4.5.0: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + make-error@1.3.6: {} + + merge2@1.4.1: {} + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + mimic-fn@2.1.0: {} + + mute-stream@0.0.8: {} + + obuf@1.1.2: {} + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + os-tmpdir@1.0.2: {} + + oso@0.27.0: + dependencies: + lodash.isequal: 4.5.0 + + packet-reader@1.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.6.2: {} + + pg-int8@1.0.1: {} + + pg-numeric@1.0.2: {} + + pg-pool@3.6.1(pg@8.11.3): + dependencies: + pg: 8.11.3 + + pg-protocol@1.6.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg-types@4.0.1: + dependencies: + pg-int8: 1.0.1 + pg-numeric: 1.0.2 + postgres-array: 3.0.2 + postgres-bytea: 3.0.0 + postgres-date: 2.0.1 + postgres-interval: 3.0.0 + postgres-range: 1.1.3 + + pg@8.11.3: + dependencies: + buffer-writer: 2.0.0 + packet-reader: 1.0.0 + pg-connection-string: 2.6.2 + pg-pool: 3.6.1(pg@8.11.3) + pg-protocol: 1.6.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picomatch@2.3.1: {} + + picomatch@3.0.1: {} + + postgres-array@2.0.0: {} + + postgres-array@3.0.2: {} + + postgres-bytea@1.0.0: {} + + postgres-bytea@3.0.0: + dependencies: + obuf: 1.1.2 + + postgres-date@1.0.7: {} + + postgres-date@2.0.1: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + postgres-interval@3.0.0: {} + + postgres-range@1.1.3: {} + + queue-microtask@1.2.3: {} + + require-directory@2.1.1: {} + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + run-async@2.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@6.6.7: + dependencies: + tslib: 1.14.1 + + safer-buffer@2.1.2: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + slash@3.0.0: {} + + split2@4.2.0: {} + + string-argv@0.3.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + through@2.3.8: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-node@10.9.1(@swc/core@1.3.99)(@types/node@20.10.0)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.10.0 + acorn: 8.11.2 + acorn-walk: 8.3.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.3.99 + + tslib@1.14.1: {} + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + typescript@5.5.4: {} + + typical@4.0.0: {} + + undici-types@5.26.5: {} + + v8-compile-cache-lib@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@4.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..4d4fb35 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,3 @@ +import pkg from "../package.json" with { type: "json" }; + +export const VERSION = pkg.version; diff --git a/src/pg-backend.ts b/src/pg-backend.ts index 02bc618..c518a3f 100644 --- a/src/pg-backend.ts +++ b/src/pg-backend.ts @@ -12,16 +12,22 @@ import { isTrueClause, simpleEvaluator, } from "./clause.js"; +import { VERSION } from "./constants.js"; import { FunctionPermission, Permission, SQLActor, SQLFunction, + SQLGroup, SQLProcedure, + SQLRowLevelSecurityPolicy, + SQLRowLevelSecurityPolicyPrivilege, + SQLRowLevelSecurityPolicyPrivileges, SQLSchema, SQLSequence, SQLTable, SQLTableMetadata, + SQLUser, SQLView, SchemaPermission, TablePermission, @@ -38,10 +44,11 @@ export class PostgresBackend implements SQLBackend { async fetchEntities(): Promise { const getUsers = () => - this.client.query<{ name: string }>( + this.client.query<{ name: string; id: number }>( ` SELECT - usename as "name" + usename as "name", + usesysid as "id" FROM pg_catalog.pg_user WHERE NOT usesuper @@ -49,10 +56,12 @@ export class PostgresBackend implements SQLBackend { ); const getGroups = () => - this.client.query<{ name: string }>( + this.client.query<{ name: string; userIds: number[]; id: number }>( ` SELECT - groname as "name" + groname as "name", + grolist as "userIds", + grosysid as "id" FROM pg_catalog.pg_group WHERE NOT groname LIKE 'pg_%' @@ -133,6 +142,7 @@ export class PostgresBackend implements SQLBackend { schema: string; table: string; permissive: "PERMISSIVE" | "RESTRICTIVE"; + cmd: string; name: string; users: string; }>( @@ -142,6 +152,7 @@ export class PostgresBackend implements SQLBackend { tablename as "table", policyname as "name", permissive, + cmd, roles as "users" FROM pg_policies @@ -258,9 +269,53 @@ export class PostgresBackend implements SQLBackend { } } + const usersById: Record = Object.fromEntries( + users.rows.map((row) => [row.id, { type: "user", name: row.name }]), + ); + const usersByName = Object.fromEntries( + Object.values(usersById).map((user) => [user.name, user]), + ); + const groupsByName: Record = {}; + for (const group of groups.rows) { + const users = group.userIds.flatMap((userId) => + usersById[userId] ? [usersById[userId]] : [], + ); + groupsByName[group.name] = { type: "group", name: group.name, users }; + } + + const rlsPolicies: SQLRowLevelSecurityPolicy[] = []; + for (const row of policies.rows) { + const users: SQLUser[] = []; + const groups: SQLGroup[] = []; + for (const role of parseArray(row.users)) { + if (groupsByName[role]) { + groups.push(groupsByName[role]); + } + if (usersByName[role]) { + users.push(usersByName[role]); + } + } + let privileges: Set; + if (row.cmd === "ALL") { + privileges = new Set(SQLRowLevelSecurityPolicyPrivileges); + } else { + privileges = new Set([row.cmd as SQLRowLevelSecurityPolicyPrivilege]); + } + + rlsPolicies.push({ + type: "rls-policy", + name: row.name, + table: { type: "table", schema: row.schema, name: row.table }, + permissive: row.permissive, + privileges, + users, + groups, + }); + } + return { - users: users.rows.map((row) => ({ type: "user", name: row.name })), - groups: groups.rows.map((row) => ({ type: "group", name: row.name })), + users: Object.values(usersById), + groups: Object.values(groupsByName), schemas: schemas.rows.map((row) => ({ type: "schema", name: row.name })), views: views.rows.map((row) => ({ type: "view", @@ -268,16 +323,7 @@ export class PostgresBackend implements SQLBackend { name: row.name, })), tables: Object.values(tableItems), - rlsPolicies: policies.rows.map((row) => ({ - type: "rls-policy", - name: row.name, - table: { type: "table", schema: row.schema, name: row.table }, - permissive: row.permissive, - users: parseArray(row.users).map((user) => ({ - type: "user", - name: user, - })), - })), + rlsPolicies, functions, procedures, sequences: sequences.rows.map((row) => ({ type: "sequence", ...row })), @@ -304,12 +350,23 @@ export class PostgresBackend implements SQLBackend { private async loadSqlFile( name: string, variables: Record, + debug?: boolean, ): Promise { const filePath = path.join(SqlDir, name); let content = await fs.promises.readFile(filePath, { encoding: "utf8" }); for (const [key, value] of Object.entries(variables)) { content = content.replaceAll(`{{${key}}}`, value); } + if (!debug) { + // Strip comments + content = content.replace(/\s--\s.+$/gm, ""); + // Trim whitespace + content = content.replace(/\s+/gm, " ").trim(); + // Add pointer to original source code + const baseUrl = `https://github.com/cfeenstra67/sqlauthz/blob/v${VERSION}/src/sql/pg`; + content += ` -- Formatted version: ${baseUrl}/${name}`; + } + return content; } @@ -371,17 +428,35 @@ export class PostgresBackend implements SQLBackend { ]), ); - const tablesWithPermissivePolicies = new Set(); + const tablesWithPermissivePolicies: Record< + string, + Record> + > = {}; for (const policy of entities.rlsPolicies) { if (policy.permissive === "PERMISSIVE") { - tablesWithPermissivePolicies.add( - this.quoteQualifiedName(policy.table), - ); + const tableName = this.quoteQualifiedName(policy.table); + tablesWithPermissivePolicies[tableName] ??= {}; + const users = tablesWithPermissivePolicies[tableName]; + const policyUsers = [...policy.users]; + for (const group of policy.groups) { + users[group.name] ??= new Set(); + const groupPerms = users[group.name]!; + for (const perm of policy.privileges) { + groupPerms.add(perm); + } + policyUsers.push(...group.users); + } + for (const user of policyUsers) { + users[user.name] ??= new Set(); + const userPerms = users[user.name]!; + for (const perm of policy.privileges) { + userPerms.add(perm); + } + } } } const tablesToAddRlsTo = new Set(); - const tablesToAddDefaultPoliciesTo = new Set(); for (const perm of permissions) { if (perm.type !== "table") { continue; @@ -389,6 +464,13 @@ export class PostgresBackend implements SQLBackend { if (isTrueClause(perm.rowClause)) { continue; } + if ( + !SQLRowLevelSecurityPolicyPrivileges.includes( + perm.privilege as SQLRowLevelSecurityPolicyPrivilege, + ) + ) { + continue; + } const tableName = this.quoteQualifiedName(perm.table); const table = metaByTable[tableName]; if (!table) { @@ -397,22 +479,85 @@ export class PostgresBackend implements SQLBackend { if (!table.rlsEnabled) { tablesToAddRlsTo.add(tableName); } - if (!tablesWithPermissivePolicies.has(tableName)) { - tablesToAddDefaultPoliciesTo.add(tableName); + } + + const defaultPoliciesToCreate: Record< + string, + Record> + > = {}; + for (const perm of permissions) { + if (perm.type !== "table") { + continue; + } + if ( + !SQLRowLevelSecurityPolicyPrivileges.includes( + perm.privilege as SQLRowLevelSecurityPolicyPrivilege, + ) + ) { + continue; + } + + const tableName = this.quoteQualifiedName(perm.table); + const table = metaByTable[tableName]; + if (!table) { + continue; + } + if (!table.rlsEnabled && !tablesToAddRlsTo.has(tableName)) { + continue; + } + + const usersWithPolicies = + tablesWithPermissivePolicies[tableName]?.[perm.user.name]; + const missingPerms = new Set(); + for (const perm of SQLRowLevelSecurityPolicyPrivileges) { + if (!usersWithPolicies?.has(perm)) { + missingPerms.add(perm); + } + } + + if (missingPerms.size === 0) { + continue; } + + defaultPoliciesToCreate[tableName] ??= {}; + defaultPoliciesToCreate[tableName]![perm.user.name] = missingPerms; } const enableRlsQueries = Array.from(tablesToAddRlsTo).map( (tableName) => `ALTER TABLE ${tableName} ENABLE ROW LEVEL SECURITY;`, ); - const addDefaultPolicyQueries = Array.from( - tablesToAddDefaultPoliciesTo, - ).map( - (tableName) => - // biome-ignore lint: best way to do this - `CREATE POLICY "default_access" ON ${tableName} AS PERMISSIVE FOR ` + - "ALL TO PUBLIC USING (true);", + const addDefaultPolicyQueries = Object.entries( + defaultPoliciesToCreate, + ).flatMap(([tableName, userPerms]) => + Object.entries(userPerms).flatMap(([userName, perms]) => { + const getQuery = (perm: string) => { + const extra: string[] = []; + if ( + perm === "ALL" || + perm === "DELETE" || + perm === "SELECT" || + perm === "UPDATE" + ) { + extra.push("USING (true)"); + } + if (perm === "ALL" || perm === "INSERT" || perm === "UPDATE") { + extra.push("WITH CHECK (true)"); + } + const name = `${userName}_${perm.toLowerCase()}`; + return ( + `CREATE POLICY ${this.quoteIdentifier(name)} ` + + `ON ${tableName} AS PERMISSIVE FOR ${perm} TO ` + + `${this.quoteIdentifier(userName)} ${extra.join(" ")};` + ); + }; + + if (perms.size === SQLRowLevelSecurityPolicyPrivileges.length) { + return [getQuery("ALL")]; + } + + return Array.from(perms).map((perm) => getQuery(perm)); + }), ); const rlsQueries = enableRlsQueries.concat(addDefaultPolicyQueries); @@ -607,6 +752,8 @@ export class PostgresBackend implements SQLBackend { .join("_") .toLowerCase(); + const rowClauseSql = this.clauseToSql(permission.rowClause); + out.push( `CREATE POLICY ${this.quoteIdentifier( policyName, @@ -614,7 +761,7 @@ export class PostgresBackend implements SQLBackend { permission.table, )} AS RESTRICTIVE FOR UPDATE TO ${this.quoteTopLevelName( permission.user, - )} USING (${this.clauseToSql(permission.rowClause)});`, + )} USING (${rowClauseSql}) WITH CHECK (${rowClauseSql});`, ); } return out; diff --git a/src/sql.ts b/src/sql.ts index 531a0c8..df670a0 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -25,12 +25,24 @@ export interface SQLSchema { name: string; } +export const SQLRowLevelSecurityPolicyPrivileges = [ + "SELECT", + "INSERT", + "UPDATE", + "DELETE", +] as const satisfies TablePrivilege[]; + +export type SQLRowLevelSecurityPolicyPrivilege = + (typeof SQLRowLevelSecurityPolicyPrivileges)[number]; + export interface SQLRowLevelSecurityPolicy { type: "rls-policy"; name: string; table: SQLTable; permissive: "PERMISSIVE" | "RESTRICTIVE"; + privileges: Set; users: SQLUser[]; + groups: SQLGroup[]; } export interface SQLFunction { @@ -61,6 +73,7 @@ export interface SQLUser { export interface SQLGroup { type: "group"; name: string; + users: SQLUser[]; } export type SQLActor = SQLUser | SQLGroup; diff --git a/test/e2e.test.ts b/test/e2e.test.ts index fe1be51..1fa8342 100644 --- a/test/e2e.test.ts +++ b/test/e2e.test.ts @@ -1278,7 +1278,7 @@ describe("adding RLS policies when RLS is already enabled", async () => { for (const [user, useClient, rowCount] of [ ["user1", useClient1, 1], - ["user2", useClient2, 0], + ["user2", useClient2, 2], ] as const) { await it(`${user}: Should not alter existing permissive RLS policies`, async () => { await useClient(async (client) => { @@ -1288,3 +1288,85 @@ describe("adding RLS policies when RLS is already enabled", async () => { }); } }); + +describe("RLS for mutation operations", async () => { + const user1 = userNameGenerator(); + const user2 = userNameGenerator(); + const db = dbNameGenerator(); + const useClient1 = dbClientGenerator(dbUrl(user1, "blah", db)); + const useClient2 = dbClientGenerator(dbUrl(user2, "blah", db)); + + let teardown: () => Promise = async () => {}; + + before(async () => { + teardown = await setupEnv("rls-mutation", "rls-mutation-1", db, { + user1, + user2, + }); + }); + + after(async () => { + await teardown(); + }); + + const authors = ["Author A", "Author B"]; + + for (const [user, userName, isDefaultPolicy, author, useClient] of [ + ["user1", user1, true, "Author A", useClient1], + ["user2", user2, false, "Author B", useClient2], + ] as const) { + const otherAuthor = authors.filter((x) => x !== author)[0]!; + + await it(`${user}: should only be able to update their own articles`, async () => { + await useClient(async (client) => { + const query = + "UPDATE test.articles SET title = title WHERE author = $1"; + const updateResult = await client.query(query, [author]); + assert.equal(updateResult.rowCount, 5); + + const updateResult2 = await client.query(query, [otherAuthor]); + assert.equal(updateResult2.rowCount, 0); + + let error: string; + if (isDefaultPolicy) { + error = `new row violates row-level security policy for table "articles"`; + } else { + error = `new row violates row-level security policy "update_${userName}" for table "articles"`; + } + + await assert.rejects( + client.query( + "UPDATE test.articles SET author = $1 WHERE author = $2", + [otherAuthor, author], + ), + { + message: error, + }, + ); + }); + }); + + await it(`${user}: should only be able to delete their own articles`, async () => { + await useClient(async (client) => { + const query = "DELETE FROM test.articles WHERE author = $1"; + const result = await client.query(query, [author]); + assert.equal(result.rowCount, 5); + const result2 = await client.query(query, [otherAuthor]); + assert.equal(result2.rowCount, 0); + }); + }); + + await it(`${user}: should only be able to create their own articles`, async () => { + await useClient(async (client) => { + const query = + "INSERT INTO test.articles (author, title) VALUES ($1, $2)"; + const result = await client.query(query, [author, "Blah 123"]); + assert.equal(result.rowCount, 1); + + await assert.rejects(client.query(query, [otherAuthor, "Blah 123"]), { + message: `new row violates row-level security policy "insert_${userName}" for table "articles"`, + }); + }); + }); + } +}); diff --git a/test/envs/partial-rls/setup.sql b/test/envs/partial-rls/setup.sql index 898bda7..889d051 100644 --- a/test/envs/partial-rls/setup.sql +++ b/test/envs/partial-rls/setup.sql @@ -47,6 +47,6 @@ CREATE USER {{user1}} WITH PASSWORD 'blah'; CREATE USER {{user2}} WITH PASSWORD 'blah'; -CREATE POLICY "only_allow_user_1" ON test.articles2 AS PERMISSIVE FOR ALL TO {{user1}} USING ("title" = 'Article 1'); +CREATE POLICY "limit_user_1" ON test.articles2 AS PERMISSIVE FOR SELECT TO {{user1}} USING ("title" = 'Article 1'); COMMIT; diff --git a/test/envs/rls-mutation/setup.sql b/test/envs/rls-mutation/setup.sql new file mode 100644 index 0000000..5ad57e8 --- /dev/null +++ b/test/envs/rls-mutation/setup.sql @@ -0,0 +1,34 @@ +BEGIN; + +CREATE SCHEMA test; + +CREATE TABLE test.articles ( + id SERIAL PRIMARY KEY, + author VARCHAR(255) NOT NULL, + title VARCHAR(255) NOT NULL +); + +INSERT INTO test.articles (author, title) +VALUES +('Author A', 'Unique Title 1'), +('Author A', 'Unique Title 2'), +('Author A', 'Unique Title 3'), +('Author A', 'Unique Title 4'), +('Author A', 'Unique Title 5'), +('Author B', 'Unique Title 6'), +('Author B', 'Unique Title 7'), +('Author B', 'Unique Title 8'), +('Author B', 'Unique Title 9'), +('Author B', 'Unique Title 10'); + +ALTER TABLE test.articles ENABLE ROW LEVEL SECURITY; + +CREATE USER {{user1}} WITH PASSWORD 'blah'; + +CREATE USER {{user2}} WITH PASSWORD 'blah'; + +CREATE POLICY "limit_user_1_update" ON test.articles AS PERMISSIVE FOR UPDATE TO {{user1}} USING ("author" = 'Author A') WITH CHECK ("author" = 'Author A'); + +CREATE POLICY "limit_user_2_delete" ON test.articles AS PERMISSIVE FOR DELETE TO {{user2}} USING ("author" = 'Author B'); + +COMMIT; diff --git a/test/envs/rls-mutation/teardown.sql b/test/envs/rls-mutation/teardown.sql new file mode 100644 index 0000000..5ebdbb8 --- /dev/null +++ b/test/envs/rls-mutation/teardown.sql @@ -0,0 +1,2 @@ +DROP ROLE {{user1}}; +DROP ROLE {{user2}}; diff --git a/test/rules/rls-mutation-1.polar b/test/rules/rls-mutation-1.polar new file mode 100644 index 0000000..78e418c --- /dev/null +++ b/test/rules/rls-mutation-1.polar @@ -0,0 +1,19 @@ + +allow(user1, "usage", "test"); +allow(user2, "usage", "test"); +allow(user1, "usage", "test.articles_id_seq"); +allow(user2, "usage", "test.articles_id_seq"); +allow(user1, "select", "test.articles"); +allow(user2, "select", "test.articles"); +allow(user1, "update", "test.articles"); +allow(user2, "delete", "test.articles"); + +allow(user2, perm, resource) + if resource == "test.articles" + and perm in ["update", "insert"] + and resource.row.author == "Author B"; + +allow(user1, perm, resource) + if resource == "test.articles" + and perm in ["delete", "insert"] + and resource.row.author == "Author A"; diff --git a/tsconfig.build.json b/tsconfig.build.json index a98d051..0070f1d 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -3,6 +3,7 @@ "include": ["src"], "compilerOptions": { "noEmit": false, + "rootDir": "./src", "outDir": "./dist" } } diff --git a/tsconfig.json b/tsconfig.json index a3e54e0..9d98d71 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", + "resolveJsonModule": true, "declaration": true, "emitDecoratorMetadata": true, "experimentalDecorators": true,