{"version":3,"file":"forms.ugBvSalc.mjs","sources":["../../../../../../node_modules/@sveltejs/kit/src/runtime/app/forms.js"],"sourcesContent":["import * as devalue from 'devalue';\nimport { DEV } from 'esm-env';\nimport { invalidateAll } from './navigation.js';\nimport { applyAction } from '../client/client.js';\n\nexport { applyAction };\n\n/**\n * Use this function to deserialize the response from a form submission.\n * Usage:\n *\n * ```js\n * import { deserialize } from '$app/forms';\n *\n * async function handleSubmit(event) {\n *   const response = await fetch('/form?/action', {\n *     method: 'POST',\n *     body: new FormData(event.target)\n *   });\n *\n *   const result = deserialize(await response.text());\n *   // ...\n * }\n * ```\n * @template {Record<string, unknown> | undefined} Success\n * @template {Record<string, unknown> | undefined} Failure\n * @param {string} result\n * @returns {import('@sveltejs/kit').ActionResult<Success, Failure>}\n */\nexport function deserialize(result) {\n\tconst parsed = JSON.parse(result);\n\tif (parsed.data) {\n\t\tparsed.data = devalue.parse(parsed.data);\n\t}\n\treturn parsed;\n}\n\n/**\n * Shallow clone an element, so that we can access e.g. `form.action` without worrying\n * that someone has added an `<input name=\"action\">` (https://github.com/sveltejs/kit/issues/7593)\n * @template {HTMLElement} T\n * @param {T} element\n * @returns {T}\n */\nfunction clone(element) {\n\treturn /** @type {T} */ (HTMLElement.prototype.cloneNode.call(element));\n}\n\n/**\n * This action enhances a `<form>` element that otherwise would work without JavaScript.\n *\n * The `submit` function is called upon submission with the given FormData and the `action` that should be triggered.\n * If `cancel` is called, the form will not be submitted.\n * You can use the abort `controller` to cancel the submission in case another one starts.\n * If a function is returned, that function is called with the response from the server.\n * If nothing is returned, the fallback will be used.\n *\n * If this function or its return value isn't set, it\n * - falls back to updating the `form` prop with the returned data if the action is on the same page as the form\n * - updates `$page.status`\n * - resets the `<form>` element and invalidates all data in case of successful submission with no redirect response\n * - redirects in case of a redirect response\n * - redirects to the nearest error page in case of an unexpected error\n *\n * If you provide a custom function with a callback and want to use the default behavior, invoke `update` in your callback.\n * @template {Record<string, unknown> | undefined} Success\n * @template {Record<string, unknown> | undefined} Failure\n * @param {HTMLFormElement} form_element The form element\n * @param {import('@sveltejs/kit').SubmitFunction<Success, Failure>} submit Submit callback\n */\nexport function enhance(form_element, submit = () => {}) {\n\tif (DEV && clone(form_element).method !== 'post') {\n\t\tthrow new Error('use:enhance can only be used on <form> fields with method=\"POST\"');\n\t}\n\n\t/**\n\t * @param {{\n\t *   action: URL;\n\t *   invalidateAll?: boolean;\n\t *   result: import('@sveltejs/kit').ActionResult;\n\t *   reset?: boolean\n\t * }} opts\n\t */\n\tconst fallback_callback = async ({\n\t\taction,\n\t\tresult,\n\t\treset = true,\n\t\tinvalidateAll: shouldInvalidateAll = true\n\t}) => {\n\t\tif (result.type === 'success') {\n\t\t\tif (reset) {\n\t\t\t\t// We call reset from the prototype to avoid DOM clobbering\n\t\t\t\tHTMLFormElement.prototype.reset.call(form_element);\n\t\t\t}\n\t\t\tif (shouldInvalidateAll) {\n\t\t\t\tawait invalidateAll();\n\t\t\t}\n\t\t}\n\n\t\t// For success/failure results, only apply action if it belongs to the\n\t\t// current page, otherwise `form` will be updated erroneously\n\t\tif (\n\t\t\tlocation.origin + location.pathname === action.origin + action.pathname ||\n\t\t\tresult.type === 'redirect' ||\n\t\t\tresult.type === 'error'\n\t\t) {\n\t\t\tapplyAction(result);\n\t\t}\n\t};\n\n\t/** @param {SubmitEvent} event */\n\tasync function handle_submit(event) {\n\t\tconst method = event.submitter?.hasAttribute('formmethod')\n\t\t\t? /** @type {HTMLButtonElement | HTMLInputElement} */ (event.submitter).formMethod\n\t\t\t: clone(form_element).method;\n\t\tif (method !== 'post') return;\n\n\t\tevent.preventDefault();\n\n\t\tconst action = new URL(\n\t\t\t// We can't do submitter.formAction directly because that property is always set\n\t\t\tevent.submitter?.hasAttribute('formaction')\n\t\t\t\t? /** @type {HTMLButtonElement | HTMLInputElement} */ (event.submitter).formAction\n\t\t\t\t: clone(form_element).action\n\t\t);\n\n\t\tconst enctype = event.submitter?.hasAttribute('formenctype')\n\t\t\t? /** @type {HTMLButtonElement | HTMLInputElement} */ (event.submitter).formEnctype\n\t\t\t: clone(form_element).enctype;\n\n\t\tconst form_data = new FormData(form_element);\n\n\t\tif (DEV && enctype !== 'multipart/form-data') {\n\t\t\tfor (const value of form_data.values()) {\n\t\t\t\tif (value instanceof File) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'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.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst submitter_name = event.submitter?.getAttribute('name');\n\t\tif (submitter_name) {\n\t\t\tform_data.append(submitter_name, event.submitter?.getAttribute('value') ?? '');\n\t\t}\n\n\t\tconst controller = new AbortController();\n\n\t\tlet cancelled = false;\n\t\tconst cancel = () => (cancelled = true);\n\n\t\tconst callback =\n\t\t\t(await submit({\n\t\t\t\taction,\n\t\t\t\tcancel,\n\t\t\t\tcontroller,\n\t\t\t\tformData: form_data,\n\t\t\t\tformElement: form_element,\n\t\t\t\tsubmitter: event.submitter\n\t\t\t})) ?? fallback_callback;\n\t\tif (cancelled) return;\n\n\t\t/** @type {import('@sveltejs/kit').ActionResult} */\n\t\tlet result;\n\n\t\ttry {\n\t\t\tconst headers = new Headers({\n\t\t\t\taccept: 'application/json',\n\t\t\t\t'x-sveltekit-action': 'true'\n\t\t\t});\n\n\t\t\t// do not explicitly set the `Content-Type` header when sending `FormData`\n\t\t\t// or else it will interfere with the browser's header setting\n\t\t\t// see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects#sect4\n\t\t\tif (enctype !== 'multipart/form-data') {\n\t\t\t\theaders.set(\n\t\t\t\t\t'Content-Type',\n\t\t\t\t\t/^(:?application\\/x-www-form-urlencoded|text\\/plain)$/.test(enctype)\n\t\t\t\t\t\t? enctype\n\t\t\t\t\t\t: 'application/x-www-form-urlencoded'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// @ts-expect-error `URLSearchParams(form_data)` is kosher, but typescript doesn't know that\n\t\t\tconst body = enctype === 'multipart/form-data' ? form_data : new URLSearchParams(form_data);\n\n\t\t\tconst response = await fetch(action, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders,\n\t\t\t\tcache: 'no-store',\n\t\t\t\tbody,\n\t\t\t\tsignal: controller.signal\n\t\t\t});\n\n\t\t\tresult = deserialize(await response.text());\n\t\t\tif (result.type === 'error') result.status = response.status;\n\t\t} catch (error) {\n\t\t\tif (/** @type {any} */ (error)?.name === 'AbortError') return;\n\t\t\tresult = { type: 'error', error };\n\t\t}\n\n\t\tcallback({\n\t\t\taction,\n\t\t\tformData: form_data,\n\t\t\tformElement: form_element,\n\t\t\tupdate: (opts) =>\n\t\t\t\tfallback_callback({\n\t\t\t\t\taction,\n\t\t\t\t\tresult,\n\t\t\t\t\treset: opts?.reset,\n\t\t\t\t\tinvalidateAll: opts?.invalidateAll\n\t\t\t\t}),\n\t\t\t// @ts-expect-error generic constraints stuff we don't care about\n\t\t\tresult\n\t\t});\n\t}\n\n\t// @ts-expect-error\n\tHTMLFormElement.prototype.addEventListener.call(form_element, 'submit', handle_submit);\n\n\treturn {\n\t\tdestroy() {\n\t\t\t// @ts-expect-error\n\t\t\tHTMLFormElement.prototype.removeEventListener.call(form_element, 'submit', handle_submit);\n\t\t}\n\t};\n}\n"],"names":["deserialize","result","parsed","devalue.parse","clone","element","enhance","form_element","submit","fallback_callback","action","reset","shouldInvalidateAll","invalidateAll","applyAction","handle_submit","event","_a","_b","enctype","_c","form_data","submitter_name","_d","_e","controller","cancelled","callback","headers","body","response","error","opts"],"mappings":"8WA6BO,SAASA,EAAYC,EAAQ,CACnC,MAAMC,EAAS,KAAK,MAAMD,CAAM,EAChC,OAAIC,EAAO,OACVA,EAAO,KAAOC,EAAcD,EAAO,IAAI,GAEjCA,CACR,CASA,SAASE,EAAMC,EAAS,CACvB,OAAyB,YAAY,UAAU,UAAU,KAAKA,CAAO,CACtE,CAwBO,SAASC,EAAQC,EAAcC,EAAS,IAAM,GAAI,CAaxD,MAAMC,EAAoB,MAAO,CAChC,OAAAC,EACA,OAAAT,EACA,MAAAU,EAAQ,GACR,cAAeC,EAAsB,EACvC,IAAO,CACDX,EAAO,OAAS,YACfU,GAEH,gBAAgB,UAAU,MAAM,KAAKJ,CAAY,EAE9CK,GACH,MAAMC,EAAa,IAOpB,SAAS,OAAS,SAAS,WAAaH,EAAO,OAASA,EAAO,UAC/DT,EAAO,OAAS,YAChBA,EAAO,OAAS,UAEhBa,EAAYb,CAAM,CAErB,EAGC,eAAec,EAAcC,EAAO,eAInC,KAHeC,EAAAD,EAAM,YAAN,MAAAC,EAAiB,aAAa,cACWD,EAAM,UAAW,WACtEZ,EAAMG,CAAY,EAAE,UACR,OAAQ,OAEvBS,EAAM,eAAc,EAEpB,MAAMN,EAAS,IAAI,KAElBQ,EAAAF,EAAM,YAAN,MAAAE,EAAiB,aAAa,cAC0BF,EAAM,UAAW,WACtEZ,EAAMG,CAAY,EAAE,MAC1B,EAEQY,GAAUC,EAAAJ,EAAM,YAAN,MAAAI,EAAiB,aAAa,eACUJ,EAAM,UAAW,YACtEZ,EAAMG,CAAY,EAAE,QAEjBc,EAAY,IAAI,SAASd,CAAY,EAYrCe,GAAiBC,EAAAP,EAAM,YAAN,YAAAO,EAAiB,aAAa,QACjDD,GACHD,EAAU,OAAOC,IAAgBE,EAAAR,EAAM,YAAN,YAAAQ,EAAiB,aAAa,WAAY,EAAE,EAG9E,MAAMC,EAAa,IAAI,gBAEvB,IAAIC,EAAY,GAGhB,MAAMC,EACJ,MAAMnB,EAAO,CACb,OAAAE,EACA,OALa,IAAOgB,EAAY,GAMhC,WAAAD,EACA,SAAUJ,EACV,YAAad,EACb,UAAWS,EAAM,SACjB,CAAA,GAAMP,EACR,GAAIiB,EAAW,OAGf,IAAIzB,EAEJ,GAAI,CACH,MAAM2B,EAAU,IAAI,QAAQ,CAC3B,OAAQ,mBACR,qBAAsB,MAC1B,CAAI,EAKGT,IAAY,uBACfS,EAAQ,IACP,eACA,uDAAuD,KAAKT,CAAO,EAChEA,EACA,mCACR,EAIG,MAAMU,EAAOV,IAAY,sBAAwBE,EAAY,IAAI,gBAAgBA,CAAS,EAEpFS,EAAW,MAAM,MAAMpB,EAAQ,CACpC,OAAQ,OACR,QAAAkB,EACA,MAAO,WACP,KAAAC,EACA,OAAQJ,EAAW,MACvB,CAAI,EAEDxB,EAASD,EAAY,MAAM8B,EAAS,KAAM,CAAA,EACtC7B,EAAO,OAAS,UAASA,EAAO,OAAS6B,EAAS,OACtD,OAAQC,EAAO,CACf,IAAwBA,GAAA,YAAAA,EAAQ,QAAS,aAAc,OACvD9B,EAAS,CAAE,KAAM,QAAS,MAAA8B,CAAK,CAC/B,CAEDJ,EAAS,CACR,OAAAjB,EACA,SAAUW,EACV,YAAad,EACb,OAASyB,GACRvB,EAAkB,CACjB,OAAAC,EACA,OAAAT,EACA,MAAO+B,GAAA,YAAAA,EAAM,MACb,cAAeA,GAAA,YAAAA,EAAM,aAC1B,CAAK,EAEF,OAAA/B,CACH,CAAG,CACD,CAGD,uBAAgB,UAAU,iBAAiB,KAAKM,EAAc,SAAUQ,CAAa,EAE9E,CACN,SAAU,CAET,gBAAgB,UAAU,oBAAoB,KAAKR,EAAc,SAAUQ,CAAa,CACxF,CACH,CACA","x_google_ignoreList":[0]}