@actuate-media/cms-core 0.53.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=collection-introspection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-introspection.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/api/collection-introspection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,129 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { summarizeCollectionFields } from '../../api/collection-introspection.js';
3
+ function byName(fields) {
4
+ return new Map(fields.map((f) => [f.name, f]));
5
+ }
6
+ describe('summarizeCollectionFields (WS-B4 deep introspection)', () => {
7
+ it('returns [] for a missing or non-object field map', () => {
8
+ expect(summarizeCollectionFields(undefined)).toEqual([]);
9
+ expect(summarizeCollectionFields(null)).toEqual([]);
10
+ expect(summarizeCollectionFields([])).toEqual([]);
11
+ expect(summarizeCollectionFields('nope')).toEqual([]);
12
+ });
13
+ it('summarizes scalar fields to { name, type, required }', () => {
14
+ const out = byName(summarizeCollectionFields({
15
+ title: { type: 'text', required: true },
16
+ body: { type: 'richText' },
17
+ }));
18
+ expect(out.get('title')).toEqual({ name: 'title', type: 'text', required: true });
19
+ expect(out.get('body')).toEqual({ name: 'body', type: 'richText', required: false });
20
+ });
21
+ it('surfaces relationTo / hasMany / options when present', () => {
22
+ const out = byName(summarizeCollectionFields({
23
+ author: { type: 'relationship', relationTo: 'team' },
24
+ related: { type: 'relationship', relationTo: ['posts', 'pages'], hasMany: true },
25
+ status: {
26
+ type: 'select',
27
+ options: [
28
+ { label: 'Draft', value: 'draft' },
29
+ { label: 'Live', value: 'live' },
30
+ ],
31
+ },
32
+ }));
33
+ expect(out.get('author')?.relationTo).toBe('team');
34
+ expect(out.get('author')?.hasMany).toBeUndefined();
35
+ expect(out.get('related')?.relationTo).toEqual(['posts', 'pages']);
36
+ expect(out.get('related')?.hasMany).toBe(true);
37
+ expect(out.get('status')?.options).toEqual([
38
+ { label: 'Draft', value: 'draft' },
39
+ { label: 'Live', value: 'live' },
40
+ ]);
41
+ });
42
+ it('recurses into array element subfields and reports row bounds', () => {
43
+ const out = byName(summarizeCollectionFields({
44
+ gallery: {
45
+ type: 'array',
46
+ minRows: 1,
47
+ maxRows: 6,
48
+ fields: {
49
+ image: { type: 'media', required: true },
50
+ caption: { type: 'text' },
51
+ },
52
+ },
53
+ }));
54
+ const gallery = out.get('gallery');
55
+ expect(gallery.type).toBe('array');
56
+ expect(gallery.minRows).toBe(1);
57
+ expect(gallery.maxRows).toBe(6);
58
+ expect(byName(gallery.fields ?? []).get('image')).toEqual({
59
+ name: 'image',
60
+ type: 'media',
61
+ required: true,
62
+ });
63
+ expect(byName(gallery.fields ?? []).get('caption')?.required).toBe(false);
64
+ });
65
+ it('recurses into blocks variants keyed by slug, with labels and subfields', () => {
66
+ const out = byName(summarizeCollectionFields({
67
+ layout: {
68
+ type: 'blocks',
69
+ blocks: [
70
+ {
71
+ slug: 'hero',
72
+ labels: { singular: 'Hero', plural: 'Heroes' },
73
+ fields: { heading: { type: 'text', required: true } },
74
+ },
75
+ {
76
+ slug: 'cta',
77
+ labels: { singular: 'Call To Action', plural: 'CTAs' },
78
+ fields: { url: { type: 'url' }, label: { type: 'text' } },
79
+ },
80
+ ],
81
+ },
82
+ }));
83
+ const layout = out.get('layout');
84
+ expect(layout.type).toBe('blocks');
85
+ expect(layout.blocks).toHaveLength(2);
86
+ const hero = layout.blocks.find((b) => b.slug === 'hero');
87
+ expect(hero.label).toBe('Hero');
88
+ expect(byName(hero.fields).get('heading')).toEqual({
89
+ name: 'heading',
90
+ type: 'text',
91
+ required: true,
92
+ });
93
+ const cta = layout.blocks.find((b) => b.slug === 'cta');
94
+ expect(cta.fields.map((f) => f.name).sort()).toEqual(['label', 'url']);
95
+ });
96
+ it('handles malformed block entries without throwing', () => {
97
+ const out = byName(summarizeCollectionFields({
98
+ layout: {
99
+ type: 'blocks',
100
+ blocks: [null, 'nope', { slug: 'ok', fields: { x: { type: 'text' } } }],
101
+ },
102
+ }));
103
+ const layout = out.get('layout');
104
+ // Only the one well-formed block survives; no label since none provided.
105
+ expect(layout.blocks).toHaveLength(1);
106
+ expect(layout.blocks[0].slug).toBe('ok');
107
+ expect(layout.blocks[0].label).toBeUndefined();
108
+ });
109
+ it('caps recursion depth defensively (no stack blow-up on deep nesting)', () => {
110
+ // Build an array nested far deeper than MAX_DEPTH (5).
111
+ let leaf = { type: 'text' };
112
+ for (let i = 0; i < 12; i++) {
113
+ leaf = { type: 'array', fields: { child: leaf } };
114
+ }
115
+ const out = summarizeCollectionFields({ deep: leaf });
116
+ // Walk down; at some point `fields` stops being populated (the cap),
117
+ // proving we don't recurse forever.
118
+ let node = out[0];
119
+ let levels = 0;
120
+ while (node?.fields && node.fields.length > 0) {
121
+ node = node.fields[0];
122
+ levels++;
123
+ if (levels > 20)
124
+ throw new Error('recursion not capped');
125
+ }
126
+ expect(levels).toBeLessThanOrEqual(6);
127
+ });
128
+ });
129
+ //# sourceMappingURL=collection-introspection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-introspection.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/collection-introspection.test.ts"],"names":[],"mappings":"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"}
@@ -166,22 +166,141 @@ describe('GET /api/cms/collections (PR F discovery endpoint)', () => {
166
166
  // that mustn't ship in the public surface. Keep the contract tight:
167
167
  // every field always carries `name`/`type`/`required`, and may ONLY
168
168
  // additionally carry the relationship-resolver hints (`relationTo`,
169
- // `hasMany`, `options`). Anything else is a leak.
170
- const ALLOWED_KEYS = new Set(['name', 'type', 'required', 'relationTo', 'hasMany', 'options']);
171
- const handler = makeHandler();
169
+ // `hasMany`, `options`) plus the WS-B4 nested-schema keys (`fields`,
170
+ // `minRows`, `maxRows`, `blocks`). Anything else is a leak. The walk is
171
+ // recursive so nested array/blocks subfields are held to the same bar.
172
+ const ALLOWED_FIELD_KEYS = new Set([
173
+ 'name',
174
+ 'type',
175
+ 'required',
176
+ 'relationTo',
177
+ 'hasMany',
178
+ 'options',
179
+ 'fields',
180
+ 'minRows',
181
+ 'maxRows',
182
+ 'blocks',
183
+ ]);
184
+ const ALLOWED_BLOCK_KEYS = new Set(['slug', 'label', 'fields']);
185
+ function assertFieldClean(field) {
186
+ expect(field).toHaveProperty('name');
187
+ expect(field).toHaveProperty('type');
188
+ expect(field).toHaveProperty('required');
189
+ for (const key of Object.keys(field)) {
190
+ expect(ALLOWED_FIELD_KEYS.has(key)).toBe(true);
191
+ }
192
+ if (Array.isArray(field.fields)) {
193
+ for (const sub of field.fields)
194
+ assertFieldClean(sub);
195
+ }
196
+ if (Array.isArray(field.blocks)) {
197
+ for (const block of field.blocks) {
198
+ for (const key of Object.keys(block)) {
199
+ expect(ALLOWED_BLOCK_KEYS.has(key)).toBe(true);
200
+ }
201
+ for (const sub of block.fields ?? []) {
202
+ assertFieldClean(sub);
203
+ }
204
+ }
205
+ }
206
+ }
207
+ // Config exercises array + blocks so the recursive guard actually runs.
208
+ setActuateConfig({
209
+ secret: SECRET,
210
+ collections: {
211
+ landing: {
212
+ slug: 'landing',
213
+ labels: { singular: 'Landing', plural: 'Landing' },
214
+ type: 'page',
215
+ fields: {
216
+ title: { type: 'text', required: true },
217
+ features: {
218
+ type: 'array',
219
+ fields: { heading: { type: 'text' }, icon: { type: 'text' } },
220
+ },
221
+ layout: {
222
+ type: 'blocks',
223
+ blocks: [
224
+ {
225
+ slug: 'hero',
226
+ labels: { singular: 'Hero', plural: 'Heroes' },
227
+ fields: { headline: { type: 'text' } },
228
+ },
229
+ ],
230
+ },
231
+ },
232
+ },
233
+ },
234
+ });
235
+ const handler = handleActuateAPI({ prismaClient: {} });
172
236
  const response = await handler(new Request('https://example.com/api/cms/collections', { method: 'GET' }));
173
237
  const payload = (await response.json());
174
238
  for (const collection of payload.data) {
175
- for (const field of collection.fields) {
176
- expect(field).toHaveProperty('name');
177
- expect(field).toHaveProperty('type');
178
- expect(field).toHaveProperty('required');
179
- for (const key of Object.keys(field)) {
180
- expect(ALLOWED_KEYS.has(key)).toBe(true);
181
- }
182
- }
239
+ for (const field of collection.fields)
240
+ assertFieldClean(field);
183
241
  }
184
242
  });
243
+ it('surfaces array element subfields and blocks variant subfields (WS-B4)', async () => {
244
+ // An agent planning a deep create needs the shape of each array row and
245
+ // each block variant — not just `type: 'array'`. Lock the recursive
246
+ // contract so a refactor can't silently flatten it back to top-level only.
247
+ setActuateConfig({
248
+ secret: SECRET,
249
+ collections: {
250
+ landing: {
251
+ slug: 'landing',
252
+ labels: { singular: 'Landing', plural: 'Landing' },
253
+ type: 'page',
254
+ fields: {
255
+ gallery: {
256
+ type: 'array',
257
+ minRows: 1,
258
+ maxRows: 8,
259
+ fields: {
260
+ image: { type: 'media', required: true },
261
+ caption: { type: 'text' },
262
+ },
263
+ },
264
+ layout: {
265
+ type: 'blocks',
266
+ blocks: [
267
+ {
268
+ slug: 'hero',
269
+ labels: { singular: 'Hero', plural: 'Heroes' },
270
+ fields: { headline: { type: 'text', required: true } },
271
+ },
272
+ {
273
+ slug: 'cta',
274
+ labels: { singular: 'CTA', plural: 'CTAs' },
275
+ fields: { url: { type: 'url' } },
276
+ },
277
+ ],
278
+ },
279
+ },
280
+ },
281
+ },
282
+ });
283
+ const handler = handleActuateAPI({ prismaClient: {} });
284
+ const response = await handler(new Request('https://example.com/api/cms/collections', { method: 'GET' }));
285
+ const payload = (await response.json());
286
+ const landing = payload.data.find((c) => c.slug === 'landing');
287
+ const byField = new Map(landing.fields.map((f) => [f.name, f]));
288
+ const gallery = byField.get('gallery');
289
+ expect(gallery.type).toBe('array');
290
+ expect(gallery.minRows).toBe(1);
291
+ expect(gallery.maxRows).toBe(8);
292
+ const galleryFields = new Map((gallery.fields ?? []).map((f) => [f.name, f]));
293
+ expect(galleryFields.get('image')).toEqual({ name: 'image', type: 'media', required: true });
294
+ expect(galleryFields.get('caption')?.required).toBe(false);
295
+ const layout = byField.get('layout');
296
+ expect(layout.type).toBe('blocks');
297
+ expect(layout.blocks).toHaveLength(2);
298
+ const hero = layout.blocks.find((b) => b.slug === 'hero');
299
+ expect(hero.label).toBe('Hero');
300
+ expect(hero.fields.find((f) => f.name === 'headline')?.required).toBe(true);
301
+ const cta = layout.blocks.find((b) => b.slug === 'cta');
302
+ expect(cta.fields.map((f) => f.name)).toEqual(['url']);
303
+ });
185
304
  it('surfaces relationTo / hasMany / select options for the relationship resolver (WS-C C2)', async () => {
186
305
  // The MCP relationship-resolver tools (get_relationship_fields,
187
306
  // resolve_relationship) depend on the discovery endpoint exposing where a
@@ -1 +1 @@
1
- {"version":3,"file":"collections-discovery.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/collections-discovery.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collections-discovery.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/collections-discovery.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Field-schema introspection for the `GET /api/cms/collections` discovery
3
+ * endpoint (roadmap WS-B4).
4
+ *
5
+ * Reduces a collection's field map to a compact, **recursive** summary an
6
+ * agent can plan a create/update against — including `array` element
7
+ * subfields and `blocks` variant subfields — WITHOUT shipping the full
8
+ * runtime validators, hooks, or access functions (those can carry closure
9
+ * state and must never reach the unauthenticated discovery surface).
10
+ *
11
+ * The shape is intentionally additive over the flat `{ name, type, required }`
12
+ * summary: relationship targets, select options, and nested subfield schemas
13
+ * appear only when present, so existing consumers keep working.
14
+ */
15
+ /** A single field reduced to agent-plannable metadata. */
16
+ export interface FieldSummary {
17
+ name: string;
18
+ type: string;
19
+ required: boolean;
20
+ /** Relationship target collection(s) — for slug→id resolution. */
21
+ relationTo?: string | string[];
22
+ /** True for multi-value relationship / select fields. */
23
+ hasMany?: boolean;
24
+ /** `select` options exactly as the config provides them (label/value objects or bare strings). */
25
+ options?: unknown[];
26
+ /** `array` element subfields (recursive). */
27
+ fields?: FieldSummary[];
28
+ /** `array` row bounds, when configured. */
29
+ minRows?: number;
30
+ maxRows?: number;
31
+ /** `blocks` variants, each with its own subfield schema (recursive). */
32
+ blocks?: BlockSummary[];
33
+ }
34
+ /** A `blocks` field variant reduced to its slug, label, and subfield schema. */
35
+ export interface BlockSummary {
36
+ slug: string;
37
+ label?: string;
38
+ fields: FieldSummary[];
39
+ }
40
+ /**
41
+ * Summarize a collection's `fields` map into the recursive {@link FieldSummary}
42
+ * array used by the discovery endpoint. Safe on any input — a non-object map
43
+ * (or a missing one) yields `[]`.
44
+ */
45
+ export declare function summarizeCollectionFields(fields: unknown, depth?: number): FieldSummary[];
46
+ //# sourceMappingURL=collection-introspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-introspection.d.ts","sourceRoot":"","sources":["../../src/api/collection-introspection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC9B,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kGAAkG;IAClG,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,EAAE,CAAA;IACvB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAA;CACxB;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,EAAE,CAAA;CACvB;AA2BD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,YAAY,EAAE,CAGpF"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Field-schema introspection for the `GET /api/cms/collections` discovery
3
+ * endpoint (roadmap WS-B4).
4
+ *
5
+ * Reduces a collection's field map to a compact, **recursive** summary an
6
+ * agent can plan a create/update against — including `array` element
7
+ * subfields and `blocks` variant subfields — WITHOUT shipping the full
8
+ * runtime validators, hooks, or access functions (those can carry closure
9
+ * state and must never reach the unauthenticated discovery surface).
10
+ *
11
+ * The shape is intentionally additive over the flat `{ name, type, required }`
12
+ * summary: relationship targets, select options, and nested subfield schemas
13
+ * appear only when present, so existing consumers keep working.
14
+ */
15
+ /**
16
+ * Defensive recursion cap. Configs are static and authored by the developer,
17
+ * so cycles are not expected, but a malformed/self-referential config must
18
+ * never be able to blow the stack or balloon the response. Five levels is far
19
+ * deeper than any realistic page/array/blocks nesting.
20
+ */
21
+ const MAX_DEPTH = 5;
22
+ function isFieldMap(value) {
23
+ return !!value && typeof value === 'object' && !Array.isArray(value);
24
+ }
25
+ /**
26
+ * Summarize a collection's `fields` map into the recursive {@link FieldSummary}
27
+ * array used by the discovery endpoint. Safe on any input — a non-object map
28
+ * (or a missing one) yields `[]`.
29
+ */
30
+ export function summarizeCollectionFields(fields, depth = 0) {
31
+ if (!isFieldMap(fields))
32
+ return [];
33
+ return Object.entries(fields).map(([name, fieldDef]) => summarizeField(name, fieldDef, depth));
34
+ }
35
+ function summarizeField(name, fieldDef, depth) {
36
+ const summary = {
37
+ name,
38
+ type: typeof fieldDef?.type === 'string' ? fieldDef.type : 'unknown',
39
+ required: fieldDef?.required === true,
40
+ };
41
+ // Relationship target collection(s) — the agent needs this to resolve a
42
+ // slug→id for a relationship field.
43
+ if (typeof fieldDef?.relationTo === 'string' || Array.isArray(fieldDef?.relationTo)) {
44
+ summary.relationTo = fieldDef.relationTo;
45
+ }
46
+ if (fieldDef?.hasMany === true || fieldDef?.multiple === true)
47
+ summary.hasMany = true;
48
+ // Select options (label/value pairs or bare strings) so the agent can fill enums.
49
+ if (Array.isArray(fieldDef?.options))
50
+ summary.options = fieldDef.options;
51
+ // Stop recursing past the cap, but still emit the field's own metadata.
52
+ if (depth >= MAX_DEPTH)
53
+ return summary;
54
+ // `array`: recurse into the element subfields so an agent knows the shape of
55
+ // each row it must author.
56
+ if (summary.type === 'array' && isFieldMap(fieldDef?.fields)) {
57
+ summary.fields = summarizeCollectionFields(fieldDef.fields, depth + 1);
58
+ if (typeof fieldDef.minRows === 'number')
59
+ summary.minRows = fieldDef.minRows;
60
+ if (typeof fieldDef.maxRows === 'number')
61
+ summary.maxRows = fieldDef.maxRows;
62
+ }
63
+ // `blocks`: recurse into each block variant's subfields, keyed by the block
64
+ // slug (the discriminator the agent writes as `blockType`).
65
+ if (summary.type === 'blocks' && Array.isArray(fieldDef?.blocks)) {
66
+ summary.blocks = fieldDef.blocks
67
+ .filter((b) => !!b && typeof b === 'object')
68
+ .map((b) => {
69
+ const slug = typeof b.slug === 'string' ? b.slug : 'unknown';
70
+ const labels = b.labels;
71
+ const block = {
72
+ slug,
73
+ fields: summarizeCollectionFields(b.fields, depth + 1),
74
+ };
75
+ if (typeof labels?.singular === 'string')
76
+ block.label = labels.singular;
77
+ return block;
78
+ });
79
+ }
80
+ return summary;
81
+ }
82
+ //# sourceMappingURL=collection-introspection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-introspection.js","sourceRoot":"","sources":["../../src/api/collection-introspection.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/api/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAomC5C,iFAAiF;AACjF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AA4LD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS9E;AA0VD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA67YzD"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/api/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAqmC5C,iFAAiF;AACjF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AA4LD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS9E;AA0VD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA25YzD"}
@@ -1,3 +1,4 @@
1
+ import { summarizeCollectionFields } from './collection-introspection.js';
1
2
  import { listDocuments, getDocument, createDocument, updateDocument, updateDocumentSeoFields, assertCollectionAccess, deleteDocument, getGlobal, updateGlobal, buildRelationLookup, } from '../actions.js';
2
3
  import { populateRelations, parsePopulateParam } from '../fields/relations.js';
3
4
  import { verifyPassword, hashPassword, needsRehash, compareToDummyHash } from '../auth/password.js';
@@ -1457,30 +1458,12 @@ export function registerCMSRoutes(router) {
1457
1458
  if (!config)
1458
1459
  return errorResponse('CMS not configured', 500);
1459
1460
  const collections = Object.entries(config.collections ?? {}).map(([slug, def]) => {
1460
- const fields = (def?.fields ?? {});
1461
1461
  // Reduce each field to `{ name, type, required }` plus, where present,
1462
- // the relationship target and select options enough for the agent to
1463
- // plan a create/update AND resolve relationship fields (WS-C C2 /
1464
- // WS-B4 overlap) without sending the full validator.
1465
- const fieldSummary = Object.entries(fields).map(([name, fieldDef]) => {
1466
- const summary = {
1467
- name,
1468
- type: typeof fieldDef?.type === 'string' ? fieldDef.type : 'unknown',
1469
- required: fieldDef?.required === true,
1470
- };
1471
- // Relationship target collection(s) — the agent needs this to know
1472
- // where to resolve a slug→id for a relationship field.
1473
- if (typeof fieldDef?.relationTo === 'string' || Array.isArray(fieldDef?.relationTo)) {
1474
- summary.relationTo = fieldDef.relationTo;
1475
- }
1476
- if (fieldDef?.hasMany === true || fieldDef?.multiple === true)
1477
- summary.hasMany = true;
1478
- // Select options (label/value pairs) so the agent can fill enums.
1479
- if (Array.isArray(fieldDef?.options)) {
1480
- summary.options = fieldDef.options;
1481
- }
1482
- return summary;
1483
- });
1462
+ // the relationship target, select options, and (for `array`/`blocks`)
1463
+ // the nested subfield schema enough for the agent to plan a deep
1464
+ // create/update AND resolve relationship fields (WS-B4 + WS-C C2)
1465
+ // without sending the full validator. See collection-introspection.ts.
1466
+ const fieldSummary = summarizeCollectionFields(def?.fields);
1484
1467
  return {
1485
1468
  slug,
1486
1469
  labels: def?.labels ?? { singular: slug, plural: slug },