diigo-cache: public list shows each bookmark's date first
The list is in diigo's updated order; each item now leads with its updated_at as Date#toISOString() (diigo sends epoch seconds; updatedISO converts, tested), or "(no date)". Generated-by: Claude Opus 5.5
This commit is contained in:
1 parent
80c9279825
commit
860bbee2b5
4 files changed
+26
-3
No files matched your search
@@ -15,7 +15,7 @@
|
|||||||
import { WorkerEntrypoint } from "cloudflare:workers";
|
import { WorkerEntrypoint } from "cloudflare:workers";
|
||||||
import { DiigoCache, PublicCache } from "./cache.js";
|
import { DiigoCache, PublicCache } from "./cache.js";
|
||||||
import type { Item } from "./cache.js";
|
import type { Item } from "./cache.js";
|
||||||
import { usernameOf } from "./items.js";
|
import { updatedISO, usernameOf } from "./items.js";
|
||||||
import { toWebkey, idFromWebkey, isWebkey, shashKey } from "./webkeys.js";
|
import { toWebkey, idFromWebkey, isWebkey, shashKey } from "./webkeys.js";
|
||||||
import { pmSave } from "./pm-save.js";
|
import { pmSave } from "./pm-save.js";
|
||||||
|
|
||||||
@@ -457,7 +457,9 @@ ${items
|
|||||||
const title = typeof it.title === "string" && it.title ? it.title : url;
|
const title = typeof it.title === "string" && it.title ? it.title : url;
|
||||||
const desc = typeof it.description === "string" && it.description ? `<br><small>${esc(it.description)}</small>` : "";
|
const desc = typeof it.description === "string" && it.description ? `<br><small>${esc(it.description)}</small>` : "";
|
||||||
const href = /^https?:\/\//i.test(url) ? url : "#";
|
const href = /^https?:\/\//i.test(url) ? url : "#";
|
||||||
return `<li><a href="${esc(href)}">${esc(title)}</a>${desc}</li>`;
|
const when = updatedISO(it);
|
||||||
|
const date = when ? `<time datetime="${when}">${when}</time>` : "(no date)";
|
||||||
|
return `<li>${date} <a href="${esc(href)}">${esc(title)}</a>${desc}</li>`;
|
||||||
})
|
})
|
||||||
.join("\n")}
|
.join("\n")}
|
||||||
</ol>`;
|
</ol>`;
|
||||||
|
|||||||
@@ -64,3 +64,11 @@ export function usernameOf(item: Item | undefined): string {
|
|||||||
export function publicOnly(rows: ItemRow[]): ItemRow[] {
|
export function publicOnly(rows: ItemRow[]): ItemRow[] {
|
||||||
return rows.filter((r) => !r.private);
|
return rows.filter((r) => !r.private);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** when diigo last updated the item, as `Date#toISOString()`, or "" when
|
||||||
|
* it carries no usable `updated_at` (diigo sends epoch *seconds*) */
|
||||||
|
export function updatedISO(item: Item): string {
|
||||||
|
const secs = item.updated_at;
|
||||||
|
if (typeof secs !== "number" || !Number.isFinite(secs)) return "";
|
||||||
|
return new Date(secs * 1000).toISOString();
|
||||||
|
}
|
||||||
@@ -117,6 +117,8 @@ describe("worker routes", () => {
|
|||||||
const again = await (await call(`/public/${username}?page=2`)).text();
|
const again = await (await call(`/public/${username}?page=2`)).text();
|
||||||
expect(again).toContain("<strong>cache: HIT");
|
expect(again).toContain("<strong>cache: HIT");
|
||||||
expect(html).toContain("bookmark 25");
|
expect(html).toContain("bookmark 25");
|
||||||
|
// the date comes first, in toISOString() form
|
||||||
|
expect(html).toMatch(/<li><time datetime="\d{4}-\d\d-\d\dT[\d:.]+Z">[^<]+<\/time> <a /);
|
||||||
expect(html).not.toContain("bookmark 27"); // private (27 % 3 === 0)
|
expect(html).not.toContain("bookmark 27"); // private (27 % 3 === 0)
|
||||||
|
|
||||||
const json = (await (
|
const json = (await (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { publicOnly, toRows, usernameOf } from "../src/items.js";
|
import { publicOnly, toRows, updatedISO, usernameOf } from "../src/items.js";
|
||||||
import type { Item } from "../src/items.js";
|
import type { Item } from "../src/items.js";
|
||||||
|
|
||||||
/** a load_user_items row: diigo's actual field names (observed
|
/** a load_user_items row: diigo's actual field names (observed
|
||||||
@@ -70,3 +70,14 @@ describe("publicOnly", () => {
|
|||||||
expect(JSON.stringify(rows)).not.toContain("secret.example");
|
expect(JSON.stringify(rows)).not.toContain("secret.example");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("updatedISO", () => {
|
||||||
|
it("reads diigo's updated_at as epoch seconds", () => {
|
||||||
|
expect(updatedISO({ updated_at: 1700000000 })).toBe("2023-11-14T22:13:20.000Z");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("answers empty when there is no usable date", () => {
|
||||||
|
expect(updatedISO({})).toBe("");
|
||||||
|
expect(updatedISO({ updated_at: "yesterday" })).toBe("");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in new issue
Block a user