// notes-api/src/index.js
// npm install express
// Run: node src/index.js
import express from 'express'
import { readFile, writeFile } from 'fs/promises'
import { existsSync } from 'fs'
import { randomUUID } from 'crypto'
const app = express()
const DB = "./notes.json"
app.use(express.json())
// Load / save helpers
async function load() {
if (!existsSync(DB)) return []
return JSON.parse(await readFile(DB, "utf-8"))
}
async function save(notes) {
await writeFile(DB, JSON.stringify(notes, null, 2))
}
// GET /notes
app.get("/notes", async (req, res) => {
const notes = await load()
const { q } = req.query
res.json(q ? notes.filter(n => n.body.includes(q) || n.title.includes(q)) : notes)
})
// GET /notes/:id
app.get("/notes/:id", async (req, res) => {
const notes = await load()
const note = notes.find(n => n.id === req.params.id)
if (!note) return res.status(404).json({ error: "Not found" })
res.json(note)
})
// POST /notes
app.post("/notes", async (req, res) => {
const { title, body } = req.body
if (!title || !body) return res.status(400).json({ error: "title and body required" })
const notes = await load()
const note = { id: randomUUID(), title, body, createdAt: new Date().toISOString() }
notes.push(note)
await save(notes)
res.status(201).json(note)
})
// PATCH /notes/:id
app.patch("/notes/:id", async (req, res) => {
const notes = await load()
const idx = notes.findIndex(n => n.id === req.params.id)
if (idx === -1) return res.status(404).json({ error: "Not found" })
notes[idx] = { ...notes[idx], ...req.body, updatedAt: new Date().toISOString() }
await save(notes)
res.json(notes[idx])
})
// DELETE /notes/:id
app.delete("/notes/:id", async (req, res) => {
const notes = await load()
const filtered = notes.filter(n => n.id !== req.params.id)
if (filtered.length === notes.length) return res.status(404).json({ error: "Not found" })
await save(filtered)
res.status(204).end()
})
app.listen(3000, () => console.log("Notes API: http://localhost:3000"))