@onchaindb/sdk 2.1.1 → 4.0.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/x402/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,2BAA2B,EAC3B,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EAEZ,MAAM,SAAS,CAAC;AAKjB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,GAAG,2BAA2B,CAkBxE;AA2BD,wBAAgB,kBAAkB,CAC9B,WAAW,EAAE,sBAAsB,EACnC,UAAU,EAAE,sBAAsB,EAAE,GACrC,SAAS,CAsCX;AAMD,wBAAgB,mBAAmB,CAC/B,WAAW,EAAE,sBAAsB,EACnC,OAAO,EAAE,iBAAiB,GAC3B,kBAAkB,CAcpB;AAMD,wBAAgB,8BAA8B,CAC1C,WAAW,EAAE,sBAAsB,EACnC,aAAa,EAAE,wBAAwB,GACxC,kBAAkB,CA2BpB;AAKD,MAAM,WAAW,2BAA2B;IACxC,IAAI,EAAE,KAAK,CAAC;IAEZ,SAAS,EAAE,MAAM,CAAC;IAElB,aAAa,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAKD,MAAM,WAAW,8BAA8B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IAEf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,wBAAwB,GAAG,2BAA2B,GAAG,8BAA8B,CAAC;AAKpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE7D;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAOvE;AAKD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAWzD;AA6CD,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,sBAAsB,EAAE,EACjC,kBAAkB,CAAC,EAAE,SAAS,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GAC1B,sBAAsB,CAwBxB;AAKD,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,sBAAsB,EAAE,GAClC,MAAM,CAAC,SAAS,EAAE,sBAAsB,EAAE,CAAC,CAuB7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/x402/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,2BAA2B,EAC3B,sBAAsB,EACtB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EAEZ,MAAM,SAAS,CAAC;AAKjB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,GAAG,2BAA2B,CAkBxE;AAqCD,wBAAgB,kBAAkB,CAC9B,WAAW,EAAE,sBAAsB,EACnC,UAAU,EAAE,sBAAsB,EAAE,GACrC,SAAS,CAsCX;AAMD,wBAAgB,mBAAmB,CAC/B,WAAW,EAAE,sBAAsB,EACnC,OAAO,EAAE,iBAAiB,GAC3B,kBAAkB,CAcpB;AAMD,wBAAgB,8BAA8B,CAC1C,WAAW,EAAE,sBAAsB,EACnC,aAAa,EAAE,wBAAwB,GACxC,kBAAkB,CA2BpB;AAKD,MAAM,WAAW,2BAA2B;IACxC,IAAI,EAAE,KAAK,CAAC;IAEZ,SAAS,EAAE,MAAM,CAAC;IAElB,aAAa,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAKD,MAAM,WAAW,8BAA8B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IAEf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,wBAAwB,GAAG,2BAA2B,GAAG,8BAA8B,CAAC;AAKpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE7D;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAOvE;AAKD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAWzD;AA6CD,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,sBAAsB,EAAE,EACjC,kBAAkB,CAAC,EAAE,SAAS,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GAC1B,sBAAsB,CAwBxB;AAKD,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,sBAAsB,EAAE,GAClC,MAAM,CAAC,SAAS,EAAE,sBAAsB,EAAE,CAAC,CAuB7C"}
@@ -39,6 +39,16 @@ function parsePaymentRequirement(req) {
39
39
  description: req.description,
40
40
  mimeType: req.mimeType || 'application/json',
41
41
  maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
42
+ tokenDecimals: req.tokenDecimals ?? 6,
43
+ tokenSymbol: req.tokenSymbol ?? '',
44
+ tokenName: req.tokenName ?? '',
45
+ tokenVersion: req.tokenVersion ?? '',
46
+ tokenMetadata: req.tokenMetadata ?? {
47
+ decimals: req.tokenDecimals ?? 6,
48
+ name: req.tokenName ?? '',
49
+ symbol: req.tokenSymbol ?? '',
50
+ version: req.tokenVersion ?? '',
51
+ },
42
52
  extra: req.extra,
43
53
  };
44
54
  }
@@ -55,7 +65,7 @@ function requirementToQuote(requirement, allOptions) {
55
65
  else if (isSolanaNetwork(requirement.network)) {
56
66
  chainType = 'solana';
57
67
  }
58
- const decimals = extra.tokenDecimals || 6;
68
+ const decimals = requirement.tokenDecimals ?? 6;
59
69
  const totalCost = parseInt(amountRaw) / Math.pow(10, decimals);
60
70
  const expiresAt = extra.pricing?.expiresAt ||
61
71
  Math.floor(Date.now() / 1000) + requirement.maxTimeoutSeconds;
@@ -69,7 +79,7 @@ function requirementToQuote(requirement, allOptions) {
69
79
  chainType,
70
80
  network: requirement.network,
71
81
  asset: requirement.asset,
72
- tokenSymbol: extra.tokenSymbol || getTokenSymbol(requirement.asset),
82
+ tokenSymbol: requirement.tokenSymbol || getTokenSymbol(requirement.asset),
73
83
  tokenDecimals: decimals,
74
84
  paymentMethod: (extra.paymentMethod || 'native'),
75
85
  facilitator: extra.facilitator,
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/x402/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/x402/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onchaindb/sdk",
3
- "version": "2.1.1",
3
+ "version": "4.0.0",
4
4
  "description": "TypeScript SDK for OnChainDB - Decentralized database built on Celestia",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/client.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  IndexResponse,
7
7
  OnDBConfig,
8
8
  OnDBError,
9
+ PaymentRequiredError,
9
10
  PricingQuoteRequest,
10
11
  RelationRequest,
11
12
  RelationResponse,
@@ -40,6 +41,7 @@ import {
40
41
  // Import database management
41
42
  import {createDatabaseManager, DatabaseManager} from './database';
42
43
  import {QueryBuilder} from "./query-sdk";
44
+ import {ModelDelegate} from './model';
43
45
 
44
46
  // Import x402 utilities
45
47
  import {
@@ -244,11 +246,9 @@ export class OnDBClient extends EventEmitter<TransactionEvents> {
244
246
 
245
247
  // Call payment callback if provided
246
248
  if (!paymentCallback) {
247
- throw new OnDBError(
249
+ throw new PaymentRequiredError(
248
250
  'Payment required but no payment callback provided. Please provide a payment callback to handle x402.',
249
- 'PAYMENT_REQUIRED',
250
- 402,
251
- quote
251
+ x402Response
252
252
  );
253
253
  }
254
254
 
@@ -354,7 +354,7 @@ export class OnDBClient extends EventEmitter<TransactionEvents> {
354
354
  */
355
355
  async store(
356
356
  request: StoreRequest,
357
- paymentCallback?: (quote: X402Quote) => Promise<X402PaymentResult>,
357
+ paymentCallback?: (quote: X402Quote) => Promise<X402PaymentCallbackResult>,
358
358
  waitForConfirmation: boolean = true
359
359
  ): Promise<StoreResponse> {
360
360
  this.validateStoreRequest(request);
@@ -371,6 +371,7 @@ export class OnDBClient extends EventEmitter<TransactionEvents> {
371
371
 
372
372
 
373
373
  const response = await this.http.post('/store', resolvedRequest);
374
+
374
375
  const serverResult = response.data;
375
376
 
376
377
  // Check if we got an async response with ticket_id (new flow)
@@ -436,10 +437,16 @@ export class OnDBClient extends EventEmitter<TransactionEvents> {
436
437
  if ((error as AxiosError)?.response) {
437
438
  const err = error as AxiosError;
438
439
  if (err.response?.status === 402 && err?.response?.data) {
439
- const v = await this.handleX402(err.response, paymentCallback, resolvedRequest, waitForConfirmation);
440
-
441
- if (v) {
442
- return v;
440
+ if (paymentCallback) {
441
+ const v = await this.handleX402(err.response, paymentCallback, resolvedRequest, waitForConfirmation);
442
+ if (v) {
443
+ return v;
444
+ }
445
+ } else {
446
+ throw new PaymentRequiredError(
447
+ err.response.statusText || 'Payment required',
448
+ err.response.data as any
449
+ );
443
450
  }
444
451
  }
445
452
 
@@ -974,6 +981,19 @@ export class OnDBClient extends EventEmitter<TransactionEvents> {
974
981
  return new QueryBuilder(httpClient, this.config.endpoint, this.config.appId);
975
982
  }
976
983
 
984
+ /**
985
+ * Returns a Prisma-like model delegate for a collection.
986
+ *
987
+ * @example
988
+ * const users = client.model<User>('users');
989
+ * await users.findMany({ where: { age: { gt: 18 } }, take: 10 });
990
+ * await users.create({ data: { name: 'Alice', age: 30 } });
991
+ * await users.count({ where: { active: true } });
992
+ */
993
+ model<T extends Record<string, any> = Record<string, any>>(collection: string): ModelDelegate<T> {
994
+ return new ModelDelegate(this, collection);
995
+ }
996
+
977
997
  /**
978
998
  * Get task status by ticket ID
979
999
  * @param ticketId - The ticket ID returned from async store operation
package/src/index.ts CHANGED
@@ -1,6 +1,26 @@
1
1
  // Main SDK exports
2
2
  export { OnDBClient } from './client';
3
- export { QueryBuilder } from './query-sdk';
3
+ export {
4
+ ModelDelegate,
5
+ type WhereInput,
6
+ type FieldFilter,
7
+ type OrderByInput,
8
+ type SelectInput,
9
+ type FindManyArgs,
10
+ type FindFirstArgs,
11
+ type FindUniqueArgs,
12
+ type CreateArgs,
13
+ type CreateManyArgs,
14
+ type CountArgs,
15
+ type AggregateArgs,
16
+ } from './model';
17
+ export {
18
+ QueryBuilder,
19
+ FieldConditionBuilder,
20
+ LogicalOperator,
21
+ NestedConditionBuilder,
22
+ NestedFieldConditionBuilder,
23
+ } from './query-sdk';
4
24
  export {
5
25
  DatabaseManager,
6
26
  createDatabaseManager,
package/src/model.ts ADDED
@@ -0,0 +1,359 @@
1
+ import { OnDBClient } from './client';
2
+ import { FieldConditionBuilder, LogicalOperator, QueryBuilder } from './query-sdk';
3
+ import { AggregateSpec, SelectionMap } from './query-sdk';
4
+ import { StoreResponse } from './types';
5
+
6
+ // ── Where input types ─────────────────────────────────────────────────────────
7
+
8
+ export type FieldFilter = {
9
+ // ── Equality ─────────────────────────────────────────────────────────────
10
+ equals?: any;
11
+ not?: any;
12
+ in?: any[];
13
+ notIn?: any[];
14
+ /** Case-sensitive membership check (unlike `in` which is case-insensitive). */
15
+ inDataset?: string[];
16
+
17
+ // ── Numeric / comparison ─────────────────────────────────────────────────
18
+ lt?: any;
19
+ lte?: any;
20
+ gt?: any;
21
+ gte?: any;
22
+ /** Exclusive range: from < value < to. */
23
+ between?: { from: any; to: any };
24
+
25
+ // ── String ───────────────────────────────────────────────────────────────
26
+ contains?: string;
27
+ startsWith?: string;
28
+ endsWith?: string;
29
+ containsCaseInsensitive?: string;
30
+ startsWithCaseInsensitive?: string;
31
+ endsWithCaseInsensitive?: string;
32
+ regex?: string;
33
+
34
+ // ── Presence ─────────────────────────────────────────────────────────────
35
+ isNotNull?: true;
36
+ exists?: boolean;
37
+
38
+ // ── IP ───────────────────────────────────────────────────────────────────
39
+ isLocalIp?: true;
40
+ isExternalIp?: true;
41
+ inCountry?: string;
42
+ /** CIDR range check. Always uses "$cidr" alias to avoid Scepter stack overflow. */
43
+ cidr?: string | string[];
44
+
45
+ // ── Misc ─────────────────────────────────────────────────────────────────
46
+ /** Array of keywords — matches if the field contains ANY of them (case-insensitive substring). */
47
+ keywords?: string[];
48
+ b64?: string;
49
+ };
50
+
51
+ /** Prisma-style where clause. Multiple top-level fields are implicitly ANDed. */
52
+ export type WhereInput<T = any> = {
53
+ [K in keyof T]?: T[K] | FieldFilter;
54
+ } & {
55
+ AND?: WhereInput<T>[];
56
+ OR?: WhereInput<T>[];
57
+ NOT?: WhereInput<T>[];
58
+ };
59
+
60
+ export type OrderByInput<T = any> = {
61
+ [K in keyof T]?: 'asc' | 'desc';
62
+ };
63
+
64
+ export type SelectInput<T = any> = {
65
+ [K in keyof T]?: boolean;
66
+ };
67
+
68
+ // ── Arg interfaces ────────────────────────────────────────────────────────────
69
+
70
+ export interface FindManyArgs<T = any> {
71
+ where?: WhereInput<T>;
72
+ select?: SelectInput<T>;
73
+ orderBy?: OrderByInput<T>;
74
+ take?: number;
75
+ skip?: number;
76
+ /**
77
+ * Exclude soft-deleted records.
78
+ * - `true` → filters out records where `deletedAt` exists
79
+ * - `string` → filters out records where the given field exists (custom delete key)
80
+ */
81
+ excludeDeleted?: boolean | string;
82
+ }
83
+
84
+ export type FindFirstArgs<T = any> = Omit<FindManyArgs<T>, 'take'>;
85
+
86
+ export interface FindUniqueArgs<T = any> {
87
+ where: WhereInput<T>;
88
+ select?: SelectInput<T>;
89
+ }
90
+
91
+ export interface CreateArgs<T = any> {
92
+ data: Partial<T> & Record<string, any>;
93
+ }
94
+
95
+ export interface CreateManyArgs<T = any> {
96
+ data: Array<Partial<T> & Record<string, any>>;
97
+ }
98
+
99
+ export interface CountArgs<T = any> {
100
+ where?: WhereInput<T>;
101
+ }
102
+
103
+ export interface AggregateArgs<T = any> {
104
+ where?: WhereInput<T>;
105
+ /** Count all records */
106
+ _count?: boolean;
107
+ /** Sum numeric fields: { _sum: { age: true } } */
108
+ _sum?: { [K in keyof T]?: boolean };
109
+ /** Average numeric fields */
110
+ _avg?: { [K in keyof T]?: boolean };
111
+ /** Minimum value per field */
112
+ _min?: { [K in keyof T]?: boolean };
113
+ /** Maximum value per field */
114
+ _max?: { [K in keyof T]?: boolean };
115
+ }
116
+
117
+ // ── Where → LogicalOperator converter ────────────────────────────────────────
118
+
119
+ const OPERATOR_KEYS = new Set([
120
+ 'equals', 'not', 'in', 'notIn', 'inDataset',
121
+ 'lt', 'lte', 'gt', 'gte', 'between',
122
+ 'contains', 'startsWith', 'endsWith',
123
+ 'containsCaseInsensitive', 'startsWithCaseInsensitive', 'endsWithCaseInsensitive',
124
+ 'regex',
125
+ 'isNotNull', 'exists',
126
+ 'isLocalIp', 'isExternalIp', 'inCountry', 'cidr',
127
+ 'keywords', 'b64',
128
+ ]);
129
+
130
+ function buildConditions(where: WhereInput): LogicalOperator[] {
131
+ const conditions: LogicalOperator[] = [];
132
+
133
+ for (const [key, value] of Object.entries(where)) {
134
+ if (key === 'AND' && Array.isArray(value)) {
135
+ const inner = (value as WhereInput[]).flatMap(buildConditions);
136
+ if (inner.length > 0) conditions.push(LogicalOperator.And(inner));
137
+
138
+ } else if (key === 'OR' && Array.isArray(value)) {
139
+ const inner = (value as WhereInput[]).flatMap(buildConditions);
140
+ if (inner.length > 0) conditions.push(LogicalOperator.Or(inner));
141
+
142
+ } else if (key === 'NOT' && Array.isArray(value)) {
143
+ const inner = (value as WhereInput[]).flatMap(buildConditions);
144
+ if (inner.length > 0) conditions.push(LogicalOperator.Not(inner));
145
+
146
+ } else if (value === null || value === undefined) {
147
+ conditions.push(new FieldConditionBuilder(key).isNull());
148
+
149
+ } else if (typeof value === 'object' && !Array.isArray(value)) {
150
+ const isOpObject = Object.keys(value as object).some(k => OPERATOR_KEYS.has(k));
151
+
152
+ if (isOpObject) {
153
+ const f = value as FieldFilter;
154
+ const fcb = (k = key) => new FieldConditionBuilder(k);
155
+
156
+ // ── Equality ─────────────────────────────────────────────────
157
+ if (f.equals !== undefined) conditions.push(fcb().equals(f.equals));
158
+ if (f.not !== undefined) conditions.push(fcb().notEquals(f.not));
159
+ if (f.in !== undefined) conditions.push(fcb().in(f.in));
160
+ if (f.notIn !== undefined) conditions.push(fcb().notIn(f.notIn));
161
+ if (f.inDataset !== undefined) conditions.push(fcb().inDataset(f.inDataset));
162
+
163
+ // ── Numeric / comparison ─────────────────────────────────────
164
+ if (f.lt !== undefined) conditions.push(fcb().lessThan(f.lt));
165
+ if (f.lte !== undefined) conditions.push(fcb().lessThanOrEqual(f.lte));
166
+ if (f.gt !== undefined) conditions.push(fcb().greaterThan(f.gt));
167
+ if (f.gte !== undefined) conditions.push(fcb().greaterThanOrEqual(f.gte));
168
+ if (f.between !== undefined) conditions.push(fcb().between(f.between.from, f.between.to));
169
+
170
+ // ── String ───────────────────────────────────────────────────
171
+ if (f.contains !== undefined) conditions.push(fcb().contains(f.contains));
172
+ if (f.startsWith !== undefined) conditions.push(fcb().startsWith(f.startsWith));
173
+ if (f.endsWith !== undefined) conditions.push(fcb().endsWith(f.endsWith));
174
+ if (f.containsCaseInsensitive !== undefined) conditions.push(fcb().includesCaseInsensitive(f.containsCaseInsensitive));
175
+ if (f.startsWithCaseInsensitive !== undefined) conditions.push(fcb().startsWithCaseInsensitive(f.startsWithCaseInsensitive));
176
+ if (f.endsWithCaseInsensitive !== undefined) conditions.push(fcb().endsWithCaseInsensitive(f.endsWithCaseInsensitive));
177
+ if (f.regex !== undefined) conditions.push(fcb().regExpMatches(f.regex));
178
+
179
+ // ── Presence ─────────────────────────────────────────────────
180
+ if (f.isNotNull) conditions.push(fcb().isNotNull());
181
+ if (f.exists === true) conditions.push(fcb().exists());
182
+ if (f.exists === false) conditions.push(fcb().notExists());
183
+
184
+ // ── IP ───────────────────────────────────────────────────────
185
+ if (f.isLocalIp) conditions.push(fcb().isLocalIp());
186
+ if (f.isExternalIp) conditions.push(fcb().isExternalIp());
187
+ if (f.inCountry !== undefined) conditions.push(fcb().inCountry(f.inCountry));
188
+ if (f.cidr !== undefined) conditions.push(fcb().cidr(f.cidr));
189
+
190
+ // ── Misc ─────────────────────────────────────────────────────
191
+ if (f.keywords !== undefined) conditions.push(fcb().keywords(f.keywords));
192
+ if (f.b64 !== undefined) conditions.push(fcb().b64(f.b64));
193
+ } else {
194
+ // Shorthand object equality: { metadata: { role: 'admin' } }
195
+ conditions.push(new FieldConditionBuilder(key).equals(value));
196
+ }
197
+
198
+ } else {
199
+ // Primitive shorthand: { name: 'Alice', active: true }
200
+ conditions.push(new FieldConditionBuilder(key).equals(value));
201
+ }
202
+ }
203
+
204
+ return conditions;
205
+ }
206
+
207
+ function applyWhere(qb: QueryBuilder, where?: WhereInput, excludeDeletedKey?: string): QueryBuilder {
208
+ const conditions: LogicalOperator[] = [];
209
+
210
+ if (where && Object.keys(where).length > 0) {
211
+ conditions.push(...buildConditions(where));
212
+ }
213
+
214
+ if (excludeDeletedKey) {
215
+ conditions.push(new FieldConditionBuilder(excludeDeletedKey).notExists());
216
+ }
217
+
218
+ if (conditions.length === 0) return qb;
219
+ const op = conditions.length === 1 ? conditions[0] : LogicalOperator.And(conditions);
220
+ return qb.find(() => op);
221
+ }
222
+
223
+ function applySelect<T>(qb: QueryBuilder, select?: SelectInput<T>): QueryBuilder {
224
+ if (!select) return qb;
225
+ const fields = Object.entries(select)
226
+ .filter(([, v]) => v === true)
227
+ .map(([k]) => k);
228
+ return fields.length > 0 ? qb.selectFields(fields) : qb;
229
+ }
230
+
231
+ function buildAggregateSpec<T>(args: AggregateArgs<T>): AggregateSpec {
232
+ const spec: AggregateSpec = {};
233
+
234
+ if (args._count) {
235
+ spec['_count'] = { '$count': '*' };
236
+ }
237
+
238
+ const numericOps: Array<[keyof AggregateArgs, string]> = [
239
+ ['_sum', '$sum'],
240
+ ['_avg', '$avg'],
241
+ ['_min', '$min'],
242
+ ['_max', '$max'],
243
+ ];
244
+
245
+ for (const [argKey, scepterOp] of numericOps) {
246
+ const fields = args[argKey as keyof typeof args] as Record<string, boolean> | undefined;
247
+ if (!fields) continue;
248
+ for (const [field, enabled] of Object.entries(fields)) {
249
+ if (enabled) spec[`${argKey}_${field}`] = { [scepterOp]: field } as any;
250
+ }
251
+ }
252
+
253
+ return spec;
254
+ }
255
+
256
+ // ── ModelDelegate ─────────────────────────────────────────────────────────────
257
+
258
+ export class ModelDelegate<T extends Record<string, any> = Record<string, any>> {
259
+ constructor(
260
+ private readonly client: OnDBClient,
261
+ private readonly collection: string
262
+ ) {}
263
+
264
+ private qb(): QueryBuilder {
265
+ return this.client.queryBuilder().collection(this.collection);
266
+ }
267
+
268
+ async findMany(args: FindManyArgs<T> = {}): Promise<T[]> {
269
+ const deletedKey = args.excludeDeleted === true ? 'deletedAt'
270
+ : typeof args.excludeDeleted === 'string' ? args.excludeDeleted
271
+ : undefined;
272
+ let qb = applyWhere(this.qb(), args.where, deletedKey);
273
+ qb = applySelect(qb, args.select);
274
+ if (args.orderBy) {
275
+ const [field, dir] = Object.entries(args.orderBy)[0];
276
+ qb = qb.sortBy(field, dir as 'asc' | 'desc');
277
+ }
278
+ if (args.take !== undefined) qb = qb.limit(args.take);
279
+ if (args.skip !== undefined) qb = qb.offset(args.skip);
280
+ const result = await qb.execute<T>();
281
+ return result.records ?? [];
282
+ }
283
+
284
+ async findFirst(args: FindFirstArgs<T> = {}): Promise<T | null> {
285
+ const results = await this.findMany({ ...args, take: 1 });
286
+ return results[0] ?? null;
287
+ }
288
+
289
+ async findUnique(args: FindUniqueArgs<T>): Promise<T | null> {
290
+ return this.findFirst(args);
291
+ }
292
+
293
+ async create(args: CreateArgs<T>): Promise<StoreResponse> {
294
+ return this.client.store({
295
+ collection: this.collection,
296
+ data: [args.data as Record<string, any>],
297
+ });
298
+ }
299
+
300
+ /** Sends all records in a single store call — not N round-trips. */
301
+ async createMany(args: CreateManyArgs<T>): Promise<StoreResponse> {
302
+ return this.client.store({
303
+ collection: this.collection,
304
+ data: args.data as Record<string, any>[],
305
+ });
306
+ }
307
+
308
+ /**
309
+ * Update a document by finding it with `identifierFind`, merging `patch` on top,
310
+ * and storing the result. OnDB deduplicates on unique fields, so this effectively
311
+ * replaces the existing record.
312
+ *
313
+ * @throws if no document matches `identifierFind`
314
+ */
315
+ async updateDocument(identifierFind: WhereInput<T>, patch: Partial<T>): Promise<StoreResponse> {
316
+ const existing = await this.findFirst({ where: identifierFind });
317
+ if (!existing) throw new Error(`updateDocument: no document found matching the identifier`);
318
+ return this.client.store({
319
+ collection: this.collection,
320
+ data: [{ ...existing, ...patch }],
321
+ });
322
+ }
323
+
324
+ /**
325
+ * Soft-delete a document by finding it with `identifierFind` and storing it back
326
+ * with `deletedAt: Date.now()` (plus any optional extra `patch`).
327
+ * OnDB deduplicates on unique fields, so this effectively marks the record as deleted.
328
+ *
329
+ * @throws if no document matches `identifierFind`
330
+ */
331
+ async deleteDocument(identifierFind: WhereInput<T>, patch?: Partial<T>): Promise<StoreResponse> {
332
+ const existing = await this.findFirst({ where: identifierFind });
333
+ if (!existing) throw new Error(`deleteDocument: no document found matching the identifier`);
334
+ return this.client.store({
335
+ collection: this.collection,
336
+ data: [{ ...existing, deletedAt: Date.now(), ...(patch ?? {}) }],
337
+ });
338
+ }
339
+
340
+ async count(args: CountArgs<T> = {}): Promise<number> {
341
+ return applyWhere(this.qb(), args.where).count();
342
+ }
343
+
344
+ /**
345
+ * Aggregate result keys follow the pattern: `_count`, `_sum_<field>`, `_avg_<field>`, etc.
346
+ * @example
347
+ * const result = await db.model('users').aggregate({
348
+ * where: { active: true },
349
+ * _count: true,
350
+ * _avg: { age: true },
351
+ * _sum: { balance: true },
352
+ * });
353
+ * // result: { _count: 42, _avg_age: 28.5, _sum_balance: 99000 }
354
+ */
355
+ async aggregate(args: AggregateArgs<T>): Promise<Record<string, any>> {
356
+ const qb = applyWhere(this.qb(), args.where);
357
+ return qb.runAggregate(buildAggregateSpec(args));
358
+ }
359
+ }
@@ -8,7 +8,6 @@ import {AxiosError} from "axios";
8
8
  import {
9
9
  X402PaymentRequiredResponse,
10
10
  encodePaymentHeader,
11
- requirementToQuote,
12
11
  } from '../x402';
13
12
 
14
13
  // Interface for server-side join configuration (Scepter format)
@@ -81,12 +80,13 @@ export class QueryBuilder {
81
80
  return new WhereClause(this, fieldName);
82
81
  }
83
82
 
84
- // Server-side JOIN with Scepter query engine (RECOMMENDED)
85
- // This generates a JOIN query that the backend executes recursively
86
- serverJoin(alias: string, model: string, resolve: { find?: any; select?: SelectionMap }): QueryBuilder {
83
+ // Server-side JOIN with Scepter query engine (low-level)
84
+ // many: true array result (joinMany), false single object (joinOne), undefined → Scepter default
85
+ serverJoin(alias: string, model: string, resolve: { find?: any; select?: SelectionMap }, many?: boolean): QueryBuilder {
87
86
  this.serverJoinConfigs.push({
88
87
  alias,
89
88
  model,
89
+ many,
90
90
  resolve
91
91
  });
92
92
  return this;
@@ -592,10 +592,8 @@ export class QueryBuilder {
592
592
  // x402: Check for 402 Payment Required
593
593
  if (response?.status === 402 && response?.data) {
594
594
  const x402Response = response.data as X402PaymentRequiredResponse;
595
- const requirement = x402Response.accepts?.[0];
596
- if (requirement) {
597
- const quote = requirementToQuote(requirement, x402Response.accepts);
598
- throw new PaymentRequiredError('Payment required for this query', quote);
595
+ if (x402Response.accepts?.length) {
596
+ throw new PaymentRequiredError('Payment required for this query', x402Response);
599
597
  }
600
598
  }
601
599
 
@@ -614,10 +612,8 @@ export class QueryBuilder {
614
612
  const response = (error as AxiosError)?.response;
615
613
  if (response?.status === 402 && response?.data) {
616
614
  const x402Response = response.data as X402PaymentRequiredResponse;
617
- const requirement = x402Response.accepts?.[0];
618
- if (requirement) {
619
- const quote = requirementToQuote(requirement, x402Response.accepts);
620
- throw new PaymentRequiredError('Payment required for this query', quote);
615
+ if (x402Response.accepts?.length) {
616
+ throw new PaymentRequiredError('Payment required for this query', x402Response);
621
617
  }
622
618
  }
623
619
  throw new Error(`Query execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);