resume-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 3f16b2375723
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 70bace54357d4b57b674108f
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
src/files.ts
// Resume as files: the name downloads get, plain text and JSON out, and JSON (JSON Resume) back in.
import { displayUrl, fromJsonResume, toJsonResume, toText, ResumeError, type Resume } from "../functions/lib/resume";
import { saveFile } from "./ui";
import { letterDate } from "./layout";
import { localPaper, type Letter } from "./store";

export function fileBase(r: Resume, what = "Resume"): string {
  const name = r.basics.name.trim().replace(/[\\/:*?"<>|]+/g, "-");
  return name ? `${name} ${what}` : what;
}

export function downloadText(r: Resume) {
  saveFile(`${fileBase(r)}.txt`, new Blob([toText(r)], { type: "text/plain;charset=utf-8" }));
}

/** The cover letter as plain text, for pasting into an application form or an email. */
export function letterText(r: Resume, letter: Letter): string {
  const b = r.basics;
  const contact = [b.email, b.phone, b.location, ...b.links.map(displayUrl)].map((s) => s.trim()).filter(Boolean).join(" | ");
  const parts = [b.name.trim(), contact, "", letterDate(), ""];
  if (letter.to.trim()) parts.push(letter.to.trim(), "");
  parts.push(letter.body.trim());
  return parts.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n";
}

export function downloadLetterText(r: Resume, letter: Letter) {
  saveFile(`${fileBase(r, "Cover Letter")}.txt`, new Blob([letterText(r, letter)], { type: "text/plain;charset=utf-8" }));
}

export function downloadJson(r: Resume) {
  saveFile(`${fileBase(r)}.json`, new Blob([JSON.stringify(toJsonResume(r), null, 2)], { type: "application/json" }));
}

/** Reads a JSON Resume file (or one Resume exported). Throws a sentence a person can read. */
export async function readJsonFile(file: File): Promise<Resume> {
  if (file.size > 1_000_000) throw new ResumeError("That file is too big for a resume.");
  let data: unknown;
  try {
    data = JSON.parse(await file.text());
  } catch {
    throw new ResumeError("That file is not JSON. Pick a .json file exported from Resume or another JSON Resume tool.");
  }
  return fromJsonResume(data, localPaper());
}

Change history

Quality pass: several resumes, cover letters, phone-readable shared pages
3f16b23757 · 5 hours ago
Bounded source sync
b7eb5b26b5 · 1 day ago
Bounded source sync
adae97536e · 1 day ago
Bounded source sync
3b0cf36b39 · 1 day ago