@forumone/throughline 2.3.1-pr-317-97d9e21 → 2.4.0-next-c49a98b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -4
- package/dist/migrate/exports.json +2 -0
- package/dist/publishing/pipeline/steps/composition.d.ts.map +1 -1
- package/dist/publishing/pipeline/steps/composition.js +32 -15
- package/dist/publishing/pipeline/steps/composition.js.map +1 -1
- package/dist/publishing/pipeline/steps/required-in-blocks.d.ts +9 -0
- package/dist/publishing/pipeline/steps/required-in-blocks.d.ts.map +1 -0
- package/dist/publishing/pipeline/steps/required-in-blocks.js +89 -0
- package/dist/publishing/pipeline/steps/required-in-blocks.js.map +1 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
# @forumone/throughline
|
|
2
2
|
|
|
3
|
-
## 2.
|
|
3
|
+
## 2.4.0-next-c49a98b
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c49a98b: A block with an empty required field no longer passes `check` or takes a page down (forumone-2026#840).
|
|
8
|
+
|
|
9
|
+
- **Publishing:** the composition step reports a `required-field` issue for each required field inside a block that is empty, for example "Block 3 (Featured Work) › Item 2 › Image is required before this can be published."
|
|
10
|
+
- `check`, `get_publish_status` and the admin's publish all see it before the write.
|
|
11
|
+
- Before this, only Payload's write enforced `required`, and `check` called such a page ready.
|
|
12
|
+
- The rule walks the block's Payload config. So a field the site adds counts, such as a form block's `source.form`. A field the site omits or hides doesn't. A required link counts too, because the contract says so even though a generated link enforces it with a validate.
|
|
13
|
+
- **Render:** `RenderBlocks` no longer renders a component whose required image didn't arrive, whether the slot is empty in a draft or the image no longer resolves.
|
|
14
|
+
- The component would read `item.image.src` from nothing and throw, and one card took Live Preview down to the error page.
|
|
15
|
+
- The new `onIncompleteBlock` decides what renders instead. It defaults to nothing.
|
|
16
|
+
- `missingRequiredImages` is exported for a host to ask the same question.
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
6
19
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
|
|
20
|
+
- e48f0cd: The `previewUrl` and `adminUrl` that MCP tools return are absolute, so a person can open them from a chat in another app (forumone-2026#840). They were paths whenever the site left Payload's `serverURL` unset. They are now made absolute against `serverURL` when it is set, and otherwise against the origin the MCP request arrived at. A document's own fields are left as they are.
|
|
21
|
+
- e48f0cd: `design_guide` for a component also returns `siteFields`: the fields a site adds to that block beyond the component's contract, described the way `get` describes a content type, with `findWith` saying which `find` kind looks up a value. A form block's `source.form` was invisible to an agent, so it added the block and left the form empty (forumone-2026#840).
|
|
22
|
+
- Updated dependencies [c49a98b]
|
|
23
|
+
- @forumone/throughline-design-system@2.4.0-next-c49a98b
|
|
10
24
|
|
|
11
25
|
## 2.3.0
|
|
12
26
|
|
|
@@ -661,6 +661,7 @@
|
|
|
661
661
|
"FieldOverride": ["@forumone/throughline-design-system/generate"],
|
|
662
662
|
"GenerateOptions": ["@forumone/throughline-design-system/generate"],
|
|
663
663
|
"GeneratedBlock": ["@forumone/throughline-design-system/generate"],
|
|
664
|
+
"IncompleteBlock": ["@forumone/throughline-design-system/render"],
|
|
664
665
|
"LinkValue": ["@forumone/throughline-design-system/render"],
|
|
665
666
|
"LintIssue": [
|
|
666
667
|
"@forumone/throughline-design-system/contract",
|
|
@@ -738,6 +739,7 @@
|
|
|
738
739
|
"lintRecipe": ["@forumone/throughline-design-system/recipes"],
|
|
739
740
|
"loadManifest": ["@forumone/throughline-design-system/contract"],
|
|
740
741
|
"loadManifestFromUrl": ["@forumone/throughline-design-system/contract"],
|
|
742
|
+
"missingRequiredImages": ["@forumone/throughline-design-system/render"],
|
|
741
743
|
"pairTitle": ["@forumone/throughline-design-system/generate"],
|
|
742
744
|
"storedObject": ["@forumone/throughline-design-system/testing"],
|
|
743
745
|
"storedValue": ["@forumone/throughline-design-system/testing"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/composition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8CAA8C,CAAA;AAK5E,OAAO,KAAK,EAAkC,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/composition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8CAA8C,CAAA;AAK5E,OAAO,KAAK,EAAkC,YAAY,EAAE,MAAM,aAAa,CAAA;AAK/E;;;GAGG;AACH,eAAO,MAAM,2BAA2B,eAEvC,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,eAA0D,CAAA;AA8BjG;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,YAiH7B,CAAA;AAiHD,6EAA6E;AAC7E,wBAAgB,UAAU,CACxB,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,EACrD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,EAAE,GAAG,SAAS,CAiBtB;AAID,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYlD"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { lintRecipe } from '@forumone/throughline-design-system/recipes';
|
|
2
2
|
import { PUBLISHING_UNAVAILABLE, TELL_AN_ADMINISTRATOR, plural } from '../../messages.js';
|
|
3
|
-
import { blockLabel, fieldConfigFor } from '../where.js';
|
|
3
|
+
import { blockLabel, describeFieldPath, fieldConfigFor } from '../where.js';
|
|
4
|
+
import { findBlock, findField } from '../../../utils/field-path.js';
|
|
5
|
+
import { emptyRequiredFields } from './required-in-blocks.js';
|
|
4
6
|
/**
|
|
5
7
|
* Symbol the Component Server's plugin (C5) attaches its composition
|
|
6
8
|
* validator to. Keep in sync with the components package.
|
|
@@ -77,20 +79,35 @@ export const compositionStep = async (ctx) => {
|
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
const manifest = ctx.payload[COMPONENTS_MANIFEST_SYMBOL];
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
82
|
+
const components = manifest ? (await manifest()).components : undefined;
|
|
83
|
+
const layout = config ? findField(config.fields, ctx.collection.layoutField)?.field : undefined;
|
|
84
|
+
for (const [index, block] of typed.entries()) {
|
|
85
|
+
if (gate && block.blockType === gate.blockType)
|
|
86
|
+
continue;
|
|
87
|
+
const at = `${ctx.collection.layoutField}[${index}]`;
|
|
88
|
+
const component = components?.[block.blockType];
|
|
89
|
+
if (components && emptyBlock(component, block)) {
|
|
90
|
+
errors.push({
|
|
91
|
+
severity: 'error',
|
|
92
|
+
rule: 'empty-block',
|
|
93
|
+
message: `This ${blockLabel(config, block.blockType)} block is empty, so it would show as a blank band on the page. Fill it in or remove it.`,
|
|
94
|
+
field: at,
|
|
95
|
+
});
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
/*
|
|
99
|
+
Started but not finished: a required field inside it is empty. See
|
|
100
|
+
`required-in-blocks.ts` (forumone-2026#840).
|
|
101
|
+
*/
|
|
102
|
+
const blockConfig = layout && config ? findBlock(layout, block.blockType, config) : undefined;
|
|
103
|
+
for (const path of emptyRequiredFields(blockConfig?.fields, component?.content.fields, block, at)) {
|
|
104
|
+
const where = config ? describeFieldPath(path, config, ctx.document) : undefined;
|
|
105
|
+
errors.push({
|
|
106
|
+
severity: 'error',
|
|
107
|
+
rule: 'required-field',
|
|
108
|
+
message: `${where ?? path} is required before this can be published.`,
|
|
109
|
+
field: path,
|
|
110
|
+
});
|
|
94
111
|
}
|
|
95
112
|
}
|
|
96
113
|
if (errors.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/composition.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAA;AAGxE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEzF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/composition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FieldLike } from '../../../utils/field-path.js';
|
|
2
|
+
export interface ContractFieldLike {
|
|
3
|
+
name: string;
|
|
4
|
+
required?: boolean | undefined;
|
|
5
|
+
of?: readonly ContractFieldLike[] | undefined;
|
|
6
|
+
}
|
|
7
|
+
/** Paths, from `prefix`, of every required field in `fields` that `data` leaves empty. */
|
|
8
|
+
export declare function emptyRequiredFields(fields: readonly FieldLike[] | undefined, contract: readonly ContractFieldLike[] | undefined, data: unknown, prefix: string): string[];
|
|
9
|
+
//# sourceMappingURL=required-in-blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-in-blocks.d.ts","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/required-in-blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAgC7D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,EAAE,CAAC,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,CAAA;CAC9C;AAqCD,0FAA0F;AAC1F,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EACxC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,EAClD,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,GACb,MAAM,EAAE,CAiEV"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const BOOKKEEPING = new Set([
|
|
2
|
+
'id',
|
|
3
|
+
'blockType',
|
|
4
|
+
'blockName',
|
|
5
|
+
'mode',
|
|
6
|
+
'newTab',
|
|
7
|
+
'relationTo',
|
|
8
|
+
'type',
|
|
9
|
+
'variant',
|
|
10
|
+
'version',
|
|
11
|
+
'format',
|
|
12
|
+
'indent',
|
|
13
|
+
'direction',
|
|
14
|
+
]);
|
|
15
|
+
/** Whether a value carries anything a reader would see. Matches the empty-block rule. */
|
|
16
|
+
function filled(value) {
|
|
17
|
+
if (value === null || value === undefined)
|
|
18
|
+
return false;
|
|
19
|
+
if (typeof value === 'string')
|
|
20
|
+
return value.trim() !== '';
|
|
21
|
+
if (typeof value === 'number')
|
|
22
|
+
return true;
|
|
23
|
+
if (typeof value === 'boolean')
|
|
24
|
+
return false;
|
|
25
|
+
if (Array.isArray(value))
|
|
26
|
+
return value.some(filled);
|
|
27
|
+
if (typeof value === 'object') {
|
|
28
|
+
return Object.entries(value).some(([key, inner]) => !BOOKKEEPING.has(key) && filled(inner));
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/** Paths, from `prefix`, of every required field in `fields` that `data` leaves empty. */
|
|
33
|
+
export function emptyRequiredFields(fields, contract, data, prefix) {
|
|
34
|
+
const out = [];
|
|
35
|
+
const record = data && typeof data === 'object' ? data : {};
|
|
36
|
+
const byName = new Map((contract ?? []).map((field) => [field.name, field]));
|
|
37
|
+
for (const raw of fields ?? []) {
|
|
38
|
+
const field = raw;
|
|
39
|
+
if (field.admin?.hidden || field.type === 'ui' || field.type === 'checkbox')
|
|
40
|
+
continue;
|
|
41
|
+
// Containers with no name keep their fields at this level.
|
|
42
|
+
if (!field.name) {
|
|
43
|
+
if (field.type === 'tabs') {
|
|
44
|
+
for (const tab of field.tabs ?? []) {
|
|
45
|
+
out.push(...(tab.name
|
|
46
|
+
? emptyRequiredFields(tab.fields, undefined, record[tab.name], `${prefix}.${tab.name}`)
|
|
47
|
+
: emptyRequiredFields(tab.fields, contract, record, prefix)));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
out.push(...emptyRequiredFields(field.fields, contract, record, prefix));
|
|
52
|
+
}
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const own = byName.get(field.name);
|
|
56
|
+
const required = field.required === true || own?.required === true;
|
|
57
|
+
const value = record[field.name];
|
|
58
|
+
const path = `${prefix}.${field.name}`;
|
|
59
|
+
if (field.type === 'group') {
|
|
60
|
+
if (!filled(value) && required) {
|
|
61
|
+
out.push(path);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// An empty optional group: only Payload's own `required` inside it.
|
|
65
|
+
const inner = filled(value) ? own?.of : undefined;
|
|
66
|
+
out.push(...emptyRequiredFields(field.fields, inner, value, path));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (field.type === 'array') {
|
|
70
|
+
const rows = Array.isArray(value) ? value : [];
|
|
71
|
+
if (required && !rows.some(filled)) {
|
|
72
|
+
out.push(path);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
rows.forEach((row, index) => {
|
|
76
|
+
const inner = filled(row) ? own?.of : undefined;
|
|
77
|
+
out.push(...emptyRequiredFields(field.fields, inner, row, `${path}[${index}]`));
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// A nested blocks field is its blocks' own business.
|
|
82
|
+
if (field.type === 'blocks')
|
|
83
|
+
continue;
|
|
84
|
+
if (required && !filled(value))
|
|
85
|
+
out.push(path);
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=required-in-blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-in-blocks.js","sourceRoot":"","sources":["../../../../src/publishing/pipeline/steps/required-in-blocks.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forumone/throughline",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-next-c49a98b",
|
|
4
4
|
"description": "Throughline: an editorial platform for Payload CMS. Publishing, approvals, audit, integrations, email and jobs, with every feature reachable over MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"dependencies": {
|
|
175
175
|
"zod": "^3.23.0",
|
|
176
176
|
"zod-to-json-schema": "^3.25.2",
|
|
177
|
-
"@forumone/throughline-design-system": "2.
|
|
177
|
+
"@forumone/throughline-design-system": "2.4.0-next-c49a98b"
|
|
178
178
|
},
|
|
179
179
|
"devDependencies": {
|
|
180
180
|
"@payloadcms/db-sqlite": "^3.83.0",
|
|
@@ -197,9 +197,9 @@
|
|
|
197
197
|
"resend": "^6.1.4",
|
|
198
198
|
"typescript": "^5.6.0",
|
|
199
199
|
"vitest": "^4.1.10",
|
|
200
|
-
"@forumone/throughline-
|
|
201
|
-
"@forumone/throughline-
|
|
202
|
-
"@forumone/throughline-
|
|
200
|
+
"@forumone/throughline-reference-ds": "0.3.24-next-c49a98b",
|
|
201
|
+
"@forumone/throughline-tsconfig": "0.0.1",
|
|
202
|
+
"@forumone/throughline-eslint-config": "0.0.1"
|
|
203
203
|
},
|
|
204
204
|
"scripts": {
|
|
205
205
|
"build": "tsc -b",
|