refactor(housekeeping): restore ase preview namespace
This commit is contained in:
1 parent
3da84ffd87
commit
d868c990bf
21 files changed
+133
-112
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -9,7 +9,7 @@ export const contentManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.content.title",
|
labelKey: "pages.housekeeping.domains.content.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.content.description",
|
descriptionKey: "pages.housekeeping.domains.content.description",
|
||||||
iconId: "file-text",
|
iconId: "file-text",
|
||||||
previewHref: "/admin-next/content",
|
previewHref: "/ase-next/content",
|
||||||
capability: anyCapability(
|
capability: anyCapability(
|
||||||
PERMS.NEWS_VIEW,
|
PERMS.NEWS_VIEW,
|
||||||
PERMS.PAGES_VIEW,
|
PERMS.PAGES_VIEW,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const economyManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.economy.title",
|
labelKey: "pages.housekeeping.domains.economy.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.economy.description",
|
descriptionKey: "pages.housekeeping.domains.economy.description",
|
||||||
iconId: "gem",
|
iconId: "gem",
|
||||||
previewHref: "/admin-next/economy",
|
previewHref: "/ase-next/economy",
|
||||||
capability: anyCapability(
|
capability: anyCapability(
|
||||||
PERMS.CATALOG_VIEW,
|
PERMS.CATALOG_VIEW,
|
||||||
PERMS.SHOP_VIEW,
|
PERMS.SHOP_VIEW,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const hotelManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.hotel.title",
|
labelKey: "pages.housekeeping.domains.hotel.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.hotel.description",
|
descriptionKey: "pages.housekeeping.domains.hotel.description",
|
||||||
iconId: "hotel",
|
iconId: "hotel",
|
||||||
previewHref: "/admin-next/hotel",
|
previewHref: "/ase-next/hotel",
|
||||||
capability: anyCapability(
|
capability: anyCapability(
|
||||||
PERMS.ROOMS_VIEW,
|
PERMS.ROOMS_VIEW,
|
||||||
PERMS.RADIO_VIEW,
|
PERMS.RADIO_VIEW,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const operationsManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.operations.title",
|
labelKey: "pages.housekeeping.domains.operations.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.operations.description",
|
descriptionKey: "pages.housekeeping.domains.operations.description",
|
||||||
iconId: "inbox",
|
iconId: "inbox",
|
||||||
previewHref: "/admin-next/operations",
|
previewHref: "/ase-next/operations",
|
||||||
capability: anyCapability(PERMS.ADMIN_DASHBOARD),
|
capability: anyCapability(PERMS.ADMIN_DASHBOARD),
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [],
|
searchProviders: [],
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const peopleManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
previewHref: "/admin-next/people",
|
previewHref: "/ase-next/people",
|
||||||
capability: anyCapability(
|
capability: anyCapability(
|
||||||
PERMS.USERS_VIEW,
|
PERMS.USERS_VIEW,
|
||||||
PERMS.MODERATION_VIEW,
|
PERMS.MODERATION_VIEW,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const systemManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.system.title",
|
labelKey: "pages.housekeeping.domains.system.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.system.description",
|
descriptionKey: "pages.housekeeping.domains.system.description",
|
||||||
iconId: "settings",
|
iconId: "settings",
|
||||||
previewHref: "/admin-next/system",
|
previewHref: "/ase-next/system",
|
||||||
capability: anyCapability(
|
capability: anyCapability(
|
||||||
PERMS.SETTINGS_VIEW,
|
PERMS.SETTINGS_VIEW,
|
||||||
PERMS.LOGS_VIEW,
|
PERMS.LOGS_VIEW,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const workItem = {
|
|||||||
occurredAt: "2026-08-24T12:00:00.000Z",
|
occurredAt: "2026-08-24T12:00:00.000Z",
|
||||||
titleKey: "pages.housekeeping.items.ticket",
|
titleKey: "pages.housekeeping.items.ticket",
|
||||||
context: { ticketId: "42" },
|
context: { ticketId: "42" },
|
||||||
href: "/admin-next/people/tickets/42",
|
href: "/ase-next/people/tickets/42",
|
||||||
freshness: "fresh",
|
freshness: "fresh",
|
||||||
} satisfies HousekeepingWorkItem;
|
} satisfies HousekeepingWorkItem;
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ const searchResult = {
|
|||||||
id: "user-42",
|
id: "user-42",
|
||||||
domain: "people",
|
domain: "people",
|
||||||
title: "operator",
|
title: "operator",
|
||||||
href: "/admin-next/people/users/42",
|
href: "/ase-next/people/users/42",
|
||||||
} satisfies HousekeepingSearchResult;
|
} satisfies HousekeepingSearchResult;
|
||||||
|
|
||||||
const searchProvider: HousekeepingSearchProvider = {
|
const searchProvider: HousekeepingSearchProvider = {
|
||||||
@@ -87,7 +87,7 @@ const manifest: HousekeepingDomainManifest = {
|
|||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
previewHref: "/admin-next/people",
|
previewHref: "/ase-next/people",
|
||||||
capability,
|
capability,
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [searchProvider],
|
searchProviders: [searchProvider],
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export interface HousekeepingDomainManifest {
|
|||||||
labelKey: string;
|
labelKey: string;
|
||||||
descriptionKey: string;
|
descriptionKey: string;
|
||||||
iconId: "inbox" | "users" | "file-text" | "gem" | "hotel" | "settings";
|
iconId: "inbox" | "users" | "file-text" | "gem" | "hotel" | "settings";
|
||||||
previewHref: `/admin-next/${HousekeepingDomainId}`;
|
previewHref: `/ase-next/${HousekeepingDomainId}`;
|
||||||
capability: CapabilityRequirement;
|
capability: CapabilityRequirement;
|
||||||
routes: readonly HousekeepingRouteDefinition[];
|
routes: readonly HousekeepingRouteDefinition[];
|
||||||
searchProviders: readonly HousekeepingSearchProvider[];
|
searchProviders: readonly HousekeepingSearchProvider[];
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ describe("housekeeping foundation completion contracts", () => {
|
|||||||
for (const path of [
|
for (const path of [
|
||||||
"src/app/admin/layout.tsx",
|
"src/app/admin/layout.tsx",
|
||||||
"src/app/mod/layout.tsx",
|
"src/app/mod/layout.tsx",
|
||||||
"src/app/admin-next/layout.tsx",
|
"src/app/ase-next/layout.tsx",
|
||||||
]) {
|
]) {
|
||||||
expect(existsSync(path), path).toBe(true);
|
expect(existsSync(path), path).toBe(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ describe("housekeeping navigation", () => {
|
|||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
previewHref: "/admin-next/people",
|
previewHref: "/ase-next/people",
|
||||||
capability: anyCapability(PERMS.MOD_CFH_VIEW),
|
capability: anyCapability(PERMS.MOD_CFH_VIEW),
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [],
|
searchProviders: [],
|
||||||
@@ -35,7 +35,7 @@ describe("housekeeping navigation", () => {
|
|||||||
labelKey: "pages.housekeeping.domains.economy.title",
|
labelKey: "pages.housekeeping.domains.economy.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.economy.description",
|
descriptionKey: "pages.housekeeping.domains.economy.description",
|
||||||
iconId: "gem",
|
iconId: "gem",
|
||||||
previewHref: "/admin-next/economy",
|
previewHref: "/ase-next/economy",
|
||||||
capability: anyCapability(PERMS.CATALOG_VIEW),
|
capability: anyCapability(PERMS.CATALOG_VIEW),
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [],
|
searchProviders: [],
|
||||||
@@ -53,7 +53,7 @@ describe("housekeeping navigation", () => {
|
|||||||
expect(navigation).toEqual([
|
expect(navigation).toEqual([
|
||||||
{
|
{
|
||||||
id: "people",
|
id: "people",
|
||||||
href: "/admin-next/people",
|
href: "/ase-next/people",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
label: "pages.housekeeping.domains.people.title",
|
label: "pages.housekeeping.domains.people.title",
|
||||||
description: "pages.housekeeping.domains.people.description",
|
description: "pages.housekeeping.domains.people.description",
|
||||||
@@ -69,19 +69,19 @@ describe("housekeeping navigation", () => {
|
|||||||
labelKey: "people.title",
|
labelKey: "people.title",
|
||||||
descriptionKey: "people.description",
|
descriptionKey: "people.description",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
previewHref: "/admin-next/people",
|
previewHref: "/ase-next/people",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "people.users",
|
labelKey: "people.users",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "bans",
|
id: "bans",
|
||||||
labelKey: "people.bans",
|
labelKey: "people.bans",
|
||||||
href: "/admin-next/people/bans",
|
href: "/ase-next/people/bans",
|
||||||
capability: anyCapability(PERMS.BANS_VIEW),
|
capability: anyCapability(PERMS.BANS_VIEW),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -94,7 +94,7 @@ describe("housekeeping navigation", () => {
|
|||||||
labelKey: "system.title",
|
labelKey: "system.title",
|
||||||
descriptionKey: "system.description",
|
descriptionKey: "system.description",
|
||||||
iconId: "settings",
|
iconId: "settings",
|
||||||
previewHref: "/admin-next/system",
|
previewHref: "/ase-next/system",
|
||||||
capability: anyCapability(PERMS.SETTINGS_VIEW),
|
capability: anyCapability(PERMS.SETTINGS_VIEW),
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [],
|
searchProviders: [],
|
||||||
@@ -113,14 +113,14 @@ describe("housekeeping navigation", () => {
|
|||||||
expect(navigation).toEqual([
|
expect(navigation).toEqual([
|
||||||
{
|
{
|
||||||
id: "people",
|
id: "people",
|
||||||
href: "/admin-next/people",
|
href: "/ase-next/people",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
label: "translated:people.title",
|
label: "translated:people.title",
|
||||||
description: "translated:people.description",
|
description: "translated:people.description",
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
label: "translated:people.users",
|
label: "translated:people.users",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -75,12 +75,12 @@ describe("HousekeepingPageState", () => {
|
|||||||
state="error"
|
state="error"
|
||||||
title="Could not load"
|
title="Could not load"
|
||||||
description="Try again later"
|
description="Try again later"
|
||||||
retryAction={<a href="/admin-next/operations">Retry preview</a>}
|
retryAction={<a href="/ase-next/operations">Retry preview</a>}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(html).toContain('role="alert"');
|
expect(html).toContain('role="alert"');
|
||||||
expect(html).toContain('href="/admin-next/operations"');
|
expect(html).toContain('href="/ase-next/operations"');
|
||||||
expect(html).toContain(">Retry preview<");
|
expect(html).toContain(">Retry preview<");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -92,7 +92,7 @@ describe("HousekeepingPageShell", () => {
|
|||||||
title="People"
|
title="People"
|
||||||
description="Review operator-facing people data"
|
description="Review operator-facing people data"
|
||||||
context={<span>Preview context</span>}
|
context={<span>Preview context</span>}
|
||||||
primaryAction={<a href="/admin-next/people/new">Create preview</a>}
|
primaryAction={<a href="/ase-next/people/new">Create preview</a>}
|
||||||
>
|
>
|
||||||
<p>Page body</p>
|
<p>Page body</p>
|
||||||
</HousekeepingPageShell>,
|
</HousekeepingPageShell>,
|
||||||
@@ -102,7 +102,7 @@ describe("HousekeepingPageShell", () => {
|
|||||||
expect(html).toContain(">People<");
|
expect(html).toContain(">People<");
|
||||||
expect(html).toContain(">Review operator-facing people data<");
|
expect(html).toContain(">Review operator-facing people data<");
|
||||||
expect(html).toContain(">Preview context<");
|
expect(html).toContain(">Preview context<");
|
||||||
expect(html).toContain('href="/admin-next/people/new"');
|
expect(html).toContain('href="/ase-next/people/new"');
|
||||||
expect(html).toContain(">Create preview<");
|
expect(html).toContain(">Create preview<");
|
||||||
expect(html).toContain(">Page body</p>");
|
expect(html).toContain(">Page body</p>");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { execFileSync } from "node:child_process";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Housekeeping preview namespace", () => {
|
||||||
|
it("uses /ase-next and removes the previous runtime namespace", () => {
|
||||||
|
const removedNamespace = ["/admin", "-next"].join("");
|
||||||
|
const files = execFileSync("git", ["ls-files", "src", ".env.example"], {
|
||||||
|
encoding: "utf8",
|
||||||
|
})
|
||||||
|
.trim()
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
const offenders = files.filter((file) =>
|
||||||
|
readFileSync(file, "utf8").includes(removedNamespace),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(offenders).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -78,16 +78,16 @@ vi.mock("@/app/actions", () => {
|
|||||||
throw new Error("preview routes must not import actions");
|
throw new Error("preview routes must not import actions");
|
||||||
});
|
});
|
||||||
|
|
||||||
import AdminNextDomainLayout from "@/app/admin-next/[domain]/layout";
|
import AdminNextDomainLayout from "@/app/ase-next/[domain]/layout";
|
||||||
import AdminNextDomainPage from "@/app/admin-next/[domain]/page";
|
import AdminNextDomainPage from "@/app/ase-next/[domain]/page";
|
||||||
import AdminNextLayout from "@/app/admin-next/layout";
|
import AdminNextLayout from "@/app/ase-next/layout";
|
||||||
import AdminNextPage from "@/app/admin-next/page";
|
import AdminNextPage from "@/app/ase-next/page";
|
||||||
|
|
||||||
const routeFiles = [
|
const routeFiles = [
|
||||||
"src/app/admin-next/layout.tsx",
|
"src/app/ase-next/layout.tsx",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
"src/app/admin-next/[domain]/layout.tsx",
|
"src/app/ase-next/[domain]/layout.tsx",
|
||||||
"src/app/admin-next/[domain]/page.tsx",
|
"src/app/ase-next/[domain]/page.tsx",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const forbiddenModuleRoots = [
|
const forbiddenModuleRoots = [
|
||||||
@@ -360,7 +360,7 @@ async function renderRoute(route: ReactNode | Promise<ReactNode>) {
|
|||||||
return renderToStaticMarkup(await route);
|
return renderToStaticMarkup(await route);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("/admin-next preview gate", () => {
|
describe("/ase-next preview gate", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
routeMocks.env.NODE_ENV = "test";
|
routeMocks.env.NODE_ENV = "test";
|
||||||
@@ -402,7 +402,7 @@ describe("/admin-next preview gate", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("/admin-next first visible domain", () => {
|
describe("/ase-next first visible domain", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
@@ -413,9 +413,9 @@ describe("/admin-next first visible domain", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await expect(AdminNextPage()).rejects.toThrow(
|
await expect(AdminNextPage()).rejects.toThrow(
|
||||||
"NEXT_REDIRECT:/admin-next/operations",
|
"NEXT_REDIRECT:/ase-next/operations",
|
||||||
);
|
);
|
||||||
expect(routeMocks.redirect).toHaveBeenCalledWith("/admin-next/operations");
|
expect(routeMocks.redirect).toHaveBeenCalledWith("/ase-next/operations");
|
||||||
expect(routeMocks.getHousekeepingCapabilityContext).toHaveBeenCalledTimes(
|
expect(routeMocks.getHousekeepingCapabilityContext).toHaveBeenCalledTimes(
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@@ -428,9 +428,9 @@ describe("/admin-next first visible domain", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await expect(AdminNextPage()).rejects.toThrow(
|
await expect(AdminNextPage()).rejects.toThrow(
|
||||||
"NEXT_REDIRECT:/admin-next/people",
|
"NEXT_REDIRECT:/ase-next/people",
|
||||||
);
|
);
|
||||||
expect(routeMocks.redirect).toHaveBeenCalledWith("/admin-next/people");
|
expect(routeMocks.redirect).toHaveBeenCalledWith("/ase-next/people");
|
||||||
expect(routeMocks.getHousekeepingCapabilityContext).toHaveBeenCalledTimes(
|
expect(routeMocks.getHousekeepingCapabilityContext).toHaveBeenCalledTimes(
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@@ -450,7 +450,7 @@ describe("/admin-next first visible domain", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("/admin-next/[domain] layout", () => {
|
describe("/ase-next/[domain] layout", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
@@ -515,7 +515,7 @@ describe("/admin-next/[domain] layout", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("/admin-next/[domain] page", () => {
|
describe("/ase-next/[domain] page", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
@@ -561,247 +561,247 @@ describe("preview route import boundary", () => {
|
|||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
"relative database import with resolver extension",
|
"relative database import with resolver extension",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../../lib/db.js";',
|
'import db from "../../lib/db.js";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"aliased database import with resolver extension",
|
"aliased database import with resolver extension",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "@/lib/db.js";',
|
'import db from "@/lib/db.js";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"action root import with resolver extension",
|
"action root import with resolver extension",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import actions from "../../actions.mjs";',
|
'import actions from "../../actions.mjs";',
|
||||||
"src/actions",
|
"src/actions",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"legacy mod root import with resolver extension",
|
"legacy mod root import with resolver extension",
|
||||||
"src/app/admin-next/layout.tsx",
|
"src/app/ase-next/layout.tsx",
|
||||||
'import mod from "../mod.cjs";',
|
'import mod from "../mod.cjs";',
|
||||||
"src/app/mod",
|
"src/app/mod",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"database import with query suffix",
|
"database import with query suffix",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../../lib/db?server-only";',
|
'import db from "../../lib/db?server-only";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"action import with hash suffix",
|
"action import with hash suffix",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import("../../actions/users#server")',
|
'import("../../actions/users#server")',
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Windows-style relative database import",
|
"Windows-style relative database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
String.raw`import db from "..\\..\\lib\\db";`,
|
String.raw`import db from "..\\..\\lib\\db";`,
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Windows-style aliased database import",
|
"Windows-style aliased database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
String.raw`import db from "@\\lib\\db";`,
|
String.raw`import db from "@\\lib\\db";`,
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"percent-encoded database import",
|
"percent-encoded database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../../lib/%64%62";',
|
'import db from "../../lib/%64%62";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"optional CommonJS database require",
|
"optional CommonJS database require",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'require?.("../../lib/db")',
|
'require?.("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"module database require",
|
"module database require",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'module.require("../../lib/db")',
|
'module.require("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"require.resolve database access",
|
"require.resolve database access",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'require.resolve("../../lib/db")',
|
'require.resolve("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"optional module database require",
|
"optional module database require",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'module.require?.("../../lib/db")',
|
'module.require?.("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"optional require.resolve database access",
|
"optional require.resolve database access",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'require.resolve?.("../../lib/db")',
|
'require.resolve?.("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"TypeScript import-equals database access",
|
"TypeScript import-equals database access",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db = require("../../lib/db");',
|
'import db = require("../../lib/db");',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"U+2028 line-continuation database import",
|
"U+2028 line-continuation database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../\\' + "\u2028" + '../lib/db";',
|
'import db from "../\\' + "\u2028" + '../lib/db";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"U+2029 line-continuation database import",
|
"U+2029 line-continuation database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../\\' + "\u2029" + '../lib/db";',
|
'import db from "../\\' + "\u2029" + '../lib/db";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"parenthesized dynamic action import",
|
"parenthesized dynamic action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import(("../../actions/users"))',
|
'import(("../../actions/users"))',
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"regex-brace template-expression action import",
|
"regex-brace template-expression action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
`const x = \`${interpolationOpen}/}/.test(value) ? import("../../actions/users") : null}\`;`,
|
`const x = \`${interpolationOpen}/}/.test(value) ? import("../../actions/users") : null}\`;`,
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"CommonJS database require",
|
"CommonJS database require",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'require("../../lib/db")',
|
'require("../../lib/db")',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"template-literal dynamic action import",
|
"template-literal dynamic action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
"import(`../../actions/users`)",
|
"import(`../../actions/users`)",
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"TypeScript-asserted dynamic action import",
|
"TypeScript-asserted dynamic action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import(("../../actions/users" as string))',
|
'import(("../../actions/users" as string))',
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"template-expression dynamic action import",
|
"template-expression dynamic action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
`const x = \`${interpolationOpen}import("../../actions/users")}\`;`,
|
`const x = \`${interpolationOpen}import("../../actions/users")}\`;`,
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"nested template-expression dynamic action import",
|
"nested template-expression dynamic action import",
|
||||||
"src/app/admin-next/[domain]/page.tsx",
|
"src/app/ase-next/[domain]/page.tsx",
|
||||||
`const x = \`${interpolationOpen}ready ? \`${interpolationOpen}import("../../../actions/nested")}\` : ""}\`;`,
|
`const x = \`${interpolationOpen}ready ? \`${interpolationOpen}import("../../../actions/nested")}\` : ""}\`;`,
|
||||||
"src/actions/nested",
|
"src/actions/nested",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"unicode escaped dynamic app-action import",
|
"unicode escaped dynamic app-action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import("\\u002e\\u002e/actions/users")',
|
'import("\\u002e\\u002e/actions/users")',
|
||||||
"src/app/actions/users",
|
"src/app/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"code-point escaped dynamic app-action import",
|
"code-point escaped dynamic app-action import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import("\\u{2e}\\u{2e}/actions/users")',
|
'import("\\u{2e}\\u{2e}/actions/users")',
|
||||||
"src/app/actions/users",
|
"src/app/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"hex escaped export-from auth import",
|
"hex escaped export-from auth import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'export * from "\\x2e\\x2e/\\x2e\\x2e/lib/auth";',
|
'export * from "\\x2e\\x2e/\\x2e\\x2e/lib/auth";',
|
||||||
"src/lib/auth",
|
"src/lib/auth",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"escaped-slash permissions import",
|
"escaped-slash permissions import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import permissions from "..\\/..\\/lib\\/permissions";',
|
'import permissions from "..\\/..\\/lib\\/permissions";',
|
||||||
"src/lib/permissions",
|
"src/lib/permissions",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"unknown escape database import",
|
"unknown escape database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../../\\lib/db";',
|
'import db from "../../\\lib/db";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"line-continuation database import",
|
"line-continuation database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import db from "../\\' + "\n" + '../lib/db";',
|
'import db from "../\\' + "\n" + '../lib/db";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"aliased database descendant import",
|
"aliased database descendant import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import { query } from "@/lib/db/query";',
|
'import { query } from "@/lib/db/query";',
|
||||||
"src/lib/db/query",
|
"src/lib/db/query",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"root relative database import",
|
"root relative database import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import { db } from "../../lib/db";',
|
'import { db } from "../../lib/db";',
|
||||||
"src/lib/db",
|
"src/lib/db",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"domain relative auth side-effect import",
|
"domain relative auth side-effect import",
|
||||||
"src/app/admin-next/[domain]/layout.tsx",
|
"src/app/ase-next/[domain]/layout.tsx",
|
||||||
'import "../../../lib/auth";',
|
'import "../../../lib/auth";',
|
||||||
"src/lib/auth",
|
"src/lib/auth",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"domain relative permissions export",
|
"domain relative permissions export",
|
||||||
"src/app/admin-next/[domain]/page.tsx",
|
"src/app/ase-next/[domain]/page.tsx",
|
||||||
'export { getAdminContext } from "../../../lib/permissions";',
|
'export { getAdminContext } from "../../../lib/permissions";',
|
||||||
"src/lib/permissions",
|
"src/lib/permissions",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"root relative action dynamic import",
|
"root relative action dynamic import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import("../../actions/users")',
|
'import("../../actions/users")',
|
||||||
"src/actions/users",
|
"src/actions/users",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"root relative app action export",
|
"root relative app action export",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'export * from "../actions";',
|
'export * from "../actions";',
|
||||||
"src/app/actions",
|
"src/app/actions",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"domain relative legacy admin import",
|
"domain relative legacy admin import",
|
||||||
"src/app/admin-next/[domain]/layout.tsx",
|
"src/app/ase-next/[domain]/layout.tsx",
|
||||||
'import page from "../../admin/users/page";',
|
'import page from "../../admin/users/page";',
|
||||||
"src/app/admin/users/page",
|
"src/app/admin/users/page",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"root relative legacy mod dynamic import",
|
"root relative legacy mod dynamic import",
|
||||||
"src/app/admin-next/layout.tsx",
|
"src/app/ase-next/layout.tsx",
|
||||||
'import("../mod/users/page")',
|
'import("../mod/users/page")',
|
||||||
"src/app/mod/users/page",
|
"src/app/mod/users/page",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Prisma TypeScript import type",
|
"Prisma TypeScript import type",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'type PrismaClient = import("@prisma/client").PrismaClient;',
|
'type PrismaClient = import("@prisma/client").PrismaClient;',
|
||||||
"@prisma/client",
|
"@prisma/client",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Drizzle package import",
|
"Drizzle package import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import { sql } from "drizzle-orm";',
|
'import { sql } from "drizzle-orm";',
|
||||||
"drizzle-orm",
|
"drizzle-orm",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"mysql2 package import",
|
"mysql2 package import",
|
||||||
"src/app/admin-next/page.tsx",
|
"src/app/ase-next/page.tsx",
|
||||||
'import type { Pool } from "mysql2";',
|
'import type { Pool } from "mysql2";',
|
||||||
"mysql2",
|
"mysql2",
|
||||||
],
|
],
|
||||||
@@ -834,7 +834,7 @@ describe("preview route import boundary", () => {
|
|||||||
],
|
],
|
||||||
] as const)("fails closed for non-literal %s", (_name, source, violation) => {
|
] as const)("fails closed for non-literal %s", (_name, source, violation) => {
|
||||||
expect(
|
expect(
|
||||||
findRouteImportBoundaryViolations(source, "src/app/admin-next/page.tsx"),
|
findRouteImportBoundaryViolations(source, "src/app/ase-next/page.tsx"),
|
||||||
).toContain(violation);
|
).toContain(violation);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -843,7 +843,7 @@ describe("preview route import boundary", () => {
|
|||||||
'import database from "@/lib/database.js?raw";',
|
'import database from "@/lib/database.js?raw";',
|
||||||
'import dbTools from "../../lib/db-tools.ts";',
|
'import dbTools from "../../lib/db-tools.ts";',
|
||||||
'import auth from "../../lib/authentication";',
|
'import auth from "../../lib/authentication";',
|
||||||
'import preview from "../admin-next-shared";',
|
'import preview from "../ase-next-shared";',
|
||||||
'import prismaTools from "@prisma/client-tools";',
|
'import prismaTools from "@prisma/client-tools";',
|
||||||
'import drizzleTools from "drizzle-orm-kit";',
|
'import drizzleTools from "drizzle-orm-kit";',
|
||||||
'import mysqlTools from "mysql2-wrapper";',
|
'import mysqlTools from "mysql2-wrapper";',
|
||||||
@@ -853,7 +853,7 @@ describe("preview route import boundary", () => {
|
|||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
findRouteImportBoundaryViolations(source, "src/app/admin-next/page.tsx"),
|
findRouteImportBoundaryViolations(source, "src/app/ase-next/page.tsx"),
|
||||||
).toEqual([]);
|
).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -25,7 +25,7 @@ const manifest = (
|
|||||||
labelKey: `pages.housekeeping.domains.${id}.title`,
|
labelKey: `pages.housekeeping.domains.${id}.title`,
|
||||||
descriptionKey: `pages.housekeeping.domains.${id}.description`,
|
descriptionKey: `pages.housekeeping.domains.${id}.description`,
|
||||||
iconId: "settings",
|
iconId: "settings",
|
||||||
previewHref: `/admin-next/${id}`,
|
previewHref: `/ase-next/${id}`,
|
||||||
capability: anyCapability(capabilitySlug),
|
capability: anyCapability(capabilitySlug),
|
||||||
routes: [],
|
routes: [],
|
||||||
searchProviders: [],
|
searchProviders: [],
|
||||||
@@ -73,7 +73,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "operations",
|
id: "operations",
|
||||||
iconId: "inbox",
|
iconId: "inbox",
|
||||||
previewHref: "/admin-next/operations",
|
previewHref: "/ase-next/operations",
|
||||||
labelKey: "pages.housekeeping.domains.operations.title",
|
labelKey: "pages.housekeeping.domains.operations.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.operations.description",
|
descriptionKey: "pages.housekeeping.domains.operations.description",
|
||||||
slugs: [PERMS.ADMIN_DASHBOARD],
|
slugs: [PERMS.ADMIN_DASHBOARD],
|
||||||
@@ -81,7 +81,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "people",
|
id: "people",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
previewHref: "/admin-next/people",
|
previewHref: "/ase-next/people",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.people.description",
|
descriptionKey: "pages.housekeeping.domains.people.description",
|
||||||
slugs: [
|
slugs: [
|
||||||
@@ -112,7 +112,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "content",
|
id: "content",
|
||||||
iconId: "file-text",
|
iconId: "file-text",
|
||||||
previewHref: "/admin-next/content",
|
previewHref: "/ase-next/content",
|
||||||
labelKey: "pages.housekeeping.domains.content.title",
|
labelKey: "pages.housekeeping.domains.content.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.content.description",
|
descriptionKey: "pages.housekeeping.domains.content.description",
|
||||||
slugs: [
|
slugs: [
|
||||||
@@ -135,7 +135,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "economy",
|
id: "economy",
|
||||||
iconId: "gem",
|
iconId: "gem",
|
||||||
previewHref: "/admin-next/economy",
|
previewHref: "/ase-next/economy",
|
||||||
labelKey: "pages.housekeeping.domains.economy.title",
|
labelKey: "pages.housekeeping.domains.economy.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.economy.description",
|
descriptionKey: "pages.housekeeping.domains.economy.description",
|
||||||
slugs: [
|
slugs: [
|
||||||
@@ -148,7 +148,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "hotel",
|
id: "hotel",
|
||||||
iconId: "hotel",
|
iconId: "hotel",
|
||||||
previewHref: "/admin-next/hotel",
|
previewHref: "/ase-next/hotel",
|
||||||
labelKey: "pages.housekeeping.domains.hotel.title",
|
labelKey: "pages.housekeeping.domains.hotel.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.hotel.description",
|
descriptionKey: "pages.housekeeping.domains.hotel.description",
|
||||||
slugs: [
|
slugs: [
|
||||||
@@ -165,7 +165,7 @@ const expectedManifests = [
|
|||||||
{
|
{
|
||||||
id: "system",
|
id: "system",
|
||||||
iconId: "settings",
|
iconId: "settings",
|
||||||
previewHref: "/admin-next/system",
|
previewHref: "/ase-next/system",
|
||||||
labelKey: "pages.housekeeping.domains.system.title",
|
labelKey: "pages.housekeeping.domains.system.title",
|
||||||
descriptionKey: "pages.housekeeping.domains.system.description",
|
descriptionKey: "pages.housekeeping.domains.system.description",
|
||||||
slugs: [
|
slugs: [
|
||||||
@@ -208,7 +208,7 @@ describe("housekeeping registry", () => {
|
|||||||
it("rejects invalid preview and empty translation keys", () => {
|
it("rejects invalid preview and empty translation keys", () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
createHousekeepingRegistry([
|
createHousekeepingRegistry([
|
||||||
{ ...manifest("people"), previewHref: "/admin-next/operations" },
|
{ ...manifest("people"), previewHref: "/ase-next/operations" },
|
||||||
]),
|
]),
|
||||||
).toThrow("invalid preview href");
|
).toThrow("invalid preview href");
|
||||||
expect(() =>
|
expect(() =>
|
||||||
@@ -232,13 +232,13 @@ describe("housekeeping registry", () => {
|
|||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/staff",
|
href: "/ase-next/people/staff",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -253,13 +253,13 @@ describe("housekeeping registry", () => {
|
|||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "staff",
|
id: "staff",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -272,7 +272,7 @@ describe("housekeeping registry", () => {
|
|||||||
const route = {
|
const route = {
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ describe("housekeeping registry", () => {
|
|||||||
{
|
{
|
||||||
id: "users",
|
id: "users",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/people/users",
|
href: "/ase-next/people/users",
|
||||||
capability: { mode: "any", slugs: [] },
|
capability: { mode: "any", slugs: [] },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -494,7 +494,7 @@ describe("housekeeping registry", () => {
|
|||||||
const route = {
|
const route = {
|
||||||
id: "shared",
|
id: "shared",
|
||||||
labelKey: "pages.housekeeping.domains.people.title",
|
labelKey: "pages.housekeeping.domains.people.title",
|
||||||
href: "/admin-next/shared",
|
href: "/ase-next/shared",
|
||||||
capability: anyCapability(PERMS.USERS_VIEW),
|
capability: anyCapability(PERMS.USERS_VIEW),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -503,7 +503,7 @@ describe("housekeeping registry", () => {
|
|||||||
{ ...manifest("people"), routes: [route] },
|
{ ...manifest("people"), routes: [route] },
|
||||||
{
|
{
|
||||||
...manifest("content"),
|
...manifest("content"),
|
||||||
routes: [{ ...route, href: "/admin-next/content/shared" }],
|
routes: [{ ...route, href: "/ase-next/content/shared" }],
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
).toThrow("duplicate route id");
|
).toThrow("duplicate route id");
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export function createHousekeepingRegistry(
|
|||||||
}
|
}
|
||||||
domainIds.add(manifest.id);
|
domainIds.add(manifest.id);
|
||||||
|
|
||||||
if (manifest.previewHref !== `/admin-next/${manifest.id}`) {
|
if (manifest.previewHref !== `/ase-next/${manifest.id}`) {
|
||||||
throw new Error(`invalid preview href: ${manifest.previewHref}`);
|
throw new Error(`invalid preview href: ${manifest.previewHref}`);
|
||||||
}
|
}
|
||||||
validateNonEmpty(manifest.labelKey, "label key");
|
validateNonEmpty(manifest.labelKey, "label key");
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ const labels = {
|
|||||||
const domains: readonly HousekeepingNavigationDomain[] = [
|
const domains: readonly HousekeepingNavigationDomain[] = [
|
||||||
{
|
{
|
||||||
id: "operations",
|
id: "operations",
|
||||||
href: "/admin-next/operations",
|
href: "/ase-next/operations",
|
||||||
iconId: "inbox",
|
iconId: "inbox",
|
||||||
label: "Operations",
|
label: "Operations",
|
||||||
description: "Manage operations",
|
description: "Manage operations",
|
||||||
items: [
|
items: [
|
||||||
{ id: "queue", href: "/admin-next/operations/queue", label: "Queue" },
|
{ id: "queue", href: "/ase-next/operations/queue", label: "Queue" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "people",
|
id: "people",
|
||||||
href: "/admin-next/people",
|
href: "/ase-next/people",
|
||||||
iconId: "users",
|
iconId: "users",
|
||||||
label: "People",
|
label: "People",
|
||||||
description: "Manage people",
|
description: "Manage people",
|
||||||
@@ -35,7 +35,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "content",
|
id: "content",
|
||||||
href: "/admin-next/content",
|
href: "/ase-next/content",
|
||||||
iconId: "file-text",
|
iconId: "file-text",
|
||||||
label: "Content",
|
label: "Content",
|
||||||
description: "Manage content",
|
description: "Manage content",
|
||||||
@@ -43,7 +43,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "economy",
|
id: "economy",
|
||||||
href: "/admin-next/economy",
|
href: "/ase-next/economy",
|
||||||
iconId: "gem",
|
iconId: "gem",
|
||||||
label: "Economy",
|
label: "Economy",
|
||||||
description: "Manage economy",
|
description: "Manage economy",
|
||||||
@@ -51,7 +51,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "hotel",
|
id: "hotel",
|
||||||
href: "/admin-next/hotel",
|
href: "/ase-next/hotel",
|
||||||
iconId: "hotel",
|
iconId: "hotel",
|
||||||
label: "Hotel",
|
label: "Hotel",
|
||||||
description: "Manage hotel",
|
description: "Manage hotel",
|
||||||
@@ -59,7 +59,7 @@ const domains: readonly HousekeepingNavigationDomain[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "system",
|
id: "system",
|
||||||
href: "/admin-next/system",
|
href: "/ase-next/system",
|
||||||
iconId: "settings",
|
iconId: "settings",
|
||||||
label: "System",
|
label: "System",
|
||||||
description: "Manage system",
|
description: "Manage system",
|
||||||
@@ -178,7 +178,7 @@ describe("HousekeepingShell", () => {
|
|||||||
expect(html).toContain('<nav aria-label="Operations navigation"');
|
expect(html).toContain('<nav aria-label="Operations navigation"');
|
||||||
expect(html).toContain('<main id="housekeeping-content"');
|
expect(html).toContain('<main id="housekeeping-content"');
|
||||||
expect(html).toContain(">Deck body</p>");
|
expect(html).toContain(">Deck body</p>");
|
||||||
expect(html).toContain('href="/admin-next/operations/queue"');
|
expect(html).toContain('href="/ase-next/operations/queue"');
|
||||||
expect(html).toContain(">Queue<");
|
expect(html).toContain(">Queue<");
|
||||||
expect(html).toContain(">Nora<");
|
expect(html).toContain(">Nora<");
|
||||||
expect(html).toContain(">6<");
|
expect(html).toContain(">6<");
|
||||||
@@ -196,7 +196,7 @@ describe("HousekeepingShell", () => {
|
|||||||
const activeAnchors = allAnchors.filter((anchor) =>
|
const activeAnchors = allAnchors.filter((anchor) =>
|
||||||
anchor.includes('aria-current="page"'),
|
anchor.includes('aria-current="page"'),
|
||||||
);
|
);
|
||||||
const peopleAnchor = anchorForHref(html, "/admin-next/people");
|
const peopleAnchor = anchorForHref(html, "/ase-next/people");
|
||||||
for (const iconClass of [
|
for (const iconClass of [
|
||||||
"lucide-inbox",
|
"lucide-inbox",
|
||||||
"lucide-users",
|
"lucide-users",
|
||||||
@@ -222,7 +222,7 @@ describe("HousekeepingShell", () => {
|
|||||||
);
|
);
|
||||||
expect(() => renderShell("system", domainsWithoutSystem)).not.toThrow();
|
expect(() => renderShell("system", domainsWithoutSystem)).not.toThrow();
|
||||||
const html = renderShell("system", domainsWithoutSystem);
|
const html = renderShell("system", domainsWithoutSystem);
|
||||||
expect(html).not.toContain('href="/admin-next/operations/queue"');
|
expect(html).not.toContain('href="/ase-next/operations/queue"');
|
||||||
expect(html).not.toContain(">Queue<");
|
expect(html).not.toContain(">Queue<");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
const ROOTS = [
|
const ROOTS = [
|
||||||
"src/app/admin",
|
"src/app/admin",
|
||||||
"src/components/admin",
|
"src/components/admin",
|
||||||
"src/app/admin-next",
|
"src/app/ase-next",
|
||||||
"src/features/housekeeping",
|
"src/features/housekeeping",
|
||||||
];
|
];
|
||||||
const GRAPHICAL_ALLOWLIST = [
|
const GRAPHICAL_ALLOWLIST = [
|
||||||
|
|||||||
Reference in new issue
Block a user