@lunora/server 1.0.0-alpha.13 → 1.0.0-alpha.15
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 +14 -75
- package/dist/index.d.ts +14 -75
- package/dist/index.mjs +19 -19
- package/dist/packem_shared/{LunoraEnvError-DjFkpkSP.mjs → LunoraEnvError-BGmd1Qs0.mjs} +4 -4
- package/dist/packem_shared/LunoraError-WbxmrpxR.mjs +9 -0
- package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-D8viLY1S.mjs → PRESENCE_DEFAULT_TTL_MS-BtPCiNLW.mjs} +4 -4
- package/dist/packem_shared/{bindOrm-Ce57S3N9.mjs → bindOrm-CNXKgfUa.mjs} +9 -7
- package/dist/packem_shared/{buildRlsReadRegistry-Do1CSBTr.mjs → buildRlsReadRegistry-DFBFLydB.mjs} +1 -1
- package/dist/packem_shared/{composePluginMiddleware-Ck5_TUO8.mjs → composePluginMiddleware-CcTj1_v2.mjs} +9 -6
- package/dist/packem_shared/{createPolicyDsl-De67zPDS.mjs → createPolicyDsl-By3QB4he.mjs} +4 -1
- package/dist/packem_shared/{createSecrets-TsIP9lOa.mjs → createSecrets-DwaR2rNG.mjs} +4 -1
- package/dist/packem_shared/{defineAggregateIndex-ZdyU78gh.mjs → defineAggregateIndex-znq4ygKQ.mjs} +17 -13
- package/dist/packem_shared/{defineIdentity-B_9YD46A.mjs → defineIdentity-DiX4zM9x.mjs} +2 -1
- package/dist/packem_shared/{defineMigration-CAJLr6fx.mjs → defineMigration-Hx01yIht.mjs} +3 -1
- package/dist/packem_shared/{defineShape-CJ27Wx7o.mjs → defineShape-C5scNOrf.mjs} +3 -2
- package/dist/packem_shared/{defineStorageRule-qu0mpilX.mjs → defineStorageRule-B5nL4Z1P.mjs} +4 -1
- package/dist/packem_shared/{httpAction-FLwfsePg.mjs → httpAction-B_16WzMO.mjs} +6 -15
- package/dist/packem_shared/{initLunora-lxwHTEV3.mjs → initLunora-sQUqaejx.mjs} +1 -1
- package/dist/packem_shared/{mask-E8MgAS3N.mjs → mask-Dc8G5Gl7.mjs} +2 -2
- package/dist/packem_shared/{protectPublic-BjFkQ_Or.mjs → protectPublic-BlcGpiRc.mjs} +1 -1
- package/dist/packem_shared/{rls-DhNgKFeW.mjs → rls-3sCJIH6F.mjs} +2 -2
- package/dist/packem_shared/{run-middleware-CYQOuoV6.mjs → run-middleware-I6EiQfxL.mjs} +3 -1
- package/dist/packem_shared/{storageRules-Cje6Woea.mjs → storageRules-6QxzDOcx.mjs} +1 -1
- package/dist/rls/testing.mjs +1 -1
- package/package.json +4 -3
- package/dist/packem_shared/LunoraError-DN7Zhhvu.mjs +0 -54
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,8 @@ import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/va
|
|
|
2
2
|
export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
|
|
3
3
|
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.mjs";
|
|
4
4
|
export { type AnyApi, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.mjs";
|
|
5
|
+
import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
|
|
6
|
+
export type { LunoraErrorCode } from '@lunora/errors';
|
|
5
7
|
import { Context, Hono } from 'hono';
|
|
6
8
|
import { b as Permission, R as Role, T as TypedDefinePolicyInput, a as Policy, D as DefinePolicyInput, W as WhereInput, c as RlsOptions } from "./packem_shared/types.d-BB3pjV0m.mjs";
|
|
7
9
|
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-BB3pjV0m.mjs";
|
|
@@ -226,8 +228,7 @@ interface EnvKeyFailure {
|
|
|
226
228
|
*
|
|
227
229
|
* Named export only (no default) per the repo export convention.
|
|
228
230
|
*/
|
|
229
|
-
declare class LunoraEnvError extends
|
|
230
|
-
override readonly name = "LunoraEnvError";
|
|
231
|
+
declare class LunoraEnvError extends LunoraError$1 {
|
|
231
232
|
readonly failures: ReadonlyArray<EnvKeyFailure>;
|
|
232
233
|
constructor(failures: ReadonlyArray<EnvKeyFailure>);
|
|
233
234
|
}
|
|
@@ -277,63 +278,7 @@ interface EnvAccessor<S extends EnvShape> {
|
|
|
277
278
|
* invalid — lazily on first access of that key, or eagerly via `config.parse(env)`.
|
|
278
279
|
*/
|
|
279
280
|
declare const defineEnv: <S extends EnvShape>(shape: S) => EnvAccessor<S>;
|
|
280
|
-
|
|
281
|
-
* Canonical error type for Lunora procedures and middleware.
|
|
282
|
-
*
|
|
283
|
-
* The runtime's structural error mapper keys off `name === "LunoraError"` plus
|
|
284
|
-
* the numeric `status`, so throwing one of these from a handler or middleware
|
|
285
|
-
* yields the right RPC/HTTP status without any further wiring. `code` carries
|
|
286
|
-
* the machine-readable reason for clients; the optional `data` carries a
|
|
287
|
-
* structured, JSON+wire-encodable payload propagated verbatim to the client
|
|
288
|
-
* (e.g. `{ retryAfterMs }`). Only an explicit `LunoraError`'s `data` crosses the
|
|
289
|
-
* wire — an unhandled throw is still redacted to a generic message server-side.
|
|
290
|
-
*/
|
|
291
|
-
declare const CODE_STATUS: {
|
|
292
|
-
readonly BAD_REQUEST: 400;
|
|
293
|
-
readonly CONFLICT: 409;
|
|
294
|
-
/**
|
|
295
|
-
* `count()` invoked against a table whose context carries an active RLS
|
|
296
|
-
* policy. The operation itself is unsupported in an RLS-restricted reader
|
|
297
|
-
* (kitcn's documented constraint) — the request is well-formed and the
|
|
298
|
-
* caller is authorized, so this is a 422 (semantic conflict) rather than a
|
|
299
|
-
* 403 (policy denial).
|
|
300
|
-
*/
|
|
301
|
-
readonly COUNT_RLS_UNSUPPORTED: 422;
|
|
302
|
-
readonly FORBIDDEN: 403;
|
|
303
|
-
readonly INTERNAL_SERVER_ERROR: 500;
|
|
304
|
-
/**
|
|
305
|
-
* An analytical reduction (`aggregate` / `groupBy`) was invoked over a
|
|
306
|
-
* column that the procedure's `mask()` middleware redacts. A masked column
|
|
307
|
-
* can't be summed, averaged, or grouped without leaking the very values the
|
|
308
|
-
* mask hides (a group key *is* the raw value; an aggregate is computed from
|
|
309
|
-
* it), so the operation fails closed. The request is well-formed and the
|
|
310
|
-
* caller is authorized — this is a 422 (semantic conflict), mirroring
|
|
311
|
-
* `COUNT_RLS_UNSUPPORTED`.
|
|
312
|
-
*/
|
|
313
|
-
readonly MASK_UNSUPPORTED: 422;
|
|
314
|
-
readonly NOT_FOUND: 404;
|
|
315
|
-
readonly NOT_IMPLEMENTED: 501;
|
|
316
|
-
/**
|
|
317
|
-
* A write policy's `when` returned a relation-crossing predicate
|
|
318
|
-
* (`some`/`none`/`every`/`is`/`isNot`). The in-memory write-policy evaluator
|
|
319
|
-
* has no child fetcher and cannot resolve a relation node, so the policy is
|
|
320
|
-
* unsupported as written. Relation predicates are valid in *read* policies
|
|
321
|
-
* and query `where` clauses (the pre-resolver handles them there). The
|
|
322
|
-
* request is well-formed; this is a 422 (semantic conflict), mirroring the
|
|
323
|
-
* sibling `*_UNSUPPORTED` codes.
|
|
324
|
-
*/
|
|
325
|
-
readonly RELATION_PREDICATE_UNSUPPORTED: 422;
|
|
326
|
-
readonly TOO_MANY_REQUESTS: 429;
|
|
327
|
-
readonly UNAUTHORIZED: 401;
|
|
328
|
-
readonly UNPROCESSABLE: 422;
|
|
329
|
-
};
|
|
330
|
-
type LunoraErrorCode = keyof typeof CODE_STATUS;
|
|
331
|
-
declare class LunoraError extends Error {
|
|
332
|
-
override readonly name = "LunoraError";
|
|
333
|
-
readonly code: LunoraErrorCode;
|
|
334
|
-
readonly status: number;
|
|
335
|
-
/** Structured, JSON+wire-encodable payload surfaced to the client alongside `code`. */
|
|
336
|
-
readonly data?: unknown;
|
|
281
|
+
declare class LunoraError extends LunoraError$1 {
|
|
337
282
|
constructor(code: LunoraErrorCode, message?: string, data?: unknown);
|
|
338
283
|
}
|
|
339
284
|
/**
|
|
@@ -659,6 +604,15 @@ interface ContextWithStorage {
|
|
|
659
604
|
storage: StorageDownloader;
|
|
660
605
|
}
|
|
661
606
|
/**
|
|
607
|
+
* True when `value` is safe to use as an HTTP header field-value: no CR, LF, or
|
|
608
|
+
* NUL. Guards against response-header injection / `Headers`-construction throws
|
|
609
|
+
* when reflecting attacker-influenced object metadata (e.g. a stored
|
|
610
|
+
* `Content-Type`). Exported (see the `export {}` at the file end) so an `httpAction`
|
|
611
|
+
* handler can guard a request-derived header value before writing it — the fix the
|
|
612
|
+
* `http_action_response_header_injection` advisor lint points to.
|
|
613
|
+
*/
|
|
614
|
+
declare const isSafeHeaderValue: (value: string) => boolean;
|
|
615
|
+
/**
|
|
662
616
|
* Stream a stored object as an HTTP {@link Response} from an `httpAction`
|
|
663
617
|
* handler, with correct `Content-Type`, `ETag`, and `Accept-Ranges: bytes`.
|
|
664
618
|
* Honors a single-range `Range` request → **206 Partial Content** with
|
|
@@ -928,21 +882,6 @@ interface MaskContextIn {
|
|
|
928
882
|
* includes this middleware — opt-in, never global (the same invariant as RLS).
|
|
929
883
|
*/
|
|
930
884
|
declare const mask: <Context extends MaskContextIn = MaskContextIn>(policies: MaskPolicies<Context>, options?: MaskOptions<Context>) => Middleware<Context, Context>;
|
|
931
|
-
/**
|
|
932
|
-
* Online data-migration authoring API.
|
|
933
|
-
*
|
|
934
|
-
* `defineMigration` declares a per-document backfill over one table: `up`
|
|
935
|
-
* transforms every existing row, `down` (optional) reverses it. Unlike the D1
|
|
936
|
-
* SQL schema migrations in `@lunora/d1`, these run *inside each shard's*
|
|
937
|
-
* Durable Object against live documents, in keyset batches, and are resumable —
|
|
938
|
-
* the per-shard runner in `@lunora/do` tracks progress in a reserved
|
|
939
|
-
* `__lunora_migrations` table so an interrupted run picks up where it stopped.
|
|
940
|
-
*
|
|
941
|
-
* The returned object carries a `__lunoraMigration` brand so codegen can
|
|
942
|
-
* discover declarations through the type checker (mirroring the procedure
|
|
943
|
-
* builder's `__lunoraProcedure` brand) and emit them into a `LUNORA_MIGRATIONS`
|
|
944
|
-
* registry the DO and CLI look migrations up by id.
|
|
945
|
-
*/
|
|
946
885
|
/** A document handed to a migration transform: the stored row including `_id`/`_creationTime`. */
|
|
947
886
|
type MigrationDocument = Record<string, unknown>;
|
|
948
887
|
/**
|
|
@@ -2052,4 +1991,4 @@ interface StorageContextIn {
|
|
|
2052
1991
|
}
|
|
2053
1992
|
declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
|
|
2054
1993
|
declare const VERSION = "0.0.0";
|
|
2055
|
-
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type
|
|
1994
|
+
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { Validator, Infer, ValidatorMap, InferValidatorMap, v } from '@lunora/va
|
|
|
2
2
|
export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
|
|
3
3
|
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.js";
|
|
4
4
|
export { type AnyApi, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionVisibility, type IndexDefinition, type IndexRangeBuilder, type LifecycleEventKind, type LunoraLogger, type PaginationOptions, type PaginationResult, type RankSortKey, type ReadOnlyStorage, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerCtx, type TriggerDatabase, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorMatch, type VectorMatches, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi } from "./types.js";
|
|
5
|
+
import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
|
|
6
|
+
export type { LunoraErrorCode } from '@lunora/errors';
|
|
5
7
|
import { Context, Hono } from 'hono';
|
|
6
8
|
import { b as Permission, R as Role, T as TypedDefinePolicyInput, a as Policy, D as DefinePolicyInput, W as WhereInput, c as RlsOptions } from "./packem_shared/types.d-Cxl6ndhm.js";
|
|
7
9
|
export type { d as PolicyContext, e as PolicyDecision, f as PolicyDecisionOf, P as PolicyOperation } from "./packem_shared/types.d-Cxl6ndhm.js";
|
|
@@ -226,8 +228,7 @@ interface EnvKeyFailure {
|
|
|
226
228
|
*
|
|
227
229
|
* Named export only (no default) per the repo export convention.
|
|
228
230
|
*/
|
|
229
|
-
declare class LunoraEnvError extends
|
|
230
|
-
override readonly name = "LunoraEnvError";
|
|
231
|
+
declare class LunoraEnvError extends LunoraError$1 {
|
|
231
232
|
readonly failures: ReadonlyArray<EnvKeyFailure>;
|
|
232
233
|
constructor(failures: ReadonlyArray<EnvKeyFailure>);
|
|
233
234
|
}
|
|
@@ -277,63 +278,7 @@ interface EnvAccessor<S extends EnvShape> {
|
|
|
277
278
|
* invalid — lazily on first access of that key, or eagerly via `config.parse(env)`.
|
|
278
279
|
*/
|
|
279
280
|
declare const defineEnv: <S extends EnvShape>(shape: S) => EnvAccessor<S>;
|
|
280
|
-
|
|
281
|
-
* Canonical error type for Lunora procedures and middleware.
|
|
282
|
-
*
|
|
283
|
-
* The runtime's structural error mapper keys off `name === "LunoraError"` plus
|
|
284
|
-
* the numeric `status`, so throwing one of these from a handler or middleware
|
|
285
|
-
* yields the right RPC/HTTP status without any further wiring. `code` carries
|
|
286
|
-
* the machine-readable reason for clients; the optional `data` carries a
|
|
287
|
-
* structured, JSON+wire-encodable payload propagated verbatim to the client
|
|
288
|
-
* (e.g. `{ retryAfterMs }`). Only an explicit `LunoraError`'s `data` crosses the
|
|
289
|
-
* wire — an unhandled throw is still redacted to a generic message server-side.
|
|
290
|
-
*/
|
|
291
|
-
declare const CODE_STATUS: {
|
|
292
|
-
readonly BAD_REQUEST: 400;
|
|
293
|
-
readonly CONFLICT: 409;
|
|
294
|
-
/**
|
|
295
|
-
* `count()` invoked against a table whose context carries an active RLS
|
|
296
|
-
* policy. The operation itself is unsupported in an RLS-restricted reader
|
|
297
|
-
* (kitcn's documented constraint) — the request is well-formed and the
|
|
298
|
-
* caller is authorized, so this is a 422 (semantic conflict) rather than a
|
|
299
|
-
* 403 (policy denial).
|
|
300
|
-
*/
|
|
301
|
-
readonly COUNT_RLS_UNSUPPORTED: 422;
|
|
302
|
-
readonly FORBIDDEN: 403;
|
|
303
|
-
readonly INTERNAL_SERVER_ERROR: 500;
|
|
304
|
-
/**
|
|
305
|
-
* An analytical reduction (`aggregate` / `groupBy`) was invoked over a
|
|
306
|
-
* column that the procedure's `mask()` middleware redacts. A masked column
|
|
307
|
-
* can't be summed, averaged, or grouped without leaking the very values the
|
|
308
|
-
* mask hides (a group key *is* the raw value; an aggregate is computed from
|
|
309
|
-
* it), so the operation fails closed. The request is well-formed and the
|
|
310
|
-
* caller is authorized — this is a 422 (semantic conflict), mirroring
|
|
311
|
-
* `COUNT_RLS_UNSUPPORTED`.
|
|
312
|
-
*/
|
|
313
|
-
readonly MASK_UNSUPPORTED: 422;
|
|
314
|
-
readonly NOT_FOUND: 404;
|
|
315
|
-
readonly NOT_IMPLEMENTED: 501;
|
|
316
|
-
/**
|
|
317
|
-
* A write policy's `when` returned a relation-crossing predicate
|
|
318
|
-
* (`some`/`none`/`every`/`is`/`isNot`). The in-memory write-policy evaluator
|
|
319
|
-
* has no child fetcher and cannot resolve a relation node, so the policy is
|
|
320
|
-
* unsupported as written. Relation predicates are valid in *read* policies
|
|
321
|
-
* and query `where` clauses (the pre-resolver handles them there). The
|
|
322
|
-
* request is well-formed; this is a 422 (semantic conflict), mirroring the
|
|
323
|
-
* sibling `*_UNSUPPORTED` codes.
|
|
324
|
-
*/
|
|
325
|
-
readonly RELATION_PREDICATE_UNSUPPORTED: 422;
|
|
326
|
-
readonly TOO_MANY_REQUESTS: 429;
|
|
327
|
-
readonly UNAUTHORIZED: 401;
|
|
328
|
-
readonly UNPROCESSABLE: 422;
|
|
329
|
-
};
|
|
330
|
-
type LunoraErrorCode = keyof typeof CODE_STATUS;
|
|
331
|
-
declare class LunoraError extends Error {
|
|
332
|
-
override readonly name = "LunoraError";
|
|
333
|
-
readonly code: LunoraErrorCode;
|
|
334
|
-
readonly status: number;
|
|
335
|
-
/** Structured, JSON+wire-encodable payload surfaced to the client alongside `code`. */
|
|
336
|
-
readonly data?: unknown;
|
|
281
|
+
declare class LunoraError extends LunoraError$1 {
|
|
337
282
|
constructor(code: LunoraErrorCode, message?: string, data?: unknown);
|
|
338
283
|
}
|
|
339
284
|
/**
|
|
@@ -659,6 +604,15 @@ interface ContextWithStorage {
|
|
|
659
604
|
storage: StorageDownloader;
|
|
660
605
|
}
|
|
661
606
|
/**
|
|
607
|
+
* True when `value` is safe to use as an HTTP header field-value: no CR, LF, or
|
|
608
|
+
* NUL. Guards against response-header injection / `Headers`-construction throws
|
|
609
|
+
* when reflecting attacker-influenced object metadata (e.g. a stored
|
|
610
|
+
* `Content-Type`). Exported (see the `export {}` at the file end) so an `httpAction`
|
|
611
|
+
* handler can guard a request-derived header value before writing it — the fix the
|
|
612
|
+
* `http_action_response_header_injection` advisor lint points to.
|
|
613
|
+
*/
|
|
614
|
+
declare const isSafeHeaderValue: (value: string) => boolean;
|
|
615
|
+
/**
|
|
662
616
|
* Stream a stored object as an HTTP {@link Response} from an `httpAction`
|
|
663
617
|
* handler, with correct `Content-Type`, `ETag`, and `Accept-Ranges: bytes`.
|
|
664
618
|
* Honors a single-range `Range` request → **206 Partial Content** with
|
|
@@ -928,21 +882,6 @@ interface MaskContextIn {
|
|
|
928
882
|
* includes this middleware — opt-in, never global (the same invariant as RLS).
|
|
929
883
|
*/
|
|
930
884
|
declare const mask: <Context extends MaskContextIn = MaskContextIn>(policies: MaskPolicies<Context>, options?: MaskOptions<Context>) => Middleware<Context, Context>;
|
|
931
|
-
/**
|
|
932
|
-
* Online data-migration authoring API.
|
|
933
|
-
*
|
|
934
|
-
* `defineMigration` declares a per-document backfill over one table: `up`
|
|
935
|
-
* transforms every existing row, `down` (optional) reverses it. Unlike the D1
|
|
936
|
-
* SQL schema migrations in `@lunora/d1`, these run *inside each shard's*
|
|
937
|
-
* Durable Object against live documents, in keyset batches, and are resumable —
|
|
938
|
-
* the per-shard runner in `@lunora/do` tracks progress in a reserved
|
|
939
|
-
* `__lunora_migrations` table so an interrupted run picks up where it stopped.
|
|
940
|
-
*
|
|
941
|
-
* The returned object carries a `__lunoraMigration` brand so codegen can
|
|
942
|
-
* discover declarations through the type checker (mirroring the procedure
|
|
943
|
-
* builder's `__lunoraProcedure` brand) and emit them into a `LUNORA_MIGRATIONS`
|
|
944
|
-
* registry the DO and CLI look migrations up by id.
|
|
945
|
-
*/
|
|
946
885
|
/** A document handed to a migration transform: the stored row including `_id`/`_creationTime`. */
|
|
947
886
|
type MigrationDocument = Record<string, unknown>;
|
|
948
887
|
/**
|
|
@@ -2052,4 +1991,4 @@ interface StorageContextIn {
|
|
|
2052
1991
|
}
|
|
2053
1992
|
declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
|
|
2054
1993
|
declare const VERSION = "0.0.0";
|
|
2055
|
-
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type
|
|
1994
|
+
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefineIdentityOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, type DurableObjectJurisdiction, type EmptyArgs, type EnvAccessor, type EnvKeyFailure, type EnvShape, type ExtendableSchema, type FacadeEntry, type FacadeWriterLike, type FunctionKind, type HttpActionCtx, type HttpActionHandler, type HttpMethod, type HttpRoute, type HttpRouteBuilder, type HttpRouteFactory, type HttpRouteHandlerOptions, type HttpStreamHandlerOptions, type IdentityContract, type IdentityRejectMode, type IdentityValidation, type InferArgs, type InferEnv, type InferIdentity, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraHttpApp, type LunoraHttpEnv, type LunoraRouteHandler, type ManyRelation, type MaskColumns, type MaskContext, type MaskFn, type MaskOptions, type MaskPolicies, type MaskStrategy, type Middleware, type MiddlewareNext, type MigrationDefinition, type MigrationDocument, type MigrationTransform, type MutationBuilder, type MutationCtx, type MutatorDefinition, type OnDeleteAction, type OneRelation, type OrmLike, DEFAULT_TTL_MS as PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, type Permission, type Plugin, type Policy, type PrefixedTables, type PresenceComponent, type PresenceFunctions, type PresenceMember, type ProtectPublicOptions, type QueryBuilder, type QueryCtx, type RankIndexDefinition, type RankIndexOptions, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMigration, type RegisteredMutation, type RegisteredMutator, type RegisteredQuery, type RegisteredShape, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type RlsReadRegistry, type Role, type Schema, type SchemaExtension, type ShapeDefinition, type ShapeReadWhereRequest, type StorageOperation, type StorageRule, type StorageRuleContext, type StorageRuleDecision, type StorageRulesOptions, type TableBuilder, type TableDefinition, type TerminalKind, type TriggerBuilder, type TriggerDefinition, type TypedDefinePolicyInput, VERSION, type VectorEmbedder, type VectorIndexDefinition, type VectorIndexOptions, type VectorMetric, type VectorizeOptions, type WhereInput, asBucketStorage, bindOrm, bindTableFacade, buildRlsReadRegistry, composePluginMiddleware, composeShapeReadWhere, createPolicyDsl, createSecrets, defineAggregateIndex, defineComponent, defineEnv, defineIdentity, defineMigration, defineMutator, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineShape, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, isSafeHeaderValue, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
|
package/dist/index.mjs
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
export { default as asBucketStorage } from './packem_shared/asBucketStorage-Cnxd9y2q.mjs';
|
|
2
|
-
export { initLunora } from './packem_shared/initLunora-
|
|
3
|
-
export { createSecrets } from './packem_shared/createSecrets-
|
|
4
|
-
export { LunoraEnvError, defineEnv, redactSecrets } from './packem_shared/LunoraEnvError-
|
|
5
|
-
export { LunoraError } from './packem_shared/LunoraError-
|
|
6
|
-
export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-
|
|
7
|
-
export { httpAction, httpRoute, httpRouter, serveStorageObject } from './packem_shared/httpAction-
|
|
8
|
-
export { defineIdentity } from './packem_shared/defineIdentity-
|
|
2
|
+
export { initLunora } from './packem_shared/initLunora-sQUqaejx.mjs';
|
|
3
|
+
export { createSecrets } from './packem_shared/createSecrets-DwaR2rNG.mjs';
|
|
4
|
+
export { LunoraEnvError, defineEnv, redactSecrets } from './packem_shared/LunoraEnvError-BGmd1Qs0.mjs';
|
|
5
|
+
export { LunoraError } from './packem_shared/LunoraError-WbxmrpxR.mjs';
|
|
6
|
+
export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-CNXKgfUa.mjs';
|
|
7
|
+
export { httpAction, httpRoute, httpRouter, isSafeHeaderValue, serveStorageObject } from './packem_shared/httpAction-B_16WzMO.mjs';
|
|
8
|
+
export { defineIdentity } from './packem_shared/defineIdentity-DiX4zM9x.mjs';
|
|
9
9
|
export { onConnect, onDisconnect } from './packem_shared/onConnect-CIPXKPyw.mjs';
|
|
10
|
-
export { defineMigration } from './packem_shared/defineMigration-
|
|
10
|
+
export { defineMigration } from './packem_shared/defineMigration-Hx01yIht.mjs';
|
|
11
11
|
export { defineMutator } from './packem_shared/defineMutator-EIXAWhs9.mjs';
|
|
12
|
-
export { composePluginMiddleware, defineComponent, definePlugin, defineSchemaExtension, installPlugins, mergeSchemaExtension } from './packem_shared/composePluginMiddleware-
|
|
13
|
-
export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-
|
|
14
|
-
export { protectPublic } from './packem_shared/protectPublic-
|
|
15
|
-
export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-
|
|
16
|
-
export { defineShape } from './packem_shared/defineShape-
|
|
12
|
+
export { composePluginMiddleware, defineComponent, definePlugin, defineSchemaExtension, installPlugins, mergeSchemaExtension } from './packem_shared/composePluginMiddleware-CcTj1_v2.mjs';
|
|
13
|
+
export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-BtPCiNLW.mjs';
|
|
14
|
+
export { protectPublic } from './packem_shared/protectPublic-BlcGpiRc.mjs';
|
|
15
|
+
export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-znq4ygKQ.mjs';
|
|
16
|
+
export { defineShape } from './packem_shared/defineShape-C5scNOrf.mjs';
|
|
17
17
|
export { anyApi } from './types.mjs';
|
|
18
18
|
export { cronJobs } from '@lunora/scheduler';
|
|
19
19
|
export { ValidationError, v } from '@lunora/values';
|
|
20
|
-
export { buildRlsReadRegistry, composeShapeReadWhere } from './packem_shared/buildRlsReadRegistry-
|
|
21
|
-
export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole } from './packem_shared/createPolicyDsl-
|
|
22
|
-
export { defineStorageRule, defineStorageRules } from './packem_shared/defineStorageRule-
|
|
23
|
-
export { mask } from './packem_shared/mask-
|
|
24
|
-
export { rls } from './packem_shared/rls-
|
|
25
|
-
export { storageRules } from './packem_shared/storageRules-
|
|
20
|
+
export { buildRlsReadRegistry, composeShapeReadWhere } from './packem_shared/buildRlsReadRegistry-DFBFLydB.mjs';
|
|
21
|
+
export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole } from './packem_shared/createPolicyDsl-By3QB4he.mjs';
|
|
22
|
+
export { defineStorageRule, defineStorageRules } from './packem_shared/defineStorageRule-B5nL4Z1P.mjs';
|
|
23
|
+
export { mask } from './packem_shared/mask-Dc8G5Gl7.mjs';
|
|
24
|
+
export { rls } from './packem_shared/rls-3sCJIH6F.mjs';
|
|
25
|
+
export { storageRules } from './packem_shared/storageRules-6QxzDOcx.mjs';
|
|
26
26
|
|
|
27
27
|
const VERSION = "0.0.0";
|
|
28
28
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
1
2
|
import { optionalInner } from '@lunora/values';
|
|
2
3
|
|
|
3
4
|
const SECRET_VALUE_PREFIXES = [
|
|
@@ -53,13 +54,12 @@ const redactValueForKey = (message, key, raw) => {
|
|
|
53
54
|
}
|
|
54
55
|
return masked;
|
|
55
56
|
};
|
|
56
|
-
class LunoraEnvError extends
|
|
57
|
-
name = "LunoraEnvError";
|
|
57
|
+
class LunoraEnvError extends LunoraError$1 {
|
|
58
58
|
failures;
|
|
59
59
|
constructor(failures) {
|
|
60
60
|
const summary = failures.map((failure) => ` - ${failure.key}: ${failure.message}`).join("\n");
|
|
61
|
-
super(`Invalid environment (${String(failures.length)} key(s)):
|
|
62
|
-
${summary}
|
|
61
|
+
super("ENV_INVALID", `Invalid environment (${String(failures.length)} key(s)):
|
|
62
|
+
${summary}`, { name: "LunoraEnvError" });
|
|
63
63
|
this.failures = failures;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { v } from '@lunora/values';
|
|
2
|
-
import { initLunora } from './initLunora-
|
|
3
|
-
import { LunoraError } from './LunoraError-
|
|
2
|
+
import { initLunora } from './initLunora-sQUqaejx.mjs';
|
|
3
|
+
import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
|
|
4
4
|
import { onDisconnect } from './onConnect-CIPXKPyw.mjs';
|
|
5
|
-
import { defineSchemaExtension, defineComponent } from './composePluginMiddleware-
|
|
6
|
-
import { defineTable } from './defineAggregateIndex-
|
|
5
|
+
import { defineSchemaExtension, defineComponent } from './composePluginMiddleware-CcTj1_v2.mjs';
|
|
6
|
+
import { defineTable } from './defineAggregateIndex-znq4ygKQ.mjs';
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TTL_MS = 3e4;
|
|
9
9
|
const MAX_DATA_BYTES = 4096;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const isUniqueConflict = (error) => typeof error === "object" && error !== null && error.code === "CONFLICT" && error.kind === "unique";
|
|
2
4
|
const buildUpsertWhere = (tableName, target, create) => {
|
|
3
5
|
const fields = typeof target === "string" ? [target] : target;
|
|
4
6
|
if (fields.length === 0) {
|
|
5
|
-
throw new
|
|
7
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.upsert: "target" must name at least one field`);
|
|
6
8
|
}
|
|
7
9
|
const where = {};
|
|
8
10
|
for (const field of fields) {
|
|
9
11
|
if (!(field in create)) {
|
|
10
|
-
throw new
|
|
12
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.upsert: target field "${field}" is missing from the create document`);
|
|
11
13
|
}
|
|
12
14
|
where[field] = create[field];
|
|
13
15
|
}
|
|
@@ -48,7 +50,7 @@ const bindTableFacade = (writer, tableName) => {
|
|
|
48
50
|
// the writer's `{ id, patch }` shape.
|
|
49
51
|
deleteMany: (ids, options) => {
|
|
50
52
|
if (writer.deleteMany === void 0) {
|
|
51
|
-
throw new
|
|
53
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.deleteMany is unavailable: this writer has no batch delete`);
|
|
52
54
|
}
|
|
53
55
|
return writer.deleteMany(ids, options, tableName);
|
|
54
56
|
},
|
|
@@ -65,14 +67,14 @@ const bindTableFacade = (writer, tableName) => {
|
|
|
65
67
|
insert,
|
|
66
68
|
insertMany: (documents, options) => {
|
|
67
69
|
if (writer.insertMany === void 0) {
|
|
68
|
-
throw new
|
|
70
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.insertMany is unavailable: this writer has no batch insert`);
|
|
69
71
|
}
|
|
70
72
|
return writer.insertMany(tableName, documents, options);
|
|
71
73
|
},
|
|
72
74
|
patch: (id, patch) => writer.patch(id, patch, tableName),
|
|
73
75
|
patchMany: (patches, options) => {
|
|
74
76
|
if (writer.patchMany === void 0) {
|
|
75
|
-
throw new
|
|
77
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.patchMany is unavailable: this writer has no batch patch`);
|
|
76
78
|
}
|
|
77
79
|
return writer.patchMany(
|
|
78
80
|
patches.map((entry) => {
|
|
@@ -87,7 +89,7 @@ const bindTableFacade = (writer, tableName) => {
|
|
|
87
89
|
replace: (id, document) => writer.replace(id, document, tableName),
|
|
88
90
|
restore: async (id) => {
|
|
89
91
|
if (!writer.restore) {
|
|
90
|
-
throw new
|
|
92
|
+
throw new LunoraError$1("INTERNAL", `ctx.db.${tableName}.restore is unavailable: this writer has no restore (is the table .softDelete()?)`);
|
|
91
93
|
}
|
|
92
94
|
await writer.restore(id, tableName);
|
|
93
95
|
},
|
|
@@ -106,7 +108,7 @@ const bindOrm = (facade) => {
|
|
|
106
108
|
const resolve = (table) => {
|
|
107
109
|
const bound = facade[table];
|
|
108
110
|
if (!bound) {
|
|
109
|
-
throw new
|
|
111
|
+
throw new LunoraError$1("INTERNAL", `unknown table: ${table}`);
|
|
110
112
|
}
|
|
111
113
|
return bound;
|
|
112
114
|
};
|
package/dist/packem_shared/{buildRlsReadRegistry-Do1CSBTr.mjs → buildRlsReadRegistry-DFBFLydB.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { indexRolePermissions, computeReadBaseWhere, permissionName } from './rls-
|
|
1
|
+
import { indexRolePermissions, computeReadBaseWhere, permissionName } from './rls-3sCJIH6F.mjs';
|
|
2
2
|
import { r as readRlsTag } from './policy-tag-DvpVH2tv.mjs';
|
|
3
3
|
|
|
4
4
|
const FALSE_PREDICATE = { OR: [] };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
import { r as runMiddlewareChain } from './run-middleware-I6EiQfxL.mjs';
|
|
2
3
|
|
|
3
4
|
const prefixTableName = (key, bareName) => `${key}_${bareName}`;
|
|
4
5
|
const rewriteReference = (target, key, bareNames) => bareNames.has(target) ? prefixTableName(key, target) : target;
|
|
@@ -19,7 +20,7 @@ const rewriteTableReferences = (table, key, bareNames, ownBareName) => {
|
|
|
19
20
|
};
|
|
20
21
|
const defineSchemaExtension = (key, options) => {
|
|
21
22
|
if (!key) {
|
|
22
|
-
throw new
|
|
23
|
+
throw new LunoraError$1("INTERNAL", "defineSchemaExtension: `key` is required and must be a non-empty string");
|
|
23
24
|
}
|
|
24
25
|
return {
|
|
25
26
|
key,
|
|
@@ -29,10 +30,10 @@ const defineSchemaExtension = (key, options) => {
|
|
|
29
30
|
};
|
|
30
31
|
const definePlugin = (key, options) => {
|
|
31
32
|
if (!key) {
|
|
32
|
-
throw new
|
|
33
|
+
throw new LunoraError$1("INTERNAL", "definePlugin: `key` is required and must be a non-empty string");
|
|
33
34
|
}
|
|
34
35
|
if (options.extension && options.extension.key !== key) {
|
|
35
|
-
throw new
|
|
36
|
+
throw new LunoraError$1("INTERNAL", `definePlugin("${key}"): extension key "${options.extension.key}" does not match plugin key`);
|
|
36
37
|
}
|
|
37
38
|
return {
|
|
38
39
|
key,
|
|
@@ -57,7 +58,8 @@ const mergeSchemaExtension = (base, extension) => {
|
|
|
57
58
|
for (const [bareName, table] of Object.entries(extension.tables)) {
|
|
58
59
|
const prefixed = prefixTableName(key, bareName);
|
|
59
60
|
if (Object.hasOwn(merged, prefixed)) {
|
|
60
|
-
throw new
|
|
61
|
+
throw new LunoraError$1(
|
|
62
|
+
"INTERNAL",
|
|
61
63
|
`defineSchema(...).extend("${key}"): table "${prefixed}" already exists in the base schema — another extension with the same key already contributed it`
|
|
62
64
|
);
|
|
63
65
|
}
|
|
@@ -68,7 +70,8 @@ const mergeSchemaExtension = (base, extension) => {
|
|
|
68
70
|
for (const [bareIndexName, index] of Object.entries(extension.vectorIndexes)) {
|
|
69
71
|
const prefixed = prefixTableName(key, bareIndexName);
|
|
70
72
|
if (Object.hasOwn(mergedVectorIndexes, prefixed)) {
|
|
71
|
-
throw new
|
|
73
|
+
throw new LunoraError$1(
|
|
74
|
+
"INTERNAL",
|
|
72
75
|
`defineSchema(...).extend("${key}"): vector index "${prefixed}" already exists in the base schema — another extension with the same key already contributed it`
|
|
73
76
|
);
|
|
74
77
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const definePolicy = (input) => {
|
|
2
4
|
return { on: input.on, table: input.table, when: input.when };
|
|
3
5
|
};
|
|
@@ -13,7 +15,8 @@ const definePolicies = (policies) => {
|
|
|
13
15
|
const key = JSON.stringify([policy.table, policy.on]);
|
|
14
16
|
const whens = seenWhenByKey.get(key) ?? /* @__PURE__ */ new Set();
|
|
15
17
|
if (whens.has(policy.when)) {
|
|
16
|
-
throw new
|
|
18
|
+
throw new LunoraError$1(
|
|
19
|
+
"INTERNAL",
|
|
17
20
|
`definePolicies: duplicate policy for (table "${policy.table}", on "${policy.on}") — the same decision function is registered more than once. Multiple distinct policies per (table, on) are allowed (reads OR, writes AND); remove the duplicate.`
|
|
18
21
|
);
|
|
19
22
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const NON_SECRET_BINDING_METHODS = [
|
|
2
4
|
"put",
|
|
3
5
|
// KV / R2
|
|
@@ -43,7 +45,8 @@ const createSecrets = (env) => {
|
|
|
43
45
|
get: async (name) => {
|
|
44
46
|
const binding = env[name];
|
|
45
47
|
if (!isSecretBinding(binding)) {
|
|
46
|
-
throw new
|
|
48
|
+
throw new LunoraError$1(
|
|
49
|
+
"INTERNAL",
|
|
47
50
|
`ctx.secrets: no Secrets Store binding named "${name}". Add a \`secrets_store_secrets[]\` entry (binding "${name}", pointing at your store + secret) to wrangler.jsonc — \`ctx.secrets\` reads a Secrets Store binding, not a plain \`.dev.vars\` value.`
|
|
48
51
|
);
|
|
49
52
|
}
|
package/dist/packem_shared/{defineAggregateIndex-ZdyU78gh.mjs → defineAggregateIndex-znq4ygKQ.mjs}
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
1
2
|
import { isOrWrapsFromValidator, v } from '@lunora/values';
|
|
2
|
-
import { mergeSchemaExtension } from './composePluginMiddleware-
|
|
3
|
+
import { mergeSchemaExtension } from './composePluginMiddleware-CcTj1_v2.mjs';
|
|
3
4
|
|
|
4
5
|
const relationBuilder = {
|
|
5
6
|
many: (table, options) => {
|
|
@@ -26,7 +27,7 @@ const defineTable = (inputShape) => {
|
|
|
26
27
|
const shape = { ...inputShape };
|
|
27
28
|
for (const [columnName, validator] of Object.entries(shape)) {
|
|
28
29
|
if (isOrWrapsFromValidator(validator)) {
|
|
29
|
-
throw new
|
|
30
|
+
throw new LunoraError$1("INTERNAL", `defineTable: column "${columnName}" uses v.from() which is args-only — table columns need a concrete v.* type`);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
const aggregateIndexes = [];
|
|
@@ -46,7 +47,7 @@ const defineTable = (inputShape) => {
|
|
|
46
47
|
aggregateIndex(name, options) {
|
|
47
48
|
const op = options?.op ?? "count";
|
|
48
49
|
if (op !== "count" && !options?.field) {
|
|
49
|
-
throw new
|
|
50
|
+
throw new LunoraError$1("INTERNAL", `aggregateIndex "${name}": op "${op}" requires a "field"`);
|
|
50
51
|
}
|
|
51
52
|
aggregateIndexes.push({
|
|
52
53
|
by: options?.by,
|
|
@@ -94,7 +95,7 @@ const defineTable = (inputShape) => {
|
|
|
94
95
|
},
|
|
95
96
|
rankIndex(name, options) {
|
|
96
97
|
if (!options.sortBy || options.sortBy.length === 0) {
|
|
97
|
-
throw new
|
|
98
|
+
throw new LunoraError$1("INTERNAL", `rankIndex "${name}": "sortBy" is required and must list at least one key`);
|
|
98
99
|
}
|
|
99
100
|
const sortBy = options.sortBy.map((key) => {
|
|
100
101
|
return {
|
|
@@ -143,10 +144,10 @@ const defineTable = (inputShape) => {
|
|
|
143
144
|
},
|
|
144
145
|
source(definition) {
|
|
145
146
|
if (!definition.binding) {
|
|
146
|
-
throw new
|
|
147
|
+
throw new LunoraError$1("INTERNAL", "source: `binding` is required (the wrangler Hyperdrive binding name)");
|
|
147
148
|
}
|
|
148
149
|
if (!definition.query) {
|
|
149
|
-
throw new
|
|
150
|
+
throw new LunoraError$1("INTERNAL", "source: `query` is required (the tenant-membership SQL)");
|
|
150
151
|
}
|
|
151
152
|
externalSource = definition;
|
|
152
153
|
isExternallyManaged = true;
|
|
@@ -198,13 +199,13 @@ const defineVectorIndex = (options) => {
|
|
|
198
199
|
const defineAggregateIndex = (name, options) => {
|
|
199
200
|
const op = options.op ?? "count";
|
|
200
201
|
if (op !== "count" && !options.field) {
|
|
201
|
-
throw new
|
|
202
|
+
throw new LunoraError$1("INTERNAL", `aggregateIndex "${name}": op "${op}" requires a "field"`);
|
|
202
203
|
}
|
|
203
204
|
return { by: options.by, field: options.field, name, on: options.on, op, where: options.where };
|
|
204
205
|
};
|
|
205
206
|
const defineRankIndex = (name, options) => {
|
|
206
207
|
if (!options.sortBy || options.sortBy.length === 0) {
|
|
207
|
-
throw new
|
|
208
|
+
throw new LunoraError$1("INTERNAL", `rankIndex "${name}": "sortBy" is required and must list at least one key`);
|
|
208
209
|
}
|
|
209
210
|
const sortBy = options.sortBy.map((key) => {
|
|
210
211
|
return {
|
|
@@ -246,14 +247,14 @@ const attachStandaloneIndexes = (tables, aggregateIndexes, rankIndexes) => {
|
|
|
246
247
|
for (const index of Object.values(aggregateIndexes)) {
|
|
247
248
|
const table = tables[index.on];
|
|
248
249
|
if (!table) {
|
|
249
|
-
throw new
|
|
250
|
+
throw new LunoraError$1("INTERNAL", `defineAggregateIndex "${index.name}": unknown table "${index.on}"`);
|
|
250
251
|
}
|
|
251
252
|
table.aggregateIndexes.push(index);
|
|
252
253
|
}
|
|
253
254
|
for (const index of Object.values(rankIndexes)) {
|
|
254
255
|
const table = tables[index.on];
|
|
255
256
|
if (!table) {
|
|
256
|
-
throw new
|
|
257
|
+
throw new LunoraError$1("INTERNAL", `defineRankIndex "${index.name}": unknown table "${index.on}"`);
|
|
257
258
|
}
|
|
258
259
|
table.rankIndexes.push(index);
|
|
259
260
|
}
|
|
@@ -265,17 +266,20 @@ const validateExternalSources = (tables) => {
|
|
|
265
266
|
continue;
|
|
266
267
|
}
|
|
267
268
|
if (table.shardMode.kind === "global") {
|
|
268
|
-
throw new
|
|
269
|
+
throw new LunoraError$1(
|
|
270
|
+
"INTERNAL",
|
|
269
271
|
`defineSchema: table "${name}" cannot be both .source() and .global() — a sourced table materializes into a shard DO's SQLite, a global table lives in the external tier`
|
|
270
272
|
);
|
|
271
273
|
}
|
|
272
274
|
if (table.shardMode.kind === "shardBy" && !source.tenantBy) {
|
|
273
|
-
throw new
|
|
275
|
+
throw new LunoraError$1(
|
|
276
|
+
"INTERNAL",
|
|
274
277
|
`defineSchema: sourced + .shardBy() table "${name}" needs a \`tenantBy\` mapper — without it every tenant's DO would run the same unscoped query and replicate the whole multitenant table (a cross-tenant leak). Add \`tenantBy: (shardKey) => [shardKey]\` binding the shard key into the query's parameters.`
|
|
275
278
|
);
|
|
276
279
|
}
|
|
277
280
|
if (source.mode === "incremental") {
|
|
278
|
-
throw new
|
|
281
|
+
throw new LunoraError$1(
|
|
282
|
+
"INTERNAL",
|
|
279
283
|
`defineSchema: table "${name}" uses \`mode: "incremental"\`, which is not yet implemented — only "full-pull" (the default) is supported. Remove \`mode\` or set it to "full-pull".`
|
|
280
284
|
);
|
|
281
285
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
1
2
|
import { parseValidatorMap, ValidationError } from '@lunora/values';
|
|
2
3
|
|
|
3
4
|
const NON_STRING_USER_ID_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -17,7 +18,7 @@ const defineIdentity = (claims, options = {}) => {
|
|
|
17
18
|
const map = claims;
|
|
18
19
|
const userIdValidator = map["userId"];
|
|
19
20
|
if (userIdValidator === void 0 || NON_STRING_USER_ID_KINDS.has(userIdValidator.kind)) {
|
|
20
|
-
throw new
|
|
21
|
+
throw new LunoraError$1("INTERNAL", "defineIdentity: the claim map must declare a required string `userId` validator (e.g. `v.string()` or `v.id(...)`)");
|
|
21
22
|
}
|
|
22
23
|
const onInvalid = options.onInvalid ?? "anonymous";
|
|
23
24
|
const validate = (identity) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const defineMigration = (definition) => {
|
|
2
4
|
if (definition.id.trim() === "") {
|
|
3
|
-
throw new
|
|
5
|
+
throw new LunoraError$1("INTERNAL", "defineMigration: `id` must be a non-empty string");
|
|
4
6
|
}
|
|
5
7
|
return { __lunoraMigration: true, ...definition };
|
|
6
8
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
1
2
|
import { v as validateArgs } from './functions-Di9FUNkf.mjs';
|
|
2
3
|
|
|
3
4
|
const defineShape = (definition) => {
|
|
4
5
|
if (definition.table.trim() === "") {
|
|
5
|
-
throw new
|
|
6
|
+
throw new LunoraError$1("INTERNAL", "defineShape: `table` must be a non-empty string");
|
|
6
7
|
}
|
|
7
8
|
if (definition.columns?.length === 0) {
|
|
8
|
-
throw new
|
|
9
|
+
throw new LunoraError$1("INTERNAL", "defineShape: `columns` must list at least one column when provided");
|
|
9
10
|
}
|
|
10
11
|
const compileWhere = (context, rawArgs) => {
|
|
11
12
|
const parsed = validateArgs(definition.args ?? {}, rawArgs);
|
package/dist/packem_shared/{defineStorageRule-qu0mpilX.mjs → defineStorageRule-B5nL4Z1P.mjs}
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const defineStorageRule = (input) => {
|
|
2
4
|
return { bucket: input.bucket, on: input.on, prefix: input.prefix, when: input.when };
|
|
3
5
|
};
|
|
@@ -7,7 +9,8 @@ const defineStorageRules = (rules) => {
|
|
|
7
9
|
const key = JSON.stringify([rule.bucket, rule.on, rule.prefix]);
|
|
8
10
|
const whens = seenWhenByKey.get(key) ?? /* @__PURE__ */ new Set();
|
|
9
11
|
if (whens.has(rule.when)) {
|
|
10
|
-
throw new
|
|
12
|
+
throw new LunoraError$1(
|
|
13
|
+
"INTERNAL",
|
|
11
14
|
`defineStorageRules: duplicate rule for (bucket "${rule.bucket}", on "${rule.on}"${rule.prefix === void 0 ? "" : `, prefix "${rule.prefix}"`}) — the same decision function is registered more than once. Multiple distinct rules per (bucket, on) are allowed (they OR); remove the duplicate.`
|
|
12
15
|
);
|
|
13
16
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { toErrorBody } from '@lunora/errors';
|
|
1
2
|
import { parseValidatorMap, ValidationError } from '@lunora/values';
|
|
2
3
|
import { Hono } from 'hono';
|
|
3
|
-
import { LunoraError } from './LunoraError-
|
|
4
|
+
import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
|
|
4
5
|
|
|
5
6
|
const httpAction = (handler) => async (c) => handler(c.get("lunora"), c.req.raw);
|
|
6
7
|
const httpRouter = () => {
|
|
@@ -126,13 +127,6 @@ const buildRouteHandler = (state, userHandler) => async (c) => {
|
|
|
126
127
|
return errorResponse(error);
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
|
-
const isLunoraErrorLike = (error) => {
|
|
130
|
-
if (!error || typeof error !== "object") {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const candidate = error;
|
|
134
|
-
return candidate.name === "LunoraError" && typeof candidate.code === "string" && typeof candidate.message === "string";
|
|
135
|
-
};
|
|
136
130
|
const sseFrame = (chunk, event) => {
|
|
137
131
|
const data = JSON.stringify(chunk);
|
|
138
132
|
const prefix = event ? `event: ${event}
|
|
@@ -193,14 +187,11 @@ const buildStreamHandler = (state, userHandler) => (
|
|
|
193
187
|
}
|
|
194
188
|
controller.enqueue(encoder.encode(sseFrame({}, "complete")));
|
|
195
189
|
} catch (error) {
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
payload = { code: error.code, message: error.message };
|
|
199
|
-
} else {
|
|
190
|
+
const { body, redacted } = toErrorBody(error, { fallbackCode: "INTERNAL_SERVER_ERROR", redactedMessage: "Internal error" });
|
|
191
|
+
if (redacted) {
|
|
200
192
|
console.error("[lunora] unhandled stream handler error:", error);
|
|
201
|
-
payload = { code: "INTERNAL_SERVER_ERROR", message: "Internal error" };
|
|
202
193
|
}
|
|
203
|
-
controller.enqueue(encoder.encode(sseFrame(
|
|
194
|
+
controller.enqueue(encoder.encode(sseFrame({ code: body.code, message: body.message }, "error")));
|
|
204
195
|
} finally {
|
|
205
196
|
request.signal.removeEventListener("abort", onAbort);
|
|
206
197
|
controller.close();
|
|
@@ -337,4 +328,4 @@ const serveStorageObject = async (context, key, request) => {
|
|
|
337
328
|
});
|
|
338
329
|
};
|
|
339
330
|
|
|
340
|
-
export { httpAction, httpRoute, httpRouter, serveStorageObject };
|
|
331
|
+
export { httpAction, httpRoute, httpRouter, isSafeHeaderValue, serveStorageObject };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { v as validateArgs } from './functions-Di9FUNkf.mjs';
|
|
2
2
|
import { r as readRlsTag } from './policy-tag-DvpVH2tv.mjs';
|
|
3
|
-
import { r as runMiddlewareChain } from './run-middleware-
|
|
3
|
+
import { r as runMiddlewareChain } from './run-middleware-I6EiQfxL.mjs';
|
|
4
4
|
|
|
5
5
|
const runMiddleware = (middlewares, baseContext) => runMiddlewareChain(middlewares, baseContext, (context) => context);
|
|
6
6
|
const makeHandler = (args, middlewares, userHandler, output) => async (context, rawArgs) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LunoraError } from './LunoraError-
|
|
2
|
-
import { bindTableFacade, bindOrm } from './bindOrm-
|
|
1
|
+
import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
|
|
2
|
+
import { bindTableFacade, bindOrm } from './bindOrm-CNXKgfUa.mjs';
|
|
3
3
|
|
|
4
4
|
const permissionName = (permission) => typeof permission === "string" ? permission : permission.name;
|
|
5
5
|
const indexRolePermissions = (roles) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LunoraError } from './LunoraError-
|
|
2
|
-
import { bindTableFacade, bindOrm } from './bindOrm-
|
|
1
|
+
import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
|
|
2
|
+
import { bindTableFacade, bindOrm } from './bindOrm-CNXKgfUa.mjs';
|
|
3
3
|
import { t as tagRlsMiddleware } from './policy-tag-DvpVH2tv.mjs';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_BATCH_LIMIT = 500;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { LunoraError as LunoraError$1 } from '@lunora/errors';
|
|
2
|
+
|
|
1
3
|
const runMiddlewareChain = async (middlewares, baseContext, terminal) => {
|
|
2
4
|
let lastIndex = -1;
|
|
3
5
|
const dispatch = async (index, context) => {
|
|
4
6
|
if (index <= lastIndex) {
|
|
5
|
-
throw new
|
|
7
|
+
throw new LunoraError$1("INTERNAL", "middleware next() called multiple times");
|
|
6
8
|
}
|
|
7
9
|
lastIndex = index;
|
|
8
10
|
const middleware = middlewares[index];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LunoraError } from './LunoraError-
|
|
1
|
+
import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
|
|
2
2
|
|
|
3
3
|
const permissionName = (permission) => typeof permission === "string" ? permission : permission.name;
|
|
4
4
|
const indexRolePermissions = (roles = []) => {
|
package/dist/rls/testing.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { indexRolePermissions, computeReadBaseWhere, matchesWhere, evaluateWrite, permissionName } from '../packem_shared/rls-
|
|
1
|
+
import { indexRolePermissions, computeReadBaseWhere, matchesWhere, evaluateWrite, permissionName } from '../packem_shared/rls-3sCJIH6F.mjs';
|
|
2
2
|
|
|
3
3
|
const expectPolicy = (policies, options = {}) => {
|
|
4
4
|
const rolePermissions = indexRolePermissions(options.roles);
|
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.15",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -62,8 +62,9 @@
|
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@lunora/
|
|
66
|
-
"@lunora/
|
|
65
|
+
"@lunora/errors": "1.0.0-alpha.1",
|
|
66
|
+
"@lunora/scheduler": "1.0.0-alpha.5",
|
|
67
|
+
"@lunora/values": "1.0.0-alpha.4",
|
|
67
68
|
"drizzle-orm": "^0.45.2",
|
|
68
69
|
"hono": "^4.12.27"
|
|
69
70
|
},
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const CODE_STATUS = {
|
|
2
|
-
BAD_REQUEST: 400,
|
|
3
|
-
CONFLICT: 409,
|
|
4
|
-
/**
|
|
5
|
-
* `count()` invoked against a table whose context carries an active RLS
|
|
6
|
-
* policy. The operation itself is unsupported in an RLS-restricted reader
|
|
7
|
-
* (kitcn's documented constraint) — the request is well-formed and the
|
|
8
|
-
* caller is authorized, so this is a 422 (semantic conflict) rather than a
|
|
9
|
-
* 403 (policy denial).
|
|
10
|
-
*/
|
|
11
|
-
COUNT_RLS_UNSUPPORTED: 422,
|
|
12
|
-
FORBIDDEN: 403,
|
|
13
|
-
INTERNAL_SERVER_ERROR: 500,
|
|
14
|
-
/**
|
|
15
|
-
* An analytical reduction (`aggregate` / `groupBy`) was invoked over a
|
|
16
|
-
* column that the procedure's `mask()` middleware redacts. A masked column
|
|
17
|
-
* can't be summed, averaged, or grouped without leaking the very values the
|
|
18
|
-
* mask hides (a group key *is* the raw value; an aggregate is computed from
|
|
19
|
-
* it), so the operation fails closed. The request is well-formed and the
|
|
20
|
-
* caller is authorized — this is a 422 (semantic conflict), mirroring
|
|
21
|
-
* `COUNT_RLS_UNSUPPORTED`.
|
|
22
|
-
*/
|
|
23
|
-
MASK_UNSUPPORTED: 422,
|
|
24
|
-
NOT_FOUND: 404,
|
|
25
|
-
NOT_IMPLEMENTED: 501,
|
|
26
|
-
/**
|
|
27
|
-
* A write policy's `when` returned a relation-crossing predicate
|
|
28
|
-
* (`some`/`none`/`every`/`is`/`isNot`). The in-memory write-policy evaluator
|
|
29
|
-
* has no child fetcher and cannot resolve a relation node, so the policy is
|
|
30
|
-
* unsupported as written. Relation predicates are valid in *read* policies
|
|
31
|
-
* and query `where` clauses (the pre-resolver handles them there). The
|
|
32
|
-
* request is well-formed; this is a 422 (semantic conflict), mirroring the
|
|
33
|
-
* sibling `*_UNSUPPORTED` codes.
|
|
34
|
-
*/
|
|
35
|
-
RELATION_PREDICATE_UNSUPPORTED: 422,
|
|
36
|
-
TOO_MANY_REQUESTS: 429,
|
|
37
|
-
UNAUTHORIZED: 401,
|
|
38
|
-
UNPROCESSABLE: 422
|
|
39
|
-
};
|
|
40
|
-
class LunoraError extends Error {
|
|
41
|
-
name = "LunoraError";
|
|
42
|
-
code;
|
|
43
|
-
status;
|
|
44
|
-
/** Structured, JSON+wire-encodable payload surfaced to the client alongside `code`. */
|
|
45
|
-
data;
|
|
46
|
-
constructor(code, message, data) {
|
|
47
|
-
super(message ?? code);
|
|
48
|
-
this.code = code;
|
|
49
|
-
this.status = CODE_STATUS[code];
|
|
50
|
-
this.data = data;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export { LunoraError };
|