Skip to content

Commit

Permalink
feat: add inkeep (for hume) (#1082)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Jun 27, 2024
1 parent 0e20afa commit 75908ce
Show file tree
Hide file tree
Showing 30 changed files with 2,749 additions and 444 deletions.
1 change: 1 addition & 0 deletions packages/commons/search-utils/.depcheckrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "ignores": ["@fern-platform/configs", "@types/node", "vite", "@types/react"], "ignore-patterns": ["dist"] }
4 changes: 4 additions & 0 deletions packages/commons/search-utils/.mrlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "react-library",
"private": true
}
1 change: 1 addition & 0 deletions packages/commons/search-utils/.prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("../../../.prettierrc.json");
1 change: 1 addition & 0 deletions packages/commons/search-utils/.stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "extends": ["../../../shared/stylelintrc.shared.json"] }
49 changes: 49 additions & 0 deletions packages/commons/search-utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@fern-ui/search-utils",
"version": "0.0.0",
"repository": {
"type": "git",
"url": "https://github.com/fern-api/fern-platform.git",
"directory": "packages/commons/search-utils"
},
"private": true,
"files": [
"dist"
],
"type": "module",
"source": "src/index.ts",
"module": "src/index.ts",
"main": "src/index.ts",
"sideEffects": false,
"scripts": {
"clean": "rm -rf ./lib && tsc --build --clean",
"compile": "tsc --build",
"test": "vitest --run --passWithNoTests --globals",
"lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../.eslintignore",
"lint:eslint:fix": "pnpm lint:eslint --fix",
"lint:style": "stylelint 'src/**/*.scss' --allow-empty-input --max-warnings 0",
"lint:style:fix": "pnpm lint:style --fix",
"format": "prettier --write --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"",
"format:check": "prettier --check --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"",
"organize-imports": "organize-imports-cli tsconfig.json",
"depcheck": "depcheck"
},
"dependencies": {
"@fern-api/fdr-sdk": "0.98.6-a0f252ba1",
"@fern-ui/core-utils": "workspace:*",
"@vercel/edge-config": "^1.1.0"
},
"devDependencies": {
"@fern-platform/configs": "workspace:*",
"@inkeep/widgets": "^0.2.288",
"@types/node": "^18.7.18",
"depcheck": "^1.4.3",
"eslint": "^8.56.0",
"organize-imports-cli": "^0.10.0",
"prettier": "^3.3.2",
"stylelint": "^16.1.0",
"ts-essentials": "^10.0.1",
"typescript": "5.4.3",
"vitest": "^1.5.0"
}
}
143 changes: 143 additions & 0 deletions packages/commons/search-utils/src/SearchConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Algolia, FdrClient } from "@fern-api/fdr-sdk";
import { assertNonNullish } from "@fern-ui/core-utils";
import type {
InkeepAIChatSettings,
InkeepModalSettings,
InkeepSearchSettings,
InkeepWidgetBaseSettings,
} from "@inkeep/widgets";
import { getAll } from "@vercel/edge-config";
import type { DeepReadonly } from "ts-essentials";

export const REGISTRY_SERVICE = new FdrClient({
environment: process.env.NEXT_PUBLIC_FDR_ORIGIN ?? "https://registry.buildwithfern.com",
});

const FEATURE_FLAGS = ["inkeep-enabled" as const];

export type InkeepSharedSettings = DeepReadonly<{
baseSettings: InkeepWidgetBaseSettings;
aiChatSettings?: Partial<InkeepAIChatSettings>;
searchSettings?: Partial<InkeepSearchSettings>;
modalSettings?: Partial<InkeepModalSettings>;
}>;

interface EdgeConfigResponse {
"inkeep-enabled"?: Record<string, InkeepSharedSettings>;
}

export declare namespace SearchConfig {
interface Unversioned {
type: "unversioned";
value: string;
}

interface Versioned {
type: "versioned";
// keyed by version id
values: Record<string, string>;
}

interface Inkeep extends InkeepSharedSettings {
isAvailable: true;
type: "inkeep";
}

interface Algolia {
isAvailable: true;
type: "algolia";
appId: string;
searchApiKey: Unversioned | Versioned;
index: string;
}

interface Unavailable {
isAvailable: false;
}
}

export type SearchConfig = SearchConfig.Inkeep | SearchConfig.Algolia | SearchConfig.Unavailable;

export interface SearchRequest {
searchInfo: Algolia.SearchInfo | undefined;
}

export async function getSearchConfig(domain: string, { searchInfo }: SearchRequest): Promise<SearchConfig> {
try {
const config = await getAll<EdgeConfigResponse>(FEATURE_FLAGS);
const maybeInkeep = config["inkeep-enabled"]?.[domain];

if (maybeInkeep?.baseSettings.integrationId != null) {
return {
isAvailable: true,
type: "inkeep",
...maybeInkeep,
};
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Error fetching edge config", e);
}

if (typeof searchInfo !== "object" || searchInfo.type === "legacyMultiAlgoliaIndex") {
return { isAvailable: false };
}

const algoliaAppId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID;
const algoliaSearchIndex = process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX;

assertNonNullish(algoliaAppId, "Missing environment variable: NEXT_PUBLIC_ALGOLIA_APP_ID");
assertNonNullish(algoliaSearchIndex, "Missing environment variable: NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX");

if (searchInfo.value.type === "unversioned") {
const resp = await REGISTRY_SERVICE.docs.v2.read.getSearchApiKeyForIndexSegment({
indexSegmentId: searchInfo.value.indexSegment.id,
});

if (!resp.ok) {
return { isAvailable: false };
}

return {
isAvailable: true,
type: "algolia",
appId: algoliaAppId,
searchApiKey: {
type: "unversioned",
value: resp.body.searchApiKey,
},
index: algoliaSearchIndex,
};
} else if (searchInfo.value.type === "versioned") {
const values: Record<string, string> = {};

for (const [versionId, indexSegment] of Object.entries(searchInfo.value.indexSegmentsByVersionId)) {
const resp = await REGISTRY_SERVICE.docs.v2.read.getSearchApiKeyForIndexSegment({
indexSegmentId: indexSegment.id,
});

if (!resp.ok) {
return { isAvailable: false };
}

values[versionId] = resp.body.searchApiKey;
}

if (Object.keys(values).length === 0) {
return { isAvailable: false };
}

return {
isAvailable: true,
type: "algolia",
appId: algoliaAppId,
searchApiKey: {
type: "versioned",
values,
},
index: algoliaSearchIndex,
};
}

return { isAvailable: false };
}
1 change: 1 addition & 0 deletions packages/commons/search-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./SearchConfig";
7 changes: 7 additions & 0 deletions packages/commons/search-utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@fern-platform/configs/tsconfig/react-library.json",
"compilerOptions": { "outDir": "./dist", "rootDir": "./src" },
"include": ["./src/**/*"],
"references": [{ "path": "../core-utils" }, { "path": "../fdr-utils" }, { "path": "../../fdr-sdk" }]
}
4 changes: 4 additions & 0 deletions packages/ui/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"@fern-ui/loadable": "workspace:*",
"@fern-ui/next-seo": "workspace:*",
"@fern-ui/react-commons": "workspace:*",
"@fern-ui/search-utils": "workspace:^",
"@headlessui/react": "^1.7.18",
"@inkeep/widgets": "^0.2.288",
"@next/third-parties": "^14.2.3",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accordion": "^1.1.2",
Expand All @@ -59,6 +61,7 @@
"@sentry/nextjs": "^7.105.0",
"@shikijs/transformers": "^1.2.2",
"@types/nprogress": "^0.2.3",
"@vercel/edge-config": "^1.1.0",
"algoliasearch": "^4.22.1",
"bezier-easing": "^2.1.0",
"clsx": "^2.1.0",
Expand Down Expand Up @@ -158,6 +161,7 @@
"storybook": "8.1.0-alpha.6",
"stylelint": "^16.1.0",
"tailwindcss": "^3.4.3",
"ts-essentials": "^10.0.1",
"typescript": "5.4.3",
"vite": "^5.2.6",
"vitest": "^1.5.0"
Expand Down
1 change: 1 addition & 0 deletions packages/ui/app/src/css/components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@apply bg-tag-default;
@apply hover:bg-tag-default-hover transition-[background,shadow];
@apply ring-inset ring-default hover:ring-default ring-1;
@apply max-sm:h-10 max-sm:text-base;

.search-placeholder {
@apply inline-flex flex-1 items-center space-x-2.5;
Expand Down
22 changes: 2 additions & 20 deletions packages/ui/app/src/docs/Docs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { DocsV1Read } from "@fern-api/fdr-sdk";
import { PLATFORM } from "@fern-ui/core-utils";
import { useKeyboardCommand, useKeyboardPress } from "@fern-ui/react-commons";
import clsx from "clsx";
import dynamic from "next/dynamic";
import { memo } from "react";
Expand All @@ -10,9 +8,8 @@ import { useDocsContext } from "../contexts/docs-context/useDocsContext";
import { useLayoutBreakpointValue } from "../contexts/layout-breakpoint/useLayoutBreakpoint";
import { useNavigationContext } from "../contexts/navigation-context";
import { FeedbackPopover } from "../custom-docs-page/FeedbackPopover";
import { useCreateSearchService } from "../services/useSearchService";
import { BuiltWithFern } from "../sidebar/BuiltWithFern";
import { useIsMobileSidebarOpen, useMessageHandler, useOpenSearchDialog } from "../sidebar/atom";
import { useIsMobileSidebarOpen, useMessageHandler } from "../sidebar/atom";
import { DocsMainContent } from "./DocsMainContent";
import { HeaderContainer } from "./HeaderContainer";

Expand All @@ -28,28 +25,13 @@ export const SearchDialog = dynamic(() => import("../search/SearchDialog").then(
});

export const Docs: React.FC<DocsProps> = memo<DocsProps>(function UnmemoizedDocs({ logoHeight, logoHref }) {
const { layout, colors, currentVersionId, sidebar } = useDocsContext();
const openSearchDialog = useOpenSearchDialog();
const { layout, colors, sidebar } = useDocsContext();
const { isInlineFeedbackEnabled } = useFeatureFlags();
const { resolvedPath } = useNavigationContext();

// set up message handler to listen for messages from custom scripts
useMessageHandler();

// set up search service
useCreateSearchService(currentVersionId);

useKeyboardCommand({ key: "K", platform: PLATFORM, onCommand: openSearchDialog });
useKeyboardPress({
key: "Slash",
onPress: () => {
const activeElementTag = document.activeElement?.tagName.toLowerCase();
if (activeElementTag !== "input" && activeElementTag !== "textarea" && activeElementTag !== "select") {
openSearchDialog();
}
},
});

const isMobileSidebarOpen = useIsMobileSidebarOpen();
const layoutBreakpoint = useLayoutBreakpointValue();

Expand Down
8 changes: 4 additions & 4 deletions packages/ui/app/src/docs/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useAtomValue } from "jotai";
import { CSSProperties, PropsWithChildren, forwardRef, memo } from "react";
import { FernLinkButton } from "../components/FernLinkButton";
import { useDocsContext } from "../contexts/docs-context/useDocsContext";
import { SEARCH_BOX_MOUNTED } from "../search/SearchBox";
import { useSearchService } from "../services/useSearchService";
import { SEARCH_BOX_MOUNTED } from "../search/algolia/SearchBox";
import { useSearchConfig } from "../services/useSearchService";
import { SidebarSearchBar } from "../sidebar/SidebarSearchBar";
import { useOpenSearchDialog } from "../sidebar/atom";
import { HeaderLogoSection } from "./HeaderLogoSection";
Expand Down Expand Up @@ -44,7 +44,7 @@ const UnmemoizedHeader = forwardRef<HTMLDivElement, PropsWithChildren<Header.Pro
const { colors } = useDocsContext();
const openSearchDialog = useOpenSearchDialog();
const isSearchBoxMounted = useAtomValue(SEARCH_BOX_MOUNTED);
const searchService = useSearchService();
const [searchService] = useSearchConfig();

const navbarLinksSection = (
<div className="hidden lg:block">
Expand Down Expand Up @@ -98,7 +98,7 @@ const UnmemoizedHeader = forwardRef<HTMLDivElement, PropsWithChildren<Header.Pro
invisible: isSearchBoxMounted,
})}
>
<SidebarSearchBar onClick={openSearchDialog} className="w-full" />
<SidebarSearchBar className="w-full" />
</div>
)}

Expand Down
25 changes: 0 additions & 25 deletions packages/ui/app/src/env.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/ui/app/src/next-app/utils/getColorVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface ColorConfig {
light: DocsV1Read.RgbaColor;
}

const DEFAULT_COLORS: {
export const DEFAULT_COLORS: {
accentPrimary: ColorConfig;
background: ColorConfig;
} = {
Expand Down
Loading

0 comments on commit 75908ce

Please sign in to comment.