@distrohelena/canton-typescript-sdk 0.1.24 → 0.1.26

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 (59) hide show
  1. package/README.md +10 -5
  2. package/dist/daml-interface/analysis/analyzed-choice.d.ts +5 -5
  3. package/dist/daml-interface/analysis/analyzed-daml-type-definition.d.ts +6 -0
  4. package/dist/daml-interface/analysis/analyzed-daml-type-definition.js +1 -0
  5. package/dist/daml-interface/analysis/analyzed-daml-type.d.ts +54 -0
  6. package/dist/daml-interface/analysis/analyzed-daml-type.js +1 -0
  7. package/dist/daml-interface/analysis/analyzed-template.d.ts +3 -3
  8. package/dist/daml-interface/analysis/daml-interface-analyzer.d.ts +3 -1
  9. package/dist/daml-interface/analysis/daml-interface-analyzer.js +183 -19
  10. package/dist/daml-interface/emission/named-type-emitter.d.ts +41 -0
  11. package/dist/daml-interface/emission/named-type-emitter.js +441 -0
  12. package/dist/daml-interface/emission/project-emitter.d.ts +5 -1
  13. package/dist/daml-interface/emission/project-emitter.js +20 -3
  14. package/dist/daml-interface/emission/registry-emitter.d.ts +1 -0
  15. package/dist/daml-interface/emission/registry-emitter.js +15 -8
  16. package/dist/daml-interface/emission/support-file-emitter.d.ts +16 -1
  17. package/dist/daml-interface/emission/support-file-emitter.js +206 -6
  18. package/dist/daml-interface/emission/template-binding-emitter.d.ts +25 -1
  19. package/dist/daml-interface/emission/template-binding-emitter.js +373 -72
  20. package/dist/daml-interface/emission/type-script-name-resolver.d.ts +50 -3
  21. package/dist/daml-interface/emission/type-script-name-resolver.js +369 -11
  22. package/dist/daml-interface/emission-model/generated-choice-binding.d.ts +7 -0
  23. package/dist/daml-interface/emission-model/generated-choice-binding.js +6 -0
  24. package/dist/daml-interface/emission-model/generated-daml-interface-project.d.ts +3 -0
  25. package/dist/daml-interface/emission-model/generated-daml-interface-project.js +2 -0
  26. package/dist/daml-interface/emission-model/generated-named-type-file.d.ts +23 -0
  27. package/dist/daml-interface/emission-model/generated-named-type-file.js +23 -0
  28. package/dist/daml-interface/emission-model/generated-template-binding.d.ts +9 -0
  29. package/dist/daml-interface/emission-model/generated-template-binding.js +8 -0
  30. package/dist/daml-interface/index.d.ts +12 -0
  31. package/dist/daml-interface/index.js +9 -0
  32. package/dist/daml-interface/runtime/daml-event-source-normalizer.d.ts +52 -0
  33. package/dist/daml-interface/runtime/daml-event-source-normalizer.js +364 -0
  34. package/dist/daml-interface/runtime/daml-materialization-error.d.ts +5 -0
  35. package/dist/daml-interface/runtime/daml-materialization-error.js +9 -0
  36. package/dist/daml-interface/runtime/daml-template.d.ts +6 -0
  37. package/dist/daml-interface/runtime/daml-template.js +10 -0
  38. package/dist/daml-interface/runtime/daml-type-descriptor.d.ts +71 -0
  39. package/dist/daml-interface/runtime/daml-type-descriptor.js +1 -0
  40. package/dist/daml-interface/runtime/daml-value-converter.d.ts +7 -0
  41. package/dist/daml-interface/runtime/daml-value-converter.js +370 -0
  42. package/dist/daml-interface/runtime/daml-value-materializer.d.ts +3 -0
  43. package/dist/daml-interface/runtime/daml-value-materializer.js +23 -0
  44. package/dist/daml-interface/writing/daml-interface-writer.js +1 -0
  45. package/dist/daml-lf/daml-lf-compilation.d.ts +1 -0
  46. package/dist/daml-lf/daml-lf-compilation.js +24 -3
  47. package/dist/daml-lf/model/daml-lf-builtin-type.d.ts +9 -0
  48. package/dist/daml-lf/model/daml-lf-builtin-type.js +9 -0
  49. package/dist/daml-lf/model/daml-lf-data-type.d.ts +18 -1
  50. package/dist/daml-lf/model/daml-lf-data-type.js +8 -1
  51. package/dist/daml-lf/model/daml-lf-type.d.ts +2 -0
  52. package/dist/daml-lf/model/daml-lf-type.js +2 -0
  53. package/dist/daml-lf/model/lf-2-model-mapper.d.ts +1 -0
  54. package/dist/daml-lf/model/lf-2-model-mapper.js +81 -25
  55. package/dist/daml-lf/semantics/daml-lf-semantic-model.d.ts +3 -0
  56. package/dist/daml-lf/semantics/daml-lf-semantic-model.js +5 -1
  57. package/dist/query/pqs/pqs-query-client.js +15 -0
  58. package/dist/query/pqs/pqs-sql-compiler.js +35 -7
  59. package/package.json +1 -1
@@ -1,23 +1,39 @@
1
1
  import { GeneratedSupportFile } from "../emission-model/generated-support-file.js";
2
2
  export class SupportFileEmitter {
3
3
  /** Emits shared support files for the generated DAML interface project. */
4
- emitSupportFiles() {
4
+ emitSupportFiles(analysis, namedTypeFiles = []) {
5
5
  return [
6
6
  new GeneratedSupportFile({
7
7
  path: "generated/support/contracts.ts",
8
8
  contents: "export type GeneratedContractId = string;\n",
9
9
  }),
10
10
  new GeneratedSupportFile({
11
- path: "generated/support/decoding.ts",
12
- contents: "export function castGeneratedEvent<T>(event: unknown): T {\n return event as T;\n}\n",
11
+ path: "generated/support/runtime.ts",
12
+ contents: [
13
+ 'export type { DamlDate, DamlNumeric, DamlParty, DamlTimestamp, DamlUnit } from "@distrohelena/canton-typescript-sdk/daml-interface";',
14
+ "",
15
+ ].join("\n"),
13
16
  }),
17
+ this.emitDescriptorRegistry(analysis, namedTypeFiles),
14
18
  ];
15
19
  }
20
+ /** Emits one barrel module for each generated DAML package/module namespace. */
21
+ emitNamespaceFiles(project) {
22
+ return this.getNamespaceGroups(project).map((group) => new GeneratedSupportFile({
23
+ path: `${group.directoryPath}/index.ts`,
24
+ contents: `${[
25
+ ...(group.namedTypeFile === undefined ? [] : ["export * from \"./types.js\";"]),
26
+ ...group.templateFiles
27
+ .map((file) => this.getFileNameWithoutExtension(file.path))
28
+ .map((fileName) => `export * from "./${fileName}.js";`),
29
+ ].join("\n")}\n`,
30
+ }));
31
+ }
16
32
  /** Emits the generated project index file. */
17
33
  emitIndexFile(project) {
18
- const exportLines = project.templateFiles
19
- .map((file) => file.path.replace(/^generated\//, "./").replace(/\.ts$/, ".js"))
20
- .map((path) => `export * from "${path}";`);
34
+ const exportLines = this.getNamespaceGroups(project)
35
+ .map((group) => `export * as ${group.alias} from "${group.directoryPath
36
+ .replace(/^generated\//, "./")}/index.js";`);
21
37
  const lines = [
22
38
  ...exportLines,
23
39
  'export * from "./registry.js";',
@@ -27,4 +43,188 @@ export class SupportFileEmitter {
27
43
  contents: `${lines.join("\n")}\n`,
28
44
  });
29
45
  }
46
+ getNamespaceGroups(project) {
47
+ const groupsByDirectory = new Map();
48
+ const directoriesByAlias = new Map();
49
+ for (const templateFile of project.templateFiles) {
50
+ const directoryPath = templateFile.path.replace(/\/[^/]+$/, "");
51
+ const alias = templateFile.binding.namespaceAlias;
52
+ const existingDirectory = directoriesByAlias.get(alias);
53
+ if (existingDirectory !== undefined && existingDirectory !== directoryPath) {
54
+ throw new Error(`Cannot emit generated namespace '${alias}' for '${existingDirectory}' and '${directoryPath}'`);
55
+ }
56
+ directoriesByAlias.set(alias, directoryPath);
57
+ const group = groupsByDirectory.get(directoryPath);
58
+ if (group === undefined) {
59
+ groupsByDirectory.set(directoryPath, {
60
+ alias,
61
+ directoryPath,
62
+ templateFiles: [templateFile],
63
+ });
64
+ }
65
+ else {
66
+ group.templateFiles.push(templateFile);
67
+ }
68
+ }
69
+ for (const namedTypeFile of project.namedTypeFiles) {
70
+ const directoryPath = namedTypeFile.path.replace(/\/[^/]+$/, "");
71
+ const group = groupsByDirectory.get(directoryPath);
72
+ if (group === undefined) {
73
+ groupsByDirectory.set(directoryPath, {
74
+ alias: namedTypeFile.namespaceAlias,
75
+ directoryPath,
76
+ templateFiles: [],
77
+ namedTypeFile,
78
+ });
79
+ }
80
+ else if (group.alias !== namedTypeFile.namespaceAlias) {
81
+ throw new Error(`Cannot emit generated namespace '${group.alias}' and '${namedTypeFile.namespaceAlias}' for '${directoryPath}'`);
82
+ }
83
+ else if (group.namedTypeFile !== undefined) {
84
+ throw new Error(`Cannot emit duplicate named DAML type file for '${directoryPath}'`);
85
+ }
86
+ else {
87
+ group.namedTypeFile = namedTypeFile;
88
+ }
89
+ }
90
+ const groups = [...groupsByDirectory.values()];
91
+ for (const group of groups) {
92
+ this.assertDistinctModuleExportedSymbols(group);
93
+ }
94
+ return groups;
95
+ }
96
+ getFileNameWithoutExtension(path) {
97
+ return path.slice(path.lastIndexOf("/") + 1).replace(/\.ts$/, "");
98
+ }
99
+ assertDistinctModuleExportedSymbols(group) {
100
+ const descriptionsBySymbol = new Map();
101
+ for (const file of group.templateFiles) {
102
+ for (const symbol of this.getExportedSymbols(file)) {
103
+ const existing = descriptionsBySymbol.get(symbol);
104
+ if (existing !== undefined) {
105
+ throw new Error(`Cannot emit generated module symbol '${symbol}' for `
106
+ + `'${existing}' and '${this.describeTemplate(file)}'`);
107
+ }
108
+ descriptionsBySymbol.set(symbol, this.describeTemplate(file));
109
+ }
110
+ }
111
+ if (group.namedTypeFile !== undefined) {
112
+ for (const symbol of group.namedTypeFile.exportedTypeNames) {
113
+ const existing = descriptionsBySymbol.get(symbol);
114
+ if (existing !== undefined) {
115
+ throw new Error(`Cannot emit generated module symbol '${symbol}' for `
116
+ + `'${existing}' and '${group.namedTypeFile.path}'`);
117
+ }
118
+ descriptionsBySymbol.set(symbol, group.namedTypeFile.path);
119
+ }
120
+ }
121
+ }
122
+ getExportedSymbols(file) {
123
+ return [
124
+ file.binding.className,
125
+ file.binding.createFieldsTypeName,
126
+ file.binding.createdEventTypeName,
127
+ ...file.binding.choices.flatMap((choice) => [
128
+ choice.choiceTypeName,
129
+ choice.exercisedEventTypeName,
130
+ ]),
131
+ ];
132
+ }
133
+ describeTemplate(file) {
134
+ return file.binding.templateIdentityKey.replaceAll("\u0000", ":");
135
+ }
136
+ emitDescriptorRegistry(analysis, namedTypeFiles) {
137
+ const identities = new Set();
138
+ const fieldPropertyNames = new Map();
139
+ for (const file of namedTypeFiles) {
140
+ for (const [key, propertyName] of file.fieldPropertyNames) {
141
+ fieldPropertyNames.set(key, propertyName);
142
+ }
143
+ }
144
+ const factories = analysis.typeDefinitions.map((definition) => {
145
+ const identityKey = this.getIdentityKey(definition.identity.packageId, definition.identity.moduleName, definition.identity.name);
146
+ if (identities.has(identityKey)) {
147
+ throw new Error(`Cannot emit duplicate named DAML type descriptor '${identityKey}'`);
148
+ }
149
+ identities.add(identityKey);
150
+ return [
151
+ ` ${JSON.stringify(identityKey)}: () => deepFreeze(${this.emitDefinitionDescriptor(definition, fieldPropertyNames)} satisfies DamlTypeDescriptor),`,
152
+ ].join("");
153
+ });
154
+ return new GeneratedSupportFile({
155
+ path: "generated/support/descriptors.ts",
156
+ contents: [
157
+ 'import type { DamlTypeDescriptor, DamlTypeDescriptorRegistry } from "@distrohelena/canton-typescript-sdk/daml-interface";',
158
+ "",
159
+ "function deepFreeze<T>(value: T): T {",
160
+ " if (value !== null && typeof value === \"object\") {",
161
+ " for (const child of Object.values(value)) {",
162
+ " deepFreeze(child);",
163
+ " }",
164
+ "",
165
+ " Object.freeze(value);",
166
+ " }",
167
+ "",
168
+ " return value;",
169
+ "}",
170
+ "",
171
+ "const generatedDamlTypeDescriptorFactories: Readonly<Record<string, () => DamlTypeDescriptor>> = Object.freeze({",
172
+ ...factories,
173
+ "});",
174
+ "",
175
+ "export const generatedDamlTypeDescriptorRegistry: DamlTypeDescriptorRegistry = Object.freeze({",
176
+ " resolve(identity) {",
177
+ " return generatedDamlTypeDescriptorFactories[`${identity.packageId}:${identity.moduleName}:${identity.entityName}`];",
178
+ " },",
179
+ "});",
180
+ "",
181
+ ].join("\n"),
182
+ });
183
+ }
184
+ emitDescriptor(type) {
185
+ switch (type.kind) {
186
+ case "primitive":
187
+ return `{ kind: "primitive", primitive: ${JSON.stringify(type.builtinType)}${type.numericScale === undefined ? "" : `, numericScale: ${type.numericScale}`} }`;
188
+ case "contractId":
189
+ return '{ kind: "contractId" }';
190
+ case "optional":
191
+ return `{ kind: "optional", element: ${this.emitDescriptor(type.element)} }`;
192
+ case "list":
193
+ return `{ kind: "list", element: ${this.emitDescriptor(type.element)} }`;
194
+ case "textMap":
195
+ return `{ kind: "textMap", value: ${this.emitDescriptor(type.value)} }`;
196
+ case "genMap":
197
+ return `{ kind: "genMap", key: ${this.emitDescriptor(type.key)}, value: ${this.emitDescriptor(type.value)} }`;
198
+ case "record":
199
+ return `{ kind: "record", fields: [${type.fields.map((field) => `{ damlLabel: ${JSON.stringify(field.damlLabel)}, propertyName: ${JSON.stringify(field.propertyName)}, type: ${this.emitDescriptor(field.type)} }`).join(", ")}] }`;
200
+ case "variant":
201
+ return `{ kind: "variant", constructors: [${type.constructors.map((constructor) => `{ constructor: ${JSON.stringify(constructor.constructor)}, payload: ${this.emitDescriptor(constructor.payload)} }`).join(", ")}] }`;
202
+ case "enum":
203
+ return `{ kind: "enum", constructors: [${type.constructors.map((constructor) => JSON.stringify(constructor)).join(", ")}] }`;
204
+ case "namedReference":
205
+ return `{ kind: "namedReference", identity: { packageId: ${JSON.stringify(type.identity.packageId)}, moduleName: ${JSON.stringify(type.identity.moduleName)}, entityName: ${JSON.stringify(type.identity.name)} } }`;
206
+ }
207
+ }
208
+ emitDefinitionDescriptor(definition, fieldPropertyNames) {
209
+ if (definition.kind !== "record") {
210
+ return this.emitDescriptor(definition);
211
+ }
212
+ return `{ kind: "record", fields: [${definition.fields.map((field, index) => `{ damlLabel: ${JSON.stringify(field.damlLabel)}, propertyName: ${JSON.stringify(this.getFieldPropertyName(definition, index, fieldPropertyNames))}, type: ${this.emitDescriptor(field.type)} }`).join(", ")}] }`;
213
+ }
214
+ getFieldPropertyName(definition, index, names) {
215
+ const name = names.get(this.getFieldKey(definition, index));
216
+ if (name !== undefined) {
217
+ return name;
218
+ }
219
+ else if (definition.kind !== "record") {
220
+ throw new Error(`Cannot resolve fields for non-record named DAML type '${definition.identity.name}'`);
221
+ }
222
+ return definition.fields[index].propertyName;
223
+ }
224
+ getFieldKey(definition, index) {
225
+ return `${definition.identity.packageId}\u0000${definition.identity.moduleName}\u0000${definition.identity.name}\u0000field\u0000${index}`;
226
+ }
227
+ getIdentityKey(packageId, moduleName, entityName) {
228
+ return `${packageId}:${moduleName}:${entityName}`;
229
+ }
30
230
  }
@@ -1,11 +1,35 @@
1
1
  import { AnalyzedTemplate } from "../analysis/analyzed-template.js";
2
+ import { GeneratedNamedTypeFile } from "../emission-model/generated-named-type-file.js";
2
3
  import { GeneratedTemplateBindingFile } from "../emission-model/generated-template-binding-file.js";
3
4
  import { TypeScriptNameResolver } from "./type-script-name-resolver.js";
5
+ /** Emits typed contract and exercise-event bindings for analyzed DAML templates. */
4
6
  export declare class TemplateBindingEmitter {
5
7
  private readonly nameResolver;
6
8
  constructor(nameResolver?: TypeScriptNameResolver);
9
+ /** Prepares stable collision-safe names before emitting a complete project. */
10
+ prepareTemplatesOrThrow(templates: readonly AnalyzedTemplate[]): void;
7
11
  /** Emits a generated TypeScript file for one analyzed DAML template. */
8
- emitTemplateFile(template: AnalyzedTemplate): GeneratedTemplateBindingFile;
12
+ emitTemplateFile(template: AnalyzedTemplate, namedTypeFiles?: readonly GeneratedNamedTypeFile[]): GeneratedTemplateBindingFile;
13
+ /** Emits binding metadata without source, for resolving named declaration exports first. */
14
+ emitTemplateBindingFile(template: AnalyzedTemplate): GeneratedTemplateBindingFile;
9
15
  private createBinding;
10
16
  private emitContents;
17
+ private emitImports;
18
+ private emitTemplateClass;
19
+ private emitChoiceEventClass;
20
+ private emitTemplateDescriptor;
21
+ private emitDescriptor;
22
+ private getTypeName;
23
+ private getPrimitiveTypeName;
24
+ private normalizeType;
25
+ private resolveNamedReferences;
26
+ private walkNamedReferences;
27
+ private getNamedReference;
28
+ private getNamedReferenceKey;
29
+ private toTypeName;
30
+ private shortHash;
31
+ private packageId;
32
+ private moduleName;
33
+ private entityName;
34
+ private relativeFilePath;
11
35
  }