Skip to the content

Capsid menu

app/lib/editor/link-targets.server.ts

40 lines and 7 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of link-targets.server.ts
FunctionLinesComplexityCoveredCRAPMutation
loadLinkTargets11 to 261No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:15>15 to 252No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
loadEditorOptions32 to 431No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:34>34 to 391No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:35>35 to 391No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:41>41 to 411No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:42>42 to 421No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code

Imports

It imports app/db/index.ts, app/lib/error-message.mjs, app/lib/timing.ts. Imported by app/routes/admin.posts.$slug.edit.tsx, app/routes/admin.posts.new.tsx.

Source

import { listAllPostsForAdmin, listBlogTags } from "~/db";
import { errorMessage } from "~/lib/error-message.mjs";
import { timed, type Timings } from "~/lib/timing";

import { stateOf } from "capsomer/publish-transition";

/**
 * Every post is offered, with its state: hiding unpublished ones makes an author paste a path from
 * memory, which is where typos come from.
 */
async function loadLinkTargets(env: Env) {
  // A failed read throws: an empty list would read as "no posts to link to".
  const rows = await listAllPostsForAdmin(env);
  const now = Date.now();
  return rows.map((row) => ({
    slug: row.slug,
    title: row.title,
    state: stateOf(
      {
        draft: row.status !== "published",
        publishAt: row.publishAt ? row.publishAt.toISOString() : "",
      },
      now,
    ),
  }));
}

/**
 * What both editors offer: the existing tags and the link targets. A failed tag read is shown,
 * never an empty list: it comes back as a sentence in `problems`, and the editor still opens.
 */
export async function loadEditorOptions(env: Env, timings: Timings | undefined) {
  const problems: string[] = [];
  const tags = await timed(timings, "d1_tags", () =>
    listBlogTags(env).catch((error: unknown) => {
      console.error(JSON.stringify({ alert: "editor-tags-read-failed", detail: errorMessage(error) }));
      problems.push(`Existing tags could not be read, so none are suggested: ${errorMessage(error)}`);
      return [];
    }),
  );
  const linkTargets = await timed(timings, "d1_link_targets", () => loadLinkTargets(env));
  return { tagOptions: tags.map((tag) => tag.slug), linkTargets, problems };
}