@beclab/olaresid 0.1.12 → 0.2.0

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 (182) hide show
  1. package/CLI-TREE.md +107 -0
  2. package/CLI.md +122 -1329
  3. package/README.md +30 -12
  4. package/SDK-TREE.md +151 -0
  5. package/TAG.md +95 -41
  6. package/config.json +6 -4
  7. package/dist/abi/TerminusDIDQueryABI.d.ts +397 -0
  8. package/dist/abi/TerminusDIDQueryABI.d.ts.map +1 -0
  9. package/dist/abi/TerminusDIDQueryABI.js +519 -0
  10. package/dist/abi/TerminusDIDQueryABI.js.map +1 -0
  11. package/dist/business/index.d.ts +1 -1
  12. package/dist/business/index.d.ts.map +1 -1
  13. package/dist/business/index.js +11 -24
  14. package/dist/business/index.js.map +1 -1
  15. package/dist/business/tag-context.d.ts +1 -0
  16. package/dist/business/tag-context.d.ts.map +1 -1
  17. package/dist/business/tag-context.js +13 -7
  18. package/dist/business/tag-context.js.map +1 -1
  19. package/dist/cli.js +238 -107
  20. package/dist/cli.js.map +1 -1
  21. package/dist/config/index.d.ts +16 -4
  22. package/dist/config/index.d.ts.map +1 -1
  23. package/dist/config/index.js +28 -14
  24. package/dist/config/index.js.map +1 -1
  25. package/dist/domain/core.d.ts +65 -0
  26. package/dist/domain/core.d.ts.map +1 -0
  27. package/dist/domain/core.js +317 -0
  28. package/dist/domain/core.js.map +1 -0
  29. package/dist/domain/index.d.ts +104 -57
  30. package/dist/domain/index.d.ts.map +1 -1
  31. package/dist/domain/index.js +188 -428
  32. package/dist/domain/index.js.map +1 -1
  33. package/dist/domain/types.d.ts +56 -0
  34. package/dist/domain/types.d.ts.map +1 -0
  35. package/dist/domain/types.js +3 -0
  36. package/dist/domain/types.js.map +1 -0
  37. package/dist/index.d.ts +81 -24
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +153 -143
  40. package/dist/index.js.map +1 -1
  41. package/dist/utils/crypto-utils.d.ts +124 -0
  42. package/dist/utils/crypto-utils.d.ts.map +1 -1
  43. package/dist/utils/crypto-utils.js +156 -8
  44. package/dist/utils/crypto-utils.js.map +1 -1
  45. package/dist/utils/error-parser.d.ts.map +1 -1
  46. package/dist/utils/error-parser.js +2 -1
  47. package/dist/utils/error-parser.js.map +1 -1
  48. package/dist/utils/event-parser.d.ts +161 -0
  49. package/dist/utils/event-parser.d.ts.map +1 -0
  50. package/dist/utils/event-parser.js +140 -0
  51. package/dist/utils/event-parser.js.map +1 -0
  52. package/dist/utils/tag-type-builder.d.ts +43 -0
  53. package/dist/utils/tag-type-builder.d.ts.map +1 -1
  54. package/dist/utils/tag-type-builder.js +122 -0
  55. package/dist/utils/tag-type-builder.js.map +1 -1
  56. package/dist/utils/tag-type-parser.d.ts +70 -0
  57. package/dist/utils/tag-type-parser.d.ts.map +1 -0
  58. package/dist/utils/tag-type-parser.js +190 -0
  59. package/dist/utils/tag-type-parser.js.map +1 -0
  60. package/examples/create-with-rpc-demo.ts +142 -0
  61. package/examples/fetch-all-flat-demo.ts +159 -0
  62. package/examples/fetch-by-indices-demo.ts +235 -0
  63. package/examples/fetch-domain-demo.ts +137 -0
  64. package/examples/fetch-domains-demo.ts +221 -0
  65. package/examples/frontend-demo/index.html +2 -2
  66. package/examples/frontend-demo/package-lock.json +4 -1
  67. package/examples/index.ts +3 -5
  68. package/jest.config.js +25 -0
  69. package/package.json +6 -2
  70. package/src/abi/TerminusDIDQueryABI.ts +516 -0
  71. package/src/business/index.ts +10 -33
  72. package/src/business/tag-context.ts +35 -7
  73. package/src/cli.ts +344 -121
  74. package/src/config/index.ts +34 -19
  75. package/src/domain/core.ts +382 -0
  76. package/src/domain/index.ts +271 -641
  77. package/src/domain/types.ts +59 -0
  78. package/src/index.ts +222 -207
  79. package/src/utils/crypto-utils.ts +239 -2
  80. package/src/utils/error-parser.ts +2 -1
  81. package/src/utils/event-parser.ts +353 -0
  82. package/src/utils/tag-type-builder.ts +138 -0
  83. package/src/utils/tag-type-parser.ts +246 -0
  84. package/tests/unit/crypto-utils.test.ts +338 -0
  85. package/tests/unit/ed25519-jwk.test.ts +201 -0
  86. package/tests/unit/event-parser.test.ts +690 -0
  87. package/tests/unit/generate-mnemonic.test.ts +268 -0
  88. package/tests/unit/olares-id-format.test.ts +321 -0
  89. package/tests/unit/tag-type-parser.test.ts +802 -0
  90. package/tests/unit/tag-types.test.ts +821 -0
  91. package/tsconfig.json +3 -2
  92. package/dist/abi/ABITypeABI.d.ts +0 -88
  93. package/dist/abi/ABITypeABI.d.ts.map +0 -1
  94. package/dist/abi/ABITypeABI.js +0 -382
  95. package/dist/abi/ABITypeABI.js.map +0 -1
  96. package/dist/abi/RegistryABI.d.ts +0 -77
  97. package/dist/abi/RegistryABI.d.ts.map +0 -1
  98. package/dist/abi/RegistryABI.js +0 -462
  99. package/dist/abi/RegistryABI.js.map +0 -1
  100. package/dist/tag/address.d.ts +0 -11
  101. package/dist/tag/address.d.ts.map +0 -1
  102. package/dist/tag/address.js +0 -44
  103. package/dist/tag/address.js.map +0 -1
  104. package/dist/tag/array.d.ts +0 -14
  105. package/dist/tag/array.d.ts.map +0 -1
  106. package/dist/tag/array.js +0 -72
  107. package/dist/tag/array.js.map +0 -1
  108. package/dist/tag/bool.d.ts +0 -11
  109. package/dist/tag/bool.d.ts.map +0 -1
  110. package/dist/tag/bool.js +0 -43
  111. package/dist/tag/bool.js.map +0 -1
  112. package/dist/tag/bytes.d.ts +0 -11
  113. package/dist/tag/bytes.d.ts.map +0 -1
  114. package/dist/tag/bytes.js +0 -37
  115. package/dist/tag/bytes.js.map +0 -1
  116. package/dist/tag/flarray.d.ts +0 -15
  117. package/dist/tag/flarray.d.ts.map +0 -1
  118. package/dist/tag/flarray.js +0 -81
  119. package/dist/tag/flarray.js.map +0 -1
  120. package/dist/tag/flbytes.d.ts +0 -11
  121. package/dist/tag/flbytes.d.ts.map +0 -1
  122. package/dist/tag/flbytes.js +0 -47
  123. package/dist/tag/flbytes.js.map +0 -1
  124. package/dist/tag/index.d.ts +0 -32
  125. package/dist/tag/index.d.ts.map +0 -1
  126. package/dist/tag/index.js +0 -121
  127. package/dist/tag/index.js.map +0 -1
  128. package/dist/tag/int.d.ts +0 -12
  129. package/dist/tag/int.d.ts.map +0 -1
  130. package/dist/tag/int.js +0 -49
  131. package/dist/tag/int.js.map +0 -1
  132. package/dist/tag/string.d.ts +0 -11
  133. package/dist/tag/string.d.ts.map +0 -1
  134. package/dist/tag/string.js +0 -37
  135. package/dist/tag/string.js.map +0 -1
  136. package/dist/tag/tag.d.ts +0 -67
  137. package/dist/tag/tag.d.ts.map +0 -1
  138. package/dist/tag/tag.js +0 -157
  139. package/dist/tag/tag.js.map +0 -1
  140. package/dist/tag/tuple.d.ts +0 -17
  141. package/dist/tag/tuple.d.ts.map +0 -1
  142. package/dist/tag/tuple.js +0 -162
  143. package/dist/tag/tuple.js.map +0 -1
  144. package/dist/tag/uint.d.ts +0 -12
  145. package/dist/tag/uint.d.ts.map +0 -1
  146. package/dist/tag/uint.js +0 -49
  147. package/dist/tag/uint.js.map +0 -1
  148. package/dist/test/did.d.ts +0 -2
  149. package/dist/test/did.d.ts.map +0 -1
  150. package/dist/test/did.js +0 -177
  151. package/dist/test/did.js.map +0 -1
  152. package/dist/utils/tag-abi-codec.d.ts +0 -69
  153. package/dist/utils/tag-abi-codec.d.ts.map +0 -1
  154. package/dist/utils/tag-abi-codec.js +0 -144
  155. package/dist/utils/tag-abi-codec.js.map +0 -1
  156. package/examples/crypto-utilities.ts +0 -140
  157. package/examples/ed25519-jwk.ts +0 -73
  158. package/examples/generate-mnemonic.ts +0 -149
  159. package/examples/legacy.ts +0 -33
  160. package/examples/olares-id-format.ts +0 -197
  161. package/examples/tag-builder.ts +0 -235
  162. package/examples/tag-nested-tuple.ts +0 -190
  163. package/examples/tag-simple.ts +0 -149
  164. package/examples/tag-tagger.ts +0 -217
  165. package/examples/test-nested-tuple-conversion.ts +0 -143
  166. package/examples/test-type-bytes-parser.ts +0 -70
  167. package/src/abi/ABITypeABI.ts +0 -379
  168. package/src/abi/RegistryABI.ts +0 -459
  169. package/src/tag/address.ts +0 -48
  170. package/src/tag/array.ts +0 -80
  171. package/src/tag/bool.ts +0 -43
  172. package/src/tag/bytes.ts +0 -38
  173. package/src/tag/flarray.ts +0 -99
  174. package/src/tag/flbytes.ts +0 -48
  175. package/src/tag/index.ts +0 -170
  176. package/src/tag/int.ts +0 -51
  177. package/src/tag/string.ts +0 -38
  178. package/src/tag/tag.ts +0 -229
  179. package/src/tag/tuple.ts +0 -193
  180. package/src/tag/uint.ts +0 -51
  181. package/src/test/did.ts +0 -346
  182. package/src/utils/tag-abi-codec.ts +0 -158
@@ -443,6 +443,144 @@ export class TagTypeBuilder {
443
443
  static uint256Array() {
444
444
  return this.array(this.uint256());
445
445
  }
446
+
447
+ // ========================================
448
+ // Object to Array Conversion (for encoding)
449
+ // ========================================
450
+
451
+ /**
452
+ * Convert object to array for tuple encoding
453
+ * Recursively handles nested tuples and tuple arrays
454
+ *
455
+ * @param abiType ABI type string (e.g., "tuple(string,uint8)")
456
+ * @param value Value to convert (object or array)
457
+ * @returns Array representation suitable for ABI encoding
458
+ *
459
+ * @example
460
+ * // Simple tuple
461
+ * convertObjectToArray(
462
+ * "tuple(string,uint8)",
463
+ * {name: "Alice", age: 30}
464
+ * ) // → ["Alice", 30]
465
+ *
466
+ * // Nested tuple
467
+ * convertObjectToArray(
468
+ * "tuple(string,tuple(uint8,bool))",
469
+ * {name: "Bob", profile: {age: 25, active: true}}
470
+ * ) // → ["Bob", [25, true]]
471
+ *
472
+ * // Tuple array
473
+ * convertObjectToArray(
474
+ * "tuple(uint8,address)[]",
475
+ * [{algorithm: 0, addr: "0x123..."}, {algorithm: 1, addr: "0x456..."}]
476
+ * ) // → [[0, "0x123..."], [1, "0x456..."]]
477
+ */
478
+ static convertObjectToArray(abiType: string, value: any): any {
479
+ // Handle null and primitives
480
+ if (value === null || typeof value !== 'object') {
481
+ return value;
482
+ }
483
+
484
+ // Handle tuple[] type (array of tuples)
485
+ // Check if it ends with [] and starts with tuple
486
+ if (abiType.startsWith('tuple(') && abiType.endsWith('[]')) {
487
+ if (Array.isArray(value)) {
488
+ // Remove [] suffix to get element type: "tuple(uint8,address)[]" → "tuple(uint8,address)"
489
+ const elementType = abiType.slice(0, -2);
490
+ // Recursively convert each element
491
+ return value.map((item) =>
492
+ this.convertObjectToArray(elementType, item)
493
+ );
494
+ }
495
+ // If not an array but type is tuple[], return as-is
496
+ return value;
497
+ }
498
+
499
+ // If already an array (but not tuple[]), return as-is
500
+ if (Array.isArray(value)) {
501
+ return value;
502
+ }
503
+
504
+ // If not a tuple type, return as-is
505
+ if (!abiType.startsWith('tuple(')) {
506
+ return value;
507
+ }
508
+
509
+ // Parse tuple field types
510
+ const fieldTypes = this.parseTupleFieldTypes(abiType);
511
+ const fieldNames = Object.keys(value);
512
+
513
+ if (fieldNames.length !== fieldTypes.length) {
514
+ throw new Error(
515
+ `Tuple field count mismatch: expected ${fieldTypes.length} fields, got ${fieldNames.length}`
516
+ );
517
+ }
518
+
519
+ // Convert object to array, recursively handling nested tuples
520
+ const result: any[] = [];
521
+ for (let i = 0; i < fieldNames.length; i++) {
522
+ const fieldName = fieldNames[i];
523
+ const fieldType = fieldTypes[i];
524
+ const fieldValue = value[fieldName];
525
+
526
+ // Recursively convert nested tuples (including nested tuple arrays)
527
+ if (fieldType.startsWith('tuple(')) {
528
+ result.push(this.convertObjectToArray(fieldType, fieldValue));
529
+ } else {
530
+ result.push(fieldValue);
531
+ }
532
+ }
533
+
534
+ return result;
535
+ }
536
+
537
+ /**
538
+ * Parse tuple field types from ABI type string
539
+ * Handles nested tuples correctly
540
+ *
541
+ * @param abiType Tuple ABI type string
542
+ * @returns Array of field type strings
543
+ *
544
+ * @example
545
+ * parseTupleFieldTypes("tuple(string,uint8)")
546
+ * // → ["string", "uint8"]
547
+ *
548
+ * parseTupleFieldTypes("tuple(string,tuple(uint8,bool))")
549
+ * // → ["string", "tuple(uint8,bool)"]
550
+ */
551
+ static parseTupleFieldTypes(abiType: string): string[] {
552
+ if (!abiType.startsWith('tuple(')) {
553
+ return [];
554
+ }
555
+
556
+ const innerTypes = abiType.slice(6, -1); // Remove "tuple(" and ")"
557
+ const fields: string[] = [];
558
+ let depth = 0;
559
+ let currentField = '';
560
+
561
+ for (let i = 0; i < innerTypes.length; i++) {
562
+ const char = innerTypes[i];
563
+
564
+ if (char === '(') {
565
+ depth++;
566
+ currentField += char;
567
+ } else if (char === ')') {
568
+ depth--;
569
+ currentField += char;
570
+ } else if (char === ',' && depth === 0) {
571
+ fields.push(currentField.trim());
572
+ currentField = '';
573
+ } else {
574
+ currentField += char;
575
+ }
576
+ }
577
+
578
+ if (currentField) {
579
+ fields.push(currentField.trim());
580
+ }
581
+
582
+ return fields;
583
+ }
446
584
  }
447
585
 
448
586
  /**
@@ -0,0 +1,246 @@
1
+ import { AbiCoder } from 'ethers';
2
+ import { TagTypeBuilder } from './tag-type-builder';
3
+ import { RawTagData, Tag } from '../domain/types';
4
+
5
+ /**
6
+ * Tag Type Parser
7
+ * Parse and decode Tag values with field name support
8
+ *
9
+ * Pair with TagTypeBuilder:
10
+ * - TagTypeBuilder: Encoding (build types, object → array)
11
+ * - TagTypeParser: Decoding (parse types, array → object, parse tags)
12
+ */
13
+ export class TagTypeParser {
14
+ /**
15
+ * Parse a raw tag into a formatted Tag object
16
+ * Handles all types including nested tuples
17
+ *
18
+ * @param rawTag Raw tag data from contract
19
+ * @param fieldNamesMap Map of field name hashes to field names
20
+ * @param abiCoder AbiCoder instance for decoding
21
+ * @returns Formatted Tag object
22
+ */
23
+ static parseTag(
24
+ rawTag: RawTagData,
25
+ fieldNamesMap: Map<string, string[]>,
26
+ abiCoder: AbiCoder
27
+ ): Tag {
28
+ // Step 1: Parse type bytes to ABI type string
29
+ const abiTypeString = TagTypeBuilder.parseTypeBytesToAbiString(
30
+ rawTag.abiType
31
+ );
32
+
33
+ // If the tag has no value (defined but not set), return it with null formatted value
34
+ if (!rawTag.value || rawTag.value === '0x' || rawTag.value === '') {
35
+ return {
36
+ from: rawTag.from,
37
+ name: rawTag.name,
38
+ abiType: abiTypeString,
39
+ value: rawTag.value,
40
+ fieldNamesHash: rawTag.fieldNamesHash,
41
+ valueFormatted: null
42
+ };
43
+ }
44
+
45
+ // Step 2: Decode value
46
+ const decoded = abiCoder.decode([abiTypeString], rawTag.value);
47
+ let decodedValue = decoded[0];
48
+
49
+ // Step 3: Convert to user-friendly format
50
+ let formattedValue: any = decodedValue;
51
+
52
+ // Handle tuple types (including tuple arrays and nested tuples)
53
+ if (abiTypeString.includes('tuple')) {
54
+ // Get all field names in pre-order (for nested tuples)
55
+ const allFieldNames = this.getAllFieldNames(
56
+ rawTag.fieldNamesHash,
57
+ fieldNamesMap
58
+ );
59
+
60
+ if (allFieldNames.length > 0) {
61
+ // Use a counter to track which field name array we're using
62
+ const context = { fieldNameIndex: 0 };
63
+
64
+ // Check if it's an array of tuples
65
+ if (
66
+ abiTypeString.startsWith('tuple(') &&
67
+ abiTypeString.endsWith('[]')
68
+ ) {
69
+ // Array of tuples: convert each element
70
+ if (Array.isArray(decodedValue)) {
71
+ formattedValue = decodedValue.map((item) => {
72
+ // Reset field name index for each array element
73
+ const itemContext = { fieldNameIndex: 0 };
74
+ return this.convertTupleToObject(
75
+ item,
76
+ abiTypeString.slice(0, -2),
77
+ allFieldNames,
78
+ itemContext
79
+ );
80
+ });
81
+ }
82
+ } else if (abiTypeString.startsWith('tuple(')) {
83
+ // Single tuple: convert to object (with nested tuple support)
84
+ formattedValue = this.convertTupleToObject(
85
+ decodedValue,
86
+ abiTypeString,
87
+ allFieldNames,
88
+ context
89
+ );
90
+ }
91
+ } else {
92
+ // Log warning if field names not found for tuple
93
+ if (
94
+ rawTag.fieldNamesHash.length > 0 &&
95
+ rawTag.fieldNamesHash[0] !==
96
+ '0x0000000000000000000000000000000000000000000000000000000000000000'
97
+ ) {
98
+ console.warn(
99
+ `⚠️ Field names not found for tag "${
100
+ rawTag.name
101
+ }" with hash(es): ${rawTag.fieldNamesHash.join(', ')}`
102
+ );
103
+ }
104
+ }
105
+ }
106
+
107
+ // Convert BigInt to string for serialization
108
+ formattedValue = this.convertBigIntToString(formattedValue);
109
+
110
+ // Serialize objects/arrays to JSON string for did-support compatibility
111
+ if (formattedValue !== null && typeof formattedValue === 'object') {
112
+ formattedValue = JSON.stringify(formattedValue);
113
+ }
114
+
115
+ return {
116
+ from: rawTag.from,
117
+ name: rawTag.name,
118
+ abiType: abiTypeString,
119
+ value: rawTag.value,
120
+ fieldNamesHash: rawTag.fieldNamesHash,
121
+ valueFormatted: formattedValue
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Convert decoded tuple array to object using field names
127
+ * Recursively handles nested tuples
128
+ *
129
+ * @param value Decoded tuple value (array form)
130
+ * @param abiType ABI type string of the tuple
131
+ * @param allFieldNames All field names in pre-order traversal
132
+ * @param context Context to track which field name array we're using
133
+ * @returns Object representation with field names
134
+ *
135
+ * @example
136
+ * // Simple tuple
137
+ * convertTupleToObject(
138
+ * ["Alice", 30],
139
+ * "tuple(string,uint8)",
140
+ * [["name", "age"]],
141
+ * { fieldNameIndex: 0 }
142
+ * ) // → { name: "Alice", age: 30 }
143
+ *
144
+ * // Nested tuple
145
+ * convertTupleToObject(
146
+ * ["Bob", [25, true]],
147
+ * "tuple(string,tuple(uint8,bool))",
148
+ * [["name", "profile"], ["age", "verified"]],
149
+ * { fieldNameIndex: 0 }
150
+ * ) // → { name: "Bob", profile: { age: 25, verified: true } }
151
+ */
152
+ static convertTupleToObject(
153
+ value: any,
154
+ abiType: string,
155
+ allFieldNames: string[][],
156
+ context: { fieldNameIndex: number }
157
+ ): any {
158
+ if (!Array.isArray(value) || !abiType.startsWith('tuple(')) {
159
+ return value;
160
+ }
161
+
162
+ // Get field names for current tuple level
163
+ if (context.fieldNameIndex >= allFieldNames.length) {
164
+ return value;
165
+ }
166
+
167
+ const fieldNames = allFieldNames[context.fieldNameIndex];
168
+ context.fieldNameIndex++;
169
+
170
+ if (fieldNames.length !== value.length) {
171
+ return value;
172
+ }
173
+
174
+ // Parse field types to determine which fields are nested tuples
175
+ const fieldTypes = TagTypeBuilder.parseTupleFieldTypes(abiType);
176
+
177
+ const obj: any = {};
178
+ for (let i = 0; i < fieldNames.length; i++) {
179
+ const fieldName = fieldNames[i];
180
+ const fieldValue = value[i];
181
+ const fieldType = fieldTypes[i];
182
+
183
+ // Recursively convert nested tuples
184
+ if (fieldType.startsWith('tuple(')) {
185
+ obj[fieldName] = this.convertTupleToObject(
186
+ fieldValue,
187
+ fieldType,
188
+ allFieldNames,
189
+ context
190
+ );
191
+ } else {
192
+ obj[fieldName] = fieldValue;
193
+ }
194
+ }
195
+
196
+ return obj;
197
+ }
198
+
199
+ /**
200
+ * Recursively convert BigInt values to strings
201
+ * Handles primitives, arrays, and objects
202
+ *
203
+ * @param value Value to convert
204
+ * @returns Value with all BigInts converted to strings
205
+ */
206
+ static convertBigIntToString(value: any): any {
207
+ if (typeof value === 'bigint') {
208
+ return value.toString();
209
+ }
210
+ if (Array.isArray(value)) {
211
+ return value.map((v) => this.convertBigIntToString(v));
212
+ }
213
+ if (value !== null && typeof value === 'object') {
214
+ const result: any = {};
215
+ for (const key in value) {
216
+ result[key] = this.convertBigIntToString(value[key]);
217
+ }
218
+ return result;
219
+ }
220
+ return value;
221
+ }
222
+
223
+ /**
224
+ * Get all field names for a tag from the field names map
225
+ * Returns all field name arrays in pre-order (for nested tuples)
226
+ *
227
+ * @param fieldNamesHashes Array of field name hashes
228
+ * @param fieldNamesMap Map of hash to field names
229
+ * @returns Array of field name arrays in pre-order
230
+ */
231
+ private static getAllFieldNames(
232
+ fieldNamesHashes: string[],
233
+ fieldNamesMap: Map<string, string[]>
234
+ ): string[][] {
235
+ const allFieldNames: string[][] = [];
236
+
237
+ for (const hash of fieldNamesHashes) {
238
+ const names = fieldNamesMap.get(hash);
239
+ if (names) {
240
+ allFieldNames.push(names);
241
+ }
242
+ }
243
+
244
+ return allFieldNames;
245
+ }
246
+ }