@carlonicora/nextjs-jsonapi 1.68.0 → 1.69.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.
Files changed (98) hide show
  1. package/dist/{AuthComponent-NwQ_ZXsv.d.mts → AuthComponent-DXe3kPzb.d.mts} +1 -1
  2. package/dist/{AuthComponent-DL1D3y7f.d.ts → AuthComponent-Di8DsZ2I.d.ts} +1 -1
  3. package/dist/{BlockNoteEditor-DXHROT4C.js → BlockNoteEditor-CBUEPFA7.js} +14 -14
  4. package/dist/{BlockNoteEditor-DXHROT4C.js.map → BlockNoteEditor-CBUEPFA7.js.map} +1 -1
  5. package/dist/{BlockNoteEditor-6FDECIS2.mjs → BlockNoteEditor-ON5Q6QWO.mjs} +4 -4
  6. package/dist/HowToInterface-DtVWAE1s.d.mts +17 -0
  7. package/dist/HowToInterface-NaqSG9sE.d.ts +17 -0
  8. package/dist/{auth.interface-BX_1qZZJ.d.ts → auth.interface-BTco8PWs.d.ts} +1 -1
  9. package/dist/{auth.interface-yeLelxdI.d.mts → auth.interface-C4uJzBec.d.mts} +1 -1
  10. package/dist/billing/index.js +346 -346
  11. package/dist/billing/index.mjs +3 -3
  12. package/dist/{chunk-37KYO2UD.js → chunk-56VU7A4I.js} +172 -18
  13. package/dist/chunk-56VU7A4I.js.map +1 -0
  14. package/dist/{chunk-ELTHSXBI.js → chunk-5X4MS55M.js} +1655 -695
  15. package/dist/chunk-5X4MS55M.js.map +1 -0
  16. package/dist/{chunk-WOJIRXIP.js → chunk-6ROMPIIP.js} +11 -11
  17. package/dist/{chunk-WOJIRXIP.js.map → chunk-6ROMPIIP.js.map} +1 -1
  18. package/dist/{chunk-IOMDNRX5.mjs → chunk-GZNHBAZF.mjs} +155 -1
  19. package/dist/chunk-GZNHBAZF.mjs.map +1 -0
  20. package/dist/{chunk-H4ZS3R76.mjs → chunk-NPF7P7MU.mjs} +2561 -1601
  21. package/dist/chunk-NPF7P7MU.mjs.map +1 -0
  22. package/dist/{chunk-WVTBEVAL.mjs → chunk-WJYWWOTG.mjs} +2 -2
  23. package/dist/client/index.d.mts +5 -6
  24. package/dist/client/index.d.ts +5 -6
  25. package/dist/client/index.js +4 -4
  26. package/dist/client/index.mjs +3 -3
  27. package/dist/components/index.d.mts +76 -8
  28. package/dist/components/index.d.ts +76 -8
  29. package/dist/components/index.js +26 -4
  30. package/dist/components/index.js.map +1 -1
  31. package/dist/components/index.mjs +25 -3
  32. package/dist/{config-D-mqttuF.d.mts → config-Bmr_0qTn.d.mts} +1 -1
  33. package/dist/{config-CyCAWW-d.d.ts → config-n0lfSf27.d.ts} +1 -1
  34. package/dist/contexts/index.d.mts +16 -4
  35. package/dist/contexts/index.d.ts +16 -4
  36. package/dist/contexts/index.js +8 -4
  37. package/dist/contexts/index.js.map +1 -1
  38. package/dist/contexts/index.mjs +7 -3
  39. package/dist/core/index.d.mts +61 -11
  40. package/dist/core/index.d.ts +61 -11
  41. package/dist/core/index.js +10 -2
  42. package/dist/core/index.js.map +1 -1
  43. package/dist/core/index.mjs +9 -1
  44. package/dist/index.d.mts +9 -10
  45. package/dist/index.d.ts +9 -10
  46. package/dist/index.js +11 -3
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +10 -2
  49. package/dist/{notification.interface-ItBxq2au.d.ts → notification.interface-DYDZENx2.d.ts} +18 -1
  50. package/dist/{notification.interface-C6UcmJqu.d.mts → notification.interface-DrHu_1MM.d.mts} +18 -1
  51. package/dist/{s3.service-N1g0piXD.d.ts → s3.service-DK2KKXbR.d.ts} +2 -3
  52. package/dist/{s3.service-CHOTwfWA.d.mts → s3.service-TsN2unZr.d.mts} +2 -3
  53. package/dist/server/index.d.mts +3 -4
  54. package/dist/server/index.d.ts +3 -4
  55. package/dist/server/index.js +3 -3
  56. package/dist/server/index.mjs +1 -1
  57. package/dist/{useRbacState-CUj0hp8t.d.ts → useRbacState-BYaSdA78.d.ts} +1 -1
  58. package/dist/{useRbacState-Btk1gkQg.d.mts → useRbacState-CQEJ_ysV.d.mts} +1 -1
  59. package/dist/{useSocket-BSUN9s3p.d.ts → useSocket-Cjt_qvkI.d.ts} +1 -1
  60. package/dist/{useSocket-DKI92Fbg.d.mts → useSocket-VAGetcT3.d.mts} +1 -1
  61. package/package.json +1 -1
  62. package/src/components/index.ts +1 -0
  63. package/src/contexts/index.ts +1 -0
  64. package/src/core/index.ts +2 -0
  65. package/src/core/registry/ModuleRegistry.ts +19 -0
  66. package/src/features/how-to/HowToModule.ts +18 -0
  67. package/src/features/how-to/components/containers/HowToCommand.tsx +230 -0
  68. package/src/features/how-to/components/containers/HowToCommandViewer.tsx +76 -0
  69. package/src/features/how-to/components/containers/HowToContainer.tsx +27 -0
  70. package/src/features/how-to/components/containers/HowToListContainer.tsx +17 -0
  71. package/src/features/how-to/components/details/HowToContent.tsx +16 -0
  72. package/src/features/how-to/components/details/HowToDetails.tsx +52 -0
  73. package/src/features/how-to/components/forms/HowToDeleter.tsx +31 -0
  74. package/src/features/how-to/components/forms/HowToEditor.tsx +270 -0
  75. package/src/features/how-to/components/forms/HowToMultiSelector.tsx +152 -0
  76. package/src/features/how-to/components/forms/HowToSelector.tsx +164 -0
  77. package/src/features/how-to/components/index.ts +11 -0
  78. package/src/features/how-to/components/lists/HowToList.tsx +39 -0
  79. package/src/features/how-to/contexts/HowToContext.tsx +101 -0
  80. package/src/features/how-to/data/HowTo.ts +69 -0
  81. package/src/features/how-to/data/HowToFields.ts +10 -0
  82. package/src/features/how-to/data/HowToInterface.ts +11 -0
  83. package/src/features/how-to/data/HowToService.ts +61 -0
  84. package/src/features/how-to/data/index.ts +4 -0
  85. package/src/features/how-to/hooks/useHowToTableStructure.tsx +86 -0
  86. package/src/features/how-to/index.ts +2 -0
  87. package/src/features/how-to/utils/blocknote.ts +108 -0
  88. package/src/features/how-to/utils/index.ts +1 -0
  89. package/dist/breadcrumb.item.data.interface-CgB4_1EE.d.mts +0 -6
  90. package/dist/breadcrumb.item.data.interface-CgB4_1EE.d.ts +0 -6
  91. package/dist/chunk-37KYO2UD.js.map +0 -1
  92. package/dist/chunk-ELTHSXBI.js.map +0 -1
  93. package/dist/chunk-H4ZS3R76.mjs.map +0 -1
  94. package/dist/chunk-IOMDNRX5.mjs.map +0 -1
  95. package/dist/content.interface-8T5-G84c.d.mts +0 -21
  96. package/dist/content.interface-D-xdYxjt.d.ts +0 -21
  97. /package/dist/{BlockNoteEditor-6FDECIS2.mjs.map → BlockNoteEditor-ON5Q6QWO.mjs.map} +0 -0
  98. /package/dist/{chunk-WVTBEVAL.mjs.map → chunk-WJYWWOTG.mjs.map} +0 -0
@@ -0,0 +1,101 @@
1
+ "use client";
2
+
3
+ import { JsonApiHydratedDataInterface, Modules, rehydrate } from "../../../core";
4
+ import { BreadcrumbItemData } from "../../../interfaces";
5
+ import { usePageUrlGenerator } from "../../../hooks";
6
+ import { SharedProvider } from "../../../contexts/SharedContext";
7
+ import { HowToInterface } from "../data/HowToInterface";
8
+ import { HowToService } from "../data/HowToService";
9
+ import HowToDeleter from "../components/forms/HowToDeleter";
10
+ import HowToEditor from "../components/forms/HowToEditor";
11
+ import { useTranslations } from "next-intl";
12
+ import { createContext, ReactNode, useContext, useState } from "react";
13
+
14
+ interface HowToContextType {
15
+ howTo: HowToInterface | undefined;
16
+ setHowTo: (value: HowToInterface | undefined) => void;
17
+ reloadHowTo: () => Promise<void>;
18
+ }
19
+
20
+ const HowToContext = createContext<HowToContextType | undefined>(undefined);
21
+
22
+ type HowToProviderProps = {
23
+ children: ReactNode;
24
+ dehydratedHowTo?: JsonApiHydratedDataInterface;
25
+ };
26
+
27
+ export const HowToProvider = ({ children, dehydratedHowTo }: HowToProviderProps) => {
28
+ const generateUrl = usePageUrlGenerator();
29
+ const t = useTranslations();
30
+
31
+ const [howTo, setHowTo] = useState<HowToInterface | undefined>(
32
+ dehydratedHowTo ? rehydrate<HowToInterface>(Modules.HowTo, dehydratedHowTo) : undefined,
33
+ );
34
+
35
+ const reloadHowTo = async () => {
36
+ if (!howTo) return;
37
+
38
+ const freshHowTo = await HowToService.findOne({ id: howTo.id });
39
+ setHowTo(freshHowTo);
40
+ };
41
+
42
+ const breadcrumb = () => {
43
+ const response: BreadcrumbItemData[] = [];
44
+
45
+ response.push({
46
+ name: t(`entities.howtos`, { count: 2 }),
47
+ href: generateUrl({ page: Modules.HowTo }),
48
+ });
49
+
50
+ if (howTo)
51
+ response.push({
52
+ name: howTo.name,
53
+ href: generateUrl({ page: Modules.HowTo, id: howTo.id }),
54
+ });
55
+
56
+ return response;
57
+ };
58
+
59
+ const title = () => {
60
+ const response: any = {
61
+ type: t(`entities.howtos`, { count: howTo ? 1 : 2 }),
62
+ };
63
+
64
+ const functions: ReactNode[] = [];
65
+
66
+ if (howTo) {
67
+ response.element = howTo.name;
68
+
69
+ functions.push(<HowToDeleter key={`HowToDeleter`} howTo={howTo} />);
70
+ functions.push(<HowToEditor key={`HowToEditor`} howTo={howTo} propagateChanges={setHowTo} />);
71
+ } else {
72
+ functions.push(<HowToEditor key={`HowToEditor`} />);
73
+ }
74
+
75
+ if (functions.length > 0) response.functions = functions;
76
+
77
+ return response;
78
+ };
79
+
80
+ return (
81
+ <SharedProvider value={{ breadcrumbs: breadcrumb(), title: title() }}>
82
+ <HowToContext.Provider
83
+ value={{
84
+ howTo: howTo,
85
+ setHowTo: setHowTo,
86
+ reloadHowTo: reloadHowTo,
87
+ }}
88
+ >
89
+ {children}
90
+ </HowToContext.Provider>
91
+ </SharedProvider>
92
+ );
93
+ };
94
+
95
+ export const useHowToContext = (): HowToContextType => {
96
+ const context = useContext(HowToContext);
97
+ if (context === undefined) {
98
+ throw new Error("useHowToContext must be used within a HowToProvider");
99
+ }
100
+ return context;
101
+ };
@@ -0,0 +1,69 @@
1
+ import { JsonApiHydratedDataInterface, Modules } from "../../../core";
2
+ import { Content } from "../../content/data/content";
3
+ import { HowToInput, HowToInterface } from "./HowToInterface";
4
+
5
+ export class HowTo extends Content implements HowToInterface {
6
+ private _description?: any;
7
+ private _pages?: string;
8
+
9
+ /**
10
+ * Parse pages from backend JSON string (handles legacy single string + JSON array)
11
+ */
12
+ static parsePagesFromString(pagesStr?: string): string[] {
13
+ if (!pagesStr) return [];
14
+ try {
15
+ const parsed = JSON.parse(pagesStr);
16
+ return Array.isArray(parsed) ? parsed : [pagesStr];
17
+ } catch {
18
+ // Legacy: treat as single page if not valid JSON
19
+ return pagesStr ? [pagesStr] : [];
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Serialize pages array to JSON string for backend
25
+ */
26
+ static serializePagesToString(pages: string[]): string | undefined {
27
+ const filtered = pages.filter((p) => p.trim());
28
+ return filtered.length > 0 ? JSON.stringify(filtered) : undefined;
29
+ }
30
+
31
+ get description(): any {
32
+ return this._description;
33
+ }
34
+
35
+ get pages(): string | undefined {
36
+ return this._pages;
37
+ }
38
+
39
+ rehydrate(data: JsonApiHydratedDataInterface): this {
40
+ super.rehydrate(data);
41
+
42
+ this._description = data.jsonApi.attributes.description
43
+ ? JSON.parse(data.jsonApi.attributes.description)
44
+ : undefined;
45
+ this._pages = data.jsonApi.attributes.pages;
46
+
47
+ return this;
48
+ }
49
+
50
+ createJsonApi(data: HowToInput) {
51
+ const response: any = {
52
+ data: {
53
+ type: Modules.HowTo.name,
54
+ id: data.id,
55
+ attributes: {},
56
+ meta: {},
57
+ relationships: {},
58
+ },
59
+ included: [],
60
+ };
61
+
62
+ super.addContentInput(response, data);
63
+
64
+ if (data.description !== undefined) response.data.attributes.description = JSON.stringify(data.description);
65
+ if (data.pages !== undefined) response.data.attributes.pages = data.pages;
66
+
67
+ return response;
68
+ }
69
+ }
@@ -0,0 +1,10 @@
1
+ export enum HowToFields {
2
+ howToId = "howToId",
3
+
4
+ name = "name",
5
+ description = "description",
6
+ pages = "pages",
7
+
8
+ createdAt = "createdAt",
9
+ updatedAt = "updatedAt",
10
+ }
@@ -0,0 +1,11 @@
1
+ import { ContentInput, ContentInterface } from "../../content/data/content.interface";
2
+
3
+ export type HowToInput = ContentInput & {
4
+ description?: any;
5
+ pages?: string | undefined | null;
6
+ };
7
+
8
+ export interface HowToInterface extends ContentInterface {
9
+ get description(): any;
10
+ get pages(): string | undefined;
11
+ }
@@ -0,0 +1,61 @@
1
+ import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from "../../../core";
2
+ import { HowToInput, HowToInterface } from "./HowToInterface";
3
+
4
+ export class HowToService extends AbstractService {
5
+ static async findOne(params: { id: string }): Promise<HowToInterface> {
6
+ return this.callApi<HowToInterface>({
7
+ type: Modules.HowTo,
8
+ method: HttpMethod.GET,
9
+ endpoint: new EndpointCreator({ endpoint: Modules.HowTo, id: params.id }).generate(),
10
+ });
11
+ }
12
+
13
+ static async findMany(
14
+ params: {
15
+ search?: string;
16
+ fetchAll?: boolean;
17
+ next?: NextRef;
18
+ prev?: PreviousRef;
19
+ } = {},
20
+ ): Promise<HowToInterface[]> {
21
+ const endpoint = new EndpointCreator({ endpoint: Modules.HowTo });
22
+
23
+ if (params.fetchAll) endpoint.addAdditionalParam("fetchAll", "true");
24
+ if (params.search) endpoint.addAdditionalParam("search", params.search);
25
+ if (Modules.HowTo.inclusions?.lists?.fields) endpoint.limitToFields(Modules.HowTo.inclusions.lists.fields);
26
+ if (Modules.HowTo.inclusions?.lists?.types) endpoint.limitToType(Modules.HowTo.inclusions.lists.types);
27
+
28
+ return this.callApi({
29
+ type: Modules.HowTo,
30
+ method: HttpMethod.GET,
31
+ endpoint: endpoint.generate(),
32
+ next: params.next,
33
+ });
34
+ }
35
+
36
+ static async create(params: HowToInput): Promise<HowToInterface> {
37
+ return this.callApi({
38
+ type: Modules.HowTo,
39
+ method: HttpMethod.POST,
40
+ endpoint: new EndpointCreator({ endpoint: Modules.HowTo }).generate(),
41
+ input: params,
42
+ });
43
+ }
44
+
45
+ static async update(params: HowToInput): Promise<HowToInterface> {
46
+ return this.callApi({
47
+ type: Modules.HowTo,
48
+ method: HttpMethod.PUT,
49
+ endpoint: new EndpointCreator({ endpoint: Modules.HowTo, id: params.id }).generate(),
50
+ input: params,
51
+ });
52
+ }
53
+
54
+ static async delete(params: { howToId: string }): Promise<void> {
55
+ await this.callApi({
56
+ type: Modules.HowTo,
57
+ method: HttpMethod.DELETE,
58
+ endpoint: new EndpointCreator({ endpoint: Modules.HowTo, id: params.howToId }).generate(),
59
+ });
60
+ }
61
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./HowTo";
2
+ export * from "./HowToFields";
3
+ export * from "./HowToInterface";
4
+ export * from "./HowToService";
@@ -0,0 +1,86 @@
1
+ "use client";
2
+
3
+ import { ColumnDef } from "@tanstack/react-table";
4
+ import { useTranslations } from "next-intl";
5
+ import { useMemo } from "react";
6
+
7
+ import { cellDate, cellId } from "../../../components";
8
+ import { Modules } from "../../../core";
9
+ import { registerTableGenerator, TableContent, usePageUrlGenerator, UseTableStructureHook } from "../../../hooks";
10
+ import { Link } from "../../../shadcnui";
11
+ import { HowToFields } from "../data/HowToFields";
12
+ import { HowToInterface } from "../data/HowToInterface";
13
+
14
+ export const useHowToTableStructure: UseTableStructureHook<HowToInterface, HowToFields> = (params) => {
15
+ const t = useTranslations();
16
+ const generateUrl = usePageUrlGenerator();
17
+
18
+ const tableData = useMemo(() => {
19
+ return params.data.map((howTo: HowToInterface) => {
20
+ const entry: TableContent<HowToInterface> = {
21
+ jsonApiData: howTo,
22
+ };
23
+ entry[HowToFields.howToId] = howTo.id;
24
+ params.fields.forEach((field) => {
25
+ entry[field] = howTo[field as keyof HowToInterface];
26
+ });
27
+ return entry;
28
+ });
29
+ }, [params.data, params.fields]);
30
+
31
+ const fieldColumnMap: Partial<Record<HowToFields, () => any>> = {
32
+ [HowToFields.howToId]: () =>
33
+ cellId({
34
+ name: "howToId",
35
+ checkedIds: params.checkedIds,
36
+ toggleId: params.toggleId,
37
+ }),
38
+ [HowToFields.name]: () => ({
39
+ id: "name",
40
+ accessorKey: "name",
41
+ header: t(`howto.fields.name.label`),
42
+ cell: ({ row }: { row: TableContent<HowToInterface> }) => {
43
+ const howTo: HowToInterface = row.original.jsonApiData;
44
+ return <Link href={generateUrl({ page: Modules.HowTo, id: howTo.id })}>{howTo.name}</Link>;
45
+ },
46
+ enableSorting: false,
47
+ enableHiding: false,
48
+ }),
49
+ [HowToFields.description]: () => ({
50
+ id: "description",
51
+ accessorKey: "description",
52
+ header: t(`howto.fields.description.label`),
53
+ cell: ({ row }: { row: TableContent<HowToInterface> }) => <>{row.getValue("description")}</>,
54
+ enableSorting: false,
55
+ enableHiding: false,
56
+ }),
57
+ [HowToFields.pages]: () => ({
58
+ id: "pages",
59
+ accessorKey: "pages",
60
+ header: t(`howto.fields.pages.label`),
61
+ cell: ({ row }: { row: TableContent<HowToInterface> }) => <>{row.getValue("pages")}</>,
62
+ enableSorting: false,
63
+ enableHiding: false,
64
+ }),
65
+ [HowToFields.createdAt]: () =>
66
+ cellDate({
67
+ name: "createdAt",
68
+ title: t(`common.date.create`),
69
+ }),
70
+ [HowToFields.updatedAt]: () =>
71
+ cellDate({
72
+ name: "updatedAt",
73
+ title: t(`common.date.update`),
74
+ }),
75
+ };
76
+
77
+ const columns = useMemo(() => {
78
+ return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<
79
+ TableContent<HowToInterface>
80
+ >[];
81
+ }, [params.fields, fieldColumnMap, t, generateUrl]);
82
+
83
+ return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);
84
+ };
85
+
86
+ registerTableGenerator("howtos", useHowToTableStructure);
@@ -0,0 +1,2 @@
1
+ export * from "./HowToModule";
2
+ export * from "./data";
@@ -0,0 +1,108 @@
1
+ export type TocHeading = {
2
+ id: string;
3
+ text: string;
4
+ level: number;
5
+ };
6
+
7
+ /**
8
+ * Extracts all text content from a BlockNote block recursively
9
+ */
10
+ function extractTextFromContent(content: any): string {
11
+ if (!content) return "";
12
+
13
+ if (typeof content === "string") return content;
14
+
15
+ if (Array.isArray(content)) {
16
+ return content.map(extractTextFromContent).join("");
17
+ }
18
+
19
+ if (content.text) return content.text;
20
+
21
+ if (content.content) {
22
+ return extractTextFromContent(content.content);
23
+ }
24
+
25
+ return "";
26
+ }
27
+
28
+ /**
29
+ * Extracts all text from BlockNote content for word counting
30
+ */
31
+ export function extractAllText(blocks: any[] | undefined): string {
32
+ if (!blocks || !Array.isArray(blocks)) return "";
33
+
34
+ return blocks
35
+ .map((block) => {
36
+ let text = extractTextFromContent(block.content);
37
+
38
+ // Recursively get text from children blocks
39
+ if (block.children && Array.isArray(block.children)) {
40
+ text += " " + extractAllText(block.children);
41
+ }
42
+
43
+ return text;
44
+ })
45
+ .join(" ")
46
+ .trim();
47
+ }
48
+
49
+ /**
50
+ * Calculates estimated reading time based on word count
51
+ * Assumes average reading speed of 200 words per minute
52
+ */
53
+ export function calculateReadingTime(blocks: any[] | undefined): number {
54
+ const text = extractAllText(blocks);
55
+ const wordCount = text.split(/\s+/).filter((word: string) => word.length > 0).length;
56
+ const minutes = Math.ceil(wordCount / 200);
57
+ return Math.max(1, minutes); // Minimum 1 minute
58
+ }
59
+
60
+ /**
61
+ * Generates a URL-friendly slug from text
62
+ */
63
+ function generateSlug(text: string, index: number): string {
64
+ const baseSlug = text
65
+ .toLowerCase()
66
+ .replace(/[^a-z0-9\s-]/g, "")
67
+ .replace(/\s+/g, "-")
68
+ .replace(/-+/g, "-")
69
+ .trim();
70
+
71
+ return baseSlug || `heading-${index}`;
72
+ }
73
+
74
+ /**
75
+ * Extracts headings from BlockNote content for table of contents
76
+ */
77
+ export function extractHeadings(blocks: any[] | undefined): TocHeading[] {
78
+ if (!blocks || !Array.isArray(blocks)) return [];
79
+
80
+ const headings: TocHeading[] = [];
81
+ let headingIndex = 0;
82
+
83
+ function processBlocks(blockArray: any[]) {
84
+ for (const block of blockArray) {
85
+ if (block.type === "heading") {
86
+ const level = block.props?.level || 1;
87
+ const text = extractTextFromContent(block.content);
88
+
89
+ if (text.trim()) {
90
+ headings.push({
91
+ id: generateSlug(text, headingIndex),
92
+ text: text.trim(),
93
+ level,
94
+ });
95
+ headingIndex++;
96
+ }
97
+ }
98
+
99
+ // Process children blocks recursively
100
+ if (block.children && Array.isArray(block.children)) {
101
+ processBlocks(block.children);
102
+ }
103
+ }
104
+ }
105
+
106
+ processBlocks(blocks);
107
+ return headings;
108
+ }
@@ -0,0 +1 @@
1
+ export * from "./blocknote";
@@ -1,6 +0,0 @@
1
- type BreadcrumbItemData = {
2
- name: string;
3
- href?: string;
4
- };
5
-
6
- export type { BreadcrumbItemData as B };
@@ -1,6 +0,0 @@
1
- type BreadcrumbItemData = {
2
- name: string;
3
- href?: string;
4
- };
5
-
6
- export type { BreadcrumbItemData as B };