@riffdb/client 0.2.3 → 0.2.5

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/README.md CHANGED
@@ -7,8 +7,8 @@ compiler IDs, storage keys, or an authorization bypass.
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- npm install --save-dev @riffdb/cli@0.2.3
11
- npm install @riffdb/client@0.2.3
10
+ npm install --save-dev @riffdb/cli@0.2.5
11
+ npm install @riffdb/client@0.2.5
12
12
  ```
13
13
 
14
14
  ## Four-step application story
@@ -3,8 +3,10 @@
3
3
  "language": "typescript",
4
4
  "artifact": "offline-npm-tree",
5
5
  "transport": "retained-rust-driver-host",
6
- "platforms": ["linux-x86_64"],
7
- "corpus_sha256": "69e9fdcbc350308ceda6fbaf1d97ff65ff6b4598dfe3b37693ed9043a05ca764",
6
+ "platforms": [
7
+ "linux-x86_64"
8
+ ],
9
+ "corpus_sha256": "57db5444d3e92f6e4b911b4db42c4d265c5dc55cae80c8270a5428dbbd7b6b74",
8
10
  "remote_tls": "installed",
9
11
  "typed_errors": "installed",
10
12
  "read_after_commit": "installed",
package/dist/driver.d.ts CHANGED
@@ -159,6 +159,7 @@ export interface DriverErrorDetails {
159
159
  readonly category: string;
160
160
  readonly operation?: string;
161
161
  readonly symbolPath: ReadonlyArray<string>;
162
+ readonly authorizationDiagnostic?: string;
162
163
  readonly contractLineage?: string;
163
164
  readonly contractVersion?: bigint;
164
165
  readonly traceId?: string;
package/dist/driver.js CHANGED
@@ -50,7 +50,14 @@ export class DriverApplicationError extends Error {
50
50
  details;
51
51
  name = "DriverApplicationError";
52
52
  constructor(details) {
53
- super(`${details.code}: ${details.message}`);
53
+ let text = `${details.code}: ${details.message}`;
54
+ if (details.symbolPath.length > 0) {
55
+ text += ` (${details.symbolPath.join(".")})`;
56
+ }
57
+ if (details.authorizationDiagnostic !== undefined) {
58
+ text += ` [diagnostic: ${details.authorizationDiagnostic}]`;
59
+ }
60
+ super(text);
54
61
  this.details = details;
55
62
  }
56
63
  }
@@ -940,6 +947,17 @@ function decodeBatchResult(response, expectedTotal, requestedCheckpoint) {
940
947
  });
941
948
  return { items, checkpoint, total };
942
949
  }
950
+ const AUTHORIZATION_DIAGNOSTIC_CODES = new Set([
951
+ "missing_permission",
952
+ "scan_budget_exceeded",
953
+ "tenant_scope_mismatch",
954
+ "partition_scope_mismatch",
955
+ "field_visibility_denied",
956
+ "row_policy_denied",
957
+ "approval_required",
958
+ "delegation_exceeds_authority",
959
+ "inactive_or_stale_capability",
960
+ ]);
943
961
  function decodeError(response) {
944
962
  const code = boundedPattern(response.code, /^[A-Z0-9-]{1,64}$/);
945
963
  const category = boundedPattern(response.category, /^[a-z_]{1,64}$/);
@@ -950,6 +968,11 @@ function decodeError(response) {
950
968
  throw new Error("RiffDB driver returned invalid error context");
951
969
  }
952
970
  const symbolPath = response.symbol_path.map((value) => boundedPattern(value, SYMBOL));
971
+ const authorizationDiagnostic = optionalPattern(response.authorization_diagnostic, SYMBOL);
972
+ if (authorizationDiagnostic !== undefined &&
973
+ (code !== "RDB-AUTH-0214" || !AUTHORIZATION_DIAGNOSTIC_CODES.has(authorizationDiagnostic))) {
974
+ throw new Error("RiffDB driver returned invalid error context");
975
+ }
953
976
  const operation = optionalPattern(response.operation, SYMBOL);
954
977
  const contractLineage = optionalPattern(response.contract_lineage, SYMBOL);
955
978
  const contractVersion = optionalPositiveBigInt(response.contract_version);
@@ -963,6 +986,7 @@ function decodeError(response) {
963
986
  return new DriverApplicationError({
964
987
  code, category, symbolPath, message, retryability, recoveryAction,
965
988
  outcomeUncertain: response.outcome_uncertain,
989
+ ...(authorizationDiagnostic === undefined ? {} : { authorizationDiagnostic }),
966
990
  ...(operation === undefined ? {} : { operation }),
967
991
  ...(contractLineage === undefined ? {} : { contractLineage }),
968
992
  ...(contractVersion === undefined ? {} : { contractVersion }),
@@ -1113,7 +1137,7 @@ function validateDriverValue(value, depth) {
1113
1137
  BigInt(boundedPattern(item.value, /^[0-9]{1,20}$/));
1114
1138
  return item;
1115
1139
  }
1116
- if (type === "string" && typeof item.value === "string" && item.value.length <= 262_144)
1140
+ if (type === "string" && typeof item.value === "string" && Buffer.byteLength(item.value, "utf8") <= 1_048_576)
1117
1141
  return item;
1118
1142
  // Byte values use padded Base64 on this bounded JSON protocol. Their
1119
1143
  // canonical decoded size is checked by the generated facade and service;
package/dist/index.js CHANGED
@@ -1247,13 +1247,13 @@ function encodeDriverValue(value, schema, budgetPath) {
1247
1247
  return { type: "u64", value: parsed.toString() };
1248
1248
  }
1249
1249
  case "string": {
1250
- const string = expectBoundedString(value, 262_144);
1250
+ const string = expectBoundedString(value, 1_048_576);
1251
1251
  if (schema.maximumBytes !== undefined && new TextEncoder().encode(string).length > schema.maximumBytes && budgetPath !== undefined) {
1252
1252
  throw new InputBudgetError("individual_value_bytes", budgetPath);
1253
1253
  }
1254
1254
  return { type: "string", value: string };
1255
1255
  }
1256
- case "cursor": return { type: "string", value: expectBoundedString(value, 262_144) };
1256
+ case "cursor": return { type: "string", value: expectBoundedString(value, 1_048_576) };
1257
1257
  case "uuid":
1258
1258
  if (typeof value !== "string" || !UUID.test(value))
1259
1259
  throw new Error("invalid generated RiffDB UUID input");
@@ -1481,7 +1481,7 @@ function decodeDriverValue(value, schema) {
1481
1481
  case "string":
1482
1482
  case "cursor":
1483
1483
  if (value.type === "string")
1484
- return expectBoundedString(value.value, 262_144);
1484
+ return expectBoundedString(value.value, 1_048_576);
1485
1485
  break;
1486
1486
  case "uuid":
1487
1487
  if (value.type === "uuid" && UUID.test(value.value))
@@ -1693,13 +1693,13 @@ function encodeValue(value, schema, budgetPath) {
1693
1693
  case "enum":
1694
1694
  return { $enum: expectSymbol(value) };
1695
1695
  case "string": {
1696
- const string = expectBoundedString(value, 262_144);
1696
+ const string = expectBoundedString(value, 1_048_576);
1697
1697
  if (schema.maximumBytes !== undefined && new TextEncoder().encode(string).length > schema.maximumBytes && budgetPath !== undefined) {
1698
1698
  throw new InputBudgetError("individual_value_bytes", budgetPath);
1699
1699
  }
1700
1700
  return string;
1701
1701
  }
1702
- case "cursor": return expectBoundedString(value, 262_144);
1702
+ case "cursor": return expectBoundedString(value, 1_048_576);
1703
1703
  case "bool":
1704
1704
  if (typeof value !== "boolean")
1705
1705
  throw new Error("invalid boolean input");
@@ -1790,7 +1790,7 @@ function canonicalValueEncodedLength(value, schema) {
1790
1790
  case "decimal": return 20;
1791
1791
  case "money": return 23;
1792
1792
  case "string":
1793
- case "cursor": return 6 + new TextEncoder().encode(expectBoundedString(value, 262_144)).byteLength;
1793
+ case "cursor": return 6 + new TextEncoder().encode(expectBoundedString(value, 1_048_576)).byteLength;
1794
1794
  case "bytes": {
1795
1795
  if (!(value instanceof Uint8Array))
1796
1796
  throw new Error("invalid generated application input");
@@ -1859,7 +1859,7 @@ function decodeTagged(value) {
1859
1859
  case "i64":
1860
1860
  case "u64": return BigInt(expectDecimal(input.value));
1861
1861
  case "string":
1862
- case "uuid": return expectBoundedString(input.value, 262_144);
1862
+ case "uuid": return expectBoundedString(input.value, 1_048_576);
1863
1863
  case "enum": return expectSymbol(input.name);
1864
1864
  case "date": return Number(expectDecimal(input.days_since_unix_epoch));
1865
1865
  case "timestamp": return createTimestampValue(BigInt(expectDecimal(input.seconds)), nonnegativeNumber(input.nanos));
@@ -2040,6 +2040,8 @@ function normalizeError(input) {
2040
2040
  output.contractVersion = Number(expectDecimal(input.contract_version));
2041
2041
  if (input.operation_symbol !== undefined)
2042
2042
  output.operationSymbol = input.operation_symbol;
2043
+ if (input.authorization_diagnostic !== undefined)
2044
+ output.authorizationDiagnostic = input.authorization_diagnostic;
2043
2045
  if (input.source_span !== undefined) {
2044
2046
  const span = exactObject(input.source_span);
2045
2047
  output.sourceSpan = { start: Number(expectDecimal(span.start)), end: Number(expectDecimal(span.end)) };
@@ -2117,7 +2119,7 @@ function encodeCliReactiveValue(value, schema) {
2117
2119
  return { type: "u64", value: value.toString() };
2118
2120
  case "string":
2119
2121
  case "cursor":
2120
- return { type: "string", value: expectBoundedString(value, 262_144) };
2122
+ return { type: "string", value: expectBoundedString(value, 1_048_576) };
2121
2123
  case "uuid":
2122
2124
  if (typeof value !== "string" || !UUID.test(value))
2123
2125
  return fail();
package/dist/operator.js CHANGED
@@ -22,14 +22,12 @@ export class OperatorError extends Error {
22
22
  */
23
23
  export class OperatorTransport {
24
24
  #socket;
25
- #identity;
26
25
  #input = Buffer.alloc(0);
27
26
  #pending;
28
27
  #nextRequest = 1;
29
28
  #closed = false;
30
- constructor(socket, identity) {
29
+ constructor(socket) {
31
30
  this.#socket = socket;
32
- this.#identity = identity;
33
31
  socket.on("data", (chunk) => this.#receive(chunk));
34
32
  socket.on("error", () => this.#fail(new Error("RiffDB operator session failed")));
35
33
  socket.on("close", () => this.#fail(new Error("RiffDB operator session closed")));
@@ -42,7 +40,7 @@ export class OperatorTransport {
42
40
  socket.once("connect", () => { socket.off("error", onError); resolve(); });
43
41
  socket.once("error", onError);
44
42
  });
45
- const transport = new OperatorTransport(socket, identity);
43
+ const transport = new OperatorTransport(socket);
46
44
  try {
47
45
  const requestId = transport.#requestId("handshake");
48
46
  const response = await transport.#request({
package/package.json CHANGED
@@ -1 +1 @@
1
- {"description":"First-party application runtime for the Rust-owned RiffDB driver host","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./operator":"./dist/operator.js"},"files":["dist","README.md","conformance-manifest-v1.json"],"license":"MIT OR Apache-2.0","name":"@riffdb/client","repository":{"type":"git","url":"git+https://github.com/riffdb/riffdb.git"},"type":"module","types":"./dist/index.d.ts","version":"0.2.3"}
1
+ {"description":"First-party application runtime for the Rust-owned RiffDB driver host","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./operator":"./dist/operator.js"},"files":["dist","README.md","conformance-manifest-v1.json"],"license":"MIT OR Apache-2.0","name":"@riffdb/client","repository":{"type":"git","url":"git+https://github.com/riffdb/riffdb.git"},"type":"module","types":"./dist/index.d.ts","version":"0.2.5"}