UNPKG

askeroo

Version:

A modern CLI prompt library with flow control, history navigation, and conditional prompts

216 lines 7.99 kB
// Completed fields store using the store factory pattern // Uses createStore for automatic reactive updates import { createStore } from "../../core/store.js"; // Create the completed fields store export const completedFieldsStore = createStore({ fieldState: { values: {}, visited: new Set(), completed: new Set(), properties: new Map(), messages: {}, groupNames: {}, groupIds: {}, }, promptOrderState: { rootFieldHistory: [], groupFieldHistory: new Map(), }, treeManager: null, revision: 0, }); // Set the tree manager (called from PromptApp) export function setTreeManager(manager) { completedFieldsStore.update((state) => { state.treeManager = manager; }); } // Notify that tree has changed (called from PromptApp after tree updates) export function notifyTreeChanged() { completedFieldsStore.update((state) => { state.revision += 1; }); } // Get current completed fields state (legacy support) export function getCompletedFieldsState() { const store = completedFieldsStore.get(); return { fieldState: store.fieldState, promptOrderState: store.promptOrderState, treeManager: store.treeManager, revision: store.revision, }; } // Helper functions for formatting values and extracting field messages function formatValue(value, fieldProperties) { // Handle empty arrays if (Array.isArray(value)) { if (value.length === 0) { return "None"; } // For multi-select fields, get the labels from the options if (fieldProperties && fieldProperties.options && Array.isArray(fieldProperties.options)) { const selectedLabels = value .map((val) => { const option = fieldProperties.options.find((opt) => opt.value === val); return option ? option.label : val; }) .filter(Boolean); return selectedLabels.join(", "); } return value.join(", "); } if (typeof value === "boolean") { // For confirm fields, try to get the label from options if (fieldProperties && fieldProperties.options && Array.isArray(fieldProperties.options)) { const option = fieldProperties.options.find((opt) => opt.value === value); return option ? option.label : value.toString(); } return value ? "Yes" : "No"; } // Handle falsey values (null, undefined, empty string, 0, false) if (!value && value !== 0 && value !== false) { if (value === null) return "None"; if (value === undefined) return "Not set"; if (value === "") return "Empty"; return "None"; } // For radio fields, get the label from options if (fieldProperties && fieldProperties.options && Array.isArray(fieldProperties.options)) { const option = fieldProperties.options.find((opt) => opt.value === value); if (option) { return option.label; } } return String(value); } // Get completed fields as formatted objects export function getCompletedFields() { const fields = []; const { fieldState, promptOrderState } = completedFieldsStore.get(); // Helper function to create field object const createField = (fieldId, index) => { if (!fieldState.completed.has(fieldId) || fieldState.values[fieldId] === undefined) { return null; } const value = fieldState.values[fieldId]; const groupName = fieldState.groupNames[fieldId]; const groupId = fieldState.groupIds[fieldId]; // Get the original field properties const originalProperties = fieldState.properties.get(fieldId) || {}; // Use the original field's label and shortLabel properties const label = originalProperties.label || originalProperties.message || fieldState.messages[fieldId] || fieldId; const shortLabel = originalProperties.shortLabel; // Format the value using the original field properties const formattedValue = formatValue(value, originalProperties); return { id: fieldId, groupName, groupId, label, shortLabel, value: String(value), formattedValue, timestamp: index, // Use index as ordering timestamp meta: originalProperties.meta, // Include meta from original field properties }; }; // Use ordering information if available if (promptOrderState?.rootFieldHistory && promptOrderState?.groupFieldHistory) { // Create a combined chronological list const allFieldsInOrder = []; // Add root fields with their position markers promptOrderState.rootFieldHistory.forEach((fieldInfo) => { allFieldsInOrder.push({ id: fieldInfo.id, type: "root" }); }); // Add group fields with their position markers for (const [groupId, groupFields,] of promptOrderState.groupFieldHistory) { groupFields.forEach((fieldInfo) => { allFieldsInOrder.push({ id: fieldInfo.id, type: "group", groupId, }); }); } // Sort by completion timestamp (when they were actually completed) allFieldsInOrder.sort((a, b) => { // Get the completion order from the Set iteration order const aCompleted = Array.from(fieldState.completed).indexOf(a.id); const bCompleted = Array.from(fieldState.completed).indexOf(b.id); return aCompleted - bCompleted; }); // Create fields in the correct chronological order allFieldsInOrder.forEach((fieldInfo, index) => { const field = createField(fieldInfo.id, index); if (field) { fields.push(field); } }); } else { // Fallback to old behavior if ordering info is not available let index = 0; for (const fieldId of fieldState.completed) { const field = createField(fieldId, index++); if (field) { fields.push(field); } } } return fields; } // NEW TREE-BASED APPROACH: Get completed fields directly from tree export function getCompletedFieldsData() { const treeManager = completedFieldsStore.get().treeManager; if (!treeManager) { // Fallback to legacy approach if tree manager not set yet return getCompletedFields(); } const completedFields = []; treeManager.traverseDepthFirst((node) => { if (node.type === "field" && node.completed && !node.excludeFromCompleted && !node.hideOnCompletion && node.value !== undefined) { const fieldProperties = node.properties || {}; const label = fieldProperties.label || fieldProperties.message || node.label || `${node.fieldType} field`; const shortLabel = fieldProperties.shortLabel; completedFields.push({ id: node.id, label, shortLabel, value: node.value, formattedValue: formatValue(node.value, fieldProperties), groupLabel: node.parent?.type === "group" ? node.parent.label : undefined, meta: fieldProperties.meta, }); } }); return completedFields; } // Clear all completed fields data (for testing/reset) export function clearCompletedFieldsStore() { completedFieldsStore.reset(); } //# sourceMappingURL=completed-fields-store.js.map