Functional Weave
Code in Rust

todo.export-csv@1.0.0

impl/typescript.ts

1,356 bytes · the TypeScript implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import { type Todo } from "./todo_item.ts";  ← from todo.item ^1.0.0 · built alongside by fune

const HEADER = [
  "id", "title", "notes", "done", "priority", "due", "tags",
  "recurrenceFrequency", "recurrenceInterval", "recurrenceAnchor", "createdAt", "completedAt", "order",
];

/** Quote a field only when RFC 4180 needs it: a comma, a double quote, CR or LF. */
function field(text: string): string {
  if (!/[",\r\n]/.test(text)) return text;
  return '"' + text.split('"').join('""') + '"';
}

/**
 * Todos as CSV, one row per todo in the order given, under a fixed header
 * of 13 columns. Nothing is escaped for spreadsheets: a title starting with
 * "=" is written as it is, so the file reads back exactly (see README).
 */
export function exportCsv(todos: readonly Todo[]): string {
  const lines = [HEADER.join(",")];
  for (const todo of todos) {
    const rule = todo.recurrence ?? null;
    const cells = [
      todo.id,
      todo.title,
      todo.notes ?? "",
      todo.done ? "true" : "false",
      todo.priority,
      todo.due ?? "",
      todo.tags.join(" "),
      rule === null ? "" : rule.frequency,
      rule === null ? "" : String(rule.interval),
      rule === null ? "" : rule.anchor,
      todo.createdAt,
      todo.completedAt ?? "",
      String(todo.order),
    ];
    lines.push(cells.map(field).join(","));
  }
  return lines.map((line) => line + "\r\n").join("");
}