Skip to content

Testing Add Snippet Feature #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
11 changes: 11 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

# The following `prisma+postgres` URL is similar to the URL produced by running a local Prisma Postgres
# server with the `prisma dev` CLI command, when not choosing any non-default ports or settings. The API key, unlike the
# one found in a remote Prisma Postgres URL, does not contain any sensitive information.

DATABASE_URL="postgresql://postgres.wgxbziqzoxkhmhvrqaee:[email protected]:5432/postgres"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bruh

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules
/generated/prisma
192 changes: 180 additions & 12 deletions index.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the options which are compulsory, such as path to file containing snippet, lang, maybe description, consider making them requiredOptions or similar so that if they aren't given the program will throw an error.

Original file line number Diff line number Diff line change
@@ -1,21 +1,189 @@
#!/usr/bin/env node

import { Command } from 'commander';
// const {PrismaClient}=require('@prisma/client');
import { Command } from "commander";
import fs from "fs";
import path from "path";
import readline from "readline";
import clipboardy from "clipboardy";
import prisma from "./lib/prisma.js";

const program = new Command();
// const prisma = new PrismaClient();

program
.name("snippet-cli")
.description("My Code Snippet CLI program")
.version("1.0.0");

// Add snippet
program
.command("add-snippet <name>")
.description("Add a code snippet")
.option("-l, --lang <language>", "Programming language")
.option("-d, --desc <description>", "Snippet description")
.option("-f, --file <path>", "Path to the file containing the snippet")
.option("--tags <tags>", "Comma-separated tags", (val) => val.split(","))
.action(async (name, options) => {
try {
if (!options.file || !fs.existsSync(options.file)) {
console.error("❌ File path is required and must exist.");
process.exit(1);
}

const code = fs.readFileSync(options.file, "utf-8");

await prisma.snippet.create({
data: {
name,
lang: options.lang || "",
desc: options.desc || "",
file: options.file,
tags: options.tags || [],
code,
},
});

console.log(`✅ Snippet "${name}" saved to DB.`);
} catch (err) {
console.error(`❌ Failed to save snippet: ${err.message}`);
}
});

// Delete snippet
program
.command("delete-snippet <name>")
.description("Delete a snippet from the database")
.action(async (name) => {
try {
await prisma.snippet.delete({
where: { name },
});
console.log(`🗑️ Snippet "${name}" deleted.`);
} catch (err) {
console.error(`❌ Failed to delete: ${err.message}`);
}
});

// Edit snippet
program
.command("edit-snippet <name>")
.description("Edit an existing snippet")
.option("-l, --lang <language>", "New programming language")
.option("-d, --desc <description>", "New description")
.option("-f, --file <path>", "New file path")
.option("--tags <tags>", "New comma-separated tags", (val) => val.split(","))
.action(async (name, options) => {
try {
const updates = {};

if (options.lang) updates.lang = options.lang;
if (options.desc) updates.desc = options.desc;
if (options.tags) updates.tags = options.tags;

if (options.file) {
if (!fs.existsSync(options.file)) {
console.error("❌ Provided file does not exist.");
process.exit(1);
Comment on lines +83 to +84

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using throw

}
updates.file = options.file;
updates.code = fs.readFileSync(options.file, "utf-8");
}

await prisma.snippet.update({
where: { name },
data: updates,
});

console.log(`✏️ Snippet "${name}" updated.`);
} catch (err) {
console.error(`❌ Failed to update: ${err.message}`);
}
});

// List snippets
program
.name(' Code Snippet CLI')
.description('My Code Snippet CLI program')
.version('1.0.0');
.command("list-snippet")
.description("List all snippets")
.action(async () => {
const snippets = await prisma.snippet.findMany();

if (snippets.length === 0) {
console.log("📭 No snippets found.");
return;
}

snippets.forEach((s, i) => {
console.log(`\n${i + 1}. ${s.name} [${s.lang}]`);
console.log(`📄 ${s.desc}`);
console.log(`📁 ${s.file}`);
console.log(`🏷️ ${s.tags?.join(", ")}`);
Comment on lines +114 to +117

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use multiline log instead

});
});

// View a snippet
program
.command("view-snippet <name>")
.description("View a specific snippet")
.action(async (name) => {
const snippet = await prisma.snippet.findUnique({ where: { name } });

if (!snippet) {
console.log("❌ Snippet not found.");
return;
}

console.log(`\n📌 Name: ${snippet.name}`);
console.log(`🖋️ Language: ${snippet.lang}`);
console.log(`📝 Description: ${snippet.desc}`);
console.log(`📁 File: ${snippet.file}`);
console.log(`🏷️ Tags: ${snippet.tags?.join(", ")}`);
console.log(`\n📄 Code:\n${snippet.code}`);
Comment on lines +133 to +138

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

rl.question("📋 Copy to clipboard? (y/n): ", (answer) => {
if (answer.toLowerCase() === "y") {
clipboardy.writeSync(snippet.code);
console.log("✅ Copied to clipboard.");
}
rl.close();
});
});

// Search snippet (basic)
program
.command('hi <name>')
.description('Says hi to the user')
.option('-f')
.action(() =>{ console.log('Hello User, Welcome to the CLI');});
.command("search-snippet")
.description("Search snippets by keyword or tag")
.option("-k, --key <keyword>", "Search in name/desc/code")
.option("--tag <tag>", "Search by tag")
.action(async (options) => {
const snippets = await prisma.snippet.findMany();

const results = snippets.filter((s) => {
const keywordMatch = options.key
? [s.name, s.desc, s.code].some((field) =>
field?.toLowerCase().includes(options.key.toLowerCase())
)
: true;

const tagMatch = options.tag
? s.tags?.includes(options.tag)
: true;

return keywordMatch && tagMatch;
});

if (!results.length) {
console.log("🔍 No matching snippets.");
return;
}

results.forEach((s, i) => {
console.log(`\n${i + 1}. ${s.name} [${s.lang}]`);
console.log(`Tags: ${s.tags?.join(", ")}`);
console.log(`File: ${s.file}`);
});
});

program.parse();
program.parse(process.argv);
5 changes: 5 additions & 0 deletions lib/prisma.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default prisma;
Loading
Loading