@palbase/backend 7.0.0 → 8.1.0

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/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-BFgsOTiL.cjs';
2
- export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCmsClient, V as PalbaseCmsFindOneOptions, W as PalbaseCmsFindOptions, X as PalbaseCohortQueryInput, Y as PalbaseCohortResult, Z as PalbaseCollectionRef, _ as PalbaseCountQueryInput, $ as PalbaseCountResult, a0 as PalbaseCreateLinkParams, a1 as PalbaseDeviceInfo, a2 as PalbaseDeviceTokenView, a3 as PalbaseDocumentRef, a4 as PalbaseDocumentSnapshot, a5 as PalbaseEmailClient, a6 as PalbaseEmailSendParams, a7 as PalbaseEmailSendResponse, a8 as PalbaseEventNamesResult, a9 as PalbaseEventsQueryInput, aa as PalbaseEventsResult, ab as PalbaseFileObject, ac as PalbaseFlag, ad as PalbaseFlagContext, ae as PalbaseFlagSource, af as PalbaseFlagValue, ag as PalbaseFlagVariant, ah as PalbaseFlagsServiceClient, ai as PalbaseFunctionsClient, aj as PalbaseFunnelQueryInput, ak as PalbaseFunnelResult, al as PalbaseIdentifyTraits, am as PalbaseInboxClient, an as PalbaseInboxListOptions, ao as PalbaseInboxListResult, ap as PalbaseInboxMessage, aq as PalbaseInboxSendParams, ar as PalbaseInboxSendResponse, as as PalbaseInitialLink, at as PalbaseInvokeOptions, au as PalbaseLink, av as PalbaseLinkAnalytics, aw as PalbaseLinkDetails, ax as PalbaseLinksClient, ay as PalbaseListLinksOptions, az as PalbaseListLinksResult, aA as PalbaseListOptions, aB as PalbaseMatchParams, aC as PalbaseMultiChannelResponse, aD as PalbaseOverviewResult, aE as PalbasePreferences, aF as PalbasePreferencesClient, aG as PalbasePublicUrlResponse, aH as PalbasePushClient, aI as PalbasePushSendParams, aJ as PalbasePushSendResponse, aK as PalbaseQrCodeOptions, aL as PalbaseQuerySnapshot, aM as PalbaseRegisterDeviceParams, aN as PalbaseResult, aO as PalbaseRetentionQueryInput, aP as PalbaseRetentionResult, aQ as PalbaseSession, aR as PalbaseSetOverrideResult, aS as PalbaseSetOverridesResult, aT as PalbaseSignedUrlResponse, aU as PalbaseSmsClient, aV as PalbaseSmsSendParams, aW as PalbaseSmsSendResponse, aX as PalbaseTransformOptions, aY as PalbaseUpdateLinkParams, aZ as PalbaseUploadOptions, a_ as PalbaseUser, a$ as PalbaseUserDetailResult, b0 as PalbaseUsersQueryInput, b1 as PalbaseUsersResult, b2 as PalbaseVerifyRequestSignatureParams, b3 as PalbaseWhereOperator, b4 as TooManyRequests, b5 as TxClient, b6 as Unauthorized, b7 as defineMiddleware } from './endpoint-BFgsOTiL.cjs';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-fW9yWla0.cjs';
2
+ export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as TooManyRequests, b2 as TxClient, b3 as Unauthorized, b4 as defineMiddleware } from './endpoint-fW9yWla0.cjs';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { E as EnvTypedDatabase, S as SchemaDef } from './index-CE31P7Dt.cjs';
5
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from './index-CE31P7Dt.cjs';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-BZdDJJIy.cjs';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from './index-BZdDJJIy.cjs';
6
6
  export { TableTypes, Tables } from './db/env.cjs';
7
7
  import { ZodTypeAny, z } from 'zod';
8
8
  export { z } from 'zod';
@@ -53,7 +53,7 @@ export { z } from 'zod';
53
53
  * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but
54
54
  * cannot hold a subscription socket — `subscribe()` lives on the client SDK).
55
55
  *
56
- * EXCLUDED on purpose: Functions, CMS, Links, Analytics, Auth. They are not
56
+ * EXCLUDED on purpose: Functions, Links, Analytics, Auth. They are not
57
57
  * exposed as backend handler singletons (auth lives on the client SDK; the rest
58
58
  * are out of scope for backend endpoints). */
59
59
  interface RuntimeServices {
@@ -702,6 +702,90 @@ interface ControllerOptions {
702
702
  */
703
703
  declare function Controller(basePath: string, options?: ControllerOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
704
704
 
705
+ /** A legacy method decorator (`experimentalDecorators`): `(prototype, name,
706
+ * descriptor)`. */
707
+ type MethodDecorator$1 = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
708
+ /** A legacy parameter decorator: `(prototype, name, paramIndex)`. */
709
+ type ParameterDecorator$1 = (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
710
+ /**
711
+ * Direct-storage upload settings for an `@Upload` route. The br-pod validates an
712
+ * authorize request against these (size/type), then mints a signed upload URL
713
+ * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT
714
+ * — the client cannot exceed what it declared.
715
+ */
716
+ interface UploadConfig {
717
+ /** Target bucket NAME. MUST exist in `config/storage.ts` `defineStorage(...)`. */
718
+ bucket: string;
719
+ /**
720
+ * Max object size in BYTES. Enforced twice: the authorize pre-flight rejects a
721
+ * larger declared size, and the signed URL pins it so storage rejects a larger
722
+ * PUT. When omitted, the bucket's own `fileSizeLimit` applies.
723
+ */
724
+ maxSize?: number;
725
+ /**
726
+ * MIME allowlist for the object. The authorize pre-flight rejects a
727
+ * non-matching declared content-type, and the signed URL pins the exact type.
728
+ * When omitted, the bucket's own `allowedMimeTypes` applies (or any type).
729
+ */
730
+ allowedTypes?: string[];
731
+ /**
732
+ * SERVER-side object key template. The client NEVER chooses the path. Tokens:
733
+ * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and
734
+ * `{filename}` (the client-declared filename, sanitized). e.g.
735
+ * `"{userId}/{uploadId}-{filename}"`.
736
+ */
737
+ pathTemplate: string;
738
+ }
739
+ /**
740
+ * `@Upload(subpath, config)` — declare a direct-storage upload route. The method
741
+ * body is the completion handler; `config.uploadConfig` drives the authorize
742
+ * guard + signed-URL pinning.
743
+ *
744
+ * @example
745
+ * @Upload("/", { bucket: "docs", maxSize: 25 * 1024 * 1024,
746
+ * allowedTypes: ["application/pdf"], pathTemplate: "{userId}/{uploadId}-{filename}" })
747
+ * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }
748
+ */
749
+ declare function Upload(subpath: string, config: UploadConfig & Pick<RouteOptions, "auth" | "rateLimit">): MethodDecorator$1;
750
+ /**
751
+ * The uploaded object, injected into an `@Upload` method body by
752
+ * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present
753
+ * (they went straight to storage) — this is the metadata the completion handler
754
+ * persists.
755
+ */
756
+ interface UploadedObject {
757
+ /** Server-minted id correlating authorize ↔ completion (idempotency key). */
758
+ uploadId: string;
759
+ /** Final object key in the bucket (rendered from `pathTemplate`). */
760
+ path: string;
761
+ /** Bucket the object landed in. */
762
+ bucket: string;
763
+ /** Object size in bytes, as reported by storage. */
764
+ size: number;
765
+ /** Object MIME type, as reported by storage. */
766
+ contentType: string;
767
+ }
768
+ /**
769
+ * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an
770
+ * `@Upload` method body (the completion input). Only valid on an `@Upload`
771
+ * route; the bytes are NOT present (they went directly to storage), this is the
772
+ * confirmed object's metadata.
773
+ *
774
+ * Co-located with the {@link UploadedObject} TYPE so a single exported name
775
+ * `UploadedObject` carries BOTH the decorator value and the type annotation.
776
+ */
777
+ declare function UploadedObject(): ParameterDecorator$1;
778
+ /**
779
+ * Cross-check one `@Upload` route's uploadConfig against the project's
780
+ * {@link StorageConfig}: the bucket must exist, the upload's `maxSize` must not
781
+ * exceed the bucket's `fileSizeLimit`, and the upload's `allowedTypes` must be a
782
+ * subset of the bucket's `allowedMimeTypes`. Throws a precise error so a
783
+ * mismatch fails at deploy, not at the first user upload.
784
+ *
785
+ * `routeLabel` is used only for error messages (e.g. `docs.upload`).
786
+ */
787
+ declare function validateUploadAgainstStorage(uploadConfig: UploadConfig, storage: StorageConfig, routeLabel: string): void;
788
+
705
789
  /** The HTTP verbs a route may declare, upper-cased (the runtime router +
706
790
  * OpenAPI lower-case on their own). */
707
791
  type HttpMethodUpper = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
@@ -711,6 +795,12 @@ interface RouteOptions {
711
795
  auth?: AuthSpec;
712
796
  /** Per-route rate limit. */
713
797
  rateLimit?: RateLimitConfig;
798
+ /** Direct-storage upload config — present ONLY on `@Upload` routes (the
799
+ * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a
800
+ * route as an upload route through the whole pipeline (registry → flatten →
801
+ * openapi → codegen). The bytes go client→storage directly; the method body
802
+ * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */
803
+ uploadConfig?: UploadConfig;
714
804
  }
715
805
  /** One inferred throw site: the error CLASS name (e.g. "TodoLocked") and its
716
806
  * wire code (e.g. "todo_locked"). `status`, `hasData`, and the data JSON schema
@@ -781,9 +871,6 @@ interface RegisteredError {
781
871
  dataDigest?: string;
782
872
  builtin: boolean;
783
873
  }
784
- /** Get (creating + pre-seeding if absent) the project-global error registry,
785
- * keyed by wire code. Anchored on `globalThis` so every copy of the SDK in a
786
- * process shares the one registry. */
787
874
  declare function getErrorRegistry(): Map<string, RegisteredError>;
788
875
  /** Class returned for schema-bearing errors: ctor(data, message?). */
789
876
  interface DefinedErrorWithData<S extends ZodTypeAny> {
@@ -1263,4 +1350,4 @@ declare const documents: {
1263
1350
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
1264
1351
  };
1265
1352
 
1266
- export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, type ThrowDescriptor, TraceId, type TwilioOptions, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineWebhook, defineWorker, documents, flag, getErrorRegistry, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage };
1353
+ export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineWebhook, defineWorker, documents, flag, getErrorRegistry, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage, validateUploadAgainstStorage };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-BFgsOTiL.js';
2
- export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCmsClient, V as PalbaseCmsFindOneOptions, W as PalbaseCmsFindOptions, X as PalbaseCohortQueryInput, Y as PalbaseCohortResult, Z as PalbaseCollectionRef, _ as PalbaseCountQueryInput, $ as PalbaseCountResult, a0 as PalbaseCreateLinkParams, a1 as PalbaseDeviceInfo, a2 as PalbaseDeviceTokenView, a3 as PalbaseDocumentRef, a4 as PalbaseDocumentSnapshot, a5 as PalbaseEmailClient, a6 as PalbaseEmailSendParams, a7 as PalbaseEmailSendResponse, a8 as PalbaseEventNamesResult, a9 as PalbaseEventsQueryInput, aa as PalbaseEventsResult, ab as PalbaseFileObject, ac as PalbaseFlag, ad as PalbaseFlagContext, ae as PalbaseFlagSource, af as PalbaseFlagValue, ag as PalbaseFlagVariant, ah as PalbaseFlagsServiceClient, ai as PalbaseFunctionsClient, aj as PalbaseFunnelQueryInput, ak as PalbaseFunnelResult, al as PalbaseIdentifyTraits, am as PalbaseInboxClient, an as PalbaseInboxListOptions, ao as PalbaseInboxListResult, ap as PalbaseInboxMessage, aq as PalbaseInboxSendParams, ar as PalbaseInboxSendResponse, as as PalbaseInitialLink, at as PalbaseInvokeOptions, au as PalbaseLink, av as PalbaseLinkAnalytics, aw as PalbaseLinkDetails, ax as PalbaseLinksClient, ay as PalbaseListLinksOptions, az as PalbaseListLinksResult, aA as PalbaseListOptions, aB as PalbaseMatchParams, aC as PalbaseMultiChannelResponse, aD as PalbaseOverviewResult, aE as PalbasePreferences, aF as PalbasePreferencesClient, aG as PalbasePublicUrlResponse, aH as PalbasePushClient, aI as PalbasePushSendParams, aJ as PalbasePushSendResponse, aK as PalbaseQrCodeOptions, aL as PalbaseQuerySnapshot, aM as PalbaseRegisterDeviceParams, aN as PalbaseResult, aO as PalbaseRetentionQueryInput, aP as PalbaseRetentionResult, aQ as PalbaseSession, aR as PalbaseSetOverrideResult, aS as PalbaseSetOverridesResult, aT as PalbaseSignedUrlResponse, aU as PalbaseSmsClient, aV as PalbaseSmsSendParams, aW as PalbaseSmsSendResponse, aX as PalbaseTransformOptions, aY as PalbaseUpdateLinkParams, aZ as PalbaseUploadOptions, a_ as PalbaseUser, a$ as PalbaseUserDetailResult, b0 as PalbaseUsersQueryInput, b1 as PalbaseUsersResult, b2 as PalbaseVerifyRequestSignatureParams, b3 as PalbaseWhereOperator, b4 as TooManyRequests, b5 as TxClient, b6 as Unauthorized, b7 as defineMiddleware } from './endpoint-BFgsOTiL.js';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-fW9yWla0.js';
2
+ export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as TooManyRequests, b2 as TxClient, b3 as Unauthorized, b4 as defineMiddleware } from './endpoint-fW9yWla0.js';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { E as EnvTypedDatabase, S as SchemaDef } from './index-E7CMoir3.js';
5
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from './index-E7CMoir3.js';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-CArW1VMq.js';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from './index-CArW1VMq.js';
6
6
  export { TableTypes, Tables } from './db/env.js';
7
7
  import { ZodTypeAny, z } from 'zod';
8
8
  export { z } from 'zod';
@@ -53,7 +53,7 @@ export { z } from 'zod';
53
53
  * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but
54
54
  * cannot hold a subscription socket — `subscribe()` lives on the client SDK).
55
55
  *
56
- * EXCLUDED on purpose: Functions, CMS, Links, Analytics, Auth. They are not
56
+ * EXCLUDED on purpose: Functions, Links, Analytics, Auth. They are not
57
57
  * exposed as backend handler singletons (auth lives on the client SDK; the rest
58
58
  * are out of scope for backend endpoints). */
59
59
  interface RuntimeServices {
@@ -702,6 +702,90 @@ interface ControllerOptions {
702
702
  */
703
703
  declare function Controller(basePath: string, options?: ControllerOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
704
704
 
705
+ /** A legacy method decorator (`experimentalDecorators`): `(prototype, name,
706
+ * descriptor)`. */
707
+ type MethodDecorator$1 = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
708
+ /** A legacy parameter decorator: `(prototype, name, paramIndex)`. */
709
+ type ParameterDecorator$1 = (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
710
+ /**
711
+ * Direct-storage upload settings for an `@Upload` route. The br-pod validates an
712
+ * authorize request against these (size/type), then mints a signed upload URL
713
+ * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT
714
+ * — the client cannot exceed what it declared.
715
+ */
716
+ interface UploadConfig {
717
+ /** Target bucket NAME. MUST exist in `config/storage.ts` `defineStorage(...)`. */
718
+ bucket: string;
719
+ /**
720
+ * Max object size in BYTES. Enforced twice: the authorize pre-flight rejects a
721
+ * larger declared size, and the signed URL pins it so storage rejects a larger
722
+ * PUT. When omitted, the bucket's own `fileSizeLimit` applies.
723
+ */
724
+ maxSize?: number;
725
+ /**
726
+ * MIME allowlist for the object. The authorize pre-flight rejects a
727
+ * non-matching declared content-type, and the signed URL pins the exact type.
728
+ * When omitted, the bucket's own `allowedMimeTypes` applies (or any type).
729
+ */
730
+ allowedTypes?: string[];
731
+ /**
732
+ * SERVER-side object key template. The client NEVER chooses the path. Tokens:
733
+ * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and
734
+ * `{filename}` (the client-declared filename, sanitized). e.g.
735
+ * `"{userId}/{uploadId}-{filename}"`.
736
+ */
737
+ pathTemplate: string;
738
+ }
739
+ /**
740
+ * `@Upload(subpath, config)` — declare a direct-storage upload route. The method
741
+ * body is the completion handler; `config.uploadConfig` drives the authorize
742
+ * guard + signed-URL pinning.
743
+ *
744
+ * @example
745
+ * @Upload("/", { bucket: "docs", maxSize: 25 * 1024 * 1024,
746
+ * allowedTypes: ["application/pdf"], pathTemplate: "{userId}/{uploadId}-{filename}" })
747
+ * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }
748
+ */
749
+ declare function Upload(subpath: string, config: UploadConfig & Pick<RouteOptions, "auth" | "rateLimit">): MethodDecorator$1;
750
+ /**
751
+ * The uploaded object, injected into an `@Upload` method body by
752
+ * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present
753
+ * (they went straight to storage) — this is the metadata the completion handler
754
+ * persists.
755
+ */
756
+ interface UploadedObject {
757
+ /** Server-minted id correlating authorize ↔ completion (idempotency key). */
758
+ uploadId: string;
759
+ /** Final object key in the bucket (rendered from `pathTemplate`). */
760
+ path: string;
761
+ /** Bucket the object landed in. */
762
+ bucket: string;
763
+ /** Object size in bytes, as reported by storage. */
764
+ size: number;
765
+ /** Object MIME type, as reported by storage. */
766
+ contentType: string;
767
+ }
768
+ /**
769
+ * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an
770
+ * `@Upload` method body (the completion input). Only valid on an `@Upload`
771
+ * route; the bytes are NOT present (they went directly to storage), this is the
772
+ * confirmed object's metadata.
773
+ *
774
+ * Co-located with the {@link UploadedObject} TYPE so a single exported name
775
+ * `UploadedObject` carries BOTH the decorator value and the type annotation.
776
+ */
777
+ declare function UploadedObject(): ParameterDecorator$1;
778
+ /**
779
+ * Cross-check one `@Upload` route's uploadConfig against the project's
780
+ * {@link StorageConfig}: the bucket must exist, the upload's `maxSize` must not
781
+ * exceed the bucket's `fileSizeLimit`, and the upload's `allowedTypes` must be a
782
+ * subset of the bucket's `allowedMimeTypes`. Throws a precise error so a
783
+ * mismatch fails at deploy, not at the first user upload.
784
+ *
785
+ * `routeLabel` is used only for error messages (e.g. `docs.upload`).
786
+ */
787
+ declare function validateUploadAgainstStorage(uploadConfig: UploadConfig, storage: StorageConfig, routeLabel: string): void;
788
+
705
789
  /** The HTTP verbs a route may declare, upper-cased (the runtime router +
706
790
  * OpenAPI lower-case on their own). */
707
791
  type HttpMethodUpper = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
@@ -711,6 +795,12 @@ interface RouteOptions {
711
795
  auth?: AuthSpec;
712
796
  /** Per-route rate limit. */
713
797
  rateLimit?: RateLimitConfig;
798
+ /** Direct-storage upload config — present ONLY on `@Upload` routes (the
799
+ * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a
800
+ * route as an upload route through the whole pipeline (registry → flatten →
801
+ * openapi → codegen). The bytes go client→storage directly; the method body
802
+ * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */
803
+ uploadConfig?: UploadConfig;
714
804
  }
715
805
  /** One inferred throw site: the error CLASS name (e.g. "TodoLocked") and its
716
806
  * wire code (e.g. "todo_locked"). `status`, `hasData`, and the data JSON schema
@@ -781,9 +871,6 @@ interface RegisteredError {
781
871
  dataDigest?: string;
782
872
  builtin: boolean;
783
873
  }
784
- /** Get (creating + pre-seeding if absent) the project-global error registry,
785
- * keyed by wire code. Anchored on `globalThis` so every copy of the SDK in a
786
- * process shares the one registry. */
787
874
  declare function getErrorRegistry(): Map<string, RegisteredError>;
788
875
  /** Class returned for schema-bearing errors: ctor(data, message?). */
789
876
  interface DefinedErrorWithData<S extends ZodTypeAny> {
@@ -1263,4 +1350,4 @@ declare const documents: {
1263
1350
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
1264
1351
  };
1265
1352
 
1266
- export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, type ThrowDescriptor, TraceId, type TwilioOptions, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineWebhook, defineWorker, documents, flag, getErrorRegistry, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage };
1353
+ export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineWebhook, defineWorker, documents, flag, getErrorRegistry, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage, validateUploadAgainstStorage };
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  __requestALS,
13
13
  __runWithRuntime,
14
14
  __setRuntime
15
- } from "./chunk-SWT2QR5F.js";
15
+ } from "./chunk-RGQUB66H.js";
16
16
  import {
17
17
  EXTENSION_DEPENDENCIES,
18
18
  PALBASE_EXTENSIONS,
@@ -475,6 +475,86 @@ var Put = makeMethodDecorator("PUT");
475
475
  var Patch = makeMethodDecorator("PATCH");
476
476
  var Delete = makeMethodDecorator("DELETE");
477
477
 
478
+ // src/decorators/upload.ts
479
+ var MIME_RE2 = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*\/[A-Za-z0-9*][A-Za-z0-9!#$&^_.+-]*$/;
480
+ function Upload(subpath, config) {
481
+ const { auth: auth2, rateLimit, ...uploadConfig } = config;
482
+ validateUploadConfigShape(uploadConfig);
483
+ const options = {
484
+ uploadConfig,
485
+ ...auth2 !== void 0 ? { auth: auth2 } : {},
486
+ ...rateLimit !== void 0 ? { rateLimit } : {}
487
+ };
488
+ return function(target, propertyKey) {
489
+ recordRoute(target, String(propertyKey), "POST", subpath, options);
490
+ };
491
+ }
492
+ function UploadedObject() {
493
+ return function(target, propertyKey, parameterIndex) {
494
+ recordParam(target, String(propertyKey), {
495
+ index: parameterIndex,
496
+ kind: "uploadedObject"
497
+ });
498
+ };
499
+ }
500
+ function validateUploadConfigShape(c) {
501
+ if (c === null || typeof c !== "object") {
502
+ throw new Error("@Upload config must be an object { bucket, pathTemplate, ... }");
503
+ }
504
+ if (typeof c.bucket !== "string" || c.bucket.length === 0) {
505
+ throw new Error("@Upload config.bucket must be a non-empty bucket name");
506
+ }
507
+ if (typeof c.pathTemplate !== "string" || c.pathTemplate.length === 0) {
508
+ throw new Error("@Upload config.pathTemplate must be a non-empty key template");
509
+ }
510
+ if (c.maxSize !== void 0) {
511
+ if (!Number.isInteger(c.maxSize) || c.maxSize <= 0) {
512
+ throw new Error(`@Upload config.maxSize must be a positive integer byte count, got ${c.maxSize}`);
513
+ }
514
+ }
515
+ if (c.allowedTypes !== void 0) {
516
+ if (!Array.isArray(c.allowedTypes) || c.allowedTypes.length === 0) {
517
+ throw new Error("@Upload config.allowedTypes must be a non-empty array of MIME types when present");
518
+ }
519
+ for (const t of c.allowedTypes) {
520
+ if (typeof t !== "string" || !MIME_RE2.test(t.trim())) {
521
+ throw new Error(`@Upload config.allowedTypes entry "${t}" is not a valid MIME type (e.g. "image/png")`);
522
+ }
523
+ }
524
+ }
525
+ }
526
+ function validateUploadAgainstStorage(uploadConfig, storage2, routeLabel) {
527
+ const def = storage2.buckets[uploadConfig.bucket];
528
+ if (def === void 0) {
529
+ const known = Object.keys(storage2.buckets);
530
+ throw new Error(
531
+ `@Upload route ${routeLabel} targets bucket "${uploadConfig.bucket}" which is not declared in defineStorage(...). ` + (known.length ? `Known buckets: ${known.join(", ")}.` : "No buckets are declared.")
532
+ );
533
+ }
534
+ if (uploadConfig.maxSize !== void 0 && def.fileSizeLimit !== null && uploadConfig.maxSize > def.fileSizeLimit) {
535
+ throw new Error(
536
+ `@Upload route ${routeLabel} maxSize (${uploadConfig.maxSize} bytes) exceeds bucket "${uploadConfig.bucket}" fileSizeLimit (${def.fileSizeLimit} bytes)`
537
+ );
538
+ }
539
+ if (uploadConfig.allowedTypes !== void 0 && def.allowedMimeTypes !== null) {
540
+ const bucketAllows = (mime) => def.allowedMimeTypes.some((b) => {
541
+ if (b === mime) return true;
542
+ const slash = b.indexOf("/");
543
+ if (slash > 0 && b.slice(slash + 1) === "*") {
544
+ return mime.startsWith(b.slice(0, slash + 1));
545
+ }
546
+ return false;
547
+ });
548
+ for (const t of uploadConfig.allowedTypes) {
549
+ if (!bucketAllows(t)) {
550
+ throw new Error(
551
+ `@Upload route ${routeLabel} allows MIME "${t}" which bucket "${uploadConfig.bucket}" does not (bucket allows: ${def.allowedMimeTypes.join(", ")})`
552
+ );
553
+ }
554
+ }
555
+ }
556
+ }
557
+
478
558
  // src/decorators/params.ts
479
559
  function makeParamDecorator(kind, extra) {
480
560
  return function(target, propertyKey, parameterIndex) {
@@ -576,8 +656,8 @@ function defaultMessage(name) {
576
656
  return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
577
657
  }
578
658
  var BadRequest = class extends NamedHttpError {
579
- constructor(message, code, data) {
580
- super(400, "bad_request", "BadRequest", message, code, data);
659
+ constructor(data, message) {
660
+ super(400, "bad_request", "BadRequest", message, void 0, data);
581
661
  }
582
662
  };
583
663
  var Unauthorized = class extends NamedHttpError {
@@ -601,8 +681,8 @@ var Conflict = class extends NamedHttpError {
601
681
  }
602
682
  };
603
683
  var TooManyRequests = class extends NamedHttpError {
604
- constructor(message, code, data) {
605
- super(429, "too_many_requests", "TooManyRequests", message, code, data);
684
+ constructor(data, message) {
685
+ super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
606
686
  }
607
687
  };
608
688
 
@@ -615,6 +695,12 @@ import {
615
695
  import { z } from "zod";
616
696
  extendZodWithOpenApi(z);
617
697
  var ERROR_REGISTRY = /* @__PURE__ */ Symbol.for("palbase.backend.errorRegistry");
698
+ var BUILTIN_DATA_SCHEMAS = {
699
+ bad_request: z.object({
700
+ fields: z.array(z.object({ field: z.string(), message: z.string() }))
701
+ }),
702
+ too_many_requests: z.object({ retryAfter: z.number().int() })
703
+ };
618
704
  function getErrorRegistry() {
619
705
  const g = globalThis;
620
706
  if (!g[ERROR_REGISTRY]) {
@@ -627,7 +713,14 @@ function getErrorRegistry() {
627
713
  ["conflict", 409, "Conflict"],
628
714
  ["too_many_requests", 429, "TooManyRequests"]
629
715
  ]) {
630
- m.set(code, { code, status, className, builtin: true });
716
+ const dataSchema = BUILTIN_DATA_SCHEMAS[code];
717
+ m.set(code, {
718
+ code,
719
+ status,
720
+ className,
721
+ builtin: true,
722
+ ...dataSchema ? { dataSchema, dataDigest: digestOf(code, dataSchema) } : {}
723
+ });
631
724
  }
632
725
  g[ERROR_REGISTRY] = m;
633
726
  }
@@ -1042,6 +1135,8 @@ export {
1042
1135
  TooManyRequests,
1043
1136
  TraceId,
1044
1137
  Unauthorized,
1138
+ Upload,
1139
+ UploadedObject,
1045
1140
  User,
1046
1141
  __getRuntime,
1047
1142
  __registerResource,
@@ -1080,6 +1175,7 @@ export {
1080
1175
  text,
1081
1176
  timestamp,
1082
1177
  uuid,
1178
+ validateUploadAgainstStorage,
1083
1179
  z2 as z
1084
1180
  };
1085
1181
  //# sourceMappingURL=index.js.map