@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 +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +2 -2
- package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-pc2cfrnm.mjs → PRESENCE_DEFAULT_TTL_MS-BAD0QPAg.mjs} +1 -1
- package/dist/packem_shared/{mask-BT1YgRbF.mjs → mask-DSBtA3qp.mjs} +23 -0
- package/dist/types.d.mts +24 -2
- package/dist/types.d.ts +24 -2
- package/package.json +4 -4
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-
|
|
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-
|
|
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.<name>` /
|
|
689
|
+
* `agents.<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
|
-
|
|
697
|
-
|
|
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.<name>` /
|
|
714
|
+
* `agents.<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.<name>` /
|
|
689
|
+
* `agents.<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
|
-
|
|
697
|
-
|
|
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.<name>` /
|
|
714
|
+
* `agents.<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.
|
|
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.
|
|
66
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
67
|
-
"@lunora/values": "1.0.0-alpha.
|
|
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
|
},
|