Files
immich-folio/lib/admin/pageRefs.ts
Ralksta ad8b09700b release: v0.19.0
Release v0.19.0. See the `## [0.19.0] — 2026-09-29` section of
[CHANGELOG.md](https://github.com/ralksta/immich-folio/blob/dev/CHANGELOG.md)
for the full list.

Highlights: client proofing links (#683), custom content pages (#738),
asset picker search (#740), concurrent-edit detection (#742), env-locked
settings (#739), an accessibility baseline (#741), three security fixes
with advisories (#737, #755, #759), and a pre-release quality pass
(#780–#797).

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: ralksta <ralksta@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ralf <rohlenbo79@gmail.com>
Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com>
Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com>
Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
2026-09-29 22:50:30 +02:00

60 lines
2.4 KiB
TypeScript

/**
* Keep gallery.yaml's `- page: <slug>` references in step with the page files
* (#722): a deleted page leaves the menu, a renamed one keeps its place.
*
* Server only. Writes go through writeGalleryYaml(), so the previous
* gallery.yaml is backed up first like every other admin save.
*/
import { readGalleryYamlVersioned, writeGalleryYaml } from './yaml-service';
import { VersionConflictError } from './contentVersion';
import { invalidateConfigCache, isPageRef } from '../config';
/**
* Pure: the `subpages:` list with every reference to `from` replaced by `to`,
* or dropped when `to` is null. Returns the same list when nothing matched.
*/
export function rewritePageRefs<T>(subpages: T[], from: string, to: string | null): T[] {
if (!subpages.some((e) => isPageRef(e) && e.page === from)) return subpages;
return subpages.flatMap((entry) => {
if (!isPageRef(entry) || entry.page !== from) return [entry];
return to === null ? [] : [{ ...entry, page: to } as T];
});
}
/** gallery.yaml's version before and after a menu rewrite (#601). */
export interface GalleryVersionChange {
from: string;
to: string;
}
/**
* Apply rewritePageRefs() to gallery.yaml on disk. Returns the version change
* when the file changed, null when it did not.
*
* The page builder is open while this runs and holds gallery.yaml's version.
* With `from` and `to` it can tell "only this rewrite happened since I loaded"
* (take the new version) from "someone else saved too" (keep the old one, so
* its next save is refused rather than clobbering). The write itself is
* checked against the version read here, and re-read on a conflict, so a
* builder save racing the rewrite is not overwritten either.
*/
export async function updatePageRefs(
from: string,
to: string | null,
): Promise<GalleryVersionChange | null> {
for (let attempt = 0; ; attempt++) {
const { data: gallery, version } = await readGalleryYamlVersioned();
if (!gallery || !Array.isArray(gallery.subpages)) return null;
const next = rewritePageRefs(gallery.subpages, from, to);
if (next === gallery.subpages) return null;
try {
const written = await writeGalleryYaml({ ...gallery, subpages: next }, version);
invalidateConfigCache();
return { from: version, to: written };
} catch (err) {
if (!(err instanceof VersionConflictError) || attempt >= 2) throw err;
}
}
}