From 4274a8dfc170907f76eab7891eabe490ff1407f8 Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Wed, 20 Dec 2023 18:26:53 +0000 Subject: [PATCH] Generate TyepScript interface completely from Python (#112) --- .github/workflows/ci.yml | 1 + .pre-commit-config.yaml | 8 +- demo/auth.py | 2 +- demo/forms.py | 6 +- demo/tables.py | 8 +- package-lock.json | 656 ++++---- package.json | 4 +- pyproject.toml | 4 + src/npm-fastui-bootstrap/src/index.tsx | 10 +- src/npm-fastui-bootstrap/src/modal.tsx | 4 +- src/npm-fastui-bootstrap/src/navbar.tsx | 6 +- src/npm-fastui-bootstrap/src/pagination.tsx | 10 +- src/npm-fastui/src/components/Code.tsx | 10 - src/npm-fastui/src/components/CodeLazy.tsx | 4 +- src/npm-fastui/src/components/Custom.tsx | 15 +- src/npm-fastui/src/components/FireEvent.tsx | 13 +- src/npm-fastui/src/components/FormField.tsx | 87 +- src/npm-fastui/src/components/Iframe.tsx | 20 +- src/npm-fastui/src/components/Json.tsx | 12 +- src/npm-fastui/src/components/LinkList.tsx | 13 +- src/npm-fastui/src/components/Markdown.tsx | 9 - .../src/components/MarkdownLazy.tsx | 16 +- src/npm-fastui/src/components/PageTitle.tsx | 7 +- src/npm-fastui/src/components/ServerLoad.tsx | 16 +- src/npm-fastui/src/components/button.tsx | 14 +- src/npm-fastui/src/components/details.tsx | 19 +- src/npm-fastui/src/components/display.tsx | 83 +- src/npm-fastui/src/components/div.tsx | 21 +- src/npm-fastui/src/components/form.tsx | 31 +- src/npm-fastui/src/components/heading.tsx | 18 +- src/npm-fastui/src/components/image.tsx | 28 +- src/npm-fastui/src/components/index.tsx | 159 +- src/npm-fastui/src/components/link.tsx | 20 +- src/npm-fastui/src/components/modal.tsx | 18 +- src/npm-fastui/src/components/navbar.tsx | 17 +- src/npm-fastui/src/components/pagination.tsx | 22 +- src/npm-fastui/src/components/paragraph.tsx | 10 +- src/npm-fastui/src/components/table.tsx | 20 +- src/npm-fastui/src/components/text.tsx | 7 +- src/npm-fastui/src/components/video.tsx | 26 +- src/npm-fastui/src/events.ts | 28 +- src/npm-fastui/src/hooks/className.ts | 11 +- src/npm-fastui/src/hooks/config.ts | 3 +- src/npm-fastui/src/index.tsx | 6 +- src/npm-fastui/src/models.d.ts | 396 +++++ src/python-fastui/fastui/__main__.py | 32 + src/python-fastui/fastui/class_name.py | 3 +- .../fastui/components/__init__.py | 26 +- .../fastui/components/display.py | 22 +- src/python-fastui/fastui/components/forms.py | 18 +- src/python-fastui/fastui/components/py.typed | 0 src/python-fastui/fastui/components/tables.py | 32 +- .../fastui/generate_typescript.py | 136 ++ src/python-fastui/fastui/json_schema.py | 5 +- src/python-fastui/fastui/py.typed | 0 src/python-fastui/fastui/types.py | 44 + src/python-fastui/pyproject.toml | 3 + .../tests/react-fastui-json-schema.json | 1433 ----------------- .../tests/react-fastui-json-schema.sh | 11 - src/python-fastui/tests/test_forms.py | 12 +- src/python-fastui/tests/test_json_schema.py | 14 + .../tests/test_json_schema_match.py | 166 -- .../tests/test_tables_display.py | 76 + 63 files changed, 1354 insertions(+), 2577 deletions(-) create mode 100644 src/npm-fastui/src/models.d.ts create mode 100644 src/python-fastui/fastui/__main__.py create mode 100644 src/python-fastui/fastui/components/py.typed create mode 100644 src/python-fastui/fastui/generate_typescript.py create mode 100644 src/python-fastui/fastui/py.typed create mode 100644 src/python-fastui/fastui/types.py delete mode 100644 src/python-fastui/tests/react-fastui-json-schema.json delete mode 100755 src/python-fastui/tests/react-fastui-json-schema.sh create mode 100644 src/python-fastui/tests/test_json_schema.py delete mode 100644 src/python-fastui/tests/test_json_schema_match.py create mode 100644 src/python-fastui/tests/test_tables_display.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4f15033..325d8e55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,7 @@ jobs: node-version: 18 - run: pip install -r src/python-fastui/requirements/all.txt + - run: pip install src/python-fastui - run: npm install diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6fa200a4..e924d9a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,9 +39,9 @@ repos: entry: npm run typecheck language: system pass_filenames: false - - id: js-json-schema - name: js-json-schema - types_or: [ts, tsx] - entry: npm run generate-json-schema + - id: python-generate-ts + name: python-generate-ts + types_or: [python] + entry: fastui generate fastui:FastUI src/npm-fastui/src/models.d.ts language: system pass_filenames: false diff --git a/demo/auth.py b/demo/auth.py index 44ac057b..b9ba8da5 100644 --- a/demo/auth.py +++ b/demo/auth.py @@ -35,7 +35,7 @@ def auth_login(user: Annotated[str | None, Depends(get_user)]) -> list[AnyCompon ) ), c.Heading(text='Login'), - c.ModelForm[LoginForm](submit_url='/api/auth/login'), + c.ModelForm(model=LoginForm, submit_url='/api/auth/login'), title='Authentication', ) else: diff --git a/demo/forms.py b/demo/forms.py index 9dad9f7e..b5bf3da9 100644 --- a/demo/forms.py +++ b/demo/forms.py @@ -85,19 +85,19 @@ def form_content(kind: FormKind): return [ c.Heading(text='Login Form', level=2), c.Paragraph(text='Simple login form with email and password.'), - c.ModelForm[LoginForm](submit_url='/api/forms/login'), + c.ModelForm(model=LoginForm, submit_url='/api/forms/login'), ] case 'select': return [ c.Heading(text='Select Form', level=2), c.Paragraph(text='Form showing different ways of doing select.'), - c.ModelForm[SelectForm](submit_url='/api/forms/select'), + c.ModelForm(model=SelectForm, submit_url='/api/forms/select'), ] case 'big': return [ c.Heading(text='Large Form', level=2), c.Paragraph(text='Form with a lot of fields.'), - c.ModelForm[BigModel](submit_url='/api/forms/big'), + c.ModelForm(model=BigModel, submit_url='/api/forms/big'), ] case _: raise ValueError(f'Invalid kind {kind!r}') diff --git a/demo/tables.py b/demo/tables.py index 96a77fab..d78bc8e4 100644 --- a/demo/tables.py +++ b/demo/tables.py @@ -58,15 +58,17 @@ def cities_view(page: int = 1, country: str | None = None) -> list[AnyComponent] filter_form_initial['country'] = {'value': country, 'label': country_name} return demo_page( *tabs(), - c.ModelForm[FilterForm]( + c.ModelForm( + model=FilterForm, submit_url='.', initial=filter_form_initial, method='GOTO', submit_on_change=True, display_mode='inline', ), - c.Table[City]( + c.Table( data=cities[(page - 1) * page_size : page * page_size], + data_model=City, columns=[ DisplayLookup(field='city', on_click=GoToEvent(url='./{id}'), table_width_percent=33), DisplayLookup(field='country', table_width_percent=33), @@ -107,7 +109,7 @@ class User(BaseModel): def users_view() -> list[AnyComponent]: return demo_page( *tabs(), - c.Table[User]( + c.Table( data=users, columns=[ DisplayLookup(field='name', on_click=GoToEvent(url='/table/users/{id}/')), diff --git a/package-lock.json b/package-lock.json index 142f817c..487959a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,9 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", "eslint-plugin-simple-import-sort": "^10.0.0", + "json-schema-to-typescript": "^13.1.1", "prettier": "^3.0.3", - "typescript": "^5.0.2", - "typescript-json-schema": "^0.62.0" + "typescript": "^5.0.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -239,16 +239,22 @@ "node": ">=6.9.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@bcherny/json-schema-ref-parser": { + "version": "10.0.5-fork", + "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", + "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" }, "engines": { - "node": ">=12" + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" } }, "node_modules/@emotion/babel-plugin": { @@ -817,31 +823,12 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "dev": true }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1157,7 +1144,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -1174,7 +1160,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -1191,7 +1176,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -1208,7 +1192,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -1225,7 +1208,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -1242,7 +1224,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -1259,7 +1240,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -1276,7 +1256,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -1293,7 +1272,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -1310,7 +1288,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -1335,30 +1312,6 @@ "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", "dev": true }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -1367,6 +1320,16 @@ "@types/ms": "*" } }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/hast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", @@ -1388,6 +1351,12 @@ "dev": true, "peer": true }, + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, "node_modules/@types/mdast": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", @@ -1396,6 +1365,12 @@ "@types/unist": "*" } }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", @@ -1415,6 +1390,12 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.10", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.10.tgz", @@ -1704,15 +1685,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", - "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1753,6 +1725,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -1765,12 +1743,6 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2042,6 +2014,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2144,18 +2122,20 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" }, "engines": { - "node": ">=12" + "node": ">=0.10" } }, "node_modules/color-convert": { @@ -2211,12 +2191,6 @@ "node": ">=10" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2236,6 +2210,16 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2321,15 +2305,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2363,12 +2338,6 @@ "csstype": "^3.0.2" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2492,6 +2461,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/esbuild": { "version": "0.19.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", @@ -2529,15 +2546,6 @@ "@esbuild/win32-x64": "0.19.5" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3006,6 +3014,31 @@ "node": ">=0.10.0" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3213,15 +3246,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -3237,6 +3261,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -3298,6 +3334,25 @@ "node": ">=10.13.0" } }, + "node_modules/glob-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", + "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/ahmadnassri" + }, + "peerDependencies": { + "glob": "^7.1.6" + } + }, "node_modules/globals": { "version": "13.23.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", @@ -3830,15 +3885,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -3938,6 +3984,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -4107,6 +4159,49 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-schema-to-typescript": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.1.tgz", + "integrity": "sha512-F3CYhtA7F3yPbb8vF7sFchk/2dnr1/yTKf8RcvoNpjnh67ZS/ZMH1ElLt5KHAtf2/bymiejLQQszszPWEeTdSw==", + "dev": true, + "dependencies": { + "@bcherny/json-schema-ref-parser": "10.0.5-fork", + "@types/json-schema": "^7.0.11", + "@types/lodash": "^4.14.182", + "@types/prettier": "^2.6.1", + "cli-color": "^2.0.2", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^4.2.2", + "is-glob": "^4.0.3", + "lodash": "^4.17.21", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.6.2" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-schema-to-typescript/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4189,6 +4284,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -4240,11 +4341,14 @@ "node": ">=10" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } }, "node_modules/markdown-table": { "version": "3.0.3", @@ -4467,6 +4571,22 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5041,16 +5161,38 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -5075,6 +5217,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5311,12 +5459,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-equal": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/path-equal/-/path-equal-1.2.5.tgz", - "integrity": "sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5768,15 +5910,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -5919,15 +6052,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/sass": { "version": "1.69.5", "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", @@ -6065,20 +6189,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", @@ -6220,6 +6330,37 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -6269,49 +6410,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -6330,6 +6428,12 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6432,44 +6536,6 @@ "node": ">=14.17" } }, - "node_modules/typescript-json-schema": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.62.0.tgz", - "integrity": "sha512-qRO6pCgyjKJ230QYdOxDRpdQrBeeino4v5p2rYmSD72Jf4rD3O+cJcROv46sQukm46CLWoeusqvBgKpynEv25g==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/node": "^16.9.2", - "glob": "^7.1.7", - "path-equal": "^1.2.5", - "safe-stable-stringify": "^2.2.0", - "ts-node": "^10.9.1", - "typescript": "~5.1.0", - "yargs": "^17.1.1" - }, - "bin": { - "typescript-json-schema": "bin/typescript-json-schema" - } - }, - "node_modules/typescript-json-schema/node_modules/@types/node": { - "version": "16.18.67", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.67.tgz", - "integrity": "sha512-gUa0tDO9oxyAYO9V9tqxDJguVMDpqUwH5I5Q9ASYBCso+8CUdJlKPKDYS1YSS9kyZWIduDafZvucGM0zGNKFjg==", - "dev": true - }, - "node_modules/typescript-json-schema/node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6608,12 +6674,6 @@ } } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/vfile": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", @@ -6796,23 +6856,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6827,15 +6870,6 @@ "node": ">=0.4" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -6850,42 +6884,6 @@ "node": ">= 6" } }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "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.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index ad2657d3..98639d0a 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", "eslint-plugin-simple-import-sort": "^10.0.0", + "json-schema-to-typescript": "^13.1.1", "prettier": "^3.0.3", - "typescript": "^5.0.2", - "typescript-json-schema": "^0.62.0" + "typescript": "^5.0.2" } } diff --git a/pyproject.toml b/pyproject.toml index 3636de43..cae01196 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,3 +22,7 @@ asyncio_mode = "auto" [tool.coverage.run] source = ["src/python-fastui/fastui"] +omit = [ + "src/python-fastui/fastui/__main__.py", + "src/python-fastui/fastui/generate_typescript.py", +] diff --git a/src/npm-fastui-bootstrap/src/index.tsx b/src/npm-fastui-bootstrap/src/index.tsx index 8eb7c20a..10525181 100644 --- a/src/npm-fastui-bootstrap/src/index.tsx +++ b/src/npm-fastui-bootstrap/src/index.tsx @@ -1,6 +1,6 @@ import { pathMatch } from 'fastui' -import type { ClassNameGenerator, CustomRender, ClassName } from 'fastui' +import type { ClassNameGenerator, CustomRender, models } from 'fastui' import { Modal } from './modal' import { Navbar } from './navbar' @@ -18,7 +18,11 @@ export const customRender: CustomRender = (props) => { } } -export const classNameGenerator: ClassNameGenerator = ({ props, fullPath, subElement }): ClassName => { +export const classNameGenerator: ClassNameGenerator = ({ + props, + fullPath, + subElement, +}): models.ClassName | undefined => { const { type } = props switch (type) { case 'Page': @@ -78,7 +82,7 @@ export const classNameGenerator: ClassNameGenerator = ({ props, fullPath, subEle if (props.displayMode === 'inline') { return 'visually-hidden' } else { - return { 'form-label': true, 'fw-bold': props.required, 'form-check-label': type === 'FormFieldBoolean' } + return { 'form-label': true, 'fw-bold': !!props.required, 'form-check-label': type === 'FormFieldBoolean' } } case 'error': return 'invalid-feedback' diff --git a/src/npm-fastui-bootstrap/src/modal.tsx b/src/npm-fastui-bootstrap/src/modal.tsx index 91e701d8..a286ec76 100644 --- a/src/npm-fastui-bootstrap/src/modal.tsx +++ b/src/npm-fastui-bootstrap/src/modal.tsx @@ -1,8 +1,8 @@ import { FC } from 'react' -import { components, events, renderClassName, EventContextProvider } from 'fastui' +import { models, components, events, renderClassName, EventContextProvider } from 'fastui' import BootstrapModal from 'react-bootstrap/Modal' -export const Modal: FC = (props) => { +export const Modal: FC = (props) => { const { className, title, body, footer, openTrigger, openContext } = props const { eventContext, fireId, clear } = events.usePageEventListen(openTrigger, openContext) diff --git a/src/npm-fastui-bootstrap/src/navbar.tsx b/src/npm-fastui-bootstrap/src/navbar.tsx index a571b4a0..4e84faf6 100644 --- a/src/npm-fastui-bootstrap/src/navbar.tsx +++ b/src/npm-fastui-bootstrap/src/navbar.tsx @@ -1,8 +1,8 @@ import { FC } from 'react' -import { components, useClassName } from 'fastui' +import { components, useClassName, models } from 'fastui' import BootstrapNavbar from 'react-bootstrap/Navbar' -export const Navbar: FC = (props) => { +export const Navbar: FC = (props) => { const links = props.links.map((link) => { link.mode = link.mode || 'navbar' return link @@ -26,7 +26,7 @@ export const Navbar: FC = (props) => { ) } -const NavbarTitle = (props: components.NavbarProps) => { +const NavbarTitle = (props: models.Navbar) => { const { title, titleEvent } = props const className = useClassName(props, { el: 'title' }) if (title) { diff --git a/src/npm-fastui-bootstrap/src/pagination.tsx b/src/npm-fastui-bootstrap/src/pagination.tsx index 7e6a9919..ed32fe68 100644 --- a/src/npm-fastui-bootstrap/src/pagination.tsx +++ b/src/npm-fastui-bootstrap/src/pagination.tsx @@ -1,5 +1,5 @@ import { FC } from 'react' -import { components, ClassName, renderClassName, events } from 'fastui' +import { components, models, renderClassName } from 'fastui' interface Link { Display: FC @@ -9,7 +9,7 @@ interface Link { page?: number } -export const Pagination: FC = (props) => { +export const Pagination: FC = (props) => { const { page, pageCount } = props if (pageCount === 1) return null @@ -81,10 +81,10 @@ const PaginationLink: FC = ({ Display, ariaLabel, locked, active, page }) ) } - const className = renderClassName({ 'page-link': true, disabled: locked && !active, active } as ClassName) - let onClick: events.GoToEvent + const className = renderClassName({ 'page-link': true, disabled: locked && !active, active } as models.ClassName) + let onClick: models.GoToEvent if (page === 1) { - onClick = { type: 'go-to', query: { page: null } } + onClick = { type: 'go-to', query: {} } } else { onClick = { type: 'go-to', query: { page } } } diff --git a/src/npm-fastui/src/components/Code.tsx b/src/npm-fastui/src/components/Code.tsx index 39046e92..af269c92 100644 --- a/src/npm-fastui/src/components/Code.tsx +++ b/src/npm-fastui/src/components/Code.tsx @@ -1,13 +1,3 @@ import { lazy } from 'react' -import { ClassName } from '../hooks/className' - -export interface CodeProps { - type: 'Code' - text: string - language?: string - className?: ClassName - codeStyle?: string -} - export const CodeComp = lazy(() => import('./CodeLazy')) diff --git a/src/npm-fastui/src/components/CodeLazy.tsx b/src/npm-fastui/src/components/CodeLazy.tsx index 1bd10946..a2f4fdee 100644 --- a/src/npm-fastui/src/components/CodeLazy.tsx +++ b/src/npm-fastui/src/components/CodeLazy.tsx @@ -1,11 +1,11 @@ import * as codeStyles from 'react-syntax-highlighter/dist/esm/styles/prism' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' -import type { CodeProps } from './Code' +import type { Code } from '../models' import { useClassName } from '../hooks/className' -export default function (props: CodeProps) { +export default function (props: Code) { const { text, language, codeStyle } = props const codeLookup = codeStyle as keyof typeof codeStyles const style = (codeStyle && codeStyles[codeLookup]) || codeStyles.coldarkCold diff --git a/src/npm-fastui/src/components/Custom.tsx b/src/npm-fastui/src/components/Custom.tsx index 3fce72a1..8ef1fb5f 100644 --- a/src/npm-fastui/src/components/Custom.tsx +++ b/src/npm-fastui/src/components/Custom.tsx @@ -1,19 +1,12 @@ import { FC, useContext } from 'react' -import { ClassName } from '../hooks/className' -import { ErrorContext } from '../hooks/error' +import type { Custom } from '../models' -import { JsonData, JsonComp } from './Json' +import { ErrorContext } from '../hooks/error' -export interface CustomProps { - type: 'Custom' - data: JsonData - subType: string - library?: string - className?: ClassName -} +import { JsonComp } from './Json' -export const CustomComp: FC = (props) => { +export const CustomComp: FC = (props) => { const { data, subType, library } = props const { DisplayError } = useContext(ErrorContext) diff --git a/src/npm-fastui/src/components/FireEvent.tsx b/src/npm-fastui/src/components/FireEvent.tsx index d34a4226..5949c122 100644 --- a/src/npm-fastui/src/components/FireEvent.tsx +++ b/src/npm-fastui/src/components/FireEvent.tsx @@ -1,17 +1,10 @@ import { FC, useEffect, useRef } from 'react' -import { AnyEvent, useFireEvent } from '../events' -import { ClassName } from '../hooks/className' +import type { FireEvent } from '../models' -export interface FireEventProps { - type: 'FireEvent' - event: AnyEvent - message?: string - // className is not used, but it's here to satisfy ClassName hooks type checks - className?: ClassName -} +import { useFireEvent } from '../events' -export const FireEventComp: FC = ({ event, message }) => { +export const FireEventComp: FC = ({ event, message }) => { const { fireEvent } = useFireEvent() const fireEventRef = useRef(fireEvent) diff --git a/src/npm-fastui/src/components/FormField.tsx b/src/npm-fastui/src/components/FormField.tsx index dcf88fb4..31eeca50 100644 --- a/src/npm-fastui/src/components/FormField.tsx +++ b/src/npm-fastui/src/components/FormField.tsx @@ -2,37 +2,26 @@ import { FC, useState } from 'react' import AsyncSelect from 'react-select/async' import Select, { StylesConfig } from 'react-select' -import { ClassName, useClassName } from '../hooks/className' +import type { + FormFieldInput, + FormFieldBoolean, + FormFieldFile, + FormFieldSelect, + FormFieldSelectSearch, + SelectOption, + SelectOptions, + SelectGroup, +} from '../models' + +import { useClassName } from '../hooks/className' import { debounce, useRequest } from '../tools' type PrivateOnChange = () => void -interface BaseFormFieldProps { - name: string - title: string | string[] - required: boolean - locked: boolean - error?: string - description?: string - displayMode?: 'default' | 'inline' - className?: ClassName +interface FormFieldInputProps extends FormFieldInput { onChange?: PrivateOnChange } -export type FormFieldProps = - | FormFieldInputProps - | FormFieldBooleanProps - | FormFieldFileProps - | FormFieldSelectProps - | FormFieldSelectSearchProps - -interface FormFieldInputProps extends BaseFormFieldProps { - type: 'FormFieldInput' - htmlType: 'text' | 'date' | 'datetime-local' | 'time' | 'email' | 'url' | 'number' | 'password' | 'hidden' - initial?: string | number - placeholder?: string -} - export const FormFieldInputComp: FC = (props) => { const { name, placeholder, required, htmlType, locked } = props @@ -55,10 +44,8 @@ export const FormFieldInputComp: FC = (props) => { ) } -interface FormFieldBooleanProps extends BaseFormFieldProps { - type: 'FormFieldBoolean' - mode: 'checkbox' | 'switch' - initial?: boolean +interface FormFieldBooleanProps extends FormFieldBoolean { + onChange?: PrivateOnChange } export const FormFieldBooleanComp: FC = (props) => { @@ -82,10 +69,8 @@ export const FormFieldBooleanComp: FC = (props) => { ) } -interface FormFieldFileProps extends BaseFormFieldProps { - type: 'FormFieldFile' - multiple?: boolean - accept?: string +interface FormFieldFileProps extends FormFieldFile { + onChange?: PrivateOnChange } export const FormFieldFileComp: FC = (props) => { @@ -109,31 +94,14 @@ export const FormFieldFileComp: FC = (props) => { ) } -interface SelectOption { - value: string - label: string -} - -interface SelectGroup { - label: string - options: SelectOption[] -} - -type SelectOptions = SelectOption[] | SelectGroup[] - // cheat slightly and match bootstrap 😱 // TODO make this configurable as an argument to `FastUI` const styles: StylesConfig = { control: (base) => ({ ...base, borderRadius: '0.375rem', border: '1px solid #dee2e6' }), } -interface FormFieldSelectProps extends BaseFormFieldProps { - type: 'FormFieldSelect' - options: SelectOptions - initial?: string - multiple?: boolean - vanilla?: boolean - placeholder?: string +interface FormFieldSelectProps extends FormFieldSelect { + onChange?: PrivateOnChange } export const FormFieldSelectComp: FC = (props) => { @@ -238,14 +206,8 @@ function findDefault(options: SelectOptions, value?: string): SelectOption | und } } -interface FormFieldSelectSearchProps extends BaseFormFieldProps { - type: 'FormFieldSelectSearch' - searchUrl: string - /** @TJS-type integer */ - debounce?: number - initial?: SelectOption - multiple?: boolean - placeholder?: string +interface FormFieldSelectSearchProps extends FormFieldSelectSearch { + onChange?: PrivateOnChange } export const FormFieldSelectSearchComp: FC = (props) => { @@ -320,6 +282,13 @@ const Label: FC = (props) => { ) } +export type FormFieldProps = + | FormFieldInputProps + | FormFieldBooleanProps + | FormFieldFileProps + | FormFieldSelectProps + | FormFieldSelectSearchProps + const inputId = (props: FormFieldProps) => `form-field-${props.name}` const descId = (props: FormFieldProps) => (props.description ? `${inputId(props)}-desc` : undefined) diff --git a/src/npm-fastui/src/components/Iframe.tsx b/src/npm-fastui/src/components/Iframe.tsx index c7895765..818d8160 100644 --- a/src/npm-fastui/src/components/Iframe.tsx +++ b/src/npm-fastui/src/components/Iframe.tsx @@ -1,24 +1,8 @@ import { FC } from 'react' -import { ClassName } from '../hooks/className' +import type { Iframe } from '../models' -export interface IframeProps { - type: 'Iframe' - /** - * @format uri - * @maxLength 2083 - * @minLength 1 - */ - src: string - /** @TJS-type ["string", "integer"] */ - width?: string | number - /** @TJS-type ["string", "integer"] */ - height?: string | number - title?: string - className?: ClassName -} - -export const IframeComp: FC = (props) => { +export const IframeComp: FC