@mvriu5/payload-ai 1.2.0 → 1.3.2
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 +42 -0
- package/dist/components/Icons.d.ts +0 -8
- package/dist/components/Icons.js +4 -216
- package/dist/components/{ActionToast.d.ts → action-toast/ActionToast.d.ts} +1 -2
- package/dist/components/{ActionToast.js → action-toast/ActionToast.js} +25 -34
- package/dist/components/{ActionToast.module.css → action-toast/ActionToast.module.css} +0 -79
- package/dist/components/ai-input/AIInput.js +433 -0
- package/dist/components/{AIInput.module.css → ai-input/AIInput.module.css} +111 -43
- package/dist/components/ai-input/badge.d.ts +14 -0
- package/dist/components/ai-input/badge.js +85 -0
- package/dist/components/{AuditLogList.d.ts → audit-log-list/AuditLogList.d.ts} +4 -8
- package/dist/components/{AuditLogList.js → audit-log-list/AuditLogList.js} +49 -21
- package/dist/components/{AuditLogList.module.css → audit-log-list/AuditLogList.module.css} +11 -65
- package/dist/components/dashboard/Dashboard.d.ts +2 -0
- package/dist/components/dashboard/Dashboard.js +15 -0
- package/dist/components/dashboard/Dashboard.module.css +13 -0
- package/dist/components/{DiffDialog.d.ts → diff-dialog/DiffDialog.d.ts} +2 -2
- package/dist/components/{DiffDialog.js → diff-dialog/DiffDialog.js} +200 -189
- package/dist/components/{DiffDialog.module.css → diff-dialog/DiffDialog.module.css} +17 -35
- package/dist/components/hooks/useAIChatStream.d.ts +39 -0
- package/dist/components/hooks/useAIChatStream.js +217 -0
- package/dist/components/hooks/useAISettings.js +26 -25
- package/dist/components/hooks/useAuditLog.d.ts +11 -0
- package/dist/components/hooks/useAuditLog.js +41 -0
- package/dist/components/hooks/useDocumentMentionSuggestions.d.ts +1 -1
- package/dist/components/hooks/useDocumentMentionSuggestions.js +31 -27
- package/dist/components/hooks/useMentions.d.ts +58 -0
- package/dist/components/hooks/useMentions.js +276 -0
- package/dist/components/hooks/usePluginConfig.d.ts +52 -0
- package/dist/components/hooks/usePluginConfig.js +20 -0
- package/dist/components/{MentionPopover.d.ts → mention-popover/MentionPopover.d.ts} +2 -4
- package/dist/components/{MentionPopover.js → mention-popover/MentionPopover.js} +1 -8
- package/dist/components/{MentionPopover.module.css → mention-popover/MentionPopover.module.css} +1 -1
- package/dist/exports/client.d.ts +2 -2
- package/dist/exports/client.js +2 -2
- package/dist/handlers/applyActionHandler.js +27 -7
- package/dist/handlers/chatHandler.js +302 -58
- package/dist/handlers/mediaUploadHandler.d.ts +7 -0
- package/dist/handlers/mediaUploadHandler.js +99 -0
- package/dist/handlers/mentionSuggestionHandler.js +16 -14
- package/dist/handlers/proposalDiffHandler.js +41 -29
- package/dist/index.d.ts +6 -0
- package/dist/index.js +39 -7
- package/dist/payload/collectionPermissions.js +3 -1
- package/dist/payload/normalizeData.d.ts +0 -6
- package/dist/payload/normalizeData.js +25 -13
- package/dist/payload/proposalData.js +4 -1
- package/dist/payload/schemaContext.js +98 -43
- package/package.json +6 -6
- package/dist/components/AIInput.js +0 -896
- /package/dist/components/{AIInput.d.ts → ai-input/AIInput.d.ts} +0 -0
|
@@ -44,26 +44,30 @@ const getLocaleConfigs = (req)=>{
|
|
|
44
44
|
};
|
|
45
45
|
const getSerializableOptions = (options)=>{
|
|
46
46
|
if (!Array.isArray(options)) return undefined;
|
|
47
|
-
const serializedOptions = options.
|
|
47
|
+
const serializedOptions = options.flatMap((option)=>{
|
|
48
48
|
if (typeof option === "string") {
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
label: option,
|
|
52
|
+
value: option
|
|
53
|
+
}
|
|
54
|
+
];
|
|
53
55
|
}
|
|
54
|
-
if (!isRecord(option)) return
|
|
56
|
+
if (!isRecord(option)) return [];
|
|
55
57
|
const label = "label" in option ? getSerializableLabel(option.label) : undefined;
|
|
56
58
|
const value = "value" in option && typeof option.value === "string" ? option.value : undefined;
|
|
57
|
-
if (!label && !value) return
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
label
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
value
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
if (!label && !value) return [];
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
...label ? {
|
|
63
|
+
label
|
|
64
|
+
} : {},
|
|
65
|
+
...value ? {
|
|
66
|
+
value
|
|
67
|
+
} : {}
|
|
68
|
+
}
|
|
69
|
+
];
|
|
70
|
+
});
|
|
67
71
|
return serializedOptions.length > 0 ? serializedOptions : undefined;
|
|
68
72
|
};
|
|
69
73
|
const toNormalizeCollectionConfig = (config)=>{
|
|
@@ -288,8 +292,76 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
288
292
|
const context = [];
|
|
289
293
|
const seen = new Set();
|
|
290
294
|
const localeConfigs = getLocaleConfigs(req);
|
|
291
|
-
const
|
|
295
|
+
const localeConfigsByCode = new Map(localeConfigs.map((locale)=>[
|
|
296
|
+
locale.code,
|
|
297
|
+
locale
|
|
298
|
+
]));
|
|
299
|
+
const collectionSlugSet = new Set(collectionSlugs);
|
|
300
|
+
const globalSlugSet = new Set(globalSlugs);
|
|
301
|
+
const collectionConfigsBySlug = new Map(req.payload.config.collections.map((collection)=>[
|
|
302
|
+
collection.slug,
|
|
303
|
+
collection
|
|
304
|
+
]));
|
|
305
|
+
const globalConfigsBySlug = new Map(req.payload.config.globals?.map((global)=>[
|
|
306
|
+
global.slug,
|
|
307
|
+
global
|
|
308
|
+
]));
|
|
309
|
+
const blockContextsBySlug = new Map();
|
|
310
|
+
for (const block of blockContexts){
|
|
311
|
+
const blocks = blockContextsBySlug.get(block.slug) || [];
|
|
312
|
+
blocks.push(block);
|
|
313
|
+
blockContextsBySlug.set(block.slug, blocks);
|
|
314
|
+
}
|
|
315
|
+
const selectedLocales = [];
|
|
316
|
+
const selectedLocaleSet = new Set();
|
|
317
|
+
for (const mention of mentions){
|
|
318
|
+
if (mention.type !== "locale" || !mention.slug || selectedLocaleSet.has(mention.slug)) continue;
|
|
319
|
+
selectedLocaleSet.add(mention.slug);
|
|
320
|
+
selectedLocales.push(mention.slug);
|
|
321
|
+
}
|
|
292
322
|
const activeLocale = selectedLocales.at(-1);
|
|
323
|
+
const mentionDocResults = await Promise.all(mentions.slice(0, 8).map(async (mention)=>{
|
|
324
|
+
if (mention.type === "global" && mention.slug) {
|
|
325
|
+
const slug = mention.slug;
|
|
326
|
+
if (!globalSlugSet.has(slug)) return null;
|
|
327
|
+
const globalConfig = globalConfigsBySlug.get(slug);
|
|
328
|
+
if (!globalConfig) return null;
|
|
329
|
+
return {
|
|
330
|
+
doc: await req.payload.findGlobal({
|
|
331
|
+
depth: 2,
|
|
332
|
+
...activeLocale ? {
|
|
333
|
+
locale: activeLocale
|
|
334
|
+
} : {},
|
|
335
|
+
overrideAccess: false,
|
|
336
|
+
req,
|
|
337
|
+
slug: slug
|
|
338
|
+
}).catch(()=>null),
|
|
339
|
+
key: `global:${slug}`
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
if (mention.type === "doc" && mention.collection && mention.id) {
|
|
343
|
+
const slug = mention.collection;
|
|
344
|
+
if (isInternalCollection(slug) || !collectionSlugSet.has(slug)) return null;
|
|
345
|
+
return {
|
|
346
|
+
doc: await req.payload.findByID({
|
|
347
|
+
collection: slug,
|
|
348
|
+
depth: 2,
|
|
349
|
+
id: mention.id,
|
|
350
|
+
...activeLocale ? {
|
|
351
|
+
locale: activeLocale
|
|
352
|
+
} : {},
|
|
353
|
+
overrideAccess: false,
|
|
354
|
+
req
|
|
355
|
+
}).catch(()=>null),
|
|
356
|
+
key: `doc:${slug}:${mention.id}`
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return null;
|
|
360
|
+
}));
|
|
361
|
+
const docsByMentionKey = new Map();
|
|
362
|
+
for (const result of mentionDocResults){
|
|
363
|
+
if (result) docsByMentionKey.set(result.key, result.doc);
|
|
364
|
+
}
|
|
293
365
|
if (localeConfigs.length > 0) {
|
|
294
366
|
context.push({
|
|
295
367
|
activeLocale,
|
|
@@ -301,7 +373,7 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
301
373
|
}
|
|
302
374
|
for (const mention of mentions.slice(0, 8)){
|
|
303
375
|
if (mention.type === "locale" && mention.slug) {
|
|
304
|
-
const locale =
|
|
376
|
+
const locale = localeConfigsByCode.get(mention.slug);
|
|
305
377
|
if (!locale) continue;
|
|
306
378
|
const key = `locale:${locale.code}`;
|
|
307
379
|
if (seen.has(key)) continue;
|
|
@@ -314,8 +386,8 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
314
386
|
if (mention.type === "collection" && mention.slug) {
|
|
315
387
|
const slug = mention.slug;
|
|
316
388
|
const key = `collection:${slug}`;
|
|
317
|
-
if (seen.has(key) || isInternalCollection(slug) || !
|
|
318
|
-
const collectionConfig =
|
|
389
|
+
if (seen.has(key) || isInternalCollection(slug) || !collectionSlugSet.has(slug)) continue;
|
|
390
|
+
const collectionConfig = collectionConfigsBySlug.get(slug);
|
|
319
391
|
if (!collectionConfig) continue;
|
|
320
392
|
seen.add(key);
|
|
321
393
|
context.push(describeCollectionLikeConfig({
|
|
@@ -327,18 +399,10 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
327
399
|
if (mention.type === "global" && mention.slug) {
|
|
328
400
|
const slug = mention.slug;
|
|
329
401
|
const key = `global:${slug}`;
|
|
330
|
-
if (seen.has(key) || !
|
|
331
|
-
const globalConfig =
|
|
402
|
+
if (seen.has(key) || !globalSlugSet.has(slug)) continue;
|
|
403
|
+
const globalConfig = globalConfigsBySlug.get(slug);
|
|
332
404
|
if (!globalConfig) continue;
|
|
333
|
-
const globalDoc =
|
|
334
|
-
depth: 2,
|
|
335
|
-
...activeLocale ? {
|
|
336
|
-
locale: activeLocale
|
|
337
|
-
} : {},
|
|
338
|
-
overrideAccess: false,
|
|
339
|
-
req,
|
|
340
|
-
slug: slug
|
|
341
|
-
}).catch(()=>null);
|
|
405
|
+
const globalDoc = docsByMentionKey.get(key) ?? null;
|
|
342
406
|
seen.add(key);
|
|
343
407
|
context.push({
|
|
344
408
|
...describeCollectionLikeConfig({
|
|
@@ -349,7 +413,7 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
349
413
|
});
|
|
350
414
|
}
|
|
351
415
|
if (mention.type === "block" && mention.slug) {
|
|
352
|
-
const matchingBlocks =
|
|
416
|
+
const matchingBlocks = (blockContextsBySlug.get(mention.slug) || []).filter((block)=>!mention.parent || block.parent === mention.parent);
|
|
353
417
|
for (const block of matchingBlocks){
|
|
354
418
|
const key = `block:${block.parent}:${block.slug}`;
|
|
355
419
|
if (seen.has(key)) continue;
|
|
@@ -363,17 +427,8 @@ export const getMentionContext = async ({ blockContexts, collectionSlugs, collec
|
|
|
363
427
|
if (mention.type === "doc" && mention.collection && mention.id) {
|
|
364
428
|
const slug = mention.collection;
|
|
365
429
|
const key = `doc:${slug}:${mention.id}`;
|
|
366
|
-
if (seen.has(key) || isInternalCollection(slug) || !
|
|
367
|
-
const doc =
|
|
368
|
-
collection: slug,
|
|
369
|
-
depth: 2,
|
|
370
|
-
id: mention.id,
|
|
371
|
-
...activeLocale ? {
|
|
372
|
-
locale: activeLocale
|
|
373
|
-
} : {},
|
|
374
|
-
overrideAccess: false,
|
|
375
|
-
req
|
|
376
|
-
}).catch(()=>null);
|
|
430
|
+
if (seen.has(key) || isInternalCollection(slug) || !collectionSlugSet.has(slug)) continue;
|
|
431
|
+
const doc = docsByMentionKey.get(key);
|
|
377
432
|
if (!doc) continue;
|
|
378
433
|
seen.add(key);
|
|
379
434
|
context.push({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mvriu5/payload-ai",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "AI assistant plugin for Payload CMS with provider selection, CMS mentions, and signed action proposals.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"test:e2e:headed": "playwright test --headed",
|
|
64
64
|
"test:handlers": "vitest run tests/handlers",
|
|
65
65
|
"test:unit": "vitest run tests/unit",
|
|
66
|
-
"
|
|
66
|
+
"knip": "knip"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@ai-sdk/anthropic": "^3.0.81",
|
|
@@ -71,21 +71,21 @@
|
|
|
71
71
|
"@ai-sdk/mistral": "^3.0.37",
|
|
72
72
|
"@ai-sdk/openai": "^3.0.67",
|
|
73
73
|
"@openrouter/ai-sdk-provider": "^2.9.1",
|
|
74
|
-
"@playwright/test": "^1.56.1",
|
|
75
74
|
"@payloadcms/db-postgres": "3.84.1",
|
|
76
75
|
"@payloadcms/next": "3.84.1",
|
|
77
76
|
"@payloadcms/richtext-lexical": "3.84.1",
|
|
78
77
|
"@payloadcms/ui": "3.84.1",
|
|
78
|
+
"@playwright/test": "^1.56.1",
|
|
79
79
|
"@swc/cli": "0.8.1",
|
|
80
80
|
"@types/node": "25.9.3",
|
|
81
81
|
"@types/react": "19.2.17",
|
|
82
82
|
"@types/react-dom": "19.2.3",
|
|
83
83
|
"copyfiles": "2.4.1",
|
|
84
|
-
"cross-env": "^
|
|
84
|
+
"cross-env": "^10.1.0",
|
|
85
85
|
"eslint": "^10.5.0",
|
|
86
|
-
"graphql": "^
|
|
86
|
+
"graphql": "^17.0.1",
|
|
87
87
|
"jsdom": "^29.1.1",
|
|
88
|
-
"knip": "^6.
|
|
88
|
+
"knip": "^6.18.0",
|
|
89
89
|
"next": "16.2.9",
|
|
90
90
|
"payload": "3.84.1",
|
|
91
91
|
"prettier": "^3.8.4",
|