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.
@@ -80,9 +80,83 @@ function setEmptyCollection(record, key) {
80
80
  function pascalCase(str) {
81
81
  return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : "").replace(/^(.)/, (c) => c.toUpperCase());
82
82
  }
83
+ var DART_RESERVED_WORDS = /* @__PURE__ */ new Set([
84
+ "abstract",
85
+ "as",
86
+ "assert",
87
+ "async",
88
+ "augment",
89
+ "await",
90
+ "base",
91
+ "break",
92
+ "case",
93
+ "catch",
94
+ "class",
95
+ "const",
96
+ "continue",
97
+ "covariant",
98
+ "default",
99
+ "deferred",
100
+ "do",
101
+ "dynamic",
102
+ "else",
103
+ "enum",
104
+ "export",
105
+ "extends",
106
+ "extension",
107
+ "external",
108
+ "factory",
109
+ "false",
110
+ "final",
111
+ "finally",
112
+ "for",
113
+ "get",
114
+ "hide",
115
+ "if",
116
+ "implements",
117
+ "import",
118
+ "in",
119
+ "interface",
120
+ "is",
121
+ "late",
122
+ "library",
123
+ "mixin",
124
+ "native",
125
+ "new",
126
+ "null",
127
+ "of",
128
+ "on",
129
+ "operator",
130
+ "part",
131
+ "required",
132
+ "rethrow",
133
+ "return",
134
+ "sealed",
135
+ "set",
136
+ "show",
137
+ "static",
138
+ "super",
139
+ "switch",
140
+ "sync",
141
+ "this",
142
+ "throw",
143
+ "true",
144
+ "try",
145
+ "typedef",
146
+ "var",
147
+ "void",
148
+ "when",
149
+ "while",
150
+ "with",
151
+ "yield"
152
+ ]);
153
+ function escapeDartIdentifier(name) {
154
+ return DART_RESERVED_WORDS.has(name) ? `${name}_` : name;
155
+ }
83
156
  function camelCase(str) {
84
157
  const pascal = pascalCase(str);
85
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
158
+ const cased = pascal.charAt(0).toLowerCase() + pascal.slice(1);
159
+ return escapeDartIdentifier(cased);
86
160
  }
87
161
  function snakeCase(str) {
88
162
  return str.replace(/([A-Z])/g, "_$1").replace(/[-\s]+/g, "_").replace(/^_/, "").replace(/_+/g, "_").toLowerCase();
@@ -670,7 +744,7 @@ function getTypeManifestVisitor(input) {
670
744
  encoder: fragment`${use(
671
745
  "getArrayEncoder",
672
746
  "solanaCodecsDataStructures"
673
- )}<${itemType}>(${itemEncoder}${encoderSizeExpr})`,
747
+ )}(${itemEncoder}${encoderSizeExpr})`,
674
748
  decoder: fragment`${use(
675
749
  "getArrayDecoder",
676
750
  "solanaCodecsDataStructures"
@@ -726,18 +800,28 @@ function getTypeManifestVisitor(input) {
726
800
  typeFragment.imports.mergeWith(m.type.imports);
727
801
  }
728
802
  const encoderListStr = encoderList.map((e) => e.content).join(", ");
803
+ const decoderListStr = decoderList.map((d) => d.content).join(", ");
804
+ let tupleEncoderFn = "getTupleEncoder";
805
+ let tupleDecoderFn = "getTupleDecoder";
806
+ let tupleEncoderArgs = `[${encoderListStr}]`;
807
+ let tupleDecoderArgs = `[${decoderListStr}]`;
808
+ if (itemManifests.length === 2) {
809
+ tupleEncoderFn = "getTuple2Encoder";
810
+ tupleDecoderFn = "getTuple2Decoder";
811
+ tupleEncoderArgs = encoderListStr;
812
+ tupleDecoderArgs = decoderListStr;
813
+ }
729
814
  const encoderFrag = fragment`${use(
730
- "getTupleEncoder",
815
+ tupleEncoderFn,
731
816
  "solanaCodecsDataStructures"
732
- )}([${fragmentFromString(encoderListStr)}])`;
817
+ )}(${tupleEncoderArgs})`;
733
818
  for (const e of encoderList) {
734
819
  encoderFrag.imports.mergeWith(e.imports);
735
820
  }
736
- const decoderListStr = decoderList.map((d) => d.content).join(", ");
737
821
  const decoderFrag = fragment`${use(
738
- "getTupleDecoder",
822
+ tupleDecoderFn,
739
823
  "solanaCodecsDataStructures"
740
- )}([${fragmentFromString(decoderListStr)}])`;
824
+ )}(${tupleDecoderArgs})`;
741
825
  for (const d of decoderList) {
742
826
  decoderFrag.imports.mergeWith(d.imports);
743
827
  }
@@ -824,7 +908,10 @@ function getTypeManifestVisitor(input) {
824
908
  encoder: fragment`${use(
825
909
  "getNullableEncoder",
826
910
  "solanaCodecsDataStructures"
827
- )}<${fragmentFromString(itemTypeStr)}>(${itemManifest.encoder}${fragmentFromString(prefixExpr)}${fragmentFromString(noneValueExpr)})`,
911
+ )}<${fragmentFromString(itemTypeStr)}>(${use(
912
+ "transformEncoder",
913
+ "solanaCodecsCore"
914
+ )}(${itemManifest.encoder}, (${fragmentFromString(itemTypeStr)} value) => value)${fragmentFromString(prefixExpr)}${fragmentFromString(noneValueExpr)})`,
828
915
  decoder: fragment`${use(
829
916
  "getNullableDecoder",
830
917
  "solanaCodecsDataStructures"
@@ -1585,6 +1672,10 @@ ${dataCtorInitializers}` : ""};`;
1585
1672
  const accountNames = new Set(accounts.map((a) => camelCase(a.name)));
1586
1673
  const hasProgramAddressCollision = argNames.has("programAddress") || accountNames.has("programAddress");
1587
1674
  const instrProgramParam = hasProgramAddressCollision ? "instructionProgramAddress" : "programAddress";
1675
+ let instructionDataLocal = "instructionData";
1676
+ while (argNames.has(instructionDataLocal) || accountNames.has(instructionDataLocal)) {
1677
+ instructionDataLocal = `${instructionDataLocal}_`;
1678
+ }
1588
1679
  const accountParams = accounts.map((acc) => {
1589
1680
  const fieldName = camelCase(acc.name);
1590
1681
  const isRequired = !(acc.isOptional ?? false);
@@ -1693,7 +1784,7 @@ Instruction ${fragmentFromString(instrFnName)}({
1693
1784
  ${fragmentFromString(accountParams)}
1694
1785
  ${fragmentFromString(argParams)}
1695
1786
  }) {
1696
- final instructionData = ${fragmentFromString(dataClassName)}(
1787
+ final ${instructionDataLocal} = ${fragmentFromString(dataClassName)}(
1697
1788
  ${fragmentFromString(dataConstruction)}
1698
1789
  );
1699
1790
 
@@ -1702,7 +1793,7 @@ ${fragmentFromString(dataConstruction)}
1702
1793
  accounts: [
1703
1794
  ${fragmentFromString(accountMetas)}
1704
1795
  ],
1705
- data: ${fragmentFromString(dataEncoderName)}().encode(instructionData),
1796
+ data: ${fragmentFromString(dataEncoderName)}().encode(${instructionDataLocal}),
1706
1797
  );
1707
1798
  }`);
1708
1799
  parts.push(fragment`
@@ -2126,6 +2217,7 @@ function getDataEnumPageFragment(node, variants, scope) {
2126
2217
  const decoderVariants = [];
2127
2218
  const encodeCases = [];
2128
2219
  const decodeCases = [];
2220
+ let pageHasListEnums = false;
2129
2221
  const allVariantManifests = [];
2130
2222
  for (let i = 0; i < variants.length; i++) {
2131
2223
  const variant = variants[i];
@@ -2173,10 +2265,14 @@ function getDataEnumPageFragment(node, variants, scope) {
2173
2265
  const ctorSignature = fields.length === 0 ? ` const ${variantClassName}();` : ` const ${variantClassName}({
2174
2266
  ${ctorParams}
2175
2267
  });`;
2176
- const eqChecks = fields.length === 0 ? "true" : fields.map((f) => `${camelCase(f.name)} == other.${camelCase(f.name)}`).join(" &&\n ");
2177
- const hashExpression = getHashExpression(
2178
- fields.map((f) => camelCase(f.name))
2179
- );
2268
+ const eqChecks = fields.length === 0 ? "true" : fields.map((f, index) => {
2269
+ const fieldName = camelCase(f.name);
2270
+ return isListManifest(fieldManifests[index].manifest) ? `_listEquals(${fieldName}, other.${fieldName})` : `${fieldName} == other.${fieldName}`;
2271
+ }).join(" &&\n ");
2272
+ const hashExpression = getValueHashExpression(fields, fieldManifests);
2273
+ if (fieldManifests.some(({ manifest }) => isListManifest(manifest))) {
2274
+ pageHasListEnums = true;
2275
+ }
2180
2276
  const toStringFields = fields.map((f) => `${camelCase(f.name)}: $${camelCase(f.name)}`).join(", ");
2181
2277
  variantClasses.push(`final class ${variantClassName} extends ${typeName} {
2182
2278
  ${ctorSignature}
@@ -2282,7 +2378,7 @@ sealed class ${fragmentFromString(typeName)} {
2282
2378
  const ${fragmentFromString(typeName)}();
2283
2379
  }
2284
2380
 
2285
- ${fragmentFromString(variantClasses.join("\n\n"))}
2381
+ ${fragmentFromString(variantClasses.join("\n\n"))}${pageHasListEnums ? LIST_VALUE_HELPERS : ""}
2286
2382
 
2287
2383
  Encoder<${fragmentFromString(typeName)}> ${fragmentFromString(encoderName)}() {
2288
2384
  return transformEncoder<Map<String, Object?>, ${fragmentFromString(typeName)}>(
@@ -2325,6 +2421,7 @@ function getStructPageFragment(node, scope) {
2325
2421
  const structNode = node.type;
2326
2422
  if (structNode.kind !== "structTypeNode") return emptyFragment();
2327
2423
  const fields = structNode.fields ?? [];
2424
+ let pageHasListStructs = false;
2328
2425
  const fieldManifests = fields.map((f) => ({
2329
2426
  field: f,
2330
2427
  manifest: visit(f.type, scope.typeManifestVisitor)
@@ -2336,10 +2433,13 @@ function getStructPageFragment(node, scope) {
2336
2433
  const ctorSignature = fields.length === 0 ? ` const ${typeName}();` : ` const ${typeName}({
2337
2434
  ${ctorParams}
2338
2435
  });`;
2339
- const eqChecks = fields.length === 0 ? "true" : fields.map(
2340
- (f) => `${camelCase(f.name)} == other.${camelCase(f.name)}`
2341
- ).join(" &&\n ");
2342
- fields.length === 0 ? "runtimeType" : fields.map((f) => camelCase(f.name)).join(", ");
2436
+ const eqChecks = fields.length === 0 ? "true" : fieldManifests.map(({ field: f, manifest }, index) => {
2437
+ const fieldName = camelCase(f.name);
2438
+ return isListManifest(manifest) ? `_listEquals(${fieldName}, other.${fieldName})` : `${fieldName} == other.${fieldName}`;
2439
+ }).join(" &&\n ");
2440
+ if (fieldManifests.some(({ manifest }) => isListManifest(manifest))) {
2441
+ pageHasListStructs = true;
2442
+ }
2343
2443
  const toStringFields = fields.map(
2344
2444
  (f) => `${camelCase(f.name)}: $${camelCase(f.name)}`
2345
2445
  ).join(", ");
@@ -2389,12 +2489,14 @@ ${fragmentFromString(fieldDecls)}
2389
2489
  ${fragmentFromString(eqChecks)};
2390
2490
 
2391
2491
  @override
2392
- int get hashCode => ${fragmentFromString(getHashExpression(fields.map((f) => camelCase(f.name))))};
2492
+ int get hashCode => ${fragmentFromString(
2493
+ getValueHashExpression(fields, fieldManifests)
2494
+ )};
2393
2495
 
2394
2496
  @override
2395
2497
  String toString() => '${fragmentFromString(typeName)}(${fragmentFromString(toStringFields)})';
2396
2498
  }
2397
-
2499
+ ${pageHasListStructs ? LIST_VALUE_HELPERS : ""}
2398
2500
  Encoder<${fragmentFromString(typeName)}> ${fragmentFromString(encoderName)}() {
2399
2501
  final structEncoder = getStructEncoder(<(String, Encoder<Object?>)>[
2400
2502
  ${fragmentFromString(encFields)}
@@ -2460,6 +2562,56 @@ Codec<${fragmentFromString(typeName)}, ${fragmentFromString(typeName)}> ${fragme
2460
2562
  return combineCodec(${fragmentFromString(encoderName)}(), ${fragmentFromString(decoderName)}());
2461
2563
  }`;
2462
2564
  }
2565
+ function isListManifest(manifest) {
2566
+ return manifest.type.content.startsWith("List<") || manifest.type.content === "Uint8List";
2567
+ }
2568
+ var LIST_VALUE_HELPERS = `
2569
+ bool _listEquals<T>(List<T>? a, List<T>? b) {
2570
+ if (identical(a, b)) return true;
2571
+ if (a == null || b == null) return a == b;
2572
+ if (a.length != b.length) return false;
2573
+ for (var i = 0; i < a.length; i++) {
2574
+ final left = a[i];
2575
+ final right = b[i];
2576
+ if (left is List<Object?> && right is List<Object?>) {
2577
+ if (!_listEquals(left, right)) return false;
2578
+ } else if (left != right) {
2579
+ return false;
2580
+ }
2581
+ }
2582
+ return true;
2583
+ }
2584
+
2585
+ Object? _deepHash(Object? value) {
2586
+ if (value is List<Object?>) {
2587
+ return Object.hashAll(value.map(_deepHash));
2588
+ }
2589
+ return value;
2590
+ }
2591
+
2592
+ int _listHashCode<T>(List<T>? a) {
2593
+ if (a == null) return 0;
2594
+ return Object.hashAll(a.map(_deepHash));
2595
+ }
2596
+ `;
2597
+ function getValueHashExpression(fields, fieldManifests) {
2598
+ const fieldNames = fields.map(
2599
+ (f) => camelCase(f.name)
2600
+ );
2601
+ const hasListFields = fieldManifests.some(
2602
+ ({ manifest }) => isListManifest(manifest)
2603
+ );
2604
+ if (!hasListFields) {
2605
+ return getHashExpression(fieldNames);
2606
+ }
2607
+ if (fieldNames.length === 1) {
2608
+ return `_listHashCode(${fieldNames[0]})`;
2609
+ }
2610
+ const hashArgs = fields.map(
2611
+ (f, index) => isListManifest(fieldManifests[index].manifest) ? `_listHashCode(${camelCase(f.name)})` : camelCase(f.name)
2612
+ );
2613
+ return `Object.hash(${hashArgs.join(", ")})`;
2614
+ }
2463
2615
  function getHashExpression(fields) {
2464
2616
  if (fields.length === 0) return "runtimeType.hashCode";
2465
2617
  if (fields.length === 1) return `${fields[0]}.hashCode`;