@riverbankcms/sdk 0.70.3 → 0.71.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 (82) hide show
  1. package/dist/_dts/api/src/contentTypes.d.ts +2 -1
  2. package/dist/_dts/block-form/src/client/index.d.ts +1 -1
  3. package/dist/_dts/block-form/src/fields/types.d.ts +14 -2
  4. package/dist/_dts/block-form/src/registry/schemas.d.ts +2 -0
  5. package/dist/_dts/block-form/src/widgets/MediaField/mediaFieldDefaults.d.ts +2 -2
  6. package/dist/_dts/block-form/src/widgets/MediaField/mediaFieldSchema.d.ts +2 -2
  7. package/dist/_dts/blocks/src/lib/media.d.ts +1 -1
  8. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +1829 -149
  9. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +1829 -149
  10. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +1829 -149
  11. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +1829 -149
  12. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +1829 -149
  13. package/dist/_dts/blocks/src/system/blocks/cta-full.d.ts +1 -30727
  14. package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +11 -30827
  15. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +1829 -149
  16. package/dist/_dts/blocks/src/system/blocks/file-download.d.ts +3 -3
  17. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +1829 -149
  18. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +106 -1
  19. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +1829 -149
  20. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +1829 -149
  21. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +1829 -149
  22. package/dist/_dts/blocks/src/system/defineBlock.d.ts +3 -3
  23. package/dist/_dts/blocks/src/system/fragments/library/card.d.ts +2 -30793
  24. package/dist/_dts/blocks/src/system/fragments/library/ctaRow.d.ts +2 -30727
  25. package/dist/_dts/blocks/src/system/fragments/library/feedbackCallout.d.ts +2 -30779
  26. package/dist/_dts/blocks/src/system/fragments/library/heroCtaRow.d.ts +33 -30743
  27. package/dist/_dts/blocks/src/system/fragments/library/sectionState.d.ts +2 -30770
  28. package/dist/_dts/blocks/src/system/fragments/types.d.ts +8 -7
  29. package/dist/_dts/blocks/src/system/manifest/derivedContent.d.ts +7 -5
  30. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +192 -3
  32. package/dist/_dts/blocks/src/system/runtime/nodes/file-download.d.ts +1 -1
  33. package/dist/_dts/content-model/src/content-types/schema.d.ts +7 -0
  34. package/dist/_dts/content-model/src/contentManifest.d.ts +4 -1
  35. package/dist/_dts/content-model/src/templates/bindingTypeCompatibility.d.ts +1 -1
  36. package/dist/_dts/core/src/index.d.ts +1 -1
  37. package/dist/_dts/core/src/planner.d.ts +4 -0
  38. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +53 -20
  39. package/dist/_dts/editor-blocks/src/index.d.ts +1 -1
  40. package/dist/_dts/editor-blocks/src/media/MediaField.d.ts +6 -5
  41. package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +0 -1
  42. package/dist/_dts/media-editor/src/context.d.ts +4 -1
  43. package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +8 -1
  44. package/dist/_dts/media-react/src/index.d.ts +1 -5
  45. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +1 -0
  46. package/dist/_dts/preview-next/src/client/widgets/PreviewMediaField.d.ts +2 -1
  47. package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +1 -0
  48. package/dist/_dts/sdk/src/config/field-definitions.d.ts +6 -2
  49. package/dist/_dts/sdk/src/config/typed-entries.d.ts +4 -2
  50. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +2 -1
  51. package/dist/_dts/sdk/src/manifest/prompt/examples/cta.d.ts +5 -5
  52. package/dist/_dts/sdk/src/manifest/prompt/examples/features-grid.d.ts +2 -2
  53. package/dist/_dts/sdk/src/manifest/prompt/examples/hero.d.ts +2 -2
  54. package/dist/_dts/sdk/src/manifest/prompt/examples/pricing.d.ts +10 -10
  55. package/dist/_dts/sdk/src/manifest/prompt/examples/testimonials.d.ts +4 -4
  56. package/dist/_dts/sdk/src/manifest/validation/output-schema.d.ts +11 -1
  57. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +19 -1
  58. package/dist/_dts/sdk/src/public-api/contracts.d.ts +2 -1
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/cli/index.mjs +395 -190
  61. package/dist/cli/init-docs/content/workflow-preview-mode.md +167 -0
  62. package/dist/client/client.mjs +243 -203
  63. package/dist/client/hooks.mjs +172 -121
  64. package/dist/client/rendering/client.mjs +148 -112
  65. package/dist/client/rendering/islands.mjs +80 -31
  66. package/dist/client/rendering.mjs +242 -202
  67. package/dist/preview-next/client/index.mjs +60 -10
  68. package/dist/preview-next/client/runtime.mjs +408 -1141
  69. package/dist/server/components.mjs +219 -171
  70. package/dist/server/config-template-validation.mjs +31 -1
  71. package/dist/server/config-validation.mjs +172 -121
  72. package/dist/server/config.mjs +172 -121
  73. package/dist/server/data.mjs +172 -121
  74. package/dist/server/index.mjs +1 -1
  75. package/dist/server/next.mjs +220 -172
  76. package/dist/server/page-converter.mjs +379 -185
  77. package/dist/server/prebuild.mjs +1 -1
  78. package/dist/server/rendering/server.mjs +219 -171
  79. package/dist/server/rendering.mjs +219 -171
  80. package/dist/server/routing.mjs +175 -124
  81. package/dist/server/server.mjs +173 -122
  82. package/package.json +6 -1
@@ -6698,6 +6698,28 @@ function resolveRepeaterGridColumnFieldId(options) {
6698
6698
 
6699
6699
  // ../blocks/src/system/manifest/schema.ts
6700
6700
  var visibilityLevels = ["admin", "designer", "author"];
6701
+ var MEDIA_KINDS = [
6702
+ "image",
6703
+ "video",
6704
+ "audio",
6705
+ "document",
6706
+ "spreadsheet",
6707
+ "archive"
6708
+ ];
6709
+ var DISPLAY_MEDIA_KINDS = [
6710
+ "image",
6711
+ "video",
6712
+ "audio"
6713
+ ];
6714
+ var PUBLIC_FILE_FIELD_KINDS = [
6715
+ "document",
6716
+ "spreadsheet",
6717
+ "archive",
6718
+ "audio"
6719
+ ];
6720
+ function isDisplayMediaKind(kind) {
6721
+ return DISPLAY_MEDIA_KINDS.includes(kind);
6722
+ }
6701
6723
  var siteOptionSources = [
6702
6724
  "eventCategories",
6703
6725
  "venues",
@@ -6861,11 +6883,19 @@ var richTextFieldSchema = baseFieldSchema.extend({
6861
6883
  });
6862
6884
  var mediaFieldSchema = baseFieldSchema.extend({
6863
6885
  type: z4.literal("media"),
6864
- mediaKinds: z4.array(
6865
- z4.enum(["image", "video", "audio", "document", "spreadsheet", "archive"])
6866
- ).default(["image"]),
6886
+ // Keep full MEDIA_KINDS parse compatibility for pre-file-field manifests.
6887
+ // New authoring surfaces should use `file.fileKinds` for document/archive
6888
+ // style assets, but old saved schemas must not fail to open.
6889
+ mediaKinds: z4.array(z4.enum(MEDIA_KINDS)).default(["image"]).transform((kinds) => {
6890
+ const displayKinds = kinds.filter(isDisplayMediaKind);
6891
+ return displayKinds.length > 0 ? displayKinds : ["image"];
6892
+ }),
6867
6893
  aspectRatio: z4.string().optional()
6868
6894
  });
6895
+ var fileFieldSchema = baseFieldSchema.extend({
6896
+ type: z4.literal("file"),
6897
+ fileKinds: z4.array(z4.enum(PUBLIC_FILE_FIELD_KINDS)).default([...PUBLIC_FILE_FIELD_KINDS])
6898
+ });
6869
6899
  var booleanFieldSchema = baseFieldSchema.extend({
6870
6900
  type: z4.literal("boolean")
6871
6901
  });
@@ -7171,6 +7201,7 @@ function getFieldSchemaInternal() {
7171
7201
  textFieldSchema,
7172
7202
  richTextFieldSchema,
7173
7203
  mediaFieldSchema,
7204
+ fileFieldSchema,
7174
7205
  booleanFieldSchema,
7175
7206
  numberFieldSchema,
7176
7207
  dateFieldSchema,
@@ -14296,13 +14327,18 @@ var fragmentDataSchema = z27.object({
14296
14327
  loader: dataLoaderSchema.optional()
14297
14328
  });
14298
14329
  var fragmentConfigSchema = z27.object({
14299
- id: z27.string().min(1, "Fragment id is required").regex(FRAGMENT_ID_PATTERN, "Fragment id must be alphanumeric with optional . _ - separators"),
14330
+ id: z27.string().min(1, "Fragment id is required").regex(
14331
+ FRAGMENT_ID_PATTERN,
14332
+ "Fragment id must be alphanumeric with optional . _ - separators"
14333
+ ),
14300
14334
  title: z27.string().optional(),
14301
14335
  description: z27.string().optional(),
14302
14336
  category: z27.enum(["content", "media", "interactive", "layout"]).optional(),
14303
14337
  icon: z27.string().optional(),
14304
14338
  fields: fieldSchema.array().default([]),
14305
- layout: z27.union([NodeSchema, NodeSchema.array()]).transform((value) => Array.isArray(value) ? value : [value]),
14339
+ layout: z27.union([NodeSchema, NodeSchema.array()]).transform(
14340
+ (value) => Array.isArray(value) ? value : [value]
14341
+ ),
14306
14342
  data: fragmentDataSchema.optional()
14307
14343
  });
14308
14344
  var FragmentConfigError = class extends Error {
@@ -14324,13 +14360,19 @@ function defineFragment(config) {
14324
14360
  function scopeFragmentFields(fragment, scope) {
14325
14361
  const normalizedScope = scope.trim();
14326
14362
  if (!normalizedScope) {
14327
- return fragment.fields.map((field) => cloneFieldDefinition2(field));
14363
+ return fragment.fields.map(
14364
+ (field) => cloneFieldDefinition2(field)
14365
+ );
14328
14366
  }
14329
- return fragment.fields.map((field) => prefixFieldId(field, normalizedScope));
14367
+ return fragment.fields.map(
14368
+ (field) => prefixFieldId(field, normalizedScope)
14369
+ );
14330
14370
  }
14331
14371
  function scopeFragmentLayout(fragment, scope) {
14332
14372
  const normalizedScope = scope.trim();
14333
- return fragment.layout.map((node) => cloneAndScopeNode(node, normalizedScope));
14373
+ return fragment.layout.map(
14374
+ (node) => cloneAndScopeNode(node, normalizedScope)
14375
+ );
14334
14376
  }
14335
14377
  function validateFieldDefinitions(fields3, fragmentId) {
14336
14378
  const seen = /* @__PURE__ */ new Set();
@@ -14412,7 +14454,9 @@ function cloneAndScopeNode(node, scope) {
14412
14454
  ...node
14413
14455
  };
14414
14456
  if (node.children) {
14415
- cloned.children = node.children.map((child) => cloneAndScopeNode(child, scope));
14457
+ cloned.children = node.children.map(
14458
+ (child) => cloneAndScopeNode(child, scope)
14459
+ );
14416
14460
  }
14417
14461
  if (node.props) {
14418
14462
  cloned.props = scopePropBindings(node.props, scope);
@@ -14438,7 +14482,9 @@ function scopeBinding(binding, scope) {
14438
14482
  const cloned = {
14439
14483
  ...binding,
14440
14484
  transforms: binding.transforms?.map(
14441
- (step) => ({ ...step })
14485
+ (step) => ({
14486
+ ...step
14487
+ })
14442
14488
  ) ?? []
14443
14489
  };
14444
14490
  cloned.from = scopeContentPath(binding.from, scope);
@@ -14482,7 +14528,9 @@ function scopePropValue(value, scope) {
14482
14528
  };
14483
14529
  }
14484
14530
  const result = {};
14485
- for (const [key, entry] of Object.entries(value)) {
14531
+ for (const [key, entry] of Object.entries(
14532
+ value
14533
+ )) {
14486
14534
  result[key] = scopePropValue(entry, scope);
14487
14535
  }
14488
14536
  return result;
@@ -14931,28 +14979,29 @@ var ctaRowFragment = defineFragment({
14931
14979
  });
14932
14980
 
14933
14981
  // ../blocks/src/system/fragments/library/heroCtaRow.ts
14982
+ var heroCtaFields = [
14983
+ createCtasRepeater({
14984
+ label: "Calls to action",
14985
+ itemLabel: "CTA",
14986
+ maxItems: 3,
14987
+ button: {
14988
+ variants: [
14989
+ { value: "default", label: "Default" },
14990
+ { value: "primary", label: "Primary" },
14991
+ { value: "secondary", label: "Secondary" },
14992
+ { value: "outline", label: "Outline" }
14993
+ ],
14994
+ defaultVariant: "default",
14995
+ includeSize: true,
14996
+ defaultSize: "lg"
14997
+ }
14998
+ })
14999
+ ];
14934
15000
  var heroCtaRowFragment = defineFragment({
14935
15001
  id: "heroCtaRow",
14936
15002
  title: "Hero CTAs",
14937
15003
  description: "Repeatable hero calls to action rendered inline.",
14938
- fields: [
14939
- createCtasRepeater({
14940
- label: "Calls to action",
14941
- itemLabel: "CTA",
14942
- maxItems: 3,
14943
- button: {
14944
- variants: [
14945
- { value: "default", label: "Default" },
14946
- { value: "primary", label: "Primary" },
14947
- { value: "secondary", label: "Secondary" },
14948
- { value: "outline", label: "Outline" }
14949
- ],
14950
- defaultVariant: "default",
14951
- includeSize: true,
14952
- defaultSize: "lg"
14953
- }
14954
- })
14955
- ],
15004
+ fields: heroCtaFields,
14956
15005
  layout: [
14957
15006
  ctaRow({
14958
15007
  collectionPath: "content.ctas",
@@ -20809,8 +20858,7 @@ var PUBLIC_DOWNLOAD_MEDIA_TYPES = [
20809
20858
  "document",
20810
20859
  "spreadsheet",
20811
20860
  "archive",
20812
- "audio",
20813
- "video"
20861
+ "audio"
20814
20862
  ];
20815
20863
  var hotspotSchema2 = z38.object({
20816
20864
  x: z38.number().min(0).max(1),
@@ -22385,104 +22433,107 @@ var courseDetailsBlockDefinition = {
22385
22433
  };
22386
22434
 
22387
22435
  // ../blocks/src/system/blocks/events/event-spotlight.ts
22388
- var eventSpotlightManifest = createBlockManifest({
22436
+ var eventSpotlightFields = [
22437
+ ...sectionHeaderFields("Upcoming Events"),
22438
+ {
22439
+ id: "maxEvents",
22440
+ type: "select",
22441
+ label: "Events to display",
22442
+ description: "Number of events to show",
22443
+ required: false,
22444
+ multiple: false,
22445
+ defaultValue: "3",
22446
+ options: [
22447
+ { value: "1", label: "1 event" },
22448
+ { value: "2", label: "2 events" },
22449
+ { value: "3", label: "3 events" },
22450
+ { value: "4", label: "4 events" },
22451
+ { value: "5", label: "5 events" },
22452
+ { value: "6", label: "6 events" }
22453
+ ],
22454
+ ui: { intent: "display" }
22455
+ },
22456
+ {
22457
+ id: "ctaLabel",
22458
+ type: "text",
22459
+ label: "Section button text",
22460
+ description: "Optional button shown below the spotlight cards",
22461
+ required: false,
22462
+ multiline: false,
22463
+ maxLength: 40,
22464
+ ui: { intent: "content" }
22465
+ },
22466
+ {
22467
+ id: "ctaUrl",
22468
+ type: "link",
22469
+ label: "Section button destination",
22470
+ required: false,
22471
+ ui: { intent: "display" }
22472
+ },
22473
+ layoutField,
22474
+ columnsField(["2", "3"]),
22475
+ ...cardStylingFields,
22476
+ ...eventDisplayFields,
22477
+ emptyStateField,
22478
+ sectionStylesField({
22479
+ id: "_sectionStyles",
22480
+ label: "Section styles"
22481
+ })
22482
+ ];
22483
+ var eventSpotlightLayout = [
22484
+ styledSection({
22485
+ children: sectionContainer([
22486
+ // Optional heading
22487
+ text(
22488
+ { as: "h2" },
22489
+ bind("content.heading"),
22490
+ when("content.heading")
22491
+ ),
22492
+ // Optional description
22493
+ richText(
22494
+ { className: "rb-prose rb-max-w-none" },
22495
+ bind("content.description"),
22496
+ when("content.description")
22497
+ ),
22498
+ // Event spotlight component
22499
+ el("event-spotlight", {
22500
+ events: { $bind: { from: "data.events" } },
22501
+ layout: { $bind: { from: "content.layout", fallback: "grid" } },
22502
+ columns: { $bind: { from: "content.columns", fallback: "3" } },
22503
+ cardVariant: { $bind: { from: "content.cardVariant", fallback: "default" } },
22504
+ buttonVariant: { $bind: { from: "content.buttonVariant", fallback: "primary" } },
22505
+ buttonText: { $bind: { from: "content.buttonText", fallback: "View event" } },
22506
+ ctaLabel: { $bind: { from: "content.ctaLabel" } },
22507
+ ctaUrl: { $bind: { from: "content.ctaUrl", transforms: [{ id: "links.resolve" }] } },
22508
+ showVenue: { $bind: { from: "content.showVenue" } },
22509
+ showMap: { $bind: { from: "content.showMap" } },
22510
+ showCapacity: { $bind: { from: "content.showCapacity" } },
22511
+ emptyMessage: { $bind: { from: "content.emptyMessage" } }
22512
+ })
22513
+ ], {
22514
+ gap: "lg"
22515
+ }),
22516
+ // sectionContainer (rb-container) already provides horizontal padding
22517
+ baseClass: "",
22518
+ spacing: "comfortable"
22519
+ })
22520
+ ];
22521
+ var eventSpotlightConfig = {
22389
22522
  id: "block.event-spotlight",
22390
22523
  version: "1.1.0",
22391
22524
  title: "Event Spotlight",
22392
22525
  titleSource: "heading",
22393
22526
  description: "Feature a few upcoming events on your homepage",
22394
22527
  skipSectionStyles: true,
22395
- additionalFields: [
22396
- ...sectionHeaderFields("Upcoming Events"),
22397
- {
22398
- id: "maxEvents",
22399
- type: "select",
22400
- label: "Events to display",
22401
- description: "Number of events to show",
22402
- required: false,
22403
- multiple: false,
22404
- defaultValue: "3",
22405
- options: [
22406
- { value: "1", label: "1 event" },
22407
- { value: "2", label: "2 events" },
22408
- { value: "3", label: "3 events" },
22409
- { value: "4", label: "4 events" },
22410
- { value: "5", label: "5 events" },
22411
- { value: "6", label: "6 events" }
22412
- ],
22413
- ui: { intent: "display" }
22414
- },
22415
- {
22416
- id: "ctaLabel",
22417
- type: "text",
22418
- label: "Section button text",
22419
- description: "Optional button shown below the spotlight cards",
22420
- required: false,
22421
- multiline: false,
22422
- maxLength: 40,
22423
- ui: { intent: "content" }
22424
- },
22425
- {
22426
- id: "ctaUrl",
22427
- type: "link",
22428
- label: "Section button destination",
22429
- required: false,
22430
- ui: { intent: "display" }
22431
- },
22432
- layoutField,
22433
- columnsField(["2", "3"]),
22434
- ...cardStylingFields,
22435
- ...eventDisplayFields,
22436
- emptyStateField,
22437
- sectionStylesField({
22438
- id: "_sectionStyles",
22439
- label: "Section styles"
22440
- })
22441
- ],
22528
+ additionalFields: eventSpotlightFields,
22442
22529
  styleTokens: { background: "surface", typography: "body", spacing: "md" },
22443
22530
  behaviours: { supportsThemeSwitching: true, inlineEditing: false, animation: false, paletteHidden: false },
22444
22531
  category: "content",
22445
22532
  tags: ["events", "featured", "homepage", "spotlight", "upcoming"],
22446
22533
  icon: "Star",
22447
- layout: [
22448
- styledSection({
22449
- children: sectionContainer([
22450
- // Optional heading
22451
- text(
22452
- { as: "h2" },
22453
- bind("content.heading"),
22454
- when("content.heading")
22455
- ),
22456
- // Optional description
22457
- richText(
22458
- { className: "rb-prose rb-max-w-none" },
22459
- bind("content.description"),
22460
- when("content.description")
22461
- ),
22462
- // Event spotlight component
22463
- el("event-spotlight", {
22464
- events: { $bind: { from: "data.events" } },
22465
- layout: { $bind: { from: "content.layout", fallback: "grid" } },
22466
- columns: { $bind: { from: "content.columns", fallback: "3" } },
22467
- cardVariant: { $bind: { from: "content.cardVariant", fallback: "default" } },
22468
- buttonVariant: { $bind: { from: "content.buttonVariant", fallback: "primary" } },
22469
- buttonText: { $bind: { from: "content.buttonText", fallback: "View event" } },
22470
- ctaLabel: { $bind: { from: "content.ctaLabel" } },
22471
- ctaUrl: { $bind: { from: "content.ctaUrl", transforms: [{ id: "links.resolve" }] } },
22472
- showVenue: { $bind: { from: "content.showVenue" } },
22473
- showMap: { $bind: { from: "content.showMap" } },
22474
- showCapacity: { $bind: { from: "content.showCapacity" } },
22475
- emptyMessage: { $bind: { from: "content.emptyMessage" } }
22476
- })
22477
- ], {
22478
- gap: "lg"
22479
- }),
22480
- // sectionContainer (rb-container) already provides horizontal padding
22481
- baseClass: "",
22482
- spacing: "comfortable"
22483
- })
22484
- ]
22485
- });
22534
+ layout: eventSpotlightLayout
22535
+ };
22536
+ var eventSpotlightManifest = createBlockManifest(eventSpotlightConfig);
22486
22537
  var eventSpotlightBlockDefinition = {
22487
22538
  manifest: eventSpotlightManifest,
22488
22539
  dataSchemas: {
@@ -25172,18 +25223,18 @@ var fileDownloadManifest = createBlockManifest({
25172
25223
  title: "File Download",
25173
25224
  titleSource: ["title", "file.filename"],
25174
25225
  category: "media",
25175
- description: "Add a simple public download link for a document, ZIP, audio, or video file.",
25226
+ description: "Add a simple public download link for a document, ZIP, or audio file.",
25176
25227
  tags: ["file", "download", "document", "zip", "media"],
25177
25228
  icon: "Download",
25178
25229
  includeContainerStyles: true,
25179
25230
  additionalFields: [
25180
25231
  {
25181
25232
  id: "file",
25182
- type: "media",
25233
+ type: "file",
25183
25234
  label: "Download file",
25184
25235
  description: "Choose the file visitors can download.",
25185
25236
  required: false,
25186
- mediaKinds: [...PUBLIC_DOWNLOAD_MEDIA_TYPES],
25237
+ fileKinds: [...PUBLIC_DOWNLOAD_MEDIA_TYPES],
25187
25238
  ui: { intent: "content" }
25188
25239
  },
25189
25240
  {