fix(12.2): close code-review blockers on uploads, JSON caps, and pivot fill
Keep form save behind in-flight uploads, make retries idempotent via X-Upload-Id, cap remaining JSON bodies, and surface pending pivot type errors instead of zeroing them. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,7 +25,7 @@ A plugin route under the admin prefix also fails the start-up: the SPA and the a
|
||||
|
||||
The SPA signs in through the admin API and keeps the token in the HttpOnly cookie described on [Users and permissions](users-and-permissions.md). For each screen it loads the controller's localized schema (`schema/list`, `schema/form`), then the records, and renders the fields and columns the schema names. Strings come from `GET <prefix>/api/v1/lang`, the `backend::lang` bundle in the request locale, with CLDR plural forms.
|
||||
|
||||
Each record form makes a session key when it opens: 32 random bytes, base64url encoded. The form sends it in the `X-Session-Key` header with every file upload, file list and file removal, and with the final create or update save. Uploads and removals are deferred: the server holds them against the key and the admin, and the save that carries the same key commits them in its transaction. Until then the form counts as unsaved, so leaving it asks first, and a new record's files go to record id `0`. Uploads use `XMLHttpRequest` for progress events and carry the same `X-Requested-With` header and cookie as every other call. Files of a protected relation are fetched through the admin API with the key and shown from object URLs. The key travels only in headers, never in a URL. See [File uploads](forms.md#file-uploads) for the `fileupload` field.
|
||||
Each record form makes a session key when it opens: 32 random bytes, base64url encoded. The form sends it in the `X-Session-Key` header with every file upload, file list and file removal, and with the final create or update save. Uploads and removals are deferred: the server holds them against the key and the admin, and the save that carries the same key commits them in its transaction. Until then the form counts as unsaved, so leaving it asks first, and a new record's files go to record id `0`. The form will not save while an upload is still in flight. Uploads use `XMLHttpRequest` for progress events and carry the same `X-Requested-With` header and cookie as every other call, plus an `X-Upload-Id` so a retry returns the already stored file. Files of a protected relation are fetched through the admin API with the key and shown from object URLs. The key travels only in headers, never in a URL. See [File uploads](forms.md#file-uploads) for the `fileupload` field.
|
||||
|
||||
## Types from OpenAPI
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ The field takes the generic keys plus these WinterCMS keys:
|
||||
| `mode` | `image` or `file` (the default). Image mode accepts only jpg, jpeg, png, gif and webp and checks that the bytes decode as such an image. |
|
||||
| `fileTypes` | Allowed extensions, as a comma- or pipe-separated string or a list. |
|
||||
| `mimeTypes` | Allowed MIME types (`image/png`, `image/*`) or extensions. |
|
||||
| `maxFilesize` | The largest file in megabytes. It may not exceed `http.body_limits.upload_bytes`. |
|
||||
| `maxFilesize` | The largest file in megabytes. The file plus 64 KiB of multipart framing may not exceed `http.body_limits.upload_bytes`. |
|
||||
| `maxFiles` | The most files an attachMany relation may hold. Refused on attachOne. |
|
||||
| `imageWidth`, `imageHeight` | Preview size, 1 to 4096 pixels (240 by 240 when not set). |
|
||||
| `thumbOptions` | A mapping with `mode`: `auto`, `exact`, `crop` (the default) or `fit`. |
|
||||
|
||||
Reference in New Issue
Block a user