@lunora/server 1.0.0-alpha.2 → 1.0.0-alpha.4
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/README.md +1 -1
- package/__assets__/package-og.svg +1 -1
- package/dist/data-model.d.mts +104 -16
- package/dist/data-model.d.ts +104 -16
- package/dist/index.d.mts +94 -22
- package/dist/index.d.ts +94 -22
- package/dist/index.mjs +5 -5
- package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-BZYd5-uo.mjs → PRESENCE_DEFAULT_TTL_MS-BgBQsqQ-.mjs} +1 -1
- package/dist/packem_shared/{bindOrm-DCuyr46L.mjs → bindOrm-Ce57S3N9.mjs} +58 -1
- package/dist/packem_shared/{defineAggregateIndex-DxSso0rH.mjs → defineAggregateIndex-C2gT1GzM.mjs} +18 -2
- package/dist/packem_shared/{mask-Jc84C_hK.mjs → mask-eCUYOwhd.mjs} +1 -1
- package/dist/packem_shared/{rls-BDKRbMCA.mjs → rls-Bi9HiyDC.mjs} +18 -2
- package/dist/rls/testing.mjs +1 -1
- package/dist/types.d.mts +23 -1
- package/dist/types.d.ts +23 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Validator, Infer, v } from '@lunora/values';
|
|
2
2
|
export { type ColumnValidator, type Id, type Infer, ValidationError, type Validator, type ValidatorKind, v } from '@lunora/values';
|
|
3
|
-
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, RelationDefinition, GlobalBackend, OnDeleteAction, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.js";
|
|
3
|
+
import { ArgsValidator, InferArgs, RegisteredAction, ActionCtx, MutationCtx, RegisteredMutation, QueryCtx, RegisteredQuery, RegisteredStream, FunctionKind, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, 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
5
|
import { Context, Hono } from 'hono';
|
|
6
6
|
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-BDY0FYHK.js";
|
|
@@ -325,21 +325,6 @@ declare class LunoraError extends Error {
|
|
|
325
325
|
constructor(code: LunoraErrorCode, message?: string);
|
|
326
326
|
}
|
|
327
327
|
/**
|
|
328
|
-
* The per-table `ctx.db` accessor (the `ctx.db.messages.findMany(...)` form) and
|
|
329
|
-
* the kitcn-style `ctx.orm` namespace, as plain runtime helpers. This is the ONE
|
|
330
|
-
* source of truth for the facade shape, shared by two callers so they can never
|
|
331
|
-
* drift (a drift here is security-relevant — a facade accessor the RLS
|
|
332
|
-
* middleware forgot to re-bind would read around policy). `@lunora/codegen`
|
|
333
|
-
* emits `ctx.db`/`ctx.orm` by calling these over the raw shard writer (and the
|
|
334
|
-
* D1 `globalDb` writer for `.global()` tables); the RLS middleware re-binds the
|
|
335
|
-
* policy tables by calling them over the policy-enforcing wrapped writer.
|
|
336
|
-
*
|
|
337
|
-
* `bindTableFacade(writer, table)` pins `tableName` on the structural writer so
|
|
338
|
-
* callers address rows by id (`get`/`delete`/`patch`/`replace`) or by the bound
|
|
339
|
-
* table (everything else). The binding is identical regardless of which writer
|
|
340
|
-
* is passed — that's the whole point.
|
|
341
|
-
*/
|
|
342
|
-
/**
|
|
343
328
|
* Minimal structural writer the facade binds over. Declared with **method**
|
|
344
329
|
* syntax (not arrow properties) so a more-specifically-typed writer — both
|
|
345
330
|
* `@lunora/do`'s `DatabaseWriterLike` and the RLS middleware's wrapped writer —
|
|
@@ -349,7 +334,9 @@ declare class LunoraError extends Error {
|
|
|
349
334
|
interface FacadeWriterLike {
|
|
350
335
|
aggregate(tableName: string, options: unknown): Promise<unknown>;
|
|
351
336
|
count(tableName: string, where?: unknown): Promise<number>;
|
|
352
|
-
delete(id: string, expectedTable?: string
|
|
337
|
+
delete(id: string, expectedTable?: string, options?: {
|
|
338
|
+
hard?: boolean;
|
|
339
|
+
}): Promise<void>;
|
|
353
340
|
deleteMany?(ids: ReadonlyArray<string>, options?: {
|
|
354
341
|
limit?: number;
|
|
355
342
|
}, expectedTable?: string): Promise<{
|
|
@@ -377,6 +364,7 @@ interface FacadeWriterLike {
|
|
|
377
364
|
rank(tableName: string, indexName: string, options: unknown): Promise<unknown>;
|
|
378
365
|
rankPage(tableName: string, indexName: string, options?: unknown): Promise<unknown>;
|
|
379
366
|
replace(id: string, document: Record<string, unknown>, expectedTable?: string): Promise<void>;
|
|
367
|
+
restore?(id: string, expectedTable?: string): Promise<void>;
|
|
380
368
|
}
|
|
381
369
|
/** The per-table accessor object returned for the `ctx.db` table form. */
|
|
382
370
|
interface FacadeEntry {
|
|
@@ -388,12 +376,16 @@ interface FacadeEntry {
|
|
|
388
376
|
}) => Promise<{
|
|
389
377
|
deleted: number;
|
|
390
378
|
}>;
|
|
379
|
+
/** `true` when at least one row matches `where` (or any row exists when omitted). Honors RLS like `findFirst`. */
|
|
380
|
+
exists: (where?: unknown) => Promise<boolean>;
|
|
391
381
|
findFirst: (args?: unknown) => Promise<unknown>;
|
|
392
382
|
findFirstOrThrow: (args?: unknown) => Promise<unknown>;
|
|
393
383
|
findMany: (args?: unknown) => Promise<unknown>;
|
|
394
384
|
get: (id: string) => Promise<unknown>;
|
|
395
385
|
groupBy: (options: unknown) => Promise<unknown>;
|
|
396
|
-
|
|
386
|
+
/** Physically remove a row (and physically cascade), bypassing `.softDelete()`. */
|
|
387
|
+
hardDelete: (id: string) => Promise<void>;
|
|
388
|
+
insert: (document: Record<string, unknown>, options?: FacadeInsertOptions) => Promise<null | string>;
|
|
397
389
|
insertMany: (documents: ReadonlyArray<Record<string, unknown>>, options?: {
|
|
398
390
|
limit?: number;
|
|
399
391
|
}) => Promise<string[]>;
|
|
@@ -407,8 +399,47 @@ interface FacadeEntry {
|
|
|
407
399
|
rank: (indexName: string, options: unknown) => Promise<unknown>;
|
|
408
400
|
rankPage: (indexName: string, options?: unknown) => Promise<unknown>;
|
|
409
401
|
replace: (id: string, document: Record<string, unknown>) => Promise<void>;
|
|
402
|
+
/** Un-soft-delete a row: clears the `.softDelete()` marker (by-id, so it reaches a row list reads hide). */
|
|
403
|
+
restore: (id: string) => Promise<void>;
|
|
404
|
+
/** Insert when no row matches `target`, else patch the match. Composes `findFirst` + `insert`/`patch`, so RLS applies to each step. */
|
|
405
|
+
upsert: (args: UpsertArgs) => Promise<UpsertResult>;
|
|
406
|
+
/** Sequential `upsert` over many rows sharing one `target`; returns one result per input row in order. */
|
|
407
|
+
upsertMany: (args: UpsertManyArgs) => Promise<UpsertResult[]>;
|
|
410
408
|
withSearchIndex: (indexName: string, search: (q: unknown) => unknown) => unknown;
|
|
411
409
|
}
|
|
410
|
+
/** Options accepted by the per-table `insert` accessor. */
|
|
411
|
+
interface FacadeInsertOptions {
|
|
412
|
+
/**
|
|
413
|
+
* When `true`, a UNIQUE-constraint breach is swallowed: the insert becomes a
|
|
414
|
+
* silent no-op and resolves to `null` instead of throwing a `CONFLICT`. Any
|
|
415
|
+
* other error still propagates. Mirrors better-drizzle's `create({ skipDuplicates })`.
|
|
416
|
+
*/
|
|
417
|
+
skipDuplicates?: boolean;
|
|
418
|
+
}
|
|
419
|
+
/** The conflict target for `upsert`/`upsertMany`: one field name or a tuple of them. */
|
|
420
|
+
type UpsertTarget = ReadonlyArray<string> | string;
|
|
421
|
+
/** Argument to the per-table `upsert` accessor. */
|
|
422
|
+
interface UpsertArgs {
|
|
423
|
+
/** Document inserted when no existing row matches the `target`. */
|
|
424
|
+
create: Record<string, unknown>;
|
|
425
|
+
/** Field(s) — typically a `.unique()` column or unique index — used to look up an existing row. */
|
|
426
|
+
target: UpsertTarget;
|
|
427
|
+
/** Patch applied when an existing row matches the `target`. Defaults to `create`. */
|
|
428
|
+
update?: Record<string, unknown>;
|
|
429
|
+
}
|
|
430
|
+
/** Result of an `upsert`: the row's id and whether it was freshly inserted (`true`) or updated (`false`). */
|
|
431
|
+
interface UpsertResult {
|
|
432
|
+
created: boolean;
|
|
433
|
+
id: string;
|
|
434
|
+
}
|
|
435
|
+
/** Argument to the per-table `upsertMany` accessor — a shared `target` plus per-row create/update payloads. */
|
|
436
|
+
interface UpsertManyArgs {
|
|
437
|
+
rows: ReadonlyArray<{
|
|
438
|
+
create: Record<string, unknown>;
|
|
439
|
+
update?: Record<string, unknown>;
|
|
440
|
+
}>;
|
|
441
|
+
target: UpsertTarget;
|
|
442
|
+
}
|
|
412
443
|
/**
|
|
413
444
|
* Bind a structural writer to one table, producing its `ctx.db` table accessor.
|
|
414
445
|
*
|
|
@@ -426,7 +457,7 @@ declare const bindTableFacade: (writer: FacadeWriterLike, tableName: string) =>
|
|
|
426
457
|
interface OrmLike {
|
|
427
458
|
delete: (table: string, id: string) => Promise<void>;
|
|
428
459
|
insert: (table: string) => {
|
|
429
|
-
values: (document: Record<string, unknown>) => Promise<string>;
|
|
460
|
+
values: (document: Record<string, unknown>) => Promise<null | string>;
|
|
430
461
|
};
|
|
431
462
|
query: Record<string, FacadeEntry>;
|
|
432
463
|
replace: (table: string, id: string) => {
|
|
@@ -1168,6 +1199,22 @@ interface TableBuilder<Shape extends Record<string, Validator> = Record<string,
|
|
|
1168
1199
|
}) => TableBuilder<Shape>;
|
|
1169
1200
|
/** Route storage by the named field — one DO per distinct value. */
|
|
1170
1201
|
shardBy: (field: keyof Shape & string) => TableBuilder<Shape>;
|
|
1202
|
+
/**
|
|
1203
|
+
* Turn on soft delete. Adds a nullable timestamp column (`options.field`,
|
|
1204
|
+
* default `deletedAt`) and changes `ctx.db.<table>.delete()` to **set** it
|
|
1205
|
+
* instead of removing the row; `onDelete: "cascade"` children are recursively
|
|
1206
|
+
* soft-deleted too. **List reads** (`findMany`/`findFirst`/`query()`/`count`/
|
|
1207
|
+
* `aggregate`/relation loads) then hide soft-deleted rows unless they pass
|
|
1208
|
+
* `includeDeleted: true`; by-id `get`/`patch`/`replace` and the new
|
|
1209
|
+
* `restore()` still address the row directly. `hardDelete()` physically
|
|
1210
|
+
* removes it (cascading as a real delete). Note: `includeDeleted` is a read
|
|
1211
|
+
* scope, not access control — anyone who can run the read can set it; a unique
|
|
1212
|
+
* index still rejects a new row that collides with a soft-deleted one (the row
|
|
1213
|
+
* physically persists).
|
|
1214
|
+
*/
|
|
1215
|
+
softDelete: (options?: {
|
|
1216
|
+
field?: string;
|
|
1217
|
+
}) => TableBuilder<Shape>;
|
|
1171
1218
|
/** Declare named lifecycle triggers fired inline within the write path. */
|
|
1172
1219
|
triggers: (build: (t: TriggerBuilder<Shape>) => Record<string, TriggerDefinition>) => TableBuilder<Shape>;
|
|
1173
1220
|
/** Declare a vector index over a single text field on this table. */
|
|
@@ -1190,7 +1237,7 @@ interface VectorIndexOptions {
|
|
|
1190
1237
|
* Build a table definition. Returned object is both the table definition (for
|
|
1191
1238
|
* `defineSchema`) and a fluent builder for indexes + sharding metadata.
|
|
1192
1239
|
*/
|
|
1193
|
-
declare const defineTable: <Shape extends Record<string, Validator>>(
|
|
1240
|
+
declare const defineTable: <Shape extends Record<string, Validator>>(inputShape: Shape) => TableBuilder<Shape>;
|
|
1194
1241
|
/**
|
|
1195
1242
|
* Declare a standalone vector index (DSL Shape B). Pass the returned value in
|
|
1196
1243
|
* the `vectorIndexes` map of {@link defineSchema} when the source is derived
|
|
@@ -1262,6 +1309,28 @@ type ExtendableSchema<T extends Record<string, TableDefinition>> = {
|
|
|
1262
1309
|
readonly key: Key;
|
|
1263
1310
|
}) => ExtendableSchema<PrefixedTables<X, Key> & T>;
|
|
1264
1311
|
/**
|
|
1312
|
+
* Pin every Durable Object the app reaches — shards, fan-out, subscriptions,
|
|
1313
|
+
* the scheduler, and `ctx.containers` — to a Cloudflare data-residency
|
|
1314
|
+
* jurisdiction (`"eu"`, `"us"`, `"fedramp"`). Codegen reads this off the
|
|
1315
|
+
* schema and emits it into the generated worker's `createWorker({ jurisdiction })`
|
|
1316
|
+
* (and `ctx.scheduler` / `ctx.containers`). Non-mutating: returns a fresh
|
|
1317
|
+
* `ExtendableSchema`, so it composes with `.rls(...)` / `.extend(...)` in any order.
|
|
1318
|
+
*
|
|
1319
|
+
* ⚠️ **Set this once, before your first deploy — changing or removing it
|
|
1320
|
+
* strands data.** A Durable Object name maps to a *different* ID in each
|
|
1321
|
+
* jurisdiction, so toggling this on an existing app makes every shard, scheduler
|
|
1322
|
+
* job, and session DO resolve to a NEW, empty DO; the previous data stays in the
|
|
1323
|
+
* old jurisdiction's DOs and is no longer reachable. There is no in-place
|
|
1324
|
+
* migration — you would have to export from the old jurisdiction and import
|
|
1325
|
+
* into the new one.
|
|
1326
|
+
*
|
|
1327
|
+
* Note: this pins **DO-backed** state only. D1-backed state — `.global()`
|
|
1328
|
+
* tables and `@lunora/auth` sessions alike — is governed by D1's own location
|
|
1329
|
+
* settings, not this option.
|
|
1330
|
+
* @see https://developers.cloudflare.com/durable-objects/reference/data-location/
|
|
1331
|
+
*/
|
|
1332
|
+
jurisdiction: (jurisdiction: DurableObjectJurisdiction) => ExtendableSchema<T>;
|
|
1333
|
+
/**
|
|
1265
1334
|
* Turn on secure-by-default RLS for the whole schema. Every table is then
|
|
1266
1335
|
* protected — the DO/D1 write path denies raw, non-RLS `ctx.db` access, so a
|
|
1267
1336
|
* procedure that forgets `.use(rls(...))` fails closed. Opt a table out with
|
|
@@ -1562,7 +1631,9 @@ interface DatabaseWriterLike {
|
|
|
1562
1631
|
*/
|
|
1563
1632
|
aggregate: (tableName: string, options: AggregateArgs) => Promise<null | number>;
|
|
1564
1633
|
count: (tableName: string, whereOrArgs?: CountArgs | WhereInput) => Promise<number>;
|
|
1565
|
-
delete: (id: string, expectedTable?: string
|
|
1634
|
+
delete: (id: string, expectedTable?: string, options?: {
|
|
1635
|
+
hard?: boolean;
|
|
1636
|
+
}) => Promise<void>;
|
|
1566
1637
|
deleteMany: (ids: ReadonlyArray<string>, options?: {
|
|
1567
1638
|
limit?: number;
|
|
1568
1639
|
}, expectedTable?: string) => Promise<{
|
|
@@ -1633,6 +1704,7 @@ interface DatabaseWriterLike {
|
|
|
1633
1704
|
*/
|
|
1634
1705
|
rankPage: (tableName: string, indexName: string, options?: RankPageArgs) => Promise<QueryPage>;
|
|
1635
1706
|
replace: (id: string, document: Record<string, unknown>, expectedTable?: string) => Promise<void>;
|
|
1707
|
+
restore?: (id: string, expectedTable?: string) => Promise<void>;
|
|
1636
1708
|
}
|
|
1637
1709
|
/**
|
|
1638
1710
|
* What a procedure's `ctx.db` must structurally satisfy for the middleware
|
|
@@ -1738,4 +1810,4 @@ interface StorageContextIn {
|
|
|
1738
1810
|
}
|
|
1739
1811
|
declare const storageRules: <Context extends StorageContextIn = StorageContextIn>(rules: ReadonlyArray<StorageRule<Context>>, options?: StorageRulesOptions) => Middleware<Context, Context>;
|
|
1740
1812
|
declare const VERSION = "0.0.0";
|
|
1741
|
-
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, type DefinePluginOptions, type DefinePolicyInput, type DefinePresenceOptions, type DefineStorageRuleInput, 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 InferArgs, type InferEnv, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraErrorCode, 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 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 RegisteredQuery, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type Role, type Schema, type SchemaExtension, 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, composePluginMiddleware, createPolicyDsl, defineAggregateIndex, defineComponent, defineEnv, defineMigration, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
|
|
1813
|
+
export { type ActionBuilder, type ActionCtx, type AggregateIndexDefinition, type AggregateIndexOptions, type AggregateOp, type ArgsValidator, type Component, type ComponentFunctions, type CreateOptions, type DataModelInit, type DefineComponentOptions, 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 InferArgs, type InferEnv, type InlineAggregateIndexOptions, type InlineRankIndexOptions, type InternalActionBuilder, type InternalMutationBuilder, type InternalQueryBuilder, type LifecycleEvent, type LifecycleHandler, type LunoraBuilders, LunoraEnvError, LunoraError, type LunoraErrorCode, 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 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 RegisteredQuery, type RegisteredStream, type RelationBuilder, type RelationDefinition, type RlsOptions, type Role, type Schema, type SchemaExtension, 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, composePluginMiddleware, createPolicyDsl, defineAggregateIndex, defineComponent, defineEnv, defineMigration, definePermission, definePlugin, definePolicies, definePolicy, definePresence, defineRankIndex, defineRole, defineSchema, defineSchemaExtension, defineStorageRule, defineStorageRules, defineTable, defineVectorIndex, httpAction, httpRoute, httpRouter, initLunora, installPlugins, mask, mergeSchemaExtension, onConnect, onDisconnect, presenceExtension, protectPublic, redactSecrets, rls, serveStorageObject, storageRules };
|
package/dist/index.mjs
CHANGED
|
@@ -2,21 +2,21 @@ export { default as asBucketStorage } from './packem_shared/asBucketStorage-Cnxd
|
|
|
2
2
|
export { initLunora } from './packem_shared/initLunora-CATvPsVt.mjs';
|
|
3
3
|
export { LunoraEnvError, defineEnv, redactSecrets } from './packem_shared/LunoraEnvError-DjFkpkSP.mjs';
|
|
4
4
|
export { LunoraError } from './packem_shared/LunoraError-DhggBJZF.mjs';
|
|
5
|
-
export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-
|
|
5
|
+
export { bindOrm, bindTableFacade } from './packem_shared/bindOrm-Ce57S3N9.mjs';
|
|
6
6
|
export { httpAction, httpRoute, httpRouter, serveStorageObject } from './packem_shared/httpAction-B7FYUEgr.mjs';
|
|
7
7
|
export { onConnect, onDisconnect } from './packem_shared/onConnect-CIPXKPyw.mjs';
|
|
8
8
|
export { defineMigration } from './packem_shared/defineMigration-CAJLr6fx.mjs';
|
|
9
9
|
export { composePluginMiddleware, defineComponent, definePlugin, defineSchemaExtension, installPlugins, mergeSchemaExtension } from './packem_shared/composePluginMiddleware-Ck5_TUO8.mjs';
|
|
10
|
-
export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-
|
|
10
|
+
export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-BgBQsqQ-.mjs';
|
|
11
11
|
export { protectPublic } from './packem_shared/protectPublic-BjFkQ_Or.mjs';
|
|
12
|
-
export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-
|
|
12
|
+
export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-C2gT1GzM.mjs';
|
|
13
13
|
export { anyApi } from './types.mjs';
|
|
14
14
|
export { cronJobs } from '@lunora/scheduler';
|
|
15
15
|
export { ValidationError, v } from '@lunora/values';
|
|
16
16
|
export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole } from './packem_shared/createPolicyDsl-De67zPDS.mjs';
|
|
17
17
|
export { defineStorageRule, defineStorageRules } from './packem_shared/defineStorageRule-qu0mpilX.mjs';
|
|
18
|
-
export { mask } from './packem_shared/mask-
|
|
19
|
-
export { rls } from './packem_shared/rls-
|
|
18
|
+
export { mask } from './packem_shared/mask-eCUYOwhd.mjs';
|
|
19
|
+
export { rls } from './packem_shared/rls-Bi9HiyDC.mjs';
|
|
20
20
|
export { storageRules } from './packem_shared/storageRules-4a30FSpI.mjs';
|
|
21
21
|
|
|
22
22
|
const VERSION = "0.0.0";
|
|
@@ -3,7 +3,7 @@ import { initLunora } from './initLunora-CATvPsVt.mjs';
|
|
|
3
3
|
import { LunoraError } from './LunoraError-DhggBJZF.mjs';
|
|
4
4
|
import { onDisconnect } from './onConnect-CIPXKPyw.mjs';
|
|
5
5
|
import { defineSchemaExtension, defineComponent } from './composePluginMiddleware-Ck5_TUO8.mjs';
|
|
6
|
-
import { defineTable } from './defineAggregateIndex-
|
|
6
|
+
import { defineTable } from './defineAggregateIndex-C2gT1GzM.mjs';
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TTL_MS = 3e4;
|
|
9
9
|
const MAX_DATA_BYTES = 4096;
|
|
@@ -1,4 +1,42 @@
|
|
|
1
|
+
const isUniqueConflict = (error) => typeof error === "object" && error !== null && error.code === "CONFLICT" && error.kind === "unique";
|
|
2
|
+
const buildUpsertWhere = (tableName, target, create) => {
|
|
3
|
+
const fields = typeof target === "string" ? [target] : target;
|
|
4
|
+
if (fields.length === 0) {
|
|
5
|
+
throw new Error(`ctx.db.${tableName}.upsert: "target" must name at least one field`);
|
|
6
|
+
}
|
|
7
|
+
const where = {};
|
|
8
|
+
for (const field of fields) {
|
|
9
|
+
if (!(field in create)) {
|
|
10
|
+
throw new Error(`ctx.db.${tableName}.upsert: target field "${field}" is missing from the create document`);
|
|
11
|
+
}
|
|
12
|
+
where[field] = create[field];
|
|
13
|
+
}
|
|
14
|
+
return where;
|
|
15
|
+
};
|
|
1
16
|
const bindTableFacade = (writer, tableName) => {
|
|
17
|
+
const insert = async (document, options) => {
|
|
18
|
+
if (options?.skipDuplicates !== true) {
|
|
19
|
+
return writer.insert(tableName, document);
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
return await writer.insert(tableName, document);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (isUniqueConflict(error)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const upsert = async ({ create, target, update }) => {
|
|
31
|
+
const where = buildUpsertWhere(tableName, target, create);
|
|
32
|
+
const existing = await writer.findFirst(tableName, { where });
|
|
33
|
+
if (existing && typeof existing["_id"] === "string") {
|
|
34
|
+
await writer.patch(existing["_id"], update ?? create, tableName);
|
|
35
|
+
return { created: false, id: existing["_id"] };
|
|
36
|
+
}
|
|
37
|
+
const id = await writer.insert(tableName, create);
|
|
38
|
+
return { created: true, id };
|
|
39
|
+
};
|
|
2
40
|
return {
|
|
3
41
|
aggregate: (options) => writer.aggregate(tableName, options),
|
|
4
42
|
count: (where) => writer.count(tableName, where),
|
|
@@ -14,12 +52,17 @@ const bindTableFacade = (writer, tableName) => {
|
|
|
14
52
|
}
|
|
15
53
|
return writer.deleteMany(ids, options, tableName);
|
|
16
54
|
},
|
|
55
|
+
// `exists` reuses `findFirst` (RLS-filtered, indexed when a `.withIndex`-able
|
|
56
|
+
// `where` is supplied) and only asks whether a row came back — no count scan.
|
|
57
|
+
exists: async (where) => await writer.findFirst(tableName, where === void 0 ? void 0 : { where }) !== null,
|
|
17
58
|
findFirst: (args) => writer.findFirst(tableName, args),
|
|
18
59
|
findFirstOrThrow: (args) => writer.findFirstOrThrow(tableName, args),
|
|
19
60
|
findMany: (args) => writer.findMany(tableName, args),
|
|
20
61
|
get: (id) => writer.get(id, tableName),
|
|
21
62
|
groupBy: (options) => writer.groupBy(tableName, options),
|
|
22
|
-
|
|
63
|
+
// Physical removal — bypasses `.softDelete()`. RLS gates it as a delete.
|
|
64
|
+
hardDelete: (id) => writer.delete(id, tableName, { hard: true }),
|
|
65
|
+
insert,
|
|
23
66
|
insertMany: (documents, options) => {
|
|
24
67
|
if (writer.insertMany === void 0) {
|
|
25
68
|
throw new Error(`ctx.db.${tableName}.insertMany is unavailable: this writer has no batch insert`);
|
|
@@ -42,6 +85,20 @@ const bindTableFacade = (writer, tableName) => {
|
|
|
42
85
|
rank: (indexName, options) => writer.rank(tableName, indexName, options),
|
|
43
86
|
rankPage: (indexName, options) => writer.rankPage(tableName, indexName, options),
|
|
44
87
|
replace: (id, document) => writer.replace(id, document, tableName),
|
|
88
|
+
restore: async (id) => {
|
|
89
|
+
if (!writer.restore) {
|
|
90
|
+
throw new Error(`ctx.db.${tableName}.restore is unavailable: this writer has no restore (is the table .softDelete()?)`);
|
|
91
|
+
}
|
|
92
|
+
await writer.restore(id, tableName);
|
|
93
|
+
},
|
|
94
|
+
upsert,
|
|
95
|
+
upsertMany: async ({ rows, target }) => {
|
|
96
|
+
const results = [];
|
|
97
|
+
for (const row of rows) {
|
|
98
|
+
results.push(await upsert({ create: row.create, target, update: row.update }));
|
|
99
|
+
}
|
|
100
|
+
return results;
|
|
101
|
+
},
|
|
45
102
|
withSearchIndex: (indexName, search) => writer.query(tableName).withSearchIndex(indexName, search)
|
|
46
103
|
};
|
|
47
104
|
};
|
package/dist/packem_shared/{defineAggregateIndex-DxSso0rH.mjs → defineAggregateIndex-C2gT1GzM.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isOrWrapsFromValidator } from '@lunora/values';
|
|
1
|
+
import { isOrWrapsFromValidator, v } from '@lunora/values';
|
|
2
2
|
import { mergeSchemaExtension } from './composePluginMiddleware-Ck5_TUO8.mjs';
|
|
3
3
|
|
|
4
4
|
const relationBuilder = {
|
|
@@ -22,7 +22,8 @@ const createTriggerBuilder = () => {
|
|
|
22
22
|
beforeUpdate: (handler) => makeTrigger("before", "update", handler)
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
-
const defineTable = (
|
|
25
|
+
const defineTable = (inputShape) => {
|
|
26
|
+
const shape = { ...inputShape };
|
|
26
27
|
for (const [columnName, validator] of Object.entries(shape)) {
|
|
27
28
|
if (isOrWrapsFromValidator(validator)) {
|
|
28
29
|
throw new Error(`defineTable: column "${columnName}" uses v.from() which is args-only — table columns need a concrete v.* type`);
|
|
@@ -39,6 +40,7 @@ const defineTable = (shape) => {
|
|
|
39
40
|
let shardMode = { kind: "root" };
|
|
40
41
|
let isExternallyManaged = false;
|
|
41
42
|
let isPublic = false;
|
|
43
|
+
let softDelete;
|
|
42
44
|
const builder = {
|
|
43
45
|
aggregateIndex(name, options) {
|
|
44
46
|
const op = options?.op ?? "count";
|
|
@@ -132,6 +134,17 @@ const defineTable = (shape) => {
|
|
|
132
134
|
get shardMode() {
|
|
133
135
|
return shardMode;
|
|
134
136
|
},
|
|
137
|
+
get softDeleteMode() {
|
|
138
|
+
return softDelete;
|
|
139
|
+
},
|
|
140
|
+
softDelete(options) {
|
|
141
|
+
const field = options?.field ?? "deletedAt";
|
|
142
|
+
softDelete = { field };
|
|
143
|
+
if (!(field in shape)) {
|
|
144
|
+
shape[field] = v.optional(v.number().nullable());
|
|
145
|
+
}
|
|
146
|
+
return builder;
|
|
147
|
+
},
|
|
135
148
|
get triggerMap() {
|
|
136
149
|
return triggers;
|
|
137
150
|
},
|
|
@@ -192,6 +205,9 @@ const withExtend = (schema) => {
|
|
|
192
205
|
extend(extension) {
|
|
193
206
|
return withExtend(mergeSchemaExtension(schema, extension));
|
|
194
207
|
},
|
|
208
|
+
jurisdiction(_jurisdiction) {
|
|
209
|
+
return withExtend(schema);
|
|
210
|
+
},
|
|
195
211
|
rls(mode) {
|
|
196
212
|
return withExtend({ ...schema, rlsMode: mode });
|
|
197
213
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LunoraError } from './LunoraError-DhggBJZF.mjs';
|
|
2
|
-
import { bindTableFacade, bindOrm } from './bindOrm-
|
|
2
|
+
import { bindTableFacade, bindOrm } from './bindOrm-Ce57S3N9.mjs';
|
|
3
3
|
|
|
4
4
|
const permissionName = (permission) => typeof permission === "string" ? permission : permission.name;
|
|
5
5
|
const indexRolePermissions = (roles) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LunoraError } from './LunoraError-DhggBJZF.mjs';
|
|
2
|
-
import { bindTableFacade, bindOrm } from './bindOrm-
|
|
2
|
+
import { bindTableFacade, bindOrm } from './bindOrm-Ce57S3N9.mjs';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_BATCH_LIMIT = 500;
|
|
5
5
|
const assertBatchLimit = (count, limit, op) => {
|
|
@@ -324,7 +324,7 @@ const wrapDatabase = (base, raw, perTable, context) => {
|
|
|
324
324
|
restrictsCounts: (args.restrictsCounts ?? false) || restricts
|
|
325
325
|
});
|
|
326
326
|
},
|
|
327
|
-
delete: (id, expectedTable) => gateById(id, "delete", (writer) => writer.delete(id, expectedTable), void 0, expectedTable),
|
|
327
|
+
delete: (id, expectedTable, options) => gateById(id, "delete", (writer) => writer.delete(id, expectedTable, options), void 0, expectedTable),
|
|
328
328
|
async deleteMany(ids, options, expectedTable) {
|
|
329
329
|
assertBatchLimit(ids.length, options?.limit, "deleteMany");
|
|
330
330
|
for (const id of ids) {
|
|
@@ -441,6 +441,22 @@ const wrapDatabase = (base, raw, perTable, context) => {
|
|
|
441
441
|
}
|
|
442
442
|
return reader.filter((document) => matchesWhere(document, baseWhere));
|
|
443
443
|
},
|
|
444
|
+
// Restore clears the soft-delete marker — a by-id un-delete, gated as an
|
|
445
|
+
// "update" (the policy that governs patch). No post-image check: the
|
|
446
|
+
// writer owns the marker field, so we only enforce the pre-image USING.
|
|
447
|
+
restore: (id, expectedTable) => gateById(
|
|
448
|
+
id,
|
|
449
|
+
"update",
|
|
450
|
+
async (writer) => {
|
|
451
|
+
const perform = writer.restore ?? raw.restore;
|
|
452
|
+
if (!perform) {
|
|
453
|
+
throw new LunoraError("BAD_REQUEST", "restore is not supported by this writer");
|
|
454
|
+
}
|
|
455
|
+
await perform(id, expectedTable);
|
|
456
|
+
},
|
|
457
|
+
void 0,
|
|
458
|
+
expectedTable
|
|
459
|
+
),
|
|
444
460
|
replace: (id, document, expectedTable) => gateById(
|
|
445
461
|
id,
|
|
446
462
|
"update",
|
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-Bi9HiyDC.mjs';
|
|
2
2
|
|
|
3
3
|
const expectPolicy = (policies, options = {}) => {
|
|
4
4
|
const rolePermissions = indexRolePermissions(options.roles);
|
package/dist/types.d.mts
CHANGED
|
@@ -5,6 +5,14 @@ type ArgsValidator = ValidatorMap;
|
|
|
5
5
|
type InferArgs<A extends ArgsValidator> = InferValidatorMap<A>;
|
|
6
6
|
/** Storage backend for a `.global()` table: D1 (default) or a Postgres/MySQL database via Cloudflare Hyperdrive (PlanetScale, Neon, …). */
|
|
7
7
|
type GlobalBackend = "d1" | "hyperdrive";
|
|
8
|
+
/**
|
|
9
|
+
* Cloudflare Durable Object data-residency jurisdiction declared via
|
|
10
|
+
* `defineSchema(...).jurisdiction("…")`. Restricts where every DO the app
|
|
11
|
+
* reaches runs and persists data (GDPR, FedRAMP, US data residency). Widening
|
|
12
|
+
* union — Cloudflare adds values over time.
|
|
13
|
+
* @see https://developers.cloudflare.com/durable-objects/reference/data-location/
|
|
14
|
+
*/
|
|
15
|
+
type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
|
|
8
16
|
/** How a table is routed at runtime. */
|
|
9
17
|
type ShardMode = {
|
|
10
18
|
backend?: GlobalBackend;
|
|
@@ -165,6 +173,20 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
|
|
|
165
173
|
shape: Shape;
|
|
166
174
|
shardMode: ShardMode;
|
|
167
175
|
/**
|
|
176
|
+
* Set by `.softDelete()` (named `softDeleteMode`, not `softDelete`, so the
|
|
177
|
+
* data field doesn't collide with the fluent `.softDelete()` builder method —
|
|
178
|
+
* same convention as `shardBy()`/`shardMode`). When present, the table carries
|
|
179
|
+
* a nullable timestamp column (`field`, default `deletedAt`):
|
|
180
|
+
* `ctx.db.<table>.delete()` flips it instead of physically removing the row,
|
|
181
|
+
* and **list reads** (`findMany`/`findFirst`/`query()`/`count`/`aggregate`/
|
|
182
|
+
* relation loads) hide rows whose `field` is set unless
|
|
183
|
+
* `includeDeleted: true` is passed. By-id `get`/`patch`/`replace` and
|
|
184
|
+
* `restore` are unaffected. Absent ⇒ deletes are physical, as before.
|
|
185
|
+
*/
|
|
186
|
+
softDeleteMode?: {
|
|
187
|
+
field: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
168
190
|
* Declared lifecycle triggers keyed by accessor name; empty unless
|
|
169
191
|
* `.triggers()` was called. Named `triggerMap` (not `triggers`) so the
|
|
170
192
|
* fluent `.triggers((t) => …)` builder method doesn't collide with this
|
|
@@ -1048,4 +1070,4 @@ interface ActionCtx {
|
|
|
1048
1070
|
*/
|
|
1049
1071
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1050
1072
|
declare const anyApi: AnyApi;
|
|
1051
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
|
1073
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
package/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,14 @@ type ArgsValidator = ValidatorMap;
|
|
|
5
5
|
type InferArgs<A extends ArgsValidator> = InferValidatorMap<A>;
|
|
6
6
|
/** Storage backend for a `.global()` table: D1 (default) or a Postgres/MySQL database via Cloudflare Hyperdrive (PlanetScale, Neon, …). */
|
|
7
7
|
type GlobalBackend = "d1" | "hyperdrive";
|
|
8
|
+
/**
|
|
9
|
+
* Cloudflare Durable Object data-residency jurisdiction declared via
|
|
10
|
+
* `defineSchema(...).jurisdiction("…")`. Restricts where every DO the app
|
|
11
|
+
* reaches runs and persists data (GDPR, FedRAMP, US data residency). Widening
|
|
12
|
+
* union — Cloudflare adds values over time.
|
|
13
|
+
* @see https://developers.cloudflare.com/durable-objects/reference/data-location/
|
|
14
|
+
*/
|
|
15
|
+
type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
|
|
8
16
|
/** How a table is routed at runtime. */
|
|
9
17
|
type ShardMode = {
|
|
10
18
|
backend?: GlobalBackend;
|
|
@@ -165,6 +173,20 @@ interface TableDefinition<Shape extends Record<string, Validator> = Record<strin
|
|
|
165
173
|
shape: Shape;
|
|
166
174
|
shardMode: ShardMode;
|
|
167
175
|
/**
|
|
176
|
+
* Set by `.softDelete()` (named `softDeleteMode`, not `softDelete`, so the
|
|
177
|
+
* data field doesn't collide with the fluent `.softDelete()` builder method —
|
|
178
|
+
* same convention as `shardBy()`/`shardMode`). When present, the table carries
|
|
179
|
+
* a nullable timestamp column (`field`, default `deletedAt`):
|
|
180
|
+
* `ctx.db.<table>.delete()` flips it instead of physically removing the row,
|
|
181
|
+
* and **list reads** (`findMany`/`findFirst`/`query()`/`count`/`aggregate`/
|
|
182
|
+
* relation loads) hide rows whose `field` is set unless
|
|
183
|
+
* `includeDeleted: true` is passed. By-id `get`/`patch`/`replace` and
|
|
184
|
+
* `restore` are unaffected. Absent ⇒ deletes are physical, as before.
|
|
185
|
+
*/
|
|
186
|
+
softDeleteMode?: {
|
|
187
|
+
field: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
168
190
|
* Declared lifecycle triggers keyed by accessor name; empty unless
|
|
169
191
|
* `.triggers()` was called. Named `triggerMap` (not `triggers`) so the
|
|
170
192
|
* fluent `.triggers((t) => …)` builder method doesn't collide with this
|
|
@@ -1048,4 +1070,4 @@ interface ActionCtx {
|
|
|
1048
1070
|
*/
|
|
1049
1071
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1050
1072
|
declare const anyApi: AnyApi;
|
|
1051
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, anyApi };
|
|
1073
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type FunctionKind, type FunctionVisibility, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LunoraLogger, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type ShardMode, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, 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.4",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
66
|
-
"@lunora/values": "1.0.0-alpha.
|
|
65
|
+
"@lunora/scheduler": "1.0.0-alpha.2",
|
|
66
|
+
"@lunora/values": "1.0.0-alpha.2",
|
|
67
67
|
"drizzle-orm": "^0.45.2",
|
|
68
68
|
"hono": "^4.12.26"
|
|
69
69
|
},
|