@lunora/server 1.0.0-alpha.96 → 1.0.0-alpha.98
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 +30 -6
- package/dist/index.d.ts +30 -6
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/buildRlsReadRegistry-C1JR4RYW.mjs +1 -0
- package/dist/packem_shared/mask-BRaPah32.mjs +1 -0
- package/dist/packem_shared/middleware-Dh06LOt-.mjs +1 -0
- package/dist/packem_shared/rls-BL6Noj0b.mjs +1 -0
- package/dist/packem_shared/{storageRules-DHvF6Fjq.mjs → storageRules-D9JLq1Ko.mjs} +1 -1
- package/dist/packem_shared/{types.d-B-pIn8rE.d.mts → types.d-B7FLdYUD.d.mts} +13 -6
- package/dist/packem_shared/{types.d-CdPDEjhz.d.ts → types.d-BCtjbIzl.d.ts} +13 -6
- package/dist/rls/testing.d.mts +13 -5
- package/dist/rls/testing.d.ts +13 -5
- package/dist/rls/testing.mjs +1 -1
- package/dist/types.d.mts +49 -8
- package/dist/types.d.ts +49 -8
- package/package.json +4 -4
- package/dist/packem_shared/buildRlsReadRegistry-CIGmNx0b.mjs +0 -1
- package/dist/packem_shared/mask-pIhIWBcr.mjs +0 -1
- package/dist/packem_shared/middleware-Cz5s6CH-.mjs +0 -1
- package/dist/packem_shared/rls-BjRa5pMm.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Validator, Infer, v, Id, ValidatorMap, InferValidatorMap, ColumnValidator } 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, DurableStreamOptions, RegisteredStream, FunctionKind, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, GlobalBackend, RelationDefinition, OnDeleteAction, SearchLanguage, SearchStrategy, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, DurableObjectJurisdiction, AggregateIndexDefinition, RankIndexDefinition, Secrets, LifecycleEvent, ShardInitEvent, RegisteredLifecycleHook } 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 MutationStorage, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type RunQueryOptions, 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 StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, 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 MutationStorage, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type RetryPolicy, type RunQueryOptions, 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 StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
|
|
5
5
|
import { LunoraError } from '@lunora/errors';
|
|
6
6
|
export { LunoraError, type LunoraErrorCode } from '@lunora/errors';
|
|
7
7
|
import { Context, Hono } from 'hono';
|
|
8
8
|
import { WhereOperators, QueryArgs as QueryArgs$2 } from "./data-model.mjs";
|
|
9
|
-
import { W as WhereInput, a as Policy, b as RlsOptions, c as Permission, R as Role, T as TypedDefinePolicyInput, D as DefinePolicyInput } from "./packem_shared/types.d-
|
|
10
|
-
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-
|
|
9
|
+
import { W as WhereInput, a as Policy, b as RlsOptions, c as Permission, R as Role, T as TypedDefinePolicyInput, D as DefinePolicyInput } from "./packem_shared/types.d-B7FLdYUD.mjs";
|
|
10
|
+
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-B7FLdYUD.mjs";
|
|
11
11
|
export { type CronJob, type CronJobsBuilder, type CronScheduleKind, type DailySchedule, type IntervalSchedule, type MonthlySchedule, type WeeklySchedule, cronJobs } from '@lunora/scheduler';
|
|
12
12
|
/**
|
|
13
13
|
* Options for the `.stream()` terminal. `durable: true` is shorthand for
|
|
@@ -2268,9 +2268,33 @@ interface DatabaseWriterLike {
|
|
|
2268
2268
|
* `ctx`.
|
|
2269
2269
|
*/
|
|
2270
2270
|
type RlsDatabase = DatabaseWriterLike;
|
|
2271
|
-
/**
|
|
2271
|
+
/**
|
|
2272
|
+
* The slice of `ctx.auth` the policy middlewares read.
|
|
2273
|
+
*
|
|
2274
|
+
* `roles` has TWO sources and the effective list is their union, because the two
|
|
2275
|
+
* answer different questions and neither subsumes the other.
|
|
2276
|
+
*
|
|
2277
|
+
* The `roles` CLAIM on the resolved identity ({@link readIdentityRoles}) is what
|
|
2278
|
+
* the identity provider asserted about the caller. `ctx.auth.roles`, set by an
|
|
2279
|
+
* upstream middleware, is what a request-time mapping derived —
|
|
2280
|
+
* `@lunora/cloudflare-access`'s `accessRoles()` is the shipped example: the
|
|
2281
|
+
* Access envelope carries `groups`, never `roles`, and that middleware's entire
|
|
2282
|
+
* job is to map verified groups onto role labels here.
|
|
2283
|
+
*
|
|
2284
|
+
* Reading only the claim silently drops the second, which does not fail loudly —
|
|
2285
|
+
* a role-gated ALLOW branch stops firing and users lose access, and a role-gated
|
|
2286
|
+
* DENY branch stops firing and rows LEAK. `accessRoles` declares its own context
|
|
2287
|
+
* type, so there is no compile-time signal either way.
|
|
2288
|
+
*
|
|
2289
|
+
* What is deliberately absent is the same field on the TEST harness: see
|
|
2290
|
+
* `TestIdentity` in `./testing`. A middleware setting `ctx.auth.roles` is a real
|
|
2291
|
+
* request-path producer; a test setting it directly is a world with no producer
|
|
2292
|
+
* at all, which is how role-gated policies passed their tests while evaluating
|
|
2293
|
+
* against an empty list in production.
|
|
2294
|
+
*/
|
|
2272
2295
|
type AuthLike = {
|
|
2273
2296
|
getIdentity?: () => Promise<Record<string, unknown> | null>;
|
|
2297
|
+
/** Role labels contributed by an upstream middleware, unioned with the identity's `roles` claim. */
|
|
2274
2298
|
roles?: ReadonlyArray<string>;
|
|
2275
2299
|
userId?: null | string;
|
|
2276
2300
|
};
|
|
@@ -2294,6 +2318,7 @@ interface MaskContext<Context = unknown> {
|
|
|
2294
2318
|
/** `true` when any of the request's `roles` grants `permission` (see {@link MaskOptions.roles}). Fails closed for unregistered roles. */
|
|
2295
2319
|
readonly can: (permission: Permission | string) => boolean;
|
|
2296
2320
|
readonly identity?: Record<string, unknown> | null;
|
|
2321
|
+
/** Role labels from the identity's `roles` claim (see `PolicyContext.auth.roles`). */
|
|
2297
2322
|
readonly roles: ReadonlyArray<string>;
|
|
2298
2323
|
readonly userId: null | string;
|
|
2299
2324
|
};
|
|
@@ -2954,8 +2979,6 @@ interface ShapeReadWhereRequest {
|
|
|
2954
2979
|
readonly identity: Record<string, unknown> | null;
|
|
2955
2980
|
/** `true` when the schema is `.rls("required")` — gates the fail-closed branch. */
|
|
2956
2981
|
readonly rlsRequired: boolean;
|
|
2957
|
-
/** Role labels the request carries (drives `auth.can(...)`). */
|
|
2958
|
-
readonly roles: ReadonlyArray<string>;
|
|
2959
2982
|
/** The shape's own predicate (`where(ctx, args)`). */
|
|
2960
2983
|
readonly shapeWhere: WhereInput;
|
|
2961
2984
|
/** Logical table the shape replicates. */
|
|
@@ -3079,6 +3102,7 @@ interface StorageRuleContext<Context = unknown> {
|
|
|
3079
3102
|
readonly auth: {
|
|
3080
3103
|
readonly can: (permission: Permission | string) => boolean;
|
|
3081
3104
|
readonly identity?: Record<string, unknown> | null;
|
|
3105
|
+
/** Role labels from the identity's `roles` claim (see `PolicyContext.auth.roles`). */
|
|
3082
3106
|
readonly roles: ReadonlyArray<string>;
|
|
3083
3107
|
readonly userId: null | string;
|
|
3084
3108
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Validator, Infer, v, Id, ValidatorMap, InferValidatorMap, ColumnValidator } 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, DurableStreamOptions, RegisteredStream, FunctionKind, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, GlobalBackend, RelationDefinition, OnDeleteAction, SearchLanguage, SearchStrategy, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, DurableObjectJurisdiction, AggregateIndexDefinition, RankIndexDefinition, Secrets, LifecycleEvent, ShardInitEvent, RegisteredLifecycleHook } 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 MutationStorage, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type RunQueryOptions, 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 StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, 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 MutationStorage, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type RestCacheConfig, type RetryPolicy, type RunQueryOptions, 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 StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
|
|
5
5
|
import { LunoraError } from '@lunora/errors';
|
|
6
6
|
export { LunoraError, type LunoraErrorCode } from '@lunora/errors';
|
|
7
7
|
import { Context, Hono } from 'hono';
|
|
8
8
|
import { WhereOperators, QueryArgs as QueryArgs$2 } from "./data-model.js";
|
|
9
|
-
import { W as WhereInput, a as Policy, b as RlsOptions, c as Permission, R as Role, T as TypedDefinePolicyInput, D as DefinePolicyInput } from "./packem_shared/types.d-
|
|
10
|
-
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-
|
|
9
|
+
import { W as WhereInput, a as Policy, b as RlsOptions, c as Permission, R as Role, T as TypedDefinePolicyInput, D as DefinePolicyInput } from "./packem_shared/types.d-BCtjbIzl.js";
|
|
10
|
+
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-BCtjbIzl.js";
|
|
11
11
|
export { type CronJob, type CronJobsBuilder, type CronScheduleKind, type DailySchedule, type IntervalSchedule, type MonthlySchedule, type WeeklySchedule, cronJobs } from '@lunora/scheduler';
|
|
12
12
|
/**
|
|
13
13
|
* Options for the `.stream()` terminal. `durable: true` is shorthand for
|
|
@@ -2268,9 +2268,33 @@ interface DatabaseWriterLike {
|
|
|
2268
2268
|
* `ctx`.
|
|
2269
2269
|
*/
|
|
2270
2270
|
type RlsDatabase = DatabaseWriterLike;
|
|
2271
|
-
/**
|
|
2271
|
+
/**
|
|
2272
|
+
* The slice of `ctx.auth` the policy middlewares read.
|
|
2273
|
+
*
|
|
2274
|
+
* `roles` has TWO sources and the effective list is their union, because the two
|
|
2275
|
+
* answer different questions and neither subsumes the other.
|
|
2276
|
+
*
|
|
2277
|
+
* The `roles` CLAIM on the resolved identity ({@link readIdentityRoles}) is what
|
|
2278
|
+
* the identity provider asserted about the caller. `ctx.auth.roles`, set by an
|
|
2279
|
+
* upstream middleware, is what a request-time mapping derived —
|
|
2280
|
+
* `@lunora/cloudflare-access`'s `accessRoles()` is the shipped example: the
|
|
2281
|
+
* Access envelope carries `groups`, never `roles`, and that middleware's entire
|
|
2282
|
+
* job is to map verified groups onto role labels here.
|
|
2283
|
+
*
|
|
2284
|
+
* Reading only the claim silently drops the second, which does not fail loudly —
|
|
2285
|
+
* a role-gated ALLOW branch stops firing and users lose access, and a role-gated
|
|
2286
|
+
* DENY branch stops firing and rows LEAK. `accessRoles` declares its own context
|
|
2287
|
+
* type, so there is no compile-time signal either way.
|
|
2288
|
+
*
|
|
2289
|
+
* What is deliberately absent is the same field on the TEST harness: see
|
|
2290
|
+
* `TestIdentity` in `./testing`. A middleware setting `ctx.auth.roles` is a real
|
|
2291
|
+
* request-path producer; a test setting it directly is a world with no producer
|
|
2292
|
+
* at all, which is how role-gated policies passed their tests while evaluating
|
|
2293
|
+
* against an empty list in production.
|
|
2294
|
+
*/
|
|
2272
2295
|
type AuthLike = {
|
|
2273
2296
|
getIdentity?: () => Promise<Record<string, unknown> | null>;
|
|
2297
|
+
/** Role labels contributed by an upstream middleware, unioned with the identity's `roles` claim. */
|
|
2274
2298
|
roles?: ReadonlyArray<string>;
|
|
2275
2299
|
userId?: null | string;
|
|
2276
2300
|
};
|
|
@@ -2294,6 +2318,7 @@ interface MaskContext<Context = unknown> {
|
|
|
2294
2318
|
/** `true` when any of the request's `roles` grants `permission` (see {@link MaskOptions.roles}). Fails closed for unregistered roles. */
|
|
2295
2319
|
readonly can: (permission: Permission | string) => boolean;
|
|
2296
2320
|
readonly identity?: Record<string, unknown> | null;
|
|
2321
|
+
/** Role labels from the identity's `roles` claim (see `PolicyContext.auth.roles`). */
|
|
2297
2322
|
readonly roles: ReadonlyArray<string>;
|
|
2298
2323
|
readonly userId: null | string;
|
|
2299
2324
|
};
|
|
@@ -2954,8 +2979,6 @@ interface ShapeReadWhereRequest {
|
|
|
2954
2979
|
readonly identity: Record<string, unknown> | null;
|
|
2955
2980
|
/** `true` when the schema is `.rls("required")` — gates the fail-closed branch. */
|
|
2956
2981
|
readonly rlsRequired: boolean;
|
|
2957
|
-
/** Role labels the request carries (drives `auth.can(...)`). */
|
|
2958
|
-
readonly roles: ReadonlyArray<string>;
|
|
2959
2982
|
/** The shape's own predicate (`where(ctx, args)`). */
|
|
2960
2983
|
readonly shapeWhere: WhereInput;
|
|
2961
2984
|
/** Logical table the shape replicates. */
|
|
@@ -3079,6 +3102,7 @@ interface StorageRuleContext<Context = unknown> {
|
|
|
3079
3102
|
readonly auth: {
|
|
3080
3103
|
readonly can: (permission: Permission | string) => boolean;
|
|
3081
3104
|
readonly identity?: Record<string, unknown> | null;
|
|
3105
|
+
/** Role labels from the identity's `roles` claim (see `PolicyContext.auth.roles`). */
|
|
3082
3106
|
readonly roles: ReadonlyArray<string>;
|
|
3083
3107
|
readonly userId: null | string;
|
|
3084
3108
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ACTION_CACHE_DEFAULT_TTL_MS as t,ACTION_CACHE_TABLE as n,actionCacheExtension as i,cacheKeyFor as a,defineActionCache as f}from"./packem_shared/ACTION_CACHE_DEFAULT_TTL_MS-OuQ-AJjz.mjs";import{initLunora as m}from"./packem_shared/initLunora-D5TSiy5j.mjs";import{createSecrets as p}from"./packem_shared/createSecrets-D6rLB42U.mjs";import{flushDeferredDeletes as c,withDeferredDeletes as l}from"./packem_shared/flushDeferredDeletes-DEJXlhop.mjs";import{DOCUMENT_HISTORY_REDACTED_FIELDS as u,DOCUMENT_HISTORY_TABLE as S,defineDocumentHistory as T,documentHistoryExtension as h}from"./packem_shared/DOCUMENT_HISTORY_REDACTED_FIELDS-wgfbacHx.mjs";import{LunoraEnvError as g,defineEnv as R,redactSecrets as _}from"./packem_shared/LunoraEnvError-CXbrsFI8.mjs";import{bindOrm as L,bindTableFacade as C}from"./packem_shared/bindOrm-ChQydkdL.mjs";import{httpAction as y,httpRoute as M,httpRouter as P,isSafeHeaderValue as b,serveStorageObject as F}from"./packem_shared/httpAction-B8X6jXen.mjs";import{defineIdentity as H}from"./packem_shared/defineIdentity-DwkNKwYa.mjs";import{onConnect as U,onDisconnect as k,onShardInit as v}from"./packem_shared/onConnect-BLRoOpv2.mjs";import{DEFAULT_LIMIT as V,DEFAULT_MAX_LIMIT as w,clampLimit as j,defineListArgs as W}from"./packem_shared/DEFAULT_LIMIT-DC-M6faS.mjs";import{defineMigration as J}from"./packem_shared/defineMigration-CXOS0Bvq.mjs";import{defineMutator as Q}from"./packem_shared/defineMutator-DKy8UtbB.mjs";import{c as q,d as z,a as G,b as Z,e as $,f as ee,g as oe,h as re,i as te,j as ne,k as ie,m as ae}from"./packem_shared/plugin-yKCbHnlj.mjs";import{PRESENCE_DEFAULT_TTL_MS as se,PRESENCE_TABLE as me,definePresence as de,presenceExtension as pe}from"./packem_shared/PRESENCE_DEFAULT_TTL_MS-lsooaSaF.mjs";import{protectPublic as ce}from"./packem_shared/protectPublic-Csf6ObbJ.mjs";import{onQueryChange as Ee}from"./packem_shared/onQueryChange-pRK6Dh3g.mjs";import{defineShape as Se}from"./packem_shared/defineShape-BWgwFuMT.mjs";import{anyApi as he}from"./types.mjs";import{LunoraError as ge}from"@lunora/errors";import{cronJobs as _e}from"@lunora/scheduler";import{ValidationError as Le,v as Ce}from"@lunora/values";import{allowAll as ye,deny as Me,isDeny as Pe,toWhereInput as be}from"./packem_shared/allowAll-DkRAgItV.mjs";import{asBucketStorage as Oe}from"./packem_shared/asBucketStorage-BthCnWop.mjs";import{buildMaskRegistry as Ne}from"./packem_shared/buildMaskRegistry-DpWMtalG.mjs";import{buildRlsReadRegistry as ke,composeShapeReadWhere as ve}from"./packem_shared/buildRlsReadRegistry-
|
|
1
|
+
import{ACTION_CACHE_DEFAULT_TTL_MS as t,ACTION_CACHE_TABLE as n,actionCacheExtension as i,cacheKeyFor as a,defineActionCache as f}from"./packem_shared/ACTION_CACHE_DEFAULT_TTL_MS-OuQ-AJjz.mjs";import{initLunora as m}from"./packem_shared/initLunora-D5TSiy5j.mjs";import{createSecrets as p}from"./packem_shared/createSecrets-D6rLB42U.mjs";import{flushDeferredDeletes as c,withDeferredDeletes as l}from"./packem_shared/flushDeferredDeletes-DEJXlhop.mjs";import{DOCUMENT_HISTORY_REDACTED_FIELDS as u,DOCUMENT_HISTORY_TABLE as S,defineDocumentHistory as T,documentHistoryExtension as h}from"./packem_shared/DOCUMENT_HISTORY_REDACTED_FIELDS-wgfbacHx.mjs";import{LunoraEnvError as g,defineEnv as R,redactSecrets as _}from"./packem_shared/LunoraEnvError-CXbrsFI8.mjs";import{bindOrm as L,bindTableFacade as C}from"./packem_shared/bindOrm-ChQydkdL.mjs";import{httpAction as y,httpRoute as M,httpRouter as P,isSafeHeaderValue as b,serveStorageObject as F}from"./packem_shared/httpAction-B8X6jXen.mjs";import{defineIdentity as H}from"./packem_shared/defineIdentity-DwkNKwYa.mjs";import{onConnect as U,onDisconnect as k,onShardInit as v}from"./packem_shared/onConnect-BLRoOpv2.mjs";import{DEFAULT_LIMIT as V,DEFAULT_MAX_LIMIT as w,clampLimit as j,defineListArgs as W}from"./packem_shared/DEFAULT_LIMIT-DC-M6faS.mjs";import{defineMigration as J}from"./packem_shared/defineMigration-CXOS0Bvq.mjs";import{defineMutator as Q}from"./packem_shared/defineMutator-DKy8UtbB.mjs";import{c as q,d as z,a as G,b as Z,e as $,f as ee,g as oe,h as re,i as te,j as ne,k as ie,m as ae}from"./packem_shared/plugin-yKCbHnlj.mjs";import{PRESENCE_DEFAULT_TTL_MS as se,PRESENCE_TABLE as me,definePresence as de,presenceExtension as pe}from"./packem_shared/PRESENCE_DEFAULT_TTL_MS-lsooaSaF.mjs";import{protectPublic as ce}from"./packem_shared/protectPublic-Csf6ObbJ.mjs";import{onQueryChange as Ee}from"./packem_shared/onQueryChange-pRK6Dh3g.mjs";import{defineShape as Se}from"./packem_shared/defineShape-BWgwFuMT.mjs";import{anyApi as he}from"./types.mjs";import{LunoraError as ge}from"@lunora/errors";import{cronJobs as _e}from"@lunora/scheduler";import{ValidationError as Le,v as Ce}from"@lunora/values";import{allowAll as ye,deny as Me,isDeny as Pe,toWhereInput as be}from"./packem_shared/allowAll-DkRAgItV.mjs";import{asBucketStorage as Oe}from"./packem_shared/asBucketStorage-BthCnWop.mjs";import{buildMaskRegistry as Ne}from"./packem_shared/buildMaskRegistry-DpWMtalG.mjs";import{buildRlsReadRegistry as ke,composeShapeReadWhere as ve}from"./packem_shared/buildRlsReadRegistry-C1JR4RYW.mjs";import{createPolicyDsl as Ve,definePermission as we,definePolicies as je,definePolicy as We,defineRole as Ye}from"./packem_shared/createPolicyDsl-BZa6SqLJ.mjs";import{defineStorageRule as Ke,defineStorageRules as Qe}from"./packem_shared/defineStorageRule-Dv4nJE0H.mjs";import{mask as qe}from"./packem_shared/mask-BRaPah32.mjs";import{r as Ge}from"./packem_shared/middleware-Dh06LOt-.mjs";import{storageRules as $e}from"./packem_shared/storageRules-D9JLq1Ko.mjs";const e="0.0.0";export{t as ACTION_CACHE_DEFAULT_TTL_MS,n as ACTION_CACHE_TABLE,V as DEFAULT_LIMIT,w as DEFAULT_MAX_LIMIT,u as DOCUMENT_HISTORY_REDACTED_FIELDS,S as DOCUMENT_HISTORY_TABLE,g as LunoraEnvError,ge as LunoraError,se as PRESENCE_DEFAULT_TTL_MS,me as PRESENCE_TABLE,e as VERSION,Le as ValidationError,i as actionCacheExtension,ye as allowAll,he as anyApi,Oe as asBucketStorage,L as bindOrm,C as bindTableFacade,Ne as buildMaskRegistry,ke as buildRlsReadRegistry,a as cacheKeyFor,j as clampLimit,q as composePluginMiddleware,ve as composeShapeReadWhere,Ve as createPolicyDsl,p as createSecrets,_e as cronJobs,f as defineActionCache,z as defineAggregateIndex,G as defineComponent,T as defineDocumentHistory,R as defineEnv,H as defineIdentity,W as defineListArgs,J as defineMigration,Q as defineMutator,we as definePermission,Z as definePlugin,je as definePolicies,We as definePolicy,de as definePresence,$ as defineRankIndex,Ye as defineRole,ee as defineSchema,oe as defineSchemaExtension,Se as defineShape,Ke as defineStorageRule,Qe as defineStorageRules,re as defineTable,te as defineVectorIndex,Me as deny,h as documentHistoryExtension,c as flushDeferredDeletes,y as httpAction,M as httpRoute,P as httpRouter,ne as indexFieldsFromSchema,m as initLunora,ie as installPlugins,Pe as isDeny,b as isSafeHeaderValue,qe as mask,ae as mergeSchemaExtension,U as onConnect,k as onDisconnect,Ee as onQueryChange,v as onShardInit,pe as presenceExtension,ce as protectPublic,_ as redactSecrets,Ge as rls,F as serveStorageObject,$e as storageRules,be as toWhereInput,Ce as v,l as withDeferredDeletes};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as d,d as f,e as u,f as h}from"./middleware-Dh06LOt-.mjs";import{r as p}from"./policy-tag-V0lqFzgS.mjs";import{deny as g}from"./allowAll-DkRAgItV.mjs";const c=g(),b=s=>{const e=s?.rls?.tags;return e||p(s)},y=(s,e)=>{const o=d(e.roles),n=new Map,r=new Map;for(const t of e.policies){if(t.on!=="read")continue;const a=n.get(t.table)??new Set;if(a.has(t.when))continue;a.add(t.when),n.set(t.table,a);const i=r.get(t.table)??[];i.push(t),r.set(t.table,i)}for(const[t,a]of r){const i=s.get(t)??[];i.push({policies:a,rolePermissions:o}),s.set(t,i)}},l=s=>{const e=s.OR;return Array.isArray(e)&&e.length===0&&Object.keys(s).length===1},R=(s,e)=>!s||Object.keys(s).length===0?e:l(s)||Object.keys(e).length===0?s:{AND:[s,e]},m=(s,e)=>{const o=f(e.identity);return u(s.policies,{auth:{can:h(o,s.rolePermissions),identity:e.identity,roles:o,userId:e.userId},ctx:e.ctx})},T=(s,e)=>{const o=s.byTable.get(e.table);if(!o||o.length===0)return e.rlsRequired&&!e.tablePublic?c:void 0;const n=[];for(const r of o){const t=m(r,e);if(t===void 0)return;l(t)||n.push(t)}return n.length===0?c:n.length===1?n[0]:{OR:n}},W=s=>{const e=new Map,o=new Set;for(const n of s)for(const r of b(n))o.has(r)||(o.add(r),y(e,r));return{byTable:e}},A=(s,e)=>R(T(s,e),e.shapeWhere);export{W as buildRlsReadRegistry,A as composeShapeReadWhere};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as S}from"@lunora/errors";import{f as U}from"./fnv1a-D6VtE8WR.mjs";import{i as L,a as z,o as _,b as G,c as C}from"./middleware-Dh06LOt-.mjs";import{bindTableFacade as H,bindOrm as J}from"./bindOrm-ChQydkdL.mjs";import{tagMaskMiddleware as Q}from"./buildMaskRegistry-DpWMtalG.mjs";const V=(e,i,a)=>{try{return e==="redact"?null:e==="hash"?i==null?i:typeof i=="bigint"?U(i.toString()):U(typeof i=="string"?i:JSON.stringify(i)):e(i,a)}catch{return null}},u=(e,i,a)=>{const d={...e};for(const[y,g]of Object.entries(i))y in d&&(d[y]=V(g,e[y],{...a,column:y,row:e}));return d},j=(e,i,a)=>({...e,page:e.page.map(d=>u(d,i,a))}),D=(e,i,a,d)=>{if(typeof e!="function")return;const y=new Set,g=()=>new Proxy({},{get:()=>w=>(typeof w=="string"&&y.add(w),g())});e(g());for(const w of y)if(w in i)throw new S("MASK_UNSUPPORTED",`${d}() filtering "${a}" by masked column "${w}" is not supported`)},X=(e,i,a,d)=>{const y=e.rankBefore,g=e.rankPageRows,w=(r,n)=>{const t=i.get(r);return t?n.map(o=>u(o,t,a)):n},l=r=>{const n=r?.relationMask;return{...r,relationMask:n===void 0?w:(t,o)=>n(t,w(t,o))}},k=(r,n,t,o)=>{const s=i.get(r);if(!s)return;const c=d?.[r]?.[o]?.[n];if(!c)return;const f=c.find(E=>E in s);if(f!==void 0)throw new S("MASK_UNSUPPORTED",`${t}() reading "${r}" via index "${n}" would order rows by masked column "${f}" — use an index whose declared fields are all unmasked, or unmask the column`)},p=(r,n,t)=>({async*[Symbol.asyncIterator](){for await(const o of{[Symbol.asyncIterator]:()=>r[Symbol.asyncIterator]()})yield u(o,n,a)},collect:async()=>(await r.collect()).map(s=>u(s,n,a)),collectWithScores:async()=>(await r.collectWithScores()).map(s=>{const c=u(s.document,n,a);return"distanceMeters"in s?{distanceMeters:null,document:c}:{document:c,score:s.score}}),filter:o=>p(r.filter(s=>o(u(s,n,a))),n,t),first:async()=>{const o=await r.first();return o?u(o,n,a):null},order:o=>p(r.order(o),n,t),paginate:async o=>j(await r.paginate(o),n,a),take:async o=>(await r.take(o)).map(c=>u(c,n,a)),unique:async()=>{const o=await r.unique();return o?u(o,n,a):null},withIndex:(o,s)=>(k(t,o,"withIndex","index"),D(s,n,t,"withIndex"),p(r.withIndex(o,s),n,t)),withSearchIndex:(o,s)=>(D(s,n,t,"withSearchIndex"),p(r.withSearchIndex(o,s),n,t)),withGeoIndex:(o,s)=>(k(t,o,"withGeoIndex","geo"),p(r.withGeoIndex(o,s),n,t))}),O=async(r,n)=>{if(e.lookupById){const f=await e.lookupById(r,n);return f?{row:f.row,tableName:i.has(f.tableName)?f.tableName:void 0}:{row:null,tableName:void 0}}const t=await e.get(r,n);if(!t)return{row:null,tableName:void 0};const o=n!==void 0&&i.has(n)?[n]:[],s=n===void 0?[...i.keys()]:o,c=await Promise.all(s.map(async f=>(await e.findFirst(f,{limit:1,where:{_id:r}}))?._id===r?f:void 0));return{row:t,tableName:c.find(f=>f!==void 0)}},P=(r,n,t)=>{const o=i.get(r);if(!o)return;const s=n.find(c=>typeof c=="string"&&c in o);if(s!==void 0)throw new S("MASK_UNSUPPORTED",`${t}() over masked column "${s}" on "${r}" is not supported`)},A=new Set;for(const r of i.values())for(const n of Object.keys(r))A.add(n);const R=(r,n,t,o)=>{if(!(!r||typeof r!="object"||Array.isArray(r)))for(const[s,c]of Object.entries(r))K(s,c,n,t,o)},K=(r,n,t,o,s)=>{if(r==="AND"||r==="OR"){for(const c of Array.isArray(n)?n:[])R(c,t,o,s);return}if(r==="NOT"){R(n,t,o,s);return}if(!r.startsWith("__")){if(t.has(r))throw new S("MASK_UNSUPPORTED",`${s}() filtering "${o}" by masked column "${r}" is not supported`);if(C(n))for(const c of Object.values(n))R(c,A,`${o}.${r}`,s)}},B=r=>{const n=i.get(r);return n?new Set(Object.keys(n)):new Set},h=(r,n,t)=>{A.size===0||n===void 0||R(n,B(r),r,t)},F=(r,n,t,o)=>{if(Array.isArray(n)){for(const s of n)if(!(!s||typeof s!="object"||Array.isArray(s))){for(const c of Object.keys(s))if(t.has(c))throw new S("MASK_UNSUPPORTED",`${o}() ordering "${r}" by masked column "${c}" is not supported`)}}},$=(r,n,t)=>{if(!(A.size===0||!n||typeof n!="object"||Array.isArray(n)))for(const[o,s]of Object.entries(n)){if(o==="_count"||!s||typeof s!="object"||Array.isArray(s))continue;const c=s,f=`${r}.${o}`;R(c.where,A,f,t),F(f,c.orderBy,A,t),$(f,c.with,t)}},W=(r,n,t)=>{h(r,n?.where,t),h(r,n?.baseWhere,t),F(r,n?.orderBy,B(r),t),$(r,n?.with,t)},v=r=>r&&typeof r=="object"&&!Array.isArray(r)?r:void 0,M=(r,n,t)=>{const o=v(n);h(r,o?.where,t),h(r,o?.baseWhere,t),$(r,o?.with,t)},I={...e,async deleteWhere(r,n,t){if(h(r,n,"deleteMany({ where })"),e.deleteWhere===void 0)throw new S("INTERNAL",`ctx.db.${r}.deleteMany({ where }) is unavailable: this writer has no where-based delete`);return e.deleteWhere(r,n,t)},async patchWhere(r,n,t){if(h(r,n.where,"patchMany({ where })"),e.patchWhere===void 0)throw new S("INTERNAL",`ctx.db.${r}.patchMany({ where }) is unavailable: this writer has no where-based patch`);return e.patchWhere(r,n,t)},aggregate(r,n){return P(r,[n.field],"aggregate"),h(r,n.where,"aggregate"),e.aggregate(r,n)},count(r,n){const t=v(n),o=t&&("where"in t||"baseWhere"in t||"restrictsCounts"in t)?t.where:n;return h(r,o,"count"),t&&h(r,t.baseWhere,"count"),e.count(r,n)},async findFirst(r,n){W(r,n,"findFirst");const t=await e.findFirst(r,l(n)),o=i.get(r);return t&&o?u(t,o,a):t},async findFirstOrThrow(r,n){W(r,n,"findFirstOrThrow");const t=await e.findFirstOrThrow(r,l(n)),o=i.get(r);return o?u(t,o,a):t},async findMany(r,n){W(r,n,"findMany");const t=await e.findMany(r,l(n)),o=i.get(r);return o?j(t,o,a):t},async get(r,n){const{row:t,tableName:o}=await O(r,n),s=o===void 0?void 0:i.get(o);return!t||!s?t:u(t,s,a)},async lookupById(r,n){const t=await e.lookupById?.(r,n);if(!t)return null;const o=i.get(t.tableName);return{row:o?u(t.row,o,a):t.row,tableName:t.tableName}},groupBy(r,n){return P(r,[...n.by,n.agg?.field],"groupBy"),h(r,n.where,"groupBy"),e.groupBy(r,n)},query(r){const n=e.query(r),t=i.get(r);return t?p(n,t,r):n},async rank(r,n,t){return M(r,t,"rank"),k(r,n,"rank","rank"),e.rank(r,n,t)},async rankPage(r,n,t){M(r,t,"rankPage"),k(r,n,"rankPage","rank");const o=await e.rankPage(r,n,t),s=i.get(r);return s?j(o,s,a):o},..._("rankBefore",y,r=>(n,t,o)=>(M(n,o,"rankBefore"),k(n,t,"rankBefore","rank"),r(n,t,o))),..._("rankPageRows",g,r=>async(n,t,o)=>{M(n,o,"rankPageRows"),k(n,t,"rankPageRows","rank");const s=await r(n,t,o),c=i.get(n);return c?{...s,rows:s.rows.map(f=>({...f,doc:u(f.doc,c,a)}))}:s})},q=I;if(A.size>0)for(const[r,n]of Object.entries(e))G(n)&&(q[r]=H(I,r));return I},b=(e,i={})=>{const a=new Map(Object.entries(e)),d=L(i.roles),y=async({ctx:w,next:l})=>{const k={auth:await z(w.auth??{},d),ctx:w};if(i.bypass?.(k))return l();const p=X(w.db,a,k,i.indexFields),O={db:p},{orm:P}=w;return P!==null&&typeof P=="object"&&(O.orm=J(p)),l({ctx:O})},g=new Map;for(const[w,l]of a)g.set(w,new Set(Object.keys(l)));return Q(y,{columns:g})};export{b as mask};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as W}from"@lunora/errors";import{bindTableFacade as U,bindOrm as T}from"./bindOrm-ChQydkdL.mjs";import{t as j}from"./policy-tag-V0lqFzgS.mjs";import{deny as $}from"./allowAll-DkRAgItV.mjs";const N=["every","is","isNot","none","some"],q=new Set(N),Y=r=>{if(r===null||typeof r!="object"||Array.isArray(r))return!1;const t=Object.keys(r);return t.length>0&&t.every(i=>q.has(i))},M=(r,t,i)=>t?{[r]:i(t)}:{},D=500,R=(r,t,i)=>{const a=t??D;if(r>a)throw new W("BATCH_LIMIT_EXCEEDED",`${i}: batch of ${String(r)} exceeds the limit of ${String(a)} (raise options.limit or chunk the call)`,{status:400})},K=$(),z=Symbol.for("lunora.ctxdb.rls-unwrap"),H=r=>{const t=new Map;for(const i of r){const a=t.get(i.table)??[];a.push(i),t.set(i.table,a)}return t},G=(r,t)=>{const i=[];let a=!1;for(const l of r){if(l.on!=="read")continue;const f=l.when(t);if(f!==void 0){if(f===!0){a=!0;break}f!==!1&&i.push(f)}}if(!a)return i.length===0?K:i.length===1?i[0]:{OR:i}},P=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),Q=["contains","eq","gt","gte","in","isNull","lt","lte","ne","notIn"],p=r=>{const t=typeof r;return t==="number"||t==="string"||t==="bigint"},X=(r,t)=>!("lt"in t&&(!p(r)||!p(t.lt)||r>=t.lt)||"lte"in t&&(!p(r)||!p(t.lte)||r>t.lte)||"gt"in t&&(!p(r)||!p(t.gt)||r<=t.gt)||"gte"in t&&(!p(r)||!p(t.gte)||r<t.gte)),J=(r,t)=>{if("in"in t){const i=t.in;if(!Array.isArray(i)||!i.includes(r))return!1}if("notIn"in t){const i=t.notIn;if(Array.isArray(i)&&i.includes(r))return!1}if("contains"in t){const i=t.contains;if(typeof r!="string"||typeof i!="string"||!r.includes(i))return!1}return!("isNull"in t&&t.isNull===!0!==(r==null))},Z=(r,t)=>"eq"in t&&r!==t.eq||"ne"in t&&r===t.ne?!1:J(r,t)&&X(r,t),x=(r,t,i,a)=>t==="AND"?Array.isArray(i)&&i.every(l=>a(r,l)):t==="OR"?Array.isArray(i)&&i.some(l=>a(r,l)):!a(r,i??{}),C=r=>r==="AND"||r==="OR"||r==="NOT",V=r=>P(r)&&Object.keys(r).every(t=>Q.includes(t)),v=r=>Object.keys(r).some(t=>{const i=r[t];return C(t)?t==="NOT"?v(i??{}):Array.isArray(i)&&i.some(a=>v(a??{})):Y(i)}),B=(r,t)=>{for(const i of Object.keys(t)){const a=t[i];if(C(i)){if(!x(r,i,a,B))return!1;continue}const l=r[i];if(V(a)){if(!Z(l,a))return!1;continue}if(l!==a)return!1}return!0},ee=(r,t,i)=>{const a=r.when({...t,row:i});if(a===void 0||a===!0)return!0;if(a===!1)return!1;if(v(a))throw new W("RELATION_PREDICATE_UNSUPPORTED","relation predicates are not supported in write policies; use a read policy or a flat column check");return B(i,a)},re=(r,t,i)=>{const a=r.when(t);if(a===void 0||a===!0)return i===void 0||ee(r,t,i);if(a===!1)return!1;if(v(a))throw new W("RELATION_PREDICATE_UNSUPPORTED","relation predicates are not supported in write policies; use a read policy or a flat column check");return!t.row||!B(t.row,a)?!1:i===void 0||B(i,a)},_=(r,t,i,a)=>{let l=!1;for(const f of r)if(f.on===t&&(l=!0,!re(f,i,a)))return!1;return l},te=new Set(["baseWhere","relationBaseWhere","restrictsCounts","where"]),ne=(r,t)=>t===void 0?!0:r==="restrictsCounts"?typeof t=="boolean":r==="relationBaseWhere"?typeof t=="function":P(t),se=r=>{const t=Object.keys(r);return t.length===0?!1:t.every(i=>te.has(i)&&ne(i,r[i]))},ie=r=>r===void 0?{}:P(r)&&se(r)?r:{where:r},w=(r,t)=>!t||Object.keys(t).length===0?r:!r||Object.keys(r).length===0?t:{AND:[t,r]},oe=r=>{if(typeof r!="object"||r===null||Array.isArray(r))return!1;const t=r;return typeof t.findMany=="function"&&typeof t.withSearchIndex=="function"},ae=(r,t,i,a)=>{const l=new Map,f=e=>{const n=l.get(e);if(n)return n;const s=i.get(e);if(!s||s.length===0||!s.some(u=>u.on==="read")){const u={baseWhere:void 0,restricts:!1};return l.set(e,u),u}const c={baseWhere:G(s,a),restricts:!0};return l.set(e,c),c},d=e=>f(e).restricts?t:r,y=e=>f(e).baseWhere,O=async(e,n)=>{if(t.lookupById){const h=await t.lookupById(e,n);return h?{row:h.row,tableName:i.has(h.tableName)?h.tableName:void 0}:{row:null,tableName:void 0}}const s=await t.get(e,n);if(!s)return{row:null,tableName:void 0};const o=n!==void 0&&i.has(n)?[n]:[],c=n===void 0?[...i.keys()]:o,u=await Promise.all(c.map(async h=>(await t.findFirst(h,{limit:1,where:{_id:e}}))?._id===e?h:void 0));return{row:s,tableName:u.find(h=>h!==void 0)}},I=async(e,n)=>{const s=await O(e,n);return s.row&&s.tableName!==void 0?{row:s.row,tableName:s.tableName}:void 0},g=async(e,n,s,o,c)=>{const u=await I(e,c);if(!u)return s(r);const h=i.get(u.tableName);if(h){const A=o?o(u.row):void 0;if(!_(h,n,{...a,row:u.row},A))throw new W("FORBIDDEN",`${n} denied by policy`)}return s(t)},b=(e,n)=>{const{baseWhere:s,restricts:o}=f(e);if(o)throw new W("COUNT_RLS_UNSUPPORTED",`${n}() is not supported on "${e}" inside an RLS-restricted context`);return s},E=r.rankBefore,F=r.rankPageRows,k={...r,async count(e,n){const{baseWhere:s,restricts:o}=f(e),c=ie(n);return d(e).count(e,{...c,baseWhere:w(c.baseWhere,s),relationBaseWhere:y,restrictsCounts:(c.restrictsCounts??!1)||o})},delete:(e,n,s)=>g(e,"delete",o=>o.delete(e,n,s),void 0,n),async deleteAll(e,n){const s=Math.max(1,n?.chunkSize??D),{baseWhere:o}=f(e);let c=0;for(;;){const h=(await d(e).findMany(e,{baseWhere:o,limit:s,relationBaseWhere:y})).page.map(A=>String(A._id));if(h.length===0)break;for(const A of h)await g(A,"delete",S=>S.delete(A,void 0,n?.hard===void 0?void 0:{hard:n.hard})),c+=1;if(h.length<s)break}return{deleted:c}},async deleteMany(e,n,s){R(e.length,n?.limit,"deleteMany");for(const o of e)await g(o,"delete",c=>c.delete(o,s),void 0,s);return{deleted:e.length}},async deleteWhere(e,n,s){const{baseWhere:o}=f(e),u=(await d(e).findMany(e,{baseWhere:w(n,o),relationBaseWhere:y})).page.map(h=>String(h._id));return R(u.length,s?.limit,"deleteWhere"),k.deleteMany(u,s)},async findFirst(e,n){const{baseWhere:s}=f(e);return d(e).findFirst(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async findFirstOrThrow(e,n){const{baseWhere:s}=f(e);return d(e).findFirstOrThrow(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async findMany(e,n){const{baseWhere:s}=f(e);return d(e).findMany(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async get(e,n){const s=await O(e,n);if(!s.row)return null;if(s.tableName===void 0)return r.get(e,n);const{baseWhere:o,restricts:c}=f(s.tableName);if(!c)return r.get(e,n);if(!o)return s.row;const u=await t.findFirst(s.tableName,{baseWhere:o,limit:1,where:{_id:e}});return u?._id===e?u:null},async lookupById(e,n){const s=await O(e,n);if(!s.row)return null;if(s.tableName===void 0||!f(s.tableName).restricts)return await r.lookupById?.(e,n)??null;const{baseWhere:o}=f(s.tableName);if(!o)return{row:s.row,tableName:s.tableName};const c=await t.findFirst(s.tableName,{baseWhere:o,limit:1,where:{_id:e}});return c?._id===e?{row:c,tableName:s.tableName}:null},async insert(e,n){const s=i.get(e);if(s){if(!_(s,"insert",{...a,row:n}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insert(e,n)}return r.insert(e,n)},async insertMany(e,n,s){R(n.length,s?.limit,"insertMany");const o=i.get(e);if(o){for(const c of n)if(!_(o,"insert",{...a,row:c}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insertMany(e,n,s)}return r.insertMany(e,n,s)},async insertManyUnsafe(e,n,s){R(n.length,s?.limit,"insertManyUnsafe");const o=i.get(e);if(o){for(const c of n)if(!_(o,"insert",{...a,row:c}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insertManyUnsafe(e,n,s)}return r.insertManyUnsafe(e,n,s)},patch:(e,n,s)=>g(e,"update",o=>o.patch(e,n,s),o=>({...o,...n}),s),async patchMany(e,n,s){R(e.length,n?.limit,"patchMany");for(const o of e)await g(o.id,"update",c=>c.patch(o.id,o.patch,s),c=>({...c,...o.patch}),s);return{patched:e.length}},async patchWhere(e,n,s){const{baseWhere:o}=f(e),u=(await d(e).findMany(e,{baseWhere:w(n.where,o),relationBaseWhere:y})).page.map(h=>({id:String(h._id),patch:n.patch}));return R(u.length,s?.limit,"patchWhere"),k.patchMany(u,s)},query(e){const{baseWhere:n}=f(e),s=d(e).query(e);return n?s.filter(o=>B(o,n)):s},restore:(e,n)=>g(e,"update",async s=>{const o=s.restore??t.restore;if(!o)throw new W("BAD_REQUEST","restore is not supported by this writer");await o(e,n)},void 0,n),replace:(e,n,s)=>g(e,"update",o=>o.replace(e,n,s),o=>({...n,_creationTime:n._creationTime??o._creationTime,_id:o._id}),s),aggregate(e,n){const{baseWhere:s}=f(e);return d(e).aggregate(e,{...n,baseWhere:w(n.baseWhere,s),relationBaseWhere:y})},groupBy(e,n){const{baseWhere:s}=f(e);return d(e).groupBy(e,{...n,baseWhere:w(n.baseWhere,s),relationBaseWhere:y})},rank(e,n,s){const o=b(e,"rank");return d(e).rank(e,n,{...s,baseWhere:w(s.baseWhere,o)})},rankPage(e,n,s){const o=b(e,"rankPage");return d(e).rankPage(e,n,{...s,baseWhere:w(s?.baseWhere,o)})},wipeShard(){throw new W("FORBIDDEN","ctx.db.wipeShard() is unavailable under rls(): a whole-shard erase can't be policy-gated per row, and erasing only policy-visible rows would silently leave data behind. Run it from an internalMutation, or use ctx.db.deleteAll(table) per table.",{status:403})},...M("rankBefore",E,e=>(n,s,o)=>(b(n,"rankBefore"),(d(n).rankBefore??e)(n,s,o))),...M("rankPageRows",F,e=>(n,s,o)=>{const c=b(n,"rankPageRows");return(d(n).rankPageRows??e)(n,s,{...o,baseWhere:w(o?.baseWhere,c)})})},L=k;if(i.size>0)for(const[e,n]of Object.entries(r))oe(n)&&(L[e]=U(k,e));return k},m=r=>typeof r=="string"?r:r.name,ce=r=>{const t=new Map;for(const i of r??[])t.set(i.name,new Set((i.permissions??[]).map(a=>m(a))));return t},fe=(r,t)=>{const i=new Set;for(const a of r)for(const l of t.get(a)??[])i.add(l);return a=>i.has(m(a))},le=["roles","role"],ue=r=>{for(const t of le){const i=r?.[t];if(typeof i=="string"){const a=i.split(",").map(l=>l.trim()).filter(l=>l.length>0);if(a.length>0)return a}if(Array.isArray(i)){const a=i.filter(l=>typeof l=="string"&&l.length>0);if(a.length>0)return a}}return[]},he=async(r,t)=>{const i=await r.getIdentity?.()??null,a=[...new Set([...ue(i),...r.roles??[]])];return{can:fe(a,t),identity:i,roles:a,userId:r.userId??null}},We=(r,t={})=>{const i=H(r),a=ce(t.roles);return j(async({ctx:f,next:d})=>{const y={auth:await he(f.auth??{},a),ctx:f},O=f.db,I=O[z]??O,g=ae(O,I,i,y),b={db:g},{orm:E}=f;return E!==null&&typeof E=="object"&&(b.orm=T(g)),d({ctx:b})},[{policies:r,roles:t.roles??[]}])};export{he as a,oe as b,Y as c,ue as d,G as e,fe as f,_ as g,ce as i,B as m,M as o,m as p,We as r};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as o,g as t,i as m,b as l,m as p,p as d,d as n,f as c,a as h,r as u}from"./middleware-Dh06LOt-.mjs";import"./bindOrm-ChQydkdL.mjs";import"./policy-tag-V0lqFzgS.mjs";import"./allowAll-DkRAgItV.mjs";export{o as computeReadBaseWhere,t as evaluateWrite,m as indexRolePermissions,l as isFacadeEntry,p as matchesWhere,d as permissionName,n as readIdentityRoles,c as resolveCan,h as resolvePolicyAuth,u as rls};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as y}from"@lunora/errors";import{i as U,a as v}from"./middleware-
|
|
1
|
+
import{LunoraError as y}from"@lunora/errors";import{i as U,a as v}from"./middleware-Dh06LOt-.mjs";const D=(o,e)=>o===void 0||e.startsWith(o),k=o=>{const e=o[1],c=typeof e=="object"&&e!==null?e.method:void 0;return typeof c=="string"&&c.toUpperCase()==="PUT"?"write":"read"},E=[["delete","delete"],["download","read"],["generateUploadUrl","write"],["getMetadata","read"],["getSignedUrl",k],["getUrl","read"],["head","read"],["store","write"]],S=(o,e={})=>{const c=U(e.roles);return async({ctx:u,next:f})=>{const w=await v(u.auth??{},c),g=(n,r,s)=>{const i=o.filter(t=>t.on===n&&t.bucket===s);if(i.length===0)return;const a={auth:w,ctx:u,key:r};if(!i.some(t=>D(t.prefix,r)&&t.when(a)===!0))throw new y("FORBIDDEN",`storage ${n} on "${r}" in bucket "${s}" denied by access rule`)},p=n=>{const r=n.bucketName??"default",s={bucketName:r};for(const[a,d]of E){const t=n[a];typeof t=="function"&&(s[a]=(...l)=>{const m=typeof l[0]=="string"?l[0]:"",b=typeof d=="function"?d(l):d;return g(b,m,r),t(...l)})}const{bucket:i}=n;return typeof i=="function"&&(s.bucket=a=>p(i(a))),s},h=u.storage;return h===void 0?f():f({ctx:{storage:p(h)}})}};export{S as storageRules};
|
|
@@ -51,8 +51,12 @@ interface TypedDefinePolicyInput<DM, REL extends Record<keyof DM, object>, T ext
|
|
|
51
51
|
when: (context: PolicyContext<Context, Identity>) => PolicyDecisionOf<DM, REL, T>;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Context handed to a policy. `auth.roles` is the per-request role list,
|
|
55
|
-
*
|
|
54
|
+
* Context handed to a policy. `auth.roles` is the per-request role list, read
|
|
55
|
+
* from the `roles` CLAIM on the resolved identity — a `string[]` or a
|
|
56
|
+
* comma-separated string returned by `WorkerOptions.resolveIdentity` (and
|
|
57
|
+
* validated by `defineIdentity(...)` at the worker's trust boundary). A
|
|
58
|
+
* resolver that forwards no `roles` claim yields no roles, so every
|
|
59
|
+
* role-branched policy is evaluated against `[]`. `auth.can`
|
|
56
60
|
* answers whether any of those roles grants a permission (see
|
|
57
61
|
* {@link Permission} / {@link RlsOptions}). `row` is present only on write
|
|
58
62
|
* policies (`insert`/`update`/`delete`) — for `update` and `delete` it is the
|
|
@@ -117,10 +121,13 @@ interface Permission {
|
|
|
117
121
|
readonly name: string;
|
|
118
122
|
}
|
|
119
123
|
/**
|
|
120
|
-
* A role declaration. Roles are string labels
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
+
* A role declaration. Roles are string labels the request carries in the
|
|
125
|
+
* `roles` claim of its resolved identity — `WorkerOptions.resolveIdentity`
|
|
126
|
+
* forwards every non-`userId` key verbatim, so a resolver returning
|
|
127
|
+
* `{ userId, roles: ["admin"] }` (or the comma-joined `"user,admin"` that
|
|
128
|
+
* better-auth's `admin()` plugin stores) is what puts them there. `permissions`
|
|
129
|
+
* lists the capabilities the role grants — at request time the middleware
|
|
130
|
+
* unions the permissions of every role in `ctx.auth.roles` so a policy can ask
|
|
124
131
|
* `ctx.auth.can(permission)` rather than enumerate roles.
|
|
125
132
|
*/
|
|
126
133
|
interface Role {
|
|
@@ -51,8 +51,12 @@ interface TypedDefinePolicyInput<DM, REL extends Record<keyof DM, object>, T ext
|
|
|
51
51
|
when: (context: PolicyContext<Context, Identity>) => PolicyDecisionOf<DM, REL, T>;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Context handed to a policy. `auth.roles` is the per-request role list,
|
|
55
|
-
*
|
|
54
|
+
* Context handed to a policy. `auth.roles` is the per-request role list, read
|
|
55
|
+
* from the `roles` CLAIM on the resolved identity — a `string[]` or a
|
|
56
|
+
* comma-separated string returned by `WorkerOptions.resolveIdentity` (and
|
|
57
|
+
* validated by `defineIdentity(...)` at the worker's trust boundary). A
|
|
58
|
+
* resolver that forwards no `roles` claim yields no roles, so every
|
|
59
|
+
* role-branched policy is evaluated against `[]`. `auth.can`
|
|
56
60
|
* answers whether any of those roles grants a permission (see
|
|
57
61
|
* {@link Permission} / {@link RlsOptions}). `row` is present only on write
|
|
58
62
|
* policies (`insert`/`update`/`delete`) — for `update` and `delete` it is the
|
|
@@ -117,10 +121,13 @@ interface Permission {
|
|
|
117
121
|
readonly name: string;
|
|
118
122
|
}
|
|
119
123
|
/**
|
|
120
|
-
* A role declaration. Roles are string labels
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
+
* A role declaration. Roles are string labels the request carries in the
|
|
125
|
+
* `roles` claim of its resolved identity — `WorkerOptions.resolveIdentity`
|
|
126
|
+
* forwards every non-`userId` key verbatim, so a resolver returning
|
|
127
|
+
* `{ userId, roles: ["admin"] }` (or the comma-joined `"user,admin"` that
|
|
128
|
+
* better-auth's `admin()` plugin stores) is what puts them there. `permissions`
|
|
129
|
+
* lists the capabilities the role grants — at request time the middleware
|
|
130
|
+
* unions the permissions of every role in `ctx.auth.roles` so a policy can ask
|
|
124
131
|
* `ctx.auth.can(permission)` rather than enumerate roles.
|
|
125
132
|
*/
|
|
126
133
|
interface Role {
|
package/dist/rls/testing.d.mts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { P as PolicyOperation, R as Role, a as Policy } from "../packem_shared/types.d-
|
|
1
|
+
import { P as PolicyOperation, R as Role, a as Policy } from "../packem_shared/types.d-B7FLdYUD.mjs";
|
|
2
2
|
import "../data-model.mjs";
|
|
3
3
|
/**
|
|
4
4
|
* The slice of a request identity a policy reads. Mirrors the
|
|
5
5
|
* `PolicyContext.auth` shape the middleware builds at request time — every
|
|
6
6
|
* field is optional and defaults the same way the middleware defaults it
|
|
7
|
-
* (`userId`/`identity` → `null`, `roles` → `
|
|
7
|
+
* (`userId`/`identity` → `null`, `roles` → the `roles` claim on `identity`).
|
|
8
|
+
*
|
|
9
|
+
* There is deliberately NO separate `roles` field: `auth.roles` is derived from
|
|
10
|
+
* the identity claims by the same `readIdentityRoles` the middleware uses, so
|
|
11
|
+
* the harness cannot set up a world the runtime is unable to produce. Give a
|
|
12
|
+
* role-branched policy its roles the way production does —
|
|
13
|
+
* `.as({ identity: { roles: ["admin"] }, userId: "u1" })`.
|
|
8
14
|
*/
|
|
9
15
|
interface TestIdentity {
|
|
10
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Raw identity claims a policy may branch on (`auth.identity.email`, …).
|
|
18
|
+
* The `roles` claim (a `string[]` or a comma-separated string) is what
|
|
19
|
+
* populates `auth.roles` and backs `auth.can(...)`.
|
|
20
|
+
*/
|
|
11
21
|
identity?: Record<string, unknown> | null;
|
|
12
|
-
/** Role labels the request carries; resolved to permissions via the harness `roles` registry. */
|
|
13
|
-
roles?: ReadonlyArray<string>;
|
|
14
22
|
/** The caller id (`auth.userId`); `null`/omitted is the anonymous caller. */
|
|
15
23
|
userId?: null | string;
|
|
16
24
|
}
|
package/dist/rls/testing.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { P as PolicyOperation, R as Role, a as Policy } from "../packem_shared/types.d-
|
|
1
|
+
import { P as PolicyOperation, R as Role, a as Policy } from "../packem_shared/types.d-BCtjbIzl.js";
|
|
2
2
|
import "../data-model.js";
|
|
3
3
|
/**
|
|
4
4
|
* The slice of a request identity a policy reads. Mirrors the
|
|
5
5
|
* `PolicyContext.auth` shape the middleware builds at request time — every
|
|
6
6
|
* field is optional and defaults the same way the middleware defaults it
|
|
7
|
-
* (`userId`/`identity` → `null`, `roles` → `
|
|
7
|
+
* (`userId`/`identity` → `null`, `roles` → the `roles` claim on `identity`).
|
|
8
|
+
*
|
|
9
|
+
* There is deliberately NO separate `roles` field: `auth.roles` is derived from
|
|
10
|
+
* the identity claims by the same `readIdentityRoles` the middleware uses, so
|
|
11
|
+
* the harness cannot set up a world the runtime is unable to produce. Give a
|
|
12
|
+
* role-branched policy its roles the way production does —
|
|
13
|
+
* `.as({ identity: { roles: ["admin"] }, userId: "u1" })`.
|
|
8
14
|
*/
|
|
9
15
|
interface TestIdentity {
|
|
10
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Raw identity claims a policy may branch on (`auth.identity.email`, …).
|
|
18
|
+
* The `roles` claim (a `string[]` or a comma-separated string) is what
|
|
19
|
+
* populates `auth.roles` and backs `auth.can(...)`.
|
|
20
|
+
*/
|
|
11
21
|
identity?: Record<string, unknown> | null;
|
|
12
|
-
/** Role labels the request carries; resolved to permissions via the harness `roles` registry. */
|
|
13
|
-
roles?: ReadonlyArray<string>;
|
|
14
22
|
/** The caller id (`auth.userId`); `null`/omitted is the anonymous caller. */
|
|
15
23
|
userId?: null | string;
|
|
16
24
|
}
|
package/dist/rls/testing.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as
|
|
1
|
+
import{i as y,d as P,f as W,e as v,m as I,g as R}from"../packem_shared/middleware-Dh06LOt-.mjs";const p=(m,o={})=>{const h=y(o.roles),x=o.ctx??{};return{as:f=>{const c=f??{},i=c.identity??null,l=P(i),u={auth:{can:W(l,h),identity:i,roles:l,userId:c.userId??null},ctx:x},d=(e,r,t,a)=>{const s=m.filter(n=>n.table===r);if(s.length===0)return!0;if(e==="read"){if(!s.some(b=>b.on==="read"))return!0;const n=v(s,u);return n===void 0||I(t??{},n)}return R(s,e,{...u,row:t},a)};return{can:d,cannot:(e,r,t,a)=>!d(e,r,t,a)}}}};export{p as expectPolicy};
|
package/dist/types.d.mts
CHANGED
|
@@ -786,14 +786,26 @@ interface ScheduledFunctionDoc {
|
|
|
786
786
|
attempts?: number;
|
|
787
787
|
/** When the job was enqueued (epoch ms). */
|
|
788
788
|
enqueuedAt: number;
|
|
789
|
-
/**
|
|
790
|
-
|
|
789
|
+
/**
|
|
790
|
+
* Fully-qualified `ns:fn` path of the function to invoke. Absent when the job
|
|
791
|
+
* targets a durable workflow/agent instead — exactly one of `functionPath` /
|
|
792
|
+
* {@link ScheduledFunctionDoc.workflow} is set on any given row.
|
|
793
|
+
*/
|
|
794
|
+
functionPath?: string;
|
|
791
795
|
/** The job's id (the `_scheduled_functions` row id). */
|
|
792
796
|
id: string;
|
|
797
|
+
/** Logical workpool the job is concurrency-gated by, when any. */
|
|
798
|
+
pool?: string;
|
|
793
799
|
/** When the job is scheduled to fire (epoch ms). */
|
|
794
800
|
scheduledFor: number;
|
|
795
801
|
/** Routing hint forwarded so dispatch lands on the right shard. */
|
|
796
802
|
shardKey?: string;
|
|
803
|
+
/**
|
|
804
|
+
* The `WORKFLOW_*`/`AGENT_*` binding a fresh durable instance is started from
|
|
805
|
+
* on fire (the {@link ScheduledFunctionDoc.args} become its `params`). Set
|
|
806
|
+
* instead of {@link ScheduledFunctionDoc.functionPath}.
|
|
807
|
+
*/
|
|
808
|
+
workflow?: string;
|
|
797
809
|
}
|
|
798
810
|
/** Maps each system table name to the document shape its reads return. */
|
|
799
811
|
interface SystemDocMap {
|
|
@@ -1226,22 +1238,51 @@ interface AuthState {
|
|
|
1226
1238
|
}
|
|
1227
1239
|
/**
|
|
1228
1240
|
* A pending scheduled invocation as surfaced by {@link Scheduler.list} /
|
|
1229
|
-
* {@link Scheduler.get}. A clean public mirror of `@lunora/scheduler`'s
|
|
1230
|
-
* `ScheduleRecord
|
|
1231
|
-
*
|
|
1232
|
-
|
|
1241
|
+
* {@link Scheduler.get}. A clean public mirror of `@lunora/scheduler`'s
|
|
1242
|
+
* `ScheduleRecord`, re-declared so the public ctx surface names its own type
|
|
1243
|
+
* rather than re-exporting the scheduler's. It must stay field-for-field
|
|
1244
|
+
* identical: `__tests__/scheduler-mirror.test.ts` asserts mutual assignability
|
|
1245
|
+
* against the real `ScheduleRecord` and fails `lint:types` if either side moves.
|
|
1246
|
+
*/
|
|
1247
|
+
interface RetryPolicy {
|
|
1248
|
+
/** Backoff growth across attempts. Default `"exponential"`. */
|
|
1249
|
+
backoff?: "exponential" | "linear";
|
|
1250
|
+
/** Base delay in milliseconds for the first retry. Default `30_000`. */
|
|
1251
|
+
baseMs?: number;
|
|
1252
|
+
/** Maximum number of dispatch attempts before dead-lettering. Default `5`. */
|
|
1253
|
+
maxAttempts?: number;
|
|
1254
|
+
/** Optional ceiling clamping the computed backoff delay. */
|
|
1255
|
+
maxMs?: number;
|
|
1256
|
+
}
|
|
1233
1257
|
interface ScheduledJob {
|
|
1234
1258
|
args: Record<string, unknown>;
|
|
1235
1259
|
/** Number of dispatch attempts already made (absent until the first retry). */
|
|
1236
1260
|
attempts?: number;
|
|
1237
1261
|
/** When the job was enqueued (epoch ms). */
|
|
1238
1262
|
enqueuedAt: number;
|
|
1239
|
-
|
|
1263
|
+
/**
|
|
1264
|
+
* The `ns:fn` path of the function to dispatch on fire. Absent when the job
|
|
1265
|
+
* targets a durable workflow/agent instead — see {@link ScheduledJob.workflow}.
|
|
1266
|
+
* Exactly one of `functionPath` / `workflow` is set.
|
|
1267
|
+
*/
|
|
1268
|
+
functionPath?: string;
|
|
1240
1269
|
id: string;
|
|
1270
|
+
/** Scheduler/workpool instance the job was enqueued through. Absent for the default instance. */
|
|
1271
|
+
instanceName?: string;
|
|
1272
|
+
/** Logical workpool the job is concurrency-gated by. Absent for plain `runAfter`/`runAt` jobs. */
|
|
1273
|
+
pool?: string;
|
|
1274
|
+
/** Per-job retry policy; absent means the scheduler's built-in defaults. */
|
|
1275
|
+
retry?: RetryPolicy;
|
|
1241
1276
|
/** When the job is scheduled to fire (epoch ms). */
|
|
1242
1277
|
scheduledFor: number;
|
|
1243
1278
|
/** Routing hint forwarded so dispatch lands on the right shard. */
|
|
1244
1279
|
shardKey?: string;
|
|
1280
|
+
/**
|
|
1281
|
+
* The `WORKFLOW_*`/`AGENT_*` binding name a fresh durable instance is started
|
|
1282
|
+
* from on fire (the {@link ScheduledJob.args} become its `params`). Set
|
|
1283
|
+
* instead of {@link ScheduledJob.functionPath}.
|
|
1284
|
+
*/
|
|
1285
|
+
workflow?: string;
|
|
1245
1286
|
}
|
|
1246
1287
|
/**
|
|
1247
1288
|
* A schedulable durable-workflow reference — the generated `workflows.<name>` /
|
|
@@ -2328,4 +2369,4 @@ interface ActionCtx {
|
|
|
2328
2369
|
*/
|
|
2329
2370
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
2330
2371
|
declare const anyApi: AnyApi;
|
|
2331
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type DurableStreamOptions, 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 MutationStorage, 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 RunQueryOptions, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type SearchLanguage, type SearchStrategy, type Secrets, type SecretsStoreSecretLike, type ShardInitEvent, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
|
2372
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type DurableStreamOptions, 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 MutationStorage, 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 RetryPolicy, type RunQueryOptions, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type SearchLanguage, type SearchStrategy, type Secrets, type SecretsStoreSecretLike, type ShardInitEvent, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
package/dist/types.d.ts
CHANGED
|
@@ -786,14 +786,26 @@ interface ScheduledFunctionDoc {
|
|
|
786
786
|
attempts?: number;
|
|
787
787
|
/** When the job was enqueued (epoch ms). */
|
|
788
788
|
enqueuedAt: number;
|
|
789
|
-
/**
|
|
790
|
-
|
|
789
|
+
/**
|
|
790
|
+
* Fully-qualified `ns:fn` path of the function to invoke. Absent when the job
|
|
791
|
+
* targets a durable workflow/agent instead — exactly one of `functionPath` /
|
|
792
|
+
* {@link ScheduledFunctionDoc.workflow} is set on any given row.
|
|
793
|
+
*/
|
|
794
|
+
functionPath?: string;
|
|
791
795
|
/** The job's id (the `_scheduled_functions` row id). */
|
|
792
796
|
id: string;
|
|
797
|
+
/** Logical workpool the job is concurrency-gated by, when any. */
|
|
798
|
+
pool?: string;
|
|
793
799
|
/** When the job is scheduled to fire (epoch ms). */
|
|
794
800
|
scheduledFor: number;
|
|
795
801
|
/** Routing hint forwarded so dispatch lands on the right shard. */
|
|
796
802
|
shardKey?: string;
|
|
803
|
+
/**
|
|
804
|
+
* The `WORKFLOW_*`/`AGENT_*` binding a fresh durable instance is started from
|
|
805
|
+
* on fire (the {@link ScheduledFunctionDoc.args} become its `params`). Set
|
|
806
|
+
* instead of {@link ScheduledFunctionDoc.functionPath}.
|
|
807
|
+
*/
|
|
808
|
+
workflow?: string;
|
|
797
809
|
}
|
|
798
810
|
/** Maps each system table name to the document shape its reads return. */
|
|
799
811
|
interface SystemDocMap {
|
|
@@ -1226,22 +1238,51 @@ interface AuthState {
|
|
|
1226
1238
|
}
|
|
1227
1239
|
/**
|
|
1228
1240
|
* A pending scheduled invocation as surfaced by {@link Scheduler.list} /
|
|
1229
|
-
* {@link Scheduler.get}. A clean public mirror of `@lunora/scheduler`'s
|
|
1230
|
-
* `ScheduleRecord
|
|
1231
|
-
*
|
|
1232
|
-
|
|
1241
|
+
* {@link Scheduler.get}. A clean public mirror of `@lunora/scheduler`'s
|
|
1242
|
+
* `ScheduleRecord`, re-declared so the public ctx surface names its own type
|
|
1243
|
+
* rather than re-exporting the scheduler's. It must stay field-for-field
|
|
1244
|
+
* identical: `__tests__/scheduler-mirror.test.ts` asserts mutual assignability
|
|
1245
|
+
* against the real `ScheduleRecord` and fails `lint:types` if either side moves.
|
|
1246
|
+
*/
|
|
1247
|
+
interface RetryPolicy {
|
|
1248
|
+
/** Backoff growth across attempts. Default `"exponential"`. */
|
|
1249
|
+
backoff?: "exponential" | "linear";
|
|
1250
|
+
/** Base delay in milliseconds for the first retry. Default `30_000`. */
|
|
1251
|
+
baseMs?: number;
|
|
1252
|
+
/** Maximum number of dispatch attempts before dead-lettering. Default `5`. */
|
|
1253
|
+
maxAttempts?: number;
|
|
1254
|
+
/** Optional ceiling clamping the computed backoff delay. */
|
|
1255
|
+
maxMs?: number;
|
|
1256
|
+
}
|
|
1233
1257
|
interface ScheduledJob {
|
|
1234
1258
|
args: Record<string, unknown>;
|
|
1235
1259
|
/** Number of dispatch attempts already made (absent until the first retry). */
|
|
1236
1260
|
attempts?: number;
|
|
1237
1261
|
/** When the job was enqueued (epoch ms). */
|
|
1238
1262
|
enqueuedAt: number;
|
|
1239
|
-
|
|
1263
|
+
/**
|
|
1264
|
+
* The `ns:fn` path of the function to dispatch on fire. Absent when the job
|
|
1265
|
+
* targets a durable workflow/agent instead — see {@link ScheduledJob.workflow}.
|
|
1266
|
+
* Exactly one of `functionPath` / `workflow` is set.
|
|
1267
|
+
*/
|
|
1268
|
+
functionPath?: string;
|
|
1240
1269
|
id: string;
|
|
1270
|
+
/** Scheduler/workpool instance the job was enqueued through. Absent for the default instance. */
|
|
1271
|
+
instanceName?: string;
|
|
1272
|
+
/** Logical workpool the job is concurrency-gated by. Absent for plain `runAfter`/`runAt` jobs. */
|
|
1273
|
+
pool?: string;
|
|
1274
|
+
/** Per-job retry policy; absent means the scheduler's built-in defaults. */
|
|
1275
|
+
retry?: RetryPolicy;
|
|
1241
1276
|
/** When the job is scheduled to fire (epoch ms). */
|
|
1242
1277
|
scheduledFor: number;
|
|
1243
1278
|
/** Routing hint forwarded so dispatch lands on the right shard. */
|
|
1244
1279
|
shardKey?: string;
|
|
1280
|
+
/**
|
|
1281
|
+
* The `WORKFLOW_*`/`AGENT_*` binding name a fresh durable instance is started
|
|
1282
|
+
* from on fire (the {@link ScheduledJob.args} become its `params`). Set
|
|
1283
|
+
* instead of {@link ScheduledJob.functionPath}.
|
|
1284
|
+
*/
|
|
1285
|
+
workflow?: string;
|
|
1245
1286
|
}
|
|
1246
1287
|
/**
|
|
1247
1288
|
* A schedulable durable-workflow reference — the generated `workflows.<name>` /
|
|
@@ -2328,4 +2369,4 @@ interface ActionCtx {
|
|
|
2328
2369
|
*/
|
|
2329
2370
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
2330
2371
|
declare const anyApi: AnyApi;
|
|
2331
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type DurableStreamOptions, 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 MutationStorage, 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 RunQueryOptions, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type SearchLanguage, type SearchStrategy, type Secrets, type SecretsStoreSecretLike, type ShardInitEvent, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
|
2372
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type DurableStreamOptions, 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 MutationStorage, 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 RetryPolicy, type RunQueryOptions, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type SearchLanguage, type SearchStrategy, type Secrets, type SecretsStoreSecretLike, type ShardInitEvent, type ShardMode, type SpanEvaluation, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type StorageObjectBody, type StorageObjectHead, type StorageRange, 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 WorkflowEventDefinition, 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.
|
|
3
|
+
"version": "1.0.0-alpha.98",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -66,9 +66,9 @@
|
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
70
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
71
|
-
"@lunora/values": "1.0.0-alpha.
|
|
69
|
+
"@lunora/errors": "1.0.0-alpha.28",
|
|
70
|
+
"@lunora/scheduler": "1.0.0-alpha.48",
|
|
71
|
+
"@lunora/values": "1.0.0-alpha.36",
|
|
72
72
|
"drizzle-orm": "^0.45.2",
|
|
73
73
|
"hono": "^4.13.1"
|
|
74
74
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as d,c as f,d as h}from"./middleware-Cz5s6CH-.mjs";import{r as p}from"./policy-tag-V0lqFzgS.mjs";import{deny as u}from"./allowAll-DkRAgItV.mjs";const c=u(),g=s=>{const e=s?.rls?.tags;return e||p(s)},b=(s,e)=>{const r=d(e.roles),t=new Map,n=new Map;for(const o of e.policies){if(o.on!=="read")continue;const a=t.get(o.table)??new Set;if(a.has(o.when))continue;a.add(o.when),t.set(o.table,a);const i=n.get(o.table)??[];i.push(o),n.set(o.table,i)}for(const[o,a]of n){const i=s.get(o)??[];i.push({policies:a,rolePermissions:r}),s.set(o,i)}},l=s=>{const e=s.OR;return Array.isArray(e)&&e.length===0&&Object.keys(s).length===1},y=(s,e)=>!s||Object.keys(s).length===0?e:l(s)||Object.keys(e).length===0?s:{AND:[s,e]},R=(s,e)=>f(s.policies,{auth:{can:h(e.roles,s.rolePermissions),identity:e.identity,roles:e.roles,userId:e.userId},ctx:e.ctx}),m=(s,e)=>{const r=s.byTable.get(e.table);if(!r||r.length===0)return e.rlsRequired&&!e.tablePublic?c:void 0;const t=[];for(const n of r){const o=R(n,e);if(o===void 0)return;l(o)||t.push(o)}return t.length===0?c:t.length===1?t[0]:{OR:t}},P=s=>{const e=new Map,r=new Set;for(const t of s)for(const n of g(t))r.has(n)||(r.add(n),b(e,n));return{byTable:e}},W=(s,e)=>y(m(s,e),e.shapeWhere);export{P as buildRlsReadRegistry,W as composeShapeReadWhere};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as P}from"@lunora/errors";import{f as B}from"./fnv1a-D6VtE8WR.mjs";import{bindTableFacade as E,bindOrm as _}from"./bindOrm-ChQydkdL.mjs";import{i as D,a as K,o as v,b as q}from"./middleware-Cz5s6CH-.mjs";import{tagMaskMiddleware as m}from"./buildMaskRegistry-DpWMtalG.mjs";const G=(i,e,c)=>{try{return i==="redact"?null:i==="hash"?e==null?e:typeof e=="bigint"?B(e.toString()):B(typeof e=="string"?e:JSON.stringify(e)):i(e,c)}catch{return null}},a=(i,e,c)=>{const y={...i};for(const[h,g]of Object.entries(e))h in y&&(y[h]=G(g,i[h],{...c,column:h,row:i}));return y},W=(i,e,c)=>({...i,page:i.page.map(y=>a(y,e,c))}),U=(i,e,c,y)=>{if(typeof i!="function")return;const h=new Set,g=()=>new Proxy({},{get:()=>f=>(typeof f=="string"&&h.add(f),g())});i(g());for(const f of h)if(f in e)throw new P("MASK_UNSUPPORTED",`${y}() filtering "${c}" by masked column "${f}" is not supported`)},L=(i,e,c,y)=>{const h=i.rankBefore,g=i.rankPageRows,f=(r,n)=>{const t=e.get(r);return t?n.map(o=>a(o,t,c)):n},p=r=>{const n=r?.relationMask;return{...r,relationMask:n===void 0?f:(t,o)=>n(t,f(t,o))}},k=(r,n,t,o)=>{const s=e.get(r);if(!s)return;const d=y?.[r]?.[o]?.[n];if(!d)return;const w=d.find($=>$ in s);if(w!==void 0)throw new P("MASK_UNSUPPORTED",`${t}() reading "${r}" via index "${n}" would order rows by masked column "${w}" — use an index whose declared fields are all unmasked, or unmask the column`)},l=(r,n,t)=>({async*[Symbol.asyncIterator](){for await(const o of{[Symbol.asyncIterator]:()=>r[Symbol.asyncIterator]()})yield a(o,n,c)},collect:async()=>(await r.collect()).map(s=>a(s,n,c)),collectWithScores:async()=>(await r.collectWithScores()).map(s=>{const d=a(s.document,n,c);return"distanceMeters"in s?{distanceMeters:null,document:d}:{document:d,score:s.score}}),filter:o=>l(r.filter(s=>o(a(s,n,c))),n,t),first:async()=>{const o=await r.first();return o?a(o,n,c):null},order:o=>l(r.order(o),n,t),paginate:async o=>W(await r.paginate(o),n,c),take:async o=>(await r.take(o)).map(d=>a(d,n,c)),unique:async()=>{const o=await r.unique();return o?a(o,n,c):null},withIndex:(o,s)=>(k(t,o,"withIndex","index"),U(s,n,t,"withIndex"),l(r.withIndex(o,s),n,t)),withSearchIndex:(o,s)=>(U(s,n,t,"withSearchIndex"),l(r.withSearchIndex(o,s),n,t)),withGeoIndex:(o,s)=>(k(t,o,"withGeoIndex","geo"),l(r.withGeoIndex(o,s),n,t))}),S=async(r,n)=>{if(i.lookupById){const w=await i.lookupById(r,n);return w?{row:w.row,tableName:e.has(w.tableName)?w.tableName:void 0}:{row:null,tableName:void 0}}const t=await i.get(r,n);if(!t)return{row:null,tableName:void 0};const o=n!==void 0&&e.has(n)?[n]:[],s=n===void 0?[...e.keys()]:o,d=await Promise.all(s.map(async w=>(await i.findFirst(w,{limit:1,where:{_id:r}}))?._id===r?w:void 0));return{row:t,tableName:d.find(w=>w!==void 0)}},M=(r,n,t)=>{const o=e.get(r);if(!o)return;const s=n.find(d=>typeof d=="string"&&d in o);if(s!==void 0)throw new P("MASK_UNSUPPORTED",`${t}() over masked column "${s}" on "${r}" is not supported`)},R=(r,n)=>{if(!(!r||typeof r!="object"||Array.isArray(r)))for(const[t,o]of Object.entries(r))if(t==="AND"||t==="OR"){if(Array.isArray(o))for(const s of o)R(s,n)}else t==="NOT"?R(o,n):t.startsWith("__")||n.add(t)},u=(r,n,t)=>{const o=e.get(r);if(!o||n===void 0)return;const s=new Set;R(n,s);for(const d of s)if(d in o)throw new P("MASK_UNSUPPORTED",`${t}() filtering "${r}" by masked column "${d}" is not supported`)},I=(r,n,t)=>{const o=e.get(r);if(!(!o||!Array.isArray(n))){for(const s of n)if(s&&typeof s=="object"&&!Array.isArray(s)){for(const d of Object.keys(s))if(d in o)throw new P("MASK_UNSUPPORTED",`${t}() ordering "${r}" by masked column "${d}" is not supported`)}}},F=r=>r&&typeof r=="object"&&!Array.isArray(r)?r:void 0,A=(r,n,t)=>{const o=F(n);u(r,o?.where,t),u(r,o?.baseWhere,t)},O={...i,async deleteWhere(r,n,t){if(u(r,n,"deleteMany({ where })"),i.deleteWhere===void 0)throw new P("INTERNAL",`ctx.db.${r}.deleteMany({ where }) is unavailable: this writer has no where-based delete`);return i.deleteWhere(r,n,t)},async patchWhere(r,n,t){if(u(r,n.where,"patchMany({ where })"),i.patchWhere===void 0)throw new P("INTERNAL",`ctx.db.${r}.patchMany({ where }) is unavailable: this writer has no where-based patch`);return i.patchWhere(r,n,t)},aggregate(r,n){return M(r,[n.field],"aggregate"),u(r,n.where,"aggregate"),i.aggregate(r,n)},count(r,n){const t=F(n),o=t&&("where"in t||"baseWhere"in t||"restrictsCounts"in t)?t.where:n;return u(r,o,"count"),t&&u(r,t.baseWhere,"count"),i.count(r,n)},async findFirst(r,n){u(r,n?.where,"findFirst"),u(r,n?.baseWhere,"findFirst"),I(r,n?.orderBy,"findFirst");const t=await i.findFirst(r,p(n)),o=e.get(r);return t&&o?a(t,o,c):t},async findFirstOrThrow(r,n){u(r,n?.where,"findFirstOrThrow"),u(r,n?.baseWhere,"findFirstOrThrow"),I(r,n?.orderBy,"findFirstOrThrow");const t=await i.findFirstOrThrow(r,p(n)),o=e.get(r);return o?a(t,o,c):t},async findMany(r,n){u(r,n?.where,"findMany"),u(r,n?.baseWhere,"findMany"),I(r,n?.orderBy,"findMany");const t=await i.findMany(r,p(n)),o=e.get(r);return o?W(t,o,c):t},async get(r,n){const{row:t,tableName:o}=await S(r,n),s=o===void 0?void 0:e.get(o);return!t||!s?t:a(t,s,c)},async lookupById(r,n){const t=await i.lookupById?.(r,n);if(!t)return null;const o=e.get(t.tableName);return{row:o?a(t.row,o,c):t.row,tableName:t.tableName}},groupBy(r,n){return M(r,[...n.by,n.agg?.field],"groupBy"),u(r,n.where,"groupBy"),i.groupBy(r,n)},query(r){const n=i.query(r),t=e.get(r);return t?l(n,t,r):n},async rank(r,n,t){return A(r,t,"rank"),k(r,n,"rank","rank"),i.rank(r,n,t)},async rankPage(r,n,t){A(r,t,"rankPage"),k(r,n,"rankPage","rank");const o=await i.rankPage(r,n,t),s=e.get(r);return s?W(o,s,c):o},...v("rankBefore",h,r=>(n,t,o)=>(A(n,o,"rankBefore"),k(n,t,"rankBefore","rank"),r(n,t,o))),...v("rankPageRows",g,r=>async(n,t,o)=>{A(n,o,"rankPageRows"),k(n,t,"rankPageRows","rank");const s=await r(n,t,o),d=e.get(n);return d?{...s,rows:s.rows.map(w=>({...w,doc:a(w.doc,d,c)}))}:s})},j=O;for(const r of e.keys())q(i[r])&&(j[r]=E(O,r));return O},V=(i,e={})=>{const c=new Map(Object.entries(i)),y=D(e.roles),h=async({ctx:f,next:p})=>{const k={auth:await K(f.auth??{},y),ctx:f};if(e.bypass?.(k))return p();const l=L(f.db,c,k,e.indexFields),S={db:l},{orm:M}=f;return M!==null&&typeof M=="object"&&(S.orm=_(l)),p({ctx:S})},g=new Map;for(const[f,p]of c)g.set(f,new Set(Object.keys(p)));return m(h,{columns:g})};export{V as mask};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as W}from"@lunora/errors";import{bindTableFacade as L,bindOrm as T}from"./bindOrm-ChQydkdL.mjs";import{t as j}from"./policy-tag-V0lqFzgS.mjs";import{deny as $}from"./allowAll-DkRAgItV.mjs";const S=(r,t,i)=>t?{[r]:i(t)}:{},D=500,B=(r,t,i)=>{const a=t??D;if(r>a)throw new W("BATCH_LIMIT_EXCEEDED",`${i}: batch of ${String(r)} exceeds the limit of ${String(a)} (raise options.limit or chunk the call)`,{status:400})},q=$(),N=Symbol.for("lunora.ctxdb.rls-unwrap"),K=r=>{const t=new Map;for(const i of r){const a=t.get(i.table)??[];a.push(i),t.set(i.table,a)}return t},Y=(r,t)=>{const i=[];let a=!1;for(const h of r){if(h.on!=="read")continue;const f=h.when(t);if(f!==void 0){if(f===!0){a=!0;break}f!==!1&&i.push(f)}}if(!a)return i.length===0?q:i.length===1?i[0]:{OR:i}},P=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),z=["contains","eq","gt","gte","in","isNull","lt","lte","ne","notIn"],p=r=>{const t=typeof r;return t==="number"||t==="string"||t==="bigint"},H=(r,t)=>!("lt"in t&&(!p(r)||!p(t.lt)||r>=t.lt)||"lte"in t&&(!p(r)||!p(t.lte)||r>t.lte)||"gt"in t&&(!p(r)||!p(t.gt)||r<=t.gt)||"gte"in t&&(!p(r)||!p(t.gte)||r<t.gte)),G=(r,t)=>{if("in"in t){const i=t.in;if(!Array.isArray(i)||!i.includes(r))return!1}if("notIn"in t){const i=t.notIn;if(Array.isArray(i)&&i.includes(r))return!1}if("contains"in t){const i=t.contains;if(typeof r!="string"||typeof i!="string"||!r.includes(i))return!1}return!("isNull"in t&&t.isNull===!0!==(r==null))},Q=(r,t)=>"eq"in t&&r!==t.eq||"ne"in t&&r===t.ne?!1:G(r,t)&&H(r,t),X=(r,t,i,a)=>t==="AND"?Array.isArray(i)&&i.every(h=>a(r,h)):t==="OR"?Array.isArray(i)&&i.some(h=>a(r,h)):!a(r,i??{}),C=r=>r==="AND"||r==="OR"||r==="NOT",J=r=>P(r)&&Object.keys(r).every(t=>z.includes(t)),Z=["every","is","isNot","none","some"],x=r=>P(r)&&Object.keys(r).length>0&&Object.keys(r).every(t=>Z.includes(t)),E=r=>Object.keys(r).some(t=>{const i=r[t];return C(t)?t==="NOT"?E(i??{}):Array.isArray(i)&&i.some(a=>E(a??{})):x(i)}),A=(r,t)=>{for(const i of Object.keys(t)){const a=t[i];if(C(i)){if(!X(r,i,a,A))return!1;continue}const h=r[i];if(J(a)){if(!Q(h,a))return!1;continue}if(h!==a)return!1}return!0},V=(r,t,i)=>{const a=r.when({...t,row:i});if(a===void 0||a===!0)return!0;if(a===!1)return!1;if(E(a))throw new W("RELATION_PREDICATE_UNSUPPORTED","relation predicates are not supported in write policies; use a read policy or a flat column check");return A(i,a)},ee=(r,t,i)=>{const a=r.when(t);if(a===void 0||a===!0)return i===void 0||V(r,t,i);if(a===!1)return!1;if(E(a))throw new W("RELATION_PREDICATE_UNSUPPORTED","relation predicates are not supported in write policies; use a read policy or a flat column check");return!t.row||!A(t.row,a)?!1:i===void 0||A(i,a)},_=(r,t,i,a)=>{let h=!1;for(const f of r)if(f.on===t&&(h=!0,!ee(f,i,a)))return!1;return h},re=new Set(["baseWhere","relationBaseWhere","restrictsCounts","where"]),te=(r,t)=>t===void 0?!0:r==="restrictsCounts"?typeof t=="boolean":r==="relationBaseWhere"?typeof t=="function":P(t),ne=r=>{const t=Object.keys(r);return t.length===0?!1:t.every(i=>re.has(i)&&te(i,r[i]))},se=r=>r===void 0?{}:P(r)&&ne(r)?r:{where:r},w=(r,t)=>!t||Object.keys(t).length===0?r:!r||Object.keys(r).length===0?t:{AND:[t,r]},ie=r=>{if(typeof r!="object"||r===null||Array.isArray(r))return!1;const t=r;return typeof t.findMany=="function"&&typeof t.withSearchIndex=="function"},oe=(r,t,i,a)=>{const h=new Map,f=e=>{const n=h.get(e);if(n)return n;const s=i.get(e);if(!s||s.length===0||!s.some(l=>l.on==="read")){const l={baseWhere:void 0,restricts:!1};return h.set(e,l),l}const c={baseWhere:Y(s,a),restricts:!0};return h.set(e,c),c},d=e=>f(e).restricts?t:r,y=e=>f(e).baseWhere,O=async(e,n)=>{if(t.lookupById){const u=await t.lookupById(e,n);return u?{row:u.row,tableName:i.has(u.tableName)?u.tableName:void 0}:{row:null,tableName:void 0}}const s=await t.get(e,n);if(!s)return{row:null,tableName:void 0};const o=n!==void 0&&i.has(n)?[n]:[],c=n===void 0?[...i.keys()]:o,l=await Promise.all(c.map(async u=>(await t.findFirst(u,{limit:1,where:{_id:e}}))?._id===e?u:void 0));return{row:s,tableName:l.find(u=>u!==void 0)}},M=async(e,n)=>{const s=await O(e,n);return s.row&&s.tableName!==void 0?{row:s.row,tableName:s.tableName}:void 0},g=async(e,n,s,o,c)=>{const l=await M(e,c);if(!l)return s(r);const u=i.get(l.tableName);if(u){const k=o?o(l.row):void 0;if(!_(u,n,{...a,row:l.row},k))throw new W("FORBIDDEN",`${n} denied by policy`)}return s(t)},b=(e,n)=>{const{baseWhere:s,restricts:o}=f(e);if(o)throw new W("COUNT_RLS_UNSUPPORTED",`${n}() is not supported on "${e}" inside an RLS-restricted context`);return s},v=r.rankBefore,m=r.rankPageRows,R={...r,async count(e,n){const{baseWhere:s,restricts:o}=f(e),c=se(n);return d(e).count(e,{...c,baseWhere:w(c.baseWhere,s),relationBaseWhere:y,restrictsCounts:(c.restrictsCounts??!1)||o})},delete:(e,n,s)=>g(e,"delete",o=>o.delete(e,n,s),void 0,n),async deleteAll(e,n){const s=Math.max(1,n?.chunkSize??D),{baseWhere:o}=f(e);let c=0;for(;;){const u=(await d(e).findMany(e,{baseWhere:o,limit:s,relationBaseWhere:y})).page.map(k=>String(k._id));if(u.length===0)break;for(const k of u)await g(k,"delete",I=>I.delete(k,void 0,n?.hard===void 0?void 0:{hard:n.hard})),c+=1;if(u.length<s)break}return{deleted:c}},async deleteMany(e,n,s){B(e.length,n?.limit,"deleteMany");for(const o of e)await g(o,"delete",c=>c.delete(o,s),void 0,s);return{deleted:e.length}},async deleteWhere(e,n,s){const{baseWhere:o}=f(e),l=(await d(e).findMany(e,{baseWhere:w(n,o),relationBaseWhere:y})).page.map(u=>String(u._id));return B(l.length,s?.limit,"deleteWhere"),R.deleteMany(l,s)},async findFirst(e,n){const{baseWhere:s}=f(e);return d(e).findFirst(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async findFirstOrThrow(e,n){const{baseWhere:s}=f(e);return d(e).findFirstOrThrow(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async findMany(e,n){const{baseWhere:s}=f(e);return d(e).findMany(e,{...n,baseWhere:w(n?.baseWhere,s),relationBaseWhere:y})},async get(e,n){const s=await O(e,n);if(!s.row)return null;if(s.tableName===void 0)return r.get(e,n);const{baseWhere:o,restricts:c}=f(s.tableName);if(!c)return r.get(e,n);if(!o)return s.row;const l=await t.findFirst(s.tableName,{baseWhere:o,limit:1,where:{_id:e}});return l?._id===e?l:null},async lookupById(e,n){const s=await O(e,n);if(!s.row)return null;if(s.tableName===void 0||!f(s.tableName).restricts)return await r.lookupById?.(e,n)??null;const{baseWhere:o}=f(s.tableName);if(!o)return{row:s.row,tableName:s.tableName};const c=await t.findFirst(s.tableName,{baseWhere:o,limit:1,where:{_id:e}});return c?._id===e?{row:c,tableName:s.tableName}:null},async insert(e,n){const s=i.get(e);if(s){if(!_(s,"insert",{...a,row:n}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insert(e,n)}return r.insert(e,n)},async insertMany(e,n,s){B(n.length,s?.limit,"insertMany");const o=i.get(e);if(o){for(const c of n)if(!_(o,"insert",{...a,row:c}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insertMany(e,n,s)}return r.insertMany(e,n,s)},async insertManyUnsafe(e,n,s){B(n.length,s?.limit,"insertManyUnsafe");const o=i.get(e);if(o){for(const c of n)if(!_(o,"insert",{...a,row:c}))throw new W("FORBIDDEN",`insert on "${e}" denied by policy`);return t.insertManyUnsafe(e,n,s)}return r.insertManyUnsafe(e,n,s)},patch:(e,n,s)=>g(e,"update",o=>o.patch(e,n,s),o=>({...o,...n}),s),async patchMany(e,n,s){B(e.length,n?.limit,"patchMany");for(const o of e)await g(o.id,"update",c=>c.patch(o.id,o.patch,s),c=>({...c,...o.patch}),s);return{patched:e.length}},async patchWhere(e,n,s){const{baseWhere:o}=f(e),l=(await d(e).findMany(e,{baseWhere:w(n.where,o),relationBaseWhere:y})).page.map(u=>({id:String(u._id),patch:n.patch}));return B(l.length,s?.limit,"patchWhere"),R.patchMany(l,s)},query(e){const{baseWhere:n}=f(e),s=d(e).query(e);return n?s.filter(o=>A(o,n)):s},restore:(e,n)=>g(e,"update",async s=>{const o=s.restore??t.restore;if(!o)throw new W("BAD_REQUEST","restore is not supported by this writer");await o(e,n)},void 0,n),replace:(e,n,s)=>g(e,"update",o=>o.replace(e,n,s),o=>({...n,_creationTime:n._creationTime??o._creationTime,_id:o._id}),s),aggregate(e,n){const{baseWhere:s}=f(e);return d(e).aggregate(e,{...n,baseWhere:w(n.baseWhere,s),relationBaseWhere:y})},groupBy(e,n){const{baseWhere:s}=f(e);return d(e).groupBy(e,{...n,baseWhere:w(n.baseWhere,s),relationBaseWhere:y})},rank(e,n,s){const o=b(e,"rank");return d(e).rank(e,n,{...s,baseWhere:w(s.baseWhere,o)})},rankPage(e,n,s){const o=b(e,"rankPage");return d(e).rankPage(e,n,{...s,baseWhere:w(s?.baseWhere,o)})},wipeShard(){throw new W("FORBIDDEN","ctx.db.wipeShard() is unavailable under rls(): a whole-shard erase can't be policy-gated per row, and erasing only policy-visible rows would silently leave data behind. Run it from an internalMutation, or use ctx.db.deleteAll(table) per table.",{status:403})},...S("rankBefore",v,e=>(n,s,o)=>(b(n,"rankBefore"),(d(n).rankBefore??e)(n,s,o))),...S("rankPageRows",m,e=>(n,s,o)=>{const c=b(n,"rankPageRows");return(d(n).rankPageRows??e)(n,s,{...o,baseWhere:w(o?.baseWhere,c)})})},U=R;for(const e of i.keys())ie(r[e])&&(U[e]=L(R,e));return R},F=r=>typeof r=="string"?r:r.name,ae=r=>{const t=new Map;for(const i of r??[])t.set(i.name,new Set((i.permissions??[]).map(a=>F(a))));return t},ce=(r,t)=>{const i=new Set;for(const a of r)for(const h of t.get(a)??[])i.add(h);return a=>i.has(F(a))},fe=async(r,t)=>{const i=r.roles??[];return{can:ce(i,t),identity:await r.getIdentity?.()??null,roles:i,userId:r.userId??null}},ye=(r,t={})=>{const i=K(r),a=ae(t.roles);return j(async({ctx:f,next:d})=>{const y={auth:await fe(f.auth??{},a),ctx:f},O=f.db,M=O[N]??O,g=oe(O,M,i,y),b={db:g},{orm:v}=f;return v!==null&&typeof v=="object"&&(b.orm=T(g)),d({ctx:b})},[{policies:r,roles:t.roles??[]}])};export{fe as a,ie as b,Y as c,ce as d,_ as e,ae as i,A as m,S as o,F as p,ye as r};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./bindOrm-ChQydkdL.mjs";import{c as o,e as m,i as t,b as p,m as l,p as c,d as n,a as d,r as h}from"./middleware-Cz5s6CH-.mjs";import"./policy-tag-V0lqFzgS.mjs";import"./allowAll-DkRAgItV.mjs";export{o as computeReadBaseWhere,m as evaluateWrite,t as indexRolePermissions,p as isFacadeEntry,l as matchesWhere,c as permissionName,n as resolveCan,d as resolvePolicyAuth,h as rls};
|