Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(prose): update typing for Link #360

Merged
merged 11 commits into from
Jul 29, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Heading } from "@tiptap/extension-heading"
import { History } from "@tiptap/extension-history"
import { HorizontalRule } from "@tiptap/extension-horizontal-rule"
import { Italic } from "@tiptap/extension-italic"
import Link from "@tiptap/extension-link"
import { ListItem } from "@tiptap/extension-list-item"
import { OrderedList } from "@tiptap/extension-ordered-list"
import { Paragraph } from "@tiptap/extension-paragraph"
Expand All @@ -33,6 +34,7 @@ interface TiptapEditorProps extends BoxProps {
export function TiptapEditor({ data, handleChange }: TiptapEditorProps) {
const editor = useEditor({
extensions: [
Link,
Blockquote,
Bold,
BulletList.extend({
Expand Down
15 changes: 13 additions & 2 deletions packages/components/src/interfaces/native/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,27 @@ const ItalicMarkSchema = Type.Object(
},
)

const LinkMarkSchema = Type.Object(
const BaseLinkMarkSchema = Type.Object(
{
type: Type.Literal("link", { default: "link" }),
href: Type.String(),
attrs: Type.Object({
target: Type.Optional(
Type.Union([Type.Literal("_self"), Type.Literal("_blank")]),
),
// NOTE: The href given by tiptap here
// https://github.com/ueberdosis/tiptap/blob/main/packages/extension-link/src/link.ts
// defaults to `null` href
href: Type.Union([Type.String(), Type.Null()]),
}),
},
{
title: "Hyperlink",
},
)

const LinkMarkSchema =
Type.Unsafe<Static<typeof BaseLinkMarkSchema>>(BaseLinkMarkSchema)

const StrikeMarkSchema = Type.Object(
{
type: Type.Literal("strike", { default: "strike" }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export const Default: Story = {
marks: [
{
type: "link",
href: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
attrs: {
href: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
target: "_blank",
},
},
],
text: "external links",
Expand All @@ -41,7 +44,10 @@ export const Default: Story = {
marks: [
{
type: "link",
href: "/contact",
attrs: {
href: "/contact",
target: "_blank",
},
},
],
text: "internal ones",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/utils/getTextAsHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const getTextAsHtml = (content?: (HardBreakProps | TextProps)[]) => {
node.marks.forEach((mark) => {
if (mark.type === "link") {
output = `<${MARK_DOM_MAPPING[mark.type]} href="${
mark.href
mark.attrs.href
}">${output}</${MARK_DOM_MAPPING[mark.type]}>`
return
}
Expand Down
166 changes: 84 additions & 82 deletions tooling/build/scripts/generate-sitemap.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
const fs = require("fs").promises
const path = require("path")
const fs = require("fs").promises;
const path = require("path");

const JSON_SCHEMA_VERSION = "0.1.0"
const schemaDirPath = path.join(__dirname, "../schema")
const sitemapPath = path.join(__dirname, "../sitemap.json")
const JSON_SCHEMA_VERSION = "0.1.0";
const schemaDirPath = path.join(__dirname, "../schema");
const sitemapPath = path.join(__dirname, "../sitemap.json");

const getSchemaJson = async (filePath) => {
try {
const schemaContent = await fs.readFile(filePath, "utf8")
return JSON.parse(schemaContent)
const schemaContent = await fs.readFile(filePath, "utf8");
return JSON.parse(schemaContent);
} catch (error) {
return null
return null;
}
}
};

const getDirectoryItemStats = async (filePath) => {
try {
return await fs.stat(filePath)
return await fs.stat(filePath);
} catch (error) {
return null
return null;
}
}
};

const getHumanReadableFileSize = (bytes) => {
const unit = 1000
const unit = 1000;

if (Math.abs(bytes) < unit) {
return bytes + " B"
return bytes + " B";
}

const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
let index = -1
const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
let index = -1;

while (Math.abs(bytes) >= unit && index < units.length - 1) {
bytes /= unit
index++
bytes /= unit;
index++;
}

return `${bytes.toFixed(1)} ${units[index]}`
}
return `${bytes.toFixed(1)} ${units[index]}`;
};

const getSiteMapEntry = async (fullPath, relativePath, name) => {
const permalink = relativePath.split(".").slice(0, -1).join("-")
const schemaData = await getSchemaJson(fullPath)
const fileStats = await getDirectoryItemStats(fullPath)
const permalink = relativePath.split(".").slice(0, -1).join("-");
const schemaData = await getSchemaJson(fullPath);
const fileStats = await getDirectoryItemStats(fullPath);

if (!schemaData || !fileStats) {
return null
return null;
}

const pageName = name.split(".")[0].replace(/-/g, " ")
const pageName = name.split(".")[0].replace(/-/g, " ");
const title =
schemaData.page.title ||
pageName.charAt(0).toUpperCase() + pageName.slice(1)
pageName.charAt(0).toUpperCase() + pageName.slice(1);
const summary =
schemaData.page.contentPageHeader?.summary ||
schemaData.page.articlePageHeader?.summary.join(" ") ||
schemaData.page.description ||
""
"";

const siteMapEntry = {
permalink,
Expand All @@ -68,14 +68,14 @@ const getSiteMapEntry = async (fullPath, relativePath, name) => {
category: schemaData.page.category,
date: schemaData.page.date,
image: schemaData.page.image,
}
};

if (schemaData.layout === "file") {
const refFilePath = path.join(__dirname, "../public", schemaData.page.ref)
const refFileStats = await getDirectoryItemStats(refFilePath)
const refFilePath = path.join(__dirname, "../public", schemaData.page.ref);
const refFileStats = await getDirectoryItemStats(refFilePath);

if (!refFileStats) {
return null
return null;
}

return {
Expand All @@ -85,38 +85,38 @@ const getSiteMapEntry = async (fullPath, relativePath, name) => {
type: path.extname(refFilePath).slice(1).toUpperCase(),
size: getHumanReadableFileSize(refFileStats.size),
},
}
};
}

if (schemaData.layout === "link") {
return {
...siteMapEntry,
ref: schemaData.page.ref,
}
};
}

// Check if file is actually an index page for a directory
const directoryPath = path.join(
path.dirname(fullPath),
path.basename(fullPath, ".json"),
)
const directoryItemStats = await getDirectoryItemStats(directoryPath)
);
const directoryItemStats = await getDirectoryItemStats(directoryPath);
const isDirectoryAlsoPresent =
directoryItemStats && directoryItemStats.isDirectory()
directoryItemStats && directoryItemStats.isDirectory();

if (isDirectoryAlsoPresent) {
return {
...siteMapEntry,
children: await getSiteMapChildrenEntries(directoryPath, permalink),
}
};
}

return siteMapEntry
}
return siteMapEntry;
};

// Generates sitemap entries and an index file for directories without an index file
const processDanglingDirectory = async (fullPath, relativePath, name) => {
const children = await getSiteMapChildrenEntries(fullPath, relativePath)
const children = await getSiteMapChildrenEntries(fullPath, relativePath);
// TODO: Improve the content for generated index pages
const listOfChildPages = {
type: "prose",
Expand All @@ -134,7 +134,9 @@ const processDanglingDirectory = async (fullPath, relativePath, name) => {
marks: [
{
type: "link",
href: child.permalink,
attrs: {
href: child.permalink,
},
},
Comment on lines +137 to +139
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only relevant change because we update the href to be inside attrs now. i searched the 2 .js files in this directory to check if we needed to update href

fact-check me @dcshzj if this is enoguh

],
text: child.title,
Expand All @@ -143,14 +145,14 @@ const processDanglingDirectory = async (fullPath, relativePath, name) => {
},
],
})),
}
]
}
},
],
};

const pageName = name.replace(/-/g, " ")
const title = pageName.charAt(0).toUpperCase() + pageName.slice(1)
const summary = `Pages in ${title}`
const layout = "content"
const pageName = name.replace(/-/g, " ");
const title = pageName.charAt(0).toUpperCase() + pageName.slice(1);
const summary = `Pages in ${title}`;
const layout = "content";

await fs.writeFile(
path.join(fullPath + ".json"),
Expand All @@ -169,9 +171,9 @@ const processDanglingDirectory = async (fullPath, relativePath, name) => {
null,
2,
),
)
);

console.log("Generated missing index file for directory:", relativePath)
console.log("Generated missing index file for directory:", relativePath);

return {
permalink: relativePath,
Expand All @@ -180,41 +182,41 @@ const processDanglingDirectory = async (fullPath, relativePath, name) => {
title,
summary,
children,
}
}
};
};

const getSiteMapChildrenEntries = async (fullPath, relativePath) => {
const entries = await fs.readdir(fullPath, { withFileTypes: true })
const entries = await fs.readdir(fullPath, { withFileTypes: true });
const fileEntries = entries.filter(
(entry) => entry.isFile() && entry.name.endsWith(".json"),
)
);

const children = []
const children = [];

// Check if _pages.json exists
const pageOrderFilePath = path.join(fullPath, "_pages.json")
const pageOrderData = await getSchemaJson(pageOrderFilePath)
const pageOrderFilePath = path.join(fullPath, "_pages.json");
const pageOrderData = await getSchemaJson(pageOrderFilePath);

if (pageOrderData) {
const childPages = pageOrderData["pages"]
const childPages = pageOrderData["pages"];

const childEntries = await Promise.all(
childPages.map((child) => {
const fileName = child + ".json"
const fileName = child + ".json";
const childEntry = getSiteMapEntry(
path.join(fullPath, fileName),
path.join(relativePath, fileName),
fileName,
)
);

return childEntry
return childEntry;
}),
)
);

children.push(...childEntries.filter((entry) => entry !== null))
children.push(...childEntries.filter((entry) => entry !== null));
} else {
// If _pages.json does not exist, process files in the directory in arbitrary order
console.log("No _pages.json found for:", relativePath)
console.log("No _pages.json found for:", relativePath);

const childEntries = await Promise.all(
fileEntries
Expand All @@ -228,9 +230,9 @@ const getSiteMapChildrenEntries = async (fullPath, relativePath) => {
fileEntry.name,
),
),
)
);

children.push(...childEntries.filter((entry) => entry !== null))
children.push(...childEntries.filter((entry) => entry !== null));
}

// Process any directories that do not have a corresponding index file
Expand All @@ -250,19 +252,19 @@ const getSiteMapChildrenEntries = async (fullPath, relativePath) => {
dirEntry.name,
),
),
)
);

children.push(...danglingDirEntries)
children.push(...danglingDirEntries);

return children
}
return children;
};

const generateSitemap = async () => {
const startTime = performance.now()
const children = await getSiteMapChildrenEntries(schemaDirPath, "/")
const indexJsonPath = path.join(schemaDirPath, "index.json")
const indexJsonSchema = await getSchemaJson(indexJsonPath)
const indexJsonStat = await getDirectoryItemStats(indexJsonPath)
const startTime = performance.now();
const children = await getSiteMapChildrenEntries(schemaDirPath, "/");
const indexJsonPath = path.join(schemaDirPath, "index.json");
const indexJsonSchema = await getSchemaJson(indexJsonPath);
const indexJsonStat = await getDirectoryItemStats(indexJsonPath);

const sitemap = {
permalink: "/",
Expand All @@ -271,12 +273,12 @@ const generateSitemap = async () => {
title: indexJsonSchema.page.title || "Home",
summary: indexJsonSchema.page.description || "",
children,
}
};

await fs.writeFile(sitemapPath, JSON.stringify(sitemap, null, 2))
const endTime = performance.now()
console.log("Sitemap generated at:", sitemapPath)
console.log("Time taken:", (endTime - startTime) / 1000, "seconds")
}
await fs.writeFile(sitemapPath, JSON.stringify(sitemap, null, 2));
const endTime = performance.now();
console.log("Sitemap generated at:", sitemapPath);
console.log("Time taken:", (endTime - startTime) / 1000, "seconds");
};

generateSitemap().catch(console.error)
generateSitemap().catch(console.error);
Loading