paste-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 01fdb2b1f66e
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 6eca480d6447d873e2e5eed9
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/lib/format.ts
// Small words and links the pages share: when a paste expires, where its pages are, and readable errors.
import { SITE_URL } from "../../functions/lib/config";
import type { Saved } from "./mine";

export const HOST = SITE_URL.replace(/^https?:\/\//, "");

/** The link to share: an encrypted paste carries its key after the #. */
export const shareUrl = (id: string, secret?: string) => `${SITE_URL}/${id}${secret ? `#${secret}` : ""}`;
export const adminPath = (s: Pick<Saved, "id" | "key" | "secret">) => `/${s.id}/admin#k=${s.key}${s.secret ? `&e=${s.secret}` : ""}`;
export const adminLink = (s: Pick<Saved, "id" | "key" | "secret">) => `${SITE_URL}${adminPath(s)}`;

/** "in 5 minutes", "in 3 hours", "in 6 days", "in 2 months", "in 1 year", for a time in unix seconds. */
export function fromNow(at: number): string {
  const s = Math.max(0, at - Date.now() / 1000);
  const [n, unit] =
    s < 3570 ? [Math.max(1, Math.round(s / 60)), "minute"]
    : s < 86400 * 2 ? [Math.round(s / 3600), "hour"]
    : s < 86400 * 45 ? [Math.round(s / 86400), "day"]
    : s < 86400 * 330 ? [Math.round(s / (86400 * 30)), "month"]
    : [Math.max(1, Math.round(s / (86400 * 365))), "year"];
  return `in ${n} ${unit}${n === 1 ? "" : "s"}`;
}

export function expiryText(s: { createdAt: number; ttl: number; burn: boolean }): string {
  if (s.burn) return "Deletes itself after the first view";
  return s.ttl ? `Expires ${fromNow(s.createdAt + s.ttl)}` : "Never expires";
}

/** A sentence a person can read for a failed write or read. */
export function explain(err: unknown): string {
  const e = err as { message?: string; decline?: unknown };
  const msg = String(e?.message || err || "");
  if (/413|too large/i.test(msg)) return "That paste is too large to save. Pastes can hold up to 512 KB.";
  if (!navigator.onLine || /network|fetch|Failed to fetch/i.test(msg)) return "Paste could not be reached. Check your connection, then try again.";
  // The data rules refuse with a generic message. Reloading shows the real state, for example a paste that expired meanwhile.
  if (e?.decline || /denied|policy|403|forbidden/i.test(msg)) return "That was refused. Reload the page and try again.";
  return msg || "Something went wrong. Try again.";
}

Change history

Quality pass: password lock, year expiry, line links, text/plain API
01fdb2b1f6 · 4 hours ago
Bounded source sync
fe5788c2d2 · 1 day ago
Bounded source sync
ac6f7dbc95 · 1 day ago
Bounded source sync
0a45926293 · 1 day ago