@letanure/resend-cli
Version:
A command-line interface for Resend email API
221 lines • 10.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Alert } from '@inkjs/ui';
import { Box, useInput } from 'ink';
import { useState } from 'react';
import { SelectField } from '../../../components/forms/SelectField.js';
import { TextInput } from '../../../components/forms/TextInput.js';
import { ErrorScreen } from '../../../components/ui/ErrorScreen.js';
import { Layout } from '../../../components/ui/layout.js';
import { SuccessScreen } from '../../../components/ui/SuccessScreen.js';
import { config } from '../../../config/config.js';
import { useDryRun } from '../../../contexts/DryRunProvider.js';
import { useResend } from '../../../contexts/ResendProvider.js';
import { createApiKey } from './action.js';
import { displayFields, fields } from './fields.js';
import { CreateApiKeyOptionsSchema } from './schema.js';
export const Form = ({ onExit }) => {
const { isDryRun } = useDryRun();
const { apiKey } = useResend();
const [formData, setFormData] = useState({
name: '',
permission: 'full_access',
domain_id: '',
});
const [currentField, setCurrentField] = useState(0);
const [errors, setErrors] = useState({});
const [formError, setFormError] = useState('');
const [successData, setSuccessData] = useState(null);
const [isDryRunSuccess, setIsDryRunSuccess] = useState(false);
const [error, setError] = useState(null);
const visibleFields = fields;
// Find next/previous non-disabled field
const findNextField = (start, direction) => {
let index = start;
const max = visibleFields.length - 1;
do {
index += direction;
if (index < 0) {
index = max;
}
if (index > max) {
index = 0;
}
const field = visibleFields[index];
const isDisabled = field?.name === 'domain_id' && formData.permission === 'full_access';
if (!isDisabled) {
return index;
}
} while (index !== start);
return start;
};
// Handle Esc/Left arrow key to go back from result screens
useInput((_input, key) => {
if ((key.escape || key.leftArrow) && (successData || error)) {
setSuccessData(null);
setIsDryRunSuccess(false);
setError(null);
}
}, { isActive: !!(successData || error) });
useInput((input, key) => {
if (successData || error) {
return; // Don't handle input when showing result
}
const currentFieldData = visibleFields[currentField];
const isSelectField = currentFieldData?.type === 'select';
const keyHandlers = [
{ condition: () => key.escape, action: onExit },
// Left arrow to exit form - only if NOT on a select field
{ condition: () => key.leftArrow && !isSelectField, action: onExit },
{ condition: () => key.shift && key.tab, action: () => setCurrentField(findNextField(currentField, -1)) },
{
condition: () => key.tab && !key.shift,
action: () => setCurrentField(findNextField(currentField, 1)),
},
{
condition: () => key.downArrow,
action: () => setCurrentField(findNextField(currentField, 1)),
},
{ condition: () => key.upArrow, action: () => setCurrentField(findNextField(currentField, -1)) },
{
condition: () => (key.leftArrow || key.rightArrow) && isSelectField,
action: () => currentFieldData && handleSelectToggle(currentFieldData),
},
{
condition: () => input === ' ' && isSelectField,
action: () => currentFieldData && handleSelectToggle(currentFieldData),
},
{ condition: () => key.return, action: handleFormSubmission },
];
for (const handler of keyHandlers) {
if (handler.condition()) {
handler.action();
break;
}
}
});
const handleFormSubmission = async () => {
const validationErrors = {};
let validatedData = null;
let currentFormError = '';
const cleanedData = {};
for (const [key, value] of Object.entries(formData)) {
if (typeof value === 'string') {
cleanedData[key] = value.trim() === '' ? undefined : value.trim();
}
else {
cleanedData[key] = value;
}
}
const result = CreateApiKeyOptionsSchema.safeParse(cleanedData);
if (result.success) {
validatedData = result.data;
}
else {
result.error.issues.forEach((issue) => {
const field = issue.path[0];
if (typeof field === 'string') {
validationErrors[field] = issue.message;
}
else {
currentFormError = issue.message;
}
});
}
if (Object.keys(validationErrors).length === 0 && !currentFormError) {
setFormError('');
if (validatedData) {
try {
if (isDryRun) {
setSuccessData({
id: 'dry-run-api-key-id',
token: 'dry-run-token-re_xxxxx',
});
setIsDryRunSuccess(true);
}
else {
const apiResult = await createApiKey(validatedData, apiKey);
if (apiResult.success && apiResult.data) {
setSuccessData(apiResult.data);
setIsDryRunSuccess(false);
}
else {
setError({
title: 'API Key Creation Failed',
message: apiResult.error || 'Unknown error occurred',
suggestion: 'Check your API key and permissions',
});
}
}
}
catch (err) {
setError({
title: 'API Key Creation Error',
message: err instanceof Error ? err.message : 'Unknown error',
suggestion: 'Please check your API key and network connection',
});
}
}
}
else {
setErrors(validationErrors);
setFormError(currentFormError);
}
};
const handleFieldChange = (fieldName, value) => {
setFormData((prev) => {
const newData = { ...prev, [fieldName]: value };
// Clear domain_id when switching to full_access
if (fieldName === 'permission' && value === 'full_access') {
newData.domain_id = '';
}
return newData;
});
// Clear error when user starts typing
if (errors[fieldName]) {
setErrors((prev) => ({ ...prev, [fieldName]: '' }));
}
// Clear form-level error when user starts typing
if (formError) {
setFormError('');
}
if (fieldName === 'permission') {
const currentFieldData = visibleFields[currentField];
if (currentFieldData?.name === 'domain_id' && value === 'full_access') {
// Move to first non-disabled field
setCurrentField(findNextField(currentField, 1));
}
}
};
const handleSelectToggle = (field) => {
if (field.options && field.options.length > 1) {
const currentValue = formData[field.name];
const currentIndex = field.options.findIndex((option) => option.value === currentValue);
const nextIndex = (currentIndex + 1) % field.options.length;
const nextValue = field.options[nextIndex]?.value;
handleFieldChange(field.name, nextValue);
}
};
if (successData) {
return (_jsx(SuccessScreen, { data: successData, successMessage: "API Key Created Successfully", headerText: `${config.baseTitle} - API Keys - Create`, fields: displayFields, isDryRun: isDryRunSuccess, onExit: () => {
setSuccessData(null);
setIsDryRunSuccess(false);
onExit();
} }));
}
if (error) {
return (_jsx(ErrorScreen, { title: error.title, message: error.message, suggestion: error.suggestion, headerText: `${config.baseTitle} - API Keys - Create`, onExit: () => {
setError(null);
onExit();
}, showRetry: true, onRetry: () => {
setError(null);
} }));
}
return (_jsx(Layout, { headerText: `${config.baseTitle} - API Keys - Create`, showNavigationInstructions: true, navigationContext: "form", children: _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [formError && (_jsx(Box, { marginBottom: 1, children: _jsx(Alert, { variant: "error", children: formError }) })), visibleFields.map((field, index) => {
if (field.type === 'select' && field.options) {
return (_jsx(SelectField, { label: field.label, options: field.options, value: formData[field.name], isActive: currentField === index, helpText: field.helpText, errorMessage: errors[field.name], display: field.display, onToggle: () => handleSelectToggle(field) }, field.name));
}
const isDisabled = field.name === 'domain_id' && formData.permission === 'full_access';
return (_jsx(TextInput, { label: field.label, value: String(formData[field.name] || ''), onChange: (value) => handleFieldChange(field.name, value), placeholder: field.placeholder, helpText: isDisabled ? 'Only available for sending_access permission' : field.helpText, isFocused: currentField === index, error: errors[field.name], disabled: isDisabled }, field.name));
})] }) }));
};
//# sourceMappingURL=Form.js.map