@carlonicora/nextjs-jsonapi 1.109.0 → 1.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AssistantMessageInterface-Cs1yb-gF.d.ts → AssistantMessageInterface-BNzf1etU.d.ts} +14 -1
- package/dist/{AssistantMessageInterface-DQ3mH5L8.d.mts → AssistantMessageInterface-DrgHDjZ5.d.mts} +14 -1
- package/dist/{BlockNoteEditor-3XYBZLWO.js → BlockNoteEditor-7OKW6HHN.js} +19 -20
- package/dist/BlockNoteEditor-7OKW6HHN.js.map +1 -0
- package/dist/{BlockNoteEditor-EBFZG7AL.mjs → BlockNoteEditor-K7IIWM3S.mjs} +4 -5
- package/dist/{BlockNoteEditor-EBFZG7AL.mjs.map → BlockNoteEditor-K7IIWM3S.mjs.map} +1 -1
- package/dist/BlockNoteViewer-OPSCTHKJ.mjs +31 -0
- package/dist/BlockNoteViewer-OPSCTHKJ.mjs.map +1 -0
- package/dist/BlockNoteViewer-UW5VZ5UF.js +31 -0
- package/dist/BlockNoteViewer-UW5VZ5UF.js.map +1 -0
- package/dist/billing/index.d.mts +41 -41
- package/dist/billing/index.d.ts +41 -41
- package/dist/billing/index.js +346 -347
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +3 -4
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-7E3O52U5.js → chunk-6XWW67F2.js} +25 -12
- package/dist/chunk-6XWW67F2.js.map +1 -0
- package/dist/{chunk-UHO3KUUH.js → chunk-AKXUNE3A.js} +977 -850
- package/dist/chunk-AKXUNE3A.js.map +1 -0
- package/dist/{chunk-UOYIWJEJ.mjs → chunk-CWVYU4YZ.mjs} +18 -5
- package/dist/{chunk-UOYIWJEJ.mjs.map → chunk-CWVYU4YZ.mjs.map} +1 -1
- package/dist/{chunk-CRTVAQEK.mjs → chunk-TXVVZLUQ.mjs} +1388 -1261
- package/dist/chunk-TXVVZLUQ.mjs.map +1 -0
- package/dist/{chunk-CFI4WZ5R.js → chunk-U2HR57MY.js} +111 -5
- package/dist/chunk-U2HR57MY.js.map +1 -0
- package/dist/chunk-WPAQRB5Q.mjs +7 -0
- package/dist/chunk-WPAQRB5Q.mjs.map +1 -0
- package/dist/chunk-YBZVWLPH.js +7 -0
- package/dist/chunk-YBZVWLPH.js.map +1 -0
- package/dist/{chunk-MSNNAHDB.mjs → chunk-ZYPNVEHB.mjs} +112 -6
- package/dist/{chunk-MSNNAHDB.mjs.map → chunk-ZYPNVEHB.mjs.map} +1 -1
- package/dist/client/index.d.mts +3 -4
- package/dist/client/index.d.ts +3 -4
- package/dist/client/index.js +4 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -4
- package/dist/components/index.d.mts +418 -415
- package/dist/components/index.d.ts +418 -415
- package/dist/components/index.js +6 -5
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +5 -4
- package/dist/{config-CN23v3eJ.d.ts → config-BrkU_Ynz.d.ts} +2 -2
- package/dist/{config-gh88Qn4h.d.mts → config-snd2ToEB.d.mts} +2 -2
- package/dist/contexts/index.d.mts +15 -15
- package/dist/contexts/index.d.ts +15 -15
- package/dist/contexts/index.js +4 -5
- package/dist/contexts/index.js.map +1 -1
- package/dist/contexts/index.mjs +3 -4
- package/dist/core/index.d.mts +35 -4
- package/dist/core/index.d.ts +35 -4
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/features/help/index.d.mts +25 -66
- package/dist/features/help/index.d.ts +25 -66
- package/dist/features/help/index.js +114 -124
- package/dist/features/help/index.js.map +1 -1
- package/dist/features/help/index.mjs +95 -105
- package/dist/features/help/index.mjs.map +1 -1
- package/dist/features/help/server.d.mts +27 -65
- package/dist/features/help/server.d.ts +27 -65
- package/dist/features/help/server.js +4 -119
- package/dist/features/help/server.js.map +1 -1
- package/dist/features/help/server.mjs +4 -119
- package/dist/features/help/server.mjs.map +1 -1
- package/dist/help-content-config.interface-C5ESIod9.d.mts +13 -0
- package/dist/help-content-config.interface-C5ESIod9.d.ts +13 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -3
- package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.js +54 -0
- package/dist/scripts/generate-web-module/__tests__/container.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.js +19 -0
- package/dist/scripts/generate-web-module/__tests__/data-service.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.js +35 -0
- package/dist/scripts/generate-web-module/__tests__/editor.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts +4 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.js +45 -0
- package/dist/scripts/generate-web-module/__tests__/fixtures.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js +74 -0
- package/dist/scripts/generate-web-module/__tests__/model-interface.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js +21 -0
- package/dist/scripts/generate-web-module/__tests__/plumbing.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.js +25 -0
- package/dist/scripts/generate-web-module/__tests__/selector.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts +2 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js +55 -0
- package/dist/scripts/generate-web-module/__tests__/table-module-list.spec.js.map +1 -0
- package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/generator.js +14 -11
- package/dist/scripts/generate-web-module/generator.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.d.ts +5 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.js +43 -63
- package/dist/scripts/generate-web-module/templates/components/container.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/content.template.d.ts +7 -4
- package/dist/scripts/generate-web-module/templates/components/content.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/content.template.js +103 -14
- package/dist/scripts/generate-web-module/templates/components/content.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.d.ts +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.js +139 -150
- package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/index.d.ts +0 -1
- package/dist/scripts/generate-web-module/templates/components/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/index.js +1 -3
- package/dist/scripts/generate-web-module/templates/components/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/list-container.template.js +2 -2
- package/dist/scripts/generate-web-module/templates/components/list.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/list.template.js +6 -1
- package/dist/scripts/generate-web-module/templates/components/list.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.js +48 -52
- package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/interface.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/interface.template.js +38 -11
- package/dist/scripts/generate-web-module/templates/data/interface.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/model.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/model.template.js +83 -26
- package/dist/scripts/generate-web-module/templates/data/model.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js +21 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.js +1 -2
- package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/module.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/module.template.js +11 -3
- package/dist/scripts/generate-web-module/templates/module.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/table-hook.template.js +31 -1
- package/dist/scripts/generate-web-module/templates/table-hook.template.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts +0 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.js +0 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts +5 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.js +21 -0
- package/dist/scripts/generate-web-module/transformers/relationship-key.js.map +1 -0
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js +2 -0
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts +21 -0
- package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +17 -0
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/testing/index.d.mts +1 -2
- package/dist/testing/index.d.ts +1 -2
- package/package.json +1 -6
- package/scripts/generate-web-module/__tests__/container.spec.ts +58 -0
- package/scripts/generate-web-module/__tests__/data-service.spec.ts +18 -0
- package/scripts/generate-web-module/__tests__/editor.spec.ts +36 -0
- package/scripts/generate-web-module/__tests__/fixtures.ts +43 -0
- package/scripts/generate-web-module/__tests__/model-interface.spec.ts +77 -0
- package/scripts/generate-web-module/__tests__/plumbing.spec.ts +21 -0
- package/scripts/generate-web-module/__tests__/selector.spec.ts +24 -0
- package/scripts/generate-web-module/__tests__/table-module-list.spec.ts +59 -0
- package/scripts/generate-web-module/generator.ts +14 -13
- package/scripts/generate-web-module/templates/components/container.template.ts +51 -66
- package/scripts/generate-web-module/templates/components/content.template.ts +107 -15
- package/scripts/generate-web-module/templates/components/editor.template.ts +140 -152
- package/scripts/generate-web-module/templates/components/index.ts +0 -1
- package/scripts/generate-web-module/templates/components/list-container.template.ts +2 -2
- package/scripts/generate-web-module/templates/components/list.template.ts +6 -1
- package/scripts/generate-web-module/templates/components/selector.template.ts +48 -52
- package/scripts/generate-web-module/templates/data/interface.template.ts +44 -12
- package/scripts/generate-web-module/templates/data/model.template.ts +88 -28
- package/scripts/generate-web-module/templates/data/service.template.ts +23 -1
- package/scripts/generate-web-module/templates/index.ts +0 -1
- package/scripts/generate-web-module/templates/module.template.ts +13 -3
- package/scripts/generate-web-module/templates/table-hook.template.ts +31 -2
- package/scripts/generate-web-module/transformers/import-resolver.ts +0 -2
- package/scripts/generate-web-module/transformers/relationship-key.ts +18 -0
- package/scripts/generate-web-module/transformers/relationship-resolver.ts +2 -0
- package/scripts/generate-web-module/types/json-schema.interface.ts +9 -0
- package/scripts/generate-web-module/types/template-data.interface.ts +7 -0
- package/src/client/config.ts +1 -1
- package/src/components/index.ts +1 -0
- package/src/components/viewers/BlockNoteViewer.tsx +27 -0
- package/src/components/viewers/BlockNoteViewerContainer.tsx +10 -0
- package/src/core/registry/helpStore.ts +2 -19
- package/src/features/assistant-message/components/parts/MessageSourcesContainer.tsx +4 -0
- package/src/features/assistant-message/components/parts/tabs/ContentsTab.tsx +5 -5
- package/src/features/assistant-message/components/parts/tabs/ReferencesTab.tsx +3 -2
- package/src/features/help/components/HelpArticleBody.tsx +27 -19
- package/src/features/help/components/HelpHint.tsx +20 -11
- package/src/features/help/components/HelpSearchResultRow.tsx +16 -6
- package/src/features/help/components/HelpSideNav.tsx +54 -19
- package/src/features/help/components/__tests__/HelpAskAi.spec.tsx +1 -1
- package/src/features/help/components/__tests__/HelpHint.spec.tsx +17 -17
- package/src/features/help/components/__tests__/HelpSearchResultRow.spec.tsx +18 -19
- package/src/features/help/components/__tests__/HelpSideNav.spec.tsx +20 -22
- package/src/features/help/contexts/HelpContext.spec.tsx +1 -3
- package/src/features/help/index.ts +3 -6
- package/src/features/help/interfaces/help-content-config.interface.ts +0 -5
- package/src/features/help/server-entry.ts +6 -15
- package/src/features/help/types/help-article.types.ts +2 -4
- package/src/features/how-to/HowToModule.ts +14 -1
- package/src/features/how-to/components/forms/HowToEditor.tsx +108 -4
- package/src/features/how-to/data/HowTo.spec.ts +43 -0
- package/src/features/how-to/data/HowTo.ts +47 -4
- package/src/features/how-to/data/HowToInterface.ts +14 -1
- package/src/features/how-to/data/HowToService.ts +61 -0
- package/dist/BlockNoteEditor-3XYBZLWO.js.map +0 -1
- package/dist/chunk-3J7RQBF3.js +0 -123
- package/dist/chunk-3J7RQBF3.js.map +0 -1
- package/dist/chunk-7E3O52U5.js.map +0 -1
- package/dist/chunk-CFI4WZ5R.js.map +0 -1
- package/dist/chunk-CQID6RCF.mjs +0 -38
- package/dist/chunk-CQID6RCF.mjs.map +0 -1
- package/dist/chunk-CRTVAQEK.mjs.map +0 -1
- package/dist/chunk-MZTKPPET.mjs +0 -123
- package/dist/chunk-MZTKPPET.mjs.map +0 -1
- package/dist/chunk-UHO3KUUH.js.map +0 -1
- package/dist/chunk-YQQHAFBS.js +0 -38
- package/dist/chunk-YQQHAFBS.js.map +0 -1
- package/dist/features/help/server/createHelpAssetRouteHandler.d.mts +0 -11
- package/dist/features/help/server/createHelpAssetRouteHandler.d.ts +0 -11
- package/dist/features/help/server/createHelpAssetRouteHandler.js +0 -43
- package/dist/features/help/server/createHelpAssetRouteHandler.js.map +0 -1
- package/dist/features/help/server/createHelpAssetRouteHandler.mjs +0 -43
- package/dist/features/help/server/createHelpAssetRouteHandler.mjs.map +0 -1
- package/dist/help-content-config.interface-B9L02u9i.d.mts +0 -50
- package/dist/help-content-config.interface-B9L02u9i.d.ts +0 -50
- package/dist/scripts/generate-web-module/templates/components/details.template.d.ts +0 -14
- package/dist/scripts/generate-web-module/templates/components/details.template.d.ts.map +0 -1
- package/dist/scripts/generate-web-module/templates/components/details.template.js +0 -112
- package/dist/scripts/generate-web-module/templates/components/details.template.js.map +0 -1
- package/scripts/generate-web-module/templates/components/details.template.ts +0 -116
- package/src/features/help/components/mdx/Callout.tsx +0 -21
- package/src/features/help/components/mdx/EntityRef.tsx +0 -18
- package/src/features/help/components/mdx/KeyBinding.tsx +0 -6
- package/src/features/help/components/mdx/Related.tsx +0 -33
- package/src/features/help/components/mdx/Screenshot.tsx +0 -9
- package/src/features/help/components/mdx/Steps.tsx +0 -21
- package/src/features/help/components/mdx/Video.tsx +0 -8
- package/src/features/help/components/mdx/mdx-server-components.ts +0 -23
- package/src/features/help/components/mdx/mdxComponents.ts +0 -9
- package/src/features/help/hooks/useHelpArticle.ts +0 -7
- package/src/features/help/hooks/useHelpManifest.ts +0 -5
- package/src/features/help/server/__tests__/createHelpAssetRouteHandler.spec.ts +0 -43
- package/src/features/help/server/createHelpAssetRouteHandler.ts +0 -35
- package/src/features/help/server/generateHelpArticleMetadata.ts +0 -18
- package/src/features/help/server/generateHelpArticleStaticParams.ts +0 -7
- package/src/features/help/server/generateHelpModeStaticParams.ts +0 -5
- package/src/features/help/server/getHelpContent.ts +0 -17
- package/src/features/help/server/index.ts +0 -8
- package/src/features/help/server/serializeHelpArticle.tsx +0 -46
- package/src/features/help/utils/__tests__/helpNavigation.spec.ts +0 -70
- package/src/features/help/utils/helpNavigation.ts +0 -29
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export function Video({ src, poster }: { src: string; poster?: string }) {
|
|
2
|
-
const url = src.startsWith("/") ? src : `/help-assets/${src}`;
|
|
3
|
-
return (
|
|
4
|
-
<video controls preload="metadata" poster={poster} className="my-4 w-full rounded-md ring-1 ring-border">
|
|
5
|
-
<source src={url} />
|
|
6
|
-
</video>
|
|
7
|
-
);
|
|
8
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// Server-safe subset of MDX_COMPONENTS used by `renderHelpArticle`.
|
|
2
|
-
// Mirrors `mdxComponents.ts` but EXCLUDES `Related` (which is a client
|
|
3
|
-
// component that uses `useHelp` + `usePageUrlGenerator`). Server-side rendering
|
|
4
|
-
// of `<Related>` would require passing the manifest by prop, which the standard
|
|
5
|
-
// MDX components map cannot do — articles that need related links should be
|
|
6
|
-
// extended via a server-side render hook rather than the MDX shortcode.
|
|
7
|
-
|
|
8
|
-
import { Callout } from "./Callout";
|
|
9
|
-
import { Steps, Step } from "./Steps";
|
|
10
|
-
import { Screenshot } from "./Screenshot";
|
|
11
|
-
import { EntityRef } from "./EntityRef";
|
|
12
|
-
import { KeyBinding } from "./KeyBinding";
|
|
13
|
-
import { Video } from "./Video";
|
|
14
|
-
|
|
15
|
-
export const MDX_SERVER_COMPONENTS = {
|
|
16
|
-
Callout,
|
|
17
|
-
Steps,
|
|
18
|
-
Step,
|
|
19
|
-
Screenshot,
|
|
20
|
-
EntityRef,
|
|
21
|
-
KeyBinding,
|
|
22
|
-
Video,
|
|
23
|
-
} as const;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Callout } from "./Callout";
|
|
2
|
-
import { Steps, Step } from "./Steps";
|
|
3
|
-
import { Screenshot } from "./Screenshot";
|
|
4
|
-
import { EntityRef } from "./EntityRef";
|
|
5
|
-
import { KeyBinding } from "./KeyBinding";
|
|
6
|
-
import { Video } from "./Video";
|
|
7
|
-
import { Related } from "./Related";
|
|
8
|
-
|
|
9
|
-
export const MDX_COMPONENTS = { Callout, Steps, Step, Screenshot, EntityRef, KeyBinding, Video, Related };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { mkdtemp, writeFile, mkdir, rm } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { createHelpAssetRouteHandler } from "../createHelpAssetRouteHandler";
|
|
6
|
-
|
|
7
|
-
describe("createHelpAssetRouteHandler", () => {
|
|
8
|
-
let srcRoot: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
srcRoot = await mkdtemp(join(tmpdir(), "help-assets-"));
|
|
12
|
-
await mkdir(srcRoot, { recursive: true });
|
|
13
|
-
await writeFile(join(srcRoot, "ok.png"), Buffer.from([0x89, 0x50, 0x4e, 0x47]));
|
|
14
|
-
});
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await rm(srcRoot, { recursive: true, force: true });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("returns 200 with correct MIME for an existing PNG", async () => {
|
|
20
|
-
const GET = createHelpAssetRouteHandler({ srcRoot });
|
|
21
|
-
const res = await GET(new Request("http://localhost/help-assets/ok.png"), {
|
|
22
|
-
params: Promise.resolve({ path: ["ok.png"] }),
|
|
23
|
-
});
|
|
24
|
-
expect(res.status).toBe(200);
|
|
25
|
-
expect(res.headers.get("Content-Type")).toBe("image/png");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("returns 404 for missing files", async () => {
|
|
29
|
-
const GET = createHelpAssetRouteHandler({ srcRoot });
|
|
30
|
-
const res = await GET(new Request("http://localhost/help-assets/missing.png"), {
|
|
31
|
-
params: Promise.resolve({ path: ["missing.png"] }),
|
|
32
|
-
});
|
|
33
|
-
expect(res.status).toBe(404);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("sanitizes path traversal attempts", async () => {
|
|
37
|
-
const GET = createHelpAssetRouteHandler({ srcRoot });
|
|
38
|
-
const res = await GET(new Request("http://localhost/help-assets/etc/passwd"), {
|
|
39
|
-
params: Promise.resolve({ path: ["..", "..", "etc", "passwd"] }),
|
|
40
|
-
});
|
|
41
|
-
expect(res.status).toBe(404);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import { readFile, stat } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
|
|
5
|
-
const MIME: Record<string, string> = {
|
|
6
|
-
".png": "image/png",
|
|
7
|
-
".jpg": "image/jpeg",
|
|
8
|
-
".jpeg": "image/jpeg",
|
|
9
|
-
".webp": "image/webp",
|
|
10
|
-
".gif": "image/gif",
|
|
11
|
-
".svg": "image/svg+xml",
|
|
12
|
-
".mp4": "video/mp4",
|
|
13
|
-
".webm": "video/webm",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function createHelpAssetRouteHandler({ srcRoot }: { srcRoot: string }) {
|
|
17
|
-
return async function GET(_req: Request, { params }: { params: Promise<{ path: string[] }> }) {
|
|
18
|
-
const { path } = await params;
|
|
19
|
-
const safe = path.filter((p) => p !== ".." && !p.includes("/")).join("/");
|
|
20
|
-
const filePath = join(srcRoot, safe);
|
|
21
|
-
try {
|
|
22
|
-
const s = await stat(filePath);
|
|
23
|
-
if (!s.isFile()) return new NextResponse("Not found", { status: 404 });
|
|
24
|
-
const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
|
|
25
|
-
const mime = MIME[ext] ?? "application/octet-stream";
|
|
26
|
-
const data = await readFile(filePath);
|
|
27
|
-
return new NextResponse(data, {
|
|
28
|
-
status: 200,
|
|
29
|
-
headers: { "Content-Type": mime, "Cache-Control": "public, max-age=3600" },
|
|
30
|
-
});
|
|
31
|
-
} catch {
|
|
32
|
-
return new NextResponse("Not found", { status: 404 });
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Metadata } from "next";
|
|
2
|
-
import { findHelpArticle } from "../utils/helpNavigation";
|
|
3
|
-
import { getHelpContent } from "./getHelpContent";
|
|
4
|
-
|
|
5
|
-
export async function generateHelpArticleMetadata({
|
|
6
|
-
params,
|
|
7
|
-
}: {
|
|
8
|
-
params: Promise<{ mode: string; slug: string }>;
|
|
9
|
-
}): Promise<Metadata> {
|
|
10
|
-
const { mode, slug } = await params;
|
|
11
|
-
const article = findHelpArticle(getHelpContent().manifest, mode, slug);
|
|
12
|
-
if (!article) return {};
|
|
13
|
-
return {
|
|
14
|
-
title: article.title,
|
|
15
|
-
description: article.summary,
|
|
16
|
-
openGraph: { title: article.title, description: article.summary },
|
|
17
|
-
};
|
|
18
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { _getStaticHelpContent } from "../../../core/registry/helpStore";
|
|
2
|
-
import type { HelpContentConfig } from "../interfaces/help-content-config.interface";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Server-side accessor for the help-content config set via configureJsonApi().
|
|
6
|
-
* Returns the same value <HelpProvider> exposes via React Context to client components.
|
|
7
|
-
* Throws with a setup error if helpContent was never configured.
|
|
8
|
-
*/
|
|
9
|
-
export function getHelpContent(): HelpContentConfig {
|
|
10
|
-
const cfg = _getStaticHelpContent<HelpContentConfig>();
|
|
11
|
-
if (!cfg) {
|
|
12
|
-
throw new Error(
|
|
13
|
-
"Help content not configured — call configureJsonApi({ helpContent: {...} }) before importing help pages.",
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
return cfg;
|
|
17
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { getHelpContent } from "./getHelpContent";
|
|
2
|
-
export { renderHelpArticle, serializeHelpArticle } from "./serializeHelpArticle";
|
|
3
|
-
export { generateHelpArticleStaticParams } from "./generateHelpArticleStaticParams";
|
|
4
|
-
export { generateHelpArticleMetadata } from "./generateHelpArticleMetadata";
|
|
5
|
-
export { generateHelpModeStaticParams } from "./generateHelpModeStaticParams";
|
|
6
|
-
// NOTE: `createHelpAssetRouteHandler` is intentionally NOT re-exported here.
|
|
7
|
-
// It uses `node:fs/promises` and must only be reachable via the dedicated
|
|
8
|
-
// `@carlonicora/nextjs-jsonapi/help-asset-route` subpath, never the main bundle.
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { MDXRemote } from "next-mdx-remote/rsc";
|
|
2
|
-
import remarkGfm from "remark-gfm";
|
|
3
|
-
import rehypeSlug from "rehype-slug";
|
|
4
|
-
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
|
5
|
-
import type { ReactElement } from "react";
|
|
6
|
-
import type { HelpArticle } from "../types/help-article.types";
|
|
7
|
-
import { _getStaticHelpReader } from "../../../core/registry/helpStore";
|
|
8
|
-
import { MDX_SERVER_COMPONENTS } from "../components/mdx/mdx-server-components";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Server-side: read the article's raw markdown via the registered help reader
|
|
12
|
-
* and render it through `next-mdx-remote/rsc`'s server-side MDXRemote, using
|
|
13
|
-
* the server-safe MDX components (Callout, Steps, Screenshot, EntityRef,
|
|
14
|
-
* KeyBinding, Video). The returned React element can be embedded inside a
|
|
15
|
-
* server component (e.g. as `children` of `<HelpArticleBody>`).
|
|
16
|
-
*
|
|
17
|
-
* Note: `<Related>` is intentionally not part of the server map — it's a client
|
|
18
|
-
* component that reads HelpContext. Articles that reference `<Related>` would
|
|
19
|
-
* need a separate render path that injects the manifest by prop.
|
|
20
|
-
*/
|
|
21
|
-
export async function renderHelpArticle(article: HelpArticle): Promise<ReactElement> {
|
|
22
|
-
const readRawMarkdown = _getStaticHelpReader();
|
|
23
|
-
if (!readRawMarkdown) {
|
|
24
|
-
throw new Error(
|
|
25
|
-
"Help reader not configured. Call setHelpReader(fn) from a server-only entrypoint (e.g. Next.js instrumentation register()) before rendering help articles.",
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
const source = await readRawMarkdown(article);
|
|
29
|
-
return (
|
|
30
|
-
<MDXRemote
|
|
31
|
-
source={source}
|
|
32
|
-
components={MDX_SERVER_COMPONENTS}
|
|
33
|
-
options={{
|
|
34
|
-
parseFrontmatter: true,
|
|
35
|
-
mdxOptions: {
|
|
36
|
-
remarkPlugins: [remarkGfm],
|
|
37
|
-
rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: "wrap" }]],
|
|
38
|
-
},
|
|
39
|
-
}}
|
|
40
|
-
/>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** @deprecated Use `renderHelpArticle` instead — the legacy serialize + client
|
|
45
|
-
* MDXRemote pattern is incompatible with App Router RSC. */
|
|
46
|
-
export const serializeHelpArticle = renderHelpArticle;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { buildHelpNav, findHelpArticle, prevNextWithinMode } from "../helpNavigation";
|
|
3
|
-
|
|
4
|
-
const base = {
|
|
5
|
-
tags: [],
|
|
6
|
-
contextualKeys: [],
|
|
7
|
-
aiIndexed: true,
|
|
8
|
-
draft: false,
|
|
9
|
-
contentHash: "h",
|
|
10
|
-
headings: [],
|
|
11
|
-
relatedSlugs: [],
|
|
12
|
-
lastUpdated: "",
|
|
13
|
-
};
|
|
14
|
-
const manifest = [
|
|
15
|
-
{
|
|
16
|
-
...base,
|
|
17
|
-
id: "a",
|
|
18
|
-
slug: "a",
|
|
19
|
-
mode: "how-to" as const,
|
|
20
|
-
title: "Alpha",
|
|
21
|
-
summary: "s",
|
|
22
|
-
order: 1,
|
|
23
|
-
path: "how-to/a.mdx",
|
|
24
|
-
},
|
|
25
|
-
{ ...base, id: "b", slug: "b", mode: "how-to" as const, title: "Beta", summary: "s", order: 2, path: "how-to/b.mdx" },
|
|
26
|
-
{
|
|
27
|
-
...base,
|
|
28
|
-
id: "c",
|
|
29
|
-
slug: "c",
|
|
30
|
-
mode: "tutorial" as const,
|
|
31
|
-
title: "Gamma",
|
|
32
|
-
summary: "s",
|
|
33
|
-
order: 1,
|
|
34
|
-
path: "tutorial/c.mdx",
|
|
35
|
-
},
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
describe("helpNavigation", () => {
|
|
39
|
-
it("buildHelpNav groups articles by mode, sorted by order", () => {
|
|
40
|
-
const groups = buildHelpNav(manifest);
|
|
41
|
-
const howTo = groups.find((g) => g.mode === "how-to")!;
|
|
42
|
-
expect(howTo.articles.map((a) => a.slug)).toEqual(["a", "b"]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("findHelpArticle locates by mode + slug", () => {
|
|
46
|
-
expect(findHelpArticle(manifest, "how-to", "b")?.title).toBe("Beta");
|
|
47
|
-
expect(findHelpArticle(manifest, "how-to", "missing")).toBeUndefined();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("prevNextWithinMode returns siblings within the same mode", () => {
|
|
51
|
-
const current = manifest[0]; // Alpha (how-to, order 1)
|
|
52
|
-
const { prev, next } = prevNextWithinMode(manifest, current);
|
|
53
|
-
expect(prev).toBeNull();
|
|
54
|
-
expect(next?.slug).toBe("b");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("prevNextWithinMode returns null at the boundaries", () => {
|
|
58
|
-
const current = manifest[1]; // Beta (how-to, order 2)
|
|
59
|
-
const { prev, next } = prevNextWithinMode(manifest, current);
|
|
60
|
-
expect(prev?.slug).toBe("a");
|
|
61
|
-
expect(next).toBeNull();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("prevNextWithinMode does not cross modes", () => {
|
|
65
|
-
const current = manifest[2]; // Gamma (tutorial)
|
|
66
|
-
const { prev, next } = prevNextWithinMode(manifest, current);
|
|
67
|
-
expect(prev).toBeNull();
|
|
68
|
-
expect(next).toBeNull();
|
|
69
|
-
});
|
|
70
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { HELP_MODES, type HelpArticle, type HelpMode } from "../types/help-article.types";
|
|
2
|
-
|
|
3
|
-
export interface HelpNavGroup {
|
|
4
|
-
mode: HelpMode;
|
|
5
|
-
articles: HelpArticle[];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function buildHelpNav(manifest: readonly HelpArticle[]): HelpNavGroup[] {
|
|
9
|
-
return HELP_MODES.map((mode) => ({
|
|
10
|
-
mode,
|
|
11
|
-
articles: manifest.filter((a) => a.mode === mode && !a.draft).sort((a, b) => a.order - b.order),
|
|
12
|
-
}));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function findHelpArticle(manifest: readonly HelpArticle[], mode: string, slug: string): HelpArticle | undefined {
|
|
16
|
-
return manifest.find((a) => a.mode === mode && a.slug === slug);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function prevNextWithinMode(
|
|
20
|
-
manifest: readonly HelpArticle[],
|
|
21
|
-
current: HelpArticle,
|
|
22
|
-
): { prev: HelpArticle | null; next: HelpArticle | null } {
|
|
23
|
-
const siblings = manifest.filter((a) => a.mode === current.mode && !a.draft).sort((a, b) => a.order - b.order);
|
|
24
|
-
const idx = siblings.findIndex((a) => a.slug === current.slug);
|
|
25
|
-
return {
|
|
26
|
-
prev: idx > 0 ? siblings[idx - 1] : null,
|
|
27
|
-
next: idx >= 0 && idx < siblings.length - 1 ? siblings[idx + 1] : null,
|
|
28
|
-
};
|
|
29
|
-
}
|