@rebasepro/server 0.19.1 → 0.19.2-canary.g08eed46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{GCSStorageController-ZXPoNqW3.js → GCSStorageController-CLIJXwGS.js} +2 -2
- package/dist/{GCSStorageController-ZXPoNqW3.js.map → GCSStorageController-CLIJXwGS.js.map} +1 -1
- package/dist/{S3StorageController-5pAXyv31.js → S3StorageController-Dcuf8lMA.js} +2 -2
- package/dist/{S3StorageController-5pAXyv31.js.map → S3StorageController-Dcuf8lMA.js.map} +1 -1
- package/dist/api/errors.d.ts +6 -1
- package/dist/api/rest/api-generator.d.ts +80 -0
- package/dist/api/rest/batch.d.ts +71 -0
- package/dist/api/rest/conflict-target.d.ts +20 -0
- package/dist/api/rest/etag.d.ts +55 -0
- package/dist/api/rest/field-access-query.d.ts +66 -0
- package/dist/api/rest/field-ops.d.ts +86 -0
- package/dist/api/rest/query-parser.d.ts +16 -2
- package/dist/api/rest/soft-delete-params.d.ts +37 -0
- package/dist/api/rest/write-validation.d.ts +51 -8
- package/dist/api/types.d.ts +28 -3
- package/dist/{ast-schema-editor-CNgFJ3NF.js → ast-schema-editor-C6mDz0XN.js} +2 -2
- package/dist/{ast-schema-editor-CNgFJ3NF.js.map → ast-schema-editor-C6mDz0XN.js.map} +1 -1
- package/dist/auth/jwt.d.ts +17 -0
- package/dist/auth/rls-scope.d.ts +1 -0
- package/dist/{auth-BRiOuyq8.js → auth-DJsLXsCR.js} +61 -60
- package/dist/auth-DJsLXsCR.js.map +1 -0
- package/dist/{backup-C8P6Cl3G.js → backup-DGu0v9Ku.js} +2 -2
- package/dist/{backup-C8P6Cl3G.js.map → backup-DGu0v9Ku.js.map} +1 -1
- package/dist/boot/bundle.d.ts +12 -3
- package/dist/boot/driver.d.ts +11 -4
- package/dist/boot/env.d.ts +2 -2
- package/dist/{contract-routes-CusnEB5h.js → contract-routes-eLxV0le1.js} +2 -2
- package/dist/{contract-routes-CusnEB5h.js.map → contract-routes-eLxV0le1.js.map} +1 -1
- package/dist/{cron-loader-DnmIePn_.js → cron-loader-CQjvjpEw.js} +2 -2
- package/dist/{cron-loader-DnmIePn_.js.map → cron-loader-CQjvjpEw.js.map} +1 -1
- package/dist/{cron-routes-D3x2ydMa.js → cron-routes-Bfwni8Zg.js} +3 -3
- package/dist/{cron-routes-D3x2ydMa.js.map → cron-routes-Bfwni8Zg.js.map} +1 -1
- package/dist/{cron-store-CCQXwgVL.js → cron-store-Bsiw4Q6u.js} +3 -3
- package/dist/{cron-store-CCQXwgVL.js.map → cron-store-Bsiw4Q6u.js.map} +1 -1
- package/dist/{errors-HjfaPlvY.js → errors-DMImyqyR.js} +8 -3
- package/dist/errors-DMImyqyR.js.map +1 -0
- package/dist/{function-routes-gQ0EShVG.js → function-routes-C4nB2h0z.js} +2 -2
- package/dist/{function-routes-gQ0EShVG.js.map → function-routes-C4nB2h0z.js.map} +1 -1
- package/dist/functions/index.js +7 -2
- package/dist/functions/index.js.map +1 -1
- package/dist/{history-recorder-B1FwXx9J.js → history-recorder-r5_IzSHK.js} +2 -2
- package/dist/{history-recorder-B1FwXx9J.js.map → history-recorder-r5_IzSHK.js.map} +1 -1
- package/dist/{history-store-LHXaQywp.js → history-store-D4RVK-uZ.js} +2 -2
- package/dist/{history-store-LHXaQywp.js.map → history-store-D4RVK-uZ.js.map} +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.es.js +2429 -7303
- package/dist/index.es.js.map +1 -1
- package/dist/{jobs-DkkD9mPV.js → jobs-CW5lm_Ix.js} +3 -3
- package/dist/{jobs-DkkD9mPV.js.map → jobs-CW5lm_Ix.js.map} +1 -1
- package/dist/{jwt-DkhXwMzR.js → jwt-DATvkKB_.js} +39 -3
- package/dist/{jwt-DkhXwMzR.js.map → jwt-DATvkKB_.js.map} +1 -1
- package/dist/{keys-g8lbVC_o.js → keys-Qfc4XieN.js} +2 -2
- package/dist/{keys-g8lbVC_o.js.map → keys-Qfc4XieN.js.map} +1 -1
- package/dist/{logs-routes-CbsTpozn.js → logs-routes-DnJINsMu.js} +2 -2
- package/dist/{logs-routes-CbsTpozn.js.map → logs-routes-DnJINsMu.js.map} +1 -1
- package/dist/{openapi-generator-BIBbO1Tq.js → openapi-generator-DGyLbISS.js} +374 -48
- package/dist/openapi-generator-DGyLbISS.js.map +1 -0
- package/dist/{query-parser-C68Q9EX4.js → query-parser-BQiPZrM-.js} +257 -17
- package/dist/query-parser-BQiPZrM-.js.map +1 -0
- package/dist/{request-timeout-DESvlfrS.js → request-timeout-BR-OBwES.js} +2 -2
- package/dist/{request-timeout-DESvlfrS.js.map → request-timeout-BR-OBwES.js.map} +1 -1
- package/dist/{schema-editor-routes-CcZKh50q.js → schema-editor-routes-C3TLZqAC.js} +13 -13
- package/dist/{schema-editor-routes-CcZKh50q.js.map → schema-editor-routes-C3TLZqAC.js.map} +1 -1
- package/dist/{src-DHK4fHkw.js → src-Br6ARbs6.js} +26 -2
- package/dist/src-Br6ARbs6.js.map +1 -0
- package/dist/{src-Dq-I3Ybx.js → src-DqZ9YiGA.js} +1387 -94
- package/dist/src-DqZ9YiGA.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/property-limits.d.ts +77 -0
- package/dist/storage/routes.d.ts +13 -0
- package/dist/storage/tus-handler.d.ts +22 -1
- package/package.json +7 -6
- package/dist/auth-BRiOuyq8.js.map +0 -1
- package/dist/errors-HjfaPlvY.js.map +0 -1
- package/dist/openapi-generator-BIBbO1Tq.js.map +0 -1
- package/dist/query-parser-C68Q9EX4.js.map +0 -1
- package/dist/schemas-C3234HWE.js +0 -6827
- package/dist/schemas-C3234HWE.js.map +0 -1
- package/dist/src-DHK4fHkw.js.map +0 -1
- package/dist/src-Dq-I3Ybx.js.map +0 -1
package/dist/storage/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export * from "./storage-registry.js";
|
|
|
21
21
|
export { parseTransformOptions, transformImage, isTransformableImage, TransformCache } from "./image-transform.js";
|
|
22
22
|
export type { ImageTransformOptions } from "./image-transform.js";
|
|
23
23
|
export { TusHandler } from "./tus-handler.js";
|
|
24
|
+
export { createUploadConstraintResolver, assertUploadWithinPropertyLimits, isAcceptedFile, readUploadPropertyContext, UPLOAD_COLLECTION_FIELD, UPLOAD_PROPERTY_FIELD } from "./property-limits.js";
|
|
25
|
+
export type { UploadConstraints, ResolveUploadConstraints } from "./property-limits.js";
|
|
24
26
|
import { BackendStorageConfig, StorageController } from "./types.js";
|
|
25
27
|
/**
|
|
26
28
|
* Create a storage controller from a config object.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* Server-side enforcement of a storage property's own `maxSize` and
|
|
4
|
+
* `acceptedFiles`.
|
|
5
|
+
*
|
|
6
|
+
* Both were declared per property, published in the generated types, rendered
|
|
7
|
+
* by the panel's file picker — and enforced by exactly one thing: the browser.
|
|
8
|
+
* `packages/server/src/storage/routes.ts` knew a single global `maxFileSize`
|
|
9
|
+
* and nothing about the property a file was destined for, so
|
|
10
|
+
* `storage: { maxSize: 200_000, acceptedFiles: ["image/*"] }` on an avatar was
|
|
11
|
+
* a suggestion. `curl -F file=@payload.exe` past the picker put a 40 MB
|
|
12
|
+
* executable in the avatar bucket, and the config that said otherwise was never
|
|
13
|
+
* consulted.
|
|
14
|
+
*
|
|
15
|
+
* The limits are per *property*, so enforcing them needs to know which property
|
|
16
|
+
* a request is for. Uploads carry that as context (a form field on `POST
|
|
17
|
+
* /upload`, `Upload-Metadata` on the resumable path); when it is absent the
|
|
18
|
+
* global cap is still the ceiling, exactly as before. That is the honest
|
|
19
|
+
* fallback: an upload that names no property has no property limit to check,
|
|
20
|
+
* and refusing every context-less upload would break every existing client.
|
|
21
|
+
*/
|
|
22
|
+
/** What a property says a file may be. */
|
|
23
|
+
export interface UploadConstraints {
|
|
24
|
+
/** Bytes. From `StorageConfig.maxSize`. */
|
|
25
|
+
maxSize?: number;
|
|
26
|
+
/** MIME types or extensions. From `StorageConfig.acceptedFiles`. */
|
|
27
|
+
acceptedFiles?: readonly string[];
|
|
28
|
+
/** `posts.coverImage` — for the message, so the answer names the rule. */
|
|
29
|
+
source: string;
|
|
30
|
+
}
|
|
31
|
+
/** Look up the constraints for a collection slug and a property path. */
|
|
32
|
+
export type ResolveUploadConstraints = (collectionSlug: string, propertyPath: string) => UploadConstraints | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* A resolver over the collections this backend serves.
|
|
35
|
+
*
|
|
36
|
+
* Built from the registry rather than from the request, deliberately: the
|
|
37
|
+
* limits have to be the server's, resolved by slug, or a caller could send
|
|
38
|
+
* their own generous `maxSize` alongside the file and the check would be theirs
|
|
39
|
+
* to choose.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createUploadConstraintResolver(collections: readonly CollectionConfig[]): ResolveUploadConstraints;
|
|
42
|
+
/** Is this file one the property accepts? */
|
|
43
|
+
export declare function isAcceptedFile(accepted: readonly string[] | undefined, contentType: string | undefined, fileName: string | undefined): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Refuse an upload the destination property does not accept.
|
|
46
|
+
*
|
|
47
|
+
* `413` for size and `400` for type, which is the distinction HTTP already
|
|
48
|
+
* draws: one is "too big for this endpoint", the other is "this is not the
|
|
49
|
+
* thing being asked for". Both name the property, because "file too large" with
|
|
50
|
+
* no limit and no field is a message a developer cannot act on.
|
|
51
|
+
*/
|
|
52
|
+
export declare function assertUploadWithinPropertyLimits(constraints: UploadConstraints | undefined, file: {
|
|
53
|
+
size?: number;
|
|
54
|
+
type?: string;
|
|
55
|
+
name?: string;
|
|
56
|
+
}): void;
|
|
57
|
+
/**
|
|
58
|
+
* The property an upload names, from a request's own fields.
|
|
59
|
+
*
|
|
60
|
+
* Two keys, not one: the collection is resolved against the registry, so a
|
|
61
|
+
* caller cannot invent a limit — the worst they can do is name a property whose
|
|
62
|
+
* rules are *stricter*, or none at all, which leaves the global cap.
|
|
63
|
+
*/
|
|
64
|
+
export declare function readUploadPropertyContext(source: Record<string, unknown> | undefined): {
|
|
65
|
+
collection: string;
|
|
66
|
+
property: string;
|
|
67
|
+
} | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* The names the context travels under.
|
|
70
|
+
*
|
|
71
|
+
* Shared constants rather than three string literals, because the client
|
|
72
|
+
* writes them and two servers read them (the multipart route and the TUS
|
|
73
|
+
* metadata parser), and a typo in any one of the three fails silently as "no
|
|
74
|
+
* context, use the global cap".
|
|
75
|
+
*/
|
|
76
|
+
export declare const UPLOAD_COLLECTION_FIELD = "collection";
|
|
77
|
+
export declare const UPLOAD_PROPERTY_FIELD = "property";
|
package/dist/storage/routes.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { Hono } from "hono";
|
|
|
10
10
|
import { StorageController, type StorageAuthorize, type StorageAuthorizeData } from "./types.js";
|
|
11
11
|
import { type StorageRegistry } from "./storage-registry.js";
|
|
12
12
|
import { type StorageSourceDefinition, type AuthAdapter } from "@rebasepro/types";
|
|
13
|
+
import { type ResolveUploadConstraints } from "./property-limits.js";
|
|
13
14
|
import { HonoEnv } from "../api/types.js";
|
|
14
15
|
import { type StorageTrigger } from "./triggers.js";
|
|
15
16
|
import { type RenditionCacheConfig } from "./rendition-cache.js";
|
|
@@ -60,6 +61,18 @@ export interface StorageRoutesConfig {
|
|
|
60
61
|
* controller's check runs at finalize, after every byte is on disk.
|
|
61
62
|
*/
|
|
62
63
|
maxFileSize?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Per-property upload limits, looked up by collection slug and property
|
|
66
|
+
* path — `StorageConfig.maxSize` and `StorageConfig.acceptedFiles`.
|
|
67
|
+
*
|
|
68
|
+
* The global `maxFileSize` above is a ceiling for the *endpoint*; these are
|
|
69
|
+
* the rules a particular property declared, and until now the only thing
|
|
70
|
+
* enforcing them was the browser's file picker. See `property-limits.ts`.
|
|
71
|
+
*
|
|
72
|
+
* Omitted, or handed a request with no property context, uploads fall back
|
|
73
|
+
* to the global cap exactly as before.
|
|
74
|
+
*/
|
|
75
|
+
uploadConstraints?: ResolveUploadConstraints;
|
|
63
76
|
/**
|
|
64
77
|
* When provided, storage routes delegate auth to this adapter instead
|
|
65
78
|
* of the built-in JWT module. This mirrors how data routes use
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { Context } from "hono";
|
|
11
11
|
import type { StorageController } from "./types.js";
|
|
12
12
|
import { type StorageRegistry } from "./storage-registry.js";
|
|
13
|
+
import { type ResolveUploadConstraints } from "./property-limits.js";
|
|
13
14
|
/**
|
|
14
15
|
* TUS resumable upload handler.
|
|
15
16
|
*
|
|
@@ -54,6 +55,16 @@ export declare class TusHandler {
|
|
|
54
55
|
* instead of an hour of the customer's bandwidth.
|
|
55
56
|
*/
|
|
56
57
|
private maxFileSize?;
|
|
58
|
+
/**
|
|
59
|
+
* The destination property's own `maxSize` / `acceptedFiles`.
|
|
60
|
+
*
|
|
61
|
+
* Read from `Upload-Metadata` (`collection` and `property`), which is
|
|
62
|
+
* where a resumable upload carries everything else about its
|
|
63
|
+
* destination. Checked at `create`, from the declared `Upload-Length`
|
|
64
|
+
* and the metadata's content type, so a file the property will not
|
|
65
|
+
* accept is refused before the first chunk rather than after the last.
|
|
66
|
+
*/
|
|
67
|
+
private uploadConstraints?;
|
|
57
68
|
private uploads;
|
|
58
69
|
private tusDir;
|
|
59
70
|
private cleanupTimer?;
|
|
@@ -102,7 +113,17 @@ export declare class TusHandler {
|
|
|
102
113
|
* and written to disk. Told up front, the refusal costs one request
|
|
103
114
|
* instead of an hour of the customer's bandwidth.
|
|
104
115
|
*/
|
|
105
|
-
maxFileSize?: number | undefined
|
|
116
|
+
maxFileSize?: number | undefined,
|
|
117
|
+
/**
|
|
118
|
+
* The destination property's own `maxSize` / `acceptedFiles`.
|
|
119
|
+
*
|
|
120
|
+
* Read from `Upload-Metadata` (`collection` and `property`), which is
|
|
121
|
+
* where a resumable upload carries everything else about its
|
|
122
|
+
* destination. Checked at `create`, from the declared `Upload-Length`
|
|
123
|
+
* and the metadata's content type, so a file the property will not
|
|
124
|
+
* accept is refused before the first chunk rather than after the last.
|
|
125
|
+
*/
|
|
126
|
+
uploadConstraints?: ResolveUploadConstraints | undefined);
|
|
106
127
|
/** Ensure the temp directory exists. */
|
|
107
128
|
private ensureDir;
|
|
108
129
|
/** Start periodic cleanup of stale uploads. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/server",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.2-canary.g08eed46",
|
|
4
4
|
"description": "Database-Agnostic Backend Core for Rebase",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rebase",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"jsonwebtoken": "^9.0.3",
|
|
55
55
|
"ws": "^8.21.1",
|
|
56
56
|
"zod": "^4.4.3",
|
|
57
|
-
"@rebasepro/client": "0.19.
|
|
58
|
-
"@rebasepro/
|
|
59
|
-
"@rebasepro/
|
|
60
|
-
"@rebasepro/
|
|
57
|
+
"@rebasepro/client": "0.19.2-canary.g08eed46",
|
|
58
|
+
"@rebasepro/common": "0.19.2-canary.g08eed46",
|
|
59
|
+
"@rebasepro/types": "0.19.2-canary.g08eed46",
|
|
60
|
+
"@rebasepro/utils": "0.19.2-canary.g08eed46"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@jest/globals": "^30.4.1",
|
|
@@ -72,7 +72,8 @@
|
|
|
72
72
|
"jest": "^30.4.2",
|
|
73
73
|
"ts-jest": "29.4.12",
|
|
74
74
|
"typescript": "^6.0.3",
|
|
75
|
-
"vite": "^8.1.5"
|
|
75
|
+
"vite": "^8.1.5",
|
|
76
|
+
"zod-4-5": "npm:zod@4.5.4"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
79
|
"@aws-sdk/client-s3": "^3.1068.0",
|