Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 1.0.0-alpha.5

### Minor Changes

- feat: add new `fetchAlwaysLastModified` content base option

### Patch Changes

- fix: app navigation link types
- chore: use `throwError` method from `@jadeja/ts` in components
- chore: add comment for loading dynamic modules

## 1.0.0-alpha.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@jadeja/docs",
"description": "an opinionated documentation framework",
"version": "1.0.0-alpha.4",
"version": "1.0.0-alpha.5",
"type": "module",
"exports": {
"./styles/*": {
Expand Down
3 changes: 2 additions & 1 deletion src/components/layout/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/* ============================================================================================= */

import debounce from "@jadeja/ts/lib/debounce";
import { throwError } from "@jadeja/ts/lib/logger";
import { useState, useEffect, startTransition, useRef, createContext, useContext } from "react";

import { XIcon } from "@/components/assets/icons";
Expand Down Expand Up @@ -33,7 +34,7 @@ export const useSearchContext = () => {
const context = useContext(SearchContext);

if (!context) {
throw new Error("components must be used inside SearchRoot");
return throwError("components must be used inside SearchRoot");
}

return context;
Expand Down
3 changes: 2 additions & 1 deletion src/components/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/* ============================================================================================= */

import { throwError } from "@jadeja/ts/lib/logger";
import { default as NextLink } from "next/link.js";
import { usePathname } from "next/navigation.js";

Expand All @@ -25,7 +26,7 @@ export const Link = ({ href, navLink, ...rest }: LinkProps): ReactElement<HTMLAn
const pathname = usePathname();

if (!href) {
throw new Error("`href` prop is missing!");
return throwError("`href` prop is missing!");
}

// open external link in new tab
Expand Down
18 changes: 15 additions & 3 deletions src/lib/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export class Content<U extends Record<string, unknown> = {}> {

instance.options ??= options;

if (!("fetchAlwaysLastModified" in instance.options)) {
// oxlint-disable-next-line node/no-process-env
instance.options.fetchAlwaysLastModified = process.env.NODE_ENV === "production";
}

instance.paths ??= paths;

// register methods, so `this` would point to singleton instance and not this class
Expand Down Expand Up @@ -368,16 +373,23 @@ export class Content<U extends Record<string, unknown> = {}> {

const fields = attributes;

if (!fields.title || !fields.description || !fields.keywords || !fields.authors) {
if (!fields.title || !fields.description || !fields.keywords || !fields.authors?.length) {
return throwError(
`Missing frontmatter [title, description, keywords, authors] field(s) in ${filePATH} with index ${index}`,
);
}

if (!fields.publishedAt || !fields.lastModifiedAt) {
if (!fields.publishedAt || !fields.lastModifiedAt || this.options.fetchAlwaysLastModified) {
//
let { lastModifiedAt } = fields;

if (!lastModifiedAt || this.options.fetchAlwaysLastModified) {
lastModifiedAt = getLastModified(filePATH);
}

Object.assign(fields, {
publishedAt: fields.publishedAt ?? new Date().toISOString(),
lastModifiedAt: fields.lastModifiedAt ?? getLastModified(filePATH),
lastModifiedAt,
});

// add modified frontmatter back to file (full rewrite)
Expand Down
4 changes: 4 additions & 0 deletions src/lib/load-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export const loadModule = async ({ content, slugs }: LoadModuleOptions): LoadMod

try {
// dynamically import `.mdx` file as module
// NOTE: if bundler can't resolve the dynamic module, add alias with aboslute path
// NOTE: `"@/content": resolve(import.meta.dirname, "src/content")`
// TODO: find a more reliable way
//
// oxlint-disable-next-line typescript/no-unsafe-assignment
const dynamicModule: DocsModuleType = await import(
`@/content/${content.paths.dir}/${filePath}`
Expand Down
6 changes: 5 additions & 1 deletion src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface DocsConfig {
analytics?: Analytics;
constants: Constants;
links: {
navigations: Record<string, Link>;
navigations: Record<string, NavigationLink>;
socials: Record<string, Link>;
};
mdxConfig: NextMDXOptions;
Expand Down Expand Up @@ -155,6 +155,10 @@ export interface Link {
title?: string;
}

export type NavigationLink = Omit<Link, "url"> & {
url: Link["url"] | `/${string}`;
};

export type AuthorLink = Omit<Link, "icon"> & {
img?: string;
};
Expand Down
1 change: 1 addition & 0 deletions src/types/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { DocsConfig } from "@/types/config";
================================================================================================ */

export interface ContentBaseOptions {
fetchAlwaysLastModified?: boolean;
search: CreateSearchInstanceOptions;
trailingSlash: DocsConfig["trailingSlash"];
}
Expand Down