smoodly 0.0.11 → 0.0.13
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/README.md +259 -38
- package/dist/admin/editor/CanvasOverlay.d.ts +6 -2
- package/dist/admin/editor/CanvasOverlay.js +9 -11
- package/dist/admin/editor/EditorView.js +130 -25
- package/dist/admin/editor/FloatingToolbar.d.ts +16 -0
- package/dist/admin/editor/FloatingToolbar.js +14 -0
- package/dist/admin/editor/InlineRichtext.d.ts +9 -0
- package/dist/admin/editor/InlineRichtext.js +50 -0
- package/dist/admin/editor/Outline.d.ts +16 -10
- package/dist/admin/editor/Outline.js +13 -10
- package/dist/admin/editor/inline-dom.d.ts +27 -0
- package/dist/admin/editor/inline-dom.js +43 -0
- package/dist/admin/editor/inline-session.d.ts +30 -0
- package/dist/admin/editor/inline-session.js +19 -0
- package/dist/admin/editor/protocol.d.ts +22 -1
- package/dist/admin/editor/useCanvasBridge.d.ts +8 -4
- package/dist/admin/editor/useCanvasBridge.js +12 -7
- package/dist/admin/editor/useInlineSession.d.ts +46 -0
- package/dist/admin/editor/useInlineSession.js +244 -0
- package/dist/admin/field-paths.d.ts +13 -0
- package/dist/admin/field-paths.js +49 -0
- package/dist/admin/forms/FieldWidget.d.ts +7 -2
- package/dist/admin/forms/FieldWidget.js +12 -40
- package/dist/admin/forms/ListField.d.ts +10 -0
- package/dist/admin/forms/ListField.js +42 -0
- package/dist/admin/forms/MediaWidget.js +10 -3
- package/dist/admin/forms/RichtextElementCard.d.ts +3 -0
- package/dist/admin/forms/RichtextElementCard.js +37 -0
- package/dist/admin/forms/RichtextImageCard.d.ts +3 -0
- package/dist/admin/forms/RichtextImageCard.js +42 -0
- package/dist/admin/forms/RichtextInsertMenu.d.ts +6 -0
- package/dist/admin/forms/RichtextInsertMenu.js +6 -0
- package/dist/admin/forms/RichtextPopovers.d.ts +7 -0
- package/dist/admin/forms/RichtextPopovers.js +25 -0
- package/dist/admin/forms/RichtextToolbar.d.ts +4 -2
- package/dist/admin/forms/RichtextToolbar.js +4 -2
- package/dist/admin/forms/RichtextWidget.d.ts +4 -1
- package/dist/admin/forms/RichtextWidget.js +23 -120
- package/dist/admin/forms/elements-context.d.ts +7 -0
- package/dist/admin/forms/elements-context.js +13 -0
- package/dist/admin/forms/reveal.d.ts +5 -0
- package/dist/admin/forms/reveal.js +47 -0
- package/dist/admin/forms/richtext-extensions.d.ts +8 -0
- package/dist/admin/forms/richtext-extensions.js +11 -0
- package/dist/admin/forms/richtext-form-context.d.ts +16 -0
- package/dist/admin/forms/richtext-form-context.js +18 -0
- package/dist/admin/forms/richtext-insert.d.ts +38 -0
- package/dist/admin/forms/richtext-insert.js +37 -0
- package/dist/admin/forms/richtext-nodes.d.ts +37 -0
- package/dist/admin/forms/richtext-nodes.js +85 -0
- package/dist/admin/forms/richtext-paste.js +5 -0
- package/dist/admin/forms/tabs.d.ts +3 -0
- package/dist/admin/forms/tabs.js +6 -0
- package/dist/admin/forms/useRichtextEditor.d.ts +51 -0
- package/dist/admin/forms/useRichtextEditor.js +281 -0
- package/dist/admin/next/bridge.js +51 -20
- package/dist/admin/ops-impl.js +13 -8
- package/dist/admin/richtext-doc.d.ts +3 -0
- package/dist/admin/richtext-doc.js +12 -0
- package/dist/admin/serialize.d.ts +7 -0
- package/dist/admin/serialize.js +16 -1
- package/dist/admin/shell/AdminApp.js +2 -1
- package/dist/admin/shell/EntriesList.js +34 -12
- package/dist/admin/shell/EntryForm.js +22 -15
- package/dist/admin/shell/IconRail.js +6 -5
- package/dist/admin/shell/ListView.d.ts +9 -2
- package/dist/admin/shell/ListView.js +7 -6
- package/dist/admin/shell/LoginView.js +2 -2
- package/dist/admin/shell/PagesList.js +53 -24
- package/dist/admin/shell/SharedForm.js +17 -11
- package/dist/admin/shell/SharedList.js +5 -3
- package/dist/admin/shell/entries-list.d.ts +4 -0
- package/dist/admin/shell/entries-list.js +6 -0
- package/dist/admin/shell/pages-tree.d.ts +24 -0
- package/dist/admin/shell/pages-tree.js +59 -1
- package/dist/admin/tree-ops.d.ts +9 -1
- package/dist/admin/tree-ops.js +27 -0
- package/dist/admin/ui/LocaleSwitcher.d.ts +10 -0
- package/dist/admin/ui/LocaleSwitcher.js +28 -8
- package/dist/admin/ui/Modal.js +14 -2
- package/dist/admin/ui/ResizeHandle.d.ts +1 -0
- package/dist/admin/ui/ResizeHandle.js +127 -0
- package/dist/admin/ui/primitives.d.ts +29 -4
- package/dist/admin/ui/primitives.js +29 -10
- package/dist/admin/ui/resize.d.ts +16 -0
- package/dist/admin/ui/resize.js +23 -0
- package/dist/admin/ui/sortable.d.ts +23 -0
- package/dist/admin/ui/sortable.js +57 -0
- package/dist/admin/ui/theme.d.ts +3 -1
- package/dist/admin/ui/theme.js +512 -165
- package/dist/admin/ui/useSortable.d.ts +35 -0
- package/dist/admin/ui/useSortable.js +220 -0
- package/dist/admin/validate.d.ts +6 -1
- package/dist/admin/validate.js +28 -9
- package/dist/config.d.ts +1 -0
- package/dist/config.js +36 -0
- package/dist/entry-store.d.ts +5 -2
- package/dist/entry-store.js +4 -3
- package/dist/fields.d.ts +4 -0
- package/dist/fields.js +2 -2
- package/dist/image/SmoodlyImage.d.ts +4 -1
- package/dist/image/SmoodlyImage.js +2 -2
- package/dist/index.d.ts +8 -1
- package/dist/index.js +5 -1
- package/dist/marks.d.ts +53 -0
- package/dist/marks.js +43 -0
- package/dist/media.d.ts +3 -2
- package/dist/media.js +48 -6
- package/dist/refs.d.ts +2 -2
- package/dist/refs.js +33 -12
- package/dist/render.js +2 -1
- package/dist/resolve.d.ts +8 -2
- package/dist/resolve.js +8 -7
- package/dist/richtext/index.d.ts +12 -0
- package/dist/richtext/index.js +9 -0
- package/dist/richtext-render.d.ts +22 -2
- package/dist/richtext-render.js +40 -13
- package/dist/richtext-walk.d.ts +44 -0
- package/dist/richtext-walk.js +46 -0
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +13 -1
- package/dist/section-wrapper.js +2 -1
- package/dist/site.d.ts +2 -0
- package/dist/site.js +7 -4
- package/dist/store.d.ts +3 -1
- package/dist/store.js +4 -4
- package/dist/supabase-entry-store.d.ts +1 -0
- package/dist/supabase-entry-store.js +2 -1
- package/dist/supabase-store.js +1 -1
- package/dist/toolset.d.ts +7 -1
- package/dist/toolset.js +13 -4
- package/package.json +10 -1
package/dist/site.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { entryFieldsIn, schemaOf } from "./entry-store.js";
|
|
2
2
|
import { buildPageTree, chainOf, entryPathRows, entrySegment, pagePath, } from "./paths.js";
|
|
3
3
|
import { resolveFields, resolveMedia, resolveMediaSets, resolveTree } from "./resolve.js";
|
|
4
|
+
import { elementSchemas } from "./richtext-walk.js";
|
|
4
5
|
import { STYLES_KEY } from "./shared.js";
|
|
5
6
|
/** The `page` prop for a loaded page. `toUrl` is the app's `href` seam
|
|
6
7
|
* bound to the render locale; the default keeps CMS paths as URLs. */
|
|
@@ -18,6 +19,7 @@ export function pageContextOf(hit, toUrl = (p) => p) {
|
|
|
18
19
|
export function createSmoodlySite(options) {
|
|
19
20
|
const locales = options.locales;
|
|
20
21
|
const homePageSlug = options.homePageSlug ?? "home";
|
|
22
|
+
const elements = elementSchemas(options.elements);
|
|
21
23
|
const pathOpts = { locales, homePageSlug };
|
|
22
24
|
const mounted = options.collections.filter((c) => c.path !== undefined);
|
|
23
25
|
/** The resolver's fetcher, bound to a locale: the merged fields of that
|
|
@@ -65,6 +67,7 @@ export function createSmoodlySite(options) {
|
|
|
65
67
|
sections: options.sections,
|
|
66
68
|
collections: options.collections,
|
|
67
69
|
shared: options.shared,
|
|
70
|
+
elements: options.elements,
|
|
68
71
|
fetch: fetcher(draft, locale),
|
|
69
72
|
assets: assetFetcher(),
|
|
70
73
|
});
|
|
@@ -107,7 +110,7 @@ export function createSmoodlySite(options) {
|
|
|
107
110
|
: (await entries.getMany(schema.name, [id], locale, { status: "published" }))[id];
|
|
108
111
|
if (!raw)
|
|
109
112
|
return null;
|
|
110
|
-
const fields = await resolveFields(raw, schema.fields, { collections: options.collections, fetch: fetcher(draft, locale), assets: assetFetcher() });
|
|
113
|
+
const fields = await resolveFields(raw, schema.fields, { collections: options.collections, elements: options.elements, fetch: fetcher(draft, locale), assets: assetFetcher() });
|
|
111
114
|
// Alternates advertise PUBLISHED locales only; the editor (draft) sees every present one.
|
|
112
115
|
const paths = Object.fromEntries(Object.entries(await entries.pathsOf(schema.name, id)).filter(([l]) => draft || record.locales[l]?.status === "published"));
|
|
113
116
|
return { kind: "entry", collection: schema.name, entry: { ...record, fields }, path, paths };
|
|
@@ -141,7 +144,7 @@ export function createSmoodlySite(options) {
|
|
|
141
144
|
// the whole list), because a list page's cards need their image URLs.
|
|
142
145
|
const fetchAssets = assetFetcher();
|
|
143
146
|
if (fetchAssets)
|
|
144
|
-
await resolveMediaSets(Object.values(published).map((values) => ({ values, descriptors: schema.fields })), fetchAssets);
|
|
147
|
+
await resolveMediaSets(Object.values(published).map((values) => ({ values, descriptors: schema.fields })), fetchAssets, elements);
|
|
145
148
|
return entryItems(schema, wanted, all, locale, published);
|
|
146
149
|
}
|
|
147
150
|
const api = {
|
|
@@ -207,13 +210,13 @@ export function createSmoodlySite(options) {
|
|
|
207
210
|
: (await entries.getMany(item.name, [record.id], locale, { status: "published" }))[record.id];
|
|
208
211
|
if (!raw)
|
|
209
212
|
return null;
|
|
210
|
-
const fields = await resolveFields(raw, item.fields, { collections: options.collections, fetch: fetcher(draft, locale), assets: assetFetcher() });
|
|
213
|
+
const fields = await resolveFields(raw, item.fields, { collections: options.collections, elements: options.elements, fetch: fetcher(draft, locale), assets: assetFetcher() });
|
|
211
214
|
if (!item.section)
|
|
212
215
|
return fields;
|
|
213
216
|
const { [STYLES_KEY]: styles, ...rest } = fields;
|
|
214
217
|
const fetch = assetFetcher();
|
|
215
218
|
if (fetch && styles && typeof styles === "object")
|
|
216
|
-
await resolveMedia(styles, sectionStyles(item.section), fetch);
|
|
219
|
+
await resolveMedia(styles, sectionStyles(item.section), fetch, elements);
|
|
217
220
|
return { ...rest, styles: styles !== null && typeof styles === "object" ? styles : {} };
|
|
218
221
|
},
|
|
219
222
|
};
|
package/dist/store.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export interface PageStore {
|
|
|
86
86
|
* written; without `entries` publishing is not integrity-checked. */
|
|
87
87
|
export type PageStoreOptions = {
|
|
88
88
|
sections?: SectionLike[];
|
|
89
|
+
/** Registered Elements a richtext document may embed (spec 2026-09-08 block nodes §2). */
|
|
90
|
+
elements?: SectionLike[];
|
|
89
91
|
entries?: EntryStore;
|
|
90
92
|
/** The shared URL index (one instance for pages AND entries). */
|
|
91
93
|
paths?: PathIndex;
|
|
@@ -123,7 +125,7 @@ export declare function localeRow(page: PageRecord, locale: string): PageLocale;
|
|
|
123
125
|
/** A page's refs rows cover EVERY live tree — each locale's draft and
|
|
124
126
|
* published trees — so an entry stays delete-guarded while any of them
|
|
125
127
|
* shows it. Callers dedupe on write (the SQL PK does it for real). */
|
|
126
|
-
export declare function pageRefEdges(trees: PageTree[], sections: SectionLike[]): RefEdge[];
|
|
128
|
+
export declare function pageRefEdges(trees: PageTree[], sections: SectionLike[], elements?: SectionLike[]): RefEdge[];
|
|
127
129
|
/** The publish-integrity gate (DESIGN.md §3), per locale: a page must not
|
|
128
130
|
* go live in a locale showing entries the published site cannot resolve
|
|
129
131
|
* THERE — every referenced entry must exist, have a row in that locale,
|
package/dist/store.js
CHANGED
|
@@ -50,10 +50,10 @@ export function localeRow(page, locale) {
|
|
|
50
50
|
/** A page's refs rows cover EVERY live tree — each locale's draft and
|
|
51
51
|
* published trees — so an entry stays delete-guarded while any of them
|
|
52
52
|
* shows it. Callers dedupe on write (the SQL PK does it for real). */
|
|
53
|
-
export function pageRefEdges(trees, sections) {
|
|
53
|
+
export function pageRefEdges(trees, sections, elements) {
|
|
54
54
|
const edges = [];
|
|
55
55
|
for (const tree of trees)
|
|
56
|
-
edges.push(...collectTreeRefs(tree, sections));
|
|
56
|
+
edges.push(...collectTreeRefs(tree, sections, elements));
|
|
57
57
|
return edges;
|
|
58
58
|
}
|
|
59
59
|
/** The publish-integrity gate (DESIGN.md §3), per locale: a page must not
|
|
@@ -159,10 +159,10 @@ export class MemoryPageStore {
|
|
|
159
159
|
return trees;
|
|
160
160
|
}
|
|
161
161
|
writeRefs(page) {
|
|
162
|
-
const { sections, refs } = this.options;
|
|
162
|
+
const { sections, elements, refs } = this.options;
|
|
163
163
|
if (!sections || !refs)
|
|
164
164
|
return;
|
|
165
|
-
refs.rewrite({ sourceKind: "page", sourceId: page.id }, pageRefEdges(this.liveTrees(page), sections));
|
|
165
|
+
refs.rewrite({ sourceKind: "page", sourceId: page.id }, pageRefEdges(this.liveTrees(page), sections, elements));
|
|
166
166
|
}
|
|
167
167
|
newVersion(pageId, locale, tree) {
|
|
168
168
|
const version = { id: uid(), pageId, locale, tree: structuredClone(tree), createdAt: Date.now() };
|
|
@@ -6,6 +6,7 @@ export declare class SupabaseEntryStore implements EntryStore {
|
|
|
6
6
|
private paths;
|
|
7
7
|
private locales;
|
|
8
8
|
private schemas;
|
|
9
|
+
private elements;
|
|
9
10
|
private spaceId?;
|
|
10
11
|
constructor(db: SupabaseClient, collections: CollectionSchema<any>[], options?: EntryStoreOptions);
|
|
11
12
|
private fail;
|
|
@@ -48,6 +48,7 @@ export class SupabaseEntryStore {
|
|
|
48
48
|
this.paths = options.paths ?? new SupabasePathIndex(db);
|
|
49
49
|
this.locales = options.locales ?? DEFAULT_ENTRY_LOCALES;
|
|
50
50
|
this.schemas = [...collections, ...(options.shared ?? [])];
|
|
51
|
+
this.elements = options.elements;
|
|
51
52
|
}
|
|
52
53
|
fail(message) {
|
|
53
54
|
throw new Error(`smoodly: ${message}`);
|
|
@@ -167,7 +168,7 @@ export class SupabaseEntryStore {
|
|
|
167
168
|
this.fail(deleted.error.message);
|
|
168
169
|
// dedupe: the refs PK is (source_kind, source_id, source_field, target_id)
|
|
169
170
|
const rows = new Map();
|
|
170
|
-
for (const edge of entryRefEdges(await this.liveFieldSets(entry), schema)) {
|
|
171
|
+
for (const edge of entryRefEdges(await this.liveFieldSets(entry), schema, this.elements)) {
|
|
171
172
|
rows.set(`${edge.field}\x00${edge.targetId}`, {
|
|
172
173
|
source_kind: "entry",
|
|
173
174
|
source_id: entry.id,
|
package/dist/supabase-store.js
CHANGED
|
@@ -189,7 +189,7 @@ export class SupabasePageStore {
|
|
|
189
189
|
async writeRefs(page) {
|
|
190
190
|
if (!this.options.sections)
|
|
191
191
|
return;
|
|
192
|
-
const edges = pageRefEdges(await this.liveTrees(page), this.options.sections);
|
|
192
|
+
const edges = pageRefEdges(await this.liveTrees(page), this.options.sections, this.options.elements);
|
|
193
193
|
const deleted = await this.db.from("refs").delete().eq("source_kind", "page").eq("source_id", page.id);
|
|
194
194
|
if (deleted.error)
|
|
195
195
|
this.fail(deleted.error.message);
|
package/dist/toolset.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const TOOLSET_MARKS: readonly ["bold", "italic", "link"];
|
|
2
|
-
export declare const TOOLSET_NODES: readonly ["h1", "h2", "h3", "h4", "h5", "h6", "bulletList", "orderedList", "blockquote"];
|
|
2
|
+
export declare const TOOLSET_NODES: readonly ["h1", "h2", "h3", "h4", "h5", "h6", "bulletList", "orderedList", "blockquote", "image"];
|
|
3
3
|
export type ToolsetMark = (typeof TOOLSET_MARKS)[number];
|
|
4
4
|
export type ToolsetNode = (typeof TOOLSET_NODES)[number];
|
|
5
5
|
export type Toolset = {
|
|
@@ -13,9 +13,11 @@ export declare const DEFAULT_TOOLSET: Toolset;
|
|
|
13
13
|
export declare function toolset(input: {
|
|
14
14
|
marks?: readonly ToolsetMark[];
|
|
15
15
|
nodes?: readonly ToolsetNode[];
|
|
16
|
+
/** Registered Elements embeddable in this toolset, by value (spec 2026-09-08 block nodes §1). */
|
|
16
17
|
elements?: {
|
|
17
18
|
schema: {
|
|
18
19
|
name: string;
|
|
20
|
+
contexts?: readonly string[];
|
|
19
21
|
};
|
|
20
22
|
}[];
|
|
21
23
|
}): Toolset;
|
|
@@ -26,5 +28,9 @@ export type Allowed = {
|
|
|
26
28
|
nodes: ReadonlySet<ToolsetNode>;
|
|
27
29
|
/** The allowed heading levels, ascending. */
|
|
28
30
|
headingLevels: number[];
|
|
31
|
+
/** Whether the image block may be inserted. */
|
|
32
|
+
image: boolean;
|
|
33
|
+
/** The element names that may be inserted, in toolset order. */
|
|
34
|
+
elements: string[];
|
|
29
35
|
};
|
|
30
36
|
export declare function allowedOf(input: unknown): Allowed;
|
package/dist/toolset.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// registration; a field without a toolset carries the default. `Allowed`
|
|
5
5
|
// is the resolved form the widget reads (spec 2026-09-08 §1).
|
|
6
6
|
export const TOOLSET_MARKS = ["bold", "italic", "link"];
|
|
7
|
-
export const TOOLSET_NODES = ["h1", "h2", "h3", "h4", "h5", "h6", "bulletList", "orderedList", "blockquote"];
|
|
7
|
+
export const TOOLSET_NODES = ["h1", "h2", "h3", "h4", "h5", "h6", "bulletList", "orderedList", "blockquote", "image"];
|
|
8
8
|
/** What a richtext field gets when it declares nothing. `h1` is left out:
|
|
9
9
|
* the section or page shape owns the page's first heading. */
|
|
10
10
|
export const DEFAULT_TOOLSET = {
|
|
@@ -29,21 +29,30 @@ export function toolset(input) {
|
|
|
29
29
|
}
|
|
30
30
|
out.nodes = [...input.nodes];
|
|
31
31
|
}
|
|
32
|
-
if (input.elements)
|
|
32
|
+
if (input.elements) {
|
|
33
|
+
for (const e of input.elements) {
|
|
34
|
+
if (!(e.schema.contexts ?? []).includes("richtext")) {
|
|
35
|
+
throw new Error(`smoodly: element "${e.schema.name}" is not registered for the richtext context — add "richtext" to its contexts.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
33
38
|
out.elements = input.elements.map((e) => e.schema.name);
|
|
39
|
+
}
|
|
34
40
|
return out;
|
|
35
41
|
}
|
|
36
42
|
const HEADING = /^h([1-6])$/;
|
|
37
43
|
export function allowedOf(input) {
|
|
38
44
|
// A missing or malformed toolset is the default; a declared one is exact,
|
|
39
45
|
// so a group it leaves out allows nothing (a marks-only toolset has no headings).
|
|
40
|
-
const t = input && typeof input === "object"
|
|
46
|
+
const t = input && typeof input === "object"
|
|
47
|
+
? input
|
|
48
|
+
: DEFAULT_TOOLSET;
|
|
41
49
|
const marks = Array.isArray(t.marks) ? t.marks.filter((m) => typeof m === "string" && isMark(m)) : [];
|
|
42
50
|
const nodes = Array.isArray(t.nodes) ? t.nodes.filter((n) => typeof n === "string" && isNode(n)) : [];
|
|
51
|
+
const elements = Array.isArray(t.elements) ? t.elements.filter((e) => typeof e === "string") : [];
|
|
43
52
|
const headingLevels = nodes
|
|
44
53
|
.map((n) => HEADING.exec(n)?.[1])
|
|
45
54
|
.filter((l) => l !== undefined)
|
|
46
55
|
.map(Number)
|
|
47
56
|
.sort((a, b) => a - b);
|
|
48
|
-
return { marks: new Set(marks), nodes: new Set(nodes), headingLevels };
|
|
57
|
+
return { marks: new Set(marks), nodes: new Set(nodes), headingLevels, image: nodes.includes("image"), elements };
|
|
49
58
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smoodly",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Open-source, code-first CMS for Next.js on Supabase: define a component once, it becomes a typed, editable building block.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -24,6 +24,14 @@
|
|
|
24
24
|
"types": "./dist/image/index.d.ts",
|
|
25
25
|
"default": "./dist/image/index.js"
|
|
26
26
|
},
|
|
27
|
+
"./image/config": {
|
|
28
|
+
"types": "./dist/image/next-config.d.ts",
|
|
29
|
+
"default": "./dist/image/next-config.js"
|
|
30
|
+
},
|
|
31
|
+
"./richtext": {
|
|
32
|
+
"types": "./dist/richtext/index.d.ts",
|
|
33
|
+
"default": "./dist/richtext/index.js"
|
|
34
|
+
},
|
|
27
35
|
"./admin": {
|
|
28
36
|
"types": "./dist/admin/index.d.ts",
|
|
29
37
|
"default": "./dist/admin/index.js"
|
|
@@ -79,6 +87,7 @@
|
|
|
79
87
|
"@tiptap/pm": "3.31.3",
|
|
80
88
|
"@tiptap/react": "3.31.3",
|
|
81
89
|
"@tiptap/starter-kit": "3.31.3",
|
|
90
|
+
"@tiptap/suggestion": "3.31.3",
|
|
82
91
|
"lucide-react": "^1.41.0"
|
|
83
92
|
}
|
|
84
93
|
}
|