@forumone/throughline 2.1.0 → 2.2.0-next-623d42c

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 (183) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/approvals/endpoints/action.d.ts.map +1 -1
  3. package/dist/approvals/endpoints/action.js +27 -8
  4. package/dist/approvals/endpoints/action.js.map +1 -1
  5. package/dist/approvals/tokens.d.ts +3 -0
  6. package/dist/approvals/tokens.d.ts.map +1 -1
  7. package/dist/approvals/tokens.js +1 -1
  8. package/dist/approvals/tokens.js.map +1 -1
  9. package/dist/authoring/tools.d.ts.map +1 -1
  10. package/dist/authoring/tools.js +6 -1
  11. package/dist/authoring/tools.js.map +1 -1
  12. package/dist/components/tools/validate-composition.d.ts.map +1 -1
  13. package/dist/components/tools/validate-composition.js +4 -1
  14. package/dist/components/tools/validate-composition.js.map +1 -1
  15. package/dist/components/validation/composition.d.ts +9 -1
  16. package/dist/components/validation/composition.d.ts.map +1 -1
  17. package/dist/components/validation/composition.js +9 -7
  18. package/dist/components/validation/composition.js.map +1 -1
  19. package/dist/exports/client.d.ts +3 -0
  20. package/dist/exports/client.d.ts.map +1 -1
  21. package/dist/exports/client.js +2 -0
  22. package/dist/exports/client.js.map +1 -1
  23. package/dist/fields/slug.d.ts.map +1 -1
  24. package/dist/fields/slug.js +4 -1
  25. package/dist/fields/slug.js.map +1 -1
  26. package/dist/integrations/admin/SyncButton.d.ts.map +1 -1
  27. package/dist/integrations/admin/SyncButton.js +11 -5
  28. package/dist/integrations/admin/SyncButton.js.map +1 -1
  29. package/dist/integrations/admin/sync-client.d.ts +2 -0
  30. package/dist/integrations/admin/sync-client.d.ts.map +1 -1
  31. package/dist/integrations/admin/sync-client.js +7 -1
  32. package/dist/integrations/admin/sync-client.js.map +1 -1
  33. package/dist/integrations/collection.d.ts +1 -1
  34. package/dist/integrations/collection.d.ts.map +1 -1
  35. package/dist/integrations/collection.js +11 -4
  36. package/dist/integrations/collection.js.map +1 -1
  37. package/dist/integrations/sync/status.d.ts +17 -4
  38. package/dist/integrations/sync/status.d.ts.map +1 -1
  39. package/dist/integrations/sync/status.js +37 -6
  40. package/dist/integrations/sync/status.js.map +1 -1
  41. package/dist/media/hooks.d.ts.map +1 -1
  42. package/dist/media/hooks.js +11 -9
  43. package/dist/media/hooks.js.map +1 -1
  44. package/dist/migrate/exports.json +16 -0
  45. package/dist/publishing/admin/FirstErrorProvider.d.ts +24 -0
  46. package/dist/publishing/admin/FirstErrorProvider.d.ts.map +1 -0
  47. package/dist/publishing/admin/FirstErrorProvider.js +100 -0
  48. package/dist/publishing/admin/FirstErrorProvider.js.map +1 -0
  49. package/dist/publishing/admin/PublishButton.d.ts.map +1 -1
  50. package/dist/publishing/admin/PublishButton.js +18 -3
  51. package/dist/publishing/admin/PublishButton.js.map +1 -1
  52. package/dist/publishing/admin/SchedulePublishField.d.ts.map +1 -1
  53. package/dist/publishing/admin/SchedulePublishField.js +25 -10
  54. package/dist/publishing/admin/SchedulePublishField.js.map +1 -1
  55. package/dist/publishing/admin/UnpublishButton.d.ts.map +1 -1
  56. package/dist/publishing/admin/UnpublishButton.js +9 -3
  57. package/dist/publishing/admin/UnpublishButton.js.map +1 -1
  58. package/dist/publishing/admin/first-error.d.ts +60 -0
  59. package/dist/publishing/admin/first-error.d.ts.map +1 -0
  60. package/dist/publishing/admin/first-error.js +211 -0
  61. package/dist/publishing/admin/first-error.js.map +1 -0
  62. package/dist/publishing/admin/publishing-client.d.ts +33 -4
  63. package/dist/publishing/admin/publishing-client.d.ts.map +1 -1
  64. package/dist/publishing/admin/publishing-client.js +56 -21
  65. package/dist/publishing/admin/publishing-client.js.map +1 -1
  66. package/dist/publishing/admin/schedule-state.d.ts +31 -4
  67. package/dist/publishing/admin/schedule-state.d.ts.map +1 -1
  68. package/dist/publishing/admin/schedule-state.js +26 -14
  69. package/dist/publishing/admin/schedule-state.js.map +1 -1
  70. package/dist/publishing/checks/alt-text.d.ts.map +1 -1
  71. package/dist/publishing/checks/alt-text.js +3 -1
  72. package/dist/publishing/checks/alt-text.js.map +1 -1
  73. package/dist/publishing/checks/heading-hierarchy.d.ts +9 -3
  74. package/dist/publishing/checks/heading-hierarchy.d.ts.map +1 -1
  75. package/dist/publishing/checks/heading-hierarchy.js +19 -6
  76. package/dist/publishing/checks/heading-hierarchy.js.map +1 -1
  77. package/dist/publishing/checks/link-labels.js +1 -1
  78. package/dist/publishing/checks/link-labels.js.map +1 -1
  79. package/dist/publishing/endpoints/admin.d.ts.map +1 -1
  80. package/dist/publishing/endpoints/admin.js +26 -7
  81. package/dist/publishing/endpoints/admin.js.map +1 -1
  82. package/dist/publishing/events.d.ts +15 -1
  83. package/dist/publishing/events.d.ts.map +1 -1
  84. package/dist/publishing/events.js +17 -2
  85. package/dist/publishing/events.js.map +1 -1
  86. package/dist/publishing/hooks/block-status-writes.js +5 -2
  87. package/dist/publishing/hooks/block-status-writes.js.map +1 -1
  88. package/dist/publishing/hooks/schedule-events.d.ts.map +1 -1
  89. package/dist/publishing/hooks/schedule-events.js +5 -7
  90. package/dist/publishing/hooks/schedule-events.js.map +1 -1
  91. package/dist/publishing/index.d.ts +9 -1
  92. package/dist/publishing/index.d.ts.map +1 -1
  93. package/dist/publishing/index.js +7 -0
  94. package/dist/publishing/index.js.map +1 -1
  95. package/dist/publishing/messages.d.ts +63 -0
  96. package/dist/publishing/messages.d.ts.map +1 -0
  97. package/dist/publishing/messages.js +84 -0
  98. package/dist/publishing/messages.js.map +1 -0
  99. package/dist/publishing/options.d.ts +46 -1
  100. package/dist/publishing/options.d.ts.map +1 -1
  101. package/dist/publishing/options.js +8 -0
  102. package/dist/publishing/options.js.map +1 -1
  103. package/dist/publishing/pipeline/finish.d.ts +12 -0
  104. package/dist/publishing/pipeline/finish.d.ts.map +1 -0
  105. package/dist/publishing/pipeline/finish.js +24 -0
  106. package/dist/publishing/pipeline/finish.js.map +1 -0
  107. package/dist/publishing/pipeline/index.d.ts.map +1 -1
  108. package/dist/publishing/pipeline/index.js +11 -8
  109. package/dist/publishing/pipeline/index.js.map +1 -1
  110. package/dist/publishing/pipeline/steps/accessibility.d.ts +3 -3
  111. package/dist/publishing/pipeline/steps/accessibility.d.ts.map +1 -1
  112. package/dist/publishing/pipeline/steps/accessibility.js +17 -9
  113. package/dist/publishing/pipeline/steps/accessibility.js.map +1 -1
  114. package/dist/publishing/pipeline/steps/approval.d.ts.map +1 -1
  115. package/dist/publishing/pipeline/steps/approval.js +6 -4
  116. package/dist/publishing/pipeline/steps/approval.js.map +1 -1
  117. package/dist/publishing/pipeline/steps/composition.d.ts.map +1 -1
  118. package/dist/publishing/pipeline/steps/composition.js +36 -17
  119. package/dist/publishing/pipeline/steps/composition.js.map +1 -1
  120. package/dist/publishing/pipeline/steps/embargo.d.ts +4 -0
  121. package/dist/publishing/pipeline/steps/embargo.d.ts.map +1 -1
  122. package/dist/publishing/pipeline/steps/embargo.js +13 -4
  123. package/dist/publishing/pipeline/steps/embargo.js.map +1 -1
  124. package/dist/publishing/pipeline/steps/execute.d.ts.map +1 -1
  125. package/dist/publishing/pipeline/steps/execute.js +48 -5
  126. package/dist/publishing/pipeline/steps/execute.js.map +1 -1
  127. package/dist/publishing/pipeline/steps/exist.d.ts +2 -0
  128. package/dist/publishing/pipeline/steps/exist.d.ts.map +1 -1
  129. package/dist/publishing/pipeline/steps/exist.js +5 -3
  130. package/dist/publishing/pipeline/steps/exist.js.map +1 -1
  131. package/dist/publishing/pipeline/steps/link-targets.d.ts +3 -0
  132. package/dist/publishing/pipeline/steps/link-targets.d.ts.map +1 -0
  133. package/dist/publishing/pipeline/steps/link-targets.js +293 -0
  134. package/dist/publishing/pipeline/steps/link-targets.js.map +1 -0
  135. package/dist/publishing/pipeline/steps/required-fields.d.ts.map +1 -1
  136. package/dist/publishing/pipeline/steps/required-fields.js +7 -5
  137. package/dist/publishing/pipeline/steps/required-fields.js.map +1 -1
  138. package/dist/publishing/pipeline/types.d.ts +25 -0
  139. package/dist/publishing/pipeline/types.d.ts.map +1 -1
  140. package/dist/publishing/pipeline/where.d.ts +13 -0
  141. package/dist/publishing/pipeline/where.d.ts.map +1 -0
  142. package/dist/publishing/pipeline/where.js +44 -0
  143. package/dist/publishing/pipeline/where.js.map +1 -0
  144. package/dist/publishing/plugin.d.ts.map +1 -1
  145. package/dist/publishing/plugin.js +22 -0
  146. package/dist/publishing/plugin.js.map +1 -1
  147. package/dist/publishing/service.d.ts +26 -17
  148. package/dist/publishing/service.d.ts.map +1 -1
  149. package/dist/publishing/service.js +43 -32
  150. package/dist/publishing/service.js.map +1 -1
  151. package/dist/publishing/tools/get-publish-status.d.ts.map +1 -1
  152. package/dist/publishing/tools/get-publish-status.js +4 -0
  153. package/dist/publishing/tools/get-publish-status.js.map +1 -1
  154. package/dist/publishing/tools/rollback.d.ts.map +1 -1
  155. package/dist/publishing/tools/rollback.js +1 -1
  156. package/dist/publishing/tools/rollback.js.map +1 -1
  157. package/dist/references/UsedOnPanel.d.ts.map +1 -1
  158. package/dist/references/UsedOnPanel.js +1 -1
  159. package/dist/references/UsedOnPanel.js.map +1 -1
  160. package/dist/references/find.d.ts +12 -1
  161. package/dist/references/find.d.ts.map +1 -1
  162. package/dist/references/find.js +24 -5
  163. package/dist/references/find.js.map +1 -1
  164. package/dist/references/guards.d.ts.map +1 -1
  165. package/dist/references/guards.js +9 -2
  166. package/dist/references/guards.js.map +1 -1
  167. package/dist/references/index.d.ts +4 -2
  168. package/dist/references/index.d.ts.map +1 -1
  169. package/dist/references/index.js +2 -1
  170. package/dist/references/index.js.map +1 -1
  171. package/dist/references/links.d.ts +45 -0
  172. package/dist/references/links.d.ts.map +1 -0
  173. package/dist/references/links.js +117 -0
  174. package/dist/references/links.js.map +1 -0
  175. package/dist/references/walk.d.ts +70 -0
  176. package/dist/references/walk.d.ts.map +1 -1
  177. package/dist/references/walk.js +88 -41
  178. package/dist/references/walk.js.map +1 -1
  179. package/dist/utils/field-path.d.ts +56 -0
  180. package/dist/utils/field-path.d.ts.map +1 -0
  181. package/dist/utils/field-path.js +146 -0
  182. package/dist/utils/field-path.js.map +1 -0
  183. package/package.json +6 -5
@@ -1 +1 @@
1
- {"version":3,"file":"publishing-client.d.ts","sourceRoot":"","sources":["../../../src/publishing/admin/publishing-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,eAAe,EAAE,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAA;IAC3D,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GACtC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAElC;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAkC/B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC1B,oBAAoB,EAAE,CAgBxB;AAeD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,kBAAkB,EACxB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC;IACD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB,CA4BA"}
1
+ {"version":3,"file":"publishing-client.d.ts","sourceRoot":"","sources":["../../../src/publishing/admin/publishing-client.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,14 @@
2
2
  * Client-side helpers shared by the admin Publish and Unpublish controls.
3
3
  * No JSX here so the message formatting can be unit tested directly.
4
4
  */
5
+ import { goToFirstError } from './first-error.js';
6
+ import { TRY_AGAIN, localiseMessage, } from '../messages.js';
7
+ const VERB = {
8
+ publish: 'publish',
9
+ unpublish: 'unpublish',
10
+ schedule: 'schedule',
11
+ unschedule: 'cancel the schedule',
12
+ };
5
13
  /**
6
14
  * POSTs to the plugin's admin endpoint using the browser's session cookie.
7
15
  * Returns a transport-level failure as `ok: false`; a pipeline block comes
@@ -23,20 +31,21 @@ export async function callPublishingEndpoint(args) {
23
31
  });
24
32
  }
25
33
  catch {
26
- return { ok: false, message: 'Could not reach the publishing server.' };
34
+ return {
35
+ ok: false,
36
+ message: `Couldn't connect to ${VERB[args.action]}. Check your internet connection and try again. Nothing was changed.`,
37
+ };
27
38
  }
39
+ const unexpected = `Publishing didn't respond as expected (error ${response.status}). ${TRY_AGAIN}`;
28
40
  let body;
29
41
  try {
30
42
  body = (await response.json());
31
43
  }
32
44
  catch {
33
- return { ok: false, message: `Publishing server returned ${response.status}.` };
45
+ return { ok: false, message: unexpected };
34
46
  }
35
47
  if (!response.ok) {
36
- return {
37
- ok: false,
38
- message: body.error ?? `Publishing server returned ${response.status}.`,
39
- };
48
+ return { ok: false, message: body.error ?? unexpected };
40
49
  }
41
50
  return { ok: true, body };
42
51
  }
@@ -83,12 +92,16 @@ export function fieldErrorsFromBlock(body, formPaths) {
83
92
  for (const issue of body.issues ?? []) {
84
93
  if (!issue.field)
85
94
  continue;
86
- const resolved = resolveFieldPath(toFormPath(issue.field), paths);
95
+ const exact = toFormPath(issue.field);
96
+ const resolved = resolveFieldPath(exact, paths);
87
97
  if (!resolved)
88
98
  continue;
99
+ // On the field itself the field is the location. On an ancestor — three
100
+ // blocks' problems all on `layout` — each needs saying which it is.
101
+ const message = resolved !== exact && issue.where ? `${issue.where}: ${issue.message}` : issue.message;
89
102
  const messages = byPath.get(resolved) ?? [];
90
- if (!messages.includes(issue.message))
91
- messages.push(issue.message);
103
+ if (!messages.includes(message))
104
+ messages.push(message);
92
105
  byPath.set(resolved, messages);
93
106
  }
94
107
  return [...byPath].map(([path, messages]) => ({ path, message: messages.join('; ') }));
@@ -107,33 +120,55 @@ function resolveFieldPath(path, formPaths) {
107
120
  }
108
121
  const MAX_LISTED_ISSUES = 5;
109
122
  /**
110
- * Turns a pipeline block into something an editor can act on: which step
111
- * said no, what it objected to, and what to do about it. This is the
112
- * information the pipeline already returns — it just never had a way to
113
- * reach the screen.
123
+ * Turns a pipeline block into something an editor can act on: what is wrong,
124
+ * where, and what to do about it. forumone-2026#805.
125
+ *
126
+ * Which step refused is software's business — it stays in `failedAt` and
127
+ * `code` — and an issue's location is said the way the edit view says it,
128
+ * `Block 3 (Image Hero) › Image`, from the `where` the pipeline attached.
129
+ * An issue the pipeline could not place is listed by its message alone, never
130
+ * by its raw path. A date the server wrote in its own zone is rewritten into
131
+ * the editor's.
114
132
  */
115
133
  export function describeBlock(body, options = {}) {
116
- const title = body.reason ?? `Publish blocked at the ${body.failedAt ?? 'policy'} check.`;
134
+ const local = (text) => localiseMessage(text, body.when, options.date);
135
+ const title = body.reason ? local(body.reason) : "This can't be published yet.";
117
136
  const lines = [];
118
- if (body.failedAt && body.reason) {
119
- lines.push(`Blocked at: ${body.failedAt}`);
120
- }
121
137
  const issues = body.issues ?? [];
122
138
  for (const issue of issues.slice(0, MAX_LISTED_ISSUES)) {
123
- lines.push(`• ${issue.field ? `${issue.field}: ` : ''}${issue.message}`);
139
+ lines.push(`• ${issue.where ? `${issue.where}: ` : ''}${issue.message}`);
124
140
  }
125
141
  if (issues.length > MAX_LISTED_ISSUES) {
126
142
  lines.push(`• …and ${issues.length - MAX_LISTED_ISSUES} more`);
127
143
  }
128
144
  if (body.suggestion) {
129
- lines.push(`Suggestion: ${body.suggestion}`);
145
+ lines.push(local(body.suggestion));
130
146
  }
131
147
  // Said only when it is true. An editor who has read a toast listing five
132
- // paths still has to find them, and the answer — they are marked on the
148
+ // problems still has to find them, and the answer — they are marked on the
133
149
  // fields — is not something the toast otherwise reveals.
134
150
  if ((options.markedFields ?? 0) > 0) {
135
- lines.push('Fields with a problem are highlighted in the form.');
151
+ lines.push('The fields with a problem are highlighted.');
136
152
  }
137
153
  return { title, description: lines.join('\n') };
138
154
  }
155
+ /**
156
+ * The "Show me" action on an error toast whose problems are marked on fields:
157
+ * takes the editor to the first of them again, for one who has scrolled away.
158
+ * The toast stays open, since it is still the list of what to fix.
159
+ */
160
+ export const SHOW_ME = {
161
+ label: 'Show me',
162
+ onClick: (event) => {
163
+ event.preventDefault();
164
+ void goToFirstError();
165
+ },
166
+ };
167
+ /**
168
+ * The toast id for a refusal of `action` on one document, so a second click
169
+ * replaces the first toast rather than stacking a copy on it.
170
+ */
171
+ export function blockToastId(action, collection, id) {
172
+ return `throughline:${action}-blocked:${collection}:${id}`;
173
+ }
139
174
  //# sourceMappingURL=publishing-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"publishing-client.js","sourceRoot":"","sources":["../../../src/publishing/admin/publishing-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publishing-client.js","sourceRoot":"","sources":["../../../src/publishing/admin/publishing-client.ts"],"names":[],"mappings":"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"}
@@ -22,9 +22,36 @@ export type ScheduleState = {
22
22
  };
23
23
  export declare function scheduleState(value: unknown, now: number, locale?: string): ScheduleState;
24
24
  /**
25
- * The time in the editor's own zone, with the zone named. An editor in London
26
- * and one in New York looking at the same post see different wall-clock
27
- * times, and each needs to know which one they are reading.
25
+ * The time in the editor's own zone, with the zone named: `Tue 6 Oct 2026,
26
+ * 9:00 am EDT`. An editor in London and one in New York looking at the same
27
+ * post see different wall-clock times, and each needs to know which one they
28
+ * are reading. The same form as every other date the admin shows
29
+ * (forumone-2026#805); `_locale` is no longer read.
28
30
  */
29
- export declare function formatScheduledTime(at: Date, locale?: string): string;
31
+ export declare function formatScheduledTime(at: Date, _locale?: string, timeZone?: string): string;
32
+ /** What the Schedule control says after a cancel, and whether the field empties. */
33
+ export type UnscheduleOutcome = {
34
+ kind: 'success';
35
+ message: string;
36
+ clear: true;
37
+ } | {
38
+ kind: 'info';
39
+ message: string;
40
+ clear: true;
41
+ } | {
42
+ kind: 'error';
43
+ message: string;
44
+ clear: false;
45
+ };
46
+ /**
47
+ * A cancel that found nothing to cancel is not a cancellation, and used to
48
+ * say "Schedule cancelled" anyway (forumone-2026#805). The field still empties
49
+ * — nothing scheduled is what the editor asked for — but the toast says what
50
+ * was true.
51
+ */
52
+ export declare function unscheduleOutcome(body: {
53
+ unscheduled?: boolean;
54
+ code?: string;
55
+ reason?: string;
56
+ }): UnscheduleOutcome;
30
57
  //# sourceMappingURL=schedule-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-state.d.ts","sourceRoot":"","sources":["../../../src/publishing/admin/schedule-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC/C;;;;;GAKG;GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAShD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CASzF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAWrE"}
1
+ {"version":3,"file":"schedule-state.d.ts","sourceRoot":"","sources":["../../../src/publishing/admin/schedule-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC/C;;;;;GAKG;GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAShD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CASzF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED,oFAAoF;AACpF,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAEpD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,iBAAiB,CAUpB"}
@@ -2,6 +2,7 @@
2
2
  * What the Schedule control says about a stored scheduled time. No JSX, so it
3
3
  * can be tested without a form.
4
4
  */
5
+ import { formatHumanDate } from '../messages.js';
5
6
  /**
6
7
  * How long past its time a schedule may be before it is called overdue. The
7
8
  * run wakes on the minute, but it still has to load the document and pass the
@@ -20,20 +21,31 @@ export function scheduleState(value, now, locale) {
20
21
  : { kind: 'upcoming', at, label };
21
22
  }
22
23
  /**
23
- * The time in the editor's own zone, with the zone named. An editor in London
24
- * and one in New York looking at the same post see different wall-clock
25
- * times, and each needs to know which one they are reading.
24
+ * The time in the editor's own zone, with the zone named: `Tue 6 Oct 2026,
25
+ * 9:00 am EDT`. An editor in London and one in New York looking at the same
26
+ * post see different wall-clock times, and each needs to know which one they
27
+ * are reading. The same form as every other date the admin shows
28
+ * (forumone-2026#805); `_locale` is no longer read.
26
29
  */
27
- export function formatScheduledTime(at, locale) {
28
- // Spelled out rather than `dateStyle`/`timeStyle`, which the spec forbids
29
- // alongside `timeZoneName` — the constructor throws, in browsers too.
30
- return new Intl.DateTimeFormat(locale, {
31
- year: 'numeric',
32
- month: 'short',
33
- day: 'numeric',
34
- hour: 'numeric',
35
- minute: '2-digit',
36
- timeZoneName: 'short',
37
- }).format(at);
30
+ export function formatScheduledTime(at, _locale, timeZone) {
31
+ return formatHumanDate(at, { zoneName: true, ...(timeZone ? { timeZone } : {}) });
32
+ }
33
+ /**
34
+ * A cancel that found nothing to cancel is not a cancellation, and used to
35
+ * say "Schedule cancelled" anyway (forumone-2026#805). The field still empties
36
+ * — nothing scheduled is what the editor asked for — but the toast says what
37
+ * was true.
38
+ */
39
+ export function unscheduleOutcome(body) {
40
+ if (body.unscheduled)
41
+ return { kind: 'success', message: 'Schedule cancelled.', clear: true };
42
+ if (body.code === 'not-scheduled') {
43
+ return { kind: 'info', message: body.reason ?? 'There was nothing scheduled.', clear: true };
44
+ }
45
+ return {
46
+ kind: 'error',
47
+ message: body.reason ?? "The schedule couldn't be cancelled. Nothing was changed.",
48
+ clear: false,
49
+ };
38
50
  }
39
51
  //# sourceMappingURL=schedule-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-state.js","sourceRoot":"","sources":["../../../src/publishing/admin/schedule-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AAEtC,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,GAAW,EAAE,MAAe;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACtD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAEvD,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC7C,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,gBAAgB;QAC1C,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE;QAChC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAQ,EAAE,MAAe;IAC3D,0EAA0E;IAC1E,sEAAsE;IACtE,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;QACrC,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,OAAO;QACd,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,OAAO;KACtB,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"schedule-state.js","sourceRoot":"","sources":["../../../src/publishing/admin/schedule-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAahD;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AAEtC,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,GAAW,EAAE,MAAe;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACtD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAEvD,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC7C,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,gBAAgB;QAC1C,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE;QAChC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAQ,EAAE,OAAgB,EAAE,QAAiB;IAC/E,OAAO,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;AACnF,CAAC;AAQD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAIjC;IACC,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IAC7F,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,8BAA8B,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IAC9F,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,0DAA0D;QAClF,KAAK,EAAE,KAAK;KACb,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"alt-text.d.ts","sourceRoot":"","sources":["../../../src/publishing/checks/alt-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAE3E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,EAAE,kBAgB1B,CAAA"}
1
+ {"version":3,"file":"alt-text.d.ts","sourceRoot":"","sources":["../../../src/publishing/checks/alt-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAE3E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,EAAE,kBAkB1B,CAAA"}
@@ -21,7 +21,9 @@ export const altTextCheck = {
21
21
  if (typeof alt !== 'string' || alt.trim() === '') {
22
22
  issues.push({
23
23
  field: path,
24
- message: `Image at "${path}" is missing alt text`,
24
+ // Where the image is reaches the editor as the issue's `where`, so
25
+ // the message says only what is wrong and what to do.
26
+ message: "This image has no alt text. Describe what it shows, for someone who can't see it.",
25
27
  severity: 'error',
26
28
  });
27
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"alt-text.js","sourceRoot":"","sources":["../../../src/publishing/checks/alt-text.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAuB;IAC9C,IAAI,EAAE,UAAU;IAChB,GAAG,CAAC,GAAG;QACL,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,aAAa,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACjD,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,IAAI;oBACX,OAAO,EAAE,aAAa,IAAI,uBAAuB;oBACjD,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAED,SAAS,aAAa,CACpB,KAAc,EACd,KAA6D,EAC7D,IAAI,GAAG,EAAE;IAET,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAM;IAE/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;QACjD,CAAC;QACD,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,KAAgC,CAAA;IAC5C,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,sDAAsD;QACtD,IAAI,OAAO,IAAI,GAAG,KAAK,OAAO;YAAE,SAAQ;QACxC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAA4B;IAClD,wEAAwE;IACxE,qEAAqE;IACrE,wEAAwE;IACxE,qBAAqB;IACrB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC9D,OAAO,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAA;AAC5C,CAAC"}
1
+ {"version":3,"file":"alt-text.js","sourceRoot":"","sources":["../../../src/publishing/checks/alt-text.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAuB;IAC9C,IAAI,EAAE,UAAU;IAChB,GAAG,CAAC,GAAG;QACL,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,aAAa,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACjD,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,IAAI;oBACX,mEAAmE;oBACnE,sDAAsD;oBACtD,OAAO,EAAE,mFAAmF;oBAC5F,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAED,SAAS,aAAa,CACpB,KAAc,EACd,KAA6D,EAC7D,IAAI,GAAG,EAAE;IAET,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAM;IAE/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;QACjD,CAAC;QACD,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,KAAgC,CAAA;IAC5C,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,sDAAsD;QACtD,IAAI,OAAO,IAAI,GAAG,KAAK,OAAO;YAAE,SAAQ;QACxC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAA4B;IAClD,wEAAwE;IACxE,qEAAqE;IACrE,wEAAwE;IACxE,qBAAqB;IACrB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC9D,OAAO,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAA;AAC5C,CAAC"}
@@ -2,10 +2,16 @@ import type { AccessibilityCheck } from '../options.js';
2
2
  /**
3
3
  * Structural heading-hierarchy check. Without rendering the page we can't
4
4
  * fully audit heading levels, but we can flag the most common structural
5
- * mistake: multiple Hero blocks (each becomes an h1 in the reference DS).
5
+ * mistake: more than one hero, when each hero holds the page's `h1`.
6
6
  *
7
- * Block types are matched case-insensitively against `'hero'` since the
8
- * `blockType` field is by convention lower-cased in Payload.
7
+ * A hero is a block whose contract's `category` is `hero` — `ImageHero`,
8
+ * `VideoHero`, `CollageHero` alike. It used to be a block whose type was
9
+ * literally `hero`, which no design system using Throughline has, so the check
10
+ * never fired (forumone-2026#805). A contract's `maxPerPage` catches two of
11
+ * the *same* hero; only this catches two different ones.
12
+ *
13
+ * Without the components plugin there are no contracts to ask, and a block
14
+ * typed `hero` is still counted, as before.
9
15
  */
10
16
  export declare const headingHierarchyCheck: AccessibilityCheck;
11
17
  //# sourceMappingURL=heading-hierarchy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"heading-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/publishing/checks/heading-hierarchy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAE3E;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAuBnC,CAAA"}
1
+ {"version":3,"file":"heading-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/publishing/checks/heading-hierarchy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAE3E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBA8BnC,CAAA"}
@@ -1,28 +1,41 @@
1
1
  /**
2
2
  * Structural heading-hierarchy check. Without rendering the page we can't
3
3
  * fully audit heading levels, but we can flag the most common structural
4
- * mistake: multiple Hero blocks (each becomes an h1 in the reference DS).
4
+ * mistake: more than one hero, when each hero holds the page's `h1`.
5
5
  *
6
- * Block types are matched case-insensitively against `'hero'` since the
7
- * `blockType` field is by convention lower-cased in Payload.
6
+ * A hero is a block whose contract's `category` is `hero` — `ImageHero`,
7
+ * `VideoHero`, `CollageHero` alike. It used to be a block whose type was
8
+ * literally `hero`, which no design system using Throughline has, so the check
9
+ * never fired (forumone-2026#805). A contract's `maxPerPage` catches two of
10
+ * the *same* hero; only this catches two different ones.
11
+ *
12
+ * Without the components plugin there are no contracts to ask, and a block
13
+ * typed `hero` is still counted, as before.
8
14
  */
9
15
  export const headingHierarchyCheck = {
10
16
  name: 'heading-hierarchy',
11
- run(doc, collection) {
17
+ run(doc, collection, context) {
12
18
  const issues = [];
13
19
  const layoutValue = doc[collection.layoutField];
14
20
  if (!Array.isArray(layoutValue))
15
21
  return issues;
22
+ const components = context?.components;
23
+ const isHero = (blockType) => {
24
+ const contract = components?.[blockType];
25
+ if (contract)
26
+ return contract.category?.toLowerCase() === 'hero';
27
+ return blockType.toLowerCase() === 'hero';
28
+ };
16
29
  const heroCount = layoutValue.filter((block) => {
17
30
  if (!block || typeof block !== 'object')
18
31
  return false;
19
32
  const blockType = block['blockType'];
20
- return typeof blockType === 'string' && blockType.toLowerCase() === 'hero';
33
+ return typeof blockType === 'string' && isHero(blockType);
21
34
  }).length;
22
35
  if (heroCount > 1) {
23
36
  issues.push({
24
37
  field: collection.layoutField,
25
- message: `Page has ${heroCount} Hero blocks but should have exactly one (each Hero becomes an h1)`,
38
+ message: `This page has ${heroCount} hero blocks. Keep one; the hero holds the page's main heading.`,
26
39
  severity: 'error',
27
40
  });
28
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"heading-hierarchy.js","sourceRoot":"","sources":["../../../src/publishing/checks/heading-hierarchy.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAuB;IACvD,IAAI,EAAE,mBAAmB;IACzB,GAAG,CAAC,GAAG,EAAE,UAAU;QACjB,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAAE,OAAO,MAAM,CAAA;QAE9C,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAA;YACrD,MAAM,SAAS,GAAI,KAAiC,CAAC,WAAW,CAAC,CAAA;YACjE,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,CAAA;QAC5E,CAAC,CAAC,CAAC,MAAM,CAAA;QAET,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,UAAU,CAAC,WAAW;gBAC7B,OAAO,EAAE,YAAY,SAAS,oEAAoE;gBAClG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA"}
1
+ {"version":3,"file":"heading-hierarchy.js","sourceRoot":"","sources":["../../../src/publishing/checks/heading-hierarchy.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAuB;IACvD,IAAI,EAAE,mBAAmB;IACzB,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO;QAC1B,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAAE,OAAO,MAAM,CAAA;QAE9C,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,CAAA;QACtC,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAW,EAAE;YAC5C,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC,SAAS,CAAC,CAAA;YACxC,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,MAAM,CAAA;YAChE,OAAO,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,CAAA;QAC3C,CAAC,CAAA;QAED,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAA;YACrD,MAAM,SAAS,GAAI,KAAiC,CAAC,WAAW,CAAC,CAAA;YACjE,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAA;QAC3D,CAAC,CAAC,CAAC,MAAM,CAAA;QAET,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,UAAU,CAAC,WAAW;gBAC7B,OAAO,EAAE,iBAAiB,SAAS,iEAAiE;gBACpG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA"}
@@ -16,7 +16,7 @@ export const linkLabelsCheck = {
16
16
  if (hasUrl && !hasLabel) {
17
17
  issues.push({
18
18
  field: path,
19
- message: `Link at "${path}" has a URL but no label`,
19
+ message: 'This link has no text. Add the words people will click.',
20
20
  severity: 'error',
21
21
  });
22
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"link-labels.js","sourceRoot":"","sources":["../../../src/publishing/checks/link-labels.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAuB;IACjD,IAAI,EAAE,aAAa;IACnB,GAAG,CAAC,GAAG;QACL,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;YAC3B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;YAC3D,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;YACjE,IAAI,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,IAAI;oBACX,OAAO,EAAE,YAAY,IAAI,0BAA0B;oBACnD,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAED,SAAS,YAAY,CACnB,KAAc,EACd,KAA4D,EAC5D,IAAI,GAAG,EAAE;IAET,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAM;IAE/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;QAChD,CAAC;QACD,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,KAAgC,CAAA;IAC5C,IAAI,KAAK,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;QACnC,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"link-labels.js","sourceRoot":"","sources":["../../../src/publishing/checks/link-labels.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAuB;IACjD,IAAI,EAAE,aAAa;IACnB,GAAG,CAAC,GAAG;QACL,MAAM,MAAM,GAAyB,EAAE,CAAA;QACvC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;YAC3B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;YAC3D,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;YACjE,IAAI,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,IAAI;oBACX,OAAO,EAAE,yDAAyD;oBAClE,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAED,SAAS,YAAY,CACnB,KAAc,EACd,KAA4D,EAC5D,IAAI,GAAG,EAAE;IAET,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAM;IAE/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;QAChD,CAAC;QACD,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,KAAgC,CAAA;IAC5C,IAAI,KAAK,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;QACnC,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../src/publishing/endpoints/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAuB,MAAM,SAAS,CAAA;AAatE,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,QAAQ,EAAE,CAuB/E"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../src/publishing/endpoints/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAuB,MAAM,SAAS,CAAA;AActE,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,QAAQ,EAAE,CAuB/E"}
@@ -1,5 +1,6 @@
1
1
  import { APIError } from 'payload';
2
2
  import { z } from 'zod';
3
+ import { TELL_AN_ADMINISTRATOR, UNEXPECTED_PROBLEM } from '../messages.js';
3
4
  import { getPublishingService, toAuthenticatedUser } from '../service.js';
4
5
  const BodySchema = z.object({
5
6
  collection: z.string().min(1),
@@ -43,27 +44,38 @@ export function createAdminEndpoints(deps) {
43
44
  }
44
45
  async function handle(req, deps, action) {
45
46
  if (!req.user) {
46
- return json({ error: 'You must be logged in to publish.' }, 401);
47
+ return json({
48
+ error: `Your sign-in has ended. Sign in again, then ${action === 'unschedule' ? 'cancel the schedule' : action}.`,
49
+ code: 'signed-out',
50
+ }, 401);
47
51
  }
52
+ /*
53
+ The three below happen only through a bug in whatever called this — the
54
+ admin's own controls always send a well-formed body — never through anything
55
+ an editor did. So the editor reads the generic "unexpected problem", and the
56
+ specifics go in `detail` for whoever is debugging the request.
57
+ */
48
58
  let raw;
49
59
  try {
50
60
  raw = await req.json?.();
51
61
  }
52
62
  catch {
53
- return json({ error: 'Invalid JSON body.' }, 400);
63
+ return badRequest(action, 'Invalid JSON body.');
54
64
  }
55
65
  const parsed = BodySchema.safeParse(raw);
56
66
  if (!parsed.success) {
57
- return json({ error: 'Expected a JSON body with `collection` and `id`.' }, 400);
67
+ return badRequest(action, 'Expected a JSON body with `collection` and `id`.');
58
68
  }
59
69
  const { collection, publishAt } = parsed.data;
60
70
  const id = String(parsed.data.id);
61
71
  if (action === 'schedule' && !publishAt) {
62
- return json({ error: 'Expected `publishAt`, an ISO 8601 time, to schedule.' }, 400);
72
+ return badRequest(action, 'Expected `publishAt`, an ISO 8601 time, to schedule.');
63
73
  }
64
74
  if (!deps.publishableSlugs.has(collection)) {
65
75
  return json({
66
- error: `Collection "${collection}" is not registered as publishable. Add it to publishingPlugin's collections option.`,
76
+ error: `Publishing isn't set up for this kind of content. Please ${TELL_AN_ADMINISTRATOR}.`,
77
+ code: 'not-publishable',
78
+ detail: `Collection "${collection}" is not registered as publishable. Add it to publishingPlugin's collections option.`,
67
79
  }, 400);
68
80
  }
69
81
  let service;
@@ -71,7 +83,11 @@ async function handle(req, deps, action) {
71
83
  service = getPublishingService(req.payload);
72
84
  }
73
85
  catch {
74
- return json({ error: 'Publishing server not initialized.' }, 503);
86
+ return json({
87
+ error: `Publishing isn't available right now. Try again in a minute; if it keeps happening, ${TELL_AN_ADMINISTRATOR}.`,
88
+ code: 'not-initialized',
89
+ detail: 'The publishing service is not attached to this Payload instance yet.',
90
+ }, 503);
75
91
  }
76
92
  const request = {
77
93
  collection,
@@ -100,9 +116,12 @@ async function handle(req, deps, action) {
100
116
  return json({ error: error.message }, error.status || 500);
101
117
  }
102
118
  req.payload.logger.error({ err: error }, `[publishing] admin ${action} failed for ${collection}/${id}`);
103
- return json({ error: `Could not ${action} this document.` }, 500);
119
+ return json({ error: UNEXPECTED_PROBLEM(action), code: 'unexpected' }, 500);
104
120
  }
105
121
  }
122
+ function badRequest(action, detail) {
123
+ return json({ error: UNEXPECTED_PROBLEM(action), code: 'bad-request', detail }, 400);
124
+ }
106
125
  function json(body, status) {
107
126
  return new Response(JSON.stringify(body), {
108
127
  status,
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/publishing/endpoints/admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/publishing/endpoints/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsC,MAAM,SAAS,CAAA;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAEzE,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,uBAAuB;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC5D,CAAC,CAAA;AAWF;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAA8B;IACjE,OAAO;QACL;YACE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,UAAU;YACnC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;SAC/C;QACD;YACE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,YAAY;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC;SACjD;QACD;YACE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,WAAW;YACpC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC;SAChD;QACD;YACE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,aAAa;YACtC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC;SAClD;KACF,CAAA;AACH,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,GAAmB,EACnB,IAA8B,EAC9B,MAAc;IAEd,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,CACT;YACE,KAAK,EAAE,+CAA+C,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,MAAM,GAAG;YACjH,IAAI,EAAE,YAAY;SACnB,EACD,GAAG,CACJ,CAAA;IACH,CAAC;IAED;;;;;MAKE;IACF,IAAI,GAAY,CAAA;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,UAAU,CAAC,MAAM,EAAE,kDAAkD,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,CAAA;IAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEjC,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,MAAM,EAAE,sDAAsD,CAAC,CAAA;IACnF,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAI,CACT;YACE,KAAK,EAAE,4DAA4D,qBAAqB,GAAG;YAC3F,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,eAAe,UAAU,sFAAsF;SACxH,EACD,GAAG,CACJ,CAAA;IACH,CAAC;IAED,IAAI,OAAO,CAAA;IACX,IAAI,CAAC;QACH,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CACT;YACE,KAAK,EAAE,uFAAuF,qBAAqB,GAAG;YACtH,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,sEAAsE;SAC/E,EACD,GAAG,CACJ,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG;QACd,UAAU;QACV,EAAE;QACF,KAAK,EAAE;YACL,IAAI,EAAE,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;YACnC,eAAe,EAAE,GAAG,CAAC,IAAI;YACzB,OAAO,EAAE,OAAgB;SAC1B;KACF,CAAA;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GACV,MAAM,KAAK,SAAS;YAClB,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;YAChC,CAAC,CAAC,MAAM,KAAK,WAAW;gBACtB,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;gBAClC,CAAC,CAAC,MAAM,KAAK,UAAU;oBACrB,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,SAAU,EAAE,CAAC;oBAC/D,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC3C,uEAAuE;QACvE,iEAAiE;QACjE,uDAAuD;QACvD,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAA;QAC5D,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CACtB,EAAE,GAAG,EAAE,KAAK,EAAE,EACd,sBAAsB,MAAM,eAAe,UAAU,IAAI,EAAE,EAAE,CAC9D,CAAA;QACD,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,GAAG,CAAC,CAAA;IAC7E,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAc,EAAE,MAAc;IAChD,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAA;AACtF,CAAC;AAED,SAAS,IAAI,CAAC,IAAa,EAAE,MAAc;IACzC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC"}
@@ -1,5 +1,16 @@
1
1
  import type { Inngest } from 'inngest';
2
2
  type EventPayload = Parameters<Inngest['send']>[0];
3
+ /** Anything with a `warn(message)`: Payload's logger, or Throughline's. */
4
+ export interface WarnLogger {
5
+ warn: (message: string) => void;
6
+ }
7
+ /**
8
+ * What the editor reads when the change landed and the event after it did not.
9
+ * Said in terms of what they will see, because they cannot see an event: the
10
+ * live site may lag, and so may anything the site sends changes to. Nothing for
11
+ * them to redo — the obvious response to "it failed" is to publish again.
12
+ */
13
+ export declare const EVENT_NOT_SENT = "The live site may take a while to show this change, and connected services may not have been updated. If it still hasn't changed in 15 minutes, tell a site administrator.";
3
14
  /**
4
15
  * Emits a publishing event without letting a transport failure fail the
5
16
  * publish that already landed. Returns a warning on failure, `null` on success.
@@ -7,7 +18,10 @@ type EventPayload = Parameters<Inngest['send']>[0];
7
18
  * Publishing writes the document first and emits afterwards. Throwing here
8
19
  * would tell an editor their change didn't go live when it did, and the obvious
9
20
  * response to that is to click Publish again on content that is already live.
21
+ *
22
+ * The warning is for the editor; which event failed and why goes to `logger`,
23
+ * for whoever can fix it. forumone-2026#805.
10
24
  */
11
- export declare function sendEventSafely(inngest: Inngest, event: EventPayload): Promise<string | null>;
25
+ export declare function sendEventSafely(inngest: Inngest, event: EventPayload, logger?: WarnLogger | undefined): Promise<string | null>;
12
26
  export {};
13
27
  //# sourceMappingURL=events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/publishing/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGtC,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAElD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExB"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/publishing/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAItC,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAElD,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,+KAA8K,CAAA;AAEzM;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,EACnB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB"}
@@ -1,4 +1,12 @@
1
1
  import { sendEventSafely as send } from '../utils/send-event-safely.js';
2
+ import { TELL_AN_ADMINISTRATOR } from './messages.js';
3
+ /**
4
+ * What the editor reads when the change landed and the event after it did not.
5
+ * Said in terms of what they will see, because they cannot see an event: the
6
+ * live site may lag, and so may anything the site sends changes to. Nothing for
7
+ * them to redo — the obvious response to "it failed" is to publish again.
8
+ */
9
+ export const EVENT_NOT_SENT = `The live site may take a while to show this change, and connected services may not have been updated. If it still hasn't changed in 15 minutes, ${TELL_AN_ADMINISTRATOR}.`;
2
10
  /**
3
11
  * Emits a publishing event without letting a transport failure fail the
4
12
  * publish that already landed. Returns a warning on failure, `null` on success.
@@ -6,8 +14,15 @@ import { sendEventSafely as send } from '../utils/send-event-safely.js';
6
14
  * Publishing writes the document first and emits afterwards. Throwing here
7
15
  * would tell an editor their change didn't go live when it did, and the obvious
8
16
  * response to that is to click Publish again on content that is already live.
17
+ *
18
+ * The warning is for the editor; which event failed and why goes to `logger`,
19
+ * for whoever can fix it. forumone-2026#805.
9
20
  */
10
- export async function sendEventSafely(inngest, event) {
11
- return await send(inngest, event, 'revalidation and integrations may not have run');
21
+ export async function sendEventSafely(inngest, event, logger) {
22
+ const failure = await send(inngest, event, 'revalidation and integrations may not have run');
23
+ if (failure === null)
24
+ return null;
25
+ logger?.warn(`[publishing] ${failure}`);
26
+ return EVENT_NOT_SENT;
12
27
  }
13
28
  //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/publishing/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,MAAM,+BAA+B,CAAA;AAIvE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,KAAmB;IAEnB,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,gDAAgD,CAAC,CAAA;AACrF,CAAC"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/publishing/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,MAAM,+BAA+B,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AASrD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,mJAAmJ,qBAAqB,GAAG,CAAA;AAEzM;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,KAAmB,EACnB,MAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,gDAAgD,CAAC,CAAA;IAC5F,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IACjC,MAAM,EAAE,IAAI,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAA;IACvC,OAAO,cAAc,CAAA;AACvB,CAAC"}
@@ -125,9 +125,12 @@ export function createBlockStatusWritesHook() {
125
125
  // a developer, and this is the one refusal an editor reaches from the
126
126
  // admin's own controls. Same decision, words they can act on.
127
127
  if (nextStatus === 'published' && restoresFromTrash(data, originalDoc)) {
128
- throw new APIError('Restore it as a draft, then publish it. Publishing is what runs the checks a live page needs.', 400);
128
+ throw new APIError('Restore it as a draft first, then publish it from its own page.', 400);
129
129
  }
130
- throw new APIError('Direct writes to `_status` are not allowed. Use the publishing server (publish / unpublish / rollback) so the policy pipeline runs.', 400);
130
+ // Reached from the list view's bulk publish, and from restoring a version
131
+ // as published. Said for the editor who got here that way (#805); a
132
+ // developer writing `_status` reads the same sentence and the same answer.
133
+ throw new APIError("This can't be published or unpublished from here. Open the document and use its Publish or Unpublish button, so the pre-publish checks run.", 400);
131
134
  };
132
135
  }
133
136
  /**