This commit is contained in:
77
src/commands/import.ts
Normal file
77
src/commands/import.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import * as path from 'path';
|
||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import { fileUtils } from '../utils/fileUtils';
|
||||||
|
import { Layout } from '../models/types';
|
||||||
|
|
||||||
|
interface ImportOptions {
|
||||||
|
file: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importLayout(options: ImportOptions): Promise<void> {
|
||||||
|
await fileUtils.initialize();
|
||||||
|
|
||||||
|
if (!fs.existsSync(options.file)) {
|
||||||
|
throw new Error(`File not found: ${options.file}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let layout: Layout;
|
||||||
|
const fileExt = path.extname(options.file).toLowerCase();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (fileExt === '.yaml' || fileExt === '.yml') {
|
||||||
|
const content = fs.readFileSync(options.file, 'utf-8');
|
||||||
|
layout = yaml.load(content) as Layout;
|
||||||
|
} else {
|
||||||
|
layout = fs.readJsonSync(options.file) as Layout;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Failed to parse layout file: ${(error as Error).message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateLayout(layout);
|
||||||
|
|
||||||
|
let name = options.name;
|
||||||
|
if (!name) {
|
||||||
|
const baseName = path.basename(options.file).replace(/\.(json|yaml|yml)$/, '');
|
||||||
|
const existingLayouts = await fileUtils.listLayouts();
|
||||||
|
const availableName = existingLayouts.includes(`${baseName}.json`)
|
||||||
|
? `${baseName}-imported`
|
||||||
|
: baseName;
|
||||||
|
|
||||||
|
const { layoutName } = await inquirer.prompt([
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'layoutName',
|
||||||
|
message: 'Enter a name for the imported layout:',
|
||||||
|
default: availableName,
|
||||||
|
validate: (input: string) => input.trim() !== '' || 'Name cannot be empty',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
name = layoutName;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.updatedAt = new Date().toISOString();
|
||||||
|
|
||||||
|
const fileName = name || 'imported-layout';
|
||||||
|
const filePath = await fileUtils.saveLayout(fileName, layout, 'json');
|
||||||
|
console.log(`Layout imported successfully: ${filePath}`);
|
||||||
|
console.log(`Terminal type: ${layout.terminalType}`);
|
||||||
|
console.log(`Windows: ${layout.session.windows.length}`);
|
||||||
|
console.log(`Description: ${layout.metadata?.description || 'N/A'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateLayout(layout: Layout): void {
|
||||||
|
const required = ['version', 'terminalType', 'createdAt', 'session'];
|
||||||
|
for (const field of required) {
|
||||||
|
if (!(field in layout)) {
|
||||||
|
throw new Error(`Invalid layout: missing required field "${field}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layout.session || !layout.session.windows) {
|
||||||
|
throw new Error('Invalid layout: missing session.windows');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user