{"version":3,"sources":["../../../src/queues/config/collection.ts"],"sourcesContent":["import type { CollectionConfig } from '../../collections/config/types.js'\nimport type { SanitizedConfig } from '../../config/types.js'\nimport type { Field } from '../../fields/config/types.js'\nimport type { Job } from '../../index.js'\n\nimport { handleSchedulesJobsEndpoint } from '../endpoints/handleSchedules.js'\nimport { runJobsEndpoint } from '../endpoints/run.js'\nimport { getJobTaskStatus } from '../utilities/getJobTaskStatus.js'\n\nexport const jobsCollectionSlug = 'payload-jobs'\n\nexport const getDefaultJobsCollection: (jobsConfig: SanitizedConfig['jobs']) => CollectionConfig = (\n  jobsConfig,\n) => {\n  const workflowSlugs: Set<string> = new Set()\n  const taskSlugs: Set<string> = new Set(['inline'])\n\n  if (jobsConfig.workflows?.length) {\n    jobsConfig.workflows.forEach((workflow) => {\n      workflowSlugs.add(workflow.slug)\n\n      // Validate concurrency config requires enableConcurrencyControl flag\n      if (workflow.concurrency && !jobsConfig.enableConcurrencyControl) {\n        throw new Error(\n          `Workflow \"${workflow.slug}\" uses concurrency controls but \"jobs.enableConcurrencyControl\" is not enabled. ` +\n            `Set \"jobs.enableConcurrencyControl: true\" in your Payload config to use concurrency controls. ` +\n            `Note: This adds a new indexed field to the jobs collection schema and may require a database migration.`,\n        )\n      }\n    })\n  }\n\n  if (jobsConfig.tasks?.length) {\n    jobsConfig.tasks.forEach((task) => {\n      if (workflowSlugs.has(task.slug)) {\n        throw new Error(\n          `Task slug \"${task.slug}\" is already used by a workflow. No tasks are allowed to have the same slug as a workflow.`,\n        )\n      }\n\n      // Validate concurrency config requires enableConcurrencyControl flag\n      if (task.concurrency && !jobsConfig.enableConcurrencyControl) {\n        throw new Error(\n          `Task \"${task.slug}\" uses concurrency controls but \"jobs.enableConcurrencyControl\" is not enabled. ` +\n            `Set \"jobs.enableConcurrencyControl: true\" in your Payload config to use concurrency controls. ` +\n            `Note: This adds a new indexed field to the jobs collection schema and may require a database migration.`,\n        )\n      }\n\n      taskSlugs.add(task.slug)\n    })\n  }\n\n  const logFields: Field[] = [\n    {\n      name: 'executedAt',\n      type: 'date',\n      required: true,\n    },\n    {\n      name: 'completedAt',\n      type: 'date',\n      required: true,\n    },\n    {\n      name: 'taskSlug',\n      type: 'select',\n      options: [...taskSlugs],\n      required: true,\n    },\n    {\n      name: 'taskID',\n      type: 'text',\n      required: true,\n    },\n    /**\n     * @todo make required in 4.0\n     */\n    {\n      name: 'input',\n      type: 'json',\n    },\n    {\n      name: 'output',\n      type: 'json',\n    },\n    {\n      name: 'state',\n      type: 'radio',\n      options: ['failed', 'succeeded'],\n      required: true,\n    },\n    {\n      name: 'error',\n      type: 'json',\n      admin: {\n        condition: (_, data) => data.state === 'failed',\n      },\n      required: true,\n    },\n  ]\n\n  if (jobsConfig.addParentToTaskLog) {\n    logFields.push({\n      name: 'parent',\n      type: 'group',\n      fields: [\n        {\n          name: 'taskSlug',\n          type: 'select',\n          options: [...taskSlugs],\n        },\n        {\n          name: 'taskID',\n          type: 'text',\n        },\n      ],\n    })\n  }\n\n  const jobsCollection: CollectionConfig = {\n    slug: jobsCollectionSlug,\n    admin: {\n      group: 'System',\n      hidden: true,\n    },\n    endpoints: [runJobsEndpoint, handleSchedulesJobsEndpoint],\n    fields: [\n      {\n        name: 'input',\n        type: 'json',\n        admin: {\n          description: 'Input data provided to the job',\n        },\n      },\n      {\n        name: 'taskStatus',\n        type: 'json',\n        virtual: true,\n      },\n      {\n        type: 'tabs',\n        tabs: [\n          {\n            fields: [\n              {\n                name: 'completedAt',\n                type: 'date',\n                index: true,\n              },\n              {\n                name: 'totalTried',\n                type: 'number',\n                defaultValue: 0,\n                index: true,\n              },\n              {\n                name: 'hasError',\n                type: 'checkbox',\n                admin: {\n                  description: 'If hasError is true this job will not be retried',\n                },\n                defaultValue: false,\n                index: true,\n              },\n              {\n                name: 'error',\n                type: 'json',\n                admin: {\n                  condition: (data) => data.hasError,\n                  description: 'If hasError is true, this is the error that caused it',\n                },\n              },\n              {\n                name: 'log',\n                type: 'array',\n                admin: {\n                  description: 'Task execution log',\n                },\n                fields: logFields,\n              },\n            ],\n            label: 'Status',\n          },\n        ],\n      },\n      // only include the workflowSlugs field if workflows exist\n      ...((workflowSlugs.size > 0\n        ? [\n            {\n              name: 'workflowSlug',\n              type: 'select',\n              admin: {\n                position: 'sidebar',\n              },\n              index: true,\n              options: [...workflowSlugs],\n            },\n          ]\n        : []) as Field[]),\n      {\n        name: 'taskSlug',\n        type: 'select',\n        admin: {\n          position: 'sidebar',\n        },\n        index: true,\n        options: [...taskSlugs],\n        required: false,\n      },\n      {\n        name: 'queue',\n        type: 'text',\n        admin: {\n          position: 'sidebar',\n        },\n        defaultValue: 'default',\n        index: true,\n      },\n      {\n        name: 'waitUntil',\n        type: 'date',\n        admin: {\n          date: { pickerAppearance: 'dayAndTime' },\n        },\n        index: true,\n      },\n      {\n        name: 'processing',\n        type: 'checkbox',\n        admin: {\n          position: 'sidebar',\n        },\n        defaultValue: false,\n        index: true,\n      },\n      // Only add concurrencyKey field if concurrency control is enabled\n      ...(jobsConfig.enableConcurrencyControl\n        ? [\n            {\n              name: 'concurrencyKey',\n              type: 'text',\n              admin: {\n                description:\n                  'Used for concurrency control. Jobs with the same key are subject to exclusive/supersedes rules.',\n                position: 'sidebar',\n                readOnly: true,\n              },\n              index: true,\n            } as Field,\n          ]\n        : []),\n    ],\n    hooks: {\n      afterRead: [\n        ({ doc, req }) => {\n          // This hook is used to add the virtual `tasks` field to the document, that is computed from the `log` field\n\n          return jobAfterRead({ config: req.payload.config, doc })\n        },\n      ],\n      /**\n       * If another update comes in after a job as already been cancelled, we need to make sure that update doesn't\n       * change the state of the job.\n       */\n      beforeChange: [\n        ({ data, originalDoc }) => {\n          if (originalDoc?.error?.cancelled) {\n            data.processing = false\n            data.hasError = true\n            delete data.completedAt\n            delete data.waitUntil\n          }\n          return data\n        },\n      ],\n    },\n    lockDocuments: false,\n  }\n\n  if (jobsConfig.stats) {\n    // TODO: In 4.0, this should be added by default.\n    // The meta field can be used to store arbitrary data about the job. The scheduling system uses this to store\n    // `scheduled: true` to indicate that the job was queued by the scheduling system.\n    jobsCollection.fields.push({\n      name: 'meta',\n      type: 'json',\n    })\n  }\n  return jobsCollection\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function jobAfterRead({ config, doc }: { config: SanitizedConfig; doc: Job }): Job {\n  doc.taskStatus = getJobTaskStatus({\n    jobLog: doc.log || [],\n  })\n  doc.input = doc.input || {}\n  return doc\n}\n"],"names":["handleSchedulesJobsEndpoint","runJobsEndpoint","getJobTaskStatus","jobsCollectionSlug","getDefaultJobsCollection","jobsConfig","workflowSlugs","Set","taskSlugs","workflows","length","forEach","workflow","add","slug","concurrency","enableConcurrencyControl","Error","tasks","task","has","logFields","name","type","required","options","admin","condition","_","data","state","addParentToTaskLog","push","fields","jobsCollection","group","hidden","endpoints","description","virtual","tabs","index","defaultValue","hasError","label","size","position","date","pickerAppearance","readOnly","hooks","afterRead","doc","req","jobAfterRead","config","payload","beforeChange","originalDoc","error","cancelled","processing","completedAt","waitUntil","lockDocuments","stats","taskStatus","jobLog","log","input"],"mappings":"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"}