diff --git a/.gitignore b/.gitignore index d60197e0c..cc376bd6c 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ stats.html .nx/workspace-data .pnpm-store .tsup +.svelte-kit vite.config.js.timestamp-* vite.config.ts.timestamp-* diff --git a/packages/svelte-form/README.md b/packages/svelte-form/README.md new file mode 100644 index 000000000..3e608b1f8 --- /dev/null +++ b/packages/svelte-form/README.md @@ -0,0 +1 @@ +TODO - add a readme diff --git a/packages/svelte-form/eslint.config.js b/packages/svelte-form/eslint.config.js new file mode 100644 index 000000000..8ce6ad05f --- /dev/null +++ b/packages/svelte-form/eslint.config.js @@ -0,0 +1,5 @@ +// @ts-check + +import rootConfig from '../../eslint.config.js' + +export default [...rootConfig] diff --git a/packages/svelte-form/index.html b/packages/svelte-form/index.html new file mode 100644 index 000000000..f8b7e0579 --- /dev/null +++ b/packages/svelte-form/index.html @@ -0,0 +1,20 @@ + + + + + + Svelte + + +
+ + + diff --git a/packages/svelte-form/package.json b/packages/svelte-form/package.json new file mode 100644 index 000000000..08c7b7f8b --- /dev/null +++ b/packages/svelte-form/package.json @@ -0,0 +1,57 @@ +{ + "name": "@tanstack/svelte-form", + "version": "0.0.1", + "description": "Powerful, type-safe forms for Svelte.", + "author": "James Garbutt (https://github.com/43081j)", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/TanStack/form.git", + "directory": "packages/svelte-form" + }, + "homepage": "https://tanstack.com/form", + "scripts": { + "clean": "premove ./dist ./coverage", + "test:eslint": "eslint ./src ./tests", + "test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"", + "test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js", + "test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js", + "test:types:ts53": "node ../../node_modules/typescript53/lib/tsc.js", + "test:types:ts54": "node ../../node_modules/typescript54/lib/tsc.js", + "test:types:ts55": "node ../../node_modules/typescript55/lib/tsc.js", + "test:types:ts56": "tsc", + "test:lib": "vitest", + "test:lib:dev": "pnpm run test:lib --watch", + "test:build": "publint --strict", + "build": "svelte-package --input ./src --output ./dist" + }, + "type": "module", + "types": "dist/index.d.ts", + "module": "dist/index.js", + "svelte": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "svelte": "./dist/index.js", + "import": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "files": [ + "dist", + "src" + ], + "dependencies": { + "@tanstack/form-core": "workspace:*" + }, + "devDependencies": { + "@sveltejs/package": "^2.3.7", + "@sveltejs/vite-plugin-svelte": "^4.0.4", + "premove": "^4.0.0", + "svelte": "^5.16.1" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } +} diff --git a/packages/svelte-form/src/Field.svelte b/packages/svelte-form/src/Field.svelte new file mode 100644 index 000000000..45de85957 --- /dev/null +++ b/packages/svelte-form/src/Field.svelte @@ -0,0 +1,51 @@ + + + +{@render children(fieldApi)} diff --git a/packages/svelte-form/src/createField.svelte.ts b/packages/svelte-form/src/createField.svelte.ts new file mode 100644 index 000000000..75017799c --- /dev/null +++ b/packages/svelte-form/src/createField.svelte.ts @@ -0,0 +1,88 @@ +import { FieldApi } from '@tanstack/form-core' +import { onDestroy, onMount } from 'svelte' +import Field from './Field.svelte' + +import type { + DeepKeys, + DeepValue, + FieldApiOptions, + Narrow, + Validator, +} from '@tanstack/form-core' + +interface SvelteFieldApi< + TParentData, + TFormValidator extends + | Validator + | undefined = undefined, +> { + Field: Field +} + +export type CreateField< + TParentData, + TFormValidator extends + | Validator + | undefined = undefined, +> = < + TName extends DeepKeys, + TFieldValidator extends + | Validator, unknown> + | undefined = undefined, + TData extends DeepValue = DeepValue, +>( + opts: () => { name: Narrow } & Omit< + FieldApiOptions, + 'form' + >, +) => FieldApi & + SvelteFieldApi + +export function createField< + TParentData, + TName extends DeepKeys, + TFieldValidator extends + | Validator, unknown> + | undefined = undefined, + TFormValidator extends + | Validator + | undefined = undefined, + TData extends DeepValue = DeepValue, +>( + opts: () => FieldApiOptions< + TParentData, + TName, + TFieldValidator, + TFormValidator, + TData + >, +) { + const options = opts() + + const api = new FieldApi(options) + + const extendedApi: typeof api & SvelteFieldApi = + api as never + + extendedApi.Field = Field as never + + let mounted = false + // Instantiates field meta and removes it when unrendered + onMount(() => { + const cleanupFn = api.mount() + mounted = true + onDestroy(() => { + cleanupFn() + mounted = false + }) + }) + + // TODO (43081j): does this do what i think? we don't access anything + // svelte is aware of, so maybe it'll never call this? + $effect(() => { + if (!mounted) return + api.update(opts()) + }) + + return extendedApi +} diff --git a/packages/svelte-form/src/createForm.svelte.ts b/packages/svelte-form/src/createForm.svelte.ts new file mode 100644 index 000000000..fd97db98d --- /dev/null +++ b/packages/svelte-form/src/createForm.svelte.ts @@ -0,0 +1,44 @@ +import { FormApi } from '@tanstack/form-core' +import { onMount } from 'svelte' +import { createField } from './createField.svelte.js' +import Field from './Field.svelte' +import type { FormOptions, Validator } from '@tanstack/form-core' +import type { CreateField } from './createField.svelte.js' + +export interface SvelteFormApi< + TFormData, + TFormValidator extends Validator | undefined = undefined, +> { + Field: Field + createField: CreateField +} + +export function createForm< + TParentData, + TFormValidator extends + | Validator + | undefined = undefined, +>(opts?: () => FormOptions) { + const options = opts?.() + const api = new FormApi(options) + const extendedApi: typeof api & SvelteFormApi = + api as never + + // TODO (43081j): somehow this needs to actually be + // ``. + // No clue right now how we do that + extendedApi.Field = Field + extendedApi.createField = (props) => + // TODO (43081j): type is excessively deep.. no clue why yet + createField(() => { + return { ...props(), form: api } + }) + + onMount(api.mount) + + // TODO (43081j): does this actually work? we don't use any observed + // data, so maybe svelte won't re-run this effect? + $effect(() => api.update(opts?.())) + + return extendedApi +} diff --git a/packages/svelte-form/src/index.ts b/packages/svelte-form/src/index.ts new file mode 100644 index 000000000..db0fbed4b --- /dev/null +++ b/packages/svelte-form/src/index.ts @@ -0,0 +1,6 @@ +export * from '@tanstack/form-core' + +export { createForm, type SvelteFormApi } from './createForm.svelte.js' + +export type { Field } from './Field.svelte' +export { createField } from './createField.svelte.js' diff --git a/packages/svelte-form/tests/simple.svelte b/packages/svelte-form/tests/simple.svelte new file mode 100644 index 000000000..29ba29405 --- /dev/null +++ b/packages/svelte-form/tests/simple.svelte @@ -0,0 +1,179 @@ + +
+

TanStack Form - Svelte Demo

+ + + value.length < 3 ? 'Not long enough' : undefined, + }} + > + {#snippet children(field)} +
+ + field.handleBlur()} + on:input={(e: Event) => { + const target = e.target as HTMLInputElement + field.handleChange(target.value) + }} + /> +
+ {/snippet} +
+ + value.length < 3 ? 'Not long enough' : undefined, + }} + > + {#snippet children(field)} +
+ + field.handleBlur()} + on:input={(e: Event) => { + const target = e.target as HTMLInputElement + field.handleChange(target.value) + }} + /> +
+ {/snippet} +
+ + {#snippet children(field)} +
+ + +
+ {/snippet} +
+ + {#snippet children(field)} +
+ + field.handleChange(!field.state.value)} + checked={field.state.value} + on:blur={() => field.handleBlur()} + id="employed" + type="checkbox" + /> +
+ {#if field.state.value} + + value.length === 0 + ? 'Needs to have a job here' + : null, + }} + > + {#snippet children(field)} +
+ + subField.handleBlur()} + on:input={(e: Event) => { + const target = e.target as HTMLInputElement + subField.handleChange(target.value) + }} + /> +
+ {/snippet} +
+ {/if} + {/snippet} +
+
+ + +
+
+
{JSON.stringify(form.state, null, 2)}
diff --git a/packages/svelte-form/tests/simple.test.ts b/packages/svelte-form/tests/simple.test.ts new file mode 100644 index 000000000..586643e51 --- /dev/null +++ b/packages/svelte-form/tests/simple.test.ts @@ -0,0 +1,76 @@ +/// +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import '@testing-library/jest-dom' +import { userEvent } from '@testing-library/user-event' +import { mount } from 'svelte' +import TestForm from './simple' + +describe('Svelte Tests', () => { + let element: TestForm + beforeEach(async () => { + element = document.createElement('div') + document.body.appendChild(element) + mount(TestForm, { + target: element, + props: {}, + }) + }) + + afterEach(() => { + element.remove() + }) + + it('should have initial values', async () => { + expect( + await element.shadowRoot!.querySelector('#firstName'), + ).toHaveValue(sampleData.firstName) + expect( + await element.shadowRoot!.querySelector('#lastName'), + ).toHaveValue('') + const form = element.form! + expect(form.api.getFieldValue('firstName')).toBe('Bob') + expect(form.api.getFieldMeta('firstName')?.isTouched).toBeFalsy() + expect(form.api.getFieldValue('lastName')).toBe('') + expect(form.api.getFieldMeta('lastName')?.isTouched).toBeFalsy() + }) + it('should mirror user input', async () => { + const lastName = + await element.shadowRoot!.querySelector('#lastName')! + const lastNameValue = 'Jobs' + await userEvent.type(lastName, lastNameValue) + + const form = element.form! + expect(form.api.getFieldValue('lastName')).toBe(lastNameValue) + expect(form.api.getFieldMeta('lastName')?.isTouched).toBeTruthy() + }) + it('Reset form to initial value', async () => { + const firstName = + await element.shadowRoot!.querySelector('#firstName')! + await userEvent.type(firstName, '-Joseph') + + expect(firstName).toHaveValue('Christian-Joseph') + + const form = element.form + await element + .shadowRoot!.querySelector('#reset') + ?.click() + expect(form.api.getFieldValue('firstName')).toBe('Bob') + }) + + it('should display validation', async () => { + const lastName = + await element.shadowRoot!.querySelector('#lastName')! + const lastNameValue = 'Jo' + await userEvent.type(lastName, lastNameValue) + expect(lastName).toHaveValue('Jo') + const form = element.form + expect(form.api.getFieldMeta('lastName')?.errors[0]).toBe('Not long enough') + + await userEvent.type(lastName, lastNameValue) + + expect(await lastName.getAttribute('error-text')).toBeFalsy() + expect(form.api.getFieldValue('lastName')).toBe('JoJo') + expect(form.api.getFieldMeta('lastName')?.isTouched).toBeTruthy() + expect(form.api.getFieldMeta('lastName')?.errors.length).toBeFalsy() + }) +}) diff --git a/packages/svelte-form/tsconfig.build.json b/packages/svelte-form/tsconfig.build.json new file mode 100644 index 000000000..3832dfb1a --- /dev/null +++ b/packages/svelte-form/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "moduleResolution": "bundler", + "rootDir": "./src", + "outDir": "./dist", + "noEmit": false, + "declaration": true, + "sourceMap": true + }, + "include": ["src"] +} diff --git a/packages/svelte-form/tsconfig.docs.json b/packages/svelte-form/tsconfig.docs.json new file mode 100644 index 000000000..2c9444e16 --- /dev/null +++ b/packages/svelte-form/tsconfig.docs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "paths": { + "@tanstack/form-core": ["../form-core/src"] + } + }, + "exclude": ["tests", "eslint.config.js", "vite.config.ts"] +} diff --git a/packages/svelte-form/tsconfig.json b/packages/svelte-form/tsconfig.json new file mode 100644 index 000000000..c7651b3dc --- /dev/null +++ b/packages/svelte-form/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "moduleResolution": "node16" + }, + "include": ["src", "tests", "eslint.config.js", "vite.config.ts"] +} diff --git a/packages/svelte-form/vite.config.ts b/packages/svelte-form/vite.config.ts new file mode 100644 index 000000000..59194a81b --- /dev/null +++ b/packages/svelte-form/vite.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'vitest/config' +import { svelte } from '@sveltejs/vite-plugin-svelte' +import packageJson from './package.json' + +export default defineConfig({ + test: { + name: packageJson.name, + dir: './tests', + watch: false, + environment: 'jsdom', + globals: true, + coverage: { enabled: true, provider: 'istanbul', include: ['src/**/*'] }, + typecheck: { enabled: true }, + }, + plugins: [svelte({})], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b5b642c9..f34655404 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1229,6 +1229,25 @@ importers: specifier: ^2.11.0 version: 2.11.0(@testing-library/jest-dom@6.6.3)(solid-js@1.9.3)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)) + packages/svelte-form: + dependencies: + '@tanstack/form-core': + specifier: workspace:* + version: link:../form-core + devDependencies: + '@sveltejs/package': + specifier: ^2.3.7 + version: 2.3.7(svelte@5.16.1)(typescript@5.7.2) + '@sveltejs/vite-plugin-svelte': + specifier: ^4.0.4 + version: 4.0.4(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)) + premove: + specifier: ^4.0.0 + version: 4.0.0 + svelte: + specifier: ^5.16.1 + version: 5.16.1 + packages/valibot-form-adapter: dependencies: '@tanstack/form-core': @@ -4258,6 +4277,28 @@ packages: peerDependencies: eslint: '>=8.40.0' + '@sveltejs/package@2.3.7': + resolution: {integrity: sha512-LYgUkde5GUYqOpXbcoCGUpEH4Ctl3Wj4u4CVZBl56dEeLW5fGHE037ZL1qlK0Ky+QD5uUfwONSeGwIOIighFMQ==} + engines: {node: ^16.14 || >=18} + hasBin: true + peerDependencies: + svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1 + + '@sveltejs/vite-plugin-svelte-inspector@3.0.1': + resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^4.0.0-next.0||^4.0.0 + svelte: ^5.0.0-next.96 || ^5.0.0 + vite: ^5.0.0 + + '@sveltejs/vite-plugin-svelte@4.0.4': + resolution: {integrity: sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + svelte: ^5.0.0-next.96 || ^5.0.0 + vite: ^5.0.0 + '@swc/core-darwin-arm64@1.7.42': resolution: {integrity: sha512-fWhaCs2+8GDRIcjExVDEIfbptVrxDqG8oHkESnXgymmvqTWzWei5SOnPNMS8Q+MYsn/b++Y2bDxkcwmq35Bvxg==} engines: {node: '>=10'} @@ -5204,6 +5245,10 @@ packages: axios@1.7.7: resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -5793,6 +5838,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -5802,6 +5856,9 @@ packages: decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dedent-js@1.0.1: + resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: @@ -6249,6 +6306,9 @@ packages: jiti: optional: true + esm-env@1.2.1: + resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -6262,6 +6322,9 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} + esrap@1.3.2: + resolution: {integrity: sha512-C4PXusxYhFT98GjLSmb20k9PREuUdporer50dhzGuJu9IJXktbMddVCMLAERl5dAHyAi73GWWCE4FVHGP1794g==} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -7467,6 +7530,9 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -7515,6 +7581,9 @@ packages: loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -7546,6 +7615,9 @@ packages: magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magicast@0.2.11: resolution: {integrity: sha512-6saXbRDA1HMkqbsvHOU6HBjCVgZT460qheRkLhJQHWAbhXoWESI3Kn/dGGXyKs15FFKR85jsUqFx2sMK0wy/5g==} @@ -8008,6 +8080,9 @@ packages: xml2js: optional: true + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -8368,6 +8443,9 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -8597,6 +8675,11 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + premove@4.0.0: + resolution: {integrity: sha512-zim/Hr4+FVdCIM7zL9b9Z0Wfd5Ya3mnKtiuDv7L5lzYzanSq6cOcVJ7EFcgK4I0pt28l8H0jX/x3nyog380XgQ==} + engines: {node: '>=6'} + hasBin: true + prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -9510,6 +9593,16 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte2tsx@0.7.34: + resolution: {integrity: sha512-WTMhpNhFf8/h3SMtR5dkdSy2qfveomkhYei/QW9gSPccb0/b82tjHvLop6vT303ZkGswU/da1s6XvrLgthQPCw==} + peerDependencies: + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 + typescript: ^4.9.4 || ^5.0.0 + + svelte@5.16.1: + resolution: {integrity: sha512-FsA1OjAKMAFSDob6j/Tv2ZV9rY4SeqPd1WXQlQkFkePAozSHLp6tbkU9qa1xJ+uTRzMSM2Vx3USdsYZBXd3H3g==} + engines: {node: '>=18'} + symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} @@ -10546,6 +10639,9 @@ packages: yup@1.5.0: resolution: {integrity: sha512-NJfBIHnp1QbqZwxcgl6irnDMIsb/7d1prNhFx02f1kp8h+orpi4xs3w90szNpOh68a/iHPdMsYvhZWoDmUvXBQ==} + zimmerframe@1.1.2: + resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} + zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} @@ -10926,7 +11022,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - debug: 4.3.7 + debug: 4.4.0 lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -12552,7 +12648,7 @@ snapshots: '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -13317,7 +13413,7 @@ snapshots: estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 - magic-string: 0.30.12 + magic-string: 0.30.17 optionalDependencies: rollup: 4.26.0 @@ -13325,7 +13421,7 @@ snapshots: dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.26.0) estree-walker: 2.0.2 - magic-string: 0.30.12 + magic-string: 0.30.17 optionalDependencies: rollup: 4.26.0 @@ -13348,7 +13444,7 @@ snapshots: '@rollup/plugin-replace@5.0.7(rollup@4.26.0)': dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.26.0) - magic-string: 0.30.12 + magic-string: 0.30.17 optionalDependencies: rollup: 4.26.0 @@ -13540,6 +13636,39 @@ snapshots: eslint-visitor-keys: 4.2.0 espree: 10.3.0 + '@sveltejs/package@2.3.7(svelte@5.16.1)(typescript@5.7.2)': + dependencies: + chokidar: 4.0.1 + kleur: 4.1.5 + sade: 1.8.1 + semver: 7.6.3 + svelte: 5.16.1 + svelte2tsx: 0.7.34(svelte@5.16.1)(typescript@5.7.2) + transitivePeerDependencies: + - typescript + + '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)))(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0))': + dependencies: + '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)) + debug: 4.4.0 + svelte: 5.16.1 + vite: 5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)))(svelte@5.16.1)(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)) + debug: 4.4.0 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.17 + svelte: 5.16.1 + vite: 5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0) + vitefu: 1.0.4(vite@5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0)) + transitivePeerDependencies: + - supports-color + '@swc/core-darwin-arm64@1.7.42': optional: true @@ -14103,7 +14232,7 @@ snapshots: '@typescript-eslint/types': 8.17.0 '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.17.0 - debug: 4.3.7 + debug: 4.4.0 eslint: 9.16.0(jiti@2.4.0) optionalDependencies: typescript: 5.6.3 @@ -14133,7 +14262,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.17.0 '@typescript-eslint/visitor-keys': 8.17.0 - debug: 4.3.7 + debug: 4.4.0 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 @@ -14367,7 +14496,7 @@ snapshots: dependencies: '@vitest/spy': 2.1.4 estree-walker: 3.0.3 - magic-string: 0.30.12 + magic-string: 0.30.17 optionalDependencies: vite: 5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0) @@ -14383,7 +14512,7 @@ snapshots: '@vitest/snapshot@2.1.4': dependencies: '@vitest/pretty-format': 2.1.4 - magic-string: 0.30.12 + magic-string: 0.30.17 pathe: 1.1.2 '@vitest/spy@2.1.4': @@ -14648,13 +14777,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color agent-base@7.1.1: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -14850,6 +14979,8 @@ snapshots: transitivePeerDependencies: - debug + axobject-query@4.1.0: {} + b4a@1.6.7: {} babel-dead-code-elimination@1.0.6: @@ -15483,6 +15614,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.0: + dependencies: + ms: 2.1.3 + decimal.js@10.4.3: {} decode-formdata@0.8.0: {} @@ -15491,6 +15626,8 @@ snapshots: dependencies: character-entities: 2.0.2 + dedent-js@1.0.1: {} + dedent@1.5.3(babel-plugin-macros@3.1.0): optionalDependencies: babel-plugin-macros: 3.1.0 @@ -16155,6 +16292,8 @@ snapshots: transitivePeerDependencies: - supports-color + esm-env@1.2.1: {} + espree@10.3.0: dependencies: acorn: 8.14.0 @@ -16167,6 +16306,10 @@ snapshots: dependencies: estraverse: 5.3.0 + esrap@1.3.2: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -16803,7 +16946,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -16843,14 +16986,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -16939,7 +17082,7 @@ snapshots: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.3.7 + debug: 4.4.0 denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -17508,6 +17651,8 @@ snapshots: mlly: 1.7.3 pkg-types: 1.2.1 + locate-character@3.0.0: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -17553,6 +17698,10 @@ snapshots: loupe@3.1.2: {} + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + lru-cache@10.4.3: {} lru-cache@11.0.2: {} @@ -17580,6 +17729,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.2.11: dependencies: '@babel/parser': 7.26.2 @@ -17982,7 +18135,7 @@ snapshots: micromark@3.2.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.7 + debug: 4.4.0 decode-named-character-reference: 1.0.2 micromark-core-commonmark: 1.1.0 micromark-factory-space: 1.1.0 @@ -18345,6 +18498,11 @@ snapshots: - uWebSockets.js - webpack-sources + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + node-addon-api@6.1.0: optional: true @@ -18813,6 +18971,11 @@ snapshots: parseurl@1.3.3: {} + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + path-browserify@1.0.1: {} path-exists@4.0.0: {} @@ -19014,6 +19177,8 @@ snapshots: prelude-ls@1.2.1: {} + premove@4.0.0: {} + prettier@2.8.8: {} prettier@3.4.2: {} @@ -19757,7 +19922,7 @@ snapshots: socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -19819,7 +19984,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.3.7 + debug: 4.4.0 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -19830,7 +19995,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.3.7 + debug: 4.4.0 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -19981,6 +20146,30 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svelte2tsx@0.7.34(svelte@5.16.1)(typescript@5.7.2): + dependencies: + dedent-js: 1.0.1 + pascal-case: 3.1.2 + svelte: 5.16.1 + typescript: 5.7.2 + + svelte@5.16.1: + dependencies: + '@ampproject/remapping': 2.3.0 + '@jridgewell/sourcemap-codec': 1.5.0 + '@types/estree': 1.0.6 + acorn: 8.14.0 + acorn-typescript: 1.4.13(acorn@8.14.0) + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + esm-env: 1.2.1 + esrap: 1.3.2 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.12 + zimmerframe: 1.1.2 + symbol-observable@4.0.0: {} symbol-tree@3.2.4: {} @@ -20168,7 +20357,7 @@ snapshots: tuf-js@3.0.1: dependencies: '@tufjs/models': 3.0.1 - debug: 4.3.7 + debug: 4.4.0 make-fetch-happen: 14.0.3 transitivePeerDependencies: - supports-color @@ -20245,8 +20434,7 @@ snapshots: typescript@5.6.3: {} - typescript@5.7.2: - optional: true + typescript@5.7.2: {} uc.micro@2.1.0: {} @@ -20314,7 +20502,7 @@ snapshots: estree-walker: 3.0.3 fast-glob: 3.3.2 local-pkg: 0.5.1 - magic-string: 0.30.12 + magic-string: 0.30.17 mlly: 1.7.3 pathe: 1.1.2 pkg-types: 1.2.1 @@ -20418,7 +20606,7 @@ snapshots: unwasm@0.3.9(webpack-sources@3.2.3): dependencies: knitwork: 1.1.0 - magic-string: 0.30.12 + magic-string: 0.30.17 mlly: 1.7.3 pathe: 1.1.2 pkg-types: 1.2.1 @@ -20644,7 +20832,7 @@ snapshots: vite-node@2.1.4(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0): dependencies: cac: 6.7.14 - debug: 4.3.7 + debug: 4.4.0 pathe: 1.1.2 vite: 5.4.11(@types/node@22.10.1)(less@4.2.0)(sass@1.80.7)(sugarss@4.0.1(postcss@8.4.49))(terser@5.36.0) transitivePeerDependencies: @@ -21112,6 +21300,8 @@ snapshots: toposort: 2.0.2 type-fest: 2.19.0 + zimmerframe@1.1.2: {} + zip-stream@6.0.1: dependencies: archiver-utils: 5.0.2