You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Updated 2024 November 9 to include other proposals from below comments.
Describe the problem
My team is provided a set of internally-managed API client libraries. We use +page.server.js to make API requests within load and return data to the page.
It's easy to make the mistake of returning the full API response to the page without filtering out potentially sensitive fields.
Describe the proposed solution
1. Type overrides
Some way to override generated types through a global declarations file. I would imagine that would be a tough challenge since something like PageServerLoad is generated based on its inferred return type on a per-route basis; so I'm unsure of a conventional declarations file could work versus a JS function received by svelte.config.js.
Hypothetically, this override would allow me to centrally configure unacceptable return types such as the following:
importapifrom'@internal/api-profiles'/** @type {import('./$types').PageServerLoad} */exportasyncfunctionload(){// inferred type: `Promise<ClientAPIResponse>`constres=awaitapi.listProfiles({body: {page: 1,per_page: 10}})constdata=awaitres.json()// ❌ type error, cannot return `Promise<ClientAPIResponse> | ClientAPIResponse`return{ data }};
And that way, it would give pause to the developer to ensure they have sanitized their response:
In +page.server.js, allow developers to export a validate function that is called after load and before data gets server-rendered or returned to the client.
This would be a breaking change since it introduces a new reserved name as an export.
A developer can use this to apply any schema validation library they want
A new opt-in config will throw an error at build time in case any given route lacks a validate export. Such as [email protected]:true, which helps developers remember to add a validate export to any server file with a load or endpoint export
this could potentially have use with Form Actions
+page.server.js
import{z}from'zod'// param is type `RequestEvent & input`// Where `input` is the returned data from `load`exportfunctionvalidate({ input }){constschema=z.object({fruit: z.string(),age: z.number()})// strip unrecognized key `socialInsurance`constresult=schema.safeParse(input)// maybe a `handleValidation` hook can be used to make this less repetitiveif(!result.success){// log error}else{// client page's `data` prop should infer its type from this resultreturnresult}}exportasyncfunctionload(){constfetchedObject={fruit: 'apple',age: 2,socialInsurance: 'apple-54321'}returnfetchedObject}
+server.js
This example needs more thought.
Should users manipulate and return a new Response object?
There needs to be a way to validate potential 400/409/etc responses
// param is type `RequestEvent & Response`// Where `Response` is the returned data from a given endpointexportfunctionvalidate({ request, response }){switch(request.method){case'PUT':
constschema=z.object({fruit: z.string(),age: z.number()})// strip unrecognized key `socialInsurance`constresult=schema.safeParse(input)// maybe a `handleValidation` hook can be used to make this less repetitiveif(!result.success){// log error}else{// client page's `data` prop should infer its type from this resultreturnresult}break;}}exportasyncfunctionPOST(){constdata={fruit: 'apple',age: 20,socialInsurance: 'abc123'}returnnewResponse(JSON.stringify(data),{status: 201})}
And can potentially be its own ticket or enhancement.
Maybe developers could write a Vite plugin to parse their own schema methodology, such as OpenAPI Schema. The plugin needs a way to parse built SvelteKit routes in order to add custom middleware to them.
The schema update.yml contains data that maps to a path in the file-based router. In this case, update.yml has keys that point to a SvelteKit endpoint as well as JSON schemas for validation based on response:
Solve this myself with a wrapper function or by changing the behaviour of our own API client libraries to accept a required 'fields' param. Which will be my workaround
Wrap all load method data in a validator before calling return
Write a server hook that filters sensitive responses
Another idea is to adopt Open API Schema or something similar to what Hono does; allow the developer to define response schemas manually to parse out any unwanted data: https://hono.dev/examples/zod-openapi
Perhaps instead of solving this first-party, maybe SvelteKit can expose a way to allow third-party validators (Zod, AJV, Valibot, VineJS) to plug into SvelteKit types to achieve the following opt-in behaviours:
Throw a build error when any returned data from load, form actions, or endpoint responses are missing a schema.
Provide a new hook (or extend handle) to parse responses and impact generated types returned to the data and form props.
theetrain
changed the title
Ability to extend generated types for PageServerLoad and potentially others
Allow SvelteKit developers to provide schemas or contracts for returned data
Nov 9, 2024
Updated 2024 November 9 to include other proposals from below comments.
Describe the problem
My team is provided a set of internally-managed API client libraries. We use
+page.server.js
to make API requests withinload
and return data to the page.It's easy to make the mistake of returning the full API response to the page without filtering out potentially sensitive fields.
Describe the proposed solution
1. Type overrides
Some way to override generated types through a global declarations file. I would imagine that would be a tough challenge since something like
PageServerLoad
is generated based on its inferred return type on a per-route basis; so I'm unsure of a conventional declarations file could work versus a JS function received bysvelte.config.js
.Hypothetically, this override would allow me to centrally configure unacceptable return types such as the following:
And that way, it would give pause to the developer to ensure they have sanitized their response:
2. New
schema
reserved exportIn
+page.server.js
, allow developers to export avalidate
function that is called afterload
and before data gets server-rendered or returned to the client.validate
export. Such as[email protected]:true
, which helps developers remember to add avalidate
export to any server file with aload
or endpoint export+page.server.js
+server.js
This example needs more thought.
Response
object?400/409/etc
responses3. Schema hooks
Relates to: #12623
Inspired by: https://github.com/ahmadnassri/node-oas-fastify
And can potentially be its own ticket or enhancement.
Maybe developers could write a Vite plugin to parse their own schema methodology, such as OpenAPI Schema. The plugin needs a way to parse built SvelteKit routes in order to add custom middleware to them.
Given this file structure:
The schema
update.yml
contains data that maps to a path in the file-based router. In this case,update.yml
has keys that point to a SvelteKit endpoint as well as JSON schemas for validation based on response:Alternatives considered
load
method data in a validator before callingreturn
load
responses; similar to https://www.npmjs.com/package/oas-fastifyImportance
nice to have
Additional Information
The text was updated successfully, but these errors were encountered: