@@ -615,7 +615,7 @@ export function WordPressImport() {
diff --git a/packages/admin/src/components/auth/PasskeyLogin.tsx b/packages/admin/src/components/auth/PasskeyLogin.tsx
index 6e155a58f..610ec2e85 100644
--- a/packages/admin/src/components/auth/PasskeyLogin.tsx
+++ b/packages/admin/src/components/auth/PasskeyLogin.tsx
@@ -173,7 +173,7 @@ export function PasskeyLogin({
const optionsData = await parseApiResponse<{
options: PublicKeyCredentialRequestOptionsJSON;
- }>(optionsResponse, "Failed to get authentication options");
+ }>(optionsResponse, t`Failed to get authentication options`);
const { options } = optionsData;
// Step 2: Get assertion from browser
@@ -247,13 +247,13 @@ export function PasskeyLogin({
const result = await parseApiResponse
(
verifyResponse,
- "Failed to verify authentication",
+ t`Failed to verify authentication`,
);
setState({ status: "success" });
onSuccess(result);
} catch (error) {
- const message = error instanceof Error ? error.message : "Authentication failed";
+ const message = error instanceof Error ? error.message : t`Authentication failed`;
// Handle specific WebAuthn errors
let userMessage = message;
diff --git a/packages/admin/src/components/auth/PasskeyRegistration.tsx b/packages/admin/src/components/auth/PasskeyRegistration.tsx
index 60732b85b..7d5708bdb 100644
--- a/packages/admin/src/components/auth/PasskeyRegistration.tsx
+++ b/packages/admin/src/components/auth/PasskeyRegistration.tsx
@@ -177,7 +177,7 @@ export function PasskeyRegistration({
const optionsData = await parseApiResponse<{
options: PublicKeyCredentialCreationOptionsJSON;
- }>(optionsResponse, "Failed to get registration options");
+ }>(optionsResponse, t`Failed to get registration options`);
const { options } = optionsData;
// Step 2: Create credential with browser
@@ -250,13 +250,13 @@ export function PasskeyRegistration({
const result = await parseApiResponse(
verifyResponse,
- "Failed to verify registration",
+ t`Failed to verify registration`,
);
setState({ status: "success" });
onSuccess(result);
} catch (error) {
- const message = error instanceof Error ? error.message : "Registration failed";
+ const message = error instanceof Error ? error.message : t`Registration failed`;
// Handle specific WebAuthn errors
let userMessage = message;
diff --git a/packages/admin/src/components/editor/BlockMenu.tsx b/packages/admin/src/components/editor/BlockMenu.tsx
index 5043289e4..44658099a 100644
--- a/packages/admin/src/components/editor/BlockMenu.tsx
+++ b/packages/admin/src/components/editor/BlockMenu.tsx
@@ -251,7 +251,7 @@ export function BlockMenu({ editor, anchorElement, isOpen, onClose }: BlockMenuP
onClick={() => setShowTransforms(false)}
>
- Back
+ {t`Back`}
{blockTransforms.map((transform) => (
@@ -276,7 +276,7 @@ export function BlockMenu({ editor, anchorElement, isOpen, onClose }: BlockMenuP
>
- Turn into
+ {t`Turn into`}
@@ -286,7 +286,7 @@ export function BlockMenu({ editor, anchorElement, isOpen, onClose }: BlockMenuP
onClick={handleDuplicate}
>
- Duplicate
+ {t`Duplicate`}
)}
@@ -317,6 +317,7 @@ interface BlockHandleProps {
}
export function BlockHandle({ onClick, onDragStart, selected }: BlockHandleProps) {
+ const { t } = useLingui();
return (
diff --git a/packages/admin/src/components/editor/DragHandleWrapper.tsx b/packages/admin/src/components/editor/DragHandleWrapper.tsx
index 4b8b6a983..2d75374cd 100644
--- a/packages/admin/src/components/editor/DragHandleWrapper.tsx
+++ b/packages/admin/src/components/editor/DragHandleWrapper.tsx
@@ -8,6 +8,7 @@
* - Block menu integration for transforms, duplicate, delete
*/
+import { useLingui } from "@lingui/react/macro";
import { DotsSixVertical } from "@phosphor-icons/react";
import type { Editor } from "@tiptap/core";
import { DragHandle } from "@tiptap/extension-drag-handle-react";
@@ -41,6 +42,7 @@ declare module "@tiptap/core" {
* DragHandleWrapper - Official TipTap drag handle with BlockMenu integration
*/
export function DragHandleWrapper({ editor }: DragHandleWrapperProps) {
+ const { t } = useLingui();
const [hoveredNode, setHoveredNode] = React.useState
(null);
const [menuOpen, setMenuOpen] = React.useState(false);
const [menuAnchor, setMenuAnchor] = React.useState(null);
@@ -120,7 +122,7 @@ export function DragHandleWrapper({ editor }: DragHandleWrapperProps) {
)}
onClick={handleClick}
data-block-handle
- aria-label="Block actions - drag to reorder, click for menu"
+ aria-label={t`Block actions - drag to reorder, click for menu`}
>
diff --git a/packages/admin/src/lib/api/api-tokens.ts b/packages/admin/src/lib/api/api-tokens.ts
index 7e106ef81..010bb62a5 100644
--- a/packages/admin/src/lib/api/api-tokens.ts
+++ b/packages/admin/src/lib/api/api-tokens.ts
@@ -2,6 +2,9 @@
* API token management client functions
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
// =============================================================================
@@ -92,5 +95,5 @@ export async function revokeApiToken(id: string): Promise {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to revoke API token");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to revoke API token`));
}
diff --git a/packages/admin/src/lib/api/bylines.ts b/packages/admin/src/lib/api/bylines.ts
index c1abb2239..54a3060a1 100644
--- a/packages/admin/src/lib/api/bylines.ts
+++ b/packages/admin/src/lib/api/bylines.ts
@@ -1,3 +1,6 @@
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import {
API_BASE,
apiFetch,
@@ -83,5 +86,5 @@ export async function deleteByline(id: string): Promise {
const response = await apiFetch(`${API_BASE}/admin/bylines/${id}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete byline");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete byline`));
}
diff --git a/packages/admin/src/lib/api/client.ts b/packages/admin/src/lib/api/client.ts
index 53a5c4532..eca38c8f2 100644
--- a/packages/admin/src/lib/api/client.ts
+++ b/packages/admin/src/lib/api/client.ts
@@ -3,6 +3,8 @@
*/
import type { Element } from "@emdash-cms/blocks";
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
export const API_BASE = "/_emdash/api";
@@ -182,7 +184,7 @@ export async function parseApiResponse(
*/
export async function fetchManifest(): Promise {
const response = await apiFetch(`${API_BASE}/manifest`);
- return parseApiResponse(response, "Failed to fetch manifest");
+ return parseApiResponse(response, i18n._(msg`Failed to fetch manifest`));
}
/**
diff --git a/packages/admin/src/lib/api/comments.ts b/packages/admin/src/lib/api/comments.ts
index b2078b35f..d26f3512c 100644
--- a/packages/admin/src/lib/api/comments.ts
+++ b/packages/admin/src/lib/api/comments.ts
@@ -2,6 +2,9 @@
* Comment moderation API client
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import {
API_BASE,
apiFetch,
@@ -105,7 +108,7 @@ export async function deleteComment(id: string): Promise {
const response = await apiFetch(`${API_BASE}/admin/comments/${id}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete comment");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete comment`));
}
/**
diff --git a/packages/admin/src/lib/api/content.ts b/packages/admin/src/lib/api/content.ts
index ffa8ad30d..7d3fe3451 100644
--- a/packages/admin/src/lib/api/content.ts
+++ b/packages/admin/src/lib/api/content.ts
@@ -2,6 +2,9 @@
* Content CRUD and revision APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import type { BylineCreditInput, BylineSummary } from "./bylines.js";
import {
API_BASE,
@@ -211,7 +214,7 @@ export async function deleteContent(collection: string, id: string): Promise {
if (response.status === 404) {
throw new Error(`Revision not found: ${revisionId}`);
}
- await throwResponseError(response, "Failed to fetch revision");
+ await throwResponseError(response, i18n._(msg`Failed to fetch revision`));
}
- const data = await parseApiResponse<{ item: Revision }>(response, "Failed to fetch revision");
+ const data = await parseApiResponse<{ item: Revision }>(
+ response,
+ i18n._(msg`Failed to fetch revision`),
+ );
return data.item;
}
@@ -474,12 +481,12 @@ export async function restoreRevision(revisionId: string): Promise
if (response.status === 404) {
throw new Error(`Revision not found: ${revisionId}`);
}
- await throwResponseError(response, "Failed to restore revision");
+ await throwResponseError(response, i18n._(msg`Failed to restore revision`));
}
const data = await parseApiResponse<{ item: ContentItem }>(
response,
- "Failed to restore revision",
+ i18n._(msg`Failed to restore revision`),
);
return data.item;
}
diff --git a/packages/admin/src/lib/api/import.ts b/packages/admin/src/lib/api/import.ts
index bf17ddb10..80749948e 100644
--- a/packages/admin/src/lib/api/import.ts
+++ b/packages/admin/src/lib/api/import.ts
@@ -2,6 +2,9 @@
* WordPress import and source probing APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
// =============================================================================
@@ -250,7 +253,7 @@ export async function importWxrMedia(
body: JSON.stringify({ attachments, stream: !!onProgress }),
});
- if (!response.ok) await throwResponseError(response, "Failed to import media");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to import media`));
// If no progress callback, just parse as JSON (non-streaming mode)
// Note: streaming NDJSON responses are excluded from the { data } envelope
diff --git a/packages/admin/src/lib/api/marketplace.ts b/packages/admin/src/lib/api/marketplace.ts
index 3eed5dddf..16cdd9571 100644
--- a/packages/admin/src/lib/api/marketplace.ts
+++ b/packages/admin/src/lib/api/marketplace.ts
@@ -6,6 +6,9 @@
* admin UI doesn't need to know the marketplace URL.
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
// ---------------------------------------------------------------------------
@@ -154,7 +157,7 @@ export async function installMarketplacePlugin(
headers: { "Content-Type": "application/json" },
body: JSON.stringify(opts),
});
- if (!response.ok) await throwResponseError(response, "Failed to install plugin");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to install plugin`));
}
/**
@@ -170,7 +173,7 @@ export async function updateMarketplacePlugin(
headers: { "Content-Type": "application/json" },
body: JSON.stringify(opts),
});
- if (!response.ok) await throwResponseError(response, "Failed to update plugin");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to update plugin`));
}
/**
@@ -186,7 +189,7 @@ export async function uninstallMarketplacePlugin(
headers: { "Content-Type": "application/json" },
body: JSON.stringify(opts),
});
- if (!response.ok) await throwResponseError(response, "Failed to uninstall plugin");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to uninstall plugin`));
}
/**
diff --git a/packages/admin/src/lib/api/media.ts b/packages/admin/src/lib/api/media.ts
index a63651cd7..83fdbcff4 100644
--- a/packages/admin/src/lib/api/media.ts
+++ b/packages/admin/src/lib/api/media.ts
@@ -2,6 +2,9 @@
* Media upload, list, delete, and provider APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import {
API_BASE,
apiFetch,
@@ -119,7 +122,7 @@ async function uploadToSignedUrl(file: File, uploadInfo: UploadUrlResponse): Pro
body: file,
});
- if (!response.ok) await throwResponseError(response, "Failed to upload file");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to upload file`));
}
/**
@@ -201,7 +204,7 @@ export async function deleteMedia(id: string): Promise {
const response = await apiFetch(`${API_BASE}/media/${id}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete media");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete media`));
}
/**
@@ -321,5 +324,5 @@ export async function deleteFromProvider(providerId: string, itemId: string): Pr
const response = await apiFetch(`${API_BASE}/media/providers/${providerId}/${itemId}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete from provider");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete from provider`));
}
diff --git a/packages/admin/src/lib/api/menus.ts b/packages/admin/src/lib/api/menus.ts
index e6417b4b8..b137a45b9 100644
--- a/packages/admin/src/lib/api/menus.ts
+++ b/packages/admin/src/lib/api/menus.ts
@@ -6,6 +6,9 @@
* been updated yet).
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export interface Menu {
@@ -157,7 +160,7 @@ export async function deleteMenu(name: string, options: LocaleOptions = {}): Pro
const response = await apiFetch(withLocale(`${API_BASE}/menus/${name}`, options.locale), {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete menu");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete menu`));
}
/**
@@ -211,7 +214,7 @@ export async function deleteMenuItem(
withLocale(`${API_BASE}/menus/${menuName}/items?id=${itemId}`, options.locale),
{ method: "DELETE" },
);
- if (!response.ok) await throwResponseError(response, "Failed to delete menu item");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete menu item`));
}
/**
diff --git a/packages/admin/src/lib/api/plugins.ts b/packages/admin/src/lib/api/plugins.ts
index e44e05265..6cbef65d8 100644
--- a/packages/admin/src/lib/api/plugins.ts
+++ b/packages/admin/src/lib/api/plugins.ts
@@ -2,6 +2,9 @@
* Plugin management APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export interface PluginInfo {
@@ -49,9 +52,12 @@ export async function fetchPlugin(pluginId: string): Promise {
if (response.status === 404) {
throw new Error(`Plugin "${pluginId}" not found`);
}
- await throwResponseError(response, "Failed to fetch plugin");
+ await throwResponseError(response, i18n._(msg`Failed to fetch plugin`));
}
- const result = await parseApiResponse<{ item: PluginInfo }>(response, "Failed to fetch plugin");
+ const result = await parseApiResponse<{ item: PluginInfo }>(
+ response,
+ i18n._(msg`Failed to fetch plugin`),
+ );
return result.item;
}
diff --git a/packages/admin/src/lib/api/redirects.ts b/packages/admin/src/lib/api/redirects.ts
index e17382859..ed28129f2 100644
--- a/packages/admin/src/lib/api/redirects.ts
+++ b/packages/admin/src/lib/api/redirects.ts
@@ -2,6 +2,9 @@
* Redirects API client
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export interface Redirect {
@@ -105,7 +108,7 @@ export async function deleteRedirect(id: string): Promise {
const response = await apiFetch(`${API_BASE}/redirects/${encodeURIComponent(id)}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete redirect");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete redirect`));
}
/**
diff --git a/packages/admin/src/lib/api/schema.ts b/packages/admin/src/lib/api/schema.ts
index 223d2eea0..c294df23c 100644
--- a/packages/admin/src/lib/api/schema.ts
+++ b/packages/admin/src/lib/api/schema.ts
@@ -2,6 +2,9 @@
* Schema/collection/field management APIs (Content Type Builder)
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export type FieldType =
@@ -161,11 +164,11 @@ export async function fetchCollection(
if (response.status === 404) {
throw new Error(`Collection "${slug}" not found`);
}
- await throwResponseError(response, "Failed to fetch collection");
+ await throwResponseError(response, i18n._(msg`Failed to fetch collection`));
}
const data = await parseApiResponse<{ item: SchemaCollectionWithFields }>(
response,
- "Failed to fetch collection",
+ i18n._(msg`Failed to fetch collection`),
);
return data.item;
}
@@ -213,7 +216,7 @@ export async function deleteCollection(slug: string, force = false): Promise {
const response = await apiFetch(`${API_BASE}/sections/${slug}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete section");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete section`));
}
diff --git a/packages/admin/src/lib/api/taxonomies.ts b/packages/admin/src/lib/api/taxonomies.ts
index b2bc421f5..42fc2e699 100644
--- a/packages/admin/src/lib/api/taxonomies.ts
+++ b/packages/admin/src/lib/api/taxonomies.ts
@@ -7,6 +7,9 @@
* that haven't yet been updated).
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export interface TaxonomyTerm {
@@ -195,7 +198,7 @@ export async function deleteTerm(
withLocale(`${API_BASE}/taxonomies/${taxonomyName}/terms/${slug}`, options.locale),
{ method: "DELETE" },
);
- if (!response.ok) await throwResponseError(response, "Failed to delete term");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete term`));
}
/** List every translation (locale variant) of a term. */
diff --git a/packages/admin/src/lib/api/users.ts b/packages/admin/src/lib/api/users.ts
index 4e5144289..46c1a60b3 100644
--- a/packages/admin/src/lib/api/users.ts
+++ b/packages/admin/src/lib/api/users.ts
@@ -2,6 +2,9 @@
* User management, passkeys, and allowed domains APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import {
API_BASE,
apiFetch,
@@ -82,10 +85,13 @@ export async function fetchUser(id: string): Promise {
if (response.status === 404) {
throw new Error(`User not found: ${id}`);
}
- await throwResponseError(response, "Failed to fetch user");
+ await throwResponseError(response, i18n._(msg`Failed to fetch user`));
}
- const data = await parseApiResponse<{ item: UserDetail }>(response, "Failed to fetch user");
+ const data = await parseApiResponse<{ item: UserDetail }>(
+ response,
+ i18n._(msg`Failed to fetch user`),
+ );
return data.item;
}
@@ -109,7 +115,7 @@ export async function disableUser(id: string): Promise {
const response = await apiFetch(`${API_BASE}/admin/users/${id}/disable`, {
method: "POST",
});
- if (!response.ok) await throwResponseError(response, "Failed to disable user");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to disable user`));
}
/**
@@ -119,7 +125,7 @@ export async function sendRecoveryLink(id: string): Promise {
const response = await apiFetch(`${API_BASE}/admin/users/${id}/send-recovery`, {
method: "POST",
});
- if (!response.ok) await throwResponseError(response, "Failed to send recovery link");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to send recovery link`));
}
/**
@@ -129,7 +135,7 @@ export async function enableUser(id: string): Promise {
const response = await apiFetch(`${API_BASE}/admin/users/${id}/enable`, {
method: "POST",
});
- if (!response.ok) await throwResponseError(response, "Failed to enable user");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to enable user`));
}
/** Invite response -- includes inviteUrl when no email provider is configured */
@@ -247,7 +253,7 @@ export async function deletePasskey(id: string): Promise {
const response = await apiFetch(`${API_BASE}/auth/passkey/${id}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete passkey");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete passkey`));
}
// =============================================================================
@@ -335,7 +341,8 @@ export async function deleteAllowedDomain(domain: string): Promise {
method: "DELETE",
},
);
- if (!response.ok) await throwResponseError(response, "Failed to delete allowed domain");
+ if (!response.ok)
+ await throwResponseError(response, i18n._(msg`Failed to delete allowed domain`));
}
// =============================================================================
diff --git a/packages/admin/src/lib/api/widgets.ts b/packages/admin/src/lib/api/widgets.ts
index 4a5e010da..84e674541 100644
--- a/packages/admin/src/lib/api/widgets.ts
+++ b/packages/admin/src/lib/api/widgets.ts
@@ -2,6 +2,9 @@
* Widget areas APIs
*/
+import { i18n } from "@lingui/core";
+import { msg } from "@lingui/core/macro";
+
import { API_BASE, apiFetch, parseApiResponse, throwResponseError } from "./client.js";
export interface WidgetArea {
@@ -102,7 +105,7 @@ export async function deleteWidgetArea(name: string): Promise {
const response = await apiFetch(`${API_BASE}/widget-areas/${name}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete widget area");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete widget area`));
}
/**
@@ -140,7 +143,7 @@ export async function deleteWidget(areaName: string, widgetId: string): Promise<
const response = await apiFetch(`${API_BASE}/widget-areas/${areaName}/widgets/${widgetId}`, {
method: "DELETE",
});
- if (!response.ok) await throwResponseError(response, "Failed to delete widget");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to delete widget`));
}
/**
@@ -152,7 +155,7 @@ export async function reorderWidgets(areaName: string, widgetIds: string[]): Pro
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ widgetIds }),
});
- if (!response.ok) await throwResponseError(response, "Failed to reorder widgets");
+ if (!response.ok) await throwResponseError(response, i18n._(msg`Failed to reorder widgets`));
}
/**
diff --git a/packages/admin/tests/components/MenuList.test.tsx b/packages/admin/tests/components/MenuList.test.tsx
index dd51b5e03..92fd5cb35 100644
--- a/packages/admin/tests/components/MenuList.test.tsx
+++ b/packages/admin/tests/components/MenuList.test.tsx
@@ -44,7 +44,7 @@ import * as api from "../../src/lib/api";
// ---------------------------------------------------------------------------
const MAIN_MENU_ITEMS_REGEX = /main.*3 items/;
-const FOOTER_MENU_ITEMS_REGEX = /footer.*1 items/;
+const FOOTER_MENU_ITEMS_REGEX = /footer.*1 item(?!s)/;
const DELETE_MENU_CONFIRMATION_REGEX = /Are you sure you want to delete this menu/;
const CREATE_MENU_REGEX = /Create Menu/;