@elytracms/studio 0.0.98 → 0.0.99

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 (91) hide show
  1. package/convex/ingest.test.ts +84 -7
  2. package/convex/ingest.ts +110 -31
  3. package/convex/path-segment-refusal.test.ts +201 -0
  4. package/convex/records-column-transform.convex.test.ts +147 -0
  5. package/convex/schema.ts +1 -1
  6. package/dist/addon.d.ts +5 -3
  7. package/dist/addon.js +4 -3
  8. package/dist/addon.js.map +1 -1
  9. package/dist/components/app-views/default-modules.d.ts +10 -3
  10. package/dist/components/app-views/default-modules.js +5 -1
  11. package/dist/components/app-views/default-modules.js.map +1 -1
  12. package/dist/components/app-views/module.d.ts +15 -8
  13. package/dist/components/app-views/module.js.map +1 -1
  14. package/dist/components/builder/reuse-context.d.ts +29 -1
  15. package/dist/components/builder/reuse-context.js +58 -12
  16. package/dist/components/builder/reuse-context.js.map +1 -1
  17. package/dist/components/cms/cms-store.d.ts +3 -2
  18. package/dist/components/cms/cms-store.js +8 -2
  19. package/dist/components/cms/cms-store.js.map +1 -1
  20. package/dist/components/cms/field-control.js +15 -5
  21. package/dist/components/cms/field-control.js.map +1 -1
  22. package/dist/components/cms/use-document-draft.d.ts +4 -1
  23. package/dist/components/cms/use-document-draft.js +4 -1
  24. package/dist/components/cms/use-document-draft.js.map +1 -1
  25. package/dist/components/cms/use-publish-controller.d.ts +7 -0
  26. package/dist/components/cms/use-publish-controller.js +17 -3
  27. package/dist/components/cms/use-publish-controller.js.map +1 -1
  28. package/dist/components/cms/versions-pane.js +8 -5
  29. package/dist/components/cms/versions-pane.js.map +1 -1
  30. package/dist/components/delivery-health-banner.d.ts +34 -16
  31. package/dist/components/delivery-health-banner.js +59 -27
  32. package/dist/components/delivery-health-banner.js.map +1 -1
  33. package/dist/components/issue-severity.d.ts +3 -2
  34. package/dist/components/issue-severity.js.map +1 -1
  35. package/dist/components/nav-issues-registry.d.ts +39 -24
  36. package/dist/components/nav-issues-registry.js +50 -21
  37. package/dist/components/nav-issues-registry.js.map +1 -1
  38. package/dist/components/nav-issues.d.ts +23 -50
  39. package/dist/components/nav-issues.js +31 -59
  40. package/dist/components/nav-issues.js.map +1 -1
  41. package/dist/components/notifications/notice-center.d.ts +61 -0
  42. package/dist/components/notifications/notice-center.js +119 -0
  43. package/dist/components/notifications/notice-center.js.map +1 -0
  44. package/dist/components/notifications/notice-model.d.ts +137 -0
  45. package/dist/components/notifications/notice-model.js +107 -0
  46. package/dist/components/notifications/notice-model.js.map +1 -0
  47. package/dist/components/notifications/outcome-notice.d.ts +16 -0
  48. package/dist/components/notifications/outcome-notice.js +34 -0
  49. package/dist/components/notifications/outcome-notice.js.map +1 -0
  50. package/dist/components/notifications/shell-findings.d.ts +36 -0
  51. package/dist/components/notifications/shell-findings.js +140 -0
  52. package/dist/components/notifications/shell-findings.js.map +1 -0
  53. package/dist/components/rail-view-source.js +5 -0
  54. package/dist/components/rail-view-source.js.map +1 -1
  55. package/dist/components/records/record-rail.d.ts +10 -2
  56. package/dist/components/records/record-rail.js +74 -4
  57. package/dist/components/records/record-rail.js.map +1 -1
  58. package/dist/components/section-nav.d.ts +15 -3
  59. package/dist/components/section-nav.js +39 -147
  60. package/dist/components/section-nav.js.map +1 -1
  61. package/dist/components/studio-project-screen.js.map +1 -1
  62. package/dist/components/studio-shell.js +8 -3
  63. package/dist/components/studio-shell.js.map +1 -1
  64. package/dist/components/use-narrow-viewport.d.ts +11 -0
  65. package/dist/components/use-narrow-viewport.js +25 -0
  66. package/dist/components/use-narrow-viewport.js.map +1 -0
  67. package/dist/components/users/role-policy-drift-issues.d.ts +14 -7
  68. package/dist/components/users/role-policy-drift-issues.js +17 -8
  69. package/dist/components/users/role-policy-drift-issues.js.map +1 -1
  70. package/dist/lib/collection-view/collection-view-source.d.ts +4 -2
  71. package/dist/lib/collection-view/collection-view-source.js.map +1 -1
  72. package/dist/lib/engine-version.d.ts +1 -1
  73. package/dist/lib/engine-version.js +1 -1
  74. package/dist/lib/engine-version.js.map +1 -1
  75. package/dist/lib/i18n/messages.de.js +21 -3
  76. package/dist/lib/i18n/messages.de.js.map +1 -1
  77. package/dist/lib/i18n/messages.en.d.ts +19 -2
  78. package/dist/lib/i18n/messages.en.js +24 -4
  79. package/dist/lib/i18n/messages.en.js.map +1 -1
  80. package/dist/lib/notices/toast-store.d.ts +61 -0
  81. package/dist/lib/notices/toast-store.js +116 -0
  82. package/dist/lib/notices/toast-store.js.map +1 -0
  83. package/dist/lib/operations/cms-persistence.d.ts +24 -4
  84. package/dist/lib/operations/cms-persistence.js +417 -80
  85. package/dist/lib/operations/cms-persistence.js.map +1 -1
  86. package/dist/lib/persistence/convex-adapter.js +61 -30
  87. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  88. package/dist/ui/toast.d.ts +24 -16
  89. package/dist/ui/toast.js +23 -32
  90. package/dist/ui/toast.js.map +1 -1
  91. package/package.json +3 -3
@@ -75,7 +75,20 @@ declare const MESSAGES: {
75
75
  'shell.nav.planned': import("./types.js").SourceMessage;
76
76
  'shell.nav.collapseView': import("./types.js").SourceMessage;
77
77
  'shell.nav.expandView': import("./types.js").SourceMessage;
78
- 'shell.nav.issuesCount': import("./types.js").SourceMessage;
78
+ 'shell.notices.title': import("./types.js").SourceMessage;
79
+ 'shell.notices.open': import("./types.js").SourceMessage;
80
+ 'shell.notices.none': import("./types.js").SourceMessage;
81
+ 'shell.notices.errors.one': import("./types.js").SourceMessage;
82
+ 'shell.notices.errors.other': import("./types.js").SourceMessage;
83
+ 'shell.notices.warnings.one': import("./types.js").SourceMessage;
84
+ 'shell.notices.warnings.other': import("./types.js").SourceMessage;
85
+ 'shell.notices.empty': import("./types.js").SourceMessage;
86
+ 'shell.notices.goTo': import("./types.js").SourceMessage;
87
+ 'shell.notices.dismiss': import("./types.js").SourceMessage;
88
+ 'shell.notices.declaredInProject': import("./types.js").SourceMessage;
89
+ 'shell.notices.declaredInStudio': import("./types.js").SourceMessage;
90
+ 'shell.notices.deploymentSettings': import("./types.js").SourceMessage;
91
+ 'shell.notices.reservedSource': import("./types.js").SourceMessage;
79
92
  'shell.nav.orphanedCollections': import("./types.js").SourceMessage;
80
93
  'shell.nav.orphanedCollections.item': import("./types.js").SourceMessage;
81
94
  'shell.nav.orphanedCollections.itemPublished': import("./types.js").SourceMessage;
@@ -129,7 +142,9 @@ declare const MESSAGES: {
129
142
  'shell.devLogin.hint': import("./types.js").SourceMessage;
130
143
  'shell.playground.badge': import("./types.js").SourceMessage;
131
144
  'shell.playground.hint': import("./types.js").SourceMessage;
132
- 'shell.deliveryHealth.dismiss': import("./types.js").SourceMessage;
145
+ 'shell.deliveryHealth.title': import("./types.js").SourceMessage;
146
+ 'shell.deliveryHealth.missing': import("./types.js").SourceMessage;
147
+ 'shell.deliveryHealth.unchecked': import("./types.js").SourceMessage;
133
148
  'shell.rolePolicyDrift.title': import("./types.js").SourceMessage;
134
149
  'customization.issue.noCollections': import("./types.js").SourceMessage;
135
150
  'customization.issue.duplicateOverrideId': import("./types.js").SourceMessage;
@@ -472,6 +487,7 @@ declare const MESSAGES: {
472
487
  'cms.conflict.empty': import("./types.js").SourceMessage;
473
488
  'cms.conflict.structured': import("./types.js").SourceMessage;
474
489
  'cms.conflict.cellRefused': import("./types.js").SourceMessage;
490
+ 'cms.conflict.aliasRefused': import("./types.js").SourceMessage;
475
491
  'cms.conflict.unauthored': import("./types.js").SourceMessage;
476
492
  'cms.presence.inField': import("./types.js").SourceMessage;
477
493
  'cms.presence.inFieldMany': import("./types.js").SourceMessage;
@@ -654,6 +670,7 @@ declare const MESSAGES: {
654
670
  'cms.field.slug.regenerate': import("./types.js").SourceMessage;
655
671
  'cms.field.slug.taken': import("./types.js").SourceMessage;
656
672
  'cms.field.slug.takenGeneric': import("./types.js").SourceMessage;
673
+ 'cms.field.slug.routedComposesChildren': import("./types.js").SourceMessage;
657
674
  'cms.relation.change': import("./types.js").SourceMessage;
658
675
  'cms.relation.openTitle': import("./types.js").SourceMessage;
659
676
  'cms.relation.pick': import("./types.js").SourceMessage;
@@ -87,7 +87,21 @@ const MESSAGES = {
87
87
  'shell.nav.planned': msg('Planned', 'Tooltip on the status dot of a planned (not-yet-enabled) nav view.'),
88
88
  'shell.nav.collapseView': msg('Collapse {name}', 'aria-label on a parent nav item disclosure; {name} is the view label.'),
89
89
  'shell.nav.expandView': msg('Expand {name}', 'aria-label on a parent nav item disclosure; {name} is the view label.'),
90
- 'shell.nav.issuesCount': msg('{count} sidebar issues', 'aria-label summarising rail customization issues on the collapsed rail.'),
90
+ // EC-690 — the ONE notification-and-issue surface: the header badge and its issues tray.
91
+ 'shell.notices.title': msg('Issues', 'Title (and aria-label) of the issues tray the header badge opens.'),
92
+ 'shell.notices.open': msg('Show issues: {summary}', 'aria-label of the header issues badge; {summary} is shell.notices.none or e.g. "2 errors, 1 warning".'),
93
+ 'shell.notices.none': msg('No issues', 'The header badge summary when nothing needs attention.'),
94
+ 'shell.notices.errors.one': msg('{count} error'),
95
+ 'shell.notices.errors.other': msg('{count} errors'),
96
+ 'shell.notices.warnings.one': msg('{count} warning'),
97
+ 'shell.notices.warnings.other': msg('{count} warnings'),
98
+ 'shell.notices.empty': msg('Nothing needs your attention.', 'The issues tray with no notice and no finding.'),
99
+ 'shell.notices.goTo': msg('Go to', 'Link on a finding in the issues tray that opens where it is (a redirect row, a document).'),
100
+ 'shell.notices.dismiss': msg('Dismiss', 'aria-label of the dismiss button on a notice in the issues tray.'),
101
+ 'shell.notices.declaredInProject': msg('in {file}', 'Where a project-config finding is fixed; {file} is the project config file name (elytra.config.ts), untranslated.'),
102
+ 'shell.notices.declaredInStudio': msg('in your defineStudio({…}) config', 'Where a studio-customization finding is fixed; defineStudio is code, untranslated.'),
103
+ 'shell.notices.deploymentSettings': msg('Convex deployment: {settings}', 'Where a deployment finding is fixed; {settings} are environment variable names, untranslated.'),
104
+ 'shell.notices.reservedSource': msg('An addon publishes findings under "{source}", a source name the engine reserves. Rename the source it passes to useNavIssues.', 'Error finding: an addon used an engine-reserved source name. {source} and useNavIssues are code, untranslated.'),
91
105
  // EC-606 — stored documents whose collection the project no longer declares. One
92
106
  // warning at the rail foot; {collections} joins one item message per collection.
93
107
  'shell.nav.orphanedCollections': msg('Stored documents of collections this project does not declare are hidden from the studio: {collections}. To bring them back, declare the collection in "{file}" again (or restore its old id).', 'Warning at the rail foot. {collections} is a comma-separated list of shell.nav.orphanedCollections.item / .itemPublished; {file} is the project config file name (elytra.config.ts), untranslated.'),
@@ -145,8 +159,11 @@ const MESSAGES = {
145
159
  'shell.devLogin.hint': msg('Dev auto-login: the studio signed in automatically from VITE_ELYTRA_DEV_LOGIN (dev builds only). Unset it to test the real sign-in flow.'),
146
160
  'shell.playground.badge': msg('Playground', 'Product term — may stay untranslated.'),
147
161
  'shell.playground.hint': msg('Playground mode: data lives in memory on this device and resets on reload. Nothing is saved to a backend.'),
148
- 'shell.deliveryHealth.dismiss': msg('Dismiss'),
149
- // EC-605 — the role-policy drift finding in the rail's issues foot (the deployment
162
+ // EC-690 — instant-publish health (EC-268), a finding of the issues tray (it was a banner).
163
+ 'shell.deliveryHealth.title': msg('Instant publish not set up', 'Title of the instant-publish health finding.'),
164
+ 'shell.deliveryHealth.missing': msg('{vars} not set on this Convex deployment. Publishes succeed, but the live site won’t update until you set them (see CONNECT.md) and re-push functions. A project that runs no revalidate host declares instantPublish: false in {file}.', '{vars} are environment variable names; {file} is elytra.config.ts; instantPublish: false is code — all untranslated.'),
165
+ 'shell.deliveryHealth.unchecked': msg('Instant publish could not be checked: {error}', '{error} is the failed read’s message.'),
166
+ // EC-605 — the role-policy drift finding in the issues tray, for admins (the deployment
150
167
  // enforces another role policy than elytra.config.ts declares). The doctor's verdict
151
168
  // text (English, technical) follows it.
152
169
  'shell.rolePolicyDrift.title': msg('This deployment enforces a different role policy than the project declares — permissions may not be what you expect.'),
@@ -609,6 +626,7 @@ const MESSAGES = {
609
626
  'cms.conflict.empty': msg('(empty)', 'EC-595 A2: {value} when the stored value is empty.'),
610
627
  'cms.conflict.structured': msg('a structured value', 'EC-595 A2: {value} when the stored value is not plain text (an object, a list, rich text).'),
611
628
  'cms.conflict.cellRefused': msg('This field was changed by someone else since you loaded it — their value is shown.', 'EC-595 A2: a table cell or bulk edit refused because the field changed meanwhile; the stored value is kept.'),
629
+ 'cms.conflict.aliasRefused': msg('The slot was changed by someone else since you chose it — theirs is kept. Choose it again to change it.', 'EC-686: a slot (alias) change refused because a colleague changed the slot first. The slot has no field of its own to hold a take-theirs / keep-mine choice, so the stored slot is kept. Shown on the persistence error banner.'),
612
630
  'cms.conflict.unauthored': msg('A change was not saved: it does not say which version of the document it was made on, so it could overwrite a newer change. Reload the document and make it again.', 'EC-647: a write that names no revision it was authored against is refused, never sent at the newest one (it could silently overwrite a colleague). Shown on the persistence error banner.'),
613
631
  'cms.presence.inField': msg('{name} is in this field', 'EC-595 A2 thin presence: another session has this field focused. {name} is their name.'),
614
632
  'cms.presence.inFieldMany': msg('{names} are in this field', 'EC-595 A2 thin presence: several sessions have this field focused. {names} is a comma-separated list of names.'),
@@ -642,7 +660,7 @@ const MESSAGES = {
642
660
  'cms.issueMessage.unknownVersion': msg('No version {version} recorded for document "{id}".'),
643
661
  'cms.issueMessage.routeConflict': msg('Routes "{first}" and "{second}" both match the same URLs (pattern "{pattern}").'),
644
662
  'cms.issueMessage.redirectLoop': msg('Redirect chain starting at "{from}" loops (…{chain}).'),
645
- 'cms.issueMessage.duplicateRedirect': msg('Redirect "{redirect}" (from "{redirectFrom}") duplicates redirect "{kept}" (from "{keptFrom}") — both are "{from}" once trailing slashes are ignored. "{kept}" applies; delete or change the other.'),
663
+ 'cms.issueMessage.duplicateRedirect': msg('Redirect from "{redirectFrom}" duplicates the redirect from "{keptFrom}" — both are "{from}" once trailing slashes are ignored. The redirect from "{keptFrom}" applies; delete or change this one.'),
646
664
  'cms.issueMessage.redirectUnreadable': msg('Stored redirect {redirect} could not be read and is not served ({reason}).', 'EC-628 (Codex F04): {redirect} is "id" (or #index), {reason} the column findings in English.'),
647
665
  'cms.issueMessage.redirectReportUnreadable': msg("The deployment reported redirect issue #{index}, which this host cannot read — a redirect is not served; run the site on the deployment's engine version.", 'EC-628: the delivery snapshot carried a redirect issue the host (an older engine) cannot parse.'),
648
666
  'cms.issueMessage.allDynamicShadowsMount': msg('Route "{route}" ("{pattern}") has only dynamic segments, so it matches EVERY {depth}-segment URL — hierarchy mount "{mountRoute}" ("{mountPattern}") is consulted at that depth only where the route resolves no document. Nothing is unconditionally unreachable, but precedence there is decided by CONTENT rather than by the routes: {shadowed} are silently shadowed wherever a composed path collides with {claimed}, and neither side is told. Give the route a static prefix ("/blog/:slug") so it claims a namespace instead of a whole depth.'),
@@ -814,6 +832,8 @@ const MESSAGES = {
814
832
  'cms.field.slug.regenerate': msg('Regenerate the slug', 'Tooltip on the ↻ button that re-derives the slug from its source field.'),
815
833
  'cms.field.slug.taken': msg('Already used by “{title}”', 'Inline warning when the slug collides with another document.'),
816
834
  'cms.field.slug.takenGeneric': msg('This slug is already in use.', 'Inline warning when a custom uniqueness check reports the slug is taken.'),
835
+ // EC-691 — a page an explicit route binds answers only at that route's address.
836
+ 'cms.field.slug.routedComposesChildren': msg('This page’s address is {path}. Its slug only composes the paths of its child pages.', 'Hint under the slug control of a page an explicit route binds (e.g. Home at /): the slug is not an address of its own.'),
817
837
  // ─────────────────────────────────────────────────────────────────────────
818
838
  // CMS — relation picker
819
839
  // ─────────────────────────────────────────────────────────────────────────