@distrohelena/canton-typescript-sdk 0.1.8 → 0.1.11

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.
@@ -0,0 +1,5 @@
1
+ /** Explicit DAML contract-id value, distinguished from ordinary text. */
2
+ export declare class DamlContractId {
3
+ readonly value: string;
4
+ constructor(value: string);
5
+ }
@@ -0,0 +1,11 @@
1
+ import { ValidationError } from "../errors/validation-error.js";
2
+ /** Explicit DAML contract-id value, distinguished from ordinary text. */
3
+ export class DamlContractId {
4
+ value;
5
+ constructor(value) {
6
+ if (value.length === 0) {
7
+ throw new ValidationError("DAML contract ids must not be empty");
8
+ }
9
+ this.value = value;
10
+ }
11
+ }
@@ -0,0 +1,35 @@
1
+ import { TemplateId } from "../../query/model-types.js";
2
+ export declare class DamlUnit {
3
+ }
4
+ export declare class DamlDate {
5
+ readonly daysSinceEpoch: number;
6
+ constructor(daysSinceEpoch: number);
7
+ }
8
+ export declare class DamlTimestamp {
9
+ readonly microsecondsSinceEpoch: string;
10
+ constructor(microsecondsSinceEpoch: string);
11
+ }
12
+ export declare class DamlTextMap {
13
+ readonly entries: readonly (readonly [string, unknown])[];
14
+ constructor(entries: readonly (readonly [string, unknown])[]);
15
+ }
16
+ export declare class DamlGenMap {
17
+ readonly entries: readonly (readonly [unknown, unknown])[];
18
+ constructor(entries: readonly (readonly [unknown, unknown])[]);
19
+ }
20
+ export declare class DamlVariant {
21
+ readonly constructorName: string;
22
+ readonly value: unknown;
23
+ readonly variantId?: TemplateId | undefined;
24
+ constructor(constructorName: string, value: unknown, variantId?: TemplateId | undefined);
25
+ }
26
+ export declare class DamlEnum {
27
+ readonly constructorName: string;
28
+ readonly enumId?: TemplateId | undefined;
29
+ constructor(constructorName: string, enumId?: TemplateId | undefined);
30
+ }
31
+ export declare class DamlRecord {
32
+ readonly fields: Readonly<Record<string, unknown>>;
33
+ readonly recordId?: TemplateId | undefined;
34
+ constructor(fields: Readonly<Record<string, unknown>>, recordId?: TemplateId | undefined);
35
+ }
@@ -0,0 +1,52 @@
1
+ export class DamlUnit {
2
+ }
3
+ export class DamlDate {
4
+ daysSinceEpoch;
5
+ constructor(daysSinceEpoch) {
6
+ this.daysSinceEpoch = daysSinceEpoch;
7
+ }
8
+ }
9
+ export class DamlTimestamp {
10
+ microsecondsSinceEpoch;
11
+ constructor(microsecondsSinceEpoch) {
12
+ this.microsecondsSinceEpoch = microsecondsSinceEpoch;
13
+ }
14
+ }
15
+ export class DamlTextMap {
16
+ entries;
17
+ constructor(entries) {
18
+ this.entries = entries;
19
+ }
20
+ }
21
+ export class DamlGenMap {
22
+ entries;
23
+ constructor(entries) {
24
+ this.entries = entries;
25
+ }
26
+ }
27
+ export class DamlVariant {
28
+ constructorName;
29
+ value;
30
+ variantId;
31
+ constructor(constructorName, value, variantId) {
32
+ this.constructorName = constructorName;
33
+ this.value = value;
34
+ this.variantId = variantId;
35
+ }
36
+ }
37
+ export class DamlEnum {
38
+ constructorName;
39
+ enumId;
40
+ constructor(constructorName, enumId) {
41
+ this.constructorName = constructorName;
42
+ this.enumId = enumId;
43
+ }
44
+ }
45
+ export class DamlRecord {
46
+ fields;
47
+ recordId;
48
+ constructor(fields, recordId) {
49
+ this.fields = fields;
50
+ this.recordId = recordId;
51
+ }
52
+ }
package/dist/index.d.ts CHANGED
@@ -208,6 +208,8 @@ export type { ExternalPartySigner, ExternalPartySigningRequest, ExternalPartySig
208
208
  export { AllocatePartyRequest } from "./core/types/requests/allocate-party-request.js";
209
209
  export { DisclosedContract } from "./core/types/disclosed-contract.js";
210
210
  export { PreparedCommandSubmission } from "./core/types/prepared-command-submission.js";
211
+ export { DamlContractId } from "./core/types/daml-contract-id.js";
212
+ export { DamlUnit, DamlDate, DamlTimestamp, DamlTextMap, DamlGenMap, DamlVariant, DamlEnum, DamlRecord } from "./core/types/daml-values.js";
211
213
  export { AddPartyAsyncArguments } from "./core/types/requests/add-party-async-request.js";
212
214
  export { AddPartyAsyncRequest } from "./core/types/requests/add-party-async-request.js";
213
215
  export { AssembleSignedTopologyTransactionsRequest } from "./core/types/requests/assemble-signed-topology-transactions-request.js";
package/dist/index.js CHANGED
@@ -195,6 +195,8 @@ export { CreateExternalPartyRequest, } from "./core/types/requests/create-extern
195
195
  export { AllocatePartyRequest } from "./core/types/requests/allocate-party-request.js";
196
196
  export { DisclosedContract } from "./core/types/disclosed-contract.js";
197
197
  export { PreparedCommandSubmission } from "./core/types/prepared-command-submission.js";
198
+ export { DamlContractId } from "./core/types/daml-contract-id.js";
199
+ export { DamlUnit, DamlDate, DamlTimestamp, DamlTextMap, DamlGenMap, DamlVariant, DamlEnum, DamlRecord } from "./core/types/daml-values.js";
198
200
  export { AddPartyAsyncArguments } from "./core/types/requests/add-party-async-request.js";
199
201
  export { AddPartyAsyncRequest } from "./core/types/requests/add-party-async-request.js";
200
202
  export { AssembleSignedTopologyTransactionsRequest } from "./core/types/requests/assemble-signed-topology-transactions-request.js";
@@ -55,6 +55,8 @@ export class GrpcContractQueryClient {
55
55
  let rows = snapshot.filter((row) => args.where?.contractId?.equals === undefined
56
56
  ? true
57
57
  : row.contractId === args.where.contractId.equals);
58
+ if (args.where?.payload !== undefined)
59
+ rows = rows.filter((row) => matchesPayload(row.payload, args.where.payload));
58
60
  return rows;
59
61
  }
60
62
  unsupported(operation) {
@@ -99,7 +101,7 @@ export class GrpcContractQueryClient {
99
101
  function hasUnsupportedFilter(where) {
100
102
  if (where === undefined)
101
103
  return false;
102
- if ("and" in where || "or" in where || "not" in where || "payload" in where || "createdEventOffset" in where || "createdAt" in where || "archivedEventOffset" in where || "archivedAt" in where)
104
+ if ("and" in where || "or" in where || "not" in where || "createdEventOffset" in where || "createdAt" in where || "archivedEventOffset" in where || "archivedAt" in where)
103
105
  return true;
104
106
  for (const field of ["contractId", "templateId"]) {
105
107
  const filter = where[field];
@@ -115,7 +117,7 @@ function mapGrpcContract(value) {
115
117
  contractId: row.contractId ?? "",
116
118
  templateId: { packageId: template?.packageId ?? "", moduleName: template?.moduleName ?? "", entityName: template?.entityName ?? "" },
117
119
  packageId: null,
118
- payload: undefined,
120
+ payload: row.payload,
119
121
  witnesses: [],
120
122
  createdEventOffset: "",
121
123
  createdAt: null,
@@ -124,3 +126,24 @@ function mapGrpcContract(value) {
124
126
  active: true,
125
127
  };
126
128
  }
129
+ function matchesPayload(value, filter) {
130
+ const match = filter.match;
131
+ if (match === undefined)
132
+ return false;
133
+ const visit = (current, node) => Object.entries(node).every(([key, child]) => {
134
+ const next = current !== null && typeof current === "object" ? current[key] : undefined;
135
+ const predicate = child;
136
+ if (Object.keys(predicate).some((name) => ["equals", "lt", "lte", "gt", "gte", "like", "ilike"].includes(name)))
137
+ return compare(String(next ?? ""), predicate);
138
+ return visit(next, predicate);
139
+ });
140
+ return visit(value, match);
141
+ }
142
+ function compare(value, filter) { if (filter.equals !== undefined)
143
+ return value === filter.equals; if (filter.like !== undefined || filter.ilike !== undefined) {
144
+ const pattern = String(filter.like ?? filter.ilike).replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replaceAll("%", ".*").replaceAll("_", ".");
145
+ return new RegExp(`^${pattern}$`, filter.ilike === undefined ? "" : "i").test(value);
146
+ } if (filter.lt !== undefined)
147
+ return value < String(filter.lt); if (filter.lte !== undefined)
148
+ return value <= String(filter.lte); if (filter.gt !== undefined)
149
+ return value > String(filter.gt); return value >= String(filter.gte); }
@@ -106,9 +106,12 @@ type PayloadValueFilter = {
106
106
  readonly gte?: never;
107
107
  readonly like?: never;
108
108
  };
109
+ export type PayloadMatch = {
110
+ readonly [field: string]: PayloadMatch | PayloadValueFilter;
111
+ };
109
112
  export type ContractPayloadFilter = {
110
- readonly path: string;
111
- } & PayloadValueFilter;
113
+ readonly match: PayloadMatch;
114
+ };
112
115
  type ContractWhereFields = {
113
116
  readonly contractId?: StringFilter;
114
117
  readonly templateId?: Partial<{
@@ -72,14 +72,15 @@ function compileWhere(where, addValue) {
72
72
  }
73
73
  if (key === "payload") {
74
74
  const payload = value;
75
- const path = payload.path;
76
- if (typeof path !== "string" || path.split(".").some((x) => x.length === 0))
77
- throw new Error("payload path must contain non-empty segments");
78
- const ops = ["equals", "lt", "lte", "gt", "gte", "like", "ilike"].filter((op) => payload[op] !== undefined);
79
- if (ops.length !== 1 || typeof payload[ops[0]] !== "string")
80
- throw new Error("payload requires exactly one string predicate");
81
- const op = { equals: "=", lt: "<", lte: "<=", gt: ">", gte: ">=", like: "like", ilike: "ilike" }[ops[0]];
82
- parts.push(`contract_row.payload #>> ${addValue(path.split("."))}::text[] ${op} ${addValue(payload[ops[0]])}`);
75
+ const compilePayload = (path, filter) => { const ops = ["equals", "lt", "lte", "gt", "gte", "like", "ilike"].filter((op) => filter[op] !== undefined); if (ops.length === 1) {
76
+ const op = { equals: "=", lt: "<", lte: "<=", gt: ">", gte: ">=", like: "like", ilike: "ilike" }[ops[0]];
77
+ parts.push(`contract_row.payload #>> ${addValue(path)}::text[] ${op} ${addValue(filter[ops[0]])}`);
78
+ return;
79
+ } for (const [name, child] of Object.entries(filter))
80
+ compilePayload([...path, name], child); };
81
+ if (payload.match === undefined)
82
+ throw new Error("payload requires match");
83
+ compilePayload([], payload.match);
83
84
  continue;
84
85
  }
85
86
  if (key === "templateId") {
@@ -4,6 +4,8 @@ import { CreateAndExerciseCommand } from "../../../core/types/commands/create-an
4
4
  import { CreateCommand } from "../../../core/types/commands/create-command.js";
5
5
  import { DamlNumeric } from "../../../core/types/daml-numeric.js";
6
6
  import { DamlParty } from "../../../core/types/daml-party.js";
7
+ import { DamlContractId } from "../../../core/types/daml-contract-id.js";
8
+ import { DamlDate, DamlEnum, DamlGenMap, DamlRecord, DamlTextMap, DamlTimestamp, DamlUnit, DamlVariant } from "../../../core/types/daml-values.js";
7
9
  import { ExerciseByKeyCommand } from "../../../core/types/commands/exercise-by-key-command.js";
8
10
  import { ExerciseCommand } from "../../../core/types/commands/exercise-command.js";
9
11
  import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
@@ -103,6 +105,23 @@ export function mapRecord(payload) {
103
105
  };
104
106
  }
105
107
  export function mapValue(value) {
108
+ const identifier = (value) => ({ packageId: value.packageId, moduleName: value.moduleName, entityName: value.entityName });
109
+ if (value instanceof DamlUnit)
110
+ return { sum: { oneofKind: "unit", unit: {} } };
111
+ if (value instanceof DamlDate)
112
+ return { sum: { oneofKind: "date", date: value.daysSinceEpoch } };
113
+ if (value instanceof DamlTimestamp)
114
+ return { sum: { oneofKind: "timestamp", timestamp: value.microsecondsSinceEpoch } };
115
+ if (value instanceof DamlTextMap)
116
+ return { sum: { oneofKind: "textMap", textMap: { entries: value.entries.map(([key, item]) => ({ key, value: mapValue(item) })) } } };
117
+ if (value instanceof DamlGenMap)
118
+ return { sum: { oneofKind: "genMap", genMap: { entries: value.entries.map(([key, item]) => ({ key: mapValue(key), value: mapValue(item) })) } } };
119
+ if (value instanceof DamlVariant)
120
+ return { sum: { oneofKind: "variant", variant: { variantId: value.variantId && identifier(value.variantId), constructor: value.constructorName, value: mapValue(value.value) } } };
121
+ if (value instanceof DamlEnum)
122
+ return { sum: { oneofKind: "enum", enum: { enumId: value.enumId && identifier(value.enumId), constructor: value.constructorName } } };
123
+ if (value instanceof DamlRecord)
124
+ return { sum: { oneofKind: "record", record: { recordId: value.recordId && identifier(value.recordId), fields: mapRecord(value.fields).fields } } };
106
125
  if (value === null || value === undefined) {
107
126
  return {
108
127
  sum: {
@@ -119,6 +138,9 @@ export function mapValue(value) {
119
138
  },
120
139
  };
121
140
  }
141
+ else if (value instanceof DamlContractId) {
142
+ return { sum: { oneofKind: "contractId", contractId: value.value } };
143
+ }
122
144
  else if (value instanceof DamlNumeric) {
123
145
  return {
124
146
  sum: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distrohelena/canton-typescript-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",