@ai-stack/payloadcms 3.68.0 → 3.76.0-beta.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.
- package/dist/ai/core/media/image/generateImage.js +2 -6
- package/dist/ai/core/media/image/generateImage.js.map +1 -1
- package/dist/ai/core/media/image/handlers/multimodal.js +5 -0
- package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -1
- package/dist/ai/core/streamObject.js +3 -3
- package/dist/ai/core/streamObject.js.map +1 -1
- package/dist/ai/core/types.d.ts +3 -0
- package/dist/ai/core/types.js.map +1 -1
- package/dist/ai/prompts.d.ts +1 -2
- package/dist/ai/prompts.js +0 -110
- package/dist/ai/prompts.js.map +1 -1
- package/dist/ai/providers/blocks/anthropic.js +2 -1
- package/dist/ai/providers/blocks/anthropic.js.map +1 -1
- package/dist/ai/providers/blocks/elevenlabs.js +3 -2
- package/dist/ai/providers/blocks/elevenlabs.js.map +1 -1
- package/dist/ai/providers/blocks/fal.js +2 -1
- package/dist/ai/providers/blocks/fal.js.map +1 -1
- package/dist/ai/providers/blocks/google.js +11 -6
- package/dist/ai/providers/blocks/google.js.map +1 -1
- package/dist/ai/providers/blocks/openai-compatible.js +2 -1
- package/dist/ai/providers/blocks/openai-compatible.js.map +1 -1
- package/dist/ai/providers/blocks/openai.js +3 -2
- package/dist/ai/providers/blocks/openai.js.map +1 -1
- package/dist/ai/providers/blocks/xai.js +2 -1
- package/dist/ai/providers/blocks/xai.js.map +1 -1
- package/dist/ai/providers/icons.d.ts +7 -0
- package/dist/ai/providers/icons.js +9 -0
- package/dist/ai/providers/icons.js.map +1 -0
- package/dist/ai/providers/registry.js +34 -24
- package/dist/ai/providers/registry.js.map +1 -1
- package/dist/ai/utils/filterEditorSchemaByNodes.d.ts +9 -0
- package/dist/ai/utils/filterEditorSchemaByNodes.js +30 -3
- package/dist/ai/utils/filterEditorSchemaByNodes.js.map +1 -1
- package/dist/ai/utils/nodeToSchemaMap.d.ts +22 -0
- package/dist/ai/utils/nodeToSchemaMap.js +72 -0
- package/dist/ai/utils/nodeToSchemaMap.js.map +1 -0
- package/dist/collections/AIJobs.js +1 -1
- package/dist/collections/AIJobs.js.map +1 -1
- package/dist/collections/AISettings.js +47 -20
- package/dist/collections/AISettings.js.map +1 -1
- package/dist/collections/Instructions.js +37 -0
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/defaults.d.ts +1 -0
- package/dist/defaults.js +8 -0
- package/dist/defaults.js.map +1 -1
- package/dist/endpoints/chat.d.ts +4 -0
- package/dist/endpoints/fetchFields.js +10 -0
- package/dist/endpoints/fetchFields.js.map +1 -1
- package/dist/endpoints/fetchVoices.js +41 -24
- package/dist/endpoints/fetchVoices.js.map +1 -1
- package/dist/endpoints/index.js +194 -16
- package/dist/endpoints/index.js.map +1 -1
- package/dist/exports/fields.d.ts +1 -0
- package/dist/exports/fields.js +1 -0
- package/dist/exports/fields.js.map +1 -1
- package/dist/fields/ArrayComposeField/ArrayComposeField.d.ts +15 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.js +87 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.js.map +1 -0
- package/dist/fields/ArrayComposeField/ArrayComposeField.jsx +73 -0
- package/dist/fields/PromptEditorField/PromptEditorField.js +7 -2
- package/dist/fields/PromptEditorField/PromptEditorField.js.map +1 -1
- package/dist/fields/PromptEditorField/PromptEditorField.jsx +5 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/payload-ai.d.ts +152 -0
- package/dist/plugin.js +16 -32
- package/dist/plugin.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.js +47 -15
- package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +39 -16
- package/dist/providers/InstructionsProvider/context.d.ts +3 -0
- package/dist/providers/InstructionsProvider/context.js +2 -0
- package/dist/providers/InstructionsProvider/context.js.map +1 -1
- package/dist/providers/InstructionsProvider/useInstructions.js +21 -2
- package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
- package/dist/styles.d.ts +11 -0
- package/dist/types/handlebars-async-helpers.d.ts +1 -0
- package/dist/types/handlebars-dist-handlebars.d.ts +1 -0
- package/dist/types/react-mentions.d.ts +1 -0
- package/dist/types.d.ts +34 -5
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/ui/AIConfigDashboard/index.js +198 -22
- package/dist/ui/AIConfigDashboard/index.js.map +1 -1
- package/dist/ui/AIConfigDashboard/index.jsx +159 -13
- package/dist/ui/Compose/Compose.d.ts +1 -0
- package/dist/ui/Compose/Compose.js +23 -4
- package/dist/ui/Compose/Compose.js.map +1 -1
- package/dist/ui/Compose/Compose.jsx +23 -4
- package/dist/ui/Compose/UndoRedoActions.d.ts +2 -2
- package/dist/ui/Compose/UndoRedoActions.js +8 -5
- package/dist/ui/Compose/UndoRedoActions.js.map +1 -1
- package/dist/ui/Compose/UndoRedoActions.jsx +6 -5
- package/dist/ui/Compose/compose.module.css +56 -16
- package/dist/ui/Compose/hooks/menu/itemsMap.js +12 -6
- package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.js +26 -15
- package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.jsx +25 -12
- package/dist/ui/Compose/hooks/useGenerate.js +26 -174
- package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
- package/dist/ui/Compose/hooks/useGenerateUpload.d.ts +11 -0
- package/dist/ui/Compose/hooks/useGenerateUpload.js +150 -0
- package/dist/ui/Compose/hooks/useGenerateUpload.js.map +1 -0
- package/dist/ui/Compose/hooks/useHistory.d.ts +0 -1
- package/dist/ui/Compose/hooks/useHistory.js +65 -25
- package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
- package/dist/ui/Compose/hooks/useStreamingUpdate.d.ts +8 -0
- package/dist/ui/Compose/hooks/useStreamingUpdate.js +48 -0
- package/dist/ui/Compose/hooks/useStreamingUpdate.js.map +1 -0
- package/dist/ui/DynamicVoiceSelect/index.js +63 -11
- package/dist/ui/DynamicVoiceSelect/index.js.map +1 -1
- package/dist/ui/DynamicVoiceSelect/index.jsx +47 -14
- package/dist/ui/EncryptedTextField/index.js +4 -4
- package/dist/ui/EncryptedTextField/index.js.map +1 -1
- package/dist/ui/EncryptedTextField/index.jsx +4 -4
- package/dist/ui/VoicesFetcher/index.js +34 -16
- package/dist/ui/VoicesFetcher/index.js.map +1 -1
- package/dist/ui/VoicesFetcher/index.jsx +32 -15
- package/dist/utilities/buildSmartPrompt.d.ts +22 -0
- package/dist/utilities/buildSmartPrompt.js +141 -0
- package/dist/utilities/buildSmartPrompt.js.map +1 -0
- package/dist/utilities/encryption.js +2 -1
- package/dist/utilities/encryption.js.map +1 -1
- package/dist/utilities/fieldToJsonSchema.js +32 -3
- package/dist/utilities/fieldToJsonSchema.js.map +1 -1
- package/dist/utilities/resolveImageReferences.d.ts +3 -1
- package/dist/utilities/resolveImageReferences.js +21 -2
- package/dist/utilities/resolveImageReferences.js.map +1 -1
- package/dist/utilities/seedProperties.d.ts +7 -0
- package/dist/utilities/seedProperties.js +100 -0
- package/dist/utilities/seedProperties.js.map +1 -0
- package/dist/utilities/setSafeLexicalState.js +79 -6
- package/dist/utilities/setSafeLexicalState.js.map +1 -1
- package/dist/utilities/updateFieldsConfig.d.ts +1 -1
- package/dist/utilities/updateFieldsConfig.js +8 -1
- package/dist/utilities/updateFieldsConfig.js.map +1 -1
- package/package.json +35 -33
- package/dist/endpoints/chat.d.js +0 -3
- package/dist/endpoints/chat.d.js.map +0 -1
- package/dist/init.d.ts +0 -7
- package/dist/init.js +0 -135
- package/dist/init.js.map +0 -1
- package/dist/payload-ai.d.js +0 -3
- package/dist/payload-ai.d.js.map +0 -1
- package/dist/styles.d.js +0 -2
- package/dist/styles.d.js.map +0 -1
- package/dist/types/handlebars-async-helpers.d.js +0 -2
- package/dist/types/handlebars-async-helpers.d.js.map +0 -1
- package/dist/types/handlebars-dist-handlebars.d.js +0 -2
- package/dist/types/handlebars-dist-handlebars.d.js.map +0 -1
- package/dist/types/react-mentions.d.js +0 -2
- package/dist/types/react-mentions.d.js.map +0 -1
|
@@ -1,15 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieves a nested value from an object using dot-notation path.
|
|
3
|
+
* For example, getNestedValue(obj, 'a.b.c') returns obj.a.b.c
|
|
4
|
+
*/ function getNestedValue(obj, path) {
|
|
5
|
+
return path.split('.').reduce((current, key)=>{
|
|
6
|
+
if (current && typeof current === 'object' && key in current) {
|
|
7
|
+
return current[key];
|
|
8
|
+
}
|
|
9
|
+
return undefined;
|
|
10
|
+
}, obj);
|
|
11
|
+
}
|
|
1
12
|
/**
|
|
2
13
|
* Parses and resolves image references in prompts.
|
|
3
14
|
*
|
|
4
15
|
* Supports two formats:
|
|
5
16
|
* - @fieldName - for single upload fields
|
|
17
|
+
* - @collection.fieldName - schema path format (collection prefix is stripped)
|
|
6
18
|
* - @fieldName:filename.jpg - for specific images in hasMany fields
|
|
7
19
|
*
|
|
8
20
|
* @param prompt - The prompt text containing @field references
|
|
9
21
|
* @param contextData - The document data to resolve field values from
|
|
10
22
|
* @param req - Payload request object for fetching media
|
|
23
|
+
* @param collectionSlug - Optional collection slug to strip from schema path references
|
|
11
24
|
* @returns Processed prompt with references removed and array of resolved images
|
|
12
|
-
*/ export async function resolveImageReferences(prompt, contextData, req) {
|
|
25
|
+
*/ export async function resolveImageReferences(prompt, contextData, req, collectionSlug) {
|
|
13
26
|
// Pattern matches: @fieldName or @fieldName:filename.ext (filename can have spaces)
|
|
14
27
|
// The filename part matches everything up to and including an image extension
|
|
15
28
|
const pattern = /@([\w.]+)(?::(.+?\.(?:png|jpe?g|webp|gif)))?/gi;
|
|
@@ -34,7 +47,13 @@
|
|
|
34
47
|
// Resolve each reference
|
|
35
48
|
for (const ref of references){
|
|
36
49
|
try {
|
|
37
|
-
|
|
50
|
+
// Strip collection prefix from schema path if it matches the current collection
|
|
51
|
+
// e.g., "characters.ortho3d.frame" becomes "ortho3d.frame" when collectionSlug is "characters"
|
|
52
|
+
let fieldPath = ref.fieldName;
|
|
53
|
+
if (collectionSlug && fieldPath.startsWith(`${collectionSlug}.`)) {
|
|
54
|
+
fieldPath = fieldPath.slice(collectionSlug.length + 1);
|
|
55
|
+
}
|
|
56
|
+
const fieldValue = getNestedValue(contextData, fieldPath);
|
|
38
57
|
if (!fieldValue) {
|
|
39
58
|
req.payload.logger.warn(`Image reference @${ref.fieldName} not found in document context`);
|
|
40
59
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/resolveImageReferences.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\ninterface ImageReference {\n fieldName: string\n filename?: string\n fullMatch: string\n}\n\nexport interface ResolvedImage {\n image: {\n mimeType?: string\n name: string\n thumbnailURL?: string\n type: string\n url: string\n }\n}\n\ninterface ResolveImageReferencesResult {\n images: ResolvedImage[]\n processedPrompt: string\n}\n\n/**\n * Parses and resolves image references in prompts.\n * \n * Supports two formats:\n * - @fieldName - for single upload fields\n * - @fieldName:filename.jpg - for specific images in hasMany fields\n * \n * @param prompt - The prompt text containing @field references\n * @param contextData - The document data to resolve field values from\n * @param req - Payload request object for fetching media\n * @returns Processed prompt with references removed and array of resolved images\n */\nexport async function resolveImageReferences(\n prompt: string,\n contextData: Record<string, unknown>,\n req: PayloadRequest,\n): Promise<ResolveImageReferencesResult> {\n // Pattern matches: @fieldName or @fieldName:filename.ext (filename can have spaces)\n // The filename part matches everything up to and including an image extension\n const pattern = /@([\\w.]+)(?::(.+?\\.(?:png|jpe?g|webp|gif)))?/gi\n const references: ImageReference[] = []\n let match: null | RegExpExecArray\n\n // Extract all image references\n while ((match = pattern.exec(prompt)) !== null) {\n references.push({\n fieldName: match[1],\n filename: match[2],\n fullMatch: match[0],\n })\n }\n\n if (references.length === 0) {\n return { images: [], processedPrompt: prompt }\n }\n\n const resolvedImages: ResolvedImage[] = []\n let processedPrompt = prompt\n\n // Resolve each reference\n for (const ref of references) {\n try {\n const fieldValue = contextData[ref.fieldName]\n\n if (!fieldValue) {\n req.payload.logger.warn(\n `Image reference @${ref.fieldName} not found in document context`,\n )\n continue\n }\n\n // Handle single upload field (value is an ID or object)\n if (!ref.filename) {\n const mediaDoc = await resolveMediaDocument(fieldValue, req)\n if (mediaDoc) {\n resolvedImages.push(formatImageData(mediaDoc))\n }\n }\n // Handle hasMany field with filename\n else {\n const mediaDoc = await resolveMediaFromArray(fieldValue, ref.filename, req)\n if (mediaDoc) {\n resolvedImages.push(formatImageData(mediaDoc))\n }\n }\n\n // Remove the reference from the prompt\n processedPrompt = processedPrompt.replace(ref.fullMatch, '')\n } catch (error) {\n req.payload.logger.error(\n error,\n `Error resolving image reference: ${ref.fullMatch}`,\n )\n }\n }\n\n // Clean up extra whitespace from removed references\n processedPrompt = processedPrompt.replace(/\\s+/g, ' ').trim()\n\n return {\n images: resolvedImages,\n processedPrompt,\n }\n}\n\n/**\n * Resolves a single media document from an ID or populated object\n */\nasync function resolveMediaDocument(\n value: unknown,\n req: PayloadRequest,\n): Promise<null | Record<string, unknown>> {\n // If it's already a populated object with required fields\n if (typeof value === 'object' && value !== null && 'url' in value) {\n return value as Record<string, unknown>\n }\n\n // If it's an ID string, fetch the media document\n if (typeof value === 'string' || typeof value === 'number') {\n try {\n // Try to find which collection this media belongs to\n // First, check the common 'media' collection\n const collections = ['media', 'uploads']\n\n for (const collectionSlug of collections) {\n try {\n const mediaDoc = await req.payload.findByID({\n id: value,\n collection: collectionSlug,\n req,\n })\n if (mediaDoc) {\n return mediaDoc as Record<string, unknown>\n }\n } catch (_ignore) {\n // Continue to next collection\n continue\n }\n }\n } catch (error) {\n req.payload.logger.error(error, 'Error fetching media document')\n }\n }\n\n return null\n}\n\n/**\n * Resolves a specific media document from an array by matching filename\n */\nasync function resolveMediaFromArray(\n arrayValue: unknown,\n filename: string,\n req: PayloadRequest,\n): Promise<null | Record<string, unknown>> {\n if (!Array.isArray(arrayValue)) {\n return null\n }\n\n // Search through array for matching filename\n for (const item of arrayValue) {\n const mediaDoc = await resolveMediaDocument(item, req)\n\n if (mediaDoc && matchesFilename(mediaDoc, filename)) {\n return mediaDoc\n }\n }\n\n return null\n}\n\n/**\n * Checks if a media document matches the given filename\n */\nfunction matchesFilename(mediaDoc: Record<string, unknown>, filename: string): boolean {\n const docFilename = mediaDoc.filename || mediaDoc.name\n\n if (!docFilename) {\n return false\n }\n\n // Case-insensitive match\n return (docFilename as string).toLowerCase() === filename.toLowerCase()\n}\n\n/**\n * Formats media document into the expected image data structure\n */\nfunction formatImageData(mediaDoc: Record<string, unknown>): ResolvedImage {\n return {\n image: {\n name: (mediaDoc.filename || mediaDoc.name || 'unknown') as string,\n type: extractFileExtension((mediaDoc.filename || mediaDoc.name || '') as string),\n mimeType: (mediaDoc.mimeType || mediaDoc.mimetype) as string | undefined,\n thumbnailURL: mediaDoc.thumbnailURL as string | undefined,\n url: mediaDoc.url as string,\n },\n }\n}\n\n/**\n * Extracts file extension from filename\n */\nfunction extractFileExtension(filename: string): string {\n const match = filename.match(/\\.([^.]+)$/)\n return match ? match[1].toLowerCase() : 'unknown'\n}\n"],"names":["resolveImageReferences","prompt","contextData","req","pattern","references","match","exec","push","fieldName","filename","fullMatch","length","images","processedPrompt","resolvedImages","ref","fieldValue","payload","logger","warn","mediaDoc","resolveMediaDocument","formatImageData","resolveMediaFromArray","replace","error","trim","value","collections","collectionSlug","findByID","id","collection","_ignore","arrayValue","Array","isArray","item","matchesFilename","docFilename","name","toLowerCase","image","type","extractFileExtension","mimeType","mimetype","thumbnailURL","url"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/resolveImageReferences.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\ninterface ImageReference {\n fieldName: string\n filename?: string\n fullMatch: string\n}\n\nexport interface ResolvedImage {\n image: {\n mimeType?: string\n name: string\n thumbnailURL?: string\n type: string\n url: string\n }\n}\n\ninterface ResolveImageReferencesResult {\n images: ResolvedImage[]\n processedPrompt: string\n}\n\n/**\n * Retrieves a nested value from an object using dot-notation path.\n * For example, getNestedValue(obj, 'a.b.c') returns obj.a.b.c\n */\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n return path.split('.').reduce((current, key) => {\n if (current && typeof current === 'object' && key in current) {\n return (current as Record<string, unknown>)[key]\n }\n return undefined\n }, obj as unknown)\n}\n\n/**\n * Parses and resolves image references in prompts.\n * \n * Supports two formats:\n * - @fieldName - for single upload fields\n * - @collection.fieldName - schema path format (collection prefix is stripped)\n * - @fieldName:filename.jpg - for specific images in hasMany fields\n * \n * @param prompt - The prompt text containing @field references\n * @param contextData - The document data to resolve field values from\n * @param req - Payload request object for fetching media\n * @param collectionSlug - Optional collection slug to strip from schema path references\n * @returns Processed prompt with references removed and array of resolved images\n */\nexport async function resolveImageReferences(\n prompt: string,\n contextData: Record<string, unknown>,\n req: PayloadRequest,\n collectionSlug?: string,\n): Promise<ResolveImageReferencesResult> {\n // Pattern matches: @fieldName or @fieldName:filename.ext (filename can have spaces)\n // The filename part matches everything up to and including an image extension\n const pattern = /@([\\w.]+)(?::(.+?\\.(?:png|jpe?g|webp|gif)))?/gi\n const references: ImageReference[] = []\n let match: null | RegExpExecArray\n\n // Extract all image references\n while ((match = pattern.exec(prompt)) !== null) {\n references.push({\n fieldName: match[1],\n filename: match[2],\n fullMatch: match[0],\n })\n }\n\n if (references.length === 0) {\n return { images: [], processedPrompt: prompt }\n }\n\n const resolvedImages: ResolvedImage[] = []\n let processedPrompt = prompt\n\n // Resolve each reference\n for (const ref of references) {\n try {\n // Strip collection prefix from schema path if it matches the current collection\n // e.g., \"characters.ortho3d.frame\" becomes \"ortho3d.frame\" when collectionSlug is \"characters\"\n let fieldPath = ref.fieldName\n if (collectionSlug && fieldPath.startsWith(`${collectionSlug}.`)) {\n fieldPath = fieldPath.slice(collectionSlug.length + 1)\n }\n\n const fieldValue = getNestedValue(contextData, fieldPath)\n\n if (!fieldValue) {\n req.payload.logger.warn(\n `Image reference @${ref.fieldName} not found in document context`,\n )\n continue\n }\n\n // Handle single upload field (value is an ID or object)\n if (!ref.filename) {\n const mediaDoc = await resolveMediaDocument(fieldValue, req)\n if (mediaDoc) {\n resolvedImages.push(formatImageData(mediaDoc))\n }\n }\n // Handle hasMany field with filename\n else {\n const mediaDoc = await resolveMediaFromArray(fieldValue, ref.filename, req)\n if (mediaDoc) {\n resolvedImages.push(formatImageData(mediaDoc))\n }\n }\n\n // Remove the reference from the prompt\n processedPrompt = processedPrompt.replace(ref.fullMatch, '')\n } catch (error) {\n req.payload.logger.error(\n error,\n `Error resolving image reference: ${ref.fullMatch}`,\n )\n }\n }\n\n // Clean up extra whitespace from removed references\n processedPrompt = processedPrompt.replace(/\\s+/g, ' ').trim()\n\n return {\n images: resolvedImages,\n processedPrompt,\n }\n}\n\n/**\n * Resolves a single media document from an ID or populated object\n */\nasync function resolveMediaDocument(\n value: unknown,\n req: PayloadRequest,\n): Promise<null | Record<string, unknown>> {\n // If it's already a populated object with required fields\n if (typeof value === 'object' && value !== null && 'url' in value) {\n return value as Record<string, unknown>\n }\n\n // If it's an ID string, fetch the media document\n if (typeof value === 'string' || typeof value === 'number') {\n try {\n // Try to find which collection this media belongs to\n // First, check the common 'media' collection\n const collections = ['media', 'uploads']\n\n for (const collectionSlug of collections) {\n try {\n const mediaDoc = await req.payload.findByID({\n id: value,\n collection: collectionSlug,\n req,\n })\n if (mediaDoc) {\n return mediaDoc as Record<string, unknown>\n }\n } catch (_ignore) {\n // Continue to next collection\n continue\n }\n }\n } catch (error) {\n req.payload.logger.error(error, 'Error fetching media document')\n }\n }\n\n return null\n}\n\n/**\n * Resolves a specific media document from an array by matching filename\n */\nasync function resolveMediaFromArray(\n arrayValue: unknown,\n filename: string,\n req: PayloadRequest,\n): Promise<null | Record<string, unknown>> {\n if (!Array.isArray(arrayValue)) {\n return null\n }\n\n // Search through array for matching filename\n for (const item of arrayValue) {\n const mediaDoc = await resolveMediaDocument(item, req)\n\n if (mediaDoc && matchesFilename(mediaDoc, filename)) {\n return mediaDoc\n }\n }\n\n return null\n}\n\n/**\n * Checks if a media document matches the given filename\n */\nfunction matchesFilename(mediaDoc: Record<string, unknown>, filename: string): boolean {\n const docFilename = mediaDoc.filename || mediaDoc.name\n\n if (!docFilename) {\n return false\n }\n\n // Case-insensitive match\n return (docFilename as string).toLowerCase() === filename.toLowerCase()\n}\n\n/**\n * Formats media document into the expected image data structure\n */\nfunction formatImageData(mediaDoc: Record<string, unknown>): ResolvedImage {\n return {\n image: {\n name: (mediaDoc.filename || mediaDoc.name || 'unknown') as string,\n type: extractFileExtension((mediaDoc.filename || mediaDoc.name || '') as string),\n mimeType: (mediaDoc.mimeType || mediaDoc.mimetype) as string | undefined,\n thumbnailURL: mediaDoc.thumbnailURL as string | undefined,\n url: mediaDoc.url as string,\n },\n }\n}\n\n/**\n * Extracts file extension from filename\n */\nfunction extractFileExtension(filename: string): string {\n const match = filename.match(/\\.([^.]+)$/)\n return match ? match[1].toLowerCase() : 'unknown'\n}\n"],"names":["getNestedValue","obj","path","split","reduce","current","key","undefined","resolveImageReferences","prompt","contextData","req","collectionSlug","pattern","references","match","exec","push","fieldName","filename","fullMatch","length","images","processedPrompt","resolvedImages","ref","fieldPath","startsWith","slice","fieldValue","payload","logger","warn","mediaDoc","resolveMediaDocument","formatImageData","resolveMediaFromArray","replace","error","trim","value","collections","findByID","id","collection","_ignore","arrayValue","Array","isArray","item","matchesFilename","docFilename","name","toLowerCase","image","type","extractFileExtension","mimeType","mimetype","thumbnailURL","url"],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js';
|
|
2
|
+
import { updateFieldsConfig } from './updateFieldsConfig.js';
|
|
3
|
+
export const seedProperties = async ({ enabledCollections, req })=>{
|
|
4
|
+
const { payload } = req;
|
|
5
|
+
if (!enabledCollections || enabledCollections.length === 0) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
// Get all collections from payload config
|
|
9
|
+
const allCollections = payload.config.collections;
|
|
10
|
+
for (const collectionSlug of enabledCollections){
|
|
11
|
+
const collectionConfig = allCollections.find((c)=>c.slug === collectionSlug);
|
|
12
|
+
if (!collectionConfig) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
// Traverse the collection config effectively using updateFieldsConfig
|
|
16
|
+
// Use the side-effect of getting schemaPathMap from it
|
|
17
|
+
const { schemaPathMap } = updateFieldsConfig(collectionConfig);
|
|
18
|
+
for (const [schemaPath, fieldInfo] of Object.entries(schemaPathMap)){
|
|
19
|
+
const { type, custom, relationTo } = fieldInfo;
|
|
20
|
+
// Check if instruction already exists
|
|
21
|
+
const existingInstruction = await payload.find({
|
|
22
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
23
|
+
depth: 0,
|
|
24
|
+
limit: 1,
|
|
25
|
+
overrideAccess: true,
|
|
26
|
+
where: {
|
|
27
|
+
'schema-path': {
|
|
28
|
+
equals: schemaPath
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (existingInstruction.totalDocs > 0) {
|
|
33
|
+
// If developer has provided custom prompts in the schema, update the existing record
|
|
34
|
+
// but only if the values have actually changed.
|
|
35
|
+
if (custom?.ai?.prompt || custom?.ai?.system) {
|
|
36
|
+
const doc = existingInstruction.docs[0];
|
|
37
|
+
const currentPrompt = doc.prompt;
|
|
38
|
+
const currentSystem = doc.system;
|
|
39
|
+
let needsUpdate = false;
|
|
40
|
+
const updateData = {};
|
|
41
|
+
if (custom?.ai?.prompt && custom.ai.prompt !== currentPrompt) {
|
|
42
|
+
updateData.prompt = custom.ai.prompt;
|
|
43
|
+
needsUpdate = true;
|
|
44
|
+
}
|
|
45
|
+
if (custom?.ai?.system && custom.ai.system !== currentSystem) {
|
|
46
|
+
updateData.system = custom.ai.system;
|
|
47
|
+
needsUpdate = true;
|
|
48
|
+
}
|
|
49
|
+
if (needsUpdate) {
|
|
50
|
+
try {
|
|
51
|
+
await payload.update({
|
|
52
|
+
id: doc.id,
|
|
53
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
54
|
+
data: updateData,
|
|
55
|
+
overrideAccess: true
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
payload.logger.error(`Failed to update instruction for ${schemaPath}: ${error}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Use custom prompts if provided, otherwise leave empty
|
|
65
|
+
const prompt = custom?.ai?.prompt || '';
|
|
66
|
+
const system = custom?.ai?.system || '';
|
|
67
|
+
// Determine model-id based on field type
|
|
68
|
+
let modelId = 'text';
|
|
69
|
+
if (type === 'richText') {
|
|
70
|
+
modelId = 'richtext';
|
|
71
|
+
}
|
|
72
|
+
if (type === 'upload') {
|
|
73
|
+
modelId = 'image';
|
|
74
|
+
} // defaulting to image generation for uploads
|
|
75
|
+
if (type === 'array') {
|
|
76
|
+
modelId = 'array';
|
|
77
|
+
}
|
|
78
|
+
// Create new instruction
|
|
79
|
+
try {
|
|
80
|
+
await payload.create({
|
|
81
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
82
|
+
data: {
|
|
83
|
+
disabled: false,
|
|
84
|
+
'field-type': type,
|
|
85
|
+
'model-id': modelId,
|
|
86
|
+
prompt,
|
|
87
|
+
'relation-to': relationTo,
|
|
88
|
+
'schema-path': schemaPath,
|
|
89
|
+
system
|
|
90
|
+
},
|
|
91
|
+
overrideAccess: true
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
payload.logger.error(`Failed to seed instruction for ${schemaPath}: ${error}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
//# sourceMappingURL=seedProperties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/seedProperties.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { updateFieldsConfig } from './updateFieldsConfig.js'\n\ninterface SeedPropertiesArgs {\n enabledCollections: string[]\n req: PayloadRequest\n}\n\nexport const seedProperties = async ({ enabledCollections, req }: SeedPropertiesArgs): Promise<void> => {\n const { payload } = req\n\n if (!enabledCollections || enabledCollections.length === 0) {\n return\n }\n\n // Get all collections from payload config\n const allCollections = payload.config.collections\n\n for (const collectionSlug of enabledCollections) {\n const collectionConfig = allCollections.find((c) => c.slug === collectionSlug)\n if (!collectionConfig) {\n continue\n }\n\n // Traverse the collection config effectively using updateFieldsConfig\n // Use the side-effect of getting schemaPathMap from it\n const { schemaPathMap } = updateFieldsConfig(collectionConfig)\n\n for (const [schemaPath, fieldInfo] of Object.entries(schemaPathMap)) {\n const { type, custom, relationTo } = fieldInfo as {\n custom?: { ai?: { prompt?: string; system?: string } }\n relationTo?: string\n type: string\n }\n\n // Check if instruction already exists\n const existingInstruction = await payload.find({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n depth: 0,\n limit: 1,\n overrideAccess: true,\n where: {\n 'schema-path': {\n equals: schemaPath,\n },\n },\n })\n\n if (existingInstruction.totalDocs > 0) {\n // If developer has provided custom prompts in the schema, update the existing record\n // but only if the values have actually changed.\n if (custom?.ai?.prompt || custom?.ai?.system) {\n const doc = existingInstruction.docs[0] as any\n const currentPrompt = doc.prompt\n const currentSystem = doc.system\n\n let needsUpdate = false\n const updateData: any = {}\n\n if (custom?.ai?.prompt && custom.ai.prompt !== currentPrompt) {\n updateData.prompt = custom.ai.prompt\n needsUpdate = true\n }\n if (custom?.ai?.system && custom.ai.system !== currentSystem) {\n updateData.system = custom.ai.system\n needsUpdate = true\n }\n\n if (needsUpdate) {\n try {\n await payload.update({\n id: doc.id,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n data: updateData,\n overrideAccess: true,\n })\n } catch (error) {\n payload.logger.error(`Failed to update instruction for ${schemaPath}: ${error}`)\n }\n }\n }\n continue\n }\n\n // Use custom prompts if provided, otherwise leave empty\n const prompt = custom?.ai?.prompt || ''\n const system = custom?.ai?.system || ''\n\n // Determine model-id based on field type\n let modelId = 'text'\n if (type === 'richText') {\n modelId = 'richtext'\n }\n if (type === 'upload') {\n modelId = 'image'\n } // defaulting to image generation for uploads\n if (type === 'array') {\n modelId = 'array'\n }\n\n // Create new instruction\n try {\n await payload.create({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n data: {\n disabled: false,\n 'field-type': type,\n 'model-id': modelId,\n prompt,\n 'relation-to': relationTo,\n 'schema-path': schemaPath,\n system,\n },\n overrideAccess: true,\n })\n } catch (error) {\n payload.logger.error(`Failed to seed instruction for ${schemaPath}: ${error}`)\n }\n }\n }\n}\n"],"names":["PLUGIN_INSTRUCTIONS_TABLE","updateFieldsConfig","seedProperties","enabledCollections","req","payload","length","allCollections","config","collections","collectionSlug","collectionConfig","find","c","slug","schemaPathMap","schemaPath","fieldInfo","Object","entries","type","custom","relationTo","existingInstruction","collection","depth","limit","overrideAccess","where","equals","totalDocs","ai","prompt","system","doc","docs","currentPrompt","currentSystem","needsUpdate","updateData","update","id","data","error","logger","modelId","create","disabled"],"mappings":"AAEA,SAASA,yBAAyB,QAAQ,iBAAgB;AAC1D,SAASC,kBAAkB,QAAQ,0BAAyB;AAO5D,OAAO,MAAMC,iBAAiB,OAAO,EAAEC,kBAAkB,EAAEC,GAAG,EAAsB;IAClF,MAAM,EAAEC,OAAO,EAAE,GAAGD;IAEpB,IAAI,CAACD,sBAAsBA,mBAAmBG,MAAM,KAAK,GAAG;QAC1D;IACF;IAEA,0CAA0C;IAC1C,MAAMC,iBAAiBF,QAAQG,MAAM,CAACC,WAAW;IAEjD,KAAK,MAAMC,kBAAkBP,mBAAoB;QAC/C,MAAMQ,mBAAmBJ,eAAeK,IAAI,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAKJ;QAC/D,IAAI,CAACC,kBAAkB;YACrB;QACF;QAEA,sEAAsE;QACtE,uDAAuD;QACvD,MAAM,EAAEI,aAAa,EAAE,GAAGd,mBAAmBU;QAE7C,KAAK,MAAM,CAACK,YAAYC,UAAU,IAAIC,OAAOC,OAAO,CAACJ,eAAgB;YACnE,MAAM,EAAEK,IAAI,EAAEC,MAAM,EAAEC,UAAU,EAAE,GAAGL;YAMrC,sCAAsC;YACtC,MAAMM,sBAAsB,MAAMlB,QAAQO,IAAI,CAAC;gBAC7CY,YAAYxB;gBACZyB,OAAO;gBACPC,OAAO;gBACPC,gBAAgB;gBAChBC,OAAO;oBACL,eAAe;wBACbC,QAAQb;oBACV;gBACF;YACF;YAEA,IAAIO,oBAAoBO,SAAS,GAAG,GAAG;gBACrC,qFAAqF;gBACrF,gDAAgD;gBAChD,IAAIT,QAAQU,IAAIC,UAAUX,QAAQU,IAAIE,QAAQ;oBAC5C,MAAMC,MAAMX,oBAAoBY,IAAI,CAAC,EAAE;oBACvC,MAAMC,gBAAgBF,IAAIF,MAAM;oBAChC,MAAMK,gBAAgBH,IAAID,MAAM;oBAEhC,IAAIK,cAAc;oBAClB,MAAMC,aAAkB,CAAC;oBAEzB,IAAIlB,QAAQU,IAAIC,UAAUX,OAAOU,EAAE,CAACC,MAAM,KAAKI,eAAe;wBAC5DG,WAAWP,MAAM,GAAGX,OAAOU,EAAE,CAACC,MAAM;wBACpCM,cAAc;oBAChB;oBACA,IAAIjB,QAAQU,IAAIE,UAAUZ,OAAOU,EAAE,CAACE,MAAM,KAAKI,eAAe;wBAC5DE,WAAWN,MAAM,GAAGZ,OAAOU,EAAE,CAACE,MAAM;wBACpCK,cAAc;oBAChB;oBAEA,IAAIA,aAAa;wBACf,IAAI;4BACF,MAAMjC,QAAQmC,MAAM,CAAC;gCACnBC,IAAIP,IAAIO,EAAE;gCACVjB,YAAYxB;gCACZ0C,MAAMH;gCACNZ,gBAAgB;4BAClB;wBACF,EAAE,OAAOgB,OAAO;4BACdtC,QAAQuC,MAAM,CAACD,KAAK,CAAC,CAAC,iCAAiC,EAAE3B,WAAW,EAAE,EAAE2B,MAAM,CAAC;wBACjF;oBACF;gBACF;gBACA;YACF;YAEA,wDAAwD;YACxD,MAAMX,SAASX,QAAQU,IAAIC,UAAU;YACrC,MAAMC,SAASZ,QAAQU,IAAIE,UAAU;YAErC,yCAAyC;YACzC,IAAIY,UAAU;YACd,IAAIzB,SAAS,YAAY;gBACvByB,UAAU;YACZ;YACA,IAAIzB,SAAS,UAAU;gBACrByB,UAAU;YACZ,EAAE,6CAA6C;YAC/C,IAAIzB,SAAS,SAAS;gBACpByB,UAAU;YACZ;YAEA,yBAAyB;YACzB,IAAI;gBACF,MAAMxC,QAAQyC,MAAM,CAAC;oBACnBtB,YAAYxB;oBACZ0C,MAAM;wBACJK,UAAU;wBACV,cAAc3B;wBACd,YAAYyB;wBACZb;wBACA,eAAeV;wBACf,eAAeN;wBACfiB;oBACF;oBACAN,gBAAgB;gBAClB;YACF,EAAE,OAAOgB,OAAO;gBACdtC,QAAQuC,MAAM,CAACD,KAAK,CAAC,CAAC,+BAA+B,EAAE3B,WAAW,EAAE,EAAE2B,MAAM,CAAC;YAC/E;QACF;IACF;AACF,EAAC"}
|
|
@@ -1,15 +1,88 @@
|
|
|
1
|
+
const sanitizeLexicalState = (state)=>{
|
|
2
|
+
// 1. Ensure root exists and is valid
|
|
3
|
+
if (!state || typeof state !== 'object') {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
// If no root, or root is not an object, it's invalid
|
|
7
|
+
if (!state.root || typeof state.root !== 'object') {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
// 2. Clone to avoid mutation
|
|
11
|
+
const cleanState = JSON.parse(JSON.stringify(state));
|
|
12
|
+
// 3. Ensure root has required props
|
|
13
|
+
cleanState.root.type = 'root';
|
|
14
|
+
cleanState.root.format = cleanState.root.format || 'left';
|
|
15
|
+
cleanState.root.indent = cleanState.root.indent || 0;
|
|
16
|
+
cleanState.root.version = cleanState.root.version || 1;
|
|
17
|
+
// 4. Recursive sanitizer for children
|
|
18
|
+
const sanitizeNode = (node)=>{
|
|
19
|
+
if (!node || typeof node !== 'object') {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// Must have a type. If streaming incomplete node (type is missing/empty), discard it.
|
|
23
|
+
if (!node.type || typeof node.type !== 'string') {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// Default version if missing
|
|
27
|
+
node.version = node.version || 1;
|
|
28
|
+
// If node has children, sanitize them
|
|
29
|
+
if (Array.isArray(node.children)) {
|
|
30
|
+
node.children = node.children.map(sanitizeNode).filter((child)=>child !== null);
|
|
31
|
+
} else {
|
|
32
|
+
// Ensure children is at least an empty array if it's supposed to be there?
|
|
33
|
+
// Actually lots of leaf nodes don't have children.
|
|
34
|
+
// But Root, Paragraph, etc do.
|
|
35
|
+
// Let's safe-guard standard ElementNodes:
|
|
36
|
+
if ([
|
|
37
|
+
'heading',
|
|
38
|
+
'link',
|
|
39
|
+
'list',
|
|
40
|
+
'listitem',
|
|
41
|
+
'paragraph',
|
|
42
|
+
'quote',
|
|
43
|
+
'root'
|
|
44
|
+
].includes(node.type)) {
|
|
45
|
+
node.children = node.children || [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Specific node fixes
|
|
49
|
+
if (node.type === 'text') {
|
|
50
|
+
// Text nodes must have text prop
|
|
51
|
+
if (typeof node.text !== 'string') {
|
|
52
|
+
// If text is missing, it might be incomplete.
|
|
53
|
+
// We can either discard or default to empty string.
|
|
54
|
+
// For streaming, empty string is safer than discarding early if we want to show cursor?
|
|
55
|
+
node.text = node.text || '';
|
|
56
|
+
}
|
|
57
|
+
node.mode = node.mode ?? 0;
|
|
58
|
+
node.style = node.style || '';
|
|
59
|
+
node.detail = node.detail ?? 0;
|
|
60
|
+
}
|
|
61
|
+
return node;
|
|
62
|
+
};
|
|
63
|
+
// 5. Sanitize root's children
|
|
64
|
+
if (Array.isArray(cleanState.root.children)) {
|
|
65
|
+
cleanState.root.children = cleanState.root.children.map(sanitizeNode).filter((child)=>child !== null);
|
|
66
|
+
} else {
|
|
67
|
+
cleanState.root.children = [];
|
|
68
|
+
}
|
|
69
|
+
return cleanState;
|
|
70
|
+
};
|
|
1
71
|
export const setSafeLexicalState = (state, editorInstance)=>{
|
|
2
72
|
try {
|
|
3
|
-
const
|
|
73
|
+
const validState = sanitizeLexicalState(state);
|
|
74
|
+
if (!validState) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const editorState = editorInstance.parseEditorState(validState);
|
|
4
78
|
if (editorState.isEmpty()) {
|
|
5
79
|
return;
|
|
6
80
|
}
|
|
7
81
|
editorInstance.setEditorState(editorState);
|
|
8
|
-
} catch (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
});
|
|
82
|
+
} catch (_error) {
|
|
83
|
+
// Silently catch errors during streaming to avoid console noise.
|
|
84
|
+
// Lexical's parseEditorState is very strict and will throw if the
|
|
85
|
+
// object structure is even slightly incomplete during the stream.
|
|
13
86
|
}
|
|
14
87
|
};
|
|
15
88
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/setSafeLexicalState.ts"],"sourcesContent":["import type { LexicalEditor } from 'lexical'\n\
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/setSafeLexicalState.ts"],"sourcesContent":["import type { LexicalEditor } from 'lexical'\n\nconst sanitizeLexicalState = (state: any): any => {\n // 1. Ensure root exists and is valid\n if (!state || typeof state !== 'object') {\n return null\n }\n\n // If no root, or root is not an object, it's invalid\n if (!state.root || typeof state.root !== 'object') {\n return null\n }\n\n // 2. Clone to avoid mutation\n const cleanState = JSON.parse(JSON.stringify(state))\n\n // 3. Ensure root has required props\n cleanState.root.type = 'root'\n cleanState.root.format = cleanState.root.format || 'left'\n cleanState.root.indent = cleanState.root.indent || 0\n cleanState.root.version = cleanState.root.version || 1\n\n // 4. Recursive sanitizer for children\n const sanitizeNode = (node: any): any => {\n if (!node || typeof node !== 'object') {\n return null\n }\n\n // Must have a type. If streaming incomplete node (type is missing/empty), discard it.\n if (!node.type || typeof node.type !== 'string') {\n return null\n }\n\n // Default version if missing\n node.version = node.version || 1\n\n // If node has children, sanitize them\n if (Array.isArray(node.children)) {\n node.children = node.children\n .map(sanitizeNode)\n .filter((child: any) => child !== null)\n } else {\n // Ensure children is at least an empty array if it's supposed to be there? \n // Actually lots of leaf nodes don't have children. \n // But Root, Paragraph, etc do. \n // Let's safe-guard standard ElementNodes:\n if (['heading', 'link', 'list', 'listitem', 'paragraph', 'quote', 'root'].includes(node.type)) {\n node.children = node.children || []\n }\n }\n\n // Specific node fixes\n if (node.type === 'text') {\n // Text nodes must have text prop\n if (typeof node.text !== 'string') {\n // If text is missing, it might be incomplete. \n // We can either discard or default to empty string.\n // For streaming, empty string is safer than discarding early if we want to show cursor?\n node.text = node.text || ''\n }\n node.mode = node.mode ?? 0\n node.style = node.style || ''\n node.detail = node.detail ?? 0\n }\n\n return node\n }\n\n // 5. Sanitize root's children\n if (Array.isArray(cleanState.root.children)) {\n cleanState.root.children = cleanState.root.children\n .map(sanitizeNode)\n .filter((child: any) => child !== null)\n } else {\n cleanState.root.children = []\n }\n\n return cleanState\n}\n\nexport const setSafeLexicalState = (state: unknown, editorInstance: LexicalEditor) => {\n try {\n const validState = sanitizeLexicalState(state)\n \n if (!validState) {\n return\n }\n\n const editorState = editorInstance.parseEditorState(validState)\n if (editorState.isEmpty()) {\n return\n }\n\n editorInstance.setEditorState(editorState)\n } catch (_error) {\n // Silently catch errors during streaming to avoid console noise.\n // Lexical's parseEditorState is very strict and will throw if the\n // object structure is even slightly incomplete during the stream.\n }\n}\n\n"],"names":["sanitizeLexicalState","state","root","cleanState","JSON","parse","stringify","type","format","indent","version","sanitizeNode","node","Array","isArray","children","map","filter","child","includes","text","mode","style","detail","setSafeLexicalState","editorInstance","validState","editorState","parseEditorState","isEmpty","setEditorState","_error"],"mappings":"AAEA,MAAMA,uBAAuB,CAACC;IAC5B,qCAAqC;IACrC,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU;QACvC,OAAO;IACT;IAEA,qDAAqD;IACrD,IAAI,CAACA,MAAMC,IAAI,IAAI,OAAOD,MAAMC,IAAI,KAAK,UAAU;QACjD,OAAO;IACT;IAEA,6BAA6B;IAC7B,MAAMC,aAAaC,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACL;IAE7C,oCAAoC;IACpCE,WAAWD,IAAI,CAACK,IAAI,GAAG;IACvBJ,WAAWD,IAAI,CAACM,MAAM,GAAGL,WAAWD,IAAI,CAACM,MAAM,IAAI;IACnDL,WAAWD,IAAI,CAACO,MAAM,GAAGN,WAAWD,IAAI,CAACO,MAAM,IAAI;IACnDN,WAAWD,IAAI,CAACQ,OAAO,GAAGP,WAAWD,IAAI,CAACQ,OAAO,IAAI;IAErD,sCAAsC;IACtC,MAAMC,eAAe,CAACC;QACpB,IAAI,CAACA,QAAQ,OAAOA,SAAS,UAAU;YACrC,OAAO;QACT;QAEA,sFAAsF;QACtF,IAAI,CAACA,KAAKL,IAAI,IAAI,OAAOK,KAAKL,IAAI,KAAK,UAAU;YAC/C,OAAO;QACT;QAEA,6BAA6B;QAC7BK,KAAKF,OAAO,GAAGE,KAAKF,OAAO,IAAI;QAE/B,sCAAsC;QACtC,IAAIG,MAAMC,OAAO,CAACF,KAAKG,QAAQ,GAAG;YAChCH,KAAKG,QAAQ,GAAGH,KAAKG,QAAQ,CAC1BC,GAAG,CAACL,cACJM,MAAM,CAAC,CAACC,QAAeA,UAAU;QACtC,OAAO;YACL,4EAA4E;YAC5E,oDAAoD;YACpD,gCAAgC;YAChC,0CAA0C;YAC1C,IAAI;gBAAC;gBAAW;gBAAQ;gBAAQ;gBAAY;gBAAa;gBAAS;aAAO,CAACC,QAAQ,CAACP,KAAKL,IAAI,GAAG;gBAC7FK,KAAKG,QAAQ,GAAGH,KAAKG,QAAQ,IAAI,EAAE;YACrC;QACF;QAEA,sBAAsB;QACtB,IAAIH,KAAKL,IAAI,KAAK,QAAQ;YACxB,iCAAiC;YACjC,IAAI,OAAOK,KAAKQ,IAAI,KAAK,UAAU;gBACjC,+CAA+C;gBAC/C,oDAAoD;gBACpD,wFAAwF;gBACxFR,KAAKQ,IAAI,GAAGR,KAAKQ,IAAI,IAAI;YAC3B;YACAR,KAAKS,IAAI,GAAGT,KAAKS,IAAI,IAAI;YACzBT,KAAKU,KAAK,GAAGV,KAAKU,KAAK,IAAI;YAC3BV,KAAKW,MAAM,GAAGX,KAAKW,MAAM,IAAI;QAC/B;QAEA,OAAOX;IACT;IAEA,8BAA8B;IAC9B,IAAIC,MAAMC,OAAO,CAACX,WAAWD,IAAI,CAACa,QAAQ,GAAG;QAC3CZ,WAAWD,IAAI,CAACa,QAAQ,GAAGZ,WAAWD,IAAI,CAACa,QAAQ,CAChDC,GAAG,CAACL,cACJM,MAAM,CAAC,CAACC,QAAeA,UAAU;IACtC,OAAO;QACLf,WAAWD,IAAI,CAACa,QAAQ,GAAG,EAAE;IAC/B;IAEA,OAAOZ;AACT;AAEA,OAAO,MAAMqB,sBAAsB,CAACvB,OAAgBwB;IAClD,IAAI;QACF,MAAMC,aAAa1B,qBAAqBC;QAExC,IAAI,CAACyB,YAAY;YACf;QACF;QAEA,MAAMC,cAAcF,eAAeG,gBAAgB,CAACF;QACpD,IAAIC,YAAYE,OAAO,IAAI;YACzB;QACF;QAEAJ,eAAeK,cAAc,CAACH;IAChC,EAAE,OAAOI,QAAQ;IACf,iEAAiE;IACjE,kEAAkE;IAClE,kEAAkE;IACpE;AACF,EAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CollectionConfig, GlobalConfig } from 'payload';
|
|
2
2
|
interface UpdateFieldsConfig {
|
|
3
|
-
schemaPathMap: Record<string,
|
|
3
|
+
schemaPathMap: Record<string, any>;
|
|
4
4
|
updatedCollectionConfig: CollectionConfig | GlobalConfig;
|
|
5
5
|
}
|
|
6
6
|
export declare const updateFieldsConfig: (collectionConfig: CollectionConfig | GlobalConfig) => UpdateFieldsConfig;
|
|
@@ -11,6 +11,7 @@ export const updateFieldsConfig = (collectionConfig)=>{
|
|
|
11
11
|
// This is done due to save extra API call to get instructions when Field components are loaded in admin
|
|
12
12
|
// Doing is will only call instructions data when user clicks on settings
|
|
13
13
|
if ([
|
|
14
|
+
'array',
|
|
14
15
|
'richText',
|
|
15
16
|
'text',
|
|
16
17
|
'textarea',
|
|
@@ -20,13 +21,16 @@ export const updateFieldsConfig = (collectionConfig)=>{
|
|
|
20
21
|
...schemaPathMap,
|
|
21
22
|
[currentSchemaPath]: {
|
|
22
23
|
type: field.type,
|
|
24
|
+
custom: field.custom,
|
|
23
25
|
label: field.label || field.name,
|
|
24
26
|
relationTo: field.relationTo
|
|
25
27
|
}
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
// Inject AI actions, richText is not included here as it has to be explicitly defined by user
|
|
31
|
+
// Array fields also get AI injection for bulk generation
|
|
29
32
|
if ([
|
|
33
|
+
'array',
|
|
30
34
|
'text',
|
|
31
35
|
'textarea',
|
|
32
36
|
'upload'
|
|
@@ -39,6 +43,9 @@ export const updateFieldsConfig = (collectionConfig)=>{
|
|
|
39
43
|
// by overriding Description. If you need both, consider composing your own wrapper.
|
|
40
44
|
customField = {};
|
|
41
45
|
}
|
|
46
|
+
// Array fields use ArrayComposeField (always visible) since they don't have focus events
|
|
47
|
+
// Other fields use ComposeField with focus-dependent visibility
|
|
48
|
+
const componentPath = field.type === 'array' ? '@ai-stack/payloadcms/fields#ArrayComposeField' : '@ai-stack/payloadcms/fields#ComposeField';
|
|
42
49
|
return {
|
|
43
50
|
...field,
|
|
44
51
|
admin: {
|
|
@@ -49,7 +56,7 @@ export const updateFieldsConfig = (collectionConfig)=>{
|
|
|
49
56
|
clientProps: {
|
|
50
57
|
schemaPath: currentSchemaPath
|
|
51
58
|
},
|
|
52
|
-
path:
|
|
59
|
+
path: componentPath
|
|
53
60
|
},
|
|
54
61
|
...customField
|
|
55
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/updateFieldsConfig.ts"],"sourcesContent":["import type { CollectionConfig, GlobalConfig } from 'payload'\n\ninterface UpdateFieldsConfig {\n schemaPathMap: Record<string,
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/updateFieldsConfig.ts"],"sourcesContent":["import type { CollectionConfig, GlobalConfig } from 'payload'\n\ninterface UpdateFieldsConfig {\n schemaPathMap: Record<string, any>\n updatedCollectionConfig: CollectionConfig | GlobalConfig\n}\n\nexport const updateFieldsConfig = (collectionConfig: CollectionConfig | GlobalConfig): UpdateFieldsConfig => {\n let schemaPathMap = {}\n\n function updateField(field: any, parentPath = ''): any {\n const currentPath = parentPath ? `${parentPath}.${field.name}` : field.name\n const currentSchemaPath = `${collectionConfig.slug}.${currentPath}`\n\n // Disabled fields/ field types\n if (\n field.admin?.disabled ||\n field.admin?.readOnly ||\n field.admin?.hidden ||\n field.type === 'row'\n ) {\n return field\n }\n\n // Map field path for global fieldInstructionsMap to load related instructions\n // This is done due to save extra API call to get instructions when Field components are loaded in admin\n // Doing is will only call instructions data when user clicks on settings\n if (['array', 'richText', 'text', 'textarea', 'upload'].includes(field.type)) {\n schemaPathMap = {\n ...schemaPathMap,\n [currentSchemaPath]: {\n type: field.type,\n custom: field.custom,\n label: field.label || field.name,\n relationTo: field.relationTo,\n },\n }\n }\n\n // Inject AI actions, richText is not included here as it has to be explicitly defined by user\n // Array fields also get AI injection for bulk generation\n if (['array', 'text', 'textarea', 'upload'].includes(field.type)) {\n let customField = {}\n\n // Custom fields don't fully adhere to the Payload schema, making it difficult to\n // determine which components support injecting ComposeField as a Description.\n if (field.admin?.components?.Field || field.admin?.components?.Description) {\n // TODO: If a field already provides its own Description, we still inject our ComposeField\n // by overriding Description. If you need both, consider composing your own wrapper.\n customField = {}\n }\n\n // Array fields use ArrayComposeField (always visible) since they don't have focus events\n // Other fields use ComposeField with focus-dependent visibility\n const componentPath = field.type === 'array'\n ? '@ai-stack/payloadcms/fields#ArrayComposeField'\n : '@ai-stack/payloadcms/fields#ComposeField'\n\n return {\n ...field,\n admin: {\n ...field.admin,\n components: {\n ...(field.admin?.components || {}),\n Description: {\n clientProps: {\n schemaPath: currentSchemaPath,\n },\n path: componentPath,\n },\n ...customField,\n },\n },\n }\n }\n\n if (field.fields) {\n return {\n ...field,\n fields: field.fields.map((subField: any) => updateField(subField, currentPath)),\n }\n }\n\n if (field.tabs) {\n return {\n ...field,\n tabs: field.tabs.map((tab: any) => {\n return {\n ...tab,\n // Tabs are a UI construct and should not add to the schema path\n fields: (tab.fields || []).map((subField: any) => updateField(subField, parentPath)),\n }\n }),\n }\n }\n\n if (field.blocks) {\n return {\n ...field,\n blocks: field.blocks.map((block: any) => ({\n ...block,\n fields: block.fields.map((subField: any) =>\n updateField(subField, `${currentPath}.${block.slug}`),\n ),\n })),\n }\n }\n\n return field\n }\n\n const updatedCollectionConfig = {\n ...collectionConfig,\n fields: collectionConfig.fields.map((field) => updateField(field)),\n }\n\n return {\n schemaPathMap,\n updatedCollectionConfig,\n }\n}\n"],"names":["updateFieldsConfig","collectionConfig","schemaPathMap","updateField","field","parentPath","currentPath","name","currentSchemaPath","slug","admin","disabled","readOnly","hidden","type","includes","custom","label","relationTo","customField","components","Field","Description","componentPath","clientProps","schemaPath","path","fields","map","subField","tabs","tab","blocks","block","updatedCollectionConfig"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-stack/payloadcms",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.76.0-beta.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"bugs": "https://github.com/ashbuilds/payload-ai/issues",
|
|
6
6
|
"repository": "https://github.com/ashbuilds/payload-ai",
|
|
@@ -25,41 +25,42 @@
|
|
|
25
25
|
],
|
|
26
26
|
"exports": {
|
|
27
27
|
".": {
|
|
28
|
-
"import": "./
|
|
29
|
-
"types": "./
|
|
30
|
-
"default": "./
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
31
|
},
|
|
32
32
|
"./client": {
|
|
33
|
-
"import": "./
|
|
34
|
-
"types": "./
|
|
35
|
-
"default": "./
|
|
33
|
+
"import": "./dist/exports/client.js",
|
|
34
|
+
"types": "./dist/exports/client.d.ts",
|
|
35
|
+
"default": "./dist/exports/client.js"
|
|
36
36
|
},
|
|
37
37
|
"./types": {
|
|
38
|
-
"import": "./
|
|
39
|
-
"types": "./
|
|
40
|
-
"default": "./
|
|
38
|
+
"import": "./dist/exports/types.js",
|
|
39
|
+
"types": "./dist/exports/types.d.ts",
|
|
40
|
+
"default": "./dist/exports/types.js"
|
|
41
41
|
},
|
|
42
42
|
"./fields": {
|
|
43
|
-
"import": "./
|
|
44
|
-
"types": "./
|
|
45
|
-
"default": "./
|
|
43
|
+
"import": "./dist/exports/fields.js",
|
|
44
|
+
"types": "./dist/exports/fields.d.ts",
|
|
45
|
+
"default": "./dist/exports/fields.js"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
-
"main": "./
|
|
49
|
-
"types": "./
|
|
48
|
+
"main": "./dist/index.js",
|
|
49
|
+
"types": "./dist/index.d.ts",
|
|
50
50
|
"typesVersions": {
|
|
51
51
|
"*": {
|
|
52
52
|
"client": [
|
|
53
|
-
"
|
|
53
|
+
"dist/exports/client.d.ts"
|
|
54
54
|
],
|
|
55
55
|
"types": [
|
|
56
|
-
"
|
|
56
|
+
"dist/exports/types.d.ts"
|
|
57
57
|
],
|
|
58
58
|
"fields": [
|
|
59
|
-
"
|
|
59
|
+
"dist/exports/fields.d.ts"
|
|
60
60
|
],
|
|
61
61
|
"*": [
|
|
62
|
-
"
|
|
62
|
+
"dist/*.d.ts",
|
|
63
|
+
"dist/**/*.d.ts"
|
|
63
64
|
]
|
|
64
65
|
}
|
|
65
66
|
},
|
|
@@ -69,10 +70,10 @@
|
|
|
69
70
|
"scripts": {
|
|
70
71
|
"build": "pnpm copyfiles && pnpm build:types && pnpm build:swc",
|
|
71
72
|
"build:dev": "pnpm build --watch",
|
|
72
|
-
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
73
|
+
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths --ignore '**/*.d.ts'",
|
|
73
74
|
"build:types": "tsc --outDir dist --rootDir ./src",
|
|
74
75
|
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
75
|
-
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
76
|
+
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json,d.ts}\" dist/",
|
|
76
77
|
"dev": "next dev dev --turbo",
|
|
77
78
|
"dev:generate-importmap": "pnpm dev:payload generate:importmap",
|
|
78
79
|
"dev:generate-types": "pnpm dev:payload generate:types",
|
|
@@ -91,13 +92,13 @@
|
|
|
91
92
|
"devDependencies": {
|
|
92
93
|
"@eslint/eslintrc": "^3.2.0",
|
|
93
94
|
"@lexical/html": "0.35.0",
|
|
94
|
-
"@payloadcms/db-mongodb": "^3.
|
|
95
|
-
"@payloadcms/db-postgres": "^3.
|
|
96
|
-
"@payloadcms/db-sqlite": "^3.
|
|
97
|
-
"@payloadcms/eslint-config": "3.
|
|
98
|
-
"@payloadcms/next": "^3.
|
|
99
|
-
"@payloadcms/richtext-lexical": "^3.
|
|
100
|
-
"@payloadcms/ui": "^3.
|
|
95
|
+
"@payloadcms/db-mongodb": "^3.76.0",
|
|
96
|
+
"@payloadcms/db-postgres": "^3.76.0",
|
|
97
|
+
"@payloadcms/db-sqlite": "^3.76.0",
|
|
98
|
+
"@payloadcms/eslint-config": "3.28.0",
|
|
99
|
+
"@payloadcms/next": "^3.76.0",
|
|
100
|
+
"@payloadcms/richtext-lexical": "^3.76.0",
|
|
101
|
+
"@payloadcms/ui": "^3.76.0",
|
|
101
102
|
"@playwright/test": "^1.52.0",
|
|
102
103
|
"@swc-node/register": "1.10.9",
|
|
103
104
|
"@swc/cli": "0.6.0",
|
|
@@ -115,7 +116,7 @@
|
|
|
115
116
|
"mongodb-memory-server": "10.1.4",
|
|
116
117
|
"next": "15.4.7",
|
|
117
118
|
"open": "^10.1.0",
|
|
118
|
-
"payload": "^3.
|
|
119
|
+
"payload": "^3.76.0",
|
|
119
120
|
"prettier": "^3.4.2",
|
|
120
121
|
"qs-esm": "7.0.2",
|
|
121
122
|
"react": "19.1.0",
|
|
@@ -133,6 +134,7 @@
|
|
|
133
134
|
"@payloadcms/translations": "^3.55.1",
|
|
134
135
|
"@payloadcms/ui": "^3.55.1",
|
|
135
136
|
"lexical": "^0.35.0",
|
|
137
|
+
"next": ">=15.0.0",
|
|
136
138
|
"payload": "^3.55.1"
|
|
137
139
|
},
|
|
138
140
|
"engines": {
|
|
@@ -179,15 +181,15 @@
|
|
|
179
181
|
"registry": "https://registry.npmjs.org/",
|
|
180
182
|
"dependencies": {
|
|
181
183
|
"@ai-sdk/anthropic": "^2.0.50",
|
|
182
|
-
"@ai-sdk/openai": "^2.0.74",
|
|
183
|
-
"@ai-sdk/google": "^2.0.44",
|
|
184
|
-
"@ai-sdk/fal": "^1.0.24",
|
|
185
|
-
"@ai-sdk/xai": "^2.0.32",
|
|
186
184
|
"@ai-sdk/elevenlabs": "^1.0.20",
|
|
185
|
+
"@ai-sdk/fal": "^1.0.24",
|
|
186
|
+
"@ai-sdk/google": "^2.0.44",
|
|
187
|
+
"@ai-sdk/openai": "^2.0.74",
|
|
187
188
|
"@ai-sdk/openai-compatible": "^1.0.28",
|
|
188
189
|
"@ai-sdk/provider-utils": "^3.0.18",
|
|
189
190
|
"@ai-sdk/react": "^2.0.104",
|
|
190
191
|
"@ai-sdk/ui-utils": "^1.2.11",
|
|
192
|
+
"@ai-sdk/xai": "^2.0.32",
|
|
191
193
|
"@anthropic-ai/sdk": "^0.62.0",
|
|
192
194
|
"@fal-ai/client": "^1.7.0",
|
|
193
195
|
"@google/genai": "^1.30.0",
|
package/dist/endpoints/chat.d.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/chat.d.ts"],"sourcesContent":["import type { Endpoint } from 'payload';\n\nimport type { PluginConfig } from '../types.js';\nexport declare const Chat: (pluginConfig: PluginConfig) => Endpoint;\n"],"names":[],"mappings":"AAGA,WAAoE"}
|
package/dist/init.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Payload } from 'payload';
|
|
2
|
-
import type { PluginConfig } from './types.js';
|
|
3
|
-
export declare const init: (payload: Payload, fieldSchemaPaths: Record<string, {
|
|
4
|
-
label: string;
|
|
5
|
-
relationTo?: string;
|
|
6
|
-
type: string;
|
|
7
|
-
}>, pluginConfig: PluginConfig) => Promise<void>;
|