@lunora/server 1.0.0-alpha.22 → 1.0.0-alpha.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -863,12 +863,14 @@ interface QueryArgs$1 {
863
863
  baseWhere?: unknown;
864
864
  cursor?: null | string;
865
865
  limit?: number;
866
+ orderBy?: ReadonlyArray<Record<string, unknown>>;
866
867
  where?: unknown;
867
868
  with?: Record<string, unknown>;
868
869
  }
869
870
  interface AggregateArgs$1 {
870
871
  field?: string;
871
872
  op: string;
873
+ where?: unknown;
872
874
  }
873
875
  interface GroupByArgs$1 {
874
876
  agg?: {
@@ -876,6 +878,7 @@ interface GroupByArgs$1 {
876
878
  op: string;
877
879
  };
878
880
  by: ReadonlyArray<string>;
881
+ where?: unknown;
879
882
  }
880
883
  interface TableReaderLike$1 {
881
884
  collect: () => Promise<Record<string, unknown>[]>;
package/dist/index.d.ts CHANGED
@@ -863,12 +863,14 @@ interface QueryArgs$1 {
863
863
  baseWhere?: unknown;
864
864
  cursor?: null | string;
865
865
  limit?: number;
866
+ orderBy?: ReadonlyArray<Record<string, unknown>>;
866
867
  where?: unknown;
867
868
  with?: Record<string, unknown>;
868
869
  }
869
870
  interface AggregateArgs$1 {
870
871
  field?: string;
871
872
  op: string;
873
+ where?: unknown;
872
874
  }
873
875
  interface GroupByArgs$1 {
874
876
  agg?: {
@@ -876,6 +878,7 @@ interface GroupByArgs$1 {
876
878
  op: string;
877
879
  };
878
880
  by: ReadonlyArray<string>;
881
+ where?: unknown;
879
882
  }
880
883
  interface TableReaderLike$1 {
881
884
  collect: () => Promise<Record<string, unknown>[]>;
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ export { onConnect, onDisconnect } from './packem_shared/onConnect-CIPXKPyw.mjs'
10
10
  export { defineMigration } from './packem_shared/defineMigration-Hx01yIht.mjs';
11
11
  export { defineMutator } from './packem_shared/defineMutator-EIXAWhs9.mjs';
12
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-pc2cfrnm.mjs';
13
+ export { PRESENCE_DEFAULT_TTL_MS, PRESENCE_TABLE, definePresence, presenceExtension } from './packem_shared/PRESENCE_DEFAULT_TTL_MS-BAD0QPAg.mjs';
14
14
  export { protectPublic } from './packem_shared/protectPublic-BlcGpiRc.mjs';
15
15
  export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex } from './packem_shared/defineAggregateIndex-znq4ygKQ.mjs';
16
16
  export { defineShape } from './packem_shared/defineShape-C5scNOrf.mjs';
@@ -20,7 +20,7 @@ export { ValidationError, v } from '@lunora/values';
20
20
  export { buildRlsReadRegistry, composeShapeReadWhere } from './packem_shared/buildRlsReadRegistry-D54vUQe4.mjs';
21
21
  export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole } from './packem_shared/createPolicyDsl-By3QB4he.mjs';
22
22
  export { defineStorageRule, defineStorageRules } from './packem_shared/defineStorageRule-B5nL4Z1P.mjs';
23
- export { mask } from './packem_shared/mask-BT1YgRbF.mjs';
23
+ export { mask } from './packem_shared/mask-DSBtA3qp.mjs';
24
24
  export { rls } from './packem_shared/rls-B_ZWgslr.mjs';
25
25
  export { storageRules } from './packem_shared/storageRules-6QxzDOcx.mjs';
26
26
 
@@ -32,7 +32,7 @@ const definePresence = (options = {}) => {
32
32
  }).mutation(async ({ args, ctx: context }) => {
33
33
  const lastSeen = Date.now();
34
34
  const userId = context.auth.userId ?? void 0;
35
- if (args.data !== void 0 && JSON.stringify(args.data).length > MAX_DATA_BYTES) {
35
+ if (args.data !== void 0 && new TextEncoder().encode(JSON.stringify(args.data)).length > MAX_DATA_BYTES) {
36
36
  throw new LunoraError("BAD_REQUEST", `presence data exceeds the ${String(MAX_DATA_BYTES)}-byte limit`);
37
37
  }
38
38
  const existing = await context.db.query(PRESENCE_TABLE).withIndex("byRoomSession", (q) => q.eq("roomId", args.roomId).eq("sessionId", args.sessionId)).first();
@@ -191,32 +191,54 @@ const wrapDatabase = (base, perTable, context) => {
191
191
  }
192
192
  }
193
193
  };
194
+ const assertOrderByAllowed = (tableName, orderBy, method) => {
195
+ const columns = perTable.get(tableName);
196
+ if (!columns || !Array.isArray(orderBy)) {
197
+ return;
198
+ }
199
+ for (const entry of orderBy) {
200
+ if (entry && typeof entry === "object" && !Array.isArray(entry)) {
201
+ for (const field of Object.keys(entry)) {
202
+ if (field in columns) {
203
+ throw new LunoraError("MASK_UNSUPPORTED", `${method}() ordering "${tableName}" by masked column "${field}" is not supported`);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ };
194
209
  const wrapped = {
195
210
  ...base,
196
211
  aggregate(tableName, options) {
197
212
  assertReductionAllowed(tableName, [options.field], "aggregate");
213
+ assertWhereAllowed(tableName, options.where, "aggregate");
198
214
  return base.aggregate(tableName, options);
199
215
  },
200
216
  count(tableName, whereOrArgs) {
201
217
  const wrapper = whereOrArgs && typeof whereOrArgs === "object" && !Array.isArray(whereOrArgs) ? whereOrArgs : void 0;
202
218
  const where = wrapper && ("where" in wrapper || "baseWhere" in wrapper || "restrictsCounts" in wrapper) ? wrapper.where : whereOrArgs;
203
219
  assertWhereAllowed(tableName, where, "count");
220
+ if (wrapper) {
221
+ assertWhereAllowed(tableName, wrapper.baseWhere, "count");
222
+ }
204
223
  return base.count(tableName, whereOrArgs);
205
224
  },
206
225
  async findFirst(tableName, args) {
207
226
  assertWhereAllowed(tableName, args?.where, "findFirst");
227
+ assertOrderByAllowed(tableName, args?.orderBy, "findFirst");
208
228
  const row = await base.findFirst(tableName, args);
209
229
  const columns = perTable.get(tableName);
210
230
  return row && columns ? maskRow(row, columns, context) : row;
211
231
  },
212
232
  async findFirstOrThrow(tableName, args) {
213
233
  assertWhereAllowed(tableName, args?.where, "findFirstOrThrow");
234
+ assertOrderByAllowed(tableName, args?.orderBy, "findFirstOrThrow");
214
235
  const row = await base.findFirstOrThrow(tableName, args);
215
236
  const columns = perTable.get(tableName);
216
237
  return columns ? maskRow(row, columns, context) : row;
217
238
  },
218
239
  async findMany(tableName, args) {
219
240
  assertWhereAllowed(tableName, args?.where, "findMany");
241
+ assertOrderByAllowed(tableName, args?.orderBy, "findMany");
220
242
  const page = await base.findMany(tableName, args);
221
243
  const columns = perTable.get(tableName);
222
244
  return columns ? maskPage(page, columns, context) : page;
@@ -231,6 +253,7 @@ const wrapDatabase = (base, perTable, context) => {
231
253
  },
232
254
  groupBy(tableName, options) {
233
255
  assertReductionAllowed(tableName, [...options.by, options.agg?.field], "groupBy");
256
+ assertWhereAllowed(tableName, options.where, "groupBy");
234
257
  return base.groupBy(tableName, options);
235
258
  },
236
259
  query(tableName) {
package/dist/types.d.mts CHANGED
@@ -684,6 +684,21 @@ interface ScheduledJob {
684
684
  /** Routing hint forwarded so dispatch lands on the right shard. */
685
685
  shardKey?: string;
686
686
  }
687
+ /**
688
+ * A schedulable durable-workflow reference — the generated `workflows.&lt;name>` /
689
+ * `agents.&lt;name>` object, which carries its `WORKFLOW_*`/`AGENT_*` binding and
690
+ * stable name. Structural mirror of `@lunora/scheduler`'s `WorkflowReference` so
691
+ * `ctx.scheduler` can target a workflow/agent without a dependency on
692
+ * `@lunora/scheduler` / `@lunora/workflow`. A scheduled workflow target starts a
693
+ * fresh instance on fire (the args become its `params`).
694
+ */
695
+ interface SchedulableWorkflowReference {
696
+ /** The `WORKFLOW_*`/`AGENT_*` binding name (present on a generated ref). */
697
+ readonly binding?: string;
698
+ readonly isLunoraWorkflow: true;
699
+ /** The workflow/agent export/stable name (present on a generated ref). */
700
+ readonly name?: string;
701
+ }
687
702
  interface Scheduler {
688
703
  /** Cancel a pending job by id. `cancelled` is `false` when no such job exists. */
689
704
  cancel: (id: string) => Promise<{
@@ -693,8 +708,15 @@ interface Scheduler {
693
708
  get: (id: string) => Promise<ScheduledJob | null>;
694
709
  /** List all pending scheduled jobs. */
695
710
  list: () => Promise<ScheduledJob[]>;
696
- runAfter: (delayMs: number, functionPath: string, args?: Record<string, unknown>) => Promise<string>;
697
- runAt: (timestampMs: number, functionPath: string, args?: Record<string, unknown>) => Promise<string>;
711
+ /**
712
+ * Schedule a one-shot run `delayMs` from now. `target` is a function path
713
+ * (`"ns:fn"`) dispatched as a one-shot, or a generated `workflows.&lt;name>` /
714
+ * `agents.&lt;name>` reference which starts a fresh durable instance on fire
715
+ * (the args become its `params`).
716
+ */
717
+ runAfter: (delayMs: number, target: SchedulableWorkflowReference | string, args?: Record<string, unknown>) => Promise<string>;
718
+ /** Like {@link Scheduler.runAfter} but fires at an absolute epoch-ms timestamp. */
719
+ runAt: (timestampMs: number, target: SchedulableWorkflowReference | string, args?: Record<string, unknown>) => Promise<string>;
698
720
  }
699
721
  /**
700
722
  * A workflow instance's lifecycle status. Clean public mirror of
package/dist/types.d.ts CHANGED
@@ -684,6 +684,21 @@ interface ScheduledJob {
684
684
  /** Routing hint forwarded so dispatch lands on the right shard. */
685
685
  shardKey?: string;
686
686
  }
687
+ /**
688
+ * A schedulable durable-workflow reference — the generated `workflows.&lt;name>` /
689
+ * `agents.&lt;name>` object, which carries its `WORKFLOW_*`/`AGENT_*` binding and
690
+ * stable name. Structural mirror of `@lunora/scheduler`'s `WorkflowReference` so
691
+ * `ctx.scheduler` can target a workflow/agent without a dependency on
692
+ * `@lunora/scheduler` / `@lunora/workflow`. A scheduled workflow target starts a
693
+ * fresh instance on fire (the args become its `params`).
694
+ */
695
+ interface SchedulableWorkflowReference {
696
+ /** The `WORKFLOW_*`/`AGENT_*` binding name (present on a generated ref). */
697
+ readonly binding?: string;
698
+ readonly isLunoraWorkflow: true;
699
+ /** The workflow/agent export/stable name (present on a generated ref). */
700
+ readonly name?: string;
701
+ }
687
702
  interface Scheduler {
688
703
  /** Cancel a pending job by id. `cancelled` is `false` when no such job exists. */
689
704
  cancel: (id: string) => Promise<{
@@ -693,8 +708,15 @@ interface Scheduler {
693
708
  get: (id: string) => Promise<ScheduledJob | null>;
694
709
  /** List all pending scheduled jobs. */
695
710
  list: () => Promise<ScheduledJob[]>;
696
- runAfter: (delayMs: number, functionPath: string, args?: Record<string, unknown>) => Promise<string>;
697
- runAt: (timestampMs: number, functionPath: string, args?: Record<string, unknown>) => Promise<string>;
711
+ /**
712
+ * Schedule a one-shot run `delayMs` from now. `target` is a function path
713
+ * (`"ns:fn"`) dispatched as a one-shot, or a generated `workflows.&lt;name>` /
714
+ * `agents.&lt;name>` reference which starts a fresh durable instance on fire
715
+ * (the args become its `params`).
716
+ */
717
+ runAfter: (delayMs: number, target: SchedulableWorkflowReference | string, args?: Record<string, unknown>) => Promise<string>;
718
+ /** Like {@link Scheduler.runAfter} but fires at an absolute epoch-ms timestamp. */
719
+ runAt: (timestampMs: number, target: SchedulableWorkflowReference | string, args?: Record<string, unknown>) => Promise<string>;
698
720
  }
699
721
  /**
700
722
  * A workflow instance's lifecycle status. Clean public mirror of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/server",
3
- "version": "1.0.0-alpha.22",
3
+ "version": "1.0.0-alpha.24",
4
4
  "description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
5
5
  "keywords": [
6
6
  "backend",
@@ -62,9 +62,9 @@
62
62
  "access": "public"
63
63
  },
64
64
  "dependencies": {
65
- "@lunora/errors": "1.0.0-alpha.3",
66
- "@lunora/scheduler": "1.0.0-alpha.7",
67
- "@lunora/values": "1.0.0-alpha.6",
65
+ "@lunora/errors": "1.0.0-alpha.4",
66
+ "@lunora/scheduler": "1.0.0-alpha.9",
67
+ "@lunora/values": "1.0.0-alpha.7",
68
68
  "drizzle-orm": "^0.45.2",
69
69
  "hono": "^4.12.28"
70
70
  },