Kunci jawaban 20 Latihan Node.

20.1 Tool Pencari

import {readFile} from "node:fs/promises";
import process from "node:process";
 
let [kata, ...berkas] = process.argv.slice(2);
 
for (let nama of berkas) {
  let isi = await readFile(nama, "utf8");
  if (isi.includes(kata)) {
    console.log(nama);
  }
}

Kenapa: process.argv.slice(2) membuang path node dan nama script, menyisakan argumen sebenarnya; destructuring [kata, ...berkas] mengambil kata pertama dan sisanya sebagai daftar file. Tiap file dibaca ("utf8" supaya jadi string, bukan Buffer) dan dicek dengan includes. Bonus (regex): ganti isi.includes(kata) dengan new RegExp(kata).test(isi).

→ Soal: 20 Latihan Node > 20.1 Tool Pencari

20.2 Pembuatan Direktori

import {mkdir} from "node:fs/promises";
 
// di dalam router server, tambahkan handler:
async function MKCOL(path) {
  try {
    await mkdir(path);
    return {status: 204};
  } catch (e) {
    if (e.code == "EEXIST") {
      return {status: 204};   // sudah ada, anggap sukses
    }
    throw e;
  }
}

Kenapa: MKCOL adalah method HTTP untuk membuat koleksi/direktori (dipakai protokol WebDAV). Kita panggil mkdir pada path yang sudah di-resolve dengan aman. Kalau direktori sudah ada, Node melempar error dengan code == "EEXIST" — kita tangani sebagai sukses (204 No Content) supaya idempoten; error lain dilempar ulang.

→ Soal: 20 Latihan Node > 20.2 Pembuatan Direktori

20.3 Ruang Web Publik

Server (garis besar): layani file statis untuk GET, dan simpan body untuk PUT.

import {createServer} from "node:http";
import {readFile, writeFile} from "node:fs/promises";
 
createServer(async (req, res) => {
  let path = "." + decodeURIComponent(req.url);
  try {
    if (req.method == "GET") {
      let isi = await readFile(path);
      res.writeHead(200);
      res.end(isi);
    } else if (req.method == "PUT") {
      let potongan = [];
      for await (let p of req) potongan.push(p);
      await writeFile(path, Buffer.concat(potongan));
      res.writeHead(204);
      res.end();
    } else {
      res.writeHead(405);
      res.end("Method tidak didukung");
    }
  } catch (e) {
    res.writeHead(500);
    res.end(String(e));
  }
}).listen(8000);

Halaman kliennya (disimpan sebagai file yang dilayani server) mengirim perubahan dengan:

fetch(namaFile, {method: "PUT", body: teksBaru});

Kenapa: GET membaca file dan mengirimnya; PUT mengumpulkan body request (yang datang sebagai stream — dikumpulkan potong demi potong lewat for await) lalu menuliskannya ke file. Halaman HTML-nya cukup pakai fetch method: "PUT" untuk menyimpan. Peringatan penting: di server sungguhan kamu wajib memvalidasi path supaya .. gak bisa keluar dari folder yang diizinkan (celah path traversal) — di sini disederhanakan.

→ Soal: 20 Latihan Node > 20.3 Ruang Web Publik