@sundaeswap/sprinkles 0.5.0 → 0.6.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 (112) hide show
  1. package/dist/cjs/Sprinkle/__tests__/encryption.test.js +3 -1
  2. package/dist/cjs/Sprinkle/__tests__/encryption.test.js.map +1 -1
  3. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js +3 -37
  4. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  5. package/dist/cjs/Sprinkle/__tests__/field-utils.test.js +170 -0
  6. package/dist/cjs/Sprinkle/__tests__/field-utils.test.js.map +1 -0
  7. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +242 -87
  8. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  9. package/dist/cjs/Sprinkle/__tests__/formatting.test.js +97 -0
  10. package/dist/cjs/Sprinkle/__tests__/formatting.test.js.map +1 -0
  11. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js +9 -5
  12. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  13. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +9 -0
  14. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  15. package/dist/cjs/Sprinkle/index.js +135 -91
  16. package/dist/cjs/Sprinkle/index.js.map +1 -1
  17. package/dist/cjs/Sprinkle/menus/array-menu.js +195 -0
  18. package/dist/cjs/Sprinkle/menus/array-menu.js.map +1 -0
  19. package/dist/cjs/Sprinkle/menus/field-menu.js +161 -0
  20. package/dist/cjs/Sprinkle/menus/field-menu.js.map +1 -0
  21. package/dist/cjs/Sprinkle/menus/index.js +33 -0
  22. package/dist/cjs/Sprinkle/menus/index.js.map +1 -0
  23. package/dist/cjs/Sprinkle/menus/object-menu.js +324 -0
  24. package/dist/cjs/Sprinkle/menus/object-menu.js.map +1 -0
  25. package/dist/cjs/Sprinkle/prompts.js +68 -2
  26. package/dist/cjs/Sprinkle/prompts.js.map +1 -1
  27. package/dist/cjs/Sprinkle/type-guards.js +48 -1
  28. package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
  29. package/dist/cjs/Sprinkle/types.js +24 -0
  30. package/dist/cjs/Sprinkle/types.js.map +1 -1
  31. package/dist/cjs/Sprinkle/utils/field-utils.js +154 -0
  32. package/dist/cjs/Sprinkle/utils/field-utils.js.map +1 -0
  33. package/dist/cjs/Sprinkle/utils/formatting.js +126 -0
  34. package/dist/cjs/Sprinkle/utils/formatting.js.map +1 -0
  35. package/dist/cjs/Sprinkle/utils/index.js +56 -0
  36. package/dist/cjs/Sprinkle/utils/index.js.map +1 -0
  37. package/dist/esm/Sprinkle/__tests__/encryption.test.js +3 -1
  38. package/dist/esm/Sprinkle/__tests__/encryption.test.js.map +1 -1
  39. package/dist/esm/Sprinkle/__tests__/enhancements.test.js +3 -37
  40. package/dist/esm/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  41. package/dist/esm/Sprinkle/__tests__/field-utils.test.js +168 -0
  42. package/dist/esm/Sprinkle/__tests__/field-utils.test.js.map +1 -0
  43. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +243 -88
  44. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  45. package/dist/esm/Sprinkle/__tests__/formatting.test.js +95 -0
  46. package/dist/esm/Sprinkle/__tests__/formatting.test.js.map +1 -0
  47. package/dist/esm/Sprinkle/__tests__/show-menu.test.js +9 -5
  48. package/dist/esm/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  49. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +9 -0
  50. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  51. package/dist/esm/Sprinkle/index.js +102 -93
  52. package/dist/esm/Sprinkle/index.js.map +1 -1
  53. package/dist/esm/Sprinkle/menus/array-menu.js +190 -0
  54. package/dist/esm/Sprinkle/menus/array-menu.js.map +1 -0
  55. package/dist/esm/Sprinkle/menus/field-menu.js +155 -0
  56. package/dist/esm/Sprinkle/menus/field-menu.js.map +1 -0
  57. package/dist/esm/Sprinkle/menus/index.js +8 -0
  58. package/dist/esm/Sprinkle/menus/index.js.map +1 -0
  59. package/dist/esm/Sprinkle/menus/object-menu.js +318 -0
  60. package/dist/esm/Sprinkle/menus/object-menu.js.map +1 -0
  61. package/dist/esm/Sprinkle/prompts.js +59 -1
  62. package/dist/esm/Sprinkle/prompts.js.map +1 -1
  63. package/dist/esm/Sprinkle/type-guards.js +42 -0
  64. package/dist/esm/Sprinkle/type-guards.js.map +1 -1
  65. package/dist/esm/Sprinkle/types.js +24 -0
  66. package/dist/esm/Sprinkle/types.js.map +1 -1
  67. package/dist/esm/Sprinkle/utils/field-utils.js +145 -0
  68. package/dist/esm/Sprinkle/utils/field-utils.js.map +1 -0
  69. package/dist/esm/Sprinkle/utils/formatting.js +118 -0
  70. package/dist/esm/Sprinkle/utils/formatting.js.map +1 -0
  71. package/dist/esm/Sprinkle/utils/index.js +7 -0
  72. package/dist/esm/Sprinkle/utils/index.js.map +1 -0
  73. package/dist/types/Sprinkle/index.d.ts +9 -3
  74. package/dist/types/Sprinkle/index.d.ts.map +1 -1
  75. package/dist/types/Sprinkle/menus/array-menu.d.ts +31 -0
  76. package/dist/types/Sprinkle/menus/array-menu.d.ts.map +1 -0
  77. package/dist/types/Sprinkle/menus/field-menu.d.ts +34 -0
  78. package/dist/types/Sprinkle/menus/field-menu.d.ts.map +1 -0
  79. package/dist/types/Sprinkle/menus/index.d.ts +10 -0
  80. package/dist/types/Sprinkle/menus/index.d.ts.map +1 -0
  81. package/dist/types/Sprinkle/menus/object-menu.d.ts +34 -0
  82. package/dist/types/Sprinkle/menus/object-menu.d.ts.map +1 -0
  83. package/dist/types/Sprinkle/prompts.d.ts +25 -0
  84. package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
  85. package/dist/types/Sprinkle/type-guards.d.ts +24 -1
  86. package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
  87. package/dist/types/Sprinkle/types.d.ts +53 -0
  88. package/dist/types/Sprinkle/types.d.ts.map +1 -1
  89. package/dist/types/Sprinkle/utils/field-utils.d.ts +47 -0
  90. package/dist/types/Sprinkle/utils/field-utils.d.ts.map +1 -0
  91. package/dist/types/Sprinkle/utils/formatting.d.ts +30 -0
  92. package/dist/types/Sprinkle/utils/formatting.d.ts.map +1 -0
  93. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  94. package/package.json +1 -1
  95. package/src/Sprinkle/__tests__/encryption.test.ts +2 -0
  96. package/src/Sprinkle/__tests__/enhancements.test.ts +3 -42
  97. package/src/Sprinkle/__tests__/field-utils.test.ts +191 -0
  98. package/src/Sprinkle/__tests__/fill-in-struct.test.ts +252 -103
  99. package/src/Sprinkle/__tests__/formatting.test.ts +115 -0
  100. package/src/Sprinkle/__tests__/show-menu.test.ts +14 -8
  101. package/src/Sprinkle/__tests__/tx-dialog.test.ts +9 -0
  102. package/src/Sprinkle/index.ts +131 -119
  103. package/src/Sprinkle/menus/array-menu.ts +191 -0
  104. package/src/Sprinkle/menus/field-menu.ts +145 -0
  105. package/src/Sprinkle/menus/index.ts +12 -0
  106. package/src/Sprinkle/menus/object-menu.ts +336 -0
  107. package/src/Sprinkle/prompts.ts +71 -1
  108. package/src/Sprinkle/type-guards.ts +42 -0
  109. package/src/Sprinkle/types.ts +43 -0
  110. package/src/Sprinkle/utils/field-utils.ts +158 -0
  111. package/src/Sprinkle/utils/formatting.ts +127 -0
  112. package/src/Sprinkle/utils/index.ts +17 -0
@@ -3,7 +3,8 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
4
  import { Core, HotWallet } from "@blaze-cardano/sdk";
5
5
  import { CborSet, VkeyWitness, TxCBOR } from "@blaze-cardano/core";
6
- import { selectCancellable, inputCancellable, passwordCancellable, confirmCancellable, searchCancellable } from "./prompts.js";
6
+ import { selectCancellable, selectWithClear, inputCancellable, inputWithClear, passwordWithClear, confirmCancellable, searchCancellable } from "./prompts.js";
7
+ import colors from "yoctocolors-cjs";
7
8
  import { OptionalKind } from "@sinclair/typebox";
8
9
  import * as fs from "fs";
9
10
  import * as path from "path";
@@ -18,7 +19,7 @@ import { UserCancelledError } from "./types.js";
18
19
  export { NetworkSchema, MultisigScriptModule, MultisigScript, ProviderSettingsSchema, WalletSettingsSchema } from "./schemas.js";
19
20
  // Import and re-export type guards
20
21
  import { isOptional, isImport, isArray, isBigInt, isLiteral, isObject, isRef, isString, isThis, isTuple, isUnion, isSensitive } from "./type-guards.js";
21
- export { isOptional, isImport, isArray, isBigInt, isLiteral, isObject, isRef, isString, isThis, isTuple, isUnion, isSensitive } from "./type-guards.js";
22
+ export { isOptional, isImport, isArray, isBigInt, isLiteral, isObject, isRef, isString, isThis, isTuple, isUnion, isSensitive, isNull, isNullable, unwrapNullable, hasDefault, getDefault } from "./type-guards.js";
22
23
 
23
24
  // Import schemas for use in this file
24
25
 
@@ -31,6 +32,10 @@ import { bigIntReplacer, bigIntReviver, encryptSensitiveFields, decryptSensitive
31
32
 
32
33
  // Import tx-dialog utilities
33
34
  import { countSignatures, getRequiredSigners, getTxBodyHash, formatHash, mergeSignatures } from "./tx-dialog.js";
35
+
36
+ // Import menu modules
37
+ import { promptObject, promptArray } from "./menus/index.js";
38
+ import { formatPath } from "./utils/formatting.js";
34
39
  export class Sprinkle {
35
40
  constructor(type, storagePath, options) {
36
41
  _defineProperty(this, "storagePath", void 0);
@@ -353,9 +358,13 @@ export class Sprinkle {
353
358
  // --- Menu ---
354
359
 
355
360
  async showMenu(menu) {
356
- return this._showMenu(menu, true);
361
+ return this._showMenu(menu, true, [menu.title]);
357
362
  }
358
- async _showMenu(menu, main) {
363
+ async _showMenu(menu, main, path, clearPrevious = false) {
364
+ // Clear previous breadcrumb if coming back from action/submenu
365
+ if (clearPrevious) {
366
+ process.stdout.write("\x1b[1A\x1b[2K\x1b[G");
367
+ }
359
368
  if (menu.beforeShow) {
360
369
  await menu.beforeShow(this);
361
370
  }
@@ -387,11 +396,16 @@ export class Sprinkle {
387
396
  value: -1
388
397
  });
389
398
  }
390
- const selectionResult = await selectCancellable({
399
+
400
+ // Show breadcrumb
401
+ const breadcrumb = path.join(" > ");
402
+ console.log(colors.dim("🍞 " + breadcrumb));
403
+ const selectionResult = await selectWithClear({
391
404
  message: "Select an option:",
392
405
  choices: choices
393
406
  });
394
407
  // Handle escape (null) as Back
408
+ // Don't clear here - let the caller's clearPrevious handle it
395
409
  if (selectionResult === null) {
396
410
  return;
397
411
  }
@@ -402,7 +416,21 @@ export class Sprinkle {
402
416
  items: [{
403
417
  title: "View settings",
404
418
  action: async () => {
405
- console.log(JSON.stringify(this.getDisplaySettings(), bigIntReplacer, 2));
419
+ const jsonStr = JSON.stringify(this.getDisplaySettings(), bigIntReplacer, 2);
420
+ const jsonLines = jsonStr.split("\n").length;
421
+ console.log(jsonStr);
422
+
423
+ // Wait for user to press Enter
424
+ await selectWithClear({
425
+ message: "Press Enter to continue...",
426
+ choices: [{
427
+ name: "Continue",
428
+ value: "continue"
429
+ }]
430
+ });
431
+
432
+ // Clear the JSON output
433
+ process.stdout.write("\x1b[1A\x1b[2K".repeat(jsonLines) + "\x1b[G");
406
434
  }
407
435
  }, {
408
436
  title: "Edit settings",
@@ -443,24 +471,28 @@ export class Sprinkle {
443
471
  }
444
472
  }]
445
473
  };
446
- await this._showMenu(settingsMenu, false);
447
- await this._showMenu(menu, main);
474
+ await this._showMenu(settingsMenu, false, [...path, "Settings & Profiles"], true);
475
+ await this._showMenu(menu, main, path, true);
448
476
  return;
449
477
  }
450
478
  if (selection === -1) {
479
+ // Don't clear here - let the caller's clearPrevious handle it
451
480
  return;
452
481
  }
453
482
  const selectedItem = menu.items[selection];
454
483
  if ("action" in selectedItem) {
484
+ // Update breadcrumb to show current action
485
+ process.stdout.write("\x1b[1A\x1b[2K\x1b[G");
486
+ console.log(colors.dim("🍞 " + [...path, selectedItem.title].join(" > ")));
455
487
  const result = await selectedItem.action(this);
456
488
  if (result instanceof Sprinkle) {
457
489
  this.settings = result.settings;
458
490
  this.saveSettings();
459
491
  }
460
- await this._showMenu(menu, main);
492
+ await this._showMenu(menu, main, path, true);
461
493
  } else {
462
- await this._showMenu(selectedItem, false);
463
- await this._showMenu(menu, main);
494
+ await this._showMenu(selectedItem, false, [...path, selectedItem.title], true);
495
+ await this._showMenu(menu, main, path, true);
464
496
  }
465
497
  return;
466
498
  }
@@ -615,7 +647,7 @@ export class Sprinkle {
615
647
  name: "Cancel",
616
648
  value: "cancel"
617
649
  });
618
- const selection = await selectCancellable({
650
+ const selection = await selectWithClear({
619
651
  message: "Select an option:",
620
652
  choices
621
653
  });
@@ -813,46 +845,18 @@ export class Sprinkle {
813
845
  }
814
846
  }
815
847
  }
848
+
849
+ /**
850
+ * Edit an existing struct value using a menu-based interface.
851
+ * This is now unified with FillInStruct - both use the same menu system.
852
+ * @param type - The TypeBox schema
853
+ * @param current - The current value to edit
854
+ * @returns The edited value
855
+ */
816
856
  async EditStruct(type, current) {
817
- return this._editStruct(type, ["root"], current);
818
- }
819
- async _editStruct(type, path, current) {
820
- if (isObject(type)) {
821
- const obj = {};
822
- const fields = type["properties"];
823
- const menuItems = [];
824
- const currentRecord = current;
825
- for (const [field, fieldType] of Object.entries(fields)) {
826
- if (current && field in currentRecord) {
827
- obj[field] = currentRecord[field];
828
- }
829
- const menuTitle = Sprinkle.ExtractMessage(fieldType, `Edit ${field} at ${path.join(".")}`);
830
- if (isOptional(fieldType) && current && currentRecord[field] !== undefined) {
831
- menuItems.push({
832
- title: `Clear ${field}`,
833
- action: async sprinkle => {
834
- obj[field] = undefined;
835
- return sprinkle;
836
- }
837
- });
838
- }
839
- menuItems.push({
840
- title: menuTitle,
841
- action: async sprinkle => {
842
- const fieldValue = await sprinkle._editStruct(fieldType, path.concat([field]), current && field in currentRecord ? currentRecord[field] : undefined);
843
- obj[field] = fieldValue;
844
- return sprinkle;
845
- }
846
- });
847
- }
848
- const editMenu = {
849
- title: "Test",
850
- items: menuItems
851
- };
852
- await this._showMenu(editMenu, false);
853
- return obj;
854
- }
855
- return this._fillInStruct(type, path, {}, current);
857
+ // Use FillInStruct with current values as defaults
858
+ // The menu system will show existing values and allow editing
859
+ return this.FillInStruct(type, current);
856
860
  }
857
861
  async FillInStruct(type, def) {
858
862
  return this._fillInStruct(type, ["root"], {}, def);
@@ -870,8 +874,9 @@ export class Sprinkle {
870
874
  return this._fillInStruct(resolvedType, path, defs, def);
871
875
  }
872
876
  if (isOptional(type)) {
873
- const shouldSet = await selectCancellable({
874
- message: Sprinkle.ExtractMessage(type, `Set value for ${path.join(".")}?`),
877
+ const pathDisplay = formatPath(path) || "value";
878
+ const shouldSet = await selectWithClear({
879
+ message: Sprinkle.ExtractMessage(type, `Set value for ${pathDisplay}?`),
875
880
  choices: [{
876
881
  name: "Yes",
877
882
  value: true
@@ -895,6 +900,7 @@ export class Sprinkle {
895
900
  return this._fillInStruct(innerType, path, defs, def);
896
901
  }
897
902
  if (isUnion(type)) {
903
+ const pathDisplay = formatPath(path) || "value";
898
904
  const choices = [];
899
905
  const resolved = this.resolveType(type, path, defs);
900
906
  for (const variant of resolved.anyOf) {
@@ -903,10 +909,9 @@ export class Sprinkle {
903
909
  value: variant
904
910
  });
905
911
  }
906
- const selectionResult = await selectCancellable({
907
- message: Sprinkle.ExtractMessage(resolved, `Enter a choice for ${path.join(".")}`),
908
- choices: choices,
909
- default: def ? `${def}` : undefined
912
+ const selectionResult = await selectWithClear({
913
+ message: Sprinkle.ExtractMessage(resolved, `Enter a choice for ${pathDisplay}`),
914
+ choices: choices
910
915
  });
911
916
  if (selectionResult === null) {
912
917
  throw new UserCancelledError();
@@ -917,7 +922,7 @@ export class Sprinkle {
917
922
  if (isString(type)) {
918
923
  // Special handling for hot wallet private key - offer generation option
919
924
  if (type.title === "Hot Wallet Private Key") {
920
- const choice = await selectCancellable({
925
+ const choice = await selectWithClear({
921
926
  message: "Hot wallet setup:",
922
927
  choices: [{
923
928
  name: "Enter existing private key",
@@ -934,7 +939,7 @@ export class Sprinkle {
934
939
  return Sprinkle.generateWalletFromMnemonic();
935
940
  }
936
941
  // Fall through to password prompt for "existing" choice
937
- const answer = await passwordCancellable({
942
+ const answer = await passwordWithClear({
938
943
  message: "Enter your private key:"
939
944
  });
940
945
  if (answer === null) {
@@ -942,15 +947,16 @@ export class Sprinkle {
942
947
  }
943
948
  return answer;
944
949
  }
950
+ const pathDisplay = formatPath(path) || "value";
945
951
  const defaultString = def ? def : this.defaults["string"];
946
- const message = Sprinkle.ExtractMessage(type, `Enter a string for ${path.join(".")}`);
952
+ const message = Sprinkle.ExtractMessage(type, `Enter a string for ${pathDisplay}`);
947
953
  let answer;
948
954
  if (isSensitive(type)) {
949
- answer = await passwordCancellable({
955
+ answer = await passwordWithClear({
950
956
  message
951
957
  });
952
958
  } else {
953
- answer = await inputCancellable({
959
+ answer = await inputWithClear({
954
960
  message,
955
961
  default: defaultString
956
962
  });
@@ -964,8 +970,9 @@ export class Sprinkle {
964
970
  return answer;
965
971
  }
966
972
  if (isBigInt(type)) {
967
- const answer = await inputCancellable({
968
- message: Sprinkle.ExtractMessage(type, `Enter a bigint for ${path.join(".")}`),
973
+ const pathDisplay = formatPath(path) || "value";
974
+ const answer = await inputWithClear({
975
+ message: Sprinkle.ExtractMessage(type, `Enter a bigint for ${pathDisplay}`),
969
976
  default: def ? def.toString() : undefined,
970
977
  validate: s => {
971
978
  try {
@@ -985,39 +992,40 @@ export class Sprinkle {
985
992
  return type.const;
986
993
  }
987
994
  if (isObject(type)) {
988
- const obj = {};
989
- const fields = type["properties"];
990
- for (const [field, fieldType] of Object.entries(fields)) {
991
- const fieldValue = await this._fillInStruct(fieldType, path.concat([field]), defs, def ? def[field] : undefined);
992
- obj[field] = fieldValue;
995
+ // Use menu-based editing for objects
996
+ const defaults = def;
997
+ const sprinkle = this;
998
+ const result = await promptObject({
999
+ type,
1000
+ path,
1001
+ defs,
1002
+ defaults,
1003
+ fillField: async (fieldType, fieldPath, fieldDefs, fieldDef) => {
1004
+ return sprinkle._fillInStruct(fieldType, fieldPath, fieldDefs, fieldDef);
1005
+ }
1006
+ });
1007
+ if (result.action === "cancel") {
1008
+ throw new UserCancelledError();
993
1009
  }
994
- return obj;
1010
+ return result.value;
995
1011
  }
996
-
997
- //TODO: support starting with default values for arrays and allow removal of items
998
1012
  if (isArray(type)) {
999
- const arr = [];
1000
- const itemType = type.items;
1001
- let addMore = true;
1002
- while (addMore) {
1003
- const itemValue = await this._fillInStruct(itemType, path.concat([`[${arr.length}]`]), defs);
1004
- arr.push(itemValue);
1005
- const continueAnswer = await selectCancellable({
1006
- message: `Add another item to ${path.join(".")}?`,
1007
- choices: [{
1008
- name: "Yes",
1009
- value: true
1010
- }, {
1011
- name: "No",
1012
- value: false
1013
- }]
1014
- });
1015
- if (continueAnswer === null) {
1016
- throw new UserCancelledError();
1013
+ // Use menu-based editing for arrays
1014
+ const defaults = def;
1015
+ const sprinkle = this;
1016
+ const result = await promptArray({
1017
+ type,
1018
+ path,
1019
+ defs,
1020
+ defaults,
1021
+ fillField: async (itemType, itemPath, itemDefs, itemDef) => {
1022
+ return sprinkle._fillInStruct(itemType, itemPath, itemDefs, itemDef);
1017
1023
  }
1018
- addMore = continueAnswer;
1024
+ });
1025
+ if (result.action === "back") {
1026
+ throw new UserCancelledError();
1019
1027
  }
1020
- return arr;
1028
+ return result.value;
1021
1029
  }
1022
1030
  if (isTuple(type)) {
1023
1031
  const items = type.items ?? [];
@@ -1029,7 +1037,8 @@ export class Sprinkle {
1029
1037
  }
1030
1038
  return result;
1031
1039
  }
1032
- throw new Error(`Unable to fill in struct for type at path ${path.join(".")}`);
1040
+ const pathDisplay = formatPath(path) || "root";
1041
+ throw new Error(`Unable to fill in struct for type at path ${pathDisplay}`);
1033
1042
  }
1034
1043
  resolveType(type, path, defs) {
1035
1044
  if (isRef(type) || isThis(type) || isImport(type)) {