codama-renderers-dart 0.5.1 → 0.5.3

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.
@@ -84,9 +84,83 @@ function setEmptyCollection(record, key) {
84
84
  function pascalCase(str) {
85
85
  return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^(.)/, (c) => c.toUpperCase());
86
86
  }
87
+ var DART_RESERVED_WORDS = /* @__PURE__ */ new Set([
88
+ "abstract",
89
+ "as",
90
+ "assert",
91
+ "async",
92
+ "augment",
93
+ "await",
94
+ "base",
95
+ "break",
96
+ "case",
97
+ "catch",
98
+ "class",
99
+ "const",
100
+ "continue",
101
+ "covariant",
102
+ "default",
103
+ "deferred",
104
+ "do",
105
+ "dynamic",
106
+ "else",
107
+ "enum",
108
+ "export",
109
+ "extends",
110
+ "extension",
111
+ "external",
112
+ "factory",
113
+ "false",
114
+ "final",
115
+ "finally",
116
+ "for",
117
+ "get",
118
+ "hide",
119
+ "if",
120
+ "implements",
121
+ "import",
122
+ "in",
123
+ "interface",
124
+ "is",
125
+ "late",
126
+ "library",
127
+ "mixin",
128
+ "native",
129
+ "new",
130
+ "null",
131
+ "of",
132
+ "on",
133
+ "operator",
134
+ "part",
135
+ "required",
136
+ "rethrow",
137
+ "return",
138
+ "sealed",
139
+ "set",
140
+ "show",
141
+ "static",
142
+ "super",
143
+ "switch",
144
+ "sync",
145
+ "this",
146
+ "throw",
147
+ "true",
148
+ "try",
149
+ "typedef",
150
+ "var",
151
+ "void",
152
+ "when",
153
+ "while",
154
+ "with",
155
+ "yield"
156
+ ]);
157
+ function escapeDartIdentifier(name) {
158
+ return DART_RESERVED_WORDS.has(name) ? `${name}_` : name;
159
+ }
87
160
  function camelCase(str) {
88
161
  const pascal = pascalCase(str);
89
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
162
+ const cased = pascal.charAt(0).toLowerCase() + pascal.slice(1);
163
+ return escapeDartIdentifier(cased);
90
164
  }
91
165
  function snakeCase(str) {
92
166
  return str.replace(/([A-Z])/g, "_$1").replace(/[-\s]+/g, "_").replace(/^_/, "").replace(/_+/g, "_").toLowerCase();
@@ -674,7 +748,7 @@ function getTypeManifestVisitor(input) {
674
748
  encoder: fragment`${use(
675
749
  "getArrayEncoder",
676
750
  "solanaCodecsDataStructures"
677
- )}<${itemType}>(${itemEncoder}${encoderSizeExpr})`,
751
+ )}(${itemEncoder}${encoderSizeExpr})`,
678
752
  decoder: fragment`${use(
679
753
  "getArrayDecoder",
680
754
  "solanaCodecsDataStructures"
@@ -730,18 +804,28 @@ function getTypeManifestVisitor(input) {
730
804
  typeFragment.imports.mergeWith(m.type.imports);
731
805
  }
732
806
  const encoderListStr = encoderList.map((e) => e.content).join(", ");
807
+ const decoderListStr = decoderList.map((d) => d.content).join(", ");
808
+ let tupleEncoderFn = "getTupleEncoder";
809
+ let tupleDecoderFn = "getTupleDecoder";
810
+ let tupleEncoderArgs = `[${encoderListStr}]`;
811
+ let tupleDecoderArgs = `[${decoderListStr}]`;
812
+ if (itemManifests.length === 2) {
813
+ tupleEncoderFn = "getTuple2Encoder";
814
+ tupleDecoderFn = "getTuple2Decoder";
815
+ tupleEncoderArgs = encoderListStr;
816
+ tupleDecoderArgs = decoderListStr;
817
+ }
733
818
  const encoderFrag = fragment`${use(
734
- "getTupleEncoder",
819
+ tupleEncoderFn,
735
820
  "solanaCodecsDataStructures"
736
- )}([${fragmentFromString(encoderListStr)}])`;
821
+ )}(${tupleEncoderArgs})`;
737
822
  for (const e of encoderList) {
738
823
  encoderFrag.imports.mergeWith(e.imports);
739
824
  }
740
- const decoderListStr = decoderList.map((d) => d.content).join(", ");
741
825
  const decoderFrag = fragment`${use(
742
- "getTupleDecoder",
826
+ tupleDecoderFn,
743
827
  "solanaCodecsDataStructures"
744
- )}([${fragmentFromString(decoderListStr)}])`;
828
+ )}(${tupleDecoderArgs})`;
745
829
  for (const d of decoderList) {
746
830
  decoderFrag.imports.mergeWith(d.imports);
747
831
  }
@@ -828,7 +912,10 @@ function getTypeManifestVisitor(input) {
828
912
  encoder: fragment`${use(
829
913
  "getNullableEncoder",
830
914
  "solanaCodecsDataStructures"
831
- )}<${fragmentFromString(itemTypeStr)}>(${itemManifest.encoder}${fragmentFromString(prefixExpr)}${fragmentFromString(noneValueExpr)})`,
915
+ )}<${fragmentFromString(itemTypeStr)}>(${use(
916
+ "transformEncoder",
917
+ "solanaCodecsCore"
918
+ )}(${itemManifest.encoder}, (${fragmentFromString(itemTypeStr)} value) => value)${fragmentFromString(prefixExpr)}${fragmentFromString(noneValueExpr)})`,
832
919
  decoder: fragment`${use(
833
920
  "getNullableDecoder",
834
921
  "solanaCodecsDataStructures"
@@ -1589,6 +1676,10 @@ ${dataCtorInitializers}` : ""};`;
1589
1676
  const accountNames = new Set(accounts.map((a) => camelCase(a.name)));
1590
1677
  const hasProgramAddressCollision = argNames.has("programAddress") || accountNames.has("programAddress");
1591
1678
  const instrProgramParam = hasProgramAddressCollision ? "instructionProgramAddress" : "programAddress";
1679
+ let instructionDataLocal = "instructionData";
1680
+ while (argNames.has(instructionDataLocal) || accountNames.has(instructionDataLocal)) {
1681
+ instructionDataLocal = `${instructionDataLocal}_`;
1682
+ }
1592
1683
  const accountParams = accounts.map((acc) => {
1593
1684
  const fieldName = camelCase(acc.name);
1594
1685
  const isRequired = !(acc.isOptional ?? false);
@@ -1697,7 +1788,7 @@ Instruction ${fragmentFromString(instrFnName)}({
1697
1788
  ${fragmentFromString(accountParams)}
1698
1789
  ${fragmentFromString(argParams)}
1699
1790
  }) {
1700
- final instructionData = ${fragmentFromString(dataClassName)}(
1791
+ final ${instructionDataLocal} = ${fragmentFromString(dataClassName)}(
1701
1792
  ${fragmentFromString(dataConstruction)}
1702
1793
  );
1703
1794
 
@@ -1706,7 +1797,7 @@ ${fragmentFromString(dataConstruction)}
1706
1797
  accounts: [
1707
1798
  ${fragmentFromString(accountMetas)}
1708
1799
  ],
1709
- data: ${fragmentFromString(dataEncoderName)}().encode(instructionData),
1800
+ data: ${fragmentFromString(dataEncoderName)}().encode(${instructionDataLocal}),
1710
1801
  );
1711
1802
  }`);
1712
1803
  parts.push(fragment`
@@ -2130,6 +2221,7 @@ function getDataEnumPageFragment(node, variants, scope) {
2130
2221
  const decoderVariants = [];
2131
2222
  const encodeCases = [];
2132
2223
  const decodeCases = [];
2224
+ let pageHasListEnums = false;
2133
2225
  const allVariantManifests = [];
2134
2226
  for (let i = 0; i < variants.length; i++) {
2135
2227
  const variant = variants[i];
@@ -2177,10 +2269,14 @@ function getDataEnumPageFragment(node, variants, scope) {
2177
2269
  const ctorSignature = fields.length === 0 ? ` const ${variantClassName}();` : ` const ${variantClassName}({
2178
2270
  ${ctorParams}
2179
2271
  });`;
2180
- const eqChecks = fields.length === 0 ? "true" : fields.map((f) => `${camelCase(f.name)} == other.${camelCase(f.name)}`).join(" &&\n ");
2181
- const hashExpression = getHashExpression(
2182
- fields.map((f) => camelCase(f.name))
2183
- );
2272
+ const eqChecks = fields.length === 0 ? "true" : fields.map((f, index) => {
2273
+ const fieldName = camelCase(f.name);
2274
+ return isListManifest(fieldManifests[index].manifest) ? `_listEquals(${fieldName}, other.${fieldName})` : `${fieldName} == other.${fieldName}`;
2275
+ }).join(" &&\n ");
2276
+ const hashExpression = getValueHashExpression(fields, fieldManifests);
2277
+ if (fieldManifests.some(({ manifest }) => isListManifest(manifest))) {
2278
+ pageHasListEnums = true;
2279
+ }
2184
2280
  const toStringFields = fields.map((f) => `${camelCase(f.name)}: $${camelCase(f.name)}`).join(", ");
2185
2281
  variantClasses.push(`final class ${variantClassName} extends ${typeName} {
2186
2282
  ${ctorSignature}
@@ -2286,7 +2382,7 @@ sealed class ${fragmentFromString(typeName)} {
2286
2382
  const ${fragmentFromString(typeName)}();
2287
2383
  }
2288
2384
 
2289
- ${fragmentFromString(variantClasses.join("\n\n"))}
2385
+ ${fragmentFromString(variantClasses.join("\n\n"))}${pageHasListEnums ? LIST_VALUE_HELPERS : ""}
2290
2386
 
2291
2387
  Encoder<${fragmentFromString(typeName)}> ${fragmentFromString(encoderName)}() {
2292
2388
  return transformEncoder<Map<String, Object?>, ${fragmentFromString(typeName)}>(
@@ -2329,6 +2425,7 @@ function getStructPageFragment(node, scope) {
2329
2425
  const structNode = node.type;
2330
2426
  if (structNode.kind !== "structTypeNode") return emptyFragment();
2331
2427
  const fields = structNode.fields ?? [];
2428
+ let pageHasListStructs = false;
2332
2429
  const fieldManifests = fields.map((f) => ({
2333
2430
  field: f,
2334
2431
  manifest: visitorsCore.visit(f.type, scope.typeManifestVisitor)
@@ -2340,10 +2437,13 @@ function getStructPageFragment(node, scope) {
2340
2437
  const ctorSignature = fields.length === 0 ? ` const ${typeName}();` : ` const ${typeName}({
2341
2438
  ${ctorParams}
2342
2439
  });`;
2343
- const eqChecks = fields.length === 0 ? "true" : fields.map(
2344
- (f) => `${camelCase(f.name)} == other.${camelCase(f.name)}`
2345
- ).join(" &&\n ");
2346
- fields.length === 0 ? "runtimeType" : fields.map((f) => camelCase(f.name)).join(", ");
2440
+ const eqChecks = fields.length === 0 ? "true" : fieldManifests.map(({ field: f, manifest }, index) => {
2441
+ const fieldName = camelCase(f.name);
2442
+ return isListManifest(manifest) ? `_listEquals(${fieldName}, other.${fieldName})` : `${fieldName} == other.${fieldName}`;
2443
+ }).join(" &&\n ");
2444
+ if (fieldManifests.some(({ manifest }) => isListManifest(manifest))) {
2445
+ pageHasListStructs = true;
2446
+ }
2347
2447
  const toStringFields = fields.map(
2348
2448
  (f) => `${camelCase(f.name)}: $${camelCase(f.name)}`
2349
2449
  ).join(", ");
@@ -2393,12 +2493,14 @@ ${fragmentFromString(fieldDecls)}
2393
2493
  ${fragmentFromString(eqChecks)};
2394
2494
 
2395
2495
  @override
2396
- int get hashCode => ${fragmentFromString(getHashExpression(fields.map((f) => camelCase(f.name))))};
2496
+ int get hashCode => ${fragmentFromString(
2497
+ getValueHashExpression(fields, fieldManifests)
2498
+ )};
2397
2499
 
2398
2500
  @override
2399
2501
  String toString() => '${fragmentFromString(typeName)}(${fragmentFromString(toStringFields)})';
2400
2502
  }
2401
-
2503
+ ${pageHasListStructs ? LIST_VALUE_HELPERS : ""}
2402
2504
  Encoder<${fragmentFromString(typeName)}> ${fragmentFromString(encoderName)}() {
2403
2505
  final structEncoder = getStructEncoder(<(String, Encoder<Object?>)>[
2404
2506
  ${fragmentFromString(encFields)}
@@ -2464,6 +2566,56 @@ Codec<${fragmentFromString(typeName)}, ${fragmentFromString(typeName)}> ${fragme
2464
2566
  return combineCodec(${fragmentFromString(encoderName)}(), ${fragmentFromString(decoderName)}());
2465
2567
  }`;
2466
2568
  }
2569
+ function isListManifest(manifest) {
2570
+ return manifest.type.content.startsWith("List<") || manifest.type.content === "Uint8List";
2571
+ }
2572
+ var LIST_VALUE_HELPERS = `
2573
+ bool _listEquals<T>(List<T>? a, List<T>? b) {
2574
+ if (identical(a, b)) return true;
2575
+ if (a == null || b == null) return a == b;
2576
+ if (a.length != b.length) return false;
2577
+ for (var i = 0; i < a.length; i++) {
2578
+ final left = a[i];
2579
+ final right = b[i];
2580
+ if (left is List<Object?> && right is List<Object?>) {
2581
+ if (!_listEquals(left, right)) return false;
2582
+ } else if (left != right) {
2583
+ return false;
2584
+ }
2585
+ }
2586
+ return true;
2587
+ }
2588
+
2589
+ Object? _deepHash(Object? value) {
2590
+ if (value is List<Object?>) {
2591
+ return Object.hashAll(value.map(_deepHash));
2592
+ }
2593
+ return value;
2594
+ }
2595
+
2596
+ int _listHashCode<T>(List<T>? a) {
2597
+ if (a == null) return 0;
2598
+ return Object.hashAll(a.map(_deepHash));
2599
+ }
2600
+ `;
2601
+ function getValueHashExpression(fields, fieldManifests) {
2602
+ const fieldNames = fields.map(
2603
+ (f) => camelCase(f.name)
2604
+ );
2605
+ const hasListFields = fieldManifests.some(
2606
+ ({ manifest }) => isListManifest(manifest)
2607
+ );
2608
+ if (!hasListFields) {
2609
+ return getHashExpression(fieldNames);
2610
+ }
2611
+ if (fieldNames.length === 1) {
2612
+ return `_listHashCode(${fieldNames[0]})`;
2613
+ }
2614
+ const hashArgs = fields.map(
2615
+ (f, index) => isListManifest(fieldManifests[index].manifest) ? `_listHashCode(${camelCase(f.name)})` : camelCase(f.name)
2616
+ );
2617
+ return `Object.hash(${hashArgs.join(", ")})`;
2618
+ }
2467
2619
  function getHashExpression(fields) {
2468
2620
  if (fields.length === 0) return "runtimeType.hashCode";
2469
2621
  if (fields.length === 1) return `${fields[0]}.hashCode`;