Skip to content

Commit 4dc6aec

Browse files
authored
breaking: remove deprecated use:enhance callback values (#11282)
1 parent 76006b6 commit 4dc6aec

File tree

9 files changed

+27
-214
lines changed

9 files changed

+27
-214
lines changed

.changeset/chilled-fireants-learn.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': major
3+
---
4+
5+
breaking: remove deprecated `use:enhance` callback values

.changeset/mean-moose-smell.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': major
3+
---
4+
5+
breaking: error if form without multipart/form-data enctype contains a file input

documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md

+10
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ As such, SvelteKit 2 replaces `resolvePath` with a (slightly better named) funct
105105

106106
`svelte-migrate` will do the method replacement for you, though if you later prepend the result with `base`, you need to remove that yourself.
107107

108+
## `form` and `data` have been removed from `use:enhance` callbacks
109+
110+
If you provide a callback to [`use:enhance`](/docs/form-actions#progressive-enhancement-use-enhance), it will be called with an object containing various useful properties.
111+
112+
In SvelteKit 1, those properties included `form` and `data`. These were deprecated some time ago in favour of `formElement` and `formData`, and have been removed altogether in SvelteKit 2.
113+
114+
## Forms containing file inputs must use `multipart/form-data`
115+
116+
If a form contains an `<input type="file">` but does not have an `enctype="multipart/form-data"` attribute, non-JS submissions will omit the file. SvelteKit 2 will throw an error if it encounters a form like this during a `use:enhance` submission to ensure that your forms work correctly when JavaScript is not present.
117+
108118
## Updated dependency requirements
109119

110120
SvelteKit requires Node `18.13` or higher, Vite `^5.0`, vite-plugin-svelte `^3.0`, TypeScript `^5.0` and Svelte version 4 or higher. `svelte-migrate` will do the `package.json` bumps for you.

packages/kit/src/exports/public.d.ts

-20
Original file line numberDiff line numberDiff line change
@@ -1247,35 +1247,15 @@ export type SubmitFunction<
12471247
Failure extends Record<string, unknown> | undefined = Record<string, any>
12481248
> = (input: {
12491249
action: URL;
1250-
/**
1251-
* use `formData` instead of `data`
1252-
* @deprecated
1253-
*/
1254-
data: FormData;
12551250
formData: FormData;
1256-
/**
1257-
* use `formElement` instead of `form`
1258-
* @deprecated
1259-
*/
1260-
form: HTMLFormElement;
12611251
formElement: HTMLFormElement;
12621252
controller: AbortController;
12631253
submitter: HTMLElement | null;
12641254
cancel(): void;
12651255
}) => MaybePromise<
12661256
| void
12671257
| ((opts: {
1268-
/**
1269-
* use `formData` instead of `data`
1270-
* @deprecated
1271-
*/
1272-
data: FormData;
12731258
formData: FormData;
1274-
/**
1275-
* use `formElement` instead of `form`
1276-
* @deprecated
1277-
*/
1278-
form: HTMLFormElement;
12791259
formElement: HTMLFormElement;
12801260
action: URL;
12811261
result: ActionResult<Success, Failure>;

packages/kit/src/runtime/app/forms.js

+2-35
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,6 @@ export function deserialize(result) {
4949
return parsed;
5050
}
5151

52-
/**
53-
* @param {string} old_name
54-
* @param {string} new_name
55-
* @param {string} call_location
56-
* @returns void
57-
*/
58-
function warn_on_access(old_name, new_name, call_location) {
59-
if (!DEV) return;
60-
// TODO 2.0: Remove this code
61-
console.warn(
62-
`\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
63-
);
64-
}
65-
6652
/**
6753
* Shallow clone an element, so that we can access e.g. `form.action` without worrying
6854
* that someone has added an `<input name="action">` (https://github.com/sveltejs/kit/issues/7593)
@@ -157,11 +143,9 @@ export function enhance(form_element, submit = () => {}) {
157143
if (DEV && clone(form_element).enctype !== 'multipart/form-data') {
158144
for (const value of form_data.values()) {
159145
if (value instanceof File) {
160-
// TODO 2.0: Upgrade to `throw Error`
161-
console.warn(
162-
'Your form contains <input type="file"> fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.'
146+
throw new Error(
147+
'Your form contains <input type="file"> fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.'
163148
);
164-
break;
165149
}
166150
}
167151
}
@@ -176,21 +160,12 @@ export function enhance(form_element, submit = () => {}) {
176160
let cancelled = false;
177161
const cancel = () => (cancelled = true);
178162

179-
// TODO 2.0: Remove `data` and `form`
180163
const callback =
181164
(await submit({
182165
action,
183166
cancel,
184167
controller,
185-
get data() {
186-
warn_on_access('data', 'formData', 'use:enhance submit function');
187-
return form_data;
188-
},
189168
formData: form_data,
190-
get form() {
191-
warn_on_access('form', 'formElement', 'use:enhance submit function');
192-
return form_element;
193-
},
194169
formElement: form_element,
195170
submitter: event.submitter
196171
})) ?? fallback_callback;
@@ -220,15 +195,7 @@ export function enhance(form_element, submit = () => {}) {
220195

221196
callback({
222197
action,
223-
get data() {
224-
warn_on_access('data', 'formData', 'callback returned from use:enhance submit function');
225-
return form_data;
226-
},
227198
formData: form_data,
228-
get form() {
229-
warn_on_access('form', 'formElement', 'callback returned from use:enhance submit function');
230-
return form_element;
231-
},
232199
formElement: form_element,
233200
update: (opts) =>
234201
fallback_callback({

packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js

-26
This file was deleted.

packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte

-60
This file was deleted.

packages/kit/test/apps/basics/test/test.js

+5-53
Original file line numberDiff line numberDiff line change
@@ -918,69 +918,21 @@ test.describe('Actions', () => {
918918
expect(preSubmitContent).not.toBe(postSubmitContent);
919919
});
920920

921-
test('Submitting a form with a file input but no enctype="multipart/form-data" logs a warning', async ({
921+
test('Submitting a form with a file input but no enctype="multipart/form-data" throws an error', async ({
922922
page,
923923
javaScriptEnabled
924924
}) => {
925925
test.skip(!javaScriptEnabled, 'Skip when JavaScript is disabled');
926926
test.skip(!process.env.DEV, 'Skip when not in dev mode');
927927
await page.goto('/actions/file-without-enctype');
928-
const log_promise = page.waitForEvent('console');
928+
const error_promise = page.waitForEvent('pageerror');
929929
await page.click('button');
930-
const log = await log_promise;
931-
expect(log.text()).toBe(
932-
'Your form contains <input type="file"> fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.'
930+
const error = await error_promise;
931+
expect(error.message).toBe(
932+
'Your form contains <input type="file"> fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.'
933933
);
934934
});
935935

936-
test('Accessing v2 deprecated properties results in a warning log', async ({
937-
page,
938-
javaScriptEnabled
939-
}) => {
940-
test.skip(!javaScriptEnabled, 'skip when js is disabled');
941-
test.skip(!process.env.DEV, 'skip when not in dev mode');
942-
await page.goto('/actions/enhance/old-property-access');
943-
944-
for (const { id, old_name, new_name, call_location } of [
945-
{
946-
id: 'access-form-in-submit',
947-
old_name: 'form',
948-
new_name: 'formElement',
949-
call_location: 'use:enhance submit function'
950-
},
951-
{
952-
id: 'access-form-in-callback',
953-
old_name: 'form',
954-
new_name: 'formElement',
955-
call_location: 'callback returned from use:enhance submit function'
956-
},
957-
{
958-
id: 'access-data-in-submit',
959-
old_name: 'data',
960-
new_name: 'formData',
961-
call_location: 'use:enhance submit function'
962-
},
963-
{
964-
id: 'access-data-in-callback',
965-
old_name: 'data',
966-
new_name: 'formData',
967-
call_location: 'callback returned from use:enhance submit function'
968-
}
969-
]) {
970-
await test.step(id, async () => {
971-
const log_promise = page.waitForEvent('console');
972-
const button = page.locator(`#${id}`);
973-
await button.click();
974-
await expect(button).toHaveAttribute('data-processed', 'true');
975-
const log = await log_promise;
976-
expect(log.text()).toBe(
977-
`\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
978-
);
979-
expect(log.type()).toBe('warning');
980-
});
981-
}
982-
});
983-
984936
test('Error props are returned', async ({ page, javaScriptEnabled }) => {
985937
await page.goto('/actions/form-errors');
986938
await page.click('button');

packages/kit/types/index.d.ts

-20
Original file line numberDiff line numberDiff line change
@@ -1229,35 +1229,15 @@ declare module '@sveltejs/kit' {
12291229
Failure extends Record<string, unknown> | undefined = Record<string, any>
12301230
> = (input: {
12311231
action: URL;
1232-
/**
1233-
* use `formData` instead of `data`
1234-
* @deprecated
1235-
*/
1236-
data: FormData;
12371232
formData: FormData;
1238-
/**
1239-
* use `formElement` instead of `form`
1240-
* @deprecated
1241-
*/
1242-
form: HTMLFormElement;
12431233
formElement: HTMLFormElement;
12441234
controller: AbortController;
12451235
submitter: HTMLElement | null;
12461236
cancel(): void;
12471237
}) => MaybePromise<
12481238
| void
12491239
| ((opts: {
1250-
/**
1251-
* use `formData` instead of `data`
1252-
* @deprecated
1253-
*/
1254-
data: FormData;
12551240
formData: FormData;
1256-
/**
1257-
* use `formElement` instead of `form`
1258-
* @deprecated
1259-
*/
1260-
form: HTMLFormElement;
12611241
formElement: HTMLFormElement;
12621242
action: URL;
12631243
result: ActionResult<Success, Failure>;

0 commit comments

Comments
 (0)