@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.
Files changed (80) hide show
  1. package/dist/{GCSStorageController-ZXPoNqW3.js → GCSStorageController-CLIJXwGS.js} +2 -2
  2. package/dist/{GCSStorageController-ZXPoNqW3.js.map → GCSStorageController-CLIJXwGS.js.map} +1 -1
  3. package/dist/{S3StorageController-5pAXyv31.js → S3StorageController-Dcuf8lMA.js} +2 -2
  4. package/dist/{S3StorageController-5pAXyv31.js.map → S3StorageController-Dcuf8lMA.js.map} +1 -1
  5. package/dist/api/errors.d.ts +6 -1
  6. package/dist/api/rest/api-generator.d.ts +80 -0
  7. package/dist/api/rest/batch.d.ts +71 -0
  8. package/dist/api/rest/conflict-target.d.ts +20 -0
  9. package/dist/api/rest/etag.d.ts +55 -0
  10. package/dist/api/rest/field-access-query.d.ts +66 -0
  11. package/dist/api/rest/field-ops.d.ts +86 -0
  12. package/dist/api/rest/query-parser.d.ts +16 -2
  13. package/dist/api/rest/soft-delete-params.d.ts +37 -0
  14. package/dist/api/rest/write-validation.d.ts +51 -8
  15. package/dist/api/types.d.ts +28 -3
  16. package/dist/{ast-schema-editor-CNgFJ3NF.js → ast-schema-editor-C6mDz0XN.js} +2 -2
  17. package/dist/{ast-schema-editor-CNgFJ3NF.js.map → ast-schema-editor-C6mDz0XN.js.map} +1 -1
  18. package/dist/auth/jwt.d.ts +17 -0
  19. package/dist/auth/rls-scope.d.ts +1 -0
  20. package/dist/{auth-BRiOuyq8.js → auth-DJsLXsCR.js} +61 -60
  21. package/dist/auth-DJsLXsCR.js.map +1 -0
  22. package/dist/{backup-C8P6Cl3G.js → backup-DGu0v9Ku.js} +2 -2
  23. package/dist/{backup-C8P6Cl3G.js.map → backup-DGu0v9Ku.js.map} +1 -1
  24. package/dist/boot/bundle.d.ts +12 -3
  25. package/dist/boot/driver.d.ts +11 -4
  26. package/dist/boot/env.d.ts +2 -2
  27. package/dist/{contract-routes-CusnEB5h.js → contract-routes-eLxV0le1.js} +2 -2
  28. package/dist/{contract-routes-CusnEB5h.js.map → contract-routes-eLxV0le1.js.map} +1 -1
  29. package/dist/{cron-loader-DnmIePn_.js → cron-loader-CQjvjpEw.js} +2 -2
  30. package/dist/{cron-loader-DnmIePn_.js.map → cron-loader-CQjvjpEw.js.map} +1 -1
  31. package/dist/{cron-routes-D3x2ydMa.js → cron-routes-Bfwni8Zg.js} +3 -3
  32. package/dist/{cron-routes-D3x2ydMa.js.map → cron-routes-Bfwni8Zg.js.map} +1 -1
  33. package/dist/{cron-store-CCQXwgVL.js → cron-store-Bsiw4Q6u.js} +3 -3
  34. package/dist/{cron-store-CCQXwgVL.js.map → cron-store-Bsiw4Q6u.js.map} +1 -1
  35. package/dist/{errors-HjfaPlvY.js → errors-DMImyqyR.js} +8 -3
  36. package/dist/errors-DMImyqyR.js.map +1 -0
  37. package/dist/{function-routes-gQ0EShVG.js → function-routes-C4nB2h0z.js} +2 -2
  38. package/dist/{function-routes-gQ0EShVG.js.map → function-routes-C4nB2h0z.js.map} +1 -1
  39. package/dist/functions/index.js +7 -2
  40. package/dist/functions/index.js.map +1 -1
  41. package/dist/{history-recorder-B1FwXx9J.js → history-recorder-r5_IzSHK.js} +2 -2
  42. package/dist/{history-recorder-B1FwXx9J.js.map → history-recorder-r5_IzSHK.js.map} +1 -1
  43. package/dist/{history-store-LHXaQywp.js → history-store-D4RVK-uZ.js} +2 -2
  44. package/dist/{history-store-LHXaQywp.js.map → history-store-D4RVK-uZ.js.map} +1 -1
  45. package/dist/index.d.ts +5 -0
  46. package/dist/index.es.js +2429 -7303
  47. package/dist/index.es.js.map +1 -1
  48. package/dist/{jobs-DkkD9mPV.js → jobs-CW5lm_Ix.js} +3 -3
  49. package/dist/{jobs-DkkD9mPV.js.map → jobs-CW5lm_Ix.js.map} +1 -1
  50. package/dist/{jwt-DkhXwMzR.js → jwt-DATvkKB_.js} +39 -3
  51. package/dist/{jwt-DkhXwMzR.js.map → jwt-DATvkKB_.js.map} +1 -1
  52. package/dist/{keys-g8lbVC_o.js → keys-Qfc4XieN.js} +2 -2
  53. package/dist/{keys-g8lbVC_o.js.map → keys-Qfc4XieN.js.map} +1 -1
  54. package/dist/{logs-routes-CbsTpozn.js → logs-routes-DnJINsMu.js} +2 -2
  55. package/dist/{logs-routes-CbsTpozn.js.map → logs-routes-DnJINsMu.js.map} +1 -1
  56. package/dist/{openapi-generator-BIBbO1Tq.js → openapi-generator-DGyLbISS.js} +374 -48
  57. package/dist/openapi-generator-DGyLbISS.js.map +1 -0
  58. package/dist/{query-parser-C68Q9EX4.js → query-parser-BQiPZrM-.js} +257 -17
  59. package/dist/query-parser-BQiPZrM-.js.map +1 -0
  60. package/dist/{request-timeout-DESvlfrS.js → request-timeout-BR-OBwES.js} +2 -2
  61. package/dist/{request-timeout-DESvlfrS.js.map → request-timeout-BR-OBwES.js.map} +1 -1
  62. package/dist/{schema-editor-routes-CcZKh50q.js → schema-editor-routes-C3TLZqAC.js} +13 -13
  63. package/dist/{schema-editor-routes-CcZKh50q.js.map → schema-editor-routes-C3TLZqAC.js.map} +1 -1
  64. package/dist/{src-DHK4fHkw.js → src-Br6ARbs6.js} +26 -2
  65. package/dist/src-Br6ARbs6.js.map +1 -0
  66. package/dist/{src-Dq-I3Ybx.js → src-DqZ9YiGA.js} +1387 -94
  67. package/dist/src-DqZ9YiGA.js.map +1 -0
  68. package/dist/storage/index.d.ts +2 -0
  69. package/dist/storage/property-limits.d.ts +77 -0
  70. package/dist/storage/routes.d.ts +13 -0
  71. package/dist/storage/tus-handler.d.ts +22 -1
  72. package/package.json +7 -6
  73. package/dist/auth-BRiOuyq8.js.map +0 -1
  74. package/dist/errors-HjfaPlvY.js.map +0 -1
  75. package/dist/openapi-generator-BIBbO1Tq.js.map +0 -1
  76. package/dist/query-parser-C68Q9EX4.js.map +0 -1
  77. package/dist/schemas-C3234HWE.js +0 -6827
  78. package/dist/schemas-C3234HWE.js.map +0 -1
  79. package/dist/src-DHK4fHkw.js.map +0 -1
  80. package/dist/src-Dq-I3Ybx.js.map +0 -1
@@ -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";
@@ -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.1",
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.1",
58
- "@rebasepro/types": "0.19.1",
59
- "@rebasepro/utils": "0.19.1",
60
- "@rebasepro/common": "0.19.1"
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",