@sundaeswap/sprinkles 0.4.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.
- package/dist/cjs/Sprinkle/__tests__/encryption.test.js +22 -8
- package/dist/cjs/Sprinkle/__tests__/encryption.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/enhancements.test.js +37 -46
- package/dist/cjs/Sprinkle/__tests__/enhancements.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/field-utils.test.js +170 -0
- package/dist/cjs/Sprinkle/__tests__/field-utils.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +283 -81
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/formatting.test.js +97 -0
- package/dist/cjs/Sprinkle/__tests__/formatting.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/show-menu.test.js +97 -7
- package/dist/cjs/Sprinkle/__tests__/show-menu.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +30 -0
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/cjs/Sprinkle/encryption.js +131 -0
- package/dist/cjs/Sprinkle/encryption.js.map +1 -0
- package/dist/cjs/Sprinkle/index.js +427 -438
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/menus/array-menu.js +195 -0
- package/dist/cjs/Sprinkle/menus/array-menu.js.map +1 -0
- package/dist/cjs/Sprinkle/menus/field-menu.js +161 -0
- package/dist/cjs/Sprinkle/menus/field-menu.js.map +1 -0
- package/dist/cjs/Sprinkle/menus/index.js +33 -0
- package/dist/cjs/Sprinkle/menus/index.js.map +1 -0
- package/dist/cjs/Sprinkle/menus/object-menu.js +324 -0
- package/dist/cjs/Sprinkle/menus/object-menu.js.map +1 -0
- package/dist/cjs/Sprinkle/prompts.js +459 -0
- package/dist/cjs/Sprinkle/prompts.js.map +1 -0
- package/dist/cjs/Sprinkle/schemas.js +97 -0
- package/dist/cjs/Sprinkle/schemas.js.map +1 -0
- package/dist/cjs/Sprinkle/tx-dialog.js +101 -0
- package/dist/cjs/Sprinkle/tx-dialog.js.map +1 -0
- package/dist/cjs/Sprinkle/type-guards.js +89 -0
- package/dist/cjs/Sprinkle/type-guards.js.map +1 -0
- package/dist/cjs/Sprinkle/types.js +73 -0
- package/dist/cjs/Sprinkle/types.js.map +1 -0
- package/dist/cjs/Sprinkle/utils/field-utils.js +154 -0
- package/dist/cjs/Sprinkle/utils/field-utils.js.map +1 -0
- package/dist/cjs/Sprinkle/utils/formatting.js +126 -0
- package/dist/cjs/Sprinkle/utils/formatting.js.map +1 -0
- package/dist/cjs/Sprinkle/utils/index.js +56 -0
- package/dist/cjs/Sprinkle/utils/index.js.map +1 -0
- package/dist/cjs/Sprinkle/wallet.js +98 -0
- package/dist/cjs/Sprinkle/wallet.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/encryption.test.js +22 -8
- package/dist/esm/Sprinkle/__tests__/encryption.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/enhancements.test.js +37 -46
- package/dist/esm/Sprinkle/__tests__/enhancements.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/field-utils.test.js +168 -0
- package/dist/esm/Sprinkle/__tests__/field-utils.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +284 -82
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/formatting.test.js +95 -0
- package/dist/esm/Sprinkle/__tests__/formatting.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/show-menu.test.js +98 -8
- package/dist/esm/Sprinkle/__tests__/show-menu.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +30 -0
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/esm/Sprinkle/encryption.js +117 -0
- package/dist/esm/Sprinkle/encryption.js.map +1 -0
- package/dist/esm/Sprinkle/index.js +248 -425
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/menus/array-menu.js +190 -0
- package/dist/esm/Sprinkle/menus/array-menu.js.map +1 -0
- package/dist/esm/Sprinkle/menus/field-menu.js +155 -0
- package/dist/esm/Sprinkle/menus/field-menu.js.map +1 -0
- package/dist/esm/Sprinkle/menus/index.js +8 -0
- package/dist/esm/Sprinkle/menus/index.js.map +1 -0
- package/dist/esm/Sprinkle/menus/object-menu.js +318 -0
- package/dist/esm/Sprinkle/menus/object-menu.js.map +1 -0
- package/dist/esm/Sprinkle/prompts.js +443 -0
- package/dist/esm/Sprinkle/prompts.js.map +1 -0
- package/dist/esm/Sprinkle/schemas.js +91 -0
- package/dist/esm/Sprinkle/schemas.js.map +1 -0
- package/dist/esm/Sprinkle/tx-dialog.js +90 -0
- package/dist/esm/Sprinkle/tx-dialog.js.map +1 -0
- package/dist/esm/Sprinkle/type-guards.js +66 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -0
- package/dist/esm/Sprinkle/types.js +66 -0
- package/dist/esm/Sprinkle/types.js.map +1 -0
- package/dist/esm/Sprinkle/utils/field-utils.js +145 -0
- package/dist/esm/Sprinkle/utils/field-utils.js.map +1 -0
- package/dist/esm/Sprinkle/utils/formatting.js +118 -0
- package/dist/esm/Sprinkle/utils/formatting.js.map +1 -0
- package/dist/esm/Sprinkle/utils/index.js +7 -0
- package/dist/esm/Sprinkle/utils/index.js.map +1 -0
- package/dist/esm/Sprinkle/wallet.js +90 -0
- package/dist/esm/Sprinkle/wallet.js.map +1 -0
- package/dist/types/Sprinkle/encryption.d.ts +43 -0
- package/dist/types/Sprinkle/encryption.d.ts.map +1 -0
- package/dist/types/Sprinkle/index.d.ts +17 -177
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/menus/array-menu.d.ts +31 -0
- package/dist/types/Sprinkle/menus/array-menu.d.ts.map +1 -0
- package/dist/types/Sprinkle/menus/field-menu.d.ts +34 -0
- package/dist/types/Sprinkle/menus/field-menu.d.ts.map +1 -0
- package/dist/types/Sprinkle/menus/index.d.ts +10 -0
- package/dist/types/Sprinkle/menus/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/menus/object-menu.d.ts +34 -0
- package/dist/types/Sprinkle/menus/object-menu.d.ts.map +1 -0
- package/dist/types/Sprinkle/prompts.d.ts +119 -0
- package/dist/types/Sprinkle/prompts.d.ts.map +1 -0
- package/dist/types/Sprinkle/schemas.d.ts +125 -0
- package/dist/types/Sprinkle/schemas.d.ts.map +1 -0
- package/dist/types/Sprinkle/tx-dialog.d.ts +37 -0
- package/dist/types/Sprinkle/tx-dialog.d.ts.map +1 -0
- package/dist/types/Sprinkle/type-guards.d.ts +45 -0
- package/dist/types/Sprinkle/type-guards.d.ts.map +1 -0
- package/dist/types/Sprinkle/types.d.ts +115 -0
- package/dist/types/Sprinkle/types.d.ts.map +1 -0
- package/dist/types/Sprinkle/utils/field-utils.d.ts +47 -0
- package/dist/types/Sprinkle/utils/field-utils.d.ts.map +1 -0
- package/dist/types/Sprinkle/utils/formatting.d.ts +30 -0
- package/dist/types/Sprinkle/utils/formatting.d.ts.map +1 -0
- package/dist/types/Sprinkle/wallet.d.ts +27 -0
- package/dist/types/Sprinkle/wallet.d.ts.map +1 -0
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Sprinkle/__tests__/encryption.test.ts +23 -8
- package/src/Sprinkle/__tests__/enhancements.test.ts +34 -47
- package/src/Sprinkle/__tests__/field-utils.test.ts +191 -0
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +301 -86
- package/src/Sprinkle/__tests__/formatting.test.ts +115 -0
- package/src/Sprinkle/__tests__/show-menu.test.ts +102 -8
- package/src/Sprinkle/__tests__/tx-dialog.test.ts +30 -0
- package/src/Sprinkle/encryption.ts +130 -0
- package/src/Sprinkle/index.ts +368 -598
- package/src/Sprinkle/menus/array-menu.ts +191 -0
- package/src/Sprinkle/menus/field-menu.ts +145 -0
- package/src/Sprinkle/menus/index.ts +12 -0
- package/src/Sprinkle/menus/object-menu.ts +336 -0
- package/src/Sprinkle/prompts.ts +551 -0
- package/src/Sprinkle/schemas.ts +111 -0
- package/src/Sprinkle/tx-dialog.ts +100 -0
- package/src/Sprinkle/type-guards.ts +93 -0
- package/src/Sprinkle/types.ts +116 -0
- package/src/Sprinkle/utils/field-utils.ts +158 -0
- package/src/Sprinkle/utils/formatting.ts +127 -0
- package/src/Sprinkle/utils/index.ts +17 -0
- package/src/Sprinkle/wallet.ts +133 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.promptObject = promptObject;
|
|
7
|
+
var _core = require("@inquirer/core");
|
|
8
|
+
var _prompts = require("../prompts.js");
|
|
9
|
+
var _yoctocolorsCjs = _interopRequireDefault(require("yoctocolors-cjs"));
|
|
10
|
+
var _types = require("../types.js");
|
|
11
|
+
var _typeGuards = require("../type-guards.js");
|
|
12
|
+
var _fieldUtils = require("../utils/field-utils.js");
|
|
13
|
+
var _formatting = require("../utils/formatting.js");
|
|
14
|
+
var _fieldMenu = require("./field-menu.js");
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
/**
|
|
17
|
+
* Object menu module for menu-based struct editing.
|
|
18
|
+
* Shows all fields of an object and allows non-linear editing.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Type for the fill function that handles individual field types.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Options for the object menu prompt.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Show a menu-based editor for an object.
|
|
31
|
+
* Allows non-linear editing of fields with Submit/Cancel.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Object menu options
|
|
34
|
+
* @returns The edited object or cancel result
|
|
35
|
+
*/
|
|
36
|
+
async function promptObject(options) {
|
|
37
|
+
const {
|
|
38
|
+
type,
|
|
39
|
+
path,
|
|
40
|
+
defs,
|
|
41
|
+
defaults = {},
|
|
42
|
+
fillField
|
|
43
|
+
} = options;
|
|
44
|
+
const fields = type.properties;
|
|
45
|
+
const fieldNames = Object.keys(fields);
|
|
46
|
+
|
|
47
|
+
// Edge case: empty struct
|
|
48
|
+
if (fieldNames.length === 0) {
|
|
49
|
+
return {
|
|
50
|
+
action: "submit",
|
|
51
|
+
value: {}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Edge case: single required field with no optionals - skip menu
|
|
56
|
+
const requiredFields = fieldNames.filter(name => (0, _fieldUtils.isFieldRequired)(fields[name]));
|
|
57
|
+
const optionalFields = fieldNames.filter(name => !(0, _fieldUtils.isFieldRequired)(fields[name]));
|
|
58
|
+
if (requiredFields.length === 1 && optionalFields.length === 0) {
|
|
59
|
+
const fieldName = requiredFields[0];
|
|
60
|
+
const fieldType = fields[fieldName];
|
|
61
|
+
try {
|
|
62
|
+
const value = await fillField(fieldType, [...path, fieldName], defs, defaults[fieldName]);
|
|
63
|
+
return {
|
|
64
|
+
action: "submit",
|
|
65
|
+
value: {
|
|
66
|
+
[fieldName]: value
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
} catch (e) {
|
|
70
|
+
if (e instanceof _types.UserCancelledError) {
|
|
71
|
+
return {
|
|
72
|
+
action: "cancel"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Initialize state for all fields
|
|
80
|
+
const state = new Map();
|
|
81
|
+
for (const fieldName of fieldNames) {
|
|
82
|
+
const fieldType = fields[fieldName];
|
|
83
|
+
// Auto-fill Literal fields with their const value
|
|
84
|
+
if ((0, _typeGuards.isLiteral)(fieldType)) {
|
|
85
|
+
state.set(fieldName, {
|
|
86
|
+
status: "set",
|
|
87
|
+
value: fieldType.const
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
state.set(fieldName, (0, _fieldUtils.getInitialFieldState)(fieldType, defaults[fieldName]));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Main menu loop
|
|
95
|
+
while (true) {
|
|
96
|
+
const {
|
|
97
|
+
total,
|
|
98
|
+
filled
|
|
99
|
+
} = (0, _fieldUtils.countRequiredFields)(type, state);
|
|
100
|
+
const canSubmit = (0, _fieldUtils.allRequiredFieldsFilled)(type, state);
|
|
101
|
+
|
|
102
|
+
// Build menu choices
|
|
103
|
+
const choices = [];
|
|
104
|
+
|
|
105
|
+
// Add field items
|
|
106
|
+
for (const fieldName of fieldNames) {
|
|
107
|
+
const fieldType = fields[fieldName];
|
|
108
|
+
const fieldState = state.get(fieldName);
|
|
109
|
+
const label = (0, _fieldUtils.buildFieldLabel)(fieldName, fieldType, fieldState);
|
|
110
|
+
choices.push({
|
|
111
|
+
name: label,
|
|
112
|
+
value: `field:${fieldName}`
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Add separator and actions
|
|
117
|
+
choices.push(new _core.Separator("\u2500\u2500\u2500 Actions \u2500\u2500\u2500"));
|
|
118
|
+
|
|
119
|
+
// Submit button
|
|
120
|
+
if (canSubmit) {
|
|
121
|
+
choices.push({
|
|
122
|
+
name: "Submit",
|
|
123
|
+
value: "submit"
|
|
124
|
+
});
|
|
125
|
+
} else {
|
|
126
|
+
choices.push({
|
|
127
|
+
name: `Submit (${filled} of ${total} required complete)`,
|
|
128
|
+
value: "submit",
|
|
129
|
+
disabled: true
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
choices.push({
|
|
133
|
+
name: "Cancel",
|
|
134
|
+
value: "cancel"
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Show breadcrumb header if we're in a nested path
|
|
138
|
+
const breadcrumb = (0, _formatting.formatBreadcrumb)(path);
|
|
139
|
+
if (breadcrumb) {
|
|
140
|
+
console.log(_yoctocolorsCjs.default.dim(`📍 ${breadcrumb}`));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Show menu
|
|
144
|
+
const selection = await (0, _prompts.selectWithClear)({
|
|
145
|
+
message: "Edit:",
|
|
146
|
+
choices
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Clear the breadcrumb line too if we printed one
|
|
150
|
+
if (breadcrumb) {
|
|
151
|
+
(0, _prompts.clearLines)(1);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Handle escape
|
|
155
|
+
if (selection === null) {
|
|
156
|
+
// Check if any values have been set
|
|
157
|
+
const hasValues = Array.from(state.values()).some(s => s.status === "set" || s.status === "null");
|
|
158
|
+
if (hasValues) {
|
|
159
|
+
const confirmCancel = await (0, _prompts.confirmWithClear)({
|
|
160
|
+
message: "Discard changes?",
|
|
161
|
+
default: false
|
|
162
|
+
});
|
|
163
|
+
if (confirmCancel === null || confirmCancel === false) {
|
|
164
|
+
continue; // Return to menu
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
action: "cancel"
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Handle submit
|
|
173
|
+
if (selection === "submit") {
|
|
174
|
+
if (!canSubmit) {
|
|
175
|
+
continue; // Shouldn't happen due to disabled, but be safe
|
|
176
|
+
}
|
|
177
|
+
const result = buildResultObject(fields, state, defs);
|
|
178
|
+
return {
|
|
179
|
+
action: "submit",
|
|
180
|
+
value: result
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Handle cancel
|
|
185
|
+
if (selection === "cancel") {
|
|
186
|
+
const hasValues = Array.from(state.values()).some(s => s.status === "set" || s.status === "null");
|
|
187
|
+
if (hasValues) {
|
|
188
|
+
const confirmCancel = await (0, _prompts.confirmWithClear)({
|
|
189
|
+
message: "Discard changes?",
|
|
190
|
+
default: false
|
|
191
|
+
});
|
|
192
|
+
if (confirmCancel === null || confirmCancel === false) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
action: "cancel"
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Handle field selection
|
|
202
|
+
if (typeof selection === "string" && selection.startsWith("field:")) {
|
|
203
|
+
const fieldName = selection.slice(6);
|
|
204
|
+
const fieldType = fields[fieldName];
|
|
205
|
+
const fieldState = state.get(fieldName);
|
|
206
|
+
|
|
207
|
+
// If field has a value, show field sub-menu
|
|
208
|
+
if (fieldState.status === "set" || fieldState.status === "null") {
|
|
209
|
+
const menuResult = await (0, _fieldMenu.promptFieldMenu)({
|
|
210
|
+
fieldName,
|
|
211
|
+
fieldType,
|
|
212
|
+
state: fieldState
|
|
213
|
+
});
|
|
214
|
+
switch (menuResult.action) {
|
|
215
|
+
case "edit":
|
|
216
|
+
{
|
|
217
|
+
// Edit the field
|
|
218
|
+
try {
|
|
219
|
+
const newValue = await fillField(fieldType, [...path, fieldName], defs, fieldState.status === "set" ? fieldState.value : undefined);
|
|
220
|
+
state.set(fieldName, {
|
|
221
|
+
status: "set",
|
|
222
|
+
value: newValue
|
|
223
|
+
});
|
|
224
|
+
} catch (e) {
|
|
225
|
+
if (e instanceof _types.UserCancelledError) {
|
|
226
|
+
// Return to menu without changing
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case "view":
|
|
234
|
+
{
|
|
235
|
+
if (fieldState.status === "set") {
|
|
236
|
+
await (0, _fieldMenu.displayFullValue)(fieldName, fieldState.value);
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case "clear":
|
|
241
|
+
{
|
|
242
|
+
state.set(fieldName, {
|
|
243
|
+
status: "unset"
|
|
244
|
+
});
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case "setNull":
|
|
248
|
+
{
|
|
249
|
+
state.set(fieldName, {
|
|
250
|
+
status: "null"
|
|
251
|
+
});
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case "reset":
|
|
255
|
+
{
|
|
256
|
+
// Reset to default value - show as unset, will use default on submit
|
|
257
|
+
state.set(fieldName, {
|
|
258
|
+
status: "unset"
|
|
259
|
+
});
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case "back":
|
|
263
|
+
// Do nothing, return to main menu
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
// Field is unset - directly prompt for value
|
|
268
|
+
try {
|
|
269
|
+
const newValue = await fillField(fieldType, [...path, fieldName], defs, defaults[fieldName]);
|
|
270
|
+
// If user skipped an optional field (returned undefined), leave as unset
|
|
271
|
+
if (newValue === undefined) {
|
|
272
|
+
// Don't change state - field remains unset
|
|
273
|
+
} else {
|
|
274
|
+
state.set(fieldName, {
|
|
275
|
+
status: "set",
|
|
276
|
+
value: newValue
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
if (e instanceof _types.UserCancelledError) {
|
|
281
|
+
// Return to menu without changing
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
throw e;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Build the result object from the state map.
|
|
293
|
+
* Applies defaults for unset fields with defaults.
|
|
294
|
+
*/
|
|
295
|
+
function buildResultObject(fields, state, _defs) {
|
|
296
|
+
const result = {};
|
|
297
|
+
for (const [fieldName, fieldType] of Object.entries(fields)) {
|
|
298
|
+
const fieldState = state.get(fieldName);
|
|
299
|
+
if (!fieldState || fieldState.status === "unset") {
|
|
300
|
+
// If optional, skip (undefined)
|
|
301
|
+
if ((0, _typeGuards.isOptional)(fieldType)) {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// If field has a default, use it
|
|
306
|
+
if ((0, _typeGuards.hasDefault)(fieldType)) {
|
|
307
|
+
result[fieldName] = (0, _typeGuards.getDefault)(fieldType);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// No value, no default: omit from output
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (fieldState.status === "null") {
|
|
315
|
+
result[fieldName] = null;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (fieldState.status === "set") {
|
|
319
|
+
result[fieldName] = fieldState.value;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=object-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-menu.js","names":["_core","require","_prompts","_yoctocolorsCjs","_interopRequireDefault","_types","_typeGuards","_fieldUtils","_formatting","_fieldMenu","e","__esModule","default","promptObject","options","type","path","defs","defaults","fillField","fields","properties","fieldNames","Object","keys","length","action","value","requiredFields","filter","name","isFieldRequired","optionalFields","fieldName","fieldType","UserCancelledError","state","Map","isLiteral","set","status","const","getInitialFieldState","total","filled","countRequiredFields","canSubmit","allRequiredFieldsFilled","choices","fieldState","get","label","buildFieldLabel","push","Separator","disabled","breadcrumb","formatBreadcrumb","console","log","colors","dim","selection","selectWithClear","message","clearLines","hasValues","Array","from","values","some","s","confirmCancel","confirmWithClear","result","buildResultObject","startsWith","slice","menuResult","promptFieldMenu","newValue","undefined","displayFullValue","_defs","entries","isOptional","hasDefault","getDefault"],"sources":["../../../../src/Sprinkle/menus/object-menu.ts"],"sourcesContent":["/**\n * Object menu module for menu-based struct editing.\n * Shows all fields of an object and allows non-linear editing.\n */\n\nimport { Separator } from \"@inquirer/core\";\nimport type { TObject, TSchema } from \"@sinclair/typebox\";\nimport { selectWithClear, confirmWithClear, clearLines } from \"../prompts.js\";\nimport colors from \"yoctocolors-cjs\";\nimport type { FieldState, ObjectMenuResult } from \"../types.js\";\nimport { UserCancelledError } from \"../types.js\";\nimport { isOptional, hasDefault, getDefault, isNullable, isLiteral } from \"../type-guards.js\";\nimport {\n buildFieldLabel,\n countRequiredFields,\n allRequiredFieldsFilled,\n getInitialFieldState,\n isFieldRequired,\n} from \"../utils/field-utils.js\";\nimport { formatBreadcrumb } from \"../utils/formatting.js\";\nimport { promptFieldMenu, displayFullValue } from \"./field-menu.js\";\n\n/**\n * Type for the fill function that handles individual field types.\n */\nexport type FillFunction = <U extends TSchema>(\n type: U,\n path: string[],\n defs: Record<string, TSchema>,\n def?: unknown,\n) => Promise<unknown>;\n\n/**\n * Options for the object menu prompt.\n */\nexport interface ObjectMenuOptions {\n /** The object schema */\n type: TObject;\n /** Current path for display */\n path: string[];\n /** Type definitions for resolving refs */\n defs: Record<string, TSchema>;\n /** Default/existing values */\n defaults?: Record<string, unknown>;\n /** Function to fill individual fields */\n fillField: FillFunction;\n}\n\n/**\n * Show a menu-based editor for an object.\n * Allows non-linear editing of fields with Submit/Cancel.\n *\n * @param options - Object menu options\n * @returns The edited object or cancel result\n */\nexport async function promptObject<T extends Record<string, unknown>>(\n options: ObjectMenuOptions,\n): Promise<ObjectMenuResult<T>> {\n const { type, path, defs, defaults = {}, fillField } = options;\n\n const fields = type.properties as Record<string, TSchema>;\n const fieldNames = Object.keys(fields);\n\n // Edge case: empty struct\n if (fieldNames.length === 0) {\n return { action: \"submit\", value: {} as T };\n }\n\n // Edge case: single required field with no optionals - skip menu\n const requiredFields = fieldNames.filter((name) =>\n isFieldRequired(fields[name]!),\n );\n const optionalFields = fieldNames.filter(\n (name) => !isFieldRequired(fields[name]!),\n );\n\n if (requiredFields.length === 1 && optionalFields.length === 0) {\n const fieldName = requiredFields[0]!;\n const fieldType = fields[fieldName]!;\n try {\n const value = await fillField(\n fieldType,\n [...path, fieldName],\n defs,\n defaults[fieldName],\n );\n return {\n action: \"submit\",\n value: { [fieldName]: value } as T,\n };\n } catch (e) {\n if (e instanceof UserCancelledError) {\n return { action: \"cancel\" };\n }\n throw e;\n }\n }\n\n // Initialize state for all fields\n const state = new Map<string, FieldState>();\n for (const fieldName of fieldNames) {\n const fieldType = fields[fieldName]!;\n // Auto-fill Literal fields with their const value\n if (isLiteral(fieldType)) {\n state.set(fieldName, { status: \"set\", value: fieldType.const });\n } else {\n state.set(fieldName, getInitialFieldState(fieldType, defaults[fieldName]));\n }\n }\n\n // Main menu loop\n while (true) {\n const { total, filled } = countRequiredFields(type, state);\n const canSubmit = allRequiredFieldsFilled(type, state);\n\n // Build menu choices\n const choices: Array<{ name: string; value: string; disabled?: boolean | string } | Separator> = [];\n\n // Add field items\n for (const fieldName of fieldNames) {\n const fieldType = fields[fieldName]!;\n const fieldState = state.get(fieldName)!;\n const label = buildFieldLabel(fieldName, fieldType, fieldState);\n choices.push({ name: label, value: `field:${fieldName}` });\n }\n\n // Add separator and actions\n choices.push(new Separator(\"\\u2500\\u2500\\u2500 Actions \\u2500\\u2500\\u2500\"));\n\n // Submit button\n if (canSubmit) {\n choices.push({ name: \"Submit\", value: \"submit\" });\n } else {\n choices.push({\n name: `Submit (${filled} of ${total} required complete)`,\n value: \"submit\",\n disabled: true,\n });\n }\n\n choices.push({ name: \"Cancel\", value: \"cancel\" });\n\n // Show breadcrumb header if we're in a nested path\n const breadcrumb = formatBreadcrumb(path);\n if (breadcrumb) {\n console.log(colors.dim(`📍 ${breadcrumb}`));\n }\n\n // Show menu\n const selection = await selectWithClear({\n message: \"Edit:\",\n choices,\n });\n\n // Clear the breadcrumb line too if we printed one\n if (breadcrumb) {\n clearLines(1);\n }\n\n // Handle escape\n if (selection === null) {\n // Check if any values have been set\n const hasValues = Array.from(state.values()).some(\n (s) => s.status === \"set\" || s.status === \"null\",\n );\n\n if (hasValues) {\n const confirmCancel = await confirmWithClear({\n message: \"Discard changes?\",\n default: false,\n });\n if (confirmCancel === null || confirmCancel === false) {\n continue; // Return to menu\n }\n }\n return { action: \"cancel\" };\n }\n\n // Handle submit\n if (selection === \"submit\") {\n if (!canSubmit) {\n continue; // Shouldn't happen due to disabled, but be safe\n }\n const result = buildResultObject(fields, state, defs);\n return { action: \"submit\", value: result as T };\n }\n\n // Handle cancel\n if (selection === \"cancel\") {\n const hasValues = Array.from(state.values()).some(\n (s) => s.status === \"set\" || s.status === \"null\",\n );\n\n if (hasValues) {\n const confirmCancel = await confirmWithClear({\n message: \"Discard changes?\",\n default: false,\n });\n if (confirmCancel === null || confirmCancel === false) {\n continue;\n }\n }\n return { action: \"cancel\" };\n }\n\n // Handle field selection\n if (typeof selection === \"string\" && selection.startsWith(\"field:\")) {\n const fieldName = selection.slice(6);\n const fieldType = fields[fieldName]!;\n const fieldState = state.get(fieldName)!;\n\n // If field has a value, show field sub-menu\n if (fieldState.status === \"set\" || fieldState.status === \"null\") {\n const menuResult = await promptFieldMenu({\n fieldName,\n fieldType,\n state: fieldState,\n });\n\n switch (menuResult.action) {\n case \"edit\": {\n // Edit the field\n try {\n const newValue = await fillField(\n fieldType,\n [...path, fieldName],\n defs,\n fieldState.status === \"set\" ? fieldState.value : undefined,\n );\n state.set(fieldName, { status: \"set\", value: newValue });\n } catch (e) {\n if (e instanceof UserCancelledError) {\n // Return to menu without changing\n continue;\n }\n throw e;\n }\n break;\n }\n\n case \"view\": {\n if (fieldState.status === \"set\") {\n await displayFullValue(fieldName, fieldState.value);\n }\n break;\n }\n\n case \"clear\": {\n state.set(fieldName, { status: \"unset\" });\n break;\n }\n\n case \"setNull\": {\n state.set(fieldName, { status: \"null\" });\n break;\n }\n\n case \"reset\": {\n // Reset to default value - show as unset, will use default on submit\n state.set(fieldName, { status: \"unset\" });\n break;\n }\n\n case \"back\":\n // Do nothing, return to main menu\n break;\n }\n } else {\n // Field is unset - directly prompt for value\n try {\n const newValue = await fillField(\n fieldType,\n [...path, fieldName],\n defs,\n defaults[fieldName],\n );\n // If user skipped an optional field (returned undefined), leave as unset\n if (newValue === undefined) {\n // Don't change state - field remains unset\n } else {\n state.set(fieldName, { status: \"set\", value: newValue });\n }\n } catch (e) {\n if (e instanceof UserCancelledError) {\n // Return to menu without changing\n continue;\n }\n throw e;\n }\n }\n }\n }\n}\n\n/**\n * Build the result object from the state map.\n * Applies defaults for unset fields with defaults.\n */\nfunction buildResultObject(\n fields: Record<string, TSchema>,\n state: Map<string, FieldState>,\n _defs: Record<string, TSchema>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [fieldName, fieldType] of Object.entries(fields)) {\n const fieldState = state.get(fieldName);\n\n if (!fieldState || fieldState.status === \"unset\") {\n // If optional, skip (undefined)\n if (isOptional(fieldType)) {\n continue;\n }\n\n // If field has a default, use it\n if (hasDefault(fieldType)) {\n result[fieldName] = getDefault(fieldType);\n continue;\n }\n\n // No value, no default: omit from output\n continue;\n }\n\n if (fieldState.status === \"null\") {\n result[fieldName] = null;\n continue;\n }\n\n if (fieldState.status === \"set\") {\n result[fieldName] = fieldState.value;\n }\n }\n\n return result;\n}\n"],"mappings":"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","ignoreList":[]}
|