@atscript/db-client 0.1.127 → 0.1.129

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.cjs CHANGED
@@ -56,6 +56,24 @@ var VersionMismatchError = class extends ClientError {
56
56
  return this.body.currentVersion;
57
57
  }
58
58
  };
59
+ /**
60
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
61
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
62
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
63
+ * server answered and rejected — the request's outcome is unknown: a write
64
+ * may have committed. Reload before retrying a non-idempotent write.
65
+ * The underlying error is the standard `cause`.
66
+ */
67
+ var TransportError = class extends Error {
68
+ method;
69
+ url;
70
+ name = "TransportError";
71
+ constructor(method, url, detail, cause) {
72
+ super(`${method} ${url}: ${detail}`, { cause });
73
+ this.method = method;
74
+ this.url = url;
75
+ }
76
+ };
59
77
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
60
78
  var ActionNotFoundError = class extends Error {
61
79
  action;
@@ -212,22 +230,26 @@ var Client = class {
212
230
  return this._getOrNull(`one/${encodeURIComponent(String(id))}${controlStr ? `?${controlStr}` : ""}`);
213
231
  }
214
232
  async insert(data) {
215
- await this._validateData(data, "insert");
216
- return this._request("POST", "", data);
233
+ return this._request("POST", "", await this._prepareWrite(data, "insert"));
217
234
  }
218
235
  /**
219
236
  * `PATCH /` — partial update one or many records by primary key.
237
+ *
238
+ * Accepts both OCC shapes (since 0.1.128): a bare `version: N` (the wire
239
+ * contract) or the SDK `$cas: { version: N }`, which is lifted to `version`
240
+ * before preflight and sending. A stale version surfaces as
241
+ * {@link VersionMismatchError}; a PK-only body with a version is a real
242
+ * write (the server bumps the version).
220
243
  */
221
244
  async update(data) {
222
- await this._validateData(data, "patch");
223
- return this._request("PATCH", "", data);
245
+ return this._request("PATCH", "", await this._prepareWrite(data, "patch"));
224
246
  }
225
247
  /**
226
- * `PUT /` — full replace one or many records by primary key.
248
+ * `PUT /` — full replace one or many records by primary key. Same OCC
249
+ * shapes as {@link update}; the version column itself is optional.
227
250
  */
228
251
  async replace(data) {
229
- await this._validateData(data, "replace");
230
- return this._request("PUT", "", data);
252
+ return this._request("PUT", "", await this._prepareWrite(data, "replace"));
231
253
  }
232
254
  /**
233
255
  * `DELETE /:id` or `DELETE /?k1=v1&k2=v2` — remove a record by primary key.
@@ -329,8 +351,12 @@ var Client = class {
329
351
  getValidator() {
330
352
  return this._getValidator();
331
353
  }
332
- async _validateData(data, mode) {
333
- (await this._getValidator()).validate(data, mode);
354
+ /** Lifts `$cas` to the wire shape, then runs the preflight validator on the result. */
355
+ async _prepareWrite(data, mode) {
356
+ const validator = await this._getValidator();
357
+ const normalized = validator.liftCas(data, mode);
358
+ validator.validate(normalized, mode);
359
+ return normalized;
334
360
  }
335
361
  _getValidator() {
336
362
  if (!this._validatorPromise) this._validatorPromise = Promise.all([this.meta(), Promise.resolve().then(() => require("./validator.cjs"))]).then(([m, { createClientValidator }]) => createClientValidator(m, { lenientWrites: this._lenientWrites })).catch((err) => {
@@ -422,14 +448,20 @@ var Client = class {
422
448
  return init;
423
449
  }
424
450
  async _send(url, init, allowEmpty) {
425
- const res = await this._fetch(url, init);
451
+ const method = init.method ?? "GET";
452
+ let res;
453
+ try {
454
+ res = await this._fetch(url, init);
455
+ } catch (cause) {
456
+ throw new TransportError(method, url, describeCause(cause), cause);
457
+ }
426
458
  if (!res.ok) {
427
459
  let errorBody;
428
460
  try {
429
461
  errorBody = await res.json();
430
462
  } catch {
431
463
  errorBody = {
432
- message: res.statusText,
464
+ message: res.statusText || `HTTP ${res.status}`,
433
465
  statusCode: res.status
434
466
  };
435
467
  }
@@ -437,7 +469,11 @@ var Client = class {
437
469
  if (errorBody.kind === "version_mismatch") throw new VersionMismatchError(res.status, errorBody);
438
470
  throw new ClientError(res.status, errorBody);
439
471
  }
440
- if (!allowEmpty) return res.json();
472
+ if (!allowEmpty) try {
473
+ return await res.json();
474
+ } catch (cause) {
475
+ throw new TransportError(method, url, `HTTP ${res.status} body is not JSON (${describeCause(cause)})`, cause);
476
+ }
441
477
  if (res.status === 204 || res.headers.get("content-length") === "0") return void 0;
442
478
  try {
443
479
  return await res.json();
@@ -446,6 +482,11 @@ var Client = class {
446
482
  }
447
483
  }
448
484
  };
485
+ /** One-line rendering of a thrown value for a `TransportError` message. */
486
+ function describeCause(cause) {
487
+ if (cause instanceof Error) return cause.message || cause.name;
488
+ return String(cause);
489
+ }
449
490
  /**
450
491
  * Render a single identifier field for substitution into a navigate-URL
451
492
  * template or human-readable string. `null` / `undefined` collapse to `""`
@@ -487,6 +528,7 @@ exports.ActionNotFoundError = ActionNotFoundError;
487
528
  exports.ActionUnsupportedError = ActionUnsupportedError;
488
529
  exports.Client = Client;
489
530
  exports.ClientError = ClientError;
531
+ exports.TransportError = TransportError;
490
532
  exports.VersionMismatchError = VersionMismatchError;
491
533
  exports.encodeNavigateId = encodeNavigateId;
492
534
  exports.formatIdentifier = formatIdentifier;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as TDbDeleteResult, D as TypedWithRelation, E as TDbUpdateResult, O as Uniquery, S as ServerError, T as TDbInsertResult, _ as NavOf, a as ValidatorMode, b as RelationInfo, c as AggregateResult, d as ClientResponse, f as DataOf, g as MetaResponse, h as IdOf, k as UniqueryControls, l as AtscriptClientShape, m as FilterExpr, n as ClientValidator, p as FieldMeta, r as ClientValidatorOptions, s as AggregateQuery, t as ClientValidationError, u as ClientOptions, v as OwnOf, w as TDbInsertManyResult, x as SearchIndexInfo, y as PageResult } from "./validator-3I12BVi4.cjs";
1
+ import { A as TDbUpdateResult, C as RelationInfo, D as TDbDeleteResult, E as ServerError, M as Uniquery, N as UniqueryControls, O as TDbInsertManyResult, S as PatchOf, T as SearchIndexInfo, _ as IdOf, a as ValidatorMode, b as OwnOf, c as AggregateResult, d as ClientResponse, f as DataOf, g as FilterExpr, h as FieldMeta, j as TypedWithRelation, k as TDbInsertResult, l as AtscriptClientShape, m as DbRow, n as ClientValidator, p as DbPatch, r as ClientValidatorOptions, s as AggregateQuery, t as ClientValidationError, u as ClientOptions, v as MetaResponse, w as RowOf, x as PageResult, y as NavOf } from "./validator-C3uaaZkU.cjs";
2
2
  import { AggregateQuery as AggregateQuery$1, AggregateResult as AggregateResult$1, Uniquery as Uniquery$1, UniqueryControls as UniqueryControls$1 } from "@uniqu/core";
3
3
  import { TAtscriptAnnotatedType, TSerializedAnnotatedType } from "@atscript/typescript/utils";
4
4
  import { TCrudOp, TCrudPermissions, TDbActionInfo, TDbActionIntent, TDbActionLevel, TDbActionProcessor, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1 } from "@atscript/db";
@@ -6,7 +6,6 @@ import { TCrudOp, TCrudPermissions, TDbActionInfo, TDbActionIntent, TDbActionLev
6
6
  //#region src/client.d.ts
7
7
  type Own<T> = OwnOf<T>;
8
8
  type Nav<T> = NavOf<T>;
9
- type Data<T> = DataOf<T>;
10
9
  type Id<T> = IdOf<T>;
11
10
  type Response<T, Q> = ClientResponse<T, Q>;
12
11
  /**
@@ -99,21 +98,29 @@ declare class Client<T extends AtscriptClientShape = AtscriptClientShape> {
99
98
  controls?: UniqueryControls$1<Own<T>, Nav<T>>;
100
99
  }>(id: Id<T>, query?: Q): Promise<Response<T, Q> | null>;
101
100
  /**
102
- * `POST /` — insert one record.
101
+ * `POST /` — insert one record. The version column (if any) is optional —
102
+ * the server initialises it; `$cas` is rejected (no meaning on insert).
103
103
  */
104
- insert(data: Partial<Data<T>>): Promise<TDbInsertResult$1>;
104
+ insert(data: PatchOf<T>): Promise<TDbInsertResult$1>;
105
105
  /**
106
106
  * `POST /` — insert many records.
107
107
  */
108
- insert(data: Partial<Data<T>>[]): Promise<TDbInsertManyResult$1>;
108
+ insert(data: PatchOf<T>[]): Promise<TDbInsertManyResult$1>;
109
109
  /**
110
110
  * `PATCH /` — partial update one or many records by primary key.
111
+ *
112
+ * Accepts both OCC shapes (since 0.1.128): a bare `version: N` (the wire
113
+ * contract) or the SDK `$cas: { version: N }`, which is lifted to `version`
114
+ * before preflight and sending. A stale version surfaces as
115
+ * {@link VersionMismatchError}; a PK-only body with a version is a real
116
+ * write (the server bumps the version).
111
117
  */
112
- update(data: Partial<Data<T>> | Partial<Data<T>>[]): Promise<TDbUpdateResult$1>;
118
+ update(data: PatchOf<T> | PatchOf<T>[]): Promise<TDbUpdateResult$1>;
113
119
  /**
114
- * `PUT /` — full replace one or many records by primary key.
120
+ * `PUT /` — full replace one or many records by primary key. Same OCC
121
+ * shapes as {@link update}; the version column itself is optional.
115
122
  */
116
- replace(data: Data<T> | Data<T>[]): Promise<TDbUpdateResult$1>;
123
+ replace(data: RowOf<T> | RowOf<T>[]): Promise<TDbUpdateResult$1>;
117
124
  /**
118
125
  * `DELETE /:id` or `DELETE /?k1=v1&k2=v2` — remove a record by primary key.
119
126
  */
@@ -177,7 +184,8 @@ declare class Client<T extends AtscriptClientShape = AtscriptClientShape> {
177
184
  * Useful for accessing `flatMap` and `navFields` (e.g. for form generation).
178
185
  */
179
186
  getValidator(): Promise<ClientValidator>;
180
- private _validateData;
187
+ /** Lifts `$cas` to the wire shape, then runs the preflight validator on the result. */
188
+ private _prepareWrite;
181
189
  private _getValidator;
182
190
  private _buildActionBody;
183
191
  private _interpolateNavigateUrl;
@@ -287,6 +295,28 @@ declare class VersionMismatchError extends ClientError {
287
295
  /** Row's current server-side version — clients refresh + retry against it. */
288
296
  get currentVersion(): number;
289
297
  }
298
+ /**
299
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
300
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
301
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
302
+ * server answered and rejected — the request's outcome is unknown: a write
303
+ * may have committed. Reload before retrying a non-idempotent write.
304
+ * The underlying error is the standard `cause`.
305
+ */
306
+ declare class TransportError extends Error {
307
+ /** HTTP method of the failed request. */
308
+ readonly method: string;
309
+ /** Full request URL. */
310
+ readonly url: string;
311
+ name: string;
312
+ constructor(/** HTTP method of the failed request. */
313
+
314
+ method: string, /** Full request URL. */
315
+
316
+ url: string, /** What went wrong; the message is `<method> <url>: <detail>`. */
317
+
318
+ detail: string, cause?: unknown);
319
+ }
290
320
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
291
321
  declare class ActionNotFoundError extends Error {
292
322
  readonly action: string;
@@ -306,4 +336,4 @@ declare class ActionUnsupportedError extends Error {
306
336
  constructor(action: string, processor: string, message: string);
307
337
  }
308
338
  //#endregion
309
- export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type RelationInfo, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
339
+ export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, TransportError, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as TDbDeleteResult, D as TypedWithRelation, E as TDbUpdateResult, O as Uniquery, S as ServerError, T as TDbInsertResult, _ as NavOf, a as ValidatorMode, b as RelationInfo, c as AggregateResult, d as ClientResponse, f as DataOf, g as MetaResponse, h as IdOf, k as UniqueryControls, l as AtscriptClientShape, m as FilterExpr, n as ClientValidator, p as FieldMeta, r as ClientValidatorOptions, s as AggregateQuery, t as ClientValidationError, u as ClientOptions, v as OwnOf, w as TDbInsertManyResult, x as SearchIndexInfo, y as PageResult } from "./validator-DBEmk_s8.mjs";
1
+ import { A as TDbUpdateResult, C as RelationInfo, D as TDbDeleteResult, E as ServerError, M as Uniquery, N as UniqueryControls, O as TDbInsertManyResult, S as PatchOf, T as SearchIndexInfo, _ as IdOf, a as ValidatorMode, b as OwnOf, c as AggregateResult, d as ClientResponse, f as DataOf, g as FilterExpr, h as FieldMeta, j as TypedWithRelation, k as TDbInsertResult, l as AtscriptClientShape, m as DbRow, n as ClientValidator, p as DbPatch, r as ClientValidatorOptions, s as AggregateQuery, t as ClientValidationError, u as ClientOptions, v as MetaResponse, w as RowOf, x as PageResult, y as NavOf } from "./validator-CfPFKDL_.mjs";
2
2
  import { TAtscriptAnnotatedType, TSerializedAnnotatedType } from "@atscript/typescript/utils";
3
3
  import { AggregateQuery as AggregateQuery$1, AggregateResult as AggregateResult$1, Uniquery as Uniquery$1, UniqueryControls as UniqueryControls$1 } from "@uniqu/core";
4
4
  import { TCrudOp, TCrudPermissions, TDbActionInfo, TDbActionIntent, TDbActionLevel, TDbActionProcessor, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1 } from "@atscript/db";
@@ -6,7 +6,6 @@ import { TCrudOp, TCrudPermissions, TDbActionInfo, TDbActionIntent, TDbActionLev
6
6
  //#region src/client.d.ts
7
7
  type Own<T> = OwnOf<T>;
8
8
  type Nav<T> = NavOf<T>;
9
- type Data<T> = DataOf<T>;
10
9
  type Id<T> = IdOf<T>;
11
10
  type Response<T, Q> = ClientResponse<T, Q>;
12
11
  /**
@@ -99,21 +98,29 @@ declare class Client<T extends AtscriptClientShape = AtscriptClientShape> {
99
98
  controls?: UniqueryControls$1<Own<T>, Nav<T>>;
100
99
  }>(id: Id<T>, query?: Q): Promise<Response<T, Q> | null>;
101
100
  /**
102
- * `POST /` — insert one record.
101
+ * `POST /` — insert one record. The version column (if any) is optional —
102
+ * the server initialises it; `$cas` is rejected (no meaning on insert).
103
103
  */
104
- insert(data: Partial<Data<T>>): Promise<TDbInsertResult$1>;
104
+ insert(data: PatchOf<T>): Promise<TDbInsertResult$1>;
105
105
  /**
106
106
  * `POST /` — insert many records.
107
107
  */
108
- insert(data: Partial<Data<T>>[]): Promise<TDbInsertManyResult$1>;
108
+ insert(data: PatchOf<T>[]): Promise<TDbInsertManyResult$1>;
109
109
  /**
110
110
  * `PATCH /` — partial update one or many records by primary key.
111
+ *
112
+ * Accepts both OCC shapes (since 0.1.128): a bare `version: N` (the wire
113
+ * contract) or the SDK `$cas: { version: N }`, which is lifted to `version`
114
+ * before preflight and sending. A stale version surfaces as
115
+ * {@link VersionMismatchError}; a PK-only body with a version is a real
116
+ * write (the server bumps the version).
111
117
  */
112
- update(data: Partial<Data<T>> | Partial<Data<T>>[]): Promise<TDbUpdateResult$1>;
118
+ update(data: PatchOf<T> | PatchOf<T>[]): Promise<TDbUpdateResult$1>;
113
119
  /**
114
- * `PUT /` — full replace one or many records by primary key.
120
+ * `PUT /` — full replace one or many records by primary key. Same OCC
121
+ * shapes as {@link update}; the version column itself is optional.
115
122
  */
116
- replace(data: Data<T> | Data<T>[]): Promise<TDbUpdateResult$1>;
123
+ replace(data: RowOf<T> | RowOf<T>[]): Promise<TDbUpdateResult$1>;
117
124
  /**
118
125
  * `DELETE /:id` or `DELETE /?k1=v1&k2=v2` — remove a record by primary key.
119
126
  */
@@ -177,7 +184,8 @@ declare class Client<T extends AtscriptClientShape = AtscriptClientShape> {
177
184
  * Useful for accessing `flatMap` and `navFields` (e.g. for form generation).
178
185
  */
179
186
  getValidator(): Promise<ClientValidator>;
180
- private _validateData;
187
+ /** Lifts `$cas` to the wire shape, then runs the preflight validator on the result. */
188
+ private _prepareWrite;
181
189
  private _getValidator;
182
190
  private _buildActionBody;
183
191
  private _interpolateNavigateUrl;
@@ -287,6 +295,28 @@ declare class VersionMismatchError extends ClientError {
287
295
  /** Row's current server-side version — clients refresh + retry against it. */
288
296
  get currentVersion(): number;
289
297
  }
298
+ /**
299
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
300
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
301
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
302
+ * server answered and rejected — the request's outcome is unknown: a write
303
+ * may have committed. Reload before retrying a non-idempotent write.
304
+ * The underlying error is the standard `cause`.
305
+ */
306
+ declare class TransportError extends Error {
307
+ /** HTTP method of the failed request. */
308
+ readonly method: string;
309
+ /** Full request URL. */
310
+ readonly url: string;
311
+ name: string;
312
+ constructor(/** HTTP method of the failed request. */
313
+
314
+ method: string, /** Full request URL. */
315
+
316
+ url: string, /** What went wrong; the message is `<method> <url>: <detail>`. */
317
+
318
+ detail: string, cause?: unknown);
319
+ }
290
320
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
291
321
  declare class ActionNotFoundError extends Error {
292
322
  readonly action: string;
@@ -306,4 +336,4 @@ declare class ActionUnsupportedError extends Error {
306
336
  constructor(action: string, processor: string, message: string);
307
337
  }
308
338
  //#endregion
309
- export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type RelationInfo, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
339
+ export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, TransportError, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
package/dist/index.mjs CHANGED
@@ -55,6 +55,24 @@ var VersionMismatchError = class extends ClientError {
55
55
  return this.body.currentVersion;
56
56
  }
57
57
  };
58
+ /**
59
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
60
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
61
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
62
+ * server answered and rejected — the request's outcome is unknown: a write
63
+ * may have committed. Reload before retrying a non-idempotent write.
64
+ * The underlying error is the standard `cause`.
65
+ */
66
+ var TransportError = class extends Error {
67
+ method;
68
+ url;
69
+ name = "TransportError";
70
+ constructor(method, url, detail, cause) {
71
+ super(`${method} ${url}: ${detail}`, { cause });
72
+ this.method = method;
73
+ this.url = url;
74
+ }
75
+ };
58
76
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
59
77
  var ActionNotFoundError = class extends Error {
60
78
  action;
@@ -211,22 +229,26 @@ var Client = class {
211
229
  return this._getOrNull(`one/${encodeURIComponent(String(id))}${controlStr ? `?${controlStr}` : ""}`);
212
230
  }
213
231
  async insert(data) {
214
- await this._validateData(data, "insert");
215
- return this._request("POST", "", data);
232
+ return this._request("POST", "", await this._prepareWrite(data, "insert"));
216
233
  }
217
234
  /**
218
235
  * `PATCH /` — partial update one or many records by primary key.
236
+ *
237
+ * Accepts both OCC shapes (since 0.1.128): a bare `version: N` (the wire
238
+ * contract) or the SDK `$cas: { version: N }`, which is lifted to `version`
239
+ * before preflight and sending. A stale version surfaces as
240
+ * {@link VersionMismatchError}; a PK-only body with a version is a real
241
+ * write (the server bumps the version).
219
242
  */
220
243
  async update(data) {
221
- await this._validateData(data, "patch");
222
- return this._request("PATCH", "", data);
244
+ return this._request("PATCH", "", await this._prepareWrite(data, "patch"));
223
245
  }
224
246
  /**
225
- * `PUT /` — full replace one or many records by primary key.
247
+ * `PUT /` — full replace one or many records by primary key. Same OCC
248
+ * shapes as {@link update}; the version column itself is optional.
226
249
  */
227
250
  async replace(data) {
228
- await this._validateData(data, "replace");
229
- return this._request("PUT", "", data);
251
+ return this._request("PUT", "", await this._prepareWrite(data, "replace"));
230
252
  }
231
253
  /**
232
254
  * `DELETE /:id` or `DELETE /?k1=v1&k2=v2` — remove a record by primary key.
@@ -328,8 +350,12 @@ var Client = class {
328
350
  getValidator() {
329
351
  return this._getValidator();
330
352
  }
331
- async _validateData(data, mode) {
332
- (await this._getValidator()).validate(data, mode);
353
+ /** Lifts `$cas` to the wire shape, then runs the preflight validator on the result. */
354
+ async _prepareWrite(data, mode) {
355
+ const validator = await this._getValidator();
356
+ const normalized = validator.liftCas(data, mode);
357
+ validator.validate(normalized, mode);
358
+ return normalized;
333
359
  }
334
360
  _getValidator() {
335
361
  if (!this._validatorPromise) this._validatorPromise = Promise.all([this.meta(), import("./validator.mjs")]).then(([m, { createClientValidator }]) => createClientValidator(m, { lenientWrites: this._lenientWrites })).catch((err) => {
@@ -421,14 +447,20 @@ var Client = class {
421
447
  return init;
422
448
  }
423
449
  async _send(url, init, allowEmpty) {
424
- const res = await this._fetch(url, init);
450
+ const method = init.method ?? "GET";
451
+ let res;
452
+ try {
453
+ res = await this._fetch(url, init);
454
+ } catch (cause) {
455
+ throw new TransportError(method, url, describeCause(cause), cause);
456
+ }
425
457
  if (!res.ok) {
426
458
  let errorBody;
427
459
  try {
428
460
  errorBody = await res.json();
429
461
  } catch {
430
462
  errorBody = {
431
- message: res.statusText,
463
+ message: res.statusText || `HTTP ${res.status}`,
432
464
  statusCode: res.status
433
465
  };
434
466
  }
@@ -436,7 +468,11 @@ var Client = class {
436
468
  if (errorBody.kind === "version_mismatch") throw new VersionMismatchError(res.status, errorBody);
437
469
  throw new ClientError(res.status, errorBody);
438
470
  }
439
- if (!allowEmpty) return res.json();
471
+ if (!allowEmpty) try {
472
+ return await res.json();
473
+ } catch (cause) {
474
+ throw new TransportError(method, url, `HTTP ${res.status} body is not JSON (${describeCause(cause)})`, cause);
475
+ }
440
476
  if (res.status === 204 || res.headers.get("content-length") === "0") return void 0;
441
477
  try {
442
478
  return await res.json();
@@ -445,6 +481,11 @@ var Client = class {
445
481
  }
446
482
  }
447
483
  };
484
+ /** One-line rendering of a thrown value for a `TransportError` message. */
485
+ function describeCause(cause) {
486
+ if (cause instanceof Error) return cause.message || cause.name;
487
+ return String(cause);
488
+ }
448
489
  /**
449
490
  * Render a single identifier field for substitution into a navigate-URL
450
491
  * template or human-readable string. `null` / `undefined` collapse to `""`
@@ -481,4 +522,4 @@ function describeShape(value) {
481
522
  return typeof value;
482
523
  }
483
524
  //#endregion
484
- export { ActionDisabledError, ActionNotFoundError, ActionUnsupportedError, Client, ClientError, VersionMismatchError, encodeNavigateId, formatIdentifier, formatIdentifierField };
525
+ export { ActionDisabledError, ActionNotFoundError, ActionUnsupportedError, Client, ClientError, TransportError, VersionMismatchError, encodeNavigateId, formatIdentifier, formatIdentifierField };
@@ -1,9 +1,17 @@
1
1
  import { AggregateQuery as AggregateQuery$1, AggregateResult as AggregateResult$1, FilterExpr, TypedWithRelation, Uniquery as Uniquery$1, UniqueryControls as UniqueryControls$1 } from "@uniqu/core";
2
2
  import { TAtscriptAnnotatedType, TAtscriptTypeObject } from "@atscript/typescript/utils";
3
- import { DbResponse, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1, TFieldMeta, TMetaResponse, TRelationInfo, TSearchIndexInfo } from "@atscript/db";
3
+ import { DbPatch, DbResponse, DbRow, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1, TFieldMeta, TMetaResponse, TRelationInfo, TSearchIndexInfo } from "@atscript/db";
4
4
  import { DbValidationContext, ValidatorMode, ValidatorMode as ValidatorMode$1 } from "@atscript/db/validator";
5
5
 
6
6
  //#region src/types.d.ts
7
+ /**
8
+ * Write payload for `insert()` / `update()`: every key optional, optional
9
+ * columns additionally accept `null` (explicit NULL). `$cas` is accepted on
10
+ * `update()` / `replace()` through the open index signature.
11
+ */
12
+ type PatchOf<T> = DbPatch<DataOf<T>>;
13
+ /** Write payload for `replace()`: full row; optional columns additionally accept `null`. */
14
+ type RowOf<T> = DbRow<DataOf<T>>;
7
15
  /** Options for creating a Client instance. */
8
16
  interface ClientOptions {
9
17
  /**
@@ -120,6 +128,12 @@ type ClientResponse<T, Q> = DbResponse<DataOf<T>, NavOf<T>, Q> & {
120
128
  //#region src/validator.d.ts
121
129
  /** Options for {@link ClientValidator} / {@link createClientValidator}. */
122
130
  interface ClientValidatorOptions {
131
+ /**
132
+ * The table's `@db.column.version` column (from `/meta`'s `versionColumn`).
133
+ * Enables the `$cas` lift in {@link ClientValidator.liftCas}; without it a
134
+ * `$cas` payload is rejected (the table is not versioned).
135
+ */
136
+ versionColumn?: string;
123
137
  /**
124
138
  * Tolerate unknown properties in write payloads. Enable when the served
125
139
  * `/meta` type is a PROJECTION of the full server-side type (e.g. an ARBAC
@@ -144,7 +158,21 @@ declare class ClientValidator {
144
158
  readonly flatMap: Map<string, TAtscriptAnnotatedType>;
145
159
  /** Set of field paths that are navigation relations (TO/FROM/VIA). */
146
160
  readonly navFields: ReadonlySet<string>;
161
+ /** The table's version column when it opts into OCC (from `/meta`). */
162
+ readonly versionColumn?: string;
147
163
  constructor(type: TAtscriptAnnotatedType<TAtscriptTypeObject>, opts?: ClientValidatorOptions);
164
+ /**
165
+ * Normalises the SDK `$cas` shape to the wire shape (since 0.1.128):
166
+ * `{ id, $cas: { version: 4 } }` → `{ id, version: 4 }` (the server lifts
167
+ * `version` back to `$cas`). Returns a shallow clone per item; items
168
+ * without `$cas` (a `$cas: undefined` counts as absent) are returned
169
+ * as-is. Throws `ClientValidationError` when the table is not versioned,
170
+ * the `$cas` shape is invalid, or `version` and `$cas` disagree — the same
171
+ * messages the server produces, from the shared `reconcileCas` — or when
172
+ * `$cas` appears on an insert.
173
+ */
174
+ liftCas(data: unknown, mode: ValidatorMode): unknown;
175
+ private _liftCasItem;
148
176
  /**
149
177
  * Validate data for a given write mode.
150
178
  * Throws `ClientValidationError` if validation fails.
@@ -178,4 +206,4 @@ declare class ClientValidationError extends Error {
178
206
  */
179
207
  declare function createClientValidator(meta: MetaResponse, opts?: ClientValidatorOptions): ClientValidator;
180
208
  //#endregion
181
- export { TDbDeleteResult$1 as C, TypedWithRelation as D, TDbUpdateResult$1 as E, Uniquery$1 as O, ServerError as S, TDbInsertResult$1 as T, NavOf as _, ValidatorMode$1 as a, RelationInfo as b, AggregateResult$1 as c, ClientResponse as d, DataOf as f, MetaResponse as g, IdOf as h, DbValidationContext as i, UniqueryControls$1 as k, AtscriptClientShape as l, FilterExpr as m, ClientValidator as n, createClientValidator as o, FieldMeta as p, ClientValidatorOptions as r, AggregateQuery$1 as s, ClientValidationError as t, ClientOptions as u, OwnOf as v, TDbInsertManyResult$1 as w, SearchIndexInfo as x, PageResult as y };
209
+ export { TDbUpdateResult$1 as A, RelationInfo as C, TDbDeleteResult$1 as D, ServerError as E, Uniquery$1 as M, UniqueryControls$1 as N, TDbInsertManyResult$1 as O, PatchOf as S, SearchIndexInfo as T, IdOf as _, ValidatorMode$1 as a, OwnOf as b, AggregateResult$1 as c, ClientResponse as d, DataOf as f, FilterExpr as g, FieldMeta as h, DbValidationContext as i, TypedWithRelation as j, TDbInsertResult$1 as k, AtscriptClientShape as l, DbRow as m, ClientValidator as n, createClientValidator as o, DbPatch as p, ClientValidatorOptions as r, AggregateQuery$1 as s, ClientValidationError as t, ClientOptions as u, MetaResponse as v, RowOf as w, PageResult as x, NavOf as y };
@@ -1,9 +1,17 @@
1
1
  import { TAtscriptAnnotatedType, TAtscriptTypeObject } from "@atscript/typescript/utils";
2
2
  import { DbValidationContext, ValidatorMode, ValidatorMode as ValidatorMode$1 } from "@atscript/db/validator";
3
3
  import { AggregateQuery as AggregateQuery$1, AggregateResult as AggregateResult$1, FilterExpr, TypedWithRelation, Uniquery as Uniquery$1, UniqueryControls as UniqueryControls$1 } from "@uniqu/core";
4
- import { DbResponse, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1, TFieldMeta, TMetaResponse, TRelationInfo, TSearchIndexInfo } from "@atscript/db";
4
+ import { DbPatch, DbResponse, DbRow, TDbDeleteResult as TDbDeleteResult$1, TDbInsertManyResult as TDbInsertManyResult$1, TDbInsertResult as TDbInsertResult$1, TDbUpdateResult as TDbUpdateResult$1, TFieldMeta, TMetaResponse, TRelationInfo, TSearchIndexInfo } from "@atscript/db";
5
5
 
6
6
  //#region src/types.d.ts
7
+ /**
8
+ * Write payload for `insert()` / `update()`: every key optional, optional
9
+ * columns additionally accept `null` (explicit NULL). `$cas` is accepted on
10
+ * `update()` / `replace()` through the open index signature.
11
+ */
12
+ type PatchOf<T> = DbPatch<DataOf<T>>;
13
+ /** Write payload for `replace()`: full row; optional columns additionally accept `null`. */
14
+ type RowOf<T> = DbRow<DataOf<T>>;
7
15
  /** Options for creating a Client instance. */
8
16
  interface ClientOptions {
9
17
  /**
@@ -120,6 +128,12 @@ type ClientResponse<T, Q> = DbResponse<DataOf<T>, NavOf<T>, Q> & {
120
128
  //#region src/validator.d.ts
121
129
  /** Options for {@link ClientValidator} / {@link createClientValidator}. */
122
130
  interface ClientValidatorOptions {
131
+ /**
132
+ * The table's `@db.column.version` column (from `/meta`'s `versionColumn`).
133
+ * Enables the `$cas` lift in {@link ClientValidator.liftCas}; without it a
134
+ * `$cas` payload is rejected (the table is not versioned).
135
+ */
136
+ versionColumn?: string;
123
137
  /**
124
138
  * Tolerate unknown properties in write payloads. Enable when the served
125
139
  * `/meta` type is a PROJECTION of the full server-side type (e.g. an ARBAC
@@ -144,7 +158,21 @@ declare class ClientValidator {
144
158
  readonly flatMap: Map<string, TAtscriptAnnotatedType>;
145
159
  /** Set of field paths that are navigation relations (TO/FROM/VIA). */
146
160
  readonly navFields: ReadonlySet<string>;
161
+ /** The table's version column when it opts into OCC (from `/meta`). */
162
+ readonly versionColumn?: string;
147
163
  constructor(type: TAtscriptAnnotatedType<TAtscriptTypeObject>, opts?: ClientValidatorOptions);
164
+ /**
165
+ * Normalises the SDK `$cas` shape to the wire shape (since 0.1.128):
166
+ * `{ id, $cas: { version: 4 } }` → `{ id, version: 4 }` (the server lifts
167
+ * `version` back to `$cas`). Returns a shallow clone per item; items
168
+ * without `$cas` (a `$cas: undefined` counts as absent) are returned
169
+ * as-is. Throws `ClientValidationError` when the table is not versioned,
170
+ * the `$cas` shape is invalid, or `version` and `$cas` disagree — the same
171
+ * messages the server produces, from the shared `reconcileCas` — or when
172
+ * `$cas` appears on an insert.
173
+ */
174
+ liftCas(data: unknown, mode: ValidatorMode): unknown;
175
+ private _liftCasItem;
148
176
  /**
149
177
  * Validate data for a given write mode.
150
178
  * Throws `ClientValidationError` if validation fails.
@@ -178,4 +206,4 @@ declare class ClientValidationError extends Error {
178
206
  */
179
207
  declare function createClientValidator(meta: MetaResponse, opts?: ClientValidatorOptions): ClientValidator;
180
208
  //#endregion
181
- export { TDbDeleteResult$1 as C, TypedWithRelation as D, TDbUpdateResult$1 as E, Uniquery$1 as O, ServerError as S, TDbInsertResult$1 as T, NavOf as _, ValidatorMode$1 as a, RelationInfo as b, AggregateResult$1 as c, ClientResponse as d, DataOf as f, MetaResponse as g, IdOf as h, DbValidationContext as i, UniqueryControls$1 as k, AtscriptClientShape as l, FilterExpr as m, ClientValidator as n, createClientValidator as o, FieldMeta as p, ClientValidatorOptions as r, AggregateQuery$1 as s, ClientValidationError as t, ClientOptions as u, OwnOf as v, TDbInsertManyResult$1 as w, SearchIndexInfo as x, PageResult as y };
209
+ export { TDbUpdateResult$1 as A, RelationInfo as C, TDbDeleteResult$1 as D, ServerError as E, Uniquery$1 as M, UniqueryControls$1 as N, TDbInsertManyResult$1 as O, PatchOf as S, SearchIndexInfo as T, IdOf as _, ValidatorMode$1 as a, OwnOf as b, AggregateResult$1 as c, ClientResponse as d, DataOf as f, FilterExpr as g, FieldMeta as h, DbValidationContext as i, TypedWithRelation as j, TDbInsertResult$1 as k, AtscriptClientShape as l, DbRow as m, ClientValidator as n, createClientValidator as o, DbPatch as p, ClientValidatorOptions as r, AggregateQuery$1 as s, ClientValidationError as t, ClientOptions as u, MetaResponse as v, RowOf as w, PageResult as x, NavOf as y };
@@ -15,14 +15,51 @@ var ClientValidator = class {
15
15
  flatMap;
16
16
  /** Set of field paths that are navigation relations (TO/FROM/VIA). */
17
17
  navFields;
18
+ /** The table's version column when it opts into OCC (from `/meta`). */
19
+ versionColumn;
18
20
  constructor(type, opts) {
19
21
  this._type = type;
20
22
  this._lenientWrites = opts?.lenientWrites === true;
23
+ this.versionColumn = opts?.versionColumn;
21
24
  const ctx = (0, _atscript_db_validator.buildValidationContext)(type);
22
25
  this.flatMap = ctx.flatMap;
23
26
  this.navFields = ctx.navFields;
24
27
  }
25
28
  /**
29
+ * Normalises the SDK `$cas` shape to the wire shape (since 0.1.128):
30
+ * `{ id, $cas: { version: 4 } }` → `{ id, version: 4 }` (the server lifts
31
+ * `version` back to `$cas`). Returns a shallow clone per item; items
32
+ * without `$cas` (a `$cas: undefined` counts as absent) are returned
33
+ * as-is. Throws `ClientValidationError` when the table is not versioned,
34
+ * the `$cas` shape is invalid, or `version` and `$cas` disagree — the same
35
+ * messages the server produces, from the shared `reconcileCas` — or when
36
+ * `$cas` appears on an insert.
37
+ */
38
+ liftCas(data, mode) {
39
+ if (Array.isArray(data)) return data.map((item, i) => this._liftCasItem(item, mode, `[${i}].`));
40
+ return this._liftCasItem(data, mode, "");
41
+ }
42
+ _liftCasItem(item, mode, prefix) {
43
+ if (item === null || typeof item !== "object" || Array.isArray(item)) return item;
44
+ if (item.$cas === void 0) return item;
45
+ const path = `${prefix}$cas`;
46
+ if (mode === "insert") throw new ClientValidationError([{
47
+ path,
48
+ message: "$cas is not allowed on insert"
49
+ }]);
50
+ const clone = { ...item };
51
+ try {
52
+ (0, _atscript_db_validator.reconcileCas)(clone, this.versionColumn, "version");
53
+ } catch (e) {
54
+ if (e instanceof _atscript_db_validator.DbError) throw new ClientValidationError(e.errors.map((err) => ({
55
+ path: `${prefix}${err.path}`,
56
+ message: err.message
57
+ })));
58
+ throw e;
59
+ }
60
+ return clone;
61
+ }
62
+ /**
26
63
  * Validate data for a given write mode.
27
64
  * Throws `ClientValidationError` if validation fails.
28
65
  */
@@ -76,7 +113,10 @@ var ClientValidationError = class extends Error {
76
113
  * ```
77
114
  */
78
115
  function createClientValidator(meta, opts) {
79
- return new ClientValidator((0, _atscript_typescript_utils.deserializeAnnotatedType)(meta.type), opts);
116
+ return new ClientValidator((0, _atscript_typescript_utils.deserializeAnnotatedType)(meta.type), {
117
+ versionColumn: meta.versionColumn,
118
+ ...opts
119
+ });
80
120
  }
81
121
  //#endregion
82
122
  exports.ClientValidationError = ClientValidationError;
@@ -1,2 +1,2 @@
1
- import { a as ValidatorMode, i as DbValidationContext, n as ClientValidator, o as createClientValidator, r as ClientValidatorOptions, t as ClientValidationError } from "./validator-3I12BVi4.cjs";
1
+ import { a as ValidatorMode, i as DbValidationContext, n as ClientValidator, o as createClientValidator, r as ClientValidatorOptions, t as ClientValidationError } from "./validator-C3uaaZkU.cjs";
2
2
  export { ClientValidationError, ClientValidator, ClientValidatorOptions, type DbValidationContext, type ValidatorMode, createClientValidator };
@@ -1,2 +1,2 @@
1
- import { a as ValidatorMode, i as DbValidationContext, n as ClientValidator, o as createClientValidator, r as ClientValidatorOptions, t as ClientValidationError } from "./validator-DBEmk_s8.mjs";
1
+ import { a as ValidatorMode, i as DbValidationContext, n as ClientValidator, o as createClientValidator, r as ClientValidatorOptions, t as ClientValidationError } from "./validator-CfPFKDL_.mjs";
2
2
  export { ClientValidationError, ClientValidator, ClientValidatorOptions, type DbValidationContext, type ValidatorMode, createClientValidator };
@@ -1,5 +1,5 @@
1
1
  import { deserializeAnnotatedType } from "@atscript/typescript/utils";
2
- import { buildDbValidator, buildValidationContext } from "@atscript/db/validator";
2
+ import { DbError, buildDbValidator, buildValidationContext, reconcileCas } from "@atscript/db/validator";
3
3
  //#region src/validator.ts
4
4
  /**
5
5
  * Client-side validator backed by an Atscript type from the `/meta` endpoint.
@@ -14,14 +14,51 @@ var ClientValidator = class {
14
14
  flatMap;
15
15
  /** Set of field paths that are navigation relations (TO/FROM/VIA). */
16
16
  navFields;
17
+ /** The table's version column when it opts into OCC (from `/meta`). */
18
+ versionColumn;
17
19
  constructor(type, opts) {
18
20
  this._type = type;
19
21
  this._lenientWrites = opts?.lenientWrites === true;
22
+ this.versionColumn = opts?.versionColumn;
20
23
  const ctx = buildValidationContext(type);
21
24
  this.flatMap = ctx.flatMap;
22
25
  this.navFields = ctx.navFields;
23
26
  }
24
27
  /**
28
+ * Normalises the SDK `$cas` shape to the wire shape (since 0.1.128):
29
+ * `{ id, $cas: { version: 4 } }` → `{ id, version: 4 }` (the server lifts
30
+ * `version` back to `$cas`). Returns a shallow clone per item; items
31
+ * without `$cas` (a `$cas: undefined` counts as absent) are returned
32
+ * as-is. Throws `ClientValidationError` when the table is not versioned,
33
+ * the `$cas` shape is invalid, or `version` and `$cas` disagree — the same
34
+ * messages the server produces, from the shared `reconcileCas` — or when
35
+ * `$cas` appears on an insert.
36
+ */
37
+ liftCas(data, mode) {
38
+ if (Array.isArray(data)) return data.map((item, i) => this._liftCasItem(item, mode, `[${i}].`));
39
+ return this._liftCasItem(data, mode, "");
40
+ }
41
+ _liftCasItem(item, mode, prefix) {
42
+ if (item === null || typeof item !== "object" || Array.isArray(item)) return item;
43
+ if (item.$cas === void 0) return item;
44
+ const path = `${prefix}$cas`;
45
+ if (mode === "insert") throw new ClientValidationError([{
46
+ path,
47
+ message: "$cas is not allowed on insert"
48
+ }]);
49
+ const clone = { ...item };
50
+ try {
51
+ reconcileCas(clone, this.versionColumn, "version");
52
+ } catch (e) {
53
+ if (e instanceof DbError) throw new ClientValidationError(e.errors.map((err) => ({
54
+ path: `${prefix}${err.path}`,
55
+ message: err.message
56
+ })));
57
+ throw e;
58
+ }
59
+ return clone;
60
+ }
61
+ /**
25
62
  * Validate data for a given write mode.
26
63
  * Throws `ClientValidationError` if validation fails.
27
64
  */
@@ -75,7 +112,10 @@ var ClientValidationError = class extends Error {
75
112
  * ```
76
113
  */
77
114
  function createClientValidator(meta, opts) {
78
- return new ClientValidator(deserializeAnnotatedType(meta.type), opts);
115
+ return new ClientValidator(deserializeAnnotatedType(meta.type), {
116
+ versionColumn: meta.versionColumn,
117
+ ...opts
118
+ });
79
119
  }
80
120
  //#endregion
81
121
  export { ClientValidationError, ClientValidator, createClientValidator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db-client",
3
- "version": "0.1.127",
3
+ "version": "0.1.129",
4
4
  "description": "Browser-compatible HTTP client for @atscript/moost-db REST endpoints.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -43,18 +43,18 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@uniqu/url": "^0.1.7"
46
+ "@uniqu/url": "^0.1.8"
47
47
  },
48
48
  "devDependencies": {
49
- "@atscript/core": "^0.1.89",
50
- "@atscript/typescript": "^0.1.89",
51
- "@uniqu/core": "^0.1.7",
52
- "unplugin-atscript": "^0.1.89",
53
- "@atscript/db": "0.1.127"
49
+ "@atscript/core": "^0.1.92",
50
+ "@atscript/typescript": "^0.1.92",
51
+ "@uniqu/core": "^0.1.8",
52
+ "unplugin-atscript": "^0.1.92",
53
+ "@atscript/db": "0.1.129"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@atscript/db": "^0.1.44",
57
- "@atscript/typescript": "^0.1.89"
57
+ "@atscript/typescript": "^0.1.92"
58
58
  },
59
59
  "scripts": {
60
60
  "postinstall": "asc -f dts",