@lunora/server 1.0.0-alpha.49 → 1.0.0-alpha.50

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.mts CHANGED
@@ -1,15 +1,15 @@
1
- import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
1
+ import { Validator, Infer, ValidatorMap, InferValidatorMap, ColumnValidator, v } from '@lunora/values';
2
2
  export { type ColumnValidator, type GeoPoint, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
3
  import { ArgsValidator, InferArgs, RegisteredAction, ExposeConfig, X402ProcedureConfig, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.mjs";
4
- export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
4
+ export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
5
5
  import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
6
6
  export type { LunoraErrorCode } from '@lunora/errors';
7
7
  import { Context, Hono } from 'hono';
8
+ import { WhereOperators, QueryArgs as QueryArgs$2 } from "./data-model.mjs";
8
9
  import { b as Permission, R as Role, T as TypedDefinePolicyInput, a as Policy, D as DefinePolicyInput, W as WhereInput, c as RlsOptions } from "./packem_shared/types.d-C4CMJK8x.mjs";
9
10
  export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-C4CMJK8x.mjs";
10
11
  import { SearchLanguage, SearchStrategy } from '@lunora/search-core';
11
12
  export { type CronJob, type CronJobsBuilder, type CronScheduleKind, type DailySchedule, type IntervalSchedule, type MonthlySchedule, type WeeklySchedule, cronJobs } from '@lunora/scheduler';
12
- import "./data-model.mjs";
13
13
  /**
14
14
  * Make any `config.storage` result bucket-aware so `ctx.storage.bucket(name)`
15
15
  * always resolves. A `createBucketStorage(...)` result already carries
@@ -808,6 +808,91 @@ type LifecycleHandler = (context: MutationCtx, event: LifecycleEvent) => Promise
808
808
  declare const onConnect: (handler: LifecycleHandler) => RegisteredLifecycleHook;
809
809
  /** Register a hook that fires once when a client's WebSocket disconnects. */
810
810
  declare const onDisconnect: (handler: LifecycleHandler) => RegisteredLifecycleHook;
811
+ /** Default `limit` when the caller doesn't ask for one. */
812
+ declare const DEFAULT_LIMIT = 25;
813
+ /** Default ceiling on `limit`, so one request can't ask for an unbounded page. */
814
+ declare const DEFAULT_MAX_LIMIT = 100;
815
+ /**
816
+ * Per-field predicate accepted for a declared filter column. An alias of the
817
+ * `ctx.db` `where` DSL's own operator type rather than a copy, so the two cannot
818
+ * drift as operators are added.
819
+ */
820
+ type ListFilterOperators<T> = WhereOperators<T>;
821
+ /**
822
+ * The filter allow-list a caller may declare: a subset of the document's own
823
+ * columns, each with a validator for that column's type. Constraining the KEYS to
824
+ * `keyof Doc` is what turns a typo'd or renamed column into a compile error
825
+ * instead of a predicate that silently never matches.
826
+ */
827
+ type ListFilterShape<TDocument> = { [K in keyof TDocument & string]?: Validator<TDocument[K]>; };
828
+ /** The `where` argument: each declared filter column, optionally, as a bare value or an operator object. */
829
+ type ListWhere<F> = { [K in keyof F]?: Infer<NonNullable<F[K]>> | ListFilterOperators<Infer<NonNullable<F[K]>>>; };
830
+ /** One `orderBy` entry. `direction` defaults to `"asc"`. */
831
+ interface ListOrderByEntry<O extends string> {
832
+ direction?: "asc" | "desc";
833
+ field: O;
834
+ }
835
+ /** The decoded arguments a {@link defineListArgs} endpoint receives. */
836
+ interface ListArgsValue<F, O extends string> {
837
+ cursor?: null | number | string;
838
+ limit?: number;
839
+ orderBy?: ListOrderByEntry<O>[];
840
+ where?: ListWhere<F>;
841
+ }
842
+ interface DefineListArgsConfig<F, O extends string> {
843
+ /** `limit` applied when the caller omits one. Defaults to 25. */
844
+ readonly defaultLimit?: number;
845
+ /**
846
+ * Allow-list of filterable columns. Publish only columns an index can serve;
847
+ * anything absent here is unreachable from the client.
848
+ */
849
+ readonly filter: F;
850
+ /** Ceiling on `in` / `notIn` array length — one bound parameter each. Defaults to 100. */
851
+ readonly maxInValues?: number;
852
+ /** Ceiling on `limit`; a larger request is clamped down, not rejected. Defaults to 100. */
853
+ readonly maxLimit?: number;
854
+ /** Ceiling on how many `orderBy` entries a request may ask for. Defaults to 8. */
855
+ readonly maxOrderBy?: number;
856
+ /** Allow-list of sortable columns. Pass `[]` to fix the order server-side. */
857
+ readonly orderBy: ReadonlyArray<O>;
858
+ }
859
+ /** The validator map handed to `.input()`. Typed precisely so `args` infers end-to-end. */
860
+ interface ListArgsValidators<F, O extends string> {
861
+ cursor: ColumnValidator<null | number | string | undefined, null | number | string | undefined>;
862
+ limit: ColumnValidator<number | undefined, number | undefined>;
863
+ orderBy: ColumnValidator<ListOrderByEntry<O>[] | undefined, ListOrderByEntry<O>[] | undefined>;
864
+ where: ColumnValidator<ListWhere<F> | undefined, ListWhere<F> | undefined>;
865
+ }
866
+ interface ListArgsSpec<TDocument, F, O extends string> {
867
+ /** Spread into `.input(...)` — `{ cursor, limit, orderBy, where }`. */
868
+ readonly args: ListArgsValidators<F, O>;
869
+ /**
870
+ * Translate the decoded arguments into the `findMany` options object:
871
+ * `limit` clamped into `[1, maxLimit]`, `orderBy` reshaped from
872
+ * `{ field, direction }[]` into `ctx.db`'s `{ column: direction }[]`.
873
+ *
874
+ * Returns `QueryArgs&lt;Doc>` — bound to the table, not free — so a mismatch
875
+ * between what this helper declares and what the table actually holds is a
876
+ * compile error at the `findMany` call site.
877
+ */
878
+ readonly toQueryArgs: (args: ListArgsValue<F, O>) => QueryArgs$2<TDocument>;
879
+ }
880
+ /** Clamp a caller-supplied `limit` into `[1, maxLimit]`; a non-finite value falls back to `fallback`. */
881
+ declare const clampLimit: (limit: number | undefined, fallback: number, maxLimit: number) => number;
882
+ /**
883
+ * Declare the filter / sort / page arguments for a list endpoint, plus the
884
+ * translation into `ctx.db.&lt;table>.findMany(...)` options. See the module docs
885
+ * for the shape and the reasoning behind it.
886
+ *
887
+ * Curried on the document type: `defineListArgs&lt;Doc&lt;"messages">>()({ … })`. The
888
+ * extra `()` buys the thing that matters — with `Doc` bound, `filter` keys and
889
+ * `orderBy` entries are checked against the table's real columns, so a typo or a
890
+ * column renamed out from under the endpoint is a COMPILE error instead of a
891
+ * predicate that silently matches nothing. TypeScript has no partial type-argument
892
+ * inference, so binding `Doc` explicitly while still inferring `F` and `O` from
893
+ * the config requires the second call.
894
+ */
895
+ declare const defineListArgs: <TDocument>() => <F extends ListFilterShape<TDocument>, O extends keyof TDocument & string>(config: DefineListArgsConfig<F, O>) => ListArgsSpec<TDocument, F, O>;
811
896
  /**
812
897
  * Context handed to a {@link MaskFn} (and to {@link MaskOptions.bypass}). The
813
898
  * `auth` shape mirrors RLS's `PolicyContext.auth` one-for-one — same identity
@@ -2297,4 +2382,4 @@ interface StorageContextIn {
2297
2382
  }
2298
2383
  declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
2299
2384
  declare const VERSION = "0.0.0";
2300
- export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, allowAll, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, deny, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isDeny, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules, toWhereInput };
2385
+ export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefineListArgsConfig, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type ListArgsSpec, type ListArgsValidators, type ListArgsValue, type ListFilterOperators, type ListOrderByEntry, type ListWhere, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, allowAll, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, clampLimit, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineListArgs, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, deny, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isDeny, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules, toWhereInput };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/values';
1
+ import { Validator, Infer, ValidatorMap, InferValidatorMap, ColumnValidator, v } from '@lunora/values';
2
2
  export { type ColumnValidator, type GeoPoint, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
3
3
  import { ArgsValidator, InferArgs, RegisteredAction, ExposeConfig, X402ProcedureConfig, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.js";
4
- export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
4
+ export { type AnyApi, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
5
5
  import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
6
6
  export type { LunoraErrorCode } from '@lunora/errors';
7
7
  import { Context, Hono } from 'hono';
8
+ import { WhereOperators, QueryArgs as QueryArgs$2 } from "./data-model.js";
8
9
  import { b as Permission, R as Role, T as TypedDefinePolicyInput, a as Policy, D as DefinePolicyInput, W as WhereInput, c as RlsOptions } from "./packem_shared/types.d-DdYF8E18.js";
9
10
  export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-DdYF8E18.js";
10
11
  import { SearchLanguage, SearchStrategy } from '@lunora/search-core';
11
12
  export { type CronJob, type CronJobsBuilder, type CronScheduleKind, type DailySchedule, type IntervalSchedule, type MonthlySchedule, type WeeklySchedule, cronJobs } from '@lunora/scheduler';
12
- import "./data-model.js";
13
13
  /**
14
14
  * Make any `config.storage` result bucket-aware so `ctx.storage.bucket(name)`
15
15
  * always resolves. A `createBucketStorage(...)` result already carries
@@ -808,6 +808,91 @@ type LifecycleHandler = (context: MutationCtx, event: LifecycleEvent) => Promise
808
808
  declare const onConnect: (handler: LifecycleHandler) => RegisteredLifecycleHook;
809
809
  /** Register a hook that fires once when a client's WebSocket disconnects. */
810
810
  declare const onDisconnect: (handler: LifecycleHandler) => RegisteredLifecycleHook;
811
+ /** Default `limit` when the caller doesn't ask for one. */
812
+ declare const DEFAULT_LIMIT = 25;
813
+ /** Default ceiling on `limit`, so one request can't ask for an unbounded page. */
814
+ declare const DEFAULT_MAX_LIMIT = 100;
815
+ /**
816
+ * Per-field predicate accepted for a declared filter column. An alias of the
817
+ * `ctx.db` `where` DSL's own operator type rather than a copy, so the two cannot
818
+ * drift as operators are added.
819
+ */
820
+ type ListFilterOperators<T> = WhereOperators<T>;
821
+ /**
822
+ * The filter allow-list a caller may declare: a subset of the document's own
823
+ * columns, each with a validator for that column's type. Constraining the KEYS to
824
+ * `keyof Doc` is what turns a typo'd or renamed column into a compile error
825
+ * instead of a predicate that silently never matches.
826
+ */
827
+ type ListFilterShape<TDocument> = { [K in keyof TDocument & string]?: Validator<TDocument[K]>; };
828
+ /** The `where` argument: each declared filter column, optionally, as a bare value or an operator object. */
829
+ type ListWhere<F> = { [K in keyof F]?: Infer<NonNullable<F[K]>> | ListFilterOperators<Infer<NonNullable<F[K]>>>; };
830
+ /** One `orderBy` entry. `direction` defaults to `"asc"`. */
831
+ interface ListOrderByEntry<O extends string> {
832
+ direction?: "asc" | "desc";
833
+ field: O;
834
+ }
835
+ /** The decoded arguments a {@link defineListArgs} endpoint receives. */
836
+ interface ListArgsValue<F, O extends string> {
837
+ cursor?: null | number | string;
838
+ limit?: number;
839
+ orderBy?: ListOrderByEntry<O>[];
840
+ where?: ListWhere<F>;
841
+ }
842
+ interface DefineListArgsConfig<F, O extends string> {
843
+ /** `limit` applied when the caller omits one. Defaults to 25. */
844
+ readonly defaultLimit?: number;
845
+ /**
846
+ * Allow-list of filterable columns. Publish only columns an index can serve;
847
+ * anything absent here is unreachable from the client.
848
+ */
849
+ readonly filter: F;
850
+ /** Ceiling on `in` / `notIn` array length — one bound parameter each. Defaults to 100. */
851
+ readonly maxInValues?: number;
852
+ /** Ceiling on `limit`; a larger request is clamped down, not rejected. Defaults to 100. */
853
+ readonly maxLimit?: number;
854
+ /** Ceiling on how many `orderBy` entries a request may ask for. Defaults to 8. */
855
+ readonly maxOrderBy?: number;
856
+ /** Allow-list of sortable columns. Pass `[]` to fix the order server-side. */
857
+ readonly orderBy: ReadonlyArray<O>;
858
+ }
859
+ /** The validator map handed to `.input()`. Typed precisely so `args` infers end-to-end. */
860
+ interface ListArgsValidators<F, O extends string> {
861
+ cursor: ColumnValidator<null | number | string | undefined, null | number | string | undefined>;
862
+ limit: ColumnValidator<number | undefined, number | undefined>;
863
+ orderBy: ColumnValidator<ListOrderByEntry<O>[] | undefined, ListOrderByEntry<O>[] | undefined>;
864
+ where: ColumnValidator<ListWhere<F> | undefined, ListWhere<F> | undefined>;
865
+ }
866
+ interface ListArgsSpec<TDocument, F, O extends string> {
867
+ /** Spread into `.input(...)` — `{ cursor, limit, orderBy, where }`. */
868
+ readonly args: ListArgsValidators<F, O>;
869
+ /**
870
+ * Translate the decoded arguments into the `findMany` options object:
871
+ * `limit` clamped into `[1, maxLimit]`, `orderBy` reshaped from
872
+ * `{ field, direction }[]` into `ctx.db`'s `{ column: direction }[]`.
873
+ *
874
+ * Returns `QueryArgs&lt;Doc>` — bound to the table, not free — so a mismatch
875
+ * between what this helper declares and what the table actually holds is a
876
+ * compile error at the `findMany` call site.
877
+ */
878
+ readonly toQueryArgs: (args: ListArgsValue<F, O>) => QueryArgs$2<TDocument>;
879
+ }
880
+ /** Clamp a caller-supplied `limit` into `[1, maxLimit]`; a non-finite value falls back to `fallback`. */
881
+ declare const clampLimit: (limit: number | undefined, fallback: number, maxLimit: number) => number;
882
+ /**
883
+ * Declare the filter / sort / page arguments for a list endpoint, plus the
884
+ * translation into `ctx.db.&lt;table>.findMany(...)` options. See the module docs
885
+ * for the shape and the reasoning behind it.
886
+ *
887
+ * Curried on the document type: `defineListArgs&lt;Doc&lt;"messages">>()({ … })`. The
888
+ * extra `()` buys the thing that matters — with `Doc` bound, `filter` keys and
889
+ * `orderBy` entries are checked against the table's real columns, so a typo or a
890
+ * column renamed out from under the endpoint is a COMPILE error instead of a
891
+ * predicate that silently matches nothing. TypeScript has no partial type-argument
892
+ * inference, so binding `Doc` explicitly while still inferring `F` and `O` from
893
+ * the config requires the second call.
894
+ */
895
+ declare const defineListArgs: <TDocument>() => <F extends ListFilterShape<TDocument>, O extends keyof TDocument & string>(config: DefineListArgsConfig<F, O>) => ListArgsSpec<TDocument, F, O>;
811
896
  /**
812
897
  * Context handed to a {@link MaskFn} (and to {@link MaskOptions.bypass}). The
813
898
  * `auth` shape mirrors RLS's `PolicyContext.auth` one-for-one — same identity
@@ -2297,4 +2382,4 @@ interface StorageContextIn {
2297
2382
  }
2298
2383
  declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
2299
2384
  declare const VERSION = "0.0.0";
2300
- export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, allowAll, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, deny, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isDeny, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules, toWhereInput };
2385
+ export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefineListArgsConfig, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExposeConfig, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type ListArgsSpec, type ListArgsValidators, type ListArgsValue, type ListFilterOperators, type ListOrderByEntry, type ListWhere, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, allowAll, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, clampLimit, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineListArgs, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, deny, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isDeny, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules, toWhereInput };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{default as t}from"./packem_shared/asBucketStorage-1pFfH-Tn.mjs";import{initLunora as i}from"./packem_shared/initLunora-CHh1EmR4.mjs";import{createSecrets as a}from"./packem_shared/createSecrets-CgVPiW2C.mjs";import{LunoraEnvError as d,defineEnv as m,redactSecrets as x}from"./packem_shared/LunoraEnvError-CgpI2Mm_.mjs";import{LunoraError as c}from"./packem_shared/LunoraError-LVhdU0Lo.mjs";import{bindOrm as u,bindTableFacade as E}from"./packem_shared/bindOrm-Bp9hsM2q.mjs";import{httpAction as g,httpRoute as R,httpRouter as P,isSafeHeaderValue as h,serveStorageObject as b}from"./packem_shared/httpAction-C14NuF3V.mjs";import{defineIdentity as A}from"./packem_shared/defineIdentity-B7gfAgxx.mjs";import{onConnect as L,onDisconnect as T}from"./packem_shared/onConnect-CEtRmUpJ.mjs";import{defineMigration as C}from"./packem_shared/defineMigration-Bfpwxv2f.mjs";import{defineMutator as M}from"./packem_shared/defineMutator-BgpQ-xUo.mjs";import{composePluginMiddleware as _,defineComponent as k,definePlugin as N,defineSchemaExtension as O,installPlugins as w,mergeSchemaExtension as B}from"./packem_shared/composePluginMiddleware-COr09CXA.mjs";import{PRESENCE_DEFAULT_TTL_MS as W,PRESENCE_TABLE as j,definePresence as H,presenceExtension as J}from"./packem_shared/PRESENCE_DEFAULT_TTL_MS-DA0unh6n.mjs";import{protectPublic as q}from"./packem_shared/protectPublic-BhKewPqm.mjs";import{defineAggregateIndex as G,defineRankIndex as K,defineSchema as Q,defineTable as X,defineVectorIndex as Y}from"./packem_shared/defineAggregateIndex-B-401CrP.mjs";import{defineShape as $}from"./packem_shared/defineShape-Ds8uNqzX.mjs";import{anyApi as oe}from"./types.mjs";import{cronJobs as te}from"@lunora/scheduler";import{ValidationError as ie,v as fe}from"@lunora/values";import{allowAll as pe,deny as de,isDeny as me,toWhereInput as xe}from"./packem_shared/allowAll-BnyNbJZT.mjs";import{buildRlsReadRegistry as ce,composeShapeReadWhere as le}from"./packem_shared/buildRlsReadRegistry-WdiqSj87.mjs";import{createPolicyDsl as Ee,definePermission as Se,definePolicies as ge,definePolicy as Re,defineRole as Pe}from"./packem_shared/createPolicyDsl-sV1swpkD.mjs";import{defineStorageRule as be,defineStorageRules as ye}from"./packem_shared/defineStorageRule-BDu01PUn.mjs";import{mask as Ie}from"./packem_shared/mask-C6Bi78qj.mjs";import{rls as Te}from"./packem_shared/rls-_iVsPvhX.mjs";import{storageRules as Ce}from"./packem_shared/storageRules-BptPZbi8.mjs";const e="0.0.0";export{d as LunoraEnvError,c as LunoraError,W as PRESENCE_DEFAULT_TTL_MS,j as PRESENCE_TABLE,e as VERSION,ie as ValidationError,pe as allowAll,oe as anyApi,t as asBucketStorage,u as bindOrm,E as bindTableFacade,ce as buildRlsReadRegistry,_ as composePluginMiddleware,le as composeShapeReadWhere,Ee as createPolicyDsl,a as createSecrets,te as cronJobs,G as defineAggregateIndex,k as defineComponent,m as defineEnv,A as defineIdentity,C as defineMigration,M as defineMutator,Se as definePermission,N as definePlugin,ge as definePolicies,Re as definePolicy,H as definePresence,K as defineRankIndex,Pe as defineRole,Q as defineSchema,O as defineSchemaExtension,$ as defineShape,be as defineStorageRule,ye as defineStorageRules,X as defineTable,Y as defineVectorIndex,de as deny,g as httpAction,R as httpRoute,P as httpRouter,i as initLunora,w as installPlugins,me as isDeny,h as isSafeHeaderValue,Ie as mask,B as mergeSchemaExtension,L as onConnect,T as onDisconnect,J as presenceExtension,q as protectPublic,x as redactSecrets,Te as rls,b as serveStorageObject,Ce as storageRules,xe as toWhereInput,fe as v};
1
+ import{default as t}from"./packem_shared/asBucketStorage-1pFfH-Tn.mjs";import{initLunora as i}from"./packem_shared/initLunora-CHh1EmR4.mjs";import{createSecrets as p}from"./packem_shared/createSecrets-CgVPiW2C.mjs";import{LunoraEnvError as m,defineEnv as d,redactSecrets as x}from"./packem_shared/LunoraEnvError-CgpI2Mm_.mjs";import{LunoraError as c}from"./packem_shared/LunoraError-LVhdU0Lo.mjs";import{bindOrm as E,bindTableFacade as u}from"./packem_shared/bindOrm-Bp9hsM2q.mjs";import{httpAction as g,httpRoute as R,httpRouter as L,isSafeHeaderValue as P,serveStorageObject as h}from"./packem_shared/httpAction-C14NuF3V.mjs";import{defineIdentity as I}from"./packem_shared/defineIdentity-B7gfAgxx.mjs";import{onConnect as b,onDisconnect as y}from"./packem_shared/onConnect-CEtRmUpJ.mjs";import{DEFAULT_LIMIT as _,DEFAULT_MAX_LIMIT as D,clampLimit as v,defineListArgs as C}from"./packem_shared/DEFAULT_LIMIT-yHJ5O96W.mjs";import{defineMigration as V}from"./packem_shared/defineMigration-Bfpwxv2f.mjs";import{defineMutator as N}from"./packem_shared/defineMutator-BgpQ-xUo.mjs";import{composePluginMiddleware as U,defineComponent as w,definePlugin as B,defineSchemaExtension as W,installPlugins as j,mergeSchemaExtension as H}from"./packem_shared/composePluginMiddleware-COr09CXA.mjs";import{PRESENCE_DEFAULT_TTL_MS as X,PRESENCE_TABLE as q,definePresence as z,presenceExtension as G}from"./packem_shared/PRESENCE_DEFAULT_TTL_MS-DA0unh6n.mjs";import{protectPublic as Q}from"./packem_shared/protectPublic-BhKewPqm.mjs";import{defineAggregateIndex as Z,defineRankIndex as $,defineSchema as ee,defineTable as oe,defineVectorIndex as re}from"./packem_shared/defineAggregateIndex-B-401CrP.mjs";import{defineShape as ne}from"./packem_shared/defineShape-Ds8uNqzX.mjs";import{anyApi as fe}from"./types.mjs";import{cronJobs as ae}from"@lunora/scheduler";import{ValidationError as de,v as xe}from"@lunora/values";import{allowAll as ce,deny as le,isDeny as Ee,toWhereInput as ue}from"./packem_shared/allowAll-BnyNbJZT.mjs";import{buildRlsReadRegistry as ge,composeShapeReadWhere as Re}from"./packem_shared/buildRlsReadRegistry-WdiqSj87.mjs";import{createPolicyDsl as Pe,definePermission as he,definePolicies as Ae,definePolicy as Ie,defineRole as Te}from"./packem_shared/createPolicyDsl-sV1swpkD.mjs";import{defineStorageRule as ye,defineStorageRules as Me}from"./packem_shared/defineStorageRule-BDu01PUn.mjs";import{mask as De}from"./packem_shared/mask-C6Bi78qj.mjs";import{rls as Ce}from"./packem_shared/rls-_iVsPvhX.mjs";import{storageRules as Ve}from"./packem_shared/storageRules-BptPZbi8.mjs";const e="0.0.0";export{_ as DEFAULT_LIMIT,D as DEFAULT_MAX_LIMIT,m as LunoraEnvError,c as LunoraError,X as PRESENCE_DEFAULT_TTL_MS,q as PRESENCE_TABLE,e as VERSION,de as ValidationError,ce as allowAll,fe as anyApi,t as asBucketStorage,E as bindOrm,u as bindTableFacade,ge as buildRlsReadRegistry,v as clampLimit,U as composePluginMiddleware,Re as composeShapeReadWhere,Pe as createPolicyDsl,p as createSecrets,ae as cronJobs,Z as defineAggregateIndex,w as defineComponent,d as defineEnv,I as defineIdentity,C as defineListArgs,V as defineMigration,N as defineMutator,he as definePermission,B as definePlugin,Ae as definePolicies,Ie as definePolicy,z as definePresence,$ as defineRankIndex,Te as defineRole,ee as defineSchema,W as defineSchemaExtension,ne as defineShape,ye as defineStorageRule,Me as defineStorageRules,oe as defineTable,re as defineVectorIndex,le as deny,g as httpAction,R as httpRoute,L as httpRouter,i as initLunora,j as installPlugins,Ee as isDeny,P as isSafeHeaderValue,De as mask,H as mergeSchemaExtension,b as onConnect,y as onDisconnect,G as presenceExtension,Q as protectPublic,x as redactSecrets,Ce as rls,h as serveStorageObject,Ve as storageRules,ue as toWhereInput,xe as v};
@@ -0,0 +1 @@
1
+ import{v as o}from"@lunora/values";const h=25,g=100,y=100,b=8,A=(t,n)=>{const i=e=>o.optional(o.array(e).check(a=>a.length<=n,{message:`at most ${String(n)} values`}));return o.object({contains:o.optional(o.string()),eq:o.optional(t),gt:o.optional(t),gte:o.optional(t),in:i(t),isNull:o.optional(o.boolean()),lt:o.optional(t),lte:o.optional(t),ne:o.optional(t),notIn:i(t)})},L=(t,n,i)=>t===void 0||!Number.isFinite(t)?Math.min(n,i):Math.min(Math.max(1,Math.floor(t)),i),d=(t,n)=>t===void 0||!Number.isFinite(t)?n:Math.max(1,Math.floor(t)),M=new Set(["contains","eq","gt","gte","in","isNull","lt","lte","ne","notIn"]),v=(t,n)=>{if(typeof t!="object"||t===null||Array.isArray(t))return;const i=t,e={};for(const a of M){if(!Object.hasOwn(i,a))continue;const s=i[a];e[a]=Array.isArray(s)?s.slice(0,n):s}return Object.keys(e).length===0?void 0:e},B=(t,n,i)=>{const e={};for(const a of n){if(!Object.hasOwn(t,a))continue;const s=t[a],c=v(s,i);e[a]=c??s}return e},j=()=>t=>{const n=d(t.defaultLimit,h),i=d(t.maxLimit,g),e=d(t.maxInValues,y),a=d(t.maxOrderBy,b),s=new Set(Object.keys(t.filter)),c={};for(const[r,l]of Object.entries(t.filter))c[r]=o.optional(o.union(l,A(l,e)));const f=new Set(t.orderBy),p=t.orderBy.length===0?o.string().check(()=>!1,{message:"no sortable columns are declared for this endpoint"}):o.union(...t.orderBy.map(r=>o.literal(r)));return{args:{cursor:o.optional(o.union(o.string(),o.number(),o.null())),limit:o.optional(o.number()),orderBy:o.optional(o.array(o.object({direction:o.optional(o.union(o.literal("asc"),o.literal("desc"))),field:p}))),where:o.optional(o.object(c))},toQueryArgs:r=>{const l=r.orderBy?.filter(u=>f.has(u.field)).slice(0,a).map(u=>({[u.field]:u.direction??"asc"})),m=r.where===void 0?void 0:B(r.where,s,e);return{...r.cursor===void 0?{}:{cursor:typeof r.cursor=="number"?String(r.cursor):r.cursor},limit:L(r.limit,n,i),...l===void 0||l.length===0?{}:{orderBy:l},...m===void 0?{}:{where:m}}}}};export{h as DEFAULT_LIMIT,y as DEFAULT_MAX_IN_VALUES,g as DEFAULT_MAX_LIMIT,b as DEFAULT_MAX_ORDER_BY,L as clampLimit,j as defineListArgs,d as normalizeBound,B as sanitizeWhere};
package/dist/types.d.mts CHANGED
@@ -1,6 +1,29 @@
1
1
  import { SearchLanguage, SearchStrategy } from '@lunora/search-core';
2
2
  export type { SearchLanguage, SearchStrategy } from '@lunora/search-core';
3
3
  import { ValidatorMap, InferValidatorMap, Id, Validator, Infer } from '@lunora/values';
4
+ /**
5
+ * Declared HTTP caching for an exposed endpoint (`.expose({ cache })`). Lives
6
+ * here, alongside the path/method contract, for the same reason: the runtime
7
+ * WRITES these headers and the OpenAPI emitter DESCRIBES them, and the two must
8
+ * not be able to disagree. Deriving both from {@link cacheControlValue} /
9
+ * {@link cacheVaryValue} makes "the published spec matches what the runtime
10
+ * actually sends" structural rather than a hand-kept invariant.
11
+ */
12
+ interface RestCachePolicy {
13
+ /**
14
+ * Extra request headers this app authenticates on, beyond
15
+ * {@link CREDENTIAL_HEADERS}. Declare these whenever `resolveIdentity` reads
16
+ * something else (`x-api-key`, a tenant header, …): they join both the
17
+ * credential check and the emitted `Vary`. Without them, a caller
18
+ * authenticating that way is treated as anonymous.
19
+ */
20
+ readonly credentialHeaders?: ReadonlyArray<string>;
21
+ readonly maxAge: number;
22
+ readonly scope: "private" | "public";
23
+ readonly staleWhileRevalidate?: number;
24
+ readonly tag?: string;
25
+ readonly vary?: string;
26
+ }
4
27
  /** Map of validators describing a function's args record. Alias of `@lunora/values`' shared {@link ValidatorMap}. */
5
28
  type ArgsValidator = ValidatorMap;
6
29
  /** Infer the args object type from an {@link ArgsValidator}. Alias of `@lunora/values`' shared {@link InferValidatorMap}. */
@@ -435,6 +458,30 @@ interface X402ProcedureConfig {
435
458
  */
436
459
  readonly price: number | string;
437
460
  }
461
+ /**
462
+ * HTTP caching for an exposed REST endpoint, declared as
463
+ * `.expose({ rest: true, cache: { scope: "public", maxAge: 60 } })`. The runtime
464
+ * turns this into `Cache-Control` / `Cache-Tag` / `Vary` response headers, and a
465
+ * `cache.tag` is purgeable through `ctx.cache.purge({ tags: [...] })`.
466
+ *
467
+ * This is NOT equivalent to `httpRoute(...).cacheControl()`, which writes whatever
468
+ * value the author passes with no credential downgrade. That is the unguarded
469
+ * escape hatch; this is the guarded surface.
470
+ *
471
+ * Caching a procedure whose result depends on the caller is how a REST cache
472
+ * turns into a data leak, so `scope` is enforced at runtime rather than trusted:
473
+ * a request that carries credentials (an `Authorization` header or any `Cookie`)
474
+ * is ALWAYS answered `private`, even under `scope: "public"` — see
475
+ * {@link https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control MDN}
476
+ * for what `private` forbids. So a per-user response can never be stored in a
477
+ * shared/edge cache, and the worst a mis-declared `scope` can cost is a missed
478
+ * cache hit. `scope: "public"` additionally emits `Vary: authorization, cookie`
479
+ * so an intermediary can't hand a stored anonymous variant to a signed-in caller.
480
+ *
481
+ * Only ever applied to a cacheable exchange: a `GET` (so `query` procedures — a
482
+ * `mutation` / `action` is `POST`-only) that produced a 2xx.
483
+ */
484
+ type RestCacheConfig = RestCachePolicy;
438
485
  /**
439
486
  * Opt-in public-surface tag attached by the `.expose({ rest: true })` builder
440
487
  * modifier (plan 167). Marks a procedure as deliberately published over the
@@ -444,6 +491,8 @@ interface X402ProcedureConfig {
444
491
  * — a procedure without this tag is unreachable over REST.
445
492
  */
446
493
  interface ExposeConfig {
494
+ /** Opt this endpoint's responses into HTTP caching. Omit to leave them uncached. */
495
+ readonly cache?: RestCacheConfig;
447
496
  /** Publish this procedure over the public REST surface. */
448
497
  readonly rest?: boolean;
449
498
  }
@@ -1857,4 +1906,4 @@ interface ActionCtx {
1857
1906
  */
1858
1907
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1859
1908
  declare const anyApi: AnyApi;
1860
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
1909
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type RestCacheConfig, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
package/dist/types.d.ts CHANGED
@@ -1,6 +1,29 @@
1
1
  import { SearchLanguage, SearchStrategy } from '@lunora/search-core';
2
2
  export type { SearchLanguage, SearchStrategy } from '@lunora/search-core';
3
3
  import { ValidatorMap, InferValidatorMap, Id, Validator, Infer } from '@lunora/values';
4
+ /**
5
+ * Declared HTTP caching for an exposed endpoint (`.expose({ cache })`). Lives
6
+ * here, alongside the path/method contract, for the same reason: the runtime
7
+ * WRITES these headers and the OpenAPI emitter DESCRIBES them, and the two must
8
+ * not be able to disagree. Deriving both from {@link cacheControlValue} /
9
+ * {@link cacheVaryValue} makes "the published spec matches what the runtime
10
+ * actually sends" structural rather than a hand-kept invariant.
11
+ */
12
+ interface RestCachePolicy {
13
+ /**
14
+ * Extra request headers this app authenticates on, beyond
15
+ * {@link CREDENTIAL_HEADERS}. Declare these whenever `resolveIdentity` reads
16
+ * something else (`x-api-key`, a tenant header, …): they join both the
17
+ * credential check and the emitted `Vary`. Without them, a caller
18
+ * authenticating that way is treated as anonymous.
19
+ */
20
+ readonly credentialHeaders?: ReadonlyArray<string>;
21
+ readonly maxAge: number;
22
+ readonly scope: "private" | "public";
23
+ readonly staleWhileRevalidate?: number;
24
+ readonly tag?: string;
25
+ readonly vary?: string;
26
+ }
4
27
  /** Map of validators describing a function's args record. Alias of `@lunora/values`' shared {@link ValidatorMap}. */
5
28
  type ArgsValidator = ValidatorMap;
6
29
  /** Infer the args object type from an {@link ArgsValidator}. Alias of `@lunora/values`' shared {@link InferValidatorMap}. */
@@ -435,6 +458,30 @@ interface X402ProcedureConfig {
435
458
  */
436
459
  readonly price: number | string;
437
460
  }
461
+ /**
462
+ * HTTP caching for an exposed REST endpoint, declared as
463
+ * `.expose({ rest: true, cache: { scope: "public", maxAge: 60 } })`. The runtime
464
+ * turns this into `Cache-Control` / `Cache-Tag` / `Vary` response headers, and a
465
+ * `cache.tag` is purgeable through `ctx.cache.purge({ tags: [...] })`.
466
+ *
467
+ * This is NOT equivalent to `httpRoute(...).cacheControl()`, which writes whatever
468
+ * value the author passes with no credential downgrade. That is the unguarded
469
+ * escape hatch; this is the guarded surface.
470
+ *
471
+ * Caching a procedure whose result depends on the caller is how a REST cache
472
+ * turns into a data leak, so `scope` is enforced at runtime rather than trusted:
473
+ * a request that carries credentials (an `Authorization` header or any `Cookie`)
474
+ * is ALWAYS answered `private`, even under `scope: "public"` — see
475
+ * {@link https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control MDN}
476
+ * for what `private` forbids. So a per-user response can never be stored in a
477
+ * shared/edge cache, and the worst a mis-declared `scope` can cost is a missed
478
+ * cache hit. `scope: "public"` additionally emits `Vary: authorization, cookie`
479
+ * so an intermediary can't hand a stored anonymous variant to a signed-in caller.
480
+ *
481
+ * Only ever applied to a cacheable exchange: a `GET` (so `query` procedures — a
482
+ * `mutation` / `action` is `POST`-only) that produced a 2xx.
483
+ */
484
+ type RestCacheConfig = RestCachePolicy;
438
485
  /**
439
486
  * Opt-in public-surface tag attached by the `.expose({ rest: true })` builder
440
487
  * modifier (plan 167). Marks a procedure as deliberately published over the
@@ -444,6 +491,8 @@ interface X402ProcedureConfig {
444
491
  * — a procedure without this tag is unreachable over REST.
445
492
  */
446
493
  interface ExposeConfig {
494
+ /** Opt this endpoint's responses into HTTP caching. Omit to leave them uncached. */
495
+ readonly cache?: RestCacheConfig;
447
496
  /** Publish this procedure over the public REST surface. */
448
497
  readonly rest?: boolean;
449
498
  }
@@ -1857,4 +1906,4 @@ interface ActionCtx {
1857
1906
  */
1858
1907
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1859
1908
  declare const anyApi: AnyApi;
1860
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
1909
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type RestCacheConfig, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/server",
3
- "version": "1.0.0-alpha.49",
3
+ "version": "1.0.0-alpha.50",
4
4
  "description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
5
5
  "keywords": [
6
6
  "backend",