diff --git a/.changeset/odd-crews-own.md b/.changeset/odd-crews-own.md new file mode 100644 index 000000000000..1f140b9b965b --- /dev/null +++ b/.changeset/odd-crews-own.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': minor +--- + +feat: unshadow `data` and `form` in `enhance` and warn about future deprecation when used in `dev` mode diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index 24ef54daf79d..4a5a9abfbe0a 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -14,12 +14,26 @@ export function deserialize(result) { return parsed; } +/** + * @param {string} old_name + * @param {string} new_name + * @param {string} call_location + * @returns void + */ +function warn_on_access(old_name, new_name, call_location) { + if (!DEV) return; + // TODO 2.0: Remove this code + console.warn( + `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})` + ); +} + /** @type {import('$app/forms').enhance} */ -export function enhance(form, submit = () => {}) { +export function enhance(form_element, submit = () => {}) { if ( DEV && - /** @type {HTMLFormElement} */ (HTMLFormElement.prototype.cloneNode.call(form)).method !== - 'post' + /** @type {HTMLFormElement} */ (HTMLFormElement.prototype.cloneNode.call(form_element)) + .method !== 'post' ) { throw new Error('use:enhance can only be used on
+ + + + + + diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 6b976d2eee5d..1571911d7e7b 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -828,6 +828,51 @@ test.describe('Matchers', () => { }); test.describe('Actions', () => { + for (const { id, old_name, new_name, call_location } of [ + { + id: 'access-form-in-submit', + old_name: 'form', + new_name: 'formElement', + call_location: 'use:enhance submit function' + }, + { + id: 'access-form-in-callback', + old_name: 'form', + new_name: 'formElement', + call_location: 'callback returned from use:enhance submit function' + }, + { + id: 'access-data-in-submit', + old_name: 'data', + new_name: 'formData', + call_location: 'use:enhance submit function' + }, + { + id: 'access-data-in-callback', + old_name: 'data', + new_name: 'formData', + call_location: 'callback returned from use:enhance submit function' + } + ]) { + test(`Accessing v2 deprecated properties results in a warning log, type: ${id}`, async ({ + page, + javaScriptEnabled + }) => { + test.skip(!javaScriptEnabled, 'skip when js is disabled'); + test.skip(!process.env.DEV, 'skip when not in dev mode'); + await page.goto('/actions/enhance/old-property-access'); + const log_promise = page.waitForEvent('console'); + const button = page.locator(`#${id}`); + await button.click(); + expect(await button.textContent()).toBe('processed'); // needed to make sure action completes + const log = await log_promise; + expect(log.text()).toBe( + `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})` + ); + expect(log.type()).toBe('warning'); + }); + } + test('Error props are returned', async ({ page, javaScriptEnabled }) => { await page.goto('/actions/form-errors'); await page.click('button'); diff --git a/packages/kit/test/apps/dev-only/package.json b/packages/kit/test/apps/dev-only/package.json index 37ee1ab3a73d..34c9b1b80012 100644 --- a/packages/kit/test/apps/dev-only/package.json +++ b/packages/kit/test/apps/dev-only/package.json @@ -1,5 +1,5 @@ { - "name": "test-basics", + "name": "test-dev-only", "private": true, "version": "0.0.2-next.0", "scripts": { diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts index 9e6b92fa27e0..10e3529d238b 100644 --- a/packages/kit/types/ambient.d.ts +++ b/packages/kit/types/ambient.d.ts @@ -80,15 +80,36 @@ declare module '$app/forms' { Invalid extends Record