@distrohelena/canton-typescript-sdk 0.1.35 → 0.1.37

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.
Files changed (102) hide show
  1. package/README.md +159 -51
  2. package/dist/cjs/core/types/requests/{submit-command-request.js → submit-commands-request.js} +10 -6
  3. package/dist/cjs/index.js +10 -8
  4. package/dist/cjs/query/canonical/in-memory-query-evaluator.js +291 -0
  5. package/dist/cjs/query/canonical/public-identity.js +41 -0
  6. package/dist/cjs/query/canonical/query-ast.js +2 -0
  7. package/dist/cjs/query/canonical/query-dataset.js +351 -0
  8. package/dist/cjs/query/canonical/query-normalizer.js +655 -0
  9. package/dist/cjs/query/canonical/query-schema.js +86 -0
  10. package/dist/cjs/query/canton-manager.js +14 -5
  11. package/dist/cjs/query/errors/query-snapshot-incomplete-error.js +19 -0
  12. package/dist/cjs/query/grpc/grpc-contract-cache.js +484 -0
  13. package/dist/cjs/query/grpc/grpc-package-relation-reader.js +218 -0
  14. package/dist/cjs/query/grpc/grpc-query-client.js +249 -0
  15. package/dist/cjs/query/grpc/grpc-query-snapshot-reader.js +238 -0
  16. package/dist/cjs/query/grpc/grpc-query-value-mapper.js +204 -0
  17. package/dist/cjs/query/grpc/grpc-relation-mapper.js +794 -0
  18. package/dist/cjs/query/pqs/pqs-query-client.js +151 -582
  19. package/dist/cjs/query/pqs/pqs-relational-sql-compiler.js +138 -95
  20. package/dist/cjs/query/pqs/pqs-result-shape.js +28 -0
  21. package/dist/cjs/query/pqs/pqs-schema-profile.js +49 -48
  22. package/dist/cjs/query/pqs/pqs-sql-compiler.js +343 -289
  23. package/dist/cjs/query/pqs/pqs-sql-syntax.js +10 -0
  24. package/dist/cjs/services/command/command-service-client.js +16 -3
  25. package/dist/cjs/services/commands/command-payload-builder.js +1 -1
  26. package/dist/cjs/services/commands/command-submission-pipeline.js +21 -6
  27. package/dist/cjs/services/state/state-service-client.js +56 -0
  28. package/dist/cjs/testing/runtime/declarative-action-executor.js +3 -3
  29. package/dist/cjs/transports/grpc/grpc-transport.js +2 -2
  30. package/dist/cjs/transports/grpc/mappers/commands-mapper.js +6 -6
  31. package/dist/cjs/transports/grpc/mappers/interactive-command-mapper.js +1 -1
  32. package/dist/cjs/transports/json/json-transport.js +1 -1
  33. package/dist/cjs/transports/json/mappers/commands-mapper.js +3 -3
  34. package/dist/core/transports/transport.interface.d.ts +4 -4
  35. package/dist/core/types/prepared-command-submission.d.ts +3 -3
  36. package/dist/core/types/requests/{submit-command-request.d.ts → submit-commands-request.d.ts} +8 -4
  37. package/dist/core/types/requests/{submit-command-request.js → submit-commands-request.js} +8 -4
  38. package/dist/index.d.ts +5 -2
  39. package/dist/index.js +2 -1
  40. package/dist/query/canonical/in-memory-query-evaluator.d.ts +22 -0
  41. package/dist/query/canonical/in-memory-query-evaluator.js +287 -0
  42. package/dist/query/canonical/public-identity.d.ts +14 -0
  43. package/dist/query/canonical/public-identity.js +35 -0
  44. package/dist/query/canonical/query-ast.d.ts +104 -0
  45. package/dist/query/canonical/query-ast.js +1 -0
  46. package/dist/query/canonical/query-dataset.d.ts +63 -0
  47. package/dist/query/canonical/query-dataset.js +343 -0
  48. package/dist/query/canonical/query-normalizer.d.ts +10 -0
  49. package/dist/query/canonical/query-normalizer.js +646 -0
  50. package/dist/query/canonical/query-schema.d.ts +25 -0
  51. package/dist/query/canonical/query-schema.js +83 -0
  52. package/dist/query/canton-manager.js +14 -5
  53. package/dist/query/errors/query-snapshot-incomplete-error.d.ts +14 -0
  54. package/dist/query/errors/query-snapshot-incomplete-error.js +15 -0
  55. package/dist/query/grpc/grpc-contract-cache.d.ts +27 -0
  56. package/dist/query/grpc/grpc-contract-cache.js +479 -0
  57. package/dist/query/grpc/grpc-package-relation-reader.d.ts +43 -0
  58. package/dist/query/grpc/grpc-package-relation-reader.js +213 -0
  59. package/dist/query/grpc/grpc-query-client.d.ts +42 -0
  60. package/dist/query/grpc/grpc-query-client.js +245 -0
  61. package/dist/query/grpc/grpc-query-snapshot-reader.d.ts +33 -0
  62. package/dist/query/grpc/grpc-query-snapshot-reader.js +233 -0
  63. package/dist/query/grpc/grpc-query-value-mapper.d.ts +15 -0
  64. package/dist/query/grpc/grpc-query-value-mapper.js +195 -0
  65. package/dist/query/grpc/grpc-relation-mapper.d.ts +67 -0
  66. package/dist/query/grpc/grpc-relation-mapper.js +789 -0
  67. package/dist/query/pqs/pqs-query-client.d.ts +10 -20
  68. package/dist/query/pqs/pqs-query-client.js +154 -585
  69. package/dist/query/pqs/pqs-relational-sql-compiler.d.ts +9 -17
  70. package/dist/query/pqs/pqs-relational-sql-compiler.js +136 -95
  71. package/dist/query/pqs/pqs-result-shape.d.ts +25 -0
  72. package/dist/query/pqs/pqs-result-shape.js +25 -0
  73. package/dist/query/pqs/pqs-schema-profile.js +49 -48
  74. package/dist/query/pqs/pqs-sql-compiler.d.ts +18 -3
  75. package/dist/query/pqs/pqs-sql-compiler.js +337 -288
  76. package/dist/query/pqs/pqs-sql-syntax.d.ts +2 -0
  77. package/dist/query/pqs/pqs-sql-syntax.js +6 -0
  78. package/dist/query/query-client.d.ts +15 -0
  79. package/dist/services/command/command-service-client.d.ts +9 -4
  80. package/dist/services/command/command-service-client.js +16 -3
  81. package/dist/services/command-submission/command-submission-service-client.d.ts +2 -2
  82. package/dist/services/commands/command-payload-builder.d.ts +2 -2
  83. package/dist/services/commands/command-payload-builder.js +1 -1
  84. package/dist/services/commands/command-submission-pipeline.d.ts +5 -4
  85. package/dist/services/commands/command-submission-pipeline.js +21 -6
  86. package/dist/services/state/state-service-client.d.ts +4 -0
  87. package/dist/services/state/state-service-client.js +56 -0
  88. package/dist/testing/runtime/declarative-action-executor.js +3 -3
  89. package/dist/transports/grpc/grpc-transport.d.ts +4 -4
  90. package/dist/transports/grpc/grpc-transport.js +3 -3
  91. package/dist/transports/grpc/mappers/commands-mapper.d.ts +3 -3
  92. package/dist/transports/grpc/mappers/commands-mapper.js +4 -4
  93. package/dist/transports/grpc/mappers/interactive-command-mapper.d.ts +3 -3
  94. package/dist/transports/grpc/mappers/interactive-command-mapper.js +1 -1
  95. package/dist/transports/json/json-transport.d.ts +2 -2
  96. package/dist/transports/json/json-transport.js +2 -2
  97. package/dist/transports/json/mappers/commands-mapper.d.ts +2 -2
  98. package/dist/transports/json/mappers/commands-mapper.js +2 -2
  99. package/package.json +8 -3
  100. package/dist/cjs/query/grpc/grpc-contract-query-client.js +0 -178
  101. package/dist/query/grpc/grpc-contract-query-client.d.ts +0 -33
  102. package/dist/query/grpc/grpc-contract-query-client.js +0 -174
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GrpcQuerySnapshotReader = void 0;
4
+ exports.isCanonicalGrpcOffset = isCanonicalGrpcOffset;
5
+ const validation_error_js_1 = require("../../core/errors/validation-error.js");
6
+ const state_service_js_1 = require("../../transports/grpc/generated/canton/com/daml/ledger/api/v2/state_service.js");
7
+ const update_service_js_1 = require("../../transports/grpc/generated/canton/com/daml/ledger/api/v2/update_service.js");
8
+ const transaction_filter_js_1 = require("../../transports/grpc/generated/canton/com/daml/ledger/api/v2/transaction_filter.js");
9
+ const contracts_mapper_js_1 = require("../../transports/grpc/mappers/contracts-mapper.js");
10
+ const query_dataset_js_1 = require("../canonical/query-dataset.js");
11
+ const query_snapshot_incomplete_error_js_1 = require("../errors/query-snapshot-incomplete-error.js");
12
+ const DEFAULT_OPTIONS = {
13
+ maxHistoryPages: 10_000,
14
+ maxHistoryUpdates: 1_000_000,
15
+ maxActiveContractPages: 10_000,
16
+ maxActiveContracts: 1_000_000,
17
+ };
18
+ const LEDGER_BEGIN = "0";
19
+ class GrpcQuerySnapshotReader {
20
+ stateService;
21
+ updateService;
22
+ options;
23
+ constructor(stateService, updateService, options = {}) {
24
+ this.stateService = stateService;
25
+ this.updateService = updateService;
26
+ this.options = validateOptions(options);
27
+ }
28
+ async readCurrentHistoryAsync() {
29
+ const ledgerEnd = await this.stateService.getLedgerEndAsync({});
30
+ return this.readHistoryAsync(ledgerEnd.offset);
31
+ }
32
+ async readHistoryAsync(endInclusive) {
33
+ const end = parseOffset(endInclusive);
34
+ if (end === undefined) {
35
+ throw this.historyError(endInclusive, "invalid-offset");
36
+ }
37
+ const pruned = await this.stateService.getLatestPrunedOffsetsAsync({});
38
+ const prunedUpTo = parseOffset(pruned.participantPrunedUpToInclusive);
39
+ if (prunedUpTo === undefined || prunedUpTo !== 0n) {
40
+ throw this.historyError(endInclusive, "participant-pruned");
41
+ }
42
+ const updateFormat = freezeDeep(createHistoryUpdateFormat());
43
+ const updates = [];
44
+ const observedPageTokens = new Set();
45
+ let expectedLowestExclusive = 0n;
46
+ let pageToken;
47
+ let pagesRead = 0;
48
+ let previousUpdateOffset;
49
+ while (true) {
50
+ if (pagesRead >= this.options.maxHistoryPages) {
51
+ throw this.historyError(endInclusive, "max-pages-exceeded");
52
+ }
53
+ const request = {
54
+ beginOffsetExclusive: LEDGER_BEGIN,
55
+ endOffsetInclusive: endInclusive,
56
+ updateFormat,
57
+ descendingOrder: false,
58
+ pageToken: pageToken === undefined ? undefined : Uint8Array.from(pageToken),
59
+ };
60
+ const response = await this.updateService.getUpdatesPageAsync(request);
61
+ pagesRead += 1;
62
+ const lowest = parseOffset(response.lowestPageOffsetExclusive);
63
+ const highest = parseOffset(response.highestPageOffsetInclusive);
64
+ if (lowest === undefined || highest === undefined) {
65
+ throw this.historyError(endInclusive, "missing-boundary");
66
+ }
67
+ else if (lowest !== expectedLowestExclusive || highest < lowest || highest > end) {
68
+ throw this.historyError(endInclusive, "page-boundary-mismatch");
69
+ }
70
+ if (response.updates.length > this.options.maxHistoryUpdates - updates.length) {
71
+ throw this.historyError(endInclusive, "max-updates-exceeded");
72
+ }
73
+ for (const update of response.updates) {
74
+ const updateOffset = parseOffset(extractUpdateOffset(update));
75
+ if (updateOffset === undefined || updateOffset <= lowest || updateOffset > highest || (previousUpdateOffset !== undefined && updateOffset <= previousUpdateOffset)) {
76
+ throw this.historyError(endInclusive, "page-boundary-mismatch");
77
+ }
78
+ previousUpdateOffset = updateOffset;
79
+ }
80
+ updates.push(...response.updates.map(cloneFrozenUpdate));
81
+ const nextPageToken = response.nextPageToken;
82
+ if (nextPageToken === undefined || nextPageToken.length === 0) {
83
+ if (highest !== end) {
84
+ throw this.historyError(endInclusive, "nonterminal-page-without-token");
85
+ }
86
+ return freezeSnapshot({
87
+ endInclusive,
88
+ updates: Object.freeze(updates),
89
+ });
90
+ }
91
+ else if (highest >= end) {
92
+ throw this.historyError(endInclusive, "nonterminal-page-reaches-end");
93
+ }
94
+ else if (highest <= lowest) {
95
+ throw this.historyError(endInclusive, "page-boundary-mismatch");
96
+ }
97
+ const tokenKey = tokenKeyFor(nextPageToken);
98
+ if (observedPageTokens.has(tokenKey)) {
99
+ throw this.historyError(endInclusive, "repeated-page-token");
100
+ }
101
+ observedPageTokens.add(tokenKey);
102
+ expectedLowestExclusive = highest;
103
+ pageToken = Uint8Array.from(nextPageToken);
104
+ }
105
+ }
106
+ async readActiveContractsAsync(activeAtOffset, parties) {
107
+ if (parseOffset(activeAtOffset) === undefined) {
108
+ throw this.activeError(activeAtOffset, "invalid-offset");
109
+ }
110
+ const eventFormat = freezeDeep(parties === undefined ? createAllPartiesEventFormat() : (0, contracts_mapper_js_1.mapGrpcQueryContractsRequest)({ parties }).eventFormat);
111
+ const activeContracts = [];
112
+ const observedPageTokens = new Set();
113
+ let pageToken;
114
+ let pagesRead = 0;
115
+ while (true) {
116
+ if (pagesRead >= this.options.maxActiveContractPages) {
117
+ throw this.activeError(activeAtOffset, "max-pages-exceeded");
118
+ }
119
+ const request = {
120
+ activeAtOffset,
121
+ eventFormat,
122
+ pageToken: pageToken === undefined ? undefined : Uint8Array.from(pageToken),
123
+ };
124
+ const response = await this.stateService.getActiveContractsPageAsync(request);
125
+ pagesRead += 1;
126
+ const responseActiveAtOffset = parseOffset(response.activeAtOffset);
127
+ if (responseActiveAtOffset === undefined) {
128
+ throw this.activeError(activeAtOffset, "missing-active-at-offset");
129
+ }
130
+ else if (parseOffset(activeAtOffset) !== responseActiveAtOffset) {
131
+ throw this.activeError(activeAtOffset, "active-at-offset-mismatch");
132
+ }
133
+ else if (response.activeContracts.length === 0 && response.nextPageToken?.length) {
134
+ throw this.activeError(activeAtOffset, "empty-active-contract-page");
135
+ }
136
+ if (response.activeContracts.length > this.options.maxActiveContracts - activeContracts.length) {
137
+ throw this.activeError(activeAtOffset, "max-active-contracts-exceeded");
138
+ }
139
+ activeContracts.push(...response.activeContracts.map(cloneFrozenActiveContract));
140
+ const nextPageToken = response.nextPageToken;
141
+ if (nextPageToken === undefined || nextPageToken.length === 0) {
142
+ return freezeSnapshot({
143
+ activeAtOffset,
144
+ activeContracts: Object.freeze(activeContracts),
145
+ });
146
+ }
147
+ const tokenKey = tokenKeyFor(nextPageToken);
148
+ if (observedPageTokens.has(tokenKey)) {
149
+ throw this.activeError(activeAtOffset, "repeated-page-token");
150
+ }
151
+ observedPageTokens.add(tokenKey);
152
+ pageToken = Uint8Array.from(nextPageToken);
153
+ }
154
+ }
155
+ historyError(endInclusive, reason) {
156
+ return new query_snapshot_incomplete_error_js_1.QuerySnapshotIncompleteError({
157
+ beginExclusive: LEDGER_BEGIN,
158
+ endInclusive,
159
+ reason,
160
+ });
161
+ }
162
+ activeError(activeAtOffset, reason) {
163
+ return new query_snapshot_incomplete_error_js_1.QuerySnapshotIncompleteError({
164
+ beginExclusive: LEDGER_BEGIN,
165
+ endInclusive: activeAtOffset ?? "",
166
+ activeAtOffset,
167
+ reason,
168
+ });
169
+ }
170
+ }
171
+ exports.GrpcQuerySnapshotReader = GrpcQuerySnapshotReader;
172
+ function validateOptions(options) {
173
+ const validated = { ...DEFAULT_OPTIONS, ...options };
174
+ for (const [name, value] of Object.entries(validated)) {
175
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {
176
+ throw new validation_error_js_1.ValidationError(`${name} must be a finite positive integer.`);
177
+ }
178
+ }
179
+ return Object.freeze(validated);
180
+ }
181
+ function createHistoryUpdateFormat() {
182
+ return {
183
+ includeTransactions: {
184
+ eventFormat: createAllPartiesEventFormat(),
185
+ transactionShape: transaction_filter_js_1.TransactionShape.LEDGER_EFFECTS,
186
+ },
187
+ };
188
+ }
189
+ function createAllPartiesEventFormat() {
190
+ return (0, contracts_mapper_js_1.mapGrpcQueryContractsRequest)({ allParties: true }).eventFormat;
191
+ }
192
+ function parseOffset(value) {
193
+ if (typeof value !== "string" || !/^(?:0|[1-9]\d{0,18})$/.test(value)) {
194
+ return undefined;
195
+ }
196
+ const parsed = BigInt(value);
197
+ return parsed <= 9223372036854775807n ? parsed : undefined;
198
+ }
199
+ function isCanonicalGrpcOffset(value) {
200
+ return parseOffset(value) !== undefined;
201
+ }
202
+ function extractUpdateOffset(update) {
203
+ const oneof = update.update;
204
+ switch (oneof.oneofKind) {
205
+ case "transaction": return oneof.transaction?.offset;
206
+ case "reassignment": return oneof.reassignment?.offset;
207
+ case "offsetCheckpoint": return oneof.offsetCheckpoint?.offset;
208
+ case "topologyTransaction": return oneof.topologyTransaction?.offset;
209
+ default: return undefined;
210
+ }
211
+ }
212
+ function tokenKeyFor(token) {
213
+ return Array.from(token).join(",");
214
+ }
215
+ function cloneFrozenUpdate(update) {
216
+ return freezeDeep(update_service_js_1.GetUpdateResponse.fromBinary(update_service_js_1.GetUpdateResponse.toBinary(update)));
217
+ }
218
+ function cloneFrozenActiveContract(activeContract) {
219
+ return freezeDeep(state_service_js_1.GetActiveContractsResponse.fromBinary(state_service_js_1.GetActiveContractsResponse.toBinary(activeContract)));
220
+ }
221
+ function freezeSnapshot(snapshot) {
222
+ return freezeDeep(snapshot);
223
+ }
224
+ function freezeDeep(value) {
225
+ if (value instanceof Uint8Array) {
226
+ return (0, query_dataset_js_1.immutableQueryValue)(value);
227
+ }
228
+ else if (value === null || typeof value !== "object") {
229
+ return value;
230
+ }
231
+ else if (Object.isFrozen(value)) {
232
+ return value;
233
+ }
234
+ for (const [property, child] of Object.entries(value)) {
235
+ value[property] = freezeDeep(child);
236
+ }
237
+ return Object.freeze(value);
238
+ }
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_GRPC_QUERY_VALUE_DEPTH = void 0;
4
+ exports.mapGrpcQueryValue = mapGrpcQueryValue;
5
+ exports.validPartyId = validPartyId;
6
+ exports.validLedgerString = validLedgerString;
7
+ exports.validNameString = validNameString;
8
+ exports.validDottedNameString = validDottedNameString;
9
+ exports.validPackageIdString = validPackageIdString;
10
+ const validation_error_js_1 = require("../../core/errors/validation-error.js");
11
+ const query_dataset_js_1 = require("../canonical/query-dataset.js");
12
+ const MIN_DATE_EPOCH_DAY = -719_162;
13
+ const MAX_DATE_EPOCH_DAY = 2_932_896;
14
+ const INT64 = /^-?(?:0|[1-9]\d*)$/;
15
+ /** Maximum generated Value nesting accepted before recursive mapping becomes unsafe. */
16
+ exports.MAX_GRPC_QUERY_VALUE_DEPTH = 256;
17
+ /** Maps a verbose Ledger API value to the JSON convention used by PQS predicates and rows. */
18
+ function mapGrpcQueryValue(value) {
19
+ if (value === undefined || value.sum === undefined) {
20
+ throw new validation_error_js_1.ValidationError("gRPC query value is missing its sum");
21
+ }
22
+ const mapped = mapValue(value, 0);
23
+ return (0, query_dataset_js_1.immutableQueryValue)(mapped);
24
+ }
25
+ function mapValue(value, depth) {
26
+ if (depth > exports.MAX_GRPC_QUERY_VALUE_DEPTH) {
27
+ throw new validation_error_js_1.ValidationError(`gRPC query value exceeds maximum nesting depth ${exports.MAX_GRPC_QUERY_VALUE_DEPTH}`);
28
+ }
29
+ switch (value.sum.oneofKind) {
30
+ case "unit": return {};
31
+ case "bool": return value.sum.bool;
32
+ case "int64": return int64(value.sum.int64, "int64");
33
+ case "date": return date(value.sum.date);
34
+ case "timestamp": return timestamp(value.sum.timestamp);
35
+ case "numeric": return numeric(value.sum.numeric);
36
+ case "party": return validPartyId(value.sum.party);
37
+ case "text": return value.sum.text;
38
+ case "contractId": return validLedgerString(value.sum.contractId, "contract id");
39
+ case "optional": return value.sum.optional.value === undefined ? null : mapValue(value.sum.optional.value, depth + 1);
40
+ case "list": return value.sum.list.elements.map((entry) => mapValue(entry, depth + 1));
41
+ case "textMap": return mapTextMap(value.sum.textMap.entries, depth + 1);
42
+ case "genMap": return mapGenMap(value.sum.genMap.entries, depth + 1);
43
+ case "record": return mapRecord(value.sum.record.fields, depth + 1);
44
+ case "variant": {
45
+ if (value.sum.variant.value === undefined) {
46
+ throw new validation_error_js_1.ValidationError("gRPC query variant is incomplete");
47
+ }
48
+ return { tag: validNameString(value.sum.variant.constructor, "variant constructor"), value: mapValue(value.sum.variant.value, depth + 1) };
49
+ }
50
+ case "enum": {
51
+ return validNameString(value.sum.enum.constructor, "enum constructor");
52
+ }
53
+ case undefined: throw new validation_error_js_1.ValidationError("gRPC query value has no active sum");
54
+ }
55
+ }
56
+ function mapRecord(fields, depth) {
57
+ const output = Object.create(null);
58
+ for (const [index, field] of fields.entries()) {
59
+ if (field.label.length === 0) {
60
+ throw new validation_error_js_1.ValidationError(`gRPC query record field ${index} is unlabeled; verbose values are required`);
61
+ }
62
+ else if (Object.hasOwn(output, field.label)) {
63
+ throw new validation_error_js_1.ValidationError(`gRPC query record has duplicate label ${field.label}`);
64
+ }
65
+ else if (field.value === undefined) {
66
+ throw new validation_error_js_1.ValidationError(`gRPC query record field ${field.label} has no value`);
67
+ }
68
+ defineData(output, validNameString(field.label, `record field ${index} label`), mapValue(field.value, depth));
69
+ }
70
+ return output;
71
+ }
72
+ function mapTextMap(entries, depth) {
73
+ const output = Object.create(null);
74
+ for (const [index, entry] of entries.entries()) {
75
+ if (Object.hasOwn(output, entry.key)) {
76
+ throw new validation_error_js_1.ValidationError(`gRPC query text-map has duplicate key ${entry.key}`);
77
+ }
78
+ else if (entry.value === undefined) {
79
+ throw new validation_error_js_1.ValidationError(`gRPC query text-map entry ${index} has no value`);
80
+ }
81
+ defineData(output, entry.key, mapValue(entry.value, depth));
82
+ }
83
+ return output;
84
+ }
85
+ function mapGenMap(entries, depth) {
86
+ const seenKeys = new Set();
87
+ return entries.map((entry, index) => {
88
+ if (entry.key === undefined || entry.value === undefined) {
89
+ throw new validation_error_js_1.ValidationError(`gRPC query gen-map entry ${index} is incomplete`);
90
+ }
91
+ const key = mapValue(entry.key, depth);
92
+ const canonicalKey = canonicalLedgerKey(entry.key);
93
+ if (seenKeys.has(canonicalKey)) {
94
+ throw new validation_error_js_1.ValidationError(`gRPC query gen-map has duplicate key at entry ${index}`);
95
+ }
96
+ seenKeys.add(canonicalKey);
97
+ return [key, mapValue(entry.value, depth)];
98
+ });
99
+ }
100
+ function canonicalLedgerKey(value) {
101
+ switch (value.sum.oneofKind) {
102
+ case "unit": return "unit";
103
+ case "bool": return `bool:${value.sum.bool}`;
104
+ case "int64": return `int64:${JSON.stringify(value.sum.int64)}`;
105
+ case "date": return `date:${value.sum.date}`;
106
+ case "timestamp": return `timestamp:${JSON.stringify(value.sum.timestamp)}`;
107
+ case "numeric": return `numeric:${canonicalNumeric(value.sum.numeric)}`;
108
+ case "party": return `party:${JSON.stringify(value.sum.party)}`;
109
+ case "text": return `text:${JSON.stringify(value.sum.text)}`;
110
+ case "contractId": return `contractId:${JSON.stringify(value.sum.contractId)}`;
111
+ case "optional": return value.sum.optional.value === undefined ? "optional:none" : `optional:some(${canonicalLedgerKey(value.sum.optional.value)})`;
112
+ case "list": return `list:[${value.sum.list.elements.map(canonicalLedgerKey).join(",")}]`;
113
+ case "textMap": return `textMap:{${[...value.sum.textMap.entries].sort((left, right) => left.key.localeCompare(right.key)).map((entry) => `${JSON.stringify(entry.key)}:${canonicalLedgerKey(entry.value)}`).join(",")}}`;
114
+ case "genMap": return `genMap:{${value.sum.genMap.entries.map((entry) => `${canonicalLedgerKey(entry.key)}:${canonicalLedgerKey(entry.value)}`).sort().join(",")}}`;
115
+ case "record": return `record:{${[...value.sum.record.fields].sort((left, right) => left.label.localeCompare(right.label)).map((field) => `${JSON.stringify(field.label)}:${canonicalLedgerKey(field.value)}`).join(",")}}`;
116
+ case "variant": return `variant:${JSON.stringify(value.sum.variant.constructor)}:${canonicalLedgerKey(value.sum.variant.value)}`;
117
+ case "enum": return `enum:${JSON.stringify(value.sum.enum.constructor)}`;
118
+ case undefined: return invalidGenMapKey();
119
+ }
120
+ }
121
+ function canonicalNumeric(value) {
122
+ const sign = value.startsWith("-") ? "-" : "";
123
+ const unsigned = value.replace(/^[+-]/, "");
124
+ const [whole, fraction = ""] = unsigned.split(".");
125
+ const normalizedWhole = whole.replace(/^0+(?=\d)/, "");
126
+ const normalizedFraction = fraction.replace(/0+$/, "");
127
+ const normalized = `${normalizedWhole}${normalizedFraction.length === 0 ? "" : `.${normalizedFraction}`}`;
128
+ return /^0(?:\.0*)?$/.test(normalized) ? "0" : `${sign}${normalized}`;
129
+ }
130
+ function invalidGenMapKey() {
131
+ throw new validation_error_js_1.ValidationError("gRPC query gen-map key cannot be represented as ledger JSON");
132
+ }
133
+ function defineData(target, key, value) {
134
+ Object.defineProperty(target, key, { value, enumerable: true, configurable: false, writable: false });
135
+ }
136
+ function int64(value, name) {
137
+ if (!INT64.test(value)) {
138
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is not an integer`);
139
+ }
140
+ else if (BigInt(value) < -9223372036854775808n || BigInt(value) > 9223372036854775807n) {
141
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is outside the int64 range`);
142
+ }
143
+ return value;
144
+ }
145
+ function timestamp(value) {
146
+ int64(value, "timestamp");
147
+ if (BigInt(value) < -62135596800000000n || BigInt(value) > 253402300799999999n) {
148
+ throw new validation_error_js_1.ValidationError("gRPC query timestamp is outside the Ledger API range");
149
+ }
150
+ return value;
151
+ }
152
+ function date(value) {
153
+ if (!Number.isInteger(value) || value < MIN_DATE_EPOCH_DAY || value > MAX_DATE_EPOCH_DAY) {
154
+ throw new validation_error_js_1.ValidationError("gRPC query date is outside the Ledger API range");
155
+ }
156
+ return value;
157
+ }
158
+ function numeric(value) {
159
+ if (!/^[+-]?\d{1,38}(?:\.\d{0,37})?$/.test(value)) {
160
+ throw new validation_error_js_1.ValidationError("gRPC query numeric is invalid");
161
+ }
162
+ const unsigned = value.replace(/^[+-]/, "");
163
+ const [whole, fractional = ""] = unsigned.split(".");
164
+ const significant = `${whole}${fractional}`.replace(/^0+/, "").length;
165
+ if (fractional.length > 37 || significant > 38) {
166
+ throw new validation_error_js_1.ValidationError("gRPC query numeric exceeds DAML Numeric precision");
167
+ }
168
+ return value;
169
+ }
170
+ /** Validates a generated PartyIdString without applying those rules to ordinary Text values. */
171
+ function validPartyId(value) {
172
+ if (!/^[A-Za-z0-9:\-_ ]{1,255}$/.test(value)) {
173
+ throw new validation_error_js_1.ValidationError("gRPC query party is invalid");
174
+ }
175
+ return value;
176
+ }
177
+ /** Validates a generated LedgerString used specifically as a contract identifier. */
178
+ function validLedgerString(value, name = "ledger string") {
179
+ if (!/^[A-Za-z0-9#:\-_/ ]{1,255}$/.test(value)) {
180
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
181
+ }
182
+ return value;
183
+ }
184
+ /** Validates a generated NameString used by identifiers, choices, and verbose value labels. */
185
+ function validNameString(value, name = "name") {
186
+ if (!/^[A-Za-z$_][A-Za-z0-9$_]{0,999}$/.test(value)) {
187
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
188
+ }
189
+ return value;
190
+ }
191
+ /** Validates an Identifier module or entity name as nonempty dot-separated NameString segments. */
192
+ function validDottedNameString(value, name = "dotted name") {
193
+ for (const segment of value.split(".")) {
194
+ validNameString(segment, name);
195
+ }
196
+ return value;
197
+ }
198
+ /** Validates a generated PackageIdString without applying it to arbitrary package-name text. */
199
+ function validPackageIdString(value, name = "package id") {
200
+ if (!/^[A-Za-z0-9\-_ ]{1,64}$/.test(value)) {
201
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
202
+ }
203
+ return value;
204
+ }