@forumone/throughline 1.3.0 → 1.4.0-next-a7a9a8c
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 +16 -0
- package/dist/content/blocks.d.ts +230 -0
- package/dist/content/blocks.d.ts.map +1 -0
- package/dist/content/blocks.js +295 -0
- package/dist/content/blocks.js.map +1 -0
- package/dist/content/guards.d.ts +45 -0
- package/dist/content/guards.d.ts.map +1 -0
- package/dist/content/guards.js +176 -0
- package/dist/content/guards.js.map +1 -0
- package/dist/content/index.d.ts +8 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +5 -0
- package/dist/content/index.js.map +1 -1
- package/dist/content/plugin.d.ts.map +1 -1
- package/dist/content/plugin.js +14 -3
- package/dist/content/plugin.js.map +1 -1
- package/dist/content/tools.d.ts +19 -1
- package/dist/content/tools.d.ts.map +1 -1
- package/dist/content/tools.js +9 -9
- package/dist/content/tools.js.map +1 -1
- package/dist/content/validate.d.ts +20 -0
- package/dist/content/validate.d.ts.map +1 -0
- package/dist/content/validate.js +66 -0
- package/dist/content/validate.js.map +1 -0
- package/dist/content/write.d.ts +119 -0
- package/dist/content/write.d.ts.map +1 -0
- package/dist/content/write.js +353 -0
- package/dist/content/write.js.map +1 -0
- package/dist/migrate/exports.json +28 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @forumone/throughline
|
|
2
2
|
|
|
3
|
+
## 1.4.0-next-a7a9a8c
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a7a9a8c: Adds `insert_block`, `update_block`, `move_block` and `remove_block` to the content tools. They change one block of a draft's blocks field, either `layout` or a field inside a group such as a case study's `approach.blocks`, without resending the layout. A new or changed block is checked against the blocks the field offers and against its own field validation, which a draft save would otherwise skip. The field is then checked against the composition rules before saving, with the same lock check and audit record as `update_draft`.
|
|
8
|
+
|
|
9
|
+
**Upgrading: a migration.** The key collection gains four checkbox columns. Run `migrate:create` and apply it before deploying.
|
|
10
|
+
|
|
11
|
+
- 7f42a5d: Adds `create_draft` and `update_draft` to the content tools. Both write drafts only and refuse `_status`, publishing dates, the approval policy and any field off the site's allow-list. They refuse a document someone has open in the admin, naming the person (even when it's the key's own person, whose tab would autosave over the change). They also refuse a block the field doesn't offer, a layout that breaks the composition rules, and a slug that's taken, including one held in the trash. Each write is recorded in the audit log with the caller's `_meta`.
|
|
12
|
+
|
|
13
|
+
**Upgrading: a migration.** The key collection gains two checkbox columns, one per new tool. Run `migrate:create` and apply it before deploying.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- @forumone/throughline-design-system@1.4.0-next-a7a9a8c
|
|
18
|
+
|
|
3
19
|
## 1.3.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Field } from 'payload';
|
|
3
|
+
import type { McpToolDefinition } from '../plugin-contract/index.js';
|
|
4
|
+
import type { McpToolDescriptor } from '../mcp/collector.js';
|
|
5
|
+
import { type ContentWriteDeps } from './write.js';
|
|
6
|
+
export declare const CONTENT_BLOCK_TOOLS: {
|
|
7
|
+
readonly insertBlock: {
|
|
8
|
+
readonly name: "insert_block";
|
|
9
|
+
readonly description: "Adds one block to a blocks field of a draft — `layout`, or a field inside a group such as `approach.blocks` — at the end, at the start, or after a given block. The block is { blockType, ...its fields } as get_contract describes it, and is checked against the blocks the field offers, its own validation and the composition rules before anything is saved. Returns the new block's id.";
|
|
10
|
+
};
|
|
11
|
+
readonly updateBlock: {
|
|
12
|
+
readonly name: "update_block";
|
|
13
|
+
readonly description: "Changes fields of one block in a draft, by the block's id from get_document. A group inside the block is merged; an array is replaced. The block type cannot change: remove it and insert another.";
|
|
14
|
+
};
|
|
15
|
+
readonly moveBlock: {
|
|
16
|
+
readonly name: "move_block";
|
|
17
|
+
readonly description: "Moves one block within its blocks field: to the start, to the end, or after another block. Checked against the composition rules, which care about order.";
|
|
18
|
+
};
|
|
19
|
+
readonly removeBlock: {
|
|
20
|
+
readonly name: "remove_block";
|
|
21
|
+
readonly description: "Removes one block from a draft's blocks field, by its id. Checked against the composition rules, since a block may be another's required sibling.";
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export declare const CONTENT_BLOCK_TOOL_DESCRIPTORS: readonly McpToolDescriptor[];
|
|
25
|
+
type BlocksField = Extract<Field, {
|
|
26
|
+
type: 'blocks';
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Every blocks field an author may change, by path: a top-level one by its
|
|
30
|
+
* name, and one inside an allow-listed group as `group.field`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function blockFieldPaths(fields: readonly Field[]): Map<string, BlocksField>;
|
|
33
|
+
/** Block ids Payload would accept: 24 hex characters, as its own are. */
|
|
34
|
+
export declare function newBlockId(): string;
|
|
35
|
+
declare const insertInput: z.ZodObject<{
|
|
36
|
+
after: z.ZodOptional<z.ZodString>;
|
|
37
|
+
position: z.ZodOptional<z.ZodEnum<["start", "end"]>>;
|
|
38
|
+
block: z.ZodObject<{
|
|
39
|
+
blockType: z.ZodString;
|
|
40
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
41
|
+
blockType: z.ZodString;
|
|
42
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
43
|
+
blockType: z.ZodString;
|
|
44
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
45
|
+
collection: z.ZodString;
|
|
46
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
47
|
+
field: z.ZodString;
|
|
48
|
+
} & {
|
|
49
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
userPrompt: z.ZodOptional<z.ZodString>;
|
|
51
|
+
reasoning: z.ZodOptional<z.ZodString>;
|
|
52
|
+
changesSummary: z.ZodOptional<z.ZodString>;
|
|
53
|
+
}, "strip", z.ZodTypeAny, {
|
|
54
|
+
reasoning?: string | undefined;
|
|
55
|
+
changesSummary?: string | undefined;
|
|
56
|
+
userPrompt?: string | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
reasoning?: string | undefined;
|
|
59
|
+
changesSummary?: string | undefined;
|
|
60
|
+
userPrompt?: string | undefined;
|
|
61
|
+
}>>;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
collection: string;
|
|
64
|
+
block: {
|
|
65
|
+
blockType: string;
|
|
66
|
+
} & {
|
|
67
|
+
[k: string]: unknown;
|
|
68
|
+
};
|
|
69
|
+
id: string | number;
|
|
70
|
+
field: string;
|
|
71
|
+
position?: "start" | "end" | undefined;
|
|
72
|
+
_meta?: {
|
|
73
|
+
reasoning?: string | undefined;
|
|
74
|
+
changesSummary?: string | undefined;
|
|
75
|
+
userPrompt?: string | undefined;
|
|
76
|
+
} | undefined;
|
|
77
|
+
after?: string | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
collection: string;
|
|
80
|
+
block: {
|
|
81
|
+
blockType: string;
|
|
82
|
+
} & {
|
|
83
|
+
[k: string]: unknown;
|
|
84
|
+
};
|
|
85
|
+
id: string | number;
|
|
86
|
+
field: string;
|
|
87
|
+
position?: "start" | "end" | undefined;
|
|
88
|
+
_meta?: {
|
|
89
|
+
reasoning?: string | undefined;
|
|
90
|
+
changesSummary?: string | undefined;
|
|
91
|
+
userPrompt?: string | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
after?: string | undefined;
|
|
94
|
+
}>;
|
|
95
|
+
declare const updateInput: z.ZodObject<{
|
|
96
|
+
blockId: z.ZodString;
|
|
97
|
+
patch: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
98
|
+
collection: z.ZodString;
|
|
99
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
100
|
+
field: z.ZodString;
|
|
101
|
+
} & {
|
|
102
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
103
|
+
userPrompt: z.ZodOptional<z.ZodString>;
|
|
104
|
+
reasoning: z.ZodOptional<z.ZodString>;
|
|
105
|
+
changesSummary: z.ZodOptional<z.ZodString>;
|
|
106
|
+
}, "strip", z.ZodTypeAny, {
|
|
107
|
+
reasoning?: string | undefined;
|
|
108
|
+
changesSummary?: string | undefined;
|
|
109
|
+
userPrompt?: string | undefined;
|
|
110
|
+
}, {
|
|
111
|
+
reasoning?: string | undefined;
|
|
112
|
+
changesSummary?: string | undefined;
|
|
113
|
+
userPrompt?: string | undefined;
|
|
114
|
+
}>>;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
collection: string;
|
|
117
|
+
id: string | number;
|
|
118
|
+
patch: Record<string, unknown>;
|
|
119
|
+
field: string;
|
|
120
|
+
blockId: string;
|
|
121
|
+
_meta?: {
|
|
122
|
+
reasoning?: string | undefined;
|
|
123
|
+
changesSummary?: string | undefined;
|
|
124
|
+
userPrompt?: string | undefined;
|
|
125
|
+
} | undefined;
|
|
126
|
+
}, {
|
|
127
|
+
collection: string;
|
|
128
|
+
id: string | number;
|
|
129
|
+
patch: Record<string, unknown>;
|
|
130
|
+
field: string;
|
|
131
|
+
blockId: string;
|
|
132
|
+
_meta?: {
|
|
133
|
+
reasoning?: string | undefined;
|
|
134
|
+
changesSummary?: string | undefined;
|
|
135
|
+
userPrompt?: string | undefined;
|
|
136
|
+
} | undefined;
|
|
137
|
+
}>;
|
|
138
|
+
declare const moveInput: z.ZodObject<{
|
|
139
|
+
after: z.ZodOptional<z.ZodString>;
|
|
140
|
+
position: z.ZodOptional<z.ZodEnum<["start", "end"]>>;
|
|
141
|
+
blockId: z.ZodString;
|
|
142
|
+
collection: z.ZodString;
|
|
143
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
144
|
+
field: z.ZodString;
|
|
145
|
+
} & {
|
|
146
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
147
|
+
userPrompt: z.ZodOptional<z.ZodString>;
|
|
148
|
+
reasoning: z.ZodOptional<z.ZodString>;
|
|
149
|
+
changesSummary: z.ZodOptional<z.ZodString>;
|
|
150
|
+
}, "strip", z.ZodTypeAny, {
|
|
151
|
+
reasoning?: string | undefined;
|
|
152
|
+
changesSummary?: string | undefined;
|
|
153
|
+
userPrompt?: string | undefined;
|
|
154
|
+
}, {
|
|
155
|
+
reasoning?: string | undefined;
|
|
156
|
+
changesSummary?: string | undefined;
|
|
157
|
+
userPrompt?: string | undefined;
|
|
158
|
+
}>>;
|
|
159
|
+
}, "strip", z.ZodTypeAny, {
|
|
160
|
+
collection: string;
|
|
161
|
+
id: string | number;
|
|
162
|
+
field: string;
|
|
163
|
+
blockId: string;
|
|
164
|
+
position?: "start" | "end" | undefined;
|
|
165
|
+
_meta?: {
|
|
166
|
+
reasoning?: string | undefined;
|
|
167
|
+
changesSummary?: string | undefined;
|
|
168
|
+
userPrompt?: string | undefined;
|
|
169
|
+
} | undefined;
|
|
170
|
+
after?: string | undefined;
|
|
171
|
+
}, {
|
|
172
|
+
collection: string;
|
|
173
|
+
id: string | number;
|
|
174
|
+
field: string;
|
|
175
|
+
blockId: string;
|
|
176
|
+
position?: "start" | "end" | undefined;
|
|
177
|
+
_meta?: {
|
|
178
|
+
reasoning?: string | undefined;
|
|
179
|
+
changesSummary?: string | undefined;
|
|
180
|
+
userPrompt?: string | undefined;
|
|
181
|
+
} | undefined;
|
|
182
|
+
after?: string | undefined;
|
|
183
|
+
}>;
|
|
184
|
+
declare const removeInput: z.ZodObject<{
|
|
185
|
+
blockId: z.ZodString;
|
|
186
|
+
collection: z.ZodString;
|
|
187
|
+
id: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
188
|
+
field: z.ZodString;
|
|
189
|
+
} & {
|
|
190
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
191
|
+
userPrompt: z.ZodOptional<z.ZodString>;
|
|
192
|
+
reasoning: z.ZodOptional<z.ZodString>;
|
|
193
|
+
changesSummary: z.ZodOptional<z.ZodString>;
|
|
194
|
+
}, "strip", z.ZodTypeAny, {
|
|
195
|
+
reasoning?: string | undefined;
|
|
196
|
+
changesSummary?: string | undefined;
|
|
197
|
+
userPrompt?: string | undefined;
|
|
198
|
+
}, {
|
|
199
|
+
reasoning?: string | undefined;
|
|
200
|
+
changesSummary?: string | undefined;
|
|
201
|
+
userPrompt?: string | undefined;
|
|
202
|
+
}>>;
|
|
203
|
+
}, "strip", z.ZodTypeAny, {
|
|
204
|
+
collection: string;
|
|
205
|
+
id: string | number;
|
|
206
|
+
field: string;
|
|
207
|
+
blockId: string;
|
|
208
|
+
_meta?: {
|
|
209
|
+
reasoning?: string | undefined;
|
|
210
|
+
changesSummary?: string | undefined;
|
|
211
|
+
userPrompt?: string | undefined;
|
|
212
|
+
} | undefined;
|
|
213
|
+
}, {
|
|
214
|
+
collection: string;
|
|
215
|
+
id: string | number;
|
|
216
|
+
field: string;
|
|
217
|
+
blockId: string;
|
|
218
|
+
_meta?: {
|
|
219
|
+
reasoning?: string | undefined;
|
|
220
|
+
changesSummary?: string | undefined;
|
|
221
|
+
userPrompt?: string | undefined;
|
|
222
|
+
} | undefined;
|
|
223
|
+
}>;
|
|
224
|
+
export declare function createInsertBlockTool(deps: ContentWriteDeps): McpToolDefinition<typeof insertInput>;
|
|
225
|
+
export declare function createUpdateBlockTool(deps: ContentWriteDeps): McpToolDefinition<typeof updateInput>;
|
|
226
|
+
export declare function createMoveBlockTool(deps: ContentWriteDeps): McpToolDefinition<typeof moveInput>;
|
|
227
|
+
export declare function createRemoveBlockTool(deps: ContentWriteDeps): McpToolDefinition<typeof removeInput>;
|
|
228
|
+
export declare function createContentBlockTools(deps: ContentWriteDeps): McpToolDefinition[];
|
|
229
|
+
export {};
|
|
230
|
+
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/content/blocks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAyB,KAAK,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAY5D,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAe3E,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;CAqBsB,CAAA;AAEtD,eAAO,MAAM,8BAA8B,EAAE,SAAS,iBAAiB,EACnC,CAAA;AAEpC,KAAK,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAA;AAErD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAWlF;AAqBD,yEAAyE;AACzE,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAyBD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOf,CAAA;AACF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIf,CAAA;AACF,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIb,CAAA;AACF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGf,CAAA;AAmHF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAmBnG;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,WAAW,CAAC,CA2BnG;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,SAAS,CAAC,CAqB/F;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAgBnG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,CAOnF"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { withMeta } from '../mcp/meta.js';
|
|
4
|
+
import { writableFields } from './describe.js';
|
|
5
|
+
import { compositionErrors, disallowedBlocks, mergePatch } from './guards.js';
|
|
6
|
+
import { blockRegistry, defaultCanUse, refusal, requestAs, unknownCollection, } from './tools.js';
|
|
7
|
+
import { validateBlock } from './validate.js';
|
|
8
|
+
import { openForWrite, saveDraft } from './write.js';
|
|
9
|
+
/*
|
|
10
|
+
One block at a time: insert, change, move or remove a block in a blocks field,
|
|
11
|
+
without resending the whole layout.
|
|
12
|
+
|
|
13
|
+
A blocks field is named by its path: `layout`, or `approach.blocks` for one
|
|
14
|
+
inside a group, as a case study's buckets are. Each operation reads the current
|
|
15
|
+
draft, makes its one change, and checks the result before saving it: a new
|
|
16
|
+
block against the blocks the field offers, a new or changed block against its
|
|
17
|
+
own validation (which a draft save would skip), and the field as a whole
|
|
18
|
+
against the composition rules. Then it saves the draft as `update_draft` does —
|
|
19
|
+
the same lock check, the same audit.
|
|
20
|
+
*/
|
|
21
|
+
export const CONTENT_BLOCK_TOOLS = {
|
|
22
|
+
insertBlock: {
|
|
23
|
+
name: 'insert_block',
|
|
24
|
+
description: 'Adds one block to a blocks field of a draft — `layout`, or a field inside a group such as `approach.blocks` — at the end, at the start, or after a given block. The block is { blockType, ...its fields } as get_contract describes it, and is checked against the blocks the field offers, its own validation and the composition rules before anything is saved. Returns the new block\'s id.',
|
|
25
|
+
},
|
|
26
|
+
updateBlock: {
|
|
27
|
+
name: 'update_block',
|
|
28
|
+
description: 'Changes fields of one block in a draft, by the block\'s id from get_document. A group inside the block is merged; an array is replaced. The block type cannot change: remove it and insert another.',
|
|
29
|
+
},
|
|
30
|
+
moveBlock: {
|
|
31
|
+
name: 'move_block',
|
|
32
|
+
description: 'Moves one block within its blocks field: to the start, to the end, or after another block. Checked against the composition rules, which care about order.',
|
|
33
|
+
},
|
|
34
|
+
removeBlock: {
|
|
35
|
+
name: 'remove_block',
|
|
36
|
+
description: 'Removes one block from a draft\'s blocks field, by its id. Checked against the composition rules, since a block may be another\'s required sibling.',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export const CONTENT_BLOCK_TOOL_DESCRIPTORS = Object.values(CONTENT_BLOCK_TOOLS);
|
|
40
|
+
/**
|
|
41
|
+
* Every blocks field an author may change, by path: a top-level one by its
|
|
42
|
+
* name, and one inside an allow-listed group as `group.field`.
|
|
43
|
+
*/
|
|
44
|
+
export function blockFieldPaths(fields) {
|
|
45
|
+
const out = new Map();
|
|
46
|
+
for (const field of fields) {
|
|
47
|
+
if (field.type === 'blocks')
|
|
48
|
+
out.set(field.name, field);
|
|
49
|
+
if (field.type === 'group' && 'name' in field && typeof field.name === 'string') {
|
|
50
|
+
for (const inner of field.fields) {
|
|
51
|
+
if (inner.type === 'blocks')
|
|
52
|
+
out.set(`${field.name}.${inner.name}`, inner);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
function rowsAt(doc, path) {
|
|
59
|
+
const [head, tail] = path.split('.');
|
|
60
|
+
const container = tail ? doc[head] : doc;
|
|
61
|
+
const rows = container?.[tail ?? head];
|
|
62
|
+
return Array.isArray(rows) ? rows : [];
|
|
63
|
+
}
|
|
64
|
+
/** The top-level change that puts `rows` at `path`, keeping the rest of a group. */
|
|
65
|
+
function dataFor(current, path, rows) {
|
|
66
|
+
const [head, tail] = path.split('.');
|
|
67
|
+
if (!tail)
|
|
68
|
+
return { [head]: rows };
|
|
69
|
+
const group = current[head] ?? {};
|
|
70
|
+
return { [head]: { ...group, [tail]: rows } };
|
|
71
|
+
}
|
|
72
|
+
/** Block ids Payload would accept: 24 hex characters, as its own are. */
|
|
73
|
+
export function newBlockId() {
|
|
74
|
+
return randomBytes(12).toString('hex');
|
|
75
|
+
}
|
|
76
|
+
function blockConfig(field, slug, registry) {
|
|
77
|
+
return (field.blocks?.find((block) => block.slug === slug) ??
|
|
78
|
+
field.blockReferences
|
|
79
|
+
?.map((ref) => (typeof ref === 'string' ? registry.get(ref) : ref))
|
|
80
|
+
.find((block) => block?.slug === slug));
|
|
81
|
+
}
|
|
82
|
+
const target = {
|
|
83
|
+
collection: z.string().describe('The content type\'s slug, e.g. "pages".'),
|
|
84
|
+
id: z.union([z.string(), z.number()]).describe('The document id.'),
|
|
85
|
+
field: z.string().describe('The blocks field: "layout", or e.g. "approach.blocks".'),
|
|
86
|
+
};
|
|
87
|
+
const placement = {
|
|
88
|
+
after: z.string().optional().describe('The id of the block to put it after.'),
|
|
89
|
+
position: z.enum(['start', 'end']).optional().describe('Where, when not after a block. Default: end.'),
|
|
90
|
+
};
|
|
91
|
+
const insertInput = withMeta({
|
|
92
|
+
...target,
|
|
93
|
+
block: z
|
|
94
|
+
.object({ blockType: z.string() })
|
|
95
|
+
.passthrough()
|
|
96
|
+
.describe('The block: { blockType, ...fields }.'),
|
|
97
|
+
...placement,
|
|
98
|
+
});
|
|
99
|
+
const updateInput = withMeta({
|
|
100
|
+
...target,
|
|
101
|
+
blockId: z.string().describe('The block\'s id, from get_document.'),
|
|
102
|
+
patch: z.record(z.string(), z.unknown()).describe('The block fields to change.'),
|
|
103
|
+
});
|
|
104
|
+
const moveInput = withMeta({
|
|
105
|
+
...target,
|
|
106
|
+
blockId: z.string().describe('The block\'s id, from get_document.'),
|
|
107
|
+
...placement,
|
|
108
|
+
});
|
|
109
|
+
const removeInput = withMeta({
|
|
110
|
+
...target,
|
|
111
|
+
blockId: z.string().describe('The block\'s id, from get_document.'),
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* What every block tool does around its one change: who may, which field,
|
|
115
|
+
* read the draft, check the result, save it.
|
|
116
|
+
*/
|
|
117
|
+
async function operate(deps, ctx, input, tool, change) {
|
|
118
|
+
const refused = refusal(ctx, deps.canUse ?? defaultCanUse);
|
|
119
|
+
if (refused)
|
|
120
|
+
return refused;
|
|
121
|
+
const options = deps.collections[input.collection];
|
|
122
|
+
const config = deps.payload.collections[input.collection]?.config;
|
|
123
|
+
if (!options || !config)
|
|
124
|
+
return unknownCollection(deps, input.collection);
|
|
125
|
+
const fields = blockFieldPaths(writableFields(config.fields, options.fields));
|
|
126
|
+
const field = fields.get(input.field);
|
|
127
|
+
if (!field) {
|
|
128
|
+
return {
|
|
129
|
+
error: `"${input.field}" is not a blocks field you can change in ${input.collection}. Blocks fields: ${[...fields.keys()].join(', ') || 'none'}.`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const opened = await openForWrite(deps, ctx, input.collection, input.id);
|
|
133
|
+
if ('error' in opened)
|
|
134
|
+
return opened;
|
|
135
|
+
const { current } = opened;
|
|
136
|
+
const before = rowsAt(current, input.field);
|
|
137
|
+
const changed = await change(before, field);
|
|
138
|
+
if ('error' in changed)
|
|
139
|
+
return changed;
|
|
140
|
+
const req = await requestAs(deps.payload, ctx);
|
|
141
|
+
const registry = blockRegistry(deps.payload);
|
|
142
|
+
if (changed.added) {
|
|
143
|
+
const disallowed = await disallowedBlocks(field, [changed.added], before, registry, req);
|
|
144
|
+
if (disallowed.length > 0) {
|
|
145
|
+
return {
|
|
146
|
+
error: `${input.field} does not accept ${disallowed.join(', ')}. describe_content_type lists the blocks it does.`,
|
|
147
|
+
disallowed,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const config = blockConfig(field, String(changed.added['blockType']), registry);
|
|
151
|
+
const problems = config
|
|
152
|
+
? await validateBlock(config.fields, changed.added, {
|
|
153
|
+
data: { ...current, ...dataFor(current, input.field, changed.rows) },
|
|
154
|
+
req,
|
|
155
|
+
collection: input.collection,
|
|
156
|
+
id: input.id,
|
|
157
|
+
})
|
|
158
|
+
: [];
|
|
159
|
+
if (problems.length > 0) {
|
|
160
|
+
return {
|
|
161
|
+
error: `The ${String(changed.added['blockType'])} block is not valid. Nothing was saved.`,
|
|
162
|
+
problems,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const issues = await compositionErrors(deps.payload, changed.rows);
|
|
167
|
+
if (issues && issues.length > 0) {
|
|
168
|
+
return {
|
|
169
|
+
error: `${input.field} would break ${issues.length} composition rule${issues.length === 1 ? '' : 's'}. Nothing was saved.`,
|
|
170
|
+
issues,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const saved = await saveDraft(deps, ctx, {
|
|
174
|
+
collection: input.collection,
|
|
175
|
+
id: input.id,
|
|
176
|
+
data: dataFor(current, input.field, changed.rows),
|
|
177
|
+
tool,
|
|
178
|
+
changed: [input.field],
|
|
179
|
+
meta: input._meta ?? { changesSummary: changed.summary },
|
|
180
|
+
});
|
|
181
|
+
return 'error' in saved ? saved : { ...saved, field: input.field, blockId: changed.blockId };
|
|
182
|
+
}
|
|
183
|
+
function indexOf(rows, blockId) {
|
|
184
|
+
return rows.findIndex((row) => row['id'] === blockId);
|
|
185
|
+
}
|
|
186
|
+
function notFound(field, blockId) {
|
|
187
|
+
return { error: `There is no block "${blockId}" in ${field}. get_document lists the blocks and their ids.` };
|
|
188
|
+
}
|
|
189
|
+
/** Where a block goes: after another, or at an end. `-1` when `after` names no block. */
|
|
190
|
+
function placeAt(rows, placement) {
|
|
191
|
+
if (placement.after !== undefined) {
|
|
192
|
+
const at = indexOf(rows, placement.after);
|
|
193
|
+
return at === -1 ? -1 : at + 1;
|
|
194
|
+
}
|
|
195
|
+
return placement.position === 'start' ? 0 : rows.length;
|
|
196
|
+
}
|
|
197
|
+
/* ------------------------------------------------------------------------ */
|
|
198
|
+
export function createInsertBlockTool(deps) {
|
|
199
|
+
return {
|
|
200
|
+
...CONTENT_BLOCK_TOOLS.insertBlock,
|
|
201
|
+
inputSchema: insertInput,
|
|
202
|
+
requiredScope: 'content.write',
|
|
203
|
+
handler: (input, ctx) => operate(deps, ctx, input, CONTENT_BLOCK_TOOLS.insertBlock.name, async (rows) => {
|
|
204
|
+
const at = placeAt(rows, input);
|
|
205
|
+
if (at === -1)
|
|
206
|
+
return notFound(input.field, input.after);
|
|
207
|
+
const { id: _ignored, ...fields } = input.block;
|
|
208
|
+
const added = { ...fields, id: newBlockId() };
|
|
209
|
+
return {
|
|
210
|
+
rows: [...rows.slice(0, at), added, ...rows.slice(at)],
|
|
211
|
+
added,
|
|
212
|
+
blockId: added.id,
|
|
213
|
+
summary: `Inserted a ${input.block.blockType} block into ${input.field}.`,
|
|
214
|
+
};
|
|
215
|
+
}),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
export function createUpdateBlockTool(deps) {
|
|
219
|
+
return {
|
|
220
|
+
...CONTENT_BLOCK_TOOLS.updateBlock,
|
|
221
|
+
inputSchema: updateInput,
|
|
222
|
+
requiredScope: 'content.write',
|
|
223
|
+
handler: (input, ctx) => operate(deps, ctx, input, CONTENT_BLOCK_TOOLS.updateBlock.name, async (rows, field) => {
|
|
224
|
+
const at = indexOf(rows, input.blockId);
|
|
225
|
+
if (at === -1)
|
|
226
|
+
return notFound(input.field, input.blockId);
|
|
227
|
+
const row = rows[at];
|
|
228
|
+
if ('blockType' in input.patch && input.patch['blockType'] !== row['blockType']) {
|
|
229
|
+
return { error: 'A block\'s type cannot change. Remove it and insert another.' };
|
|
230
|
+
}
|
|
231
|
+
if ('id' in input.patch && input.patch['id'] !== row['id']) {
|
|
232
|
+
return { error: 'A block\'s id cannot change.' };
|
|
233
|
+
}
|
|
234
|
+
const config = blockConfig(field, String(row['blockType']), blockRegistry(deps.payload));
|
|
235
|
+
const updated = { ...row, ...mergePatch(row, input.patch, config?.fields ?? []) };
|
|
236
|
+
return {
|
|
237
|
+
rows: rows.map((r, i) => (i === at ? updated : r)),
|
|
238
|
+
// Checked whole, like a new one: a change can make it invalid.
|
|
239
|
+
added: updated,
|
|
240
|
+
blockId: input.blockId,
|
|
241
|
+
summary: `Changed ${Object.keys(input.patch).join(', ')} on a ${String(row['blockType'])} block in ${input.field}.`,
|
|
242
|
+
};
|
|
243
|
+
}),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
export function createMoveBlockTool(deps) {
|
|
247
|
+
return {
|
|
248
|
+
...CONTENT_BLOCK_TOOLS.moveBlock,
|
|
249
|
+
inputSchema: moveInput,
|
|
250
|
+
requiredScope: 'content.write',
|
|
251
|
+
handler: (input, ctx) => operate(deps, ctx, input, CONTENT_BLOCK_TOOLS.moveBlock.name, async (rows) => {
|
|
252
|
+
const from = indexOf(rows, input.blockId);
|
|
253
|
+
if (from === -1)
|
|
254
|
+
return notFound(input.field, input.blockId);
|
|
255
|
+
if (input.after === input.blockId)
|
|
256
|
+
return { error: 'A block cannot go after itself.' };
|
|
257
|
+
const moving = rows[from];
|
|
258
|
+
const rest = rows.filter((_, i) => i !== from);
|
|
259
|
+
const at = placeAt(rest, input);
|
|
260
|
+
if (at === -1)
|
|
261
|
+
return notFound(input.field, input.after);
|
|
262
|
+
return {
|
|
263
|
+
rows: [...rest.slice(0, at), moving, ...rest.slice(at)],
|
|
264
|
+
blockId: input.blockId,
|
|
265
|
+
summary: `Moved a ${String(moving['blockType'])} block in ${input.field}.`,
|
|
266
|
+
};
|
|
267
|
+
}),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export function createRemoveBlockTool(deps) {
|
|
271
|
+
return {
|
|
272
|
+
...CONTENT_BLOCK_TOOLS.removeBlock,
|
|
273
|
+
inputSchema: removeInput,
|
|
274
|
+
requiredScope: 'content.write',
|
|
275
|
+
handler: (input, ctx) => operate(deps, ctx, input, CONTENT_BLOCK_TOOLS.removeBlock.name, async (rows) => {
|
|
276
|
+
const at = indexOf(rows, input.blockId);
|
|
277
|
+
if (at === -1)
|
|
278
|
+
return notFound(input.field, input.blockId);
|
|
279
|
+
return {
|
|
280
|
+
rows: rows.filter((_, i) => i !== at),
|
|
281
|
+
blockId: input.blockId,
|
|
282
|
+
summary: `Removed a ${String(rows[at]['blockType'])} block from ${input.field}.`,
|
|
283
|
+
};
|
|
284
|
+
}),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
export function createContentBlockTools(deps) {
|
|
288
|
+
return [
|
|
289
|
+
createInsertBlockTool(deps),
|
|
290
|
+
createUpdateBlockTool(deps),
|
|
291
|
+
createMoveBlockTool(deps),
|
|
292
|
+
createRemoveBlockTool(deps),
|
|
293
|
+
];
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../src/content/blocks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Block, Field, Payload, PayloadRequest } from 'payload';
|
|
2
|
+
export interface RefusedField {
|
|
3
|
+
field: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
6
|
+
/** Every top-level key in `data` that is not on the allow-list, with why. */
|
|
7
|
+
export declare function refusedFields(data: Record<string, unknown>, allowed: readonly string[]): RefusedField[];
|
|
8
|
+
export declare function mergePatch(current: Record<string, unknown>, patch: Record<string, unknown>, fields: readonly Field[]): Record<string, unknown>;
|
|
9
|
+
export interface LockHolder {
|
|
10
|
+
/** Who has it open: their name, else their email, else their id. */
|
|
11
|
+
user: string;
|
|
12
|
+
/** Whether that is the person the key belongs to. */
|
|
13
|
+
self: boolean;
|
|
14
|
+
/** When the lock was last refreshed. */
|
|
15
|
+
since: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function lockHolder(payload: Payload, collection: string, id: number | string, self: unknown): Promise<LockHolder | undefined>;
|
|
18
|
+
export declare function lockRefusal(collection: string, id: number | string, lock: LockHolder): {
|
|
19
|
+
error: string;
|
|
20
|
+
lockedBy: string;
|
|
21
|
+
since: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The blocks in `rows` that `field` would not let an editor add, asked the way
|
|
25
|
+
* the picker asks: with the document's current rows as sibling data, so a block
|
|
26
|
+
* a document already holds stays allowed (it is how `filterOptions` keeps old
|
|
27
|
+
* documents saveable).
|
|
28
|
+
*/
|
|
29
|
+
export declare function disallowedBlocks(field: Extract<Field, {
|
|
30
|
+
type: 'blocks';
|
|
31
|
+
}>, rows: readonly unknown[], currentRows: readonly unknown[], registry: ReadonlyMap<string, Block>, req: PayloadRequest): Promise<string[]>;
|
|
32
|
+
export interface CompositionIssue {
|
|
33
|
+
rule: string;
|
|
34
|
+
message: string;
|
|
35
|
+
/** Which row, when the rule is about one. */
|
|
36
|
+
index?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The composition errors in a blocks field's rows, from the same validator the
|
|
40
|
+
* publish pipeline runs (attached by the components plugin). Warnings do not
|
|
41
|
+
* stop a publish and do not stop a draft. `undefined` when there is no
|
|
42
|
+
* validator, which is a site without the components plugin.
|
|
43
|
+
*/
|
|
44
|
+
export declare function compositionErrors(payload: Payload, rows: readonly unknown[]): Promise<CompositionIssue[] | undefined>;
|
|
45
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/content/guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAkB,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AA8BpF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,YAAY,EAAE,CAUhB;AAQD,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAoBD,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAA;IACb,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;CACd;AAWD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAqCjC;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,UAAU;;;;EAQpF;AAID;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,EACzC,IAAI,EAAE,SAAS,OAAO,EAAE,EACxB,WAAW,EAAE,SAAS,OAAO,EAAE,EAC/B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EACpC,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAQD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,CAmBzC"}
|