Skip to content

Commit

Permalink
Merge branch 'main' into dev/viewport-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nmanu1 committed Oct 25, 2023
2 parents 321f7ce + 152266f commit e00e0fb
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 7 deletions.
12 changes: 12 additions & 0 deletions packages/studio-plugin/src/orchestrators/ParsingOrchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@ export default class ParsingOrchestrator {
`The pages directory does not exist, expected directory to be at "${this.paths.pages}".`
);
}

if (this.studioConfig.isPagesJSRepo) {
const excludeReservedPagesJSFiles = (filename: string) =>
!(filename.includes("_server") || filename.includes("_client"));

return createFilenameMapping(
this.paths.pages,
this.getOrCreatePageFile,
excludeReservedPagesJSFiles
);
}

return createFilenameMapping(this.paths.pages, this.getOrCreatePageFile);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import upath from "upath";

export default function createFilenameMapping<T>(
dirPath: string,
getMappedValue: (name: string) => T
getMappedValue: (name: string) => T,
fileFilter?: (filename: string) => boolean
): Record<string, T> {
const files = fs.readdirSync(dirPath, "utf-8").filter((filename) => {
const absPath = upath.join(dirPath, filename);
return fs.lstatSync(absPath).isFile();

const isFile = fs.lstatSync(absPath).isFile();
return fileFilter ? isFile && fileFilter(filename) : isFile;
});
return files.reduce((filepathMapping, filename) => {
const name = upath.basename(filename, ".tsx");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PageContext } from "@yext/pages";
import { hydrateRoot } from "react-dom/client";

export { render };

const render = async (pageContext: PageContext<any>) => {
const { Page, pageProps } = pageContext;
const rootElement = document.getElementById("reactele");
if (rootElement) {
hydrateRoot(rootElement, <Page {...pageProps} />);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as ReactDOMServer from "react-dom/server";
import { PageContext } from "@yext/pages";

export { render };

const render = async (pageContext: PageContext<any>) => {
const { Page, pageProps } = pageContext;
const viewHtml = ReactDOMServer.renderToString(<Page {...pageProps} />);
return `<!DOCTYPE html>
<html lang="<!--app-lang-->">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="reactele">${viewHtml}</div>
</body>
</html>`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ describe("aggregates data as expected", () => {
isPagesJS: true,
});
const studioData = orchestrator.getStudioData();
expect(studioData.pageNameToErrorPageState).toEqual({});
expect(studioData.pageNameToPageState).toEqual({
basicPage: {
...basicPageState,
Expand All @@ -130,7 +131,10 @@ it("throws an error when the page imports components from unexpected folders", (
__dirname,
"../__fixtures__/ParsingOrchestrator/src/pages"
);
createParsingOrchestrator({ paths: userPaths }).getStudioData();
createParsingOrchestrator({
paths: userPaths,
isPagesJS: true,
}).getStudioData();
expect(prettyPrintError).toHaveBeenCalledTimes(1);
expect(prettyPrintError).toHaveBeenCalledWith(
expect.stringMatching(/^Failed to parse PageState/),
Expand Down
7 changes: 7 additions & 0 deletions packages/studio-ui/src/utils/PageDataValidator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { PagesRecord } from "../store/models/slices/PageSlice";

export const PAGES_JS_RESERVED_PAGE_NAMES = ["_server", "_client"];

export interface ValidationResult {
valid: boolean;
errorMessages: string[];
Expand Down Expand Up @@ -76,6 +78,11 @@ export default class PageDataValidator {
if (pageName.length > 255) {
errorMessages.push("Page name must be 255 characters or less.");
}
if (this.isPagesJSRepo && PAGES_JS_RESERVED_PAGE_NAMES.includes(pageName)) {
errorMessages.push(
`Page name "${pageName}" is a reserved PagesJS filename.`
);
}
if (this.pages[pageName]) {
errorMessages.push(`Page name "${pageName}" is already used.`);
}
Expand Down
19 changes: 15 additions & 4 deletions packages/studio-ui/tests/utils/PageDataValidator.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import PageDataValidator, {
PAGES_JS_RESERVED_PAGE_NAMES,
ValidationResult,
} from "../../src/utils/PageDataValidator";

Expand Down Expand Up @@ -44,11 +45,12 @@ describe("URL slug validation", () => {
});

describe("page name validation", () => {
const validator = new PageDataValidator({
isEntityPage: false,
isPagesJSRepo: true,
});

function expectPageNameError(input: string, errorMessages: string[]) {
const validator = new PageDataValidator({
isEntityPage: false,
isPagesJSRepo: true,
});
const result: ValidationResult = validator.validate({ pageName: input });
expect(result.valid).toBeFalsy();
expect(result.errorMessages).toEqual(expect.arrayContaining(errorMessages));
Expand All @@ -74,4 +76,13 @@ describe("page name validation", () => {
const errorMessage = "Page name must be 255 characters or less.";
expectPageNameError(longName, [errorMessage]);
});

it("gives an error when using PagesJS Reserved Filenames", () => {
const checkReservedName = (pageName: string) => {
const errorMessage = `Page name "${pageName}" is a reserved PagesJS filename.`;
expectPageNameError(pageName, [errorMessage]);
};

PAGES_JS_RESERVED_PAGE_NAMES.forEach((name) => checkReservedName(name));
});
});

0 comments on commit e00e0fb

Please sign in to comment.