@lunora/server 1.0.0-alpha.21 → 1.0.0-alpha.23

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
@@ -1,6 +1,6 @@
1
1
  import { Validator, Infer, ValidatorMap, InferValidatorMap, 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, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.mjs";
3
+ import { ArgsValidator, InferArgs, RegisteredAction, X402ProcedureConfig, 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 CachePurge, 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
5
  import { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
6
6
  export type { LunoraErrorCode } from '@lunora/errors';
@@ -85,6 +85,13 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
85
85
  signal: AbortSignal;
86
86
  }) => AsyncGenerator<R, void, void> | AsyncIterable<R>) => RegisteredStream<Args, R>;
87
87
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => QueryBuilder<ContextOut, Args, Output>;
88
+ /**
89
+ * Mark this query as paid. The origin worker answers an unpaid client RPC
90
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
91
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
92
+ * recipient, and facilitator come from the worker-level x402 charge config.
93
+ */
94
+ x402: (config: X402ProcedureConfig) => QueryBuilder<Context, Args, Output>;
88
95
  }
89
96
  interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefined> {
90
97
  readonly __lunoraProcedure: "mutation";
@@ -98,6 +105,13 @@ interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefine
98
105
  }) => Output | Promise<Output>) => RegisteredMutation<Args, Output>;
99
106
  output: <V extends Validator>(validator: V) => MutationBuilder<Context, Args, Infer<V>>;
100
107
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => MutationBuilder<ContextOut, Args, Output>;
108
+ /**
109
+ * Mark this mutation as paid. The origin worker answers an unpaid client RPC
110
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
111
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
112
+ * recipient, and facilitator come from the worker-level x402 charge config.
113
+ */
114
+ x402: (config: X402ProcedureConfig) => MutationBuilder<Context, Args, Output>;
101
115
  }
102
116
  interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined> {
103
117
  readonly __lunoraProcedure: "action";
@@ -111,6 +125,13 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
111
125
  input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
112
126
  output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
113
127
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
128
+ /**
129
+ * Mark this action as paid. The origin worker answers an unpaid client RPC
130
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
131
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
132
+ * recipient, and facilitator come from the worker-level x402 charge config.
133
+ */
134
+ x402: (config: X402ProcedureConfig) => ActionBuilder<Context, Args, Output>;
114
135
  }
115
136
  /**
116
137
  * Internal builder variants. Identical to their public counterparts but carry
@@ -842,12 +863,14 @@ interface QueryArgs$1 {
842
863
  baseWhere?: unknown;
843
864
  cursor?: null | string;
844
865
  limit?: number;
866
+ orderBy?: ReadonlyArray<Record<string, unknown>>;
845
867
  where?: unknown;
846
868
  with?: Record<string, unknown>;
847
869
  }
848
870
  interface AggregateArgs$1 {
849
871
  field?: string;
850
872
  op: string;
873
+ where?: unknown;
851
874
  }
852
875
  interface GroupByArgs$1 {
853
876
  agg?: {
@@ -855,6 +878,7 @@ interface GroupByArgs$1 {
855
878
  op: string;
856
879
  };
857
880
  by: ReadonlyArray<string>;
881
+ where?: unknown;
858
882
  }
859
883
  interface TableReaderLike$1 {
860
884
  collect: () => Promise<Record<string, unknown>[]>;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Validator, Infer, ValidatorMap, InferValidatorMap, 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, Secrets, LifecycleEvent, RegisteredLifecycleHook, TableDefinition, RegisteredFunction, VectorIndexDefinition, Schema, AggregateOp, DurableObjectJurisdiction, RelationDefinition, GlobalBackend, OnDeleteAction, ExternalSourceDefinition, TriggerBuilder, TriggerDefinition, VectorEmbedder, VectorMetric, AggregateIndexDefinition, RankIndexDefinition } from "./types.js";
3
+ import { ArgsValidator, InferArgs, RegisteredAction, X402ProcedureConfig, 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 CachePurge, 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 { LunoraError as LunoraError$1, LunoraErrorCode } from '@lunora/errors';
6
6
  export type { LunoraErrorCode } from '@lunora/errors';
@@ -85,6 +85,13 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
85
85
  signal: AbortSignal;
86
86
  }) => AsyncGenerator<R, void, void> | AsyncIterable<R>) => RegisteredStream<Args, R>;
87
87
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => QueryBuilder<ContextOut, Args, Output>;
88
+ /**
89
+ * Mark this query as paid. The origin worker answers an unpaid client RPC
90
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
91
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
92
+ * recipient, and facilitator come from the worker-level x402 charge config.
93
+ */
94
+ x402: (config: X402ProcedureConfig) => QueryBuilder<Context, Args, Output>;
88
95
  }
89
96
  interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefined> {
90
97
  readonly __lunoraProcedure: "mutation";
@@ -98,6 +105,13 @@ interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefine
98
105
  }) => Output | Promise<Output>) => RegisteredMutation<Args, Output>;
99
106
  output: <V extends Validator>(validator: V) => MutationBuilder<Context, Args, Infer<V>>;
100
107
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => MutationBuilder<ContextOut, Args, Output>;
108
+ /**
109
+ * Mark this mutation as paid. The origin worker answers an unpaid client RPC
110
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
111
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
112
+ * recipient, and facilitator come from the worker-level x402 charge config.
113
+ */
114
+ x402: (config: X402ProcedureConfig) => MutationBuilder<Context, Args, Output>;
101
115
  }
102
116
  interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined> {
103
117
  readonly __lunoraProcedure: "action";
@@ -111,6 +125,13 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
111
125
  input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
112
126
  output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
113
127
  use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
128
+ /**
129
+ * Mark this action as paid. The origin worker answers an unpaid client RPC
130
+ * with HTTP 402, verifies + settles the x402 payment, then dispatches. `price`
131
+ * is USD (a number of dollars or a `"0.01"`/`"$0.01"` string); the network,
132
+ * recipient, and facilitator come from the worker-level x402 charge config.
133
+ */
134
+ x402: (config: X402ProcedureConfig) => ActionBuilder<Context, Args, Output>;
114
135
  }
115
136
  /**
116
137
  * Internal builder variants. Identical to their public counterparts but carry
@@ -842,12 +863,14 @@ interface QueryArgs$1 {
842
863
  baseWhere?: unknown;
843
864
  cursor?: null | string;
844
865
  limit?: number;
866
+ orderBy?: ReadonlyArray<Record<string, unknown>>;
845
867
  where?: unknown;
846
868
  with?: Record<string, unknown>;
847
869
  }
848
870
  interface AggregateArgs$1 {
849
871
  field?: string;
850
872
  op: string;
873
+ where?: unknown;
851
874
  }
852
875
  interface GroupByArgs$1 {
853
876
  agg?: {
@@ -855,6 +878,7 @@ interface GroupByArgs$1 {
855
878
  op: string;
856
879
  };
857
880
  by: ReadonlyArray<string>;
881
+ where?: unknown;
858
882
  }
859
883
  interface TableReaderLike$1 {
860
884
  collect: () => Promise<Record<string, unknown>[]>;
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export { default as asBucketStorage } from './packem_shared/asBucketStorage-Cnxd9y2q.mjs';
2
- export { initLunora } from './packem_shared/initLunora-sQUqaejx.mjs';
2
+ export { initLunora } from './packem_shared/initLunora-CmMVk4i7.mjs';
3
3
  export { createSecrets } from './packem_shared/createSecrets-DwaR2rNG.mjs';
4
4
  export { LunoraEnvError, defineEnv, redactSecrets } from './packem_shared/LunoraEnvError-BGmd1Qs0.mjs';
5
5
  export { LunoraError } from './packem_shared/LunoraError-WbxmrpxR.mjs';
@@ -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-BtPCiNLW.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
 
@@ -1,5 +1,5 @@
1
1
  import { v } from '@lunora/values';
2
- import { initLunora } from './initLunora-sQUqaejx.mjs';
2
+ import { initLunora } from './initLunora-CmMVk4i7.mjs';
3
3
  import { LunoraError } from './LunoraError-WbxmrpxR.mjs';
4
4
  import { onDisconnect } from './onConnect-CIPXKPyw.mjs';
5
5
  import { defineSchemaExtension, defineComponent } from './composePluginMiddleware-CcTj1_v2.mjs';
@@ -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();
@@ -57,7 +57,8 @@ const makeBuilder = (kind, state, visibility) => {
57
57
  handler: makeHandler(state.args, state.middlewares, userHandler, state.output),
58
58
  kind,
59
59
  ...rls ? { rls } : {},
60
- ...visibility ? { visibility } : {}
60
+ ...visibility ? { visibility } : {},
61
+ ...state.x402 ? { x402: state.x402 } : {}
61
62
  };
62
63
  },
63
64
  output: (validator) => makeBuilder(kind, { ...state, output: validator }, visibility),
@@ -73,11 +74,17 @@ const makeBuilder = (kind, state, visibility) => {
73
74
  handler: makeStreamHandler(state.args, state.middlewares, userHandler),
74
75
  kind: "stream",
75
76
  ...rls ? { rls } : {},
76
- ...visibility ? { visibility } : {}
77
+ ...visibility ? { visibility } : {},
78
+ ...state.x402 ? { x402: state.x402 } : {}
77
79
  };
78
80
  }
79
81
  } : {},
80
- use: (middleware) => makeBuilder(kind, { ...state, middlewares: [...state.middlewares, middleware] }, visibility)
82
+ use: (middleware) => makeBuilder(kind, { ...state, middlewares: [...state.middlewares, middleware] }, visibility),
83
+ // `.x402({ price })` marks a public procedure as paid. It's public-only:
84
+ // internal functions are server-to-server (cron/scheduler/`ctx.run*`) and
85
+ // never reachable via a client RPC, so there's nothing to charge. Omitting
86
+ // it on internal builders keeps the runtime shape aligned with the types.
87
+ ...visibility ? {} : { x402: (config) => makeBuilder(kind, { ...state, x402: config }, visibility) }
81
88
  };
82
89
  };
83
90
  const initLunora = {
@@ -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
@@ -284,6 +284,22 @@ type FunctionKind = "action" | "mutation" | "query" | "stream";
284
284
  * back-compat with functions registered before visibility existed.
285
285
  */
286
286
  type FunctionVisibility = "internal" | "public";
287
+ /**
288
+ * x402 payment tag attached by the `.x402({ price })` builder modifier. Marks a
289
+ * public procedure as paid: the origin worker answers an unpaid client RPC with
290
+ * HTTP 402, verifies + settles the payment, and only then dispatches to the
291
+ * shard. The runtime reads only `price` from here — the network, recipient, and
292
+ * facilitator live in the worker-level x402 charge config, so `@lunora/runtime`
293
+ * never has to import `@lunora/x402` (and its viem/solana deps).
294
+ */
295
+ interface X402ProcedureConfig {
296
+ /**
297
+ * USD-denominated price: a number of dollars (`0.01`) or a decimal string
298
+ * (`"0.01"`, or the `"$0.01"` shorthand). Resolved to the network
299
+ * stablecoin's base units (USDC has 6 decimals) at challenge time.
300
+ */
301
+ readonly price: number | string;
302
+ }
287
303
  interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKind> {
288
304
  readonly args: A;
289
305
  readonly handler: (context: unknown, args: InferArgs<A>) => Promise<R> | R;
@@ -296,6 +312,12 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
296
312
  */
297
313
  readonly lifecycle?: LifecycleEventKind;
298
314
  readonly visibility?: FunctionVisibility;
315
+ /**
316
+ * Set by the `.x402({ price })` builder modifier. Marks the procedure as paid
317
+ * so the origin worker gates it behind an x402 402-challenge before dispatch.
318
+ * Absent on unpaid functions.
319
+ */
320
+ readonly x402?: X402ProcedureConfig;
299
321
  }
300
322
  type RegisteredQuery<A extends ArgsValidator, R> = RegisteredFunction<A, R, "query">;
301
323
  type RegisteredMutation<A extends ArgsValidator, R> = RegisteredFunction<A, R, "mutation">;
@@ -1249,4 +1271,4 @@ interface ActionCtx {
1249
1271
  */
1250
1272
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1251
1273
  declare const anyApi: AnyApi;
1252
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, 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 Secrets, type SecretsStoreSecretLike, 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 };
1274
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, 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 Secrets, type SecretsStoreSecretLike, 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, type X402ProcedureConfig, anyApi };
package/dist/types.d.ts CHANGED
@@ -284,6 +284,22 @@ type FunctionKind = "action" | "mutation" | "query" | "stream";
284
284
  * back-compat with functions registered before visibility existed.
285
285
  */
286
286
  type FunctionVisibility = "internal" | "public";
287
+ /**
288
+ * x402 payment tag attached by the `.x402({ price })` builder modifier. Marks a
289
+ * public procedure as paid: the origin worker answers an unpaid client RPC with
290
+ * HTTP 402, verifies + settles the payment, and only then dispatches to the
291
+ * shard. The runtime reads only `price` from here — the network, recipient, and
292
+ * facilitator live in the worker-level x402 charge config, so `@lunora/runtime`
293
+ * never has to import `@lunora/x402` (and its viem/solana deps).
294
+ */
295
+ interface X402ProcedureConfig {
296
+ /**
297
+ * USD-denominated price: a number of dollars (`0.01`) or a decimal string
298
+ * (`"0.01"`, or the `"$0.01"` shorthand). Resolved to the network
299
+ * stablecoin's base units (USDC has 6 decimals) at challenge time.
300
+ */
301
+ readonly price: number | string;
302
+ }
287
303
  interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKind> {
288
304
  readonly args: A;
289
305
  readonly handler: (context: unknown, args: InferArgs<A>) => Promise<R> | R;
@@ -296,6 +312,12 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
296
312
  */
297
313
  readonly lifecycle?: LifecycleEventKind;
298
314
  readonly visibility?: FunctionVisibility;
315
+ /**
316
+ * Set by the `.x402({ price })` builder modifier. Marks the procedure as paid
317
+ * so the origin worker gates it behind an x402 402-challenge before dispatch.
318
+ * Absent on unpaid functions.
319
+ */
320
+ readonly x402?: X402ProcedureConfig;
299
321
  }
300
322
  type RegisteredQuery<A extends ArgsValidator, R> = RegisteredFunction<A, R, "query">;
301
323
  type RegisteredMutation<A extends ArgsValidator, R> = RegisteredFunction<A, R, "mutation">;
@@ -1249,4 +1271,4 @@ interface ActionCtx {
1249
1271
  */
1250
1272
  type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
1251
1273
  declare const anyApi: AnyApi;
1252
- export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, 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 Secrets, type SecretsStoreSecretLike, 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 };
1274
+ export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, 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 Secrets, type SecretsStoreSecretLike, 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, type X402ProcedureConfig, anyApi };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/server",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.23",
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.8",
67
+ "@lunora/values": "1.0.0-alpha.7",
68
68
  "drizzle-orm": "^0.45.2",
69
69
  "hono": "^4.12.28"
70
70
  },