134 lines
3.6 KiB
JavaScript
134 lines
3.6 KiB
JavaScript
import inquirer from 'inquirer';
|
|
import { loadConfig } from '../config.js';
|
|
import { initDirectusClient, searchItems, createItem } from '../directus/client.js';
|
|
import { removeUrlProtocol } from '../sanitize.js';
|
|
|
|
export const addLinkToShare = async () => {
|
|
const config = await loadConfig();
|
|
|
|
initDirectusClient(config);
|
|
|
|
const { title, link, description, authorQuery } = await inquirer.prompt([
|
|
{
|
|
name: 'title',
|
|
message: '📝 Title for the link:',
|
|
validate: input => !!input || 'Title is required'
|
|
},
|
|
{
|
|
name: 'link',
|
|
message: '🔗 URL to share:',
|
|
validate: input => input.startsWith('http') || 'Must be a valid URL'
|
|
},
|
|
{
|
|
name: 'description',
|
|
message: '🗒 Description (optional):',
|
|
default: ''
|
|
},
|
|
{
|
|
name: 'authorQuery',
|
|
message: '👤 Search for an author:',
|
|
}
|
|
]);
|
|
|
|
const authorMatches = await searchItems('authors', authorQuery);
|
|
let author;
|
|
|
|
if (!authorMatches.length) {
|
|
const { shouldCreate } = await inquirer.prompt({
|
|
type: 'confirm',
|
|
name: 'shouldCreate',
|
|
message: '❌ No authors found. Do you want to create a new one?',
|
|
default: true,
|
|
});
|
|
|
|
if (!shouldCreate) return;
|
|
|
|
const { name, url, mastodon, rss, json, newsletter, blogroll } = await inquirer.prompt([
|
|
{ name: 'name', message: '👤 Author name:', validate: input => !!input || 'Name is required' },
|
|
{ name: 'url', message: '🔗 URL (optional):', default: '' },
|
|
{ name: 'mastodon', message: '🐘 Mastodon handle (optional):', default: '' },
|
|
{ name: 'rss', message: '📡 RSS feed (optional):', default: '' },
|
|
{ name: 'json', message: '🧾 JSON feed (optional):', default: '' },
|
|
{ name: 'newsletter', message: '📰 Newsletter URL (optional):', default: '' },
|
|
{ type: 'confirm', name: 'blogroll', message: '📌 Add to blogroll?', default: false }
|
|
]);
|
|
|
|
const created = await createItem('authors', {
|
|
name,
|
|
url,
|
|
mastodon,
|
|
rss,
|
|
json,
|
|
newsletter,
|
|
blogroll
|
|
});
|
|
|
|
author = created.data?.id || created.id;
|
|
} else {
|
|
const response = await inquirer.prompt({
|
|
type: 'list',
|
|
name: 'author',
|
|
message: 'Select an author:',
|
|
choices: authorMatches.map(a => {
|
|
const cleanUrl = removeUrlProtocol(a.url);
|
|
const display = cleanUrl ? `${a.name} (${cleanUrl})` : a.name;
|
|
|
|
return {
|
|
name: display,
|
|
value: a.id,
|
|
};
|
|
})
|
|
});
|
|
|
|
author = response.author;
|
|
}
|
|
|
|
let tagIds = [];
|
|
|
|
while (true) {
|
|
const { query } = await inquirer.prompt({
|
|
name: 'query',
|
|
message: '🏷 Search for tags (or leave blank to finish):',
|
|
});
|
|
|
|
const trimmedQuery = query.trim();
|
|
if (!trimmedQuery) break;
|
|
|
|
const tags = await searchItems('tags', trimmedQuery);
|
|
|
|
if (!tags.length) {
|
|
console.warn(`⚠️ No tags found matching "${trimmedQuery}"`);
|
|
|
|
continue;
|
|
}
|
|
|
|
const { selected } = await inquirer.prompt({
|
|
type: 'checkbox',
|
|
name: 'selected',
|
|
message: '✔ Select tags to add:',
|
|
choices: tags.map(tag => ({ name: tag.name, value: tag.id }))
|
|
});
|
|
|
|
tagIds.push(...selected);
|
|
|
|
const { again } = await inquirer.prompt({
|
|
type: 'confirm',
|
|
name: 'again',
|
|
message: 'Search and select more tags?',
|
|
default: false,
|
|
});
|
|
|
|
if (!again) break;
|
|
}
|
|
|
|
await createItem('links', {
|
|
title,
|
|
link,
|
|
description,
|
|
author,
|
|
link_tags: tagIds.map(tagId => ({ tags_id: tagId })),
|
|
date: new Date().toISOString()
|
|
});
|
|
|
|
console.log('✅ Link created successfully.');
|
|
};
|