@blinkk/root-cms 2.4.2 → 2.4.3

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/app.js CHANGED
@@ -83,7 +83,7 @@ function convertOneOfTypes(collection) {
83
83
  // package.json
84
84
  var package_default = {
85
85
  name: "@blinkk/root-cms",
86
- version: "2.4.2",
86
+ version: "2.4.3",
87
87
  author: "s@blinkk.com",
88
88
  license: "MIT",
89
89
  engines: {
@@ -143,7 +143,8 @@ var package_default = {
143
143
  "dev:core": "pnpm build:core --watch",
144
144
  "dev:signin": "pnpm build:signin --watch",
145
145
  "dev:ui": "pnpm build:ui --watch",
146
- test: "pnpm build && firebase emulators:exec 'vitest run'",
146
+ test: "pnpm build && firebase emulators:exec 'vitest run --exclude=**/*.visual.test.tsx'",
147
+ "test:visual": "vitest run --config=vitest.config.visual.ts",
147
148
  "test:watch": "pnpm build && firebase emulators:exec 'vitest'"
148
149
  },
149
150
  dependencies: {
@@ -190,6 +191,7 @@ var package_default = {
190
191
  "@lexical/react": "0.33.1",
191
192
  "@lexical/rich-text": "0.33.1",
192
193
  "@lexical/selection": "0.33.1",
194
+ "@lexical/table": "0.33.1",
193
195
  "@lexical/utils": "0.33.1",
194
196
  "@mantine/core": "4.2.12",
195
197
  "@mantine/hooks": "4.2.12",
@@ -198,6 +200,7 @@ var package_default = {
198
200
  "@mantine/spotlight": "4.2.12",
199
201
  "@preact/compat": "18.3.1",
200
202
  "@tabler/icons-preact": "3.35.0",
203
+ "@testing-library/preact": "3.2.4",
201
204
  "@types/body-parser": "1.19.3",
202
205
  "@types/fnv-plus": "1.3.2",
203
206
  "@types/gapi": "0.0.47",
@@ -206,6 +209,8 @@ var package_default = {
206
209
  "@types/google.accounts": "0.0.14",
207
210
  "@types/jsonwebtoken": "9.0.1",
208
211
  "@types/node": "24.3.1",
212
+ "@vitest/browser": "4.0.10",
213
+ "@vitest/browser-playwright": "4.0.10",
209
214
  concurrently: "7.6.0",
210
215
  esbuild: "0.25.9",
211
216
  firebase: "12.2.1",
@@ -219,6 +224,7 @@ var package_default = {
219
224
  "mdast-util-from-markdown": "2.0.1",
220
225
  "mdast-util-gfm": "3.0.0",
221
226
  "micromark-extension-gfm": "3.0.0",
227
+ playwright: "1.56.1",
222
228
  preact: "10.27.1",
223
229
  "preact-render-to-string": "6.6.1",
224
230
  "preact-router": "4.1.2",
@@ -228,11 +234,11 @@ var package_default = {
228
234
  tsup: "8.5.0",
229
235
  typescript: "5.9.2",
230
236
  vite: "7.1.4",
231
- vitest: "3.2.4",
237
+ vitest: "4.0.10",
232
238
  yjs: "13.6.27"
233
239
  },
234
240
  peerDependencies: {
235
- "@blinkk/root": "2.4.2",
241
+ "@blinkk/root": "2.4.3",
236
242
  "firebase-admin": ">=11",
237
243
  "firebase-functions": ">=4",
238
244
  preact: ">=10",
@@ -492,6 +492,14 @@ interface Action<T = any> {
492
492
  * Metadata for the action.
493
493
  */
494
494
  metadata?: T;
495
+ /**
496
+ * Optional list of quick links to display in the UI.
497
+ */
498
+ links?: {
499
+ label: string;
500
+ url: string;
501
+ target?: string;
502
+ }[];
495
503
  }
496
504
  interface ListActionsOptions {
497
505
  /**
@@ -706,6 +714,11 @@ declare class RootCMSClient {
706
714
  logAction(action: string, options?: {
707
715
  by?: string;
708
716
  metadata?: any;
717
+ links?: {
718
+ label: string;
719
+ url: string;
720
+ target?: string;
721
+ }[];
709
722
  }): Promise<void>;
710
723
  /**
711
724
  * Creates a batch request that is capable of fetching one or more docs,
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import '@blinkk/root';
2
2
  import 'firebase-admin/app';
3
3
  import 'firebase-admin/firestore';
4
- export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, D as DocMode, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, k as ListActionsOptions, g as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, j as Release, R as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, i as Translation, y as TranslationsDoc, T as TranslationsMap, U as UserRole, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-DK623LL2.js';
4
+ export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, D as DocMode, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, k as ListActionsOptions, g as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, j as Release, R as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, i as Translation, y as TranslationsDoc, T as TranslationsMap, U as UserRole, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-DYO2WWlf.js';
package/dist/client.js CHANGED
@@ -1136,6 +1136,9 @@ var RootCMSClient = class {
1136
1136
  by: options?.by || "system",
1137
1137
  metadata: options?.metadata || {}
1138
1138
  };
1139
+ if (options?.links) {
1140
+ data.links = options.links;
1141
+ }
1139
1142
  const colRef = this.db.collection(`Projects/${this.projectId}/ActionLogs`);
1140
1143
  await colRef.add(data);
1141
1144
  const metaStr = options?.metadata ? stringifyObj(options.metadata) : "";
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-DK623LL2.js';
2
- export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, k as ListActionsOptions, g as ListDocsOptions, E as Locale, N as MultiLocaleTranslationsMap, j as Release, f as SaveDraftOptions, S as SetDocOptions, O as SingleLocaleTranslationsMap, F as SourceString, I as TranslatedString, i as Translation, y as TranslationsDoc, J as TranslationsDocMode, M as TranslationsLocaleDocEntry, K as TranslationsLocaleDocHashMap, P as TranslationsManager, U as UserRole, Q as buildTranslationsDbPath, V as buildTranslationsLocaleDocDbPath, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-DK623LL2.js';
1
+ import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-DYO2WWlf.js';
2
+ export { A as Action, p as ArrayObject, z as BatchRequest, B as BatchRequestOptions, w as BatchRequestQuery, x as BatchRequestQueryOptions, C as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, h as GetCountOptions, G as GetDocOptions, H as HttpMethod, k as ListActionsOptions, g as ListDocsOptions, E as Locale, N as MultiLocaleTranslationsMap, j as Release, f as SaveDraftOptions, S as SetDocOptions, O as SingleLocaleTranslationsMap, F as SourceString, I as TranslatedString, i as Translation, y as TranslationsDoc, J as TranslationsDocMode, M as TranslationsLocaleDocEntry, K as TranslationsLocaleDocHashMap, P as TranslationsManager, U as UserRole, Q as buildTranslationsDbPath, V as buildTranslationsLocaleDocDbPath, m as getCmsPlugin, l as isRichTextData, q as marshalArray, n as marshalData, o as normalizeData, v as parseDocId, t as toArrayObject, s as translationsForLocale, r as unmarshalArray, u as unmarshalData } from './client-DYO2WWlf.js';
3
3
  import { Request, RootConfig, Response, RouteParams, GetStaticProps, GetStaticPaths } from '@blinkk/root';
4
4
  import { Query } from 'firebase-admin/firestore';
5
5
  export { s as schema } from './schema-sKTRRRSq.js';
package/dist/core.js CHANGED
@@ -1142,6 +1142,9 @@ var RootCMSClient = class {
1142
1142
  by: options?.by || "system",
1143
1143
  metadata: options?.metadata || {}
1144
1144
  };
1145
+ if (options?.links) {
1146
+ data.links = options.links;
1147
+ }
1145
1148
  const colRef = this.db.collection(`Projects/${this.projectId}/ActionLogs`);
1146
1149
  await colRef.add(data);
1147
1150
  const metaStr = options?.metadata ? stringifyObj(options.metadata) : "";
package/dist/functions.js CHANGED
@@ -1141,6 +1141,9 @@ var RootCMSClient = class {
1141
1141
  by: options?.by || "system",
1142
1142
  metadata: options?.metadata || {}
1143
1143
  };
1144
+ if (options?.links) {
1145
+ data.links = options.links;
1146
+ }
1144
1147
  const colRef = this.db.collection(`Projects/${this.projectId}/ActionLogs`);
1145
1148
  await colRef.add(data);
1146
1149
  const metaStr = options?.metadata ? stringifyObj(options.metadata) : "";
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import '@blinkk/root';
2
2
  import 'firebase-admin/app';
3
3
  import 'firebase-admin/firestore';
4
- export { Y as CMSAIConfig, W as CMSBuiltInSidebarTool, $ as CMSPlugin, _ as CMSPluginOptions, Z as CMSSidebarTool, X as CMSUser, a0 as cmsPlugin } from './client-DK623LL2.js';
4
+ export { Y as CMSAIConfig, W as CMSBuiltInSidebarTool, $ as CMSPlugin, _ as CMSPluginOptions, Z as CMSSidebarTool, X as CMSUser, a0 as cmsPlugin } from './client-DYO2WWlf.js';
package/dist/plugin.js CHANGED
@@ -1760,6 +1760,9 @@ var RootCMSClient = class {
1760
1760
  by: options?.by || "system",
1761
1761
  metadata: options?.metadata || {}
1762
1762
  };
1763
+ if (options?.links) {
1764
+ data.links = options.links;
1765
+ }
1763
1766
  const colRef = this.db.collection(`Projects/${this.projectId}/ActionLogs`);
1764
1767
  await colRef.add(data);
1765
1768
  const metaStr = options?.metadata ? stringifyObj(options.metadata) : "";
@@ -2448,7 +2451,8 @@ function api(server, options) {
2448
2451
  try {
2449
2452
  await cmsClient.logAction(action, {
2450
2453
  by: req.user?.email,
2451
- metadata
2454
+ metadata,
2455
+ links: reqBody.links
2452
2456
  });
2453
2457
  res.status(200).json({ success: true });
2454
2458
  } catch (err) {
@@ -2556,7 +2560,7 @@ function api(server, options) {
2556
2560
  // package.json
2557
2561
  var package_default = {
2558
2562
  name: "@blinkk/root-cms",
2559
- version: "2.4.2",
2563
+ version: "2.4.3",
2560
2564
  author: "s@blinkk.com",
2561
2565
  license: "MIT",
2562
2566
  engines: {
@@ -2616,7 +2620,8 @@ var package_default = {
2616
2620
  "dev:core": "pnpm build:core --watch",
2617
2621
  "dev:signin": "pnpm build:signin --watch",
2618
2622
  "dev:ui": "pnpm build:ui --watch",
2619
- test: "pnpm build && firebase emulators:exec 'vitest run'",
2623
+ test: "pnpm build && firebase emulators:exec 'vitest run --exclude=**/*.visual.test.tsx'",
2624
+ "test:visual": "vitest run --config=vitest.config.visual.ts",
2620
2625
  "test:watch": "pnpm build && firebase emulators:exec 'vitest'"
2621
2626
  },
2622
2627
  dependencies: {
@@ -2663,6 +2668,7 @@ var package_default = {
2663
2668
  "@lexical/react": "0.33.1",
2664
2669
  "@lexical/rich-text": "0.33.1",
2665
2670
  "@lexical/selection": "0.33.1",
2671
+ "@lexical/table": "0.33.1",
2666
2672
  "@lexical/utils": "0.33.1",
2667
2673
  "@mantine/core": "4.2.12",
2668
2674
  "@mantine/hooks": "4.2.12",
@@ -2671,6 +2677,7 @@ var package_default = {
2671
2677
  "@mantine/spotlight": "4.2.12",
2672
2678
  "@preact/compat": "18.3.1",
2673
2679
  "@tabler/icons-preact": "3.35.0",
2680
+ "@testing-library/preact": "3.2.4",
2674
2681
  "@types/body-parser": "1.19.3",
2675
2682
  "@types/fnv-plus": "1.3.2",
2676
2683
  "@types/gapi": "0.0.47",
@@ -2679,6 +2686,8 @@ var package_default = {
2679
2686
  "@types/google.accounts": "0.0.14",
2680
2687
  "@types/jsonwebtoken": "9.0.1",
2681
2688
  "@types/node": "24.3.1",
2689
+ "@vitest/browser": "4.0.10",
2690
+ "@vitest/browser-playwright": "4.0.10",
2682
2691
  concurrently: "7.6.0",
2683
2692
  esbuild: "0.25.9",
2684
2693
  firebase: "12.2.1",
@@ -2692,6 +2701,7 @@ var package_default = {
2692
2701
  "mdast-util-from-markdown": "2.0.1",
2693
2702
  "mdast-util-gfm": "3.0.0",
2694
2703
  "micromark-extension-gfm": "3.0.0",
2704
+ playwright: "1.56.1",
2695
2705
  preact: "10.27.1",
2696
2706
  "preact-render-to-string": "6.6.1",
2697
2707
  "preact-router": "4.1.2",
@@ -2701,11 +2711,11 @@ var package_default = {
2701
2711
  tsup: "8.5.0",
2702
2712
  typescript: "5.9.2",
2703
2713
  vite: "7.1.4",
2704
- vitest: "3.2.4",
2714
+ vitest: "4.0.10",
2705
2715
  yjs: "13.6.27"
2706
2716
  },
2707
2717
  peerDependencies: {
2708
- "@blinkk/root": "2.4.2",
2718
+ "@blinkk/root": "2.4.3",
2709
2719
  "firebase-admin": ">=11",
2710
2720
  "firebase-functions": ">=4",
2711
2721
  preact: ">=10",
@@ -23,10 +23,13 @@ interface RichTextProps {
23
23
  declare function RichText(props: RichTextProps): preact.JSX.Element;
24
24
  declare namespace RichText {
25
25
  var ParagraphBlock: (props: RichTextParagraphBlockProps) => preact.JSX.Element | null;
26
+ var DelimiterBlock: () => preact.JSX.Element;
26
27
  var HeadingBlock: (props: RichTextHeadingBlockProps) => preact.JSX.Element | null;
28
+ var QuoteBlock: (props: RichTextQuoteBlockProps) => preact.JSX.Element | null;
27
29
  var ListBlock: (props: RichTextListBlockProps) => preact.JSX.Element | null;
28
30
  var ImageBlock: (props: RichTextImageBlockProps) => preact.JSX.Element | null;
29
31
  var HtmlBlock: (props: RichTextHtmlBlockProps) => preact.JSX.Element | null;
32
+ var TableBlock: (props: RichTextTableBlockProps) => preact.JSX.Element | null;
30
33
  }
31
34
  interface RichTextParagraphBlockProps {
32
35
  type: 'paragraph';
@@ -34,6 +37,10 @@ interface RichTextParagraphBlockProps {
34
37
  text?: string;
35
38
  };
36
39
  }
40
+ interface RichTextDelimiterBlockProps {
41
+ type: 'delimiter';
42
+ data?: {};
43
+ }
37
44
  interface RichTextHeadingBlockProps {
38
45
  type: 'heading';
39
46
  data?: {
@@ -41,6 +48,12 @@ interface RichTextHeadingBlockProps {
41
48
  text?: string;
42
49
  };
43
50
  }
51
+ interface RichTextQuoteBlockProps {
52
+ type: 'quote';
53
+ data?: {
54
+ text?: string;
55
+ };
56
+ }
44
57
  interface ListItem {
45
58
  content?: string;
46
59
  items?: ListItem[];
@@ -69,5 +82,16 @@ interface RichTextHtmlBlockProps {
69
82
  html?: string;
70
83
  };
71
84
  }
85
+ interface RichTextTableBlockProps {
86
+ type: 'table';
87
+ data?: {
88
+ rows?: Array<{
89
+ cells: Array<{
90
+ blocks: RichTextBlock[];
91
+ type: 'header' | 'data';
92
+ }>;
93
+ }>;
94
+ };
95
+ }
72
96
 
73
- export { RichText, type RichTextBlock, type RichTextBlockComponent, RichTextContext, type RichTextContextProps, type RichTextData, type RichTextHeadingBlockProps, type RichTextHtmlBlockProps, type RichTextImageBlockProps, type RichTextListBlockProps, type RichTextParagraphBlockProps, type RichTextProps, useRichTextContext };
97
+ export { RichText, type RichTextBlock, type RichTextBlockComponent, RichTextContext, type RichTextContextProps, type RichTextData, type RichTextDelimiterBlockProps, type RichTextHeadingBlockProps, type RichTextHtmlBlockProps, type RichTextImageBlockProps, type RichTextListBlockProps, type RichTextParagraphBlockProps, type RichTextProps, type RichTextQuoteBlockProps, type RichTextTableBlockProps, useRichTextContext };
package/dist/richtext.js CHANGED
@@ -10,11 +10,14 @@ function useRichTextContext() {
10
10
  function RichText(props) {
11
11
  const richTextContext = useRichTextContext();
12
12
  const components = {
13
+ delimiter: RichText.DelimiterBlock,
13
14
  heading: RichText.HeadingBlock,
14
15
  html: RichText.HtmlBlock,
15
16
  image: RichText.ImageBlock,
16
17
  orderedList: RichText.ListBlock,
17
18
  paragraph: RichText.ParagraphBlock,
19
+ quote: RichText.QuoteBlock,
20
+ table: RichText.TableBlock,
18
21
  unorderedList: RichText.ListBlock,
19
22
  ...richTextContext.components,
20
23
  ...props.components
@@ -42,6 +45,9 @@ RichText.ParagraphBlock = (props) => {
42
45
  const t = useTranslations();
43
46
  return /* @__PURE__ */ jsx("p", { dangerouslySetInnerHTML: { __html: t(props.data.text) } });
44
47
  };
48
+ RichText.DelimiterBlock = () => {
49
+ return /* @__PURE__ */ jsx("hr", {});
50
+ };
45
51
  RichText.HeadingBlock = (props) => {
46
52
  if (!props.data?.text) {
47
53
  return null;
@@ -51,6 +57,13 @@ RichText.HeadingBlock = (props) => {
51
57
  const Component = `h${level}`;
52
58
  return /* @__PURE__ */ jsx(Component, { dangerouslySetInnerHTML: { __html: t(props.data.text) } });
53
59
  };
60
+ RichText.QuoteBlock = (props) => {
61
+ if (!props.data?.text) {
62
+ return null;
63
+ }
64
+ const t = useTranslations();
65
+ return /* @__PURE__ */ jsx("blockquote", { dangerouslySetInnerHTML: { __html: t(props.data.text) } });
66
+ };
54
67
  RichText.ListBlock = (props) => {
55
68
  if (!props.data?.items?.length) {
56
69
  return null;
@@ -100,6 +113,24 @@ RichText.HtmlBlock = (props) => {
100
113
  }
101
114
  return /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: html } });
102
115
  };
116
+ RichText.TableBlock = (props) => {
117
+ const rows = props.data?.rows || [];
118
+ const richTextContext = useRichTextContext();
119
+ if (rows.length === 0) {
120
+ return null;
121
+ }
122
+ return /* @__PURE__ */ jsx("table", { children: /* @__PURE__ */ jsx("tbody", { children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { children: row.cells.map((cell, cellIndex) => {
123
+ const isHeader = cell.type === "header";
124
+ const Cell = isHeader ? "th" : "td";
125
+ return /* @__PURE__ */ jsx(Cell, { children: /* @__PURE__ */ jsx(
126
+ RichText,
127
+ {
128
+ data: { blocks: cell.blocks, time: 0, version: "" },
129
+ components: richTextContext.components
130
+ }
131
+ ) }, cellIndex);
132
+ }) }, rowIndex)) }) });
133
+ };
103
134
  function toNumber(input) {
104
135
  if (input === void 0) {
105
136
  return 0;