payload-mcp-toolkit 0.3.4 → 0.7.4
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/README.md +253 -151
- package/dist/api-keys.d.ts +46 -0
- package/dist/api-keys.js +308 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/auth-strategy.d.ts +96 -0
- package/dist/auth-strategy.js +261 -0
- package/dist/auth-strategy.js.map +1 -0
- package/dist/components/CollectionScopesMatrix.d.ts +8 -0
- package/dist/components/CollectionScopesMatrix.js +32 -0
- package/dist/components/CollectionScopesMatrix.js.map +1 -0
- package/dist/components/GlobalScopesMatrix.d.ts +8 -0
- package/dist/components/GlobalScopesMatrix.js +28 -0
- package/dist/components/GlobalScopesMatrix.js.map +1 -0
- package/dist/components/ScopesTable.d.ts +19 -0
- package/dist/components/ScopesTable.js +285 -0
- package/dist/components/ScopesTable.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -0
- package/dist/conflict-detection.d.ts +13 -0
- package/dist/conflict-detection.js +41 -0
- package/dist/conflict-detection.js.map +1 -0
- package/dist/draft-workflow.d.ts +46 -48
- package/dist/draft-workflow.js +53 -135
- package/dist/draft-workflow.js.map +1 -1
- package/dist/endpoint.d.ts +35 -0
- package/dist/endpoint.js +105 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/hash.d.ts +21 -0
- package/dist/hash.js +36 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +9 -9
- package/dist/index.js +167 -69
- package/dist/index.js.map +1 -1
- package/dist/introspection.d.ts +17 -3
- package/dist/introspection.js +95 -36
- package/dist/introspection.js.map +1 -1
- package/dist/prompts.js +5 -5
- package/dist/prompts.js.map +1 -1
- package/dist/registry.d.ts +50 -0
- package/dist/registry.js +169 -0
- package/dist/registry.js.map +1 -0
- package/dist/resources.d.ts +5 -3
- package/dist/resources.js +23 -11
- package/dist/resources.js.map +1 -1
- package/dist/scope/audit-log.d.ts +18 -0
- package/dist/scope/audit-log.js +50 -0
- package/dist/scope/audit-log.js.map +1 -0
- package/dist/scope/policy.d.ts +73 -0
- package/dist/scope/policy.js +218 -0
- package/dist/scope/policy.js.map +1 -0
- package/dist/tools/_helpers.d.ts +62 -1
- package/dist/tools/_helpers.js +181 -0
- package/dist/tools/_helpers.js.map +1 -1
- package/dist/tools/_layout-helpers.d.ts +43 -0
- package/dist/tools/_layout-helpers.js +159 -0
- package/dist/tools/_layout-helpers.js.map +1 -0
- package/dist/tools/create-document.d.ts +5 -5
- package/dist/tools/create-document.js +25 -21
- package/dist/tools/create-document.js.map +1 -1
- package/dist/tools/delete-document.d.ts +25 -0
- package/dist/tools/delete-document.js +49 -0
- package/dist/tools/delete-document.js.map +1 -0
- package/dist/tools/find-document.d.ts +33 -0
- package/dist/tools/find-document.js +97 -0
- package/dist/tools/find-document.js.map +1 -0
- package/dist/tools/find-global.d.ts +26 -0
- package/dist/tools/find-global.js +122 -0
- package/dist/tools/find-global.js.map +1 -0
- package/dist/tools/global-versions.d.ts +39 -0
- package/dist/tools/global-versions.js +132 -0
- package/dist/tools/global-versions.js.map +1 -0
- package/dist/tools/patch-global-layout.d.ts +31 -0
- package/dist/tools/patch-global-layout.js +127 -0
- package/dist/tools/patch-global-layout.js.map +1 -0
- package/dist/tools/patch-layout.d.ts +5 -8
- package/dist/tools/patch-layout.js +18 -100
- package/dist/tools/patch-layout.js.map +1 -1
- package/dist/tools/publish-draft.d.ts +5 -4
- package/dist/tools/publish-draft.js +39 -2
- package/dist/tools/publish-draft.js.map +1 -1
- package/dist/tools/publish-global-draft.d.ts +20 -0
- package/dist/tools/publish-global-draft.js +79 -0
- package/dist/tools/publish-global-draft.js.map +1 -0
- package/dist/tools/resolve-reference.d.ts +5 -4
- package/dist/tools/resolve-reference.js +4 -0
- package/dist/tools/resolve-reference.js.map +1 -1
- package/dist/tools/safe-delete.d.ts +5 -5
- package/dist/tools/safe-delete.js +20 -15
- package/dist/tools/safe-delete.js.map +1 -1
- package/dist/tools/schedule-publish.d.ts +5 -5
- package/dist/tools/schedule-publish.js +23 -19
- package/dist/tools/schedule-publish.js.map +1 -1
- package/dist/tools/search-content.d.ts +5 -9
- package/dist/tools/search-content.js +16 -12
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/update-document.d.ts +5 -5
- package/dist/tools/update-document.js +10 -5
- package/dist/tools/update-document.js.map +1 -1
- package/dist/tools/update-global.d.ts +27 -0
- package/dist/tools/update-global.js +72 -0
- package/dist/tools/update-global.js.map +1 -0
- package/dist/tools/upload-media.d.ts +5 -4
- package/dist/tools/upload-media.js +6 -1
- package/dist/tools/upload-media.js.map +1 -1
- package/dist/tools/versions.d.ts +10 -9
- package/dist/tools/versions.js +15 -7
- package/dist/tools/versions.js.map +1 -1
- package/dist/types.d.ts +56 -3
- package/dist/types.js +13 -6
- package/dist/types.js.map +1 -1
- package/package.json +39 -18
- package/dist/__tests__/introspection.test.js +0 -459
- package/dist/__tests__/introspection.test.js.map +0 -1
- package/dist/__tests__/url-validator.test.js +0 -326
- package/dist/__tests__/url-validator.test.js.map +0 -1
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { introspectCollection, introspectCollections, introspectBlocks, buildBlockNestingMap, buildRelationshipGraph } from '../introspection';
|
|
3
|
-
// ─── Sample schema (kept inline so the test is self-contained) ─────
|
|
4
|
-
const Media = {
|
|
5
|
-
slug: 'media',
|
|
6
|
-
upload: true,
|
|
7
|
-
fields: [
|
|
8
|
-
{
|
|
9
|
-
name: 'alt',
|
|
10
|
-
type: 'text',
|
|
11
|
-
required: true
|
|
12
|
-
}
|
|
13
|
-
]
|
|
14
|
-
};
|
|
15
|
-
const Categories = {
|
|
16
|
-
slug: 'categories',
|
|
17
|
-
fields: [
|
|
18
|
-
{
|
|
19
|
-
name: 'name',
|
|
20
|
-
type: 'text',
|
|
21
|
-
required: true
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'slug',
|
|
25
|
-
type: 'text',
|
|
26
|
-
required: true
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
};
|
|
30
|
-
const Authors = {
|
|
31
|
-
slug: 'authors',
|
|
32
|
-
fields: [
|
|
33
|
-
{
|
|
34
|
-
name: 'name',
|
|
35
|
-
type: 'text',
|
|
36
|
-
required: true
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: 'slug',
|
|
40
|
-
type: 'text',
|
|
41
|
-
required: true
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'avatar',
|
|
45
|
-
type: 'upload',
|
|
46
|
-
relationTo: 'media'
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
};
|
|
50
|
-
// Leaf-style blocks
|
|
51
|
-
const Heading = {
|
|
52
|
-
slug: 'heading',
|
|
53
|
-
fields: [
|
|
54
|
-
{
|
|
55
|
-
name: 'text',
|
|
56
|
-
type: 'text',
|
|
57
|
-
required: true
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'level',
|
|
61
|
-
type: 'select',
|
|
62
|
-
options: [
|
|
63
|
-
'h1',
|
|
64
|
-
'h2',
|
|
65
|
-
'h3'
|
|
66
|
-
],
|
|
67
|
-
defaultValue: 'h2'
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: 'align',
|
|
71
|
-
type: 'select',
|
|
72
|
-
options: [
|
|
73
|
-
'left',
|
|
74
|
-
'center',
|
|
75
|
-
'right'
|
|
76
|
-
],
|
|
77
|
-
defaultValue: 'left'
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
};
|
|
81
|
-
const RichText = {
|
|
82
|
-
slug: 'richText',
|
|
83
|
-
fields: [
|
|
84
|
-
{
|
|
85
|
-
name: 'content',
|
|
86
|
-
type: 'richText'
|
|
87
|
-
}
|
|
88
|
-
]
|
|
89
|
-
};
|
|
90
|
-
const ImageBlock = {
|
|
91
|
-
slug: 'image',
|
|
92
|
-
fields: [
|
|
93
|
-
{
|
|
94
|
-
name: 'image',
|
|
95
|
-
type: 'upload',
|
|
96
|
-
relationTo: 'media',
|
|
97
|
-
required: true
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: 'caption',
|
|
101
|
-
type: 'text'
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
};
|
|
105
|
-
// Container-style blocks (have nested blocks fields)
|
|
106
|
-
const FullWidth = {
|
|
107
|
-
slug: 'fullWidth',
|
|
108
|
-
fields: [
|
|
109
|
-
{
|
|
110
|
-
name: 'content',
|
|
111
|
-
type: 'blocks',
|
|
112
|
-
blocks: [
|
|
113
|
-
Heading,
|
|
114
|
-
RichText,
|
|
115
|
-
ImageBlock
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
};
|
|
120
|
-
const HeadingOnly = {
|
|
121
|
-
slug: 'headingOnly',
|
|
122
|
-
fields: [
|
|
123
|
-
{
|
|
124
|
-
name: 'content',
|
|
125
|
-
type: 'blocks',
|
|
126
|
-
maxRows: 1,
|
|
127
|
-
blocks: [
|
|
128
|
-
Heading
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
};
|
|
133
|
-
const CtaBanner = {
|
|
134
|
-
slug: 'ctaBanner',
|
|
135
|
-
fields: [
|
|
136
|
-
{
|
|
137
|
-
name: 'headline',
|
|
138
|
-
type: 'text',
|
|
139
|
-
required: true
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: 'buttonLabel',
|
|
143
|
-
type: 'text'
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'buttonHref',
|
|
147
|
-
type: 'text'
|
|
148
|
-
}
|
|
149
|
-
]
|
|
150
|
-
};
|
|
151
|
-
// Deeply-nestable container — exercises the recursive path
|
|
152
|
-
const Accordion = {
|
|
153
|
-
slug: 'accordion',
|
|
154
|
-
fields: [
|
|
155
|
-
{
|
|
156
|
-
name: 'panels',
|
|
157
|
-
type: 'array',
|
|
158
|
-
fields: [
|
|
159
|
-
{
|
|
160
|
-
name: 'title',
|
|
161
|
-
type: 'text'
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
name: 'body',
|
|
165
|
-
type: 'blocks',
|
|
166
|
-
blocks: [
|
|
167
|
-
Heading,
|
|
168
|
-
RichText,
|
|
169
|
-
FullWidth
|
|
170
|
-
]
|
|
171
|
-
}
|
|
172
|
-
]
|
|
173
|
-
}
|
|
174
|
-
]
|
|
175
|
-
};
|
|
176
|
-
const allBlocks = [
|
|
177
|
-
Heading,
|
|
178
|
-
RichText,
|
|
179
|
-
ImageBlock,
|
|
180
|
-
FullWidth,
|
|
181
|
-
HeadingOnly,
|
|
182
|
-
CtaBanner,
|
|
183
|
-
Accordion
|
|
184
|
-
];
|
|
185
|
-
const Posts = {
|
|
186
|
-
slug: 'posts',
|
|
187
|
-
versions: {
|
|
188
|
-
drafts: true
|
|
189
|
-
},
|
|
190
|
-
fields: [
|
|
191
|
-
{
|
|
192
|
-
name: 'title',
|
|
193
|
-
type: 'text',
|
|
194
|
-
required: true
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
name: 'slug',
|
|
198
|
-
type: 'text',
|
|
199
|
-
required: true
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
name: 'featured',
|
|
203
|
-
type: 'checkbox'
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
name: 'category',
|
|
207
|
-
type: 'relationship',
|
|
208
|
-
relationTo: 'categories'
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
name: 'authors',
|
|
212
|
-
type: 'relationship',
|
|
213
|
-
relationTo: 'authors',
|
|
214
|
-
hasMany: true
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: 'coverImage',
|
|
218
|
-
type: 'upload',
|
|
219
|
-
relationTo: 'media'
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
name: 'tags',
|
|
223
|
-
type: 'array',
|
|
224
|
-
fields: [
|
|
225
|
-
{
|
|
226
|
-
name: 'tag',
|
|
227
|
-
type: 'text'
|
|
228
|
-
}
|
|
229
|
-
]
|
|
230
|
-
}
|
|
231
|
-
]
|
|
232
|
-
};
|
|
233
|
-
const Pages = {
|
|
234
|
-
slug: 'pages',
|
|
235
|
-
versions: {
|
|
236
|
-
drafts: true
|
|
237
|
-
},
|
|
238
|
-
fields: [
|
|
239
|
-
{
|
|
240
|
-
type: 'tabs',
|
|
241
|
-
tabs: [
|
|
242
|
-
{
|
|
243
|
-
name: 'hero',
|
|
244
|
-
label: 'Hero',
|
|
245
|
-
fields: [
|
|
246
|
-
{
|
|
247
|
-
name: 'heroTitle',
|
|
248
|
-
type: 'text'
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
name: 'heroSize',
|
|
252
|
-
type: 'select',
|
|
253
|
-
options: [
|
|
254
|
-
'small',
|
|
255
|
-
'medium',
|
|
256
|
-
'large'
|
|
257
|
-
],
|
|
258
|
-
defaultValue: 'medium'
|
|
259
|
-
}
|
|
260
|
-
]
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
label: 'Content',
|
|
264
|
-
fields: [
|
|
265
|
-
{
|
|
266
|
-
name: 'slug',
|
|
267
|
-
type: 'text',
|
|
268
|
-
required: true
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: 'layout',
|
|
272
|
-
type: 'blocks',
|
|
273
|
-
blocks: [
|
|
274
|
-
FullWidth,
|
|
275
|
-
HeadingOnly,
|
|
276
|
-
CtaBanner,
|
|
277
|
-
Accordion
|
|
278
|
-
]
|
|
279
|
-
}
|
|
280
|
-
]
|
|
281
|
-
}
|
|
282
|
-
]
|
|
283
|
-
}
|
|
284
|
-
]
|
|
285
|
-
};
|
|
286
|
-
// ─── introspectCollection ──────────────────────────────────────────
|
|
287
|
-
describe('introspectCollection', ()=>{
|
|
288
|
-
it('extracts Posts collection fields, relationships, and draft status', ()=>{
|
|
289
|
-
const schema = introspectCollection(Posts);
|
|
290
|
-
expect(schema.slug).toBe('posts');
|
|
291
|
-
expect(schema.hasDrafts).toBe(true);
|
|
292
|
-
const fieldNames = schema.fields.map((f)=>f.name);
|
|
293
|
-
expect(fieldNames).toContain('title');
|
|
294
|
-
expect(fieldNames).toContain('slug');
|
|
295
|
-
expect(fieldNames).toContain('featured');
|
|
296
|
-
expect(fieldNames).toContain('tags');
|
|
297
|
-
const relFieldNames = schema.relationships.map((r)=>r.fieldName);
|
|
298
|
-
expect(relFieldNames).toContain('category');
|
|
299
|
-
expect(relFieldNames).toContain('authors');
|
|
300
|
-
const cover = schema.relationships.find((r)=>r.fieldName === 'coverImage');
|
|
301
|
-
expect(cover).toBeDefined();
|
|
302
|
-
expect(cover.relationTo).toBe('media');
|
|
303
|
-
expect(schema.searchableFields).toContain('title');
|
|
304
|
-
expect(schema.searchableFields).toContain('slug');
|
|
305
|
-
});
|
|
306
|
-
it('extracts Pages collection with tab-nested fields', ()=>{
|
|
307
|
-
const schema = introspectCollection(Pages);
|
|
308
|
-
expect(schema.slug).toBe('pages');
|
|
309
|
-
expect(schema.hasDrafts).toBe(true);
|
|
310
|
-
const fieldNames = schema.fields.map((f)=>f.name);
|
|
311
|
-
expect(fieldNames).toContain('heroTitle');
|
|
312
|
-
expect(fieldNames).toContain('slug');
|
|
313
|
-
expect(fieldNames).toContain('layout');
|
|
314
|
-
});
|
|
315
|
-
it('detects collections without draft support', ()=>{
|
|
316
|
-
const schema = introspectCollection(Categories);
|
|
317
|
-
expect(schema.hasDrafts).toBe(false);
|
|
318
|
-
});
|
|
319
|
-
it('extracts select field options from Pages heroSize', ()=>{
|
|
320
|
-
const schema = introspectCollection(Pages);
|
|
321
|
-
const heroSize = schema.fields.find((f)=>f.name === 'heroSize');
|
|
322
|
-
expect(heroSize).toBeDefined();
|
|
323
|
-
expect(heroSize.type).toBe('select');
|
|
324
|
-
expect(heroSize.options).toBeDefined();
|
|
325
|
-
expect(heroSize.options.length).toBe(3);
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
// ─── introspectBlocks (flat catalog) ───────────────────────────────
|
|
329
|
-
describe('introspectBlocks', ()=>{
|
|
330
|
-
it('returns a flat catalog of every block with no section/leaf split', ()=>{
|
|
331
|
-
const catalog = introspectBlocks(allBlocks);
|
|
332
|
-
const slugs = catalog.blocks.map((b)=>b.slug);
|
|
333
|
-
expect(slugs).toEqual([
|
|
334
|
-
'heading',
|
|
335
|
-
'richText',
|
|
336
|
-
'image',
|
|
337
|
-
'fullWidth',
|
|
338
|
-
'headingOnly',
|
|
339
|
-
'ctaBanner',
|
|
340
|
-
'accordion'
|
|
341
|
-
]);
|
|
342
|
-
});
|
|
343
|
-
it('extracts each block\'s fields including select options', ()=>{
|
|
344
|
-
const catalog = introspectBlocks(allBlocks);
|
|
345
|
-
const heading = catalog.blocks.find((b)=>b.slug === 'heading');
|
|
346
|
-
expect(heading).toBeDefined();
|
|
347
|
-
const headingFieldNames = heading.fields.map((f)=>f.name);
|
|
348
|
-
expect(headingFieldNames).toEqual([
|
|
349
|
-
'text',
|
|
350
|
-
'level',
|
|
351
|
-
'align'
|
|
352
|
-
]);
|
|
353
|
-
const level = heading.fields.find((f)=>f.name === 'level');
|
|
354
|
-
expect(level.options).toBeDefined();
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
// ─── buildBlockNestingMap ──────────────────────────────────────────
|
|
358
|
-
describe('buildBlockNestingMap', ()=>{
|
|
359
|
-
it('records the layout field on Pages with the slugs it accepts', ()=>{
|
|
360
|
-
const map = buildBlockNestingMap([
|
|
361
|
-
Pages,
|
|
362
|
-
Posts
|
|
363
|
-
], allBlocks);
|
|
364
|
-
const pageLayout = map.find((e)=>e.ownerType === 'collection' && e.owner === 'pages' && e.fieldPath === 'layout');
|
|
365
|
-
expect(pageLayout).toBeDefined();
|
|
366
|
-
expect(pageLayout.acceptedBlockSlugs).toEqual([
|
|
367
|
-
'fullWidth',
|
|
368
|
-
'headingOnly',
|
|
369
|
-
'ctaBanner',
|
|
370
|
-
'accordion'
|
|
371
|
-
]);
|
|
372
|
-
});
|
|
373
|
-
it('records nested blocks fields inside container blocks', ()=>{
|
|
374
|
-
const map = buildBlockNestingMap([
|
|
375
|
-
Pages
|
|
376
|
-
], allBlocks);
|
|
377
|
-
const fullWidthContent = map.find((e)=>e.ownerType === 'block' && e.owner === 'fullWidth' && e.fieldPath === 'content');
|
|
378
|
-
expect(fullWidthContent).toBeDefined();
|
|
379
|
-
expect(fullWidthContent.acceptedBlockSlugs).toEqual([
|
|
380
|
-
'heading',
|
|
381
|
-
'richText',
|
|
382
|
-
'image'
|
|
383
|
-
]);
|
|
384
|
-
const headingOnly = map.find((e)=>e.ownerType === 'block' && e.owner === 'headingOnly' && e.fieldPath === 'content');
|
|
385
|
-
expect(headingOnly.acceptedBlockSlugs).toEqual([
|
|
386
|
-
'heading'
|
|
387
|
-
]);
|
|
388
|
-
expect(headingOnly.maxRows).toBe(1);
|
|
389
|
-
});
|
|
390
|
-
it('handles arbitrarily-deep nesting via array fields inside blocks', ()=>{
|
|
391
|
-
const map = buildBlockNestingMap([
|
|
392
|
-
Pages
|
|
393
|
-
], allBlocks);
|
|
394
|
-
const accordionPanelBody = map.find((e)=>e.ownerType === 'block' && e.owner === 'accordion' && e.fieldPath === 'panels[].body');
|
|
395
|
-
expect(accordionPanelBody).toBeDefined();
|
|
396
|
-
expect(accordionPanelBody.acceptedBlockSlugs).toEqual([
|
|
397
|
-
'heading',
|
|
398
|
-
'richText',
|
|
399
|
-
'fullWidth'
|
|
400
|
-
]);
|
|
401
|
-
});
|
|
402
|
-
it('omits unknown slugs not present in the block list', ()=>{
|
|
403
|
-
const Stray = {
|
|
404
|
-
slug: 'stray',
|
|
405
|
-
fields: [
|
|
406
|
-
{
|
|
407
|
-
name: 'layout',
|
|
408
|
-
type: 'blocks',
|
|
409
|
-
blocks: [
|
|
410
|
-
Heading,
|
|
411
|
-
{
|
|
412
|
-
slug: 'mystery',
|
|
413
|
-
fields: []
|
|
414
|
-
}
|
|
415
|
-
]
|
|
416
|
-
}
|
|
417
|
-
]
|
|
418
|
-
};
|
|
419
|
-
const map = buildBlockNestingMap([
|
|
420
|
-
Stray
|
|
421
|
-
], [
|
|
422
|
-
Heading
|
|
423
|
-
]) // mystery not in catalog
|
|
424
|
-
;
|
|
425
|
-
const stray = map.find((e)=>e.owner === 'stray' && e.fieldPath === 'layout');
|
|
426
|
-
expect(stray.acceptedBlockSlugs).toEqual([
|
|
427
|
-
'heading'
|
|
428
|
-
]);
|
|
429
|
-
});
|
|
430
|
-
it('omits fixed blocks (no nested blocks fields) from the map', ()=>{
|
|
431
|
-
const map = buildBlockNestingMap([
|
|
432
|
-
Pages
|
|
433
|
-
], allBlocks);
|
|
434
|
-
const ctaEntries = map.filter((e)=>e.owner === 'ctaBanner');
|
|
435
|
-
expect(ctaEntries).toHaveLength(0);
|
|
436
|
-
});
|
|
437
|
-
});
|
|
438
|
-
// ─── buildRelationshipGraph ────────────────────────────────────────
|
|
439
|
-
describe('buildRelationshipGraph', ()=>{
|
|
440
|
-
it('builds correct graph from sample collections', ()=>{
|
|
441
|
-
const schemas = introspectCollections([
|
|
442
|
-
Posts,
|
|
443
|
-
Pages,
|
|
444
|
-
Categories,
|
|
445
|
-
Authors,
|
|
446
|
-
Media
|
|
447
|
-
]);
|
|
448
|
-
const edges = buildRelationshipGraph(schemas);
|
|
449
|
-
const postEdges = edges.filter((e)=>e.fromCollection === 'posts');
|
|
450
|
-
const postTargets = postEdges.map((e)=>e.toCollection);
|
|
451
|
-
expect(postTargets).toContain('categories');
|
|
452
|
-
expect(postTargets).toContain('authors');
|
|
453
|
-
expect(postTargets).toContain('media');
|
|
454
|
-
const authorEdges = edges.filter((e)=>e.fromCollection === 'authors');
|
|
455
|
-
expect(authorEdges.map((e)=>e.toCollection)).toContain('media');
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
//# sourceMappingURL=introspection.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__tests__/introspection.test.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport type { Block, CollectionConfig } from 'payload'\nimport {\n introspectCollection,\n introspectCollections,\n introspectBlocks,\n buildBlockNestingMap,\n buildRelationshipGraph,\n} from '../introspection'\n\n// ─── Sample schema (kept inline so the test is self-contained) ─────\n\nconst Media: CollectionConfig = {\n slug: 'media',\n upload: true,\n fields: [{ name: 'alt', type: 'text', required: true }],\n}\n\nconst Categories: CollectionConfig = {\n slug: 'categories',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'slug', type: 'text', required: true },\n ],\n}\n\nconst Authors: CollectionConfig = {\n slug: 'authors',\n fields: [\n { name: 'name', type: 'text', required: true },\n { name: 'slug', type: 'text', required: true },\n { name: 'avatar', type: 'upload', relationTo: 'media' },\n ],\n}\n\n// Leaf-style blocks\nconst Heading: Block = {\n slug: 'heading',\n fields: [\n { name: 'text', type: 'text', required: true },\n {\n name: 'level',\n type: 'select',\n options: ['h1', 'h2', 'h3'],\n defaultValue: 'h2',\n },\n {\n name: 'align',\n type: 'select',\n options: ['left', 'center', 'right'],\n defaultValue: 'left',\n },\n ],\n}\n\nconst RichText: Block = {\n slug: 'richText',\n fields: [{ name: 'content', type: 'richText' }],\n}\n\nconst ImageBlock: Block = {\n slug: 'image',\n fields: [\n { name: 'image', type: 'upload', relationTo: 'media', required: true },\n { name: 'caption', type: 'text' },\n ],\n}\n\n// Container-style blocks (have nested blocks fields)\nconst FullWidth: Block = {\n slug: 'fullWidth',\n fields: [\n {\n name: 'content',\n type: 'blocks',\n blocks: [Heading, RichText, ImageBlock],\n },\n ],\n}\n\nconst HeadingOnly: Block = {\n slug: 'headingOnly',\n fields: [\n {\n name: 'content',\n type: 'blocks',\n maxRows: 1,\n blocks: [Heading],\n },\n ],\n}\n\nconst CtaBanner: Block = {\n slug: 'ctaBanner',\n fields: [\n { name: 'headline', type: 'text', required: true },\n { name: 'buttonLabel', type: 'text' },\n { name: 'buttonHref', type: 'text' },\n ],\n}\n\n// Deeply-nestable container — exercises the recursive path\nconst Accordion: Block = {\n slug: 'accordion',\n fields: [\n {\n name: 'panels',\n type: 'array',\n fields: [\n { name: 'title', type: 'text' },\n {\n name: 'body',\n type: 'blocks',\n blocks: [Heading, RichText, FullWidth],\n },\n ],\n },\n ],\n}\n\nconst allBlocks: Block[] = [Heading, RichText, ImageBlock, FullWidth, HeadingOnly, CtaBanner, Accordion]\n\nconst Posts: CollectionConfig = {\n slug: 'posts',\n versions: { drafts: true },\n fields: [\n { name: 'title', type: 'text', required: true },\n { name: 'slug', type: 'text', required: true },\n { name: 'featured', type: 'checkbox' },\n { name: 'category', type: 'relationship', relationTo: 'categories' },\n {\n name: 'authors',\n type: 'relationship',\n relationTo: 'authors',\n hasMany: true,\n },\n { name: 'coverImage', type: 'upload', relationTo: 'media' },\n {\n name: 'tags',\n type: 'array',\n fields: [{ name: 'tag', type: 'text' }],\n },\n ],\n}\n\nconst Pages: CollectionConfig = {\n slug: 'pages',\n versions: { drafts: true },\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n name: 'hero',\n label: 'Hero',\n fields: [\n { name: 'heroTitle', type: 'text' },\n {\n name: 'heroSize',\n type: 'select',\n options: ['small', 'medium', 'large'],\n defaultValue: 'medium',\n },\n ],\n },\n {\n label: 'Content',\n fields: [\n { name: 'slug', type: 'text', required: true },\n { name: 'layout', type: 'blocks', blocks: [FullWidth, HeadingOnly, CtaBanner, Accordion] },\n ],\n },\n ],\n },\n ],\n}\n\n// ─── introspectCollection ──────────────────────────────────────────\n\ndescribe('introspectCollection', () => {\n it('extracts Posts collection fields, relationships, and draft status', () => {\n const schema = introspectCollection(Posts)\n\n expect(schema.slug).toBe('posts')\n expect(schema.hasDrafts).toBe(true)\n\n const fieldNames = schema.fields.map((f) => f.name)\n expect(fieldNames).toContain('title')\n expect(fieldNames).toContain('slug')\n expect(fieldNames).toContain('featured')\n expect(fieldNames).toContain('tags')\n\n const relFieldNames = schema.relationships.map((r) => r.fieldName)\n expect(relFieldNames).toContain('category')\n expect(relFieldNames).toContain('authors')\n\n const cover = schema.relationships.find((r) => r.fieldName === 'coverImage')\n expect(cover).toBeDefined()\n expect(cover!.relationTo).toBe('media')\n\n expect(schema.searchableFields).toContain('title')\n expect(schema.searchableFields).toContain('slug')\n })\n\n it('extracts Pages collection with tab-nested fields', () => {\n const schema = introspectCollection(Pages)\n\n expect(schema.slug).toBe('pages')\n expect(schema.hasDrafts).toBe(true)\n\n const fieldNames = schema.fields.map((f) => f.name)\n expect(fieldNames).toContain('heroTitle')\n expect(fieldNames).toContain('slug')\n expect(fieldNames).toContain('layout')\n })\n\n it('detects collections without draft support', () => {\n const schema = introspectCollection(Categories)\n expect(schema.hasDrafts).toBe(false)\n })\n\n it('extracts select field options from Pages heroSize', () => {\n const schema = introspectCollection(Pages)\n const heroSize = schema.fields.find((f) => f.name === 'heroSize')\n expect(heroSize).toBeDefined()\n expect(heroSize!.type).toBe('select')\n expect(heroSize!.options).toBeDefined()\n expect(heroSize!.options!.length).toBe(3)\n })\n})\n\n// ─── introspectBlocks (flat catalog) ───────────────────────────────\n\ndescribe('introspectBlocks', () => {\n it('returns a flat catalog of every block with no section/leaf split', () => {\n const catalog = introspectBlocks(allBlocks)\n const slugs = catalog.blocks.map((b) => b.slug)\n expect(slugs).toEqual([\n 'heading',\n 'richText',\n 'image',\n 'fullWidth',\n 'headingOnly',\n 'ctaBanner',\n 'accordion',\n ])\n })\n\n it('extracts each block\\'s fields including select options', () => {\n const catalog = introspectBlocks(allBlocks)\n const heading = catalog.blocks.find((b) => b.slug === 'heading')\n expect(heading).toBeDefined()\n const headingFieldNames = heading!.fields.map((f) => f.name)\n expect(headingFieldNames).toEqual(['text', 'level', 'align'])\n const level = heading!.fields.find((f) => f.name === 'level')\n expect(level!.options).toBeDefined()\n })\n})\n\n// ─── buildBlockNestingMap ──────────────────────────────────────────\n\ndescribe('buildBlockNestingMap', () => {\n it('records the layout field on Pages with the slugs it accepts', () => {\n const map = buildBlockNestingMap([Pages, Posts], allBlocks)\n const pageLayout = map.find(\n (e) => e.ownerType === 'collection' && e.owner === 'pages' && e.fieldPath === 'layout',\n )\n expect(pageLayout).toBeDefined()\n expect(pageLayout!.acceptedBlockSlugs).toEqual(['fullWidth', 'headingOnly', 'ctaBanner', 'accordion'])\n })\n\n it('records nested blocks fields inside container blocks', () => {\n const map = buildBlockNestingMap([Pages], allBlocks)\n\n const fullWidthContent = map.find(\n (e) => e.ownerType === 'block' && e.owner === 'fullWidth' && e.fieldPath === 'content',\n )\n expect(fullWidthContent).toBeDefined()\n expect(fullWidthContent!.acceptedBlockSlugs).toEqual(['heading', 'richText', 'image'])\n\n const headingOnly = map.find(\n (e) => e.ownerType === 'block' && e.owner === 'headingOnly' && e.fieldPath === 'content',\n )\n expect(headingOnly!.acceptedBlockSlugs).toEqual(['heading'])\n expect(headingOnly!.maxRows).toBe(1)\n })\n\n it('handles arbitrarily-deep nesting via array fields inside blocks', () => {\n const map = buildBlockNestingMap([Pages], allBlocks)\n\n const accordionPanelBody = map.find(\n (e) =>\n e.ownerType === 'block' && e.owner === 'accordion' && e.fieldPath === 'panels[].body',\n )\n expect(accordionPanelBody).toBeDefined()\n expect(accordionPanelBody!.acceptedBlockSlugs).toEqual(['heading', 'richText', 'fullWidth'])\n })\n\n it('omits unknown slugs not present in the block list', () => {\n const Stray: CollectionConfig = {\n slug: 'stray',\n fields: [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [Heading, { slug: 'mystery', fields: [] } as Block],\n },\n ],\n }\n const map = buildBlockNestingMap([Stray], [Heading]) // mystery not in catalog\n const stray = map.find((e) => e.owner === 'stray' && e.fieldPath === 'layout')\n expect(stray!.acceptedBlockSlugs).toEqual(['heading'])\n })\n\n it('omits fixed blocks (no nested blocks fields) from the map', () => {\n const map = buildBlockNestingMap([Pages], allBlocks)\n const ctaEntries = map.filter((e) => e.owner === 'ctaBanner')\n expect(ctaEntries).toHaveLength(0)\n })\n})\n\n// ─── buildRelationshipGraph ────────────────────────────────────────\n\ndescribe('buildRelationshipGraph', () => {\n it('builds correct graph from sample collections', () => {\n const schemas = introspectCollections([Posts, Pages, Categories, Authors, Media])\n const edges = buildRelationshipGraph(schemas)\n\n const postEdges = edges.filter((e) => e.fromCollection === 'posts')\n const postTargets = postEdges.map((e) => e.toCollection)\n expect(postTargets).toContain('categories')\n expect(postTargets).toContain('authors')\n expect(postTargets).toContain('media')\n\n const authorEdges = edges.filter((e) => e.fromCollection === 'authors')\n expect(authorEdges.map((e) => e.toCollection)).toContain('media')\n })\n})\n"],"names":["describe","it","expect","introspectCollection","introspectCollections","introspectBlocks","buildBlockNestingMap","buildRelationshipGraph","Media","slug","upload","fields","name","type","required","Categories","Authors","relationTo","Heading","options","defaultValue","RichText","ImageBlock","FullWidth","blocks","HeadingOnly","maxRows","CtaBanner","Accordion","allBlocks","Posts","versions","drafts","hasMany","Pages","tabs","label","schema","toBe","hasDrafts","fieldNames","map","f","toContain","relFieldNames","relationships","r","fieldName","cover","find","toBeDefined","searchableFields","heroSize","length","catalog","slugs","b","toEqual","heading","headingFieldNames","level","pageLayout","e","ownerType","owner","fieldPath","acceptedBlockSlugs","fullWidthContent","headingOnly","accordionPanelBody","Stray","stray","ctaEntries","filter","toHaveLength","schemas","edges","postEdges","fromCollection","postTargets","toCollection","authorEdges"],"mappings":"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"}
|