payload 3.2.2 → 3.2.3-canary.3e78927

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.
Files changed (131) hide show
  1. package/dist/admin/elements/DatePicker.d.ts +2 -2
  2. package/dist/admin/elements/DatePicker.d.ts.map +1 -1
  3. package/dist/admin/elements/DatePicker.js.map +1 -1
  4. package/dist/admin/types.js +3 -3
  5. package/dist/admin/types.js.map +1 -1
  6. package/dist/auth/cookies.js.map +1 -1
  7. package/dist/auth/crypto.js.map +1 -1
  8. package/dist/auth/extractJWT.js.map +1 -1
  9. package/dist/auth/operations/forgotPassword.js.map +1 -1
  10. package/dist/auth/operations/login.d.ts.map +1 -1
  11. package/dist/auth/operations/login.js +0 -12
  12. package/dist/auth/operations/login.js.map +1 -1
  13. package/dist/auth/operations/me.js.map +1 -1
  14. package/dist/auth/sendVerificationEmail.js.map +1 -1
  15. package/dist/auth/strategies/apiKey.js.map +1 -1
  16. package/dist/bin/generateImportMap/index.js.map +1 -1
  17. package/dist/bin/generateImportMap/parsePayloadComponent.js +1 -0
  18. package/dist/bin/generateImportMap/parsePayloadComponent.js.map +1 -1
  19. package/dist/bin/generateTypes.js.map +1 -1
  20. package/dist/bin/index.js.map +1 -1
  21. package/dist/bin/info.js.map +1 -1
  22. package/dist/bin/migrate.js.map +1 -1
  23. package/dist/collections/operations/findVersionByID.js +2 -0
  24. package/dist/collections/operations/findVersionByID.js.map +1 -1
  25. package/dist/collections/operations/findVersions.js +1 -0
  26. package/dist/collections/operations/findVersions.js.map +1 -1
  27. package/dist/config/client.js +2 -0
  28. package/dist/config/client.js.map +1 -1
  29. package/dist/config/defaults.js.map +1 -1
  30. package/dist/config/find.js.map +1 -1
  31. package/dist/config/sanitize.js.map +1 -1
  32. package/dist/database/getLocalizedPaths.js.map +1 -1
  33. package/dist/database/migrations/createMigration.js.map +1 -1
  34. package/dist/database/migrations/getPredefinedMigration.js.map +1 -1
  35. package/dist/database/migrations/migrate.js.map +1 -1
  36. package/dist/database/migrations/migrateDown.js.map +1 -1
  37. package/dist/database/migrations/migrateRefresh.js.map +1 -1
  38. package/dist/database/migrations/migrateReset.js.map +1 -1
  39. package/dist/database/migrations/readMigrationFiles.js.map +1 -1
  40. package/dist/database/migrations/writeMigrationIndex.js.map +1 -1
  41. package/dist/database/queryValidation/validateSearchParams.js.map +1 -1
  42. package/dist/email/sendEmail.js.map +1 -1
  43. package/dist/errors/AuthenticationError.js.map +1 -1
  44. package/dist/errors/FileRetrievalError.js.map +1 -1
  45. package/dist/errors/QueryError.js.map +1 -1
  46. package/dist/errors/ValidationError.js.map +1 -1
  47. package/dist/fields/config/client.js +1 -0
  48. package/dist/fields/config/client.js.map +1 -1
  49. package/dist/fields/config/sanitize.js +1 -1
  50. package/dist/fields/config/sanitize.js.map +1 -1
  51. package/dist/fields/config/sanitizeJoinField.js.map +1 -1
  52. package/dist/fields/config/types.d.ts +14 -0
  53. package/dist/fields/config/types.d.ts.map +1 -1
  54. package/dist/fields/config/types.js.map +1 -1
  55. package/dist/fields/getFieldPaths.js.map +1 -1
  56. package/dist/fields/hooks/afterRead/relationshipPopulationPromise.js +1 -0
  57. package/dist/fields/hooks/afterRead/relationshipPopulationPromise.js.map +1 -1
  58. package/dist/fields/hooks/beforeDuplicate/promise.js +1 -0
  59. package/dist/fields/hooks/beforeDuplicate/promise.js.map +1 -1
  60. package/dist/fields/hooks/beforeValidate/promise.js +1 -0
  61. package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
  62. package/dist/fields/mergeBaseFields.js +1 -0
  63. package/dist/fields/mergeBaseFields.js.map +1 -1
  64. package/dist/fields/setDefaultBeforeDuplicate.js.map +1 -1
  65. package/dist/fields/validations.d.ts +6 -2
  66. package/dist/fields/validations.d.ts.map +1 -1
  67. package/dist/fields/validations.js +5 -1
  68. package/dist/fields/validations.js.map +1 -1
  69. package/dist/globals/config/sanitize.js +1 -0
  70. package/dist/globals/config/sanitize.js.map +1 -1
  71. package/dist/globals/operations/findVersions.js +2 -0
  72. package/dist/globals/operations/findVersions.js.map +1 -1
  73. package/dist/index.d.ts +3 -1
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +2 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/preferences/deleteUserPreferences.js.map +1 -1
  78. package/dist/queues/config/generateJobsJSONSchemas.js.map +1 -1
  79. package/dist/queues/config/types/taskTypes.d.ts +23 -4
  80. package/dist/queues/config/types/taskTypes.d.ts.map +1 -1
  81. package/dist/queues/config/types/taskTypes.js.map +1 -1
  82. package/dist/queues/config/types/workflowJSONTypes.d.ts +5 -0
  83. package/dist/queues/config/types/workflowJSONTypes.d.ts.map +1 -1
  84. package/dist/queues/config/types/workflowJSONTypes.js.map +1 -1
  85. package/dist/queues/config/types/workflowTypes.d.ts +13 -5
  86. package/dist/queues/config/types/workflowTypes.d.ts.map +1 -1
  87. package/dist/queues/config/types/workflowTypes.js.map +1 -1
  88. package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
  89. package/dist/queues/operations/runJobs/index.js +2 -1
  90. package/dist/queues/operations/runJobs/index.js.map +1 -1
  91. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.d.ts.map +1 -1
  92. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +18 -5
  93. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
  94. package/dist/queues/operations/runJobs/runJob/handleWorkflowError.d.ts.map +1 -1
  95. package/dist/queues/operations/runJobs/runJob/handleWorkflowError.js +16 -16
  96. package/dist/queues/operations/runJobs/runJob/handleWorkflowError.js.map +1 -1
  97. package/dist/queues/operations/runJobs/runJob/importHandlerPath.d.ts.map +1 -1
  98. package/dist/queues/operations/runJobs/runJob/importHandlerPath.js +8 -1
  99. package/dist/queues/operations/runJobs/runJob/importHandlerPath.js.map +1 -1
  100. package/dist/queues/operations/runJobs/runJob/index.d.ts.map +1 -1
  101. package/dist/queues/operations/runJobs/runJob/index.js +6 -1
  102. package/dist/queues/operations/runJobs/runJob/index.js.map +1 -1
  103. package/dist/queues/utilities/getJobTaskStatus.d.ts.map +1 -1
  104. package/dist/queues/utilities/getJobTaskStatus.js +5 -0
  105. package/dist/queues/utilities/getJobTaskStatus.js.map +1 -1
  106. package/dist/uploads/deleteAssociatedFiles.js.map +1 -1
  107. package/dist/uploads/formatFilesize.js.map +1 -1
  108. package/dist/uploads/generateFileData.js.map +1 -1
  109. package/dist/uploads/getBaseFields.js.map +1 -1
  110. package/dist/uploads/getExternalFile.js.map +1 -1
  111. package/dist/uploads/getSafeFilename.js.map +1 -1
  112. package/dist/uploads/imageResizer.js.map +1 -1
  113. package/dist/utilities/addSelectGenericsToGeneretedTypes.js.map +1 -1
  114. package/dist/utilities/configToJSONSchema.js +1 -0
  115. package/dist/utilities/configToJSONSchema.js.map +1 -1
  116. package/dist/utilities/dependencies/dependencyChecker.js.map +1 -1
  117. package/dist/utilities/getDataByPath.js.map +1 -1
  118. package/dist/utilities/getSiblingData.js.map +1 -1
  119. package/dist/utilities/parseCookies.js.map +1 -1
  120. package/dist/utilities/sanitizePermissions.js +4 -0
  121. package/dist/utilities/sanitizePermissions.js.map +1 -1
  122. package/dist/utilities/telemetry/conf/envPaths.js.map +1 -1
  123. package/dist/utilities/telemetry/conf/index.js.map +1 -1
  124. package/dist/utilities/timestamp.js.map +1 -1
  125. package/dist/utilities/wordBoundariesRegex.js.map +1 -1
  126. package/dist/versions/drafts/appendVersionToQueryKey.js.map +1 -1
  127. package/dist/versions/drafts/getQueryDraftsSort.js.map +1 -1
  128. package/dist/versions/enforceMaxVersions.js.map +1 -1
  129. package/dist/versions/saveVersion.js +2 -0
  130. package/dist/versions/saveVersion.js.map +1 -1
  131. package/package.json +4 -4
@@ -6,6 +6,10 @@ export type JobLog = {
6
6
  completedAt: string;
7
7
  error?: unknown;
8
8
  executedAt: string;
9
+ /**
10
+ * ID added by the array field when the log is saved in the database
11
+ */
12
+ id?: string;
9
13
  input?: any;
10
14
  output?: any;
11
15
  state: 'failed' | 'succeeded';
@@ -64,9 +68,8 @@ export type WorkflowConfig<TWorkflowSlugOrInput extends keyof TypedJobs['workflo
64
68
  * You can either pass a string-based path to the workflow function file, or the workflow function itself.
65
69
  *
66
70
  * If you are using large dependencies within your workflow control flow, you might prefer to pass the string path
67
- * because that will avoid bundling large dependencies in your Next.js app.
68
- *
69
- *
71
+ * because that will avoid bundling large dependencies in your Next.js app. Passing a string path is an advanced feature
72
+ * that may require a sophisticated build pipeline in order to work.
70
73
  */
71
74
  handler: string | WorkflowHandler<TWorkflowSlugOrInput> | WorkflowJSON<TWorkflowSlugOrInput extends object ? string : TWorkflowSlugOrInput>;
72
75
  /**
@@ -88,9 +91,14 @@ export type WorkflowConfig<TWorkflowSlugOrInput extends keyof TypedJobs['workflo
88
91
  */
89
92
  queue?: string;
90
93
  /**
91
- * Specify the number of times that this workflow should be retried if it fails for any reason.
94
+ * You can define `retries` on the workflow level, which will enforce that the workflow can only fail up to that number of retries. If a task does not have retries specified, it will inherit the retry count as specified on the workflow.
95
+ *
96
+ * You can specify `0` as `workflow` retries, which will disregard all `task` retry specifications and fail the entire workflow on any task failure.
97
+ * You can leave `workflow` retries as undefined, in which case, the workflow will respect what each task dictates as their own retry count.
98
+ *
99
+ * @default undefined. By default, workflows retries are defined by their tasks
92
100
  */
93
- retries?: number | RetryConfig;
101
+ retries?: number | RetryConfig | undefined;
94
102
  /**
95
103
  * Define a slug-based name for this job.
96
104
  */
@@ -1 +1 @@
1
- {"version":3,"file":"workflowTypes.d.ts","sourceRoot":"","sources":["../../../../src/queues/config/types/workflowTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflowTypes.d.ts","sourceRoot":"","sources":["../../../../src/queues/config/types/workflowTypes.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/queues/config/types/workflowTypes.ts"],"sourcesContent":["import type { Field } from '../../../fields/config/types.js'\nimport type { PayloadRequest, StringKeyOf, TypedCollection, TypedJobs } from '../../../index.js'\nimport type {\n RetryConfig,\n RunInlineTaskFunction,\n RunTaskFunctions,\n TaskInput,\n TaskOutput,\n TaskType,\n} from './taskTypes.js'\nimport type { WorkflowJSON } from './workflowJSONTypes.js'\n\nexport type JobLog = {\n completedAt: string\n error?: unknown\n executedAt: string\n input?: any\n output?: any\n state: 'failed' | 'succeeded'\n taskID: string\n taskSlug: string\n}\n\nexport type BaseJob = {\n completedAt?: string\n error?: unknown\n hasError?: boolean\n id: number | string\n input?: any\n log: JobLog[]\n processing?: boolean\n queue: string\n taskSlug?: string\n taskStatus?: JobTaskStatus\n totalTried: number\n waitUntil?: string\n workflowSlug?: string\n}\n\nexport type WorkflowTypes = StringKeyOf<TypedJobs['workflows']>\n\n// TODO: Type job.taskStatus once available - for JSON-defined workflows\nexport type RunningJob<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> = {\n input: TWorkflowSlugOrInput extends keyof TypedJobs['workflows']\n ? TypedJobs['workflows'][TWorkflowSlugOrInput]['input']\n : TWorkflowSlugOrInput\n taskStatus: JobTaskStatus\n} & Omit<TypedCollection['payload-jobs'], 'input' | 'taskStatus'>\n\nexport type RunningJobSimple<TWorkflowInput extends object> = {\n input: TWorkflowInput\n} & TypedCollection['payload-jobs']\n\n// Simplified version of RunningJob that doesn't break TypeScript (TypeScript seems to stop evaluating RunningJob when it's too complex)\nexport type RunningJobFromTask<TTaskSlug extends keyof TypedJobs['tasks']> = {\n input: TypedJobs['tasks'][TTaskSlug]['input']\n} & TypedCollection['payload-jobs']\n\nexport type WorkflowHandler<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> =\n (args: {\n inlineTask: RunInlineTaskFunction\n job: RunningJob<TWorkflowSlugOrInput>\n req: PayloadRequest\n tasks: RunTaskFunctions\n }) => Promise<void>\n\nexport type SingleTaskStatus<T extends keyof TypedJobs['tasks']> = {\n complete: boolean\n input: TaskInput<T>\n output: TaskOutput<T>\n taskSlug: TaskType\n totalTried: number\n}\n\n/**\n * Task IDs mapped to their status\n */\nexport type JobTaskStatus = {\n // Wrap in taskSlug to improve typing\n [taskSlug in TaskType]: {\n [taskID: string]: SingleTaskStatus<taskSlug>\n }\n}\n\nexport type WorkflowConfig<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> = {\n /**\n * You can either pass a string-based path to the workflow function file, or the workflow function itself.\n *\n * If you are using large dependencies within your workflow control flow, you might prefer to pass the string path\n * because that will avoid bundling large dependencies in your Next.js app.\n *\n *\n */\n handler:\n | string\n | WorkflowHandler<TWorkflowSlugOrInput>\n | WorkflowJSON<TWorkflowSlugOrInput extends object ? string : TWorkflowSlugOrInput>\n /**\n * Define the input field schema - payload will generate a type for this schema.\n */\n inputSchema?: Field[]\n /**\n * You can use interfaceName to change the name of the interface that is generated for this workflow. By default, this is \"Workflow\" + the capitalized workflow slug.\n */\n interfaceName?: string\n /**\n * Define a human-friendly label for this workflow.\n */\n label?: string\n /**\n * Optionally, define the default queue name that this workflow should be tied to.\n * Defaults to \"default\".\n * Can be overridden when queuing jobs via Local API.\n */\n queue?: string\n /**\n * Specify the number of times that this workflow should be retried if it fails for any reason.\n */\n retries?: number | RetryConfig\n /**\n * Define a slug-based name for this job.\n */\n slug: TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] ? TWorkflowSlugOrInput : string\n}\n\ntype AllWorkflowConfigs = {\n [TWorkflowSlug in keyof TypedJobs['workflows']]: WorkflowConfig<TWorkflowSlug>\n}[keyof TypedJobs['workflows']]\n"],"names":[],"mappings":"AAoFA,WAuCC"}
1
+ {"version":3,"sources":["../../../../src/queues/config/types/workflowTypes.ts"],"sourcesContent":["import type { Field } from '../../../fields/config/types.js'\nimport type { PayloadRequest, StringKeyOf, TypedCollection, TypedJobs } from '../../../index.js'\nimport type {\n RetryConfig,\n RunInlineTaskFunction,\n RunTaskFunctions,\n TaskInput,\n TaskOutput,\n TaskType,\n} from './taskTypes.js'\nimport type { WorkflowJSON } from './workflowJSONTypes.js'\n\nexport type JobLog = {\n completedAt: string\n error?: unknown\n executedAt: string\n /**\n * ID added by the array field when the log is saved in the database\n */\n id?: string\n input?: any\n output?: any\n state: 'failed' | 'succeeded'\n taskID: string\n taskSlug: string\n}\n\nexport type BaseJob = {\n completedAt?: string\n error?: unknown\n hasError?: boolean\n id: number | string\n input?: any\n log: JobLog[]\n processing?: boolean\n queue: string\n taskSlug?: string\n taskStatus?: JobTaskStatus\n totalTried: number\n waitUntil?: string\n workflowSlug?: string\n}\n\nexport type WorkflowTypes = StringKeyOf<TypedJobs['workflows']>\n\n// TODO: Type job.taskStatus once available - for JSON-defined workflows\nexport type RunningJob<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> = {\n input: TWorkflowSlugOrInput extends keyof TypedJobs['workflows']\n ? TypedJobs['workflows'][TWorkflowSlugOrInput]['input']\n : TWorkflowSlugOrInput\n taskStatus: JobTaskStatus\n} & Omit<TypedCollection['payload-jobs'], 'input' | 'taskStatus'>\n\nexport type RunningJobSimple<TWorkflowInput extends object> = {\n input: TWorkflowInput\n} & TypedCollection['payload-jobs']\n\n// Simplified version of RunningJob that doesn't break TypeScript (TypeScript seems to stop evaluating RunningJob when it's too complex)\nexport type RunningJobFromTask<TTaskSlug extends keyof TypedJobs['tasks']> = {\n input: TypedJobs['tasks'][TTaskSlug]['input']\n} & TypedCollection['payload-jobs']\n\nexport type WorkflowHandler<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> =\n (args: {\n inlineTask: RunInlineTaskFunction\n job: RunningJob<TWorkflowSlugOrInput>\n req: PayloadRequest\n tasks: RunTaskFunctions\n }) => Promise<void>\n\nexport type SingleTaskStatus<T extends keyof TypedJobs['tasks']> = {\n complete: boolean\n input: TaskInput<T>\n output: TaskOutput<T>\n taskSlug: TaskType\n totalTried: number\n}\n\n/**\n * Task IDs mapped to their status\n */\nexport type JobTaskStatus = {\n // Wrap in taskSlug to improve typing\n [taskSlug in TaskType]: {\n [taskID: string]: SingleTaskStatus<taskSlug>\n }\n}\n\nexport type WorkflowConfig<TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] | object> = {\n /**\n * You can either pass a string-based path to the workflow function file, or the workflow function itself.\n *\n * If you are using large dependencies within your workflow control flow, you might prefer to pass the string path\n * because that will avoid bundling large dependencies in your Next.js app. Passing a string path is an advanced feature\n * that may require a sophisticated build pipeline in order to work.\n */\n handler:\n | string\n | WorkflowHandler<TWorkflowSlugOrInput>\n | WorkflowJSON<TWorkflowSlugOrInput extends object ? string : TWorkflowSlugOrInput>\n /**\n * Define the input field schema - payload will generate a type for this schema.\n */\n inputSchema?: Field[]\n /**\n * You can use interfaceName to change the name of the interface that is generated for this workflow. By default, this is \"Workflow\" + the capitalized workflow slug.\n */\n interfaceName?: string\n /**\n * Define a human-friendly label for this workflow.\n */\n label?: string\n /**\n * Optionally, define the default queue name that this workflow should be tied to.\n * Defaults to \"default\".\n * Can be overridden when queuing jobs via Local API.\n */\n queue?: string\n /**\n * You can define `retries` on the workflow level, which will enforce that the workflow can only fail up to that number of retries. If a task does not have retries specified, it will inherit the retry count as specified on the workflow.\n *\n * You can specify `0` as `workflow` retries, which will disregard all `task` retry specifications and fail the entire workflow on any task failure.\n * You can leave `workflow` retries as undefined, in which case, the workflow will respect what each task dictates as their own retry count.\n *\n * @default undefined. By default, workflows retries are defined by their tasks\n */\n retries?: number | RetryConfig | undefined\n /**\n * Define a slug-based name for this job.\n */\n slug: TWorkflowSlugOrInput extends keyof TypedJobs['workflows'] ? TWorkflowSlugOrInput : string\n}\n\ntype AllWorkflowConfigs = {\n [TWorkflowSlug in keyof TypedJobs['workflows']]: WorkflowConfig<TWorkflowSlug>\n}[keyof TypedJobs['workflows']]\n"],"names":[],"mappings":"AAwFA,WA2CC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/queues/operations/runJobs/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,yBAAyB,CAAA;AAQpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AASrD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxC;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,OAAO,2CAKjB,WAAW,KAAG,OAAO,CAAC,aAAa,CAsNrC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/queues/operations/runJobs/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,yBAAyB,CAAA;AAQpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AASrD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,cAAc,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxC;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,OAAO,2CAKjB,WAAW,KAAG,OAAO,CAAC,aAAa,CAuNrC,CAAA"}
@@ -118,7 +118,8 @@ export const runJobs = async ({ limit = 10, overrideAccess, queue, req })=>{
118
118
  } else {
119
119
  workflowHandler = await importHandlerPath(workflowConfig.handler);
120
120
  if (!workflowHandler) {
121
- const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${job.workflowSlug}.`;
121
+ const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`;
122
+ const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${jobLabel}.`;
122
123
  req.payload.logger.error(errorMessage);
123
124
  await updateJob({
124
125
  error: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/queues/operations/runJobs/index.ts"],"sourcesContent":["import type { PaginatedDocs } from '../../../database/types.js'\nimport type { PayloadRequest, Where } from '../../../types/index.js'\nimport type { WorkflowJSON } from '../../config/types/workflowJSONTypes.js'\nimport type {\n BaseJob,\n WorkflowConfig,\n WorkflowHandler,\n WorkflowTypes,\n} from '../../config/types/workflowTypes.js'\nimport type { RunJobResult } from './runJob/index.js'\n\nimport { Forbidden } from '../../../errors/Forbidden.js'\nimport isolateObjectProperty from '../../../utilities/isolateObjectProperty.js'\nimport { getUpdateJobFunction } from './runJob/getUpdateJobFunction.js'\nimport { importHandlerPath } from './runJob/importHandlerPath.js'\nimport { runJob } from './runJob/index.js'\nimport { runJSONJob } from './runJSONJob/index.js'\n\nexport type RunJobsArgs = {\n limit?: number\n overrideAccess?: boolean\n queue?: string\n req: PayloadRequest\n}\n\nexport type RunJobsResult = {\n jobStatus?: Record<string, RunJobResult>\n /**\n * If this is false, there for sure are no jobs remaining, regardless of the limit\n */\n noJobsRemaining?: boolean\n /**\n * Out of the jobs that were queried & processed (within the set limit), how many are remaining and retryable?\n */\n remainingJobsFromQueried: number\n}\n\nexport const runJobs = async ({\n limit = 10,\n overrideAccess,\n queue,\n req,\n}: RunJobsArgs): Promise<RunJobsResult> => {\n if (!overrideAccess) {\n const hasAccess = await req.payload.config.jobs.access.run({ req })\n if (!hasAccess) {\n throw new Forbidden(req.t)\n }\n }\n const where: Where = {\n and: [\n {\n completedAt: {\n exists: false,\n },\n },\n {\n hasError: {\n not_equals: true,\n },\n },\n {\n processing: {\n equals: false,\n },\n },\n {\n or: [\n {\n waitUntil: {\n exists: false,\n },\n },\n {\n waitUntil: {\n less_than: new Date().toISOString(),\n },\n },\n ],\n },\n ],\n }\n\n if (queue) {\n where.and.push({\n queue: {\n equals: queue,\n },\n })\n }\n\n // Find all jobs and ensure we set job to processing: true as early as possible to reduce the chance of\n // the same job being picked up by another worker\n const jobsQuery = (await req.payload.update({\n collection: 'payload-jobs',\n data: {\n processing: true,\n seenByWorker: true,\n },\n depth: req.payload.config.jobs.depth,\n disableTransaction: true,\n limit,\n showHiddenFields: true,\n where,\n })) as unknown as PaginatedDocs<BaseJob>\n\n /**\n * Just for logging purposes, we want to know how many jobs are new and how many are existing (= already been tried).\n * This is only for logs - in the end we still want to run all jobs, regardless of whether they are new or existing.\n */\n const { newJobs } = jobsQuery.docs.reduce(\n (acc, job) => {\n if (job.totalTried > 0) {\n acc.existingJobs.push(job)\n } else {\n acc.newJobs.push(job)\n }\n return acc\n },\n { existingJobs: [], newJobs: [] },\n )\n\n if (!jobsQuery.docs.length) {\n return {\n noJobsRemaining: true,\n remainingJobsFromQueried: 0,\n }\n }\n\n if (jobsQuery?.docs?.length) {\n req.payload.logger.info(`Running ${jobsQuery.docs.length} jobs.`)\n }\n const jobsToDelete: (number | string)[] | undefined = req.payload.config.jobs.deleteJobOnComplete\n ? []\n : undefined\n\n const jobPromises = jobsQuery.docs.map(async (job) => {\n if (!job.workflowSlug && !job.taskSlug) {\n throw new Error('Job must have either a workflowSlug or a taskSlug')\n }\n const jobReq = isolateObjectProperty(req, 'transactionID')\n\n const workflowConfig: WorkflowConfig<WorkflowTypes> = job.workflowSlug\n ? req.payload.config.jobs?.workflows.find(({ slug }) => slug === job.workflowSlug)\n : {\n slug: 'singleTask',\n handler: async ({ job, tasks }) => {\n await tasks[job.taskSlug as string]('1', {\n input: job.input,\n })\n },\n }\n\n if (!workflowConfig) {\n return null // Skip jobs with no workflow configuration\n }\n\n const updateJob = getUpdateJobFunction(job, jobReq)\n\n // the runner will either be passed to the config\n // OR it will be a path, which we will need to import via eval to avoid\n // Next.js compiler dynamic import expression errors\n let workflowHandler: WorkflowHandler<WorkflowTypes> | WorkflowJSON<WorkflowTypes>\n\n if (\n typeof workflowConfig.handler === 'function' ||\n (typeof workflowConfig.handler === 'object' && Array.isArray(workflowConfig.handler))\n ) {\n workflowHandler = workflowConfig.handler\n } else {\n workflowHandler = await importHandlerPath<typeof workflowHandler>(workflowConfig.handler)\n\n if (!workflowHandler) {\n const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${job.workflowSlug}.`\n req.payload.logger.error(errorMessage)\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n processing: false,\n })\n\n return\n }\n }\n\n if (typeof workflowHandler === 'function') {\n const result = await runJob({\n job,\n req: jobReq,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status !== 'error' && jobsToDelete) {\n jobsToDelete.push(job.id)\n }\n\n return { id: job.id, result }\n } else {\n const result = await runJSONJob({\n job,\n req: jobReq,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status !== 'error' && jobsToDelete) {\n jobsToDelete.push(job.id)\n }\n\n return { id: job.id, result }\n }\n })\n\n const resultsArray = await Promise.all(jobPromises)\n\n if (jobsToDelete && jobsToDelete.length > 0) {\n try {\n await req.payload.delete({\n collection: 'payload-jobs',\n req,\n where: { id: { in: jobsToDelete } },\n })\n } catch (err) {\n req.payload.logger.error({\n err,\n msg: `failed to delete jobs ${jobsToDelete.join(', ')} on complete`,\n })\n }\n }\n\n const resultsObject: RunJobsResult['jobStatus'] = resultsArray.reduce((acc, cur) => {\n if (cur !== null) {\n // Check if there's a valid result to include\n acc[cur.id] = cur.result\n }\n return acc\n }, {})\n\n let remainingJobsFromQueried = 0\n for (const jobID in resultsObject) {\n const jobResult = resultsObject[jobID]\n if (jobResult.status === 'error') {\n remainingJobsFromQueried++ // Can be retried\n }\n }\n\n return {\n jobStatus: resultsObject,\n remainingJobsFromQueried,\n }\n}\n"],"names":["Forbidden","isolateObjectProperty","getUpdateJobFunction","importHandlerPath","runJob","runJSONJob","runJobs","limit","overrideAccess","queue","req","hasAccess","payload","config","jobs","access","run","t","where","and","completedAt","exists","hasError","not_equals","processing","equals","or","waitUntil","less_than","Date","toISOString","push","jobsQuery","update","collection","data","seenByWorker","depth","disableTransaction","showHiddenFields","newJobs","docs","reduce","acc","job","totalTried","existingJobs","length","noJobsRemaining","remainingJobsFromQueried","logger","info","jobsToDelete","deleteJobOnComplete","undefined","jobPromises","map","workflowSlug","taskSlug","Error","jobReq","workflowConfig","workflows","find","slug","handler","tasks","input","updateJob","workflowHandler","Array","isArray","errorMessage","error","result","status","id","resultsArray","Promise","all","delete","in","err","msg","join","resultsObject","cur","jobID","jobResult","jobStatus"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/queues/operations/runJobs/index.ts"],"sourcesContent":["import type { PaginatedDocs } from '../../../database/types.js'\nimport type { PayloadRequest, Where } from '../../../types/index.js'\nimport type { WorkflowJSON } from '../../config/types/workflowJSONTypes.js'\nimport type {\n BaseJob,\n WorkflowConfig,\n WorkflowHandler,\n WorkflowTypes,\n} from '../../config/types/workflowTypes.js'\nimport type { RunJobResult } from './runJob/index.js'\n\nimport { Forbidden } from '../../../errors/Forbidden.js'\nimport isolateObjectProperty from '../../../utilities/isolateObjectProperty.js'\nimport { getUpdateJobFunction } from './runJob/getUpdateJobFunction.js'\nimport { importHandlerPath } from './runJob/importHandlerPath.js'\nimport { runJob } from './runJob/index.js'\nimport { runJSONJob } from './runJSONJob/index.js'\n\nexport type RunJobsArgs = {\n limit?: number\n overrideAccess?: boolean\n queue?: string\n req: PayloadRequest\n}\n\nexport type RunJobsResult = {\n jobStatus?: Record<string, RunJobResult>\n /**\n * If this is false, there for sure are no jobs remaining, regardless of the limit\n */\n noJobsRemaining?: boolean\n /**\n * Out of the jobs that were queried & processed (within the set limit), how many are remaining and retryable?\n */\n remainingJobsFromQueried: number\n}\n\nexport const runJobs = async ({\n limit = 10,\n overrideAccess,\n queue,\n req,\n}: RunJobsArgs): Promise<RunJobsResult> => {\n if (!overrideAccess) {\n const hasAccess = await req.payload.config.jobs.access.run({ req })\n if (!hasAccess) {\n throw new Forbidden(req.t)\n }\n }\n const where: Where = {\n and: [\n {\n completedAt: {\n exists: false,\n },\n },\n {\n hasError: {\n not_equals: true,\n },\n },\n {\n processing: {\n equals: false,\n },\n },\n {\n or: [\n {\n waitUntil: {\n exists: false,\n },\n },\n {\n waitUntil: {\n less_than: new Date().toISOString(),\n },\n },\n ],\n },\n ],\n }\n\n if (queue) {\n where.and.push({\n queue: {\n equals: queue,\n },\n })\n }\n\n // Find all jobs and ensure we set job to processing: true as early as possible to reduce the chance of\n // the same job being picked up by another worker\n const jobsQuery = (await req.payload.update({\n collection: 'payload-jobs',\n data: {\n processing: true,\n seenByWorker: true,\n },\n depth: req.payload.config.jobs.depth,\n disableTransaction: true,\n limit,\n showHiddenFields: true,\n where,\n })) as unknown as PaginatedDocs<BaseJob>\n\n /**\n * Just for logging purposes, we want to know how many jobs are new and how many are existing (= already been tried).\n * This is only for logs - in the end we still want to run all jobs, regardless of whether they are new or existing.\n */\n const { newJobs } = jobsQuery.docs.reduce(\n (acc, job) => {\n if (job.totalTried > 0) {\n acc.existingJobs.push(job)\n } else {\n acc.newJobs.push(job)\n }\n return acc\n },\n { existingJobs: [], newJobs: [] },\n )\n\n if (!jobsQuery.docs.length) {\n return {\n noJobsRemaining: true,\n remainingJobsFromQueried: 0,\n }\n }\n\n if (jobsQuery?.docs?.length) {\n req.payload.logger.info(`Running ${jobsQuery.docs.length} jobs.`)\n }\n const jobsToDelete: (number | string)[] | undefined = req.payload.config.jobs.deleteJobOnComplete\n ? []\n : undefined\n\n const jobPromises = jobsQuery.docs.map(async (job) => {\n if (!job.workflowSlug && !job.taskSlug) {\n throw new Error('Job must have either a workflowSlug or a taskSlug')\n }\n const jobReq = isolateObjectProperty(req, 'transactionID')\n\n const workflowConfig: WorkflowConfig<WorkflowTypes> = job.workflowSlug\n ? req.payload.config.jobs?.workflows.find(({ slug }) => slug === job.workflowSlug)\n : {\n slug: 'singleTask',\n handler: async ({ job, tasks }) => {\n await tasks[job.taskSlug as string]('1', {\n input: job.input,\n })\n },\n }\n\n if (!workflowConfig) {\n return null // Skip jobs with no workflow configuration\n }\n\n const updateJob = getUpdateJobFunction(job, jobReq)\n\n // the runner will either be passed to the config\n // OR it will be a path, which we will need to import via eval to avoid\n // Next.js compiler dynamic import expression errors\n let workflowHandler: WorkflowHandler<WorkflowTypes> | WorkflowJSON<WorkflowTypes>\n\n if (\n typeof workflowConfig.handler === 'function' ||\n (typeof workflowConfig.handler === 'object' && Array.isArray(workflowConfig.handler))\n ) {\n workflowHandler = workflowConfig.handler\n } else {\n workflowHandler = await importHandlerPath<typeof workflowHandler>(workflowConfig.handler)\n\n if (!workflowHandler) {\n const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`\n const errorMessage = `Can't find runner while importing with the path ${workflowConfig.handler} in job type ${jobLabel}.`\n req.payload.logger.error(errorMessage)\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n processing: false,\n })\n\n return\n }\n }\n\n if (typeof workflowHandler === 'function') {\n const result = await runJob({\n job,\n req: jobReq,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status !== 'error' && jobsToDelete) {\n jobsToDelete.push(job.id)\n }\n\n return { id: job.id, result }\n } else {\n const result = await runJSONJob({\n job,\n req: jobReq,\n updateJob,\n workflowConfig,\n workflowHandler,\n })\n\n if (result.status !== 'error' && jobsToDelete) {\n jobsToDelete.push(job.id)\n }\n\n return { id: job.id, result }\n }\n })\n\n const resultsArray = await Promise.all(jobPromises)\n\n if (jobsToDelete && jobsToDelete.length > 0) {\n try {\n await req.payload.delete({\n collection: 'payload-jobs',\n req,\n where: { id: { in: jobsToDelete } },\n })\n } catch (err) {\n req.payload.logger.error({\n err,\n msg: `failed to delete jobs ${jobsToDelete.join(', ')} on complete`,\n })\n }\n }\n\n const resultsObject: RunJobsResult['jobStatus'] = resultsArray.reduce((acc, cur) => {\n if (cur !== null) {\n // Check if there's a valid result to include\n acc[cur.id] = cur.result\n }\n return acc\n }, {})\n\n let remainingJobsFromQueried = 0\n for (const jobID in resultsObject) {\n const jobResult = resultsObject[jobID]\n if (jobResult.status === 'error') {\n remainingJobsFromQueried++ // Can be retried\n }\n }\n\n return {\n jobStatus: resultsObject,\n remainingJobsFromQueried,\n }\n}\n"],"names":["Forbidden","isolateObjectProperty","getUpdateJobFunction","importHandlerPath","runJob","runJSONJob","runJobs","limit","overrideAccess","queue","req","hasAccess","payload","config","jobs","access","run","t","where","and","completedAt","exists","hasError","not_equals","processing","equals","or","waitUntil","less_than","Date","toISOString","push","jobsQuery","update","collection","data","seenByWorker","depth","disableTransaction","showHiddenFields","newJobs","docs","reduce","acc","job","totalTried","existingJobs","length","noJobsRemaining","remainingJobsFromQueried","logger","info","jobsToDelete","deleteJobOnComplete","undefined","jobPromises","map","workflowSlug","taskSlug","Error","jobReq","workflowConfig","workflows","find","slug","handler","tasks","input","updateJob","workflowHandler","Array","isArray","jobLabel","errorMessage","error","result","status","id","resultsArray","Promise","all","delete","in","err","msg","join","resultsObject","cur","jobID","jobResult","jobStatus"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getRunTaskFunction.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/getRunTaskFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EAErB,gBAAgB,EAChB,UAAU,EAEV,iBAAiB,EAElB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EACV,OAAO,EAEP,gBAAgB,EAChB,cAAc,EAEf,MAAM,wCAAwC,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAMlE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAAA;AAaD,wBAAsB,gBAAgB,CAAC,EACrC,KAAK,EACL,UAAU,EACV,KAAK,EACL,GAAG,EACH,UAAU,EACV,MAAM,EACN,GAAG,EACH,aAAa,EACb,YAAY,EACZ,KAAK,EACL,UAAU,EACV,MAAM,EACN,QAAQ,EACR,UAAU,EACV,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,UAAU,EAAE,IAAI,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,cAAc,CAAA;IACnB,aAAa,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,YAAY,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACxC,KAAK,EAAE,oBAAoB,CAAA;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,iBAAiB,CAAA;CAC7B,GAAG,OAAO,CAAC,KAAK,CAAC,CA+DjB;AAED,eAAO,MAAM,kBAAkB,GAAI,SAAS,SAAS,OAAO,SACnD,oBAAoB,OACtB,OAAO,kBACI,cAAc,CAAC,MAAM,CAAC,OACjC,cAAc,YACT,SAAS,aACR,iBAAiB,KAC3B,SAAS,SAAS,IAAI,GAAG,qBAAqB,GAAG,gBAqKnD,CAAA"}
1
+ {"version":3,"file":"getRunTaskFunction.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/getRunTaskFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EAErB,gBAAgB,EAChB,UAAU,EAEV,iBAAiB,EAElB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EACV,OAAO,EAEP,gBAAgB,EAChB,cAAc,EAEf,MAAM,wCAAwC,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAMlE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAAA;AAaD,wBAAsB,gBAAgB,CAAC,EACrC,KAAK,EACL,UAAU,EACV,KAAK,EACL,GAAG,EACH,UAAU,EACV,MAAM,EACN,GAAG,EACH,aAAa,EACb,YAAY,EACZ,KAAK,EACL,UAAU,EACV,MAAM,EACN,QAAQ,EACR,UAAU,EACV,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,UAAU,EAAE,IAAI,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,cAAc,CAAA;IACnB,aAAa,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,YAAY,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACxC,KAAK,EAAE,oBAAoB,CAAA;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,iBAAiB,CAAA;CAC7B,GAAG,OAAO,CAAC,KAAK,CAAC,CAuEjB;AAED,eAAO,MAAM,kBAAkB,GAAI,SAAS,SAAS,OAAO,SACnD,oBAAoB,OACtB,OAAO,kBACI,cAAc,CAAC,MAAM,CAAC,OACjC,cAAc,YACT,SAAS,aACR,iBAAiB,KAC3B,SAAS,SAAS,IAAI,GAAG,qBAAqB,GAAG,gBAiLnD,CAAA"}
@@ -13,7 +13,7 @@ export async function handleTaskFailed({ error, executedAt, input, job, maxRetri
13
13
  req.payload.logger.error({
14
14
  err: error,
15
15
  job,
16
- msg: 'Error running task',
16
+ msg: `Error running task ${taskID}`,
17
17
  taskSlug
18
18
  });
19
19
  if (taskConfig?.onFail) {
@@ -22,9 +22,14 @@ export async function handleTaskFailed({ error, executedAt, input, job, maxRetri
22
22
  if (!job.log) {
23
23
  job.log = [];
24
24
  }
25
+ const errorJSON = error ? {
26
+ name: error.name,
27
+ message: error.message,
28
+ stack: error.stack
29
+ } : runnerOutput.state;
25
30
  job.log.push({
26
31
  completedAt: new Date().toISOString(),
27
- error: error ?? runnerOutput.state,
32
+ error: errorJSON,
28
33
  executedAt: executedAt.toISOString(),
29
34
  input,
30
35
  output,
@@ -40,7 +45,7 @@ export async function handleTaskFailed({ error, executedAt, input, job, maxRetri
40
45
  delete job.waitUntil;
41
46
  }
42
47
  }
43
- if (taskStatus && !taskStatus.complete && taskStatus.totalTried >= maxRetries) {
48
+ if (!taskStatus?.complete && (taskStatus?.totalTried ?? 0) >= maxRetries) {
44
49
  state.reachedMaxRetries = true;
45
50
  await updateJob({
46
51
  error,
@@ -86,7 +91,15 @@ export const getRunTaskFunction = (state, job, workflowConfig, req, isInline, up
86
91
  throw new Error(`Task ${taskSlug} not found in workflow ${job.workflowSlug}`);
87
92
  }
88
93
  }
89
- const maxRetries = typeof retriesConfig === 'object' ? retriesConfig?.attempts : retriesConfig;
94
+ let maxRetries = typeof retriesConfig === 'object' ? retriesConfig?.attempts : retriesConfig;
95
+ if (maxRetries === undefined || maxRetries === null) {
96
+ // Inherit retries from workflow config, if they are undefined and the workflow config has retries configured
97
+ if (workflowConfig.retries !== undefined && workflowConfig.retries !== null) {
98
+ maxRetries = typeof workflowConfig.retries === 'object' ? workflowConfig.retries.attempts : workflowConfig.retries;
99
+ } else {
100
+ maxRetries = 0;
101
+ }
102
+ }
90
103
  const taskStatus = job?.taskStatus?.[taskSlug] ? job.taskStatus[taskSlug][taskID] : null;
91
104
  if (taskStatus && taskStatus.complete === true) {
92
105
  return taskStatus.output;
@@ -123,7 +136,7 @@ export const getRunTaskFunction = (state, job, workflowConfig, req, isInline, up
123
136
  });
124
137
  return;
125
138
  }
126
- let output;
139
+ let output = {};
127
140
  try {
128
141
  const runnerOutput = await runner({
129
142
  input,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/getRunTaskFunction.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type {\n RetryConfig,\n RunInlineTaskFunction,\n RunTaskFunction,\n RunTaskFunctions,\n TaskConfig,\n TaskHandler,\n TaskHandlerResult,\n TaskType,\n} from '../../../config/types/taskTypes.js'\nimport type {\n BaseJob,\n RunningJob,\n SingleTaskStatus,\n WorkflowConfig,\n WorkflowTypes,\n} from '../../../config/types/workflowTypes.js'\nimport type { UpdateJobFunction } from './getUpdateJobFunction.js'\n\nimport { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js'\nimport { importHandlerPath } from './importHandlerPath.js'\n\n// Helper object type to force being passed by reference\nexport type RunTaskFunctionState = {\n reachedMaxRetries: boolean\n}\n\nasync function getTaskHandlerFromConfig(taskConfig: TaskConfig<string>) {\n let handler: TaskHandler<TaskType>\n\n if (typeof taskConfig.handler === 'function') {\n handler = taskConfig.handler\n } else {\n handler = await importHandlerPath<TaskHandler<TaskType>>(taskConfig.handler)\n }\n return handler\n}\n\nexport async function handleTaskFailed({\n error,\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n runnerOutput,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n}: {\n error?: Error\n executedAt: Date\n input: object\n job: BaseJob\n maxRetries: number\n output: object\n req: PayloadRequest\n retriesConfig: number | RetryConfig\n runnerOutput?: TaskHandlerResult<string>\n state: RunTaskFunctionState\n taskConfig?: TaskConfig<string>\n taskID: string\n taskSlug: string\n taskStatus: null | SingleTaskStatus<string>\n updateJob: UpdateJobFunction\n}): Promise<never> {\n req.payload.logger.error({ err: error, job, msg: 'Error running task', taskSlug })\n\n if (taskConfig?.onFail) {\n await taskConfig.onFail()\n }\n\n if (!job.log) {\n job.log = []\n }\n job.log.push({\n completedAt: new Date().toISOString(),\n error: error ?? runnerOutput.state,\n executedAt: executedAt.toISOString(),\n input,\n output,\n state: 'failed',\n taskID,\n taskSlug,\n })\n\n if (job.waitUntil) {\n // Check if waitUntil is in the past\n const waitUntil = new Date(job.waitUntil)\n if (waitUntil < new Date()) {\n // Outdated waitUntil, remove it\n delete job.waitUntil\n }\n }\n\n if (taskStatus && !taskStatus.complete && taskStatus.totalTried >= maxRetries) {\n state.reachedMaxRetries = true\n\n await updateJob({\n error,\n hasError: true,\n log: job.log,\n processing: false,\n waitUntil: job.waitUntil,\n })\n\n throw new Error(\n `Task ${taskSlug} has failed more than the allowed retries in workflow ${job.workflowSlug}${error ? `. Error: ${String(error)}` : ''}`,\n )\n } else {\n // Job will retry. Let's determine when!\n const waitUntil: Date = calculateBackoffWaitUntil({\n retriesConfig,\n totalTried: taskStatus?.totalTried ?? 0,\n })\n\n // Update job's waitUntil only if this waitUntil is later than the current one\n if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {\n job.waitUntil = waitUntil.toISOString()\n }\n\n await updateJob({\n log: job.log,\n processing: false,\n waitUntil: job.waitUntil,\n })\n throw error ?? new Error('Task failed')\n }\n}\n\nexport const getRunTaskFunction = <TIsInline extends boolean>(\n state: RunTaskFunctionState,\n job: BaseJob,\n workflowConfig: WorkflowConfig<string>,\n req: PayloadRequest,\n isInline: TIsInline,\n updateJob: UpdateJobFunction,\n): TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions => {\n const runTask: <TTaskSlug extends string>(\n taskSlug: TTaskSlug,\n ) => TTaskSlug extends 'inline' ? RunInlineTaskFunction : RunTaskFunction<TTaskSlug> = (\n taskSlug,\n ) =>\n (async (\n taskID: Parameters<RunInlineTaskFunction>[0],\n {\n input,\n retries,\n task,\n }: Parameters<RunInlineTaskFunction>[1] & Parameters<RunTaskFunction<string>>[1],\n ) => {\n const executedAt = new Date()\n\n let inlineRunner: TaskHandler<TaskType> = null\n if (isInline) {\n inlineRunner = task\n }\n\n let retriesConfig: number | RetryConfig = retries\n let taskConfig: TaskConfig<string>\n if (!isInline) {\n taskConfig = req.payload.config.jobs.tasks.find((t) => t.slug === taskSlug)\n if (!retriesConfig) {\n retriesConfig = taskConfig.retries\n }\n\n if (!taskConfig) {\n throw new Error(`Task ${taskSlug} not found in workflow ${job.workflowSlug}`)\n }\n }\n const maxRetries: number =\n typeof retriesConfig === 'object' ? retriesConfig?.attempts : retriesConfig\n\n const taskStatus: null | SingleTaskStatus<string> = job?.taskStatus?.[taskSlug]\n ? job.taskStatus[taskSlug][taskID]\n : null\n\n if (taskStatus && taskStatus.complete === true) {\n return taskStatus.output\n }\n\n let runner: TaskHandler<TaskType>\n if (isInline) {\n runner = inlineRunner\n } else {\n if (!taskConfig) {\n throw new Error(`Task ${taskSlug} not found in workflow ${job.workflowSlug}`)\n }\n runner = await getTaskHandlerFromConfig(taskConfig)\n }\n\n if (!runner || typeof runner !== 'function') {\n const errorMessage = isInline\n ? `Can't find runner for inline task with ID ${taskID}`\n : `Can't find runner while importing with the path ${typeof workflowConfig.handler === 'string' ? workflowConfig.handler : 'unknown - no string path'} in job type ${job.workflowSlug} for task ${taskSlug}.`\n req.payload.logger.error(errorMessage)\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n log: [\n ...job.log,\n {\n completedAt: new Date().toISOString(),\n error: errorMessage,\n executedAt: executedAt.toISOString(),\n state: 'failed',\n taskID,\n taskSlug,\n },\n ],\n processing: false,\n })\n\n return\n }\n\n let output: object\n\n try {\n const runnerOutput = await runner({\n input,\n job: job as unknown as RunningJob<WorkflowTypes>, // TODO: Type this better\n req,\n })\n\n if (runnerOutput.state === 'failed') {\n await handleTaskFailed({\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n runnerOutput,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n })\n throw new Error('Task failed')\n } else {\n output = runnerOutput.output\n }\n } catch (err) {\n await handleTaskFailed({\n error: err,\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n })\n throw new Error('Task failed')\n }\n\n if (taskConfig?.onSuccess) {\n await taskConfig.onSuccess()\n }\n\n if (!job.log) {\n job.log = []\n }\n job.log.push({\n completedAt: new Date().toISOString(),\n executedAt: executedAt.toISOString(),\n input,\n output,\n state: 'succeeded',\n taskID,\n taskSlug,\n })\n\n await updateJob({\n log: job.log,\n })\n\n return output\n }) as any\n\n if (isInline) {\n return runTask('inline') as TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions\n } else {\n const tasks: RunTaskFunctions = {}\n for (const task of req?.payload?.config?.jobs?.tasks ?? []) {\n tasks[task.slug] = runTask(task.slug)\n }\n return tasks as TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions\n }\n}\n"],"names":["calculateBackoffWaitUntil","importHandlerPath","getTaskHandlerFromConfig","taskConfig","handler","handleTaskFailed","error","executedAt","input","job","maxRetries","output","req","retriesConfig","runnerOutput","state","taskID","taskSlug","taskStatus","updateJob","payload","logger","err","msg","onFail","log","push","completedAt","Date","toISOString","waitUntil","complete","totalTried","reachedMaxRetries","hasError","processing","Error","workflowSlug","String","getRunTaskFunction","workflowConfig","isInline","runTask","retries","task","inlineRunner","config","jobs","tasks","find","t","slug","attempts","runner","errorMessage","onSuccess"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/getRunTaskFunction.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type {\n RetryConfig,\n RunInlineTaskFunction,\n RunTaskFunction,\n RunTaskFunctions,\n TaskConfig,\n TaskHandler,\n TaskHandlerResult,\n TaskType,\n} from '../../../config/types/taskTypes.js'\nimport type {\n BaseJob,\n RunningJob,\n SingleTaskStatus,\n WorkflowConfig,\n WorkflowTypes,\n} from '../../../config/types/workflowTypes.js'\nimport type { UpdateJobFunction } from './getUpdateJobFunction.js'\n\nimport { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js'\nimport { importHandlerPath } from './importHandlerPath.js'\n\n// Helper object type to force being passed by reference\nexport type RunTaskFunctionState = {\n reachedMaxRetries: boolean\n}\n\nasync function getTaskHandlerFromConfig(taskConfig: TaskConfig<string>) {\n let handler: TaskHandler<TaskType>\n\n if (typeof taskConfig.handler === 'function') {\n handler = taskConfig.handler\n } else {\n handler = await importHandlerPath<TaskHandler<TaskType>>(taskConfig.handler)\n }\n return handler\n}\n\nexport async function handleTaskFailed({\n error,\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n runnerOutput,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n}: {\n error?: Error\n executedAt: Date\n input: object\n job: BaseJob\n maxRetries: number\n output: object\n req: PayloadRequest\n retriesConfig: number | RetryConfig\n runnerOutput?: TaskHandlerResult<string>\n state: RunTaskFunctionState\n taskConfig?: TaskConfig<string>\n taskID: string\n taskSlug: string\n taskStatus: null | SingleTaskStatus<string>\n updateJob: UpdateJobFunction\n}): Promise<never> {\n req.payload.logger.error({ err: error, job, msg: `Error running task ${taskID}`, taskSlug })\n\n if (taskConfig?.onFail) {\n await taskConfig.onFail()\n }\n\n if (!job.log) {\n job.log = []\n }\n const errorJSON = error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : runnerOutput.state\n\n job.log.push({\n completedAt: new Date().toISOString(),\n error: errorJSON,\n executedAt: executedAt.toISOString(),\n input,\n output,\n state: 'failed',\n taskID,\n taskSlug,\n })\n\n if (job.waitUntil) {\n // Check if waitUntil is in the past\n const waitUntil = new Date(job.waitUntil)\n if (waitUntil < new Date()) {\n // Outdated waitUntil, remove it\n delete job.waitUntil\n }\n }\n\n if (!taskStatus?.complete && (taskStatus?.totalTried ?? 0) >= maxRetries) {\n state.reachedMaxRetries = true\n\n await updateJob({\n error,\n hasError: true,\n log: job.log,\n processing: false,\n waitUntil: job.waitUntil,\n })\n\n throw new Error(\n `Task ${taskSlug} has failed more than the allowed retries in workflow ${job.workflowSlug}${error ? `. Error: ${String(error)}` : ''}`,\n )\n } else {\n // Job will retry. Let's determine when!\n const waitUntil: Date = calculateBackoffWaitUntil({\n retriesConfig,\n totalTried: taskStatus?.totalTried ?? 0,\n })\n\n // Update job's waitUntil only if this waitUntil is later than the current one\n if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {\n job.waitUntil = waitUntil.toISOString()\n }\n\n await updateJob({\n log: job.log,\n processing: false,\n waitUntil: job.waitUntil,\n })\n throw error ?? new Error('Task failed')\n }\n}\n\nexport const getRunTaskFunction = <TIsInline extends boolean>(\n state: RunTaskFunctionState,\n job: BaseJob,\n workflowConfig: WorkflowConfig<string>,\n req: PayloadRequest,\n isInline: TIsInline,\n updateJob: UpdateJobFunction,\n): TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions => {\n const runTask: <TTaskSlug extends string>(\n taskSlug: TTaskSlug,\n ) => TTaskSlug extends 'inline' ? RunInlineTaskFunction : RunTaskFunction<TTaskSlug> = (\n taskSlug,\n ) =>\n (async (\n taskID: Parameters<RunInlineTaskFunction>[0],\n {\n input,\n retries,\n task,\n }: Parameters<RunInlineTaskFunction>[1] & Parameters<RunTaskFunction<string>>[1],\n ) => {\n const executedAt = new Date()\n\n let inlineRunner: TaskHandler<TaskType> = null\n if (isInline) {\n inlineRunner = task\n }\n\n let retriesConfig: number | RetryConfig = retries\n let taskConfig: TaskConfig<string>\n if (!isInline) {\n taskConfig = req.payload.config.jobs.tasks.find((t) => t.slug === taskSlug)\n if (!retriesConfig) {\n retriesConfig = taskConfig.retries\n }\n\n if (!taskConfig) {\n throw new Error(`Task ${taskSlug} not found in workflow ${job.workflowSlug}`)\n }\n }\n let maxRetries: number =\n typeof retriesConfig === 'object' ? retriesConfig?.attempts : retriesConfig\n\n if (maxRetries === undefined || maxRetries === null) {\n // Inherit retries from workflow config, if they are undefined and the workflow config has retries configured\n if (workflowConfig.retries !== undefined && workflowConfig.retries !== null) {\n maxRetries =\n typeof workflowConfig.retries === 'object'\n ? workflowConfig.retries.attempts\n : workflowConfig.retries\n } else {\n maxRetries = 0\n }\n }\n\n const taskStatus: null | SingleTaskStatus<string> = job?.taskStatus?.[taskSlug]\n ? job.taskStatus[taskSlug][taskID]\n : null\n\n if (taskStatus && taskStatus.complete === true) {\n return taskStatus.output\n }\n\n let runner: TaskHandler<TaskType>\n if (isInline) {\n runner = inlineRunner\n } else {\n if (!taskConfig) {\n throw new Error(`Task ${taskSlug} not found in workflow ${job.workflowSlug}`)\n }\n runner = await getTaskHandlerFromConfig(taskConfig)\n }\n\n if (!runner || typeof runner !== 'function') {\n const errorMessage = isInline\n ? `Can't find runner for inline task with ID ${taskID}`\n : `Can't find runner while importing with the path ${typeof workflowConfig.handler === 'string' ? workflowConfig.handler : 'unknown - no string path'} in job type ${job.workflowSlug} for task ${taskSlug}.`\n req.payload.logger.error(errorMessage)\n\n await updateJob({\n error: {\n error: errorMessage,\n },\n hasError: true,\n log: [\n ...job.log,\n {\n completedAt: new Date().toISOString(),\n error: errorMessage,\n executedAt: executedAt.toISOString(),\n state: 'failed',\n taskID,\n taskSlug,\n },\n ],\n processing: false,\n })\n\n return\n }\n\n let output: object = {}\n\n try {\n const runnerOutput = await runner({\n input,\n job: job as unknown as RunningJob<WorkflowTypes>, // TODO: Type this better\n req,\n })\n\n if (runnerOutput.state === 'failed') {\n await handleTaskFailed({\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n runnerOutput,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n })\n throw new Error('Task failed')\n } else {\n output = runnerOutput.output\n }\n } catch (err) {\n await handleTaskFailed({\n error: err,\n executedAt,\n input,\n job,\n maxRetries,\n output,\n req,\n retriesConfig,\n state,\n taskConfig,\n taskID,\n taskSlug,\n taskStatus,\n updateJob,\n })\n throw new Error('Task failed')\n }\n\n if (taskConfig?.onSuccess) {\n await taskConfig.onSuccess()\n }\n\n if (!job.log) {\n job.log = []\n }\n job.log.push({\n completedAt: new Date().toISOString(),\n executedAt: executedAt.toISOString(),\n input,\n output,\n state: 'succeeded',\n taskID,\n taskSlug,\n })\n\n await updateJob({\n log: job.log,\n })\n\n return output\n }) as any\n\n if (isInline) {\n return runTask('inline') as TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions\n } else {\n const tasks: RunTaskFunctions = {}\n for (const task of req?.payload?.config?.jobs?.tasks ?? []) {\n tasks[task.slug] = runTask(task.slug)\n }\n return tasks as TIsInline extends true ? RunInlineTaskFunction : RunTaskFunctions\n }\n}\n"],"names":["calculateBackoffWaitUntil","importHandlerPath","getTaskHandlerFromConfig","taskConfig","handler","handleTaskFailed","error","executedAt","input","job","maxRetries","output","req","retriesConfig","runnerOutput","state","taskID","taskSlug","taskStatus","updateJob","payload","logger","err","msg","onFail","log","errorJSON","name","message","stack","push","completedAt","Date","toISOString","waitUntil","complete","totalTried","reachedMaxRetries","hasError","processing","Error","workflowSlug","String","getRunTaskFunction","workflowConfig","isInline","runTask","retries","task","inlineRunner","config","jobs","tasks","find","t","slug","attempts","undefined","runner","errorMessage","onSuccess"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleWorkflowError.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/handleWorkflowError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AACpG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAInE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,GAAG,EACH,GAAG,EACH,KAAK,EACL,cAAc,GACf,EAAE;IACD,KAAK,EAAE,KAAK,CAAA;IACZ,GAAG,EAAE,OAAO,CAAA;IACZ,GAAG,EAAE,cAAc,CAAA;IACnB,KAAK,EAAE,oBAAoB,CAAA;IAC3B,cAAc,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;CAC9C,GAAG;IACF,aAAa,EAAE,OAAO,CAAA;CACvB,CAyCA"}
1
+ {"version":3,"file":"handleWorkflowError.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/handleWorkflowError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AACpG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAInE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,GAAG,EACH,GAAG,EACH,KAAK,EACL,cAAc,GACf,EAAE;IACD,KAAK,EAAE,KAAK,CAAA;IACZ,GAAG,EAAE,OAAO,CAAA;IACZ,GAAG,EAAE,cAAc,CAAA;IACnB,KAAK,EAAE,oBAAoB,CAAA;IAC3B,cAAc,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;CAC9C,GAAG;IACF,aAAa,EAAE,OAAO,CAAA;CACvB,CAiDA"}
@@ -3,11 +3,16 @@ import { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js';
3
3
  * This is called if a workflow catches an error. It determines if it's a final error
4
4
  * or not and handles logging.
5
5
  */ export function handleWorkflowError({ error, job, req, state, workflowConfig }) {
6
+ const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`;
6
7
  let hasFinalError = state.reachedMaxRetries // If any TASK reached max retries, the job has an error
7
8
  ;
8
- const maxRetries = typeof workflowConfig.retries === 'object' ? workflowConfig.retries.attempts : workflowConfig.retries;
9
+ const maxWorkflowRetries = (typeof workflowConfig.retries === 'object' ? workflowConfig.retries.attempts : workflowConfig.retries) ?? undefined;
10
+ if (maxWorkflowRetries !== undefined && maxWorkflowRetries !== null && job.totalTried >= maxWorkflowRetries) {
11
+ hasFinalError = true;
12
+ state.reachedMaxRetries = true;
13
+ }
9
14
  // Now let's handle workflow retries
10
- if (!hasFinalError && workflowConfig.retries) {
15
+ if (!hasFinalError) {
11
16
  if (job.waitUntil) {
12
17
  // Check if waitUntil is in the past
13
18
  const waitUntil = new Date(job.waitUntil);
@@ -16,24 +21,19 @@ import { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js';
16
21
  delete job.waitUntil;
17
22
  }
18
23
  }
19
- if (job.totalTried >= maxRetries) {
20
- state.reachedMaxRetries = true;
21
- hasFinalError = true;
22
- } else {
23
- // Job will retry. Let's determine when!
24
- const waitUntil = calculateBackoffWaitUntil({
25
- retriesConfig: workflowConfig.retries,
26
- totalTried: job.totalTried ?? 0
27
- });
28
- // Update job's waitUntil only if this waitUntil is later than the current one
29
- if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {
30
- job.waitUntil = waitUntil.toISOString();
31
- }
24
+ // Job will retry. Let's determine when!
25
+ const waitUntil = calculateBackoffWaitUntil({
26
+ retriesConfig: workflowConfig.retries,
27
+ totalTried: job.totalTried ?? 0
28
+ });
29
+ // Update job's waitUntil only if this waitUntil is later than the current one
30
+ if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {
31
+ job.waitUntil = waitUntil.toISOString();
32
32
  }
33
33
  }
34
34
  req.payload.logger.error({
35
35
  err: error,
36
- msg: `Error running job ${job.workflowSlug} ${job.taskSlug} id: ${job.id} attempt ${job.totalTried}/${maxRetries}`
36
+ msg: `Error running job ${jobLabel} id: ${job.id} attempt ${job.totalTried + 1}${maxWorkflowRetries !== undefined ? '/' + (maxWorkflowRetries + 1) : ''}`
37
37
  });
38
38
  return {
39
39
  hasFinalError
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/handleWorkflowError.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type { BaseJob, WorkflowConfig, WorkflowTypes } from '../../../config/types/workflowTypes.js'\nimport type { RunTaskFunctionState } from './getRunTaskFunction.js'\n\nimport { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js'\n\n/**\n * This is called if a workflow catches an error. It determines if it's a final error\n * or not and handles logging.\n */\nexport function handleWorkflowError({\n error,\n job,\n req,\n state,\n workflowConfig,\n}: {\n error: Error\n job: BaseJob\n req: PayloadRequest\n state: RunTaskFunctionState\n workflowConfig: WorkflowConfig<WorkflowTypes>\n}): {\n hasFinalError: boolean\n} {\n let hasFinalError = state.reachedMaxRetries // If any TASK reached max retries, the job has an error\n const maxRetries =\n typeof workflowConfig.retries === 'object'\n ? workflowConfig.retries.attempts\n : workflowConfig.retries\n // Now let's handle workflow retries\n if (!hasFinalError && workflowConfig.retries) {\n if (job.waitUntil) {\n // Check if waitUntil is in the past\n const waitUntil = new Date(job.waitUntil)\n if (waitUntil < new Date()) {\n // Outdated waitUntil, remove it\n delete job.waitUntil\n }\n }\n if (job.totalTried >= maxRetries) {\n state.reachedMaxRetries = true\n hasFinalError = true\n } else {\n // Job will retry. Let's determine when!\n const waitUntil: Date = calculateBackoffWaitUntil({\n retriesConfig: workflowConfig.retries,\n totalTried: job.totalTried ?? 0,\n })\n\n // Update job's waitUntil only if this waitUntil is later than the current one\n if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {\n job.waitUntil = waitUntil.toISOString()\n }\n }\n }\n\n req.payload.logger.error({\n err: error,\n msg: `Error running job ${job.workflowSlug} ${job.taskSlug} id: ${job.id} attempt ${job.totalTried}/${maxRetries}`,\n })\n\n return {\n hasFinalError,\n }\n}\n"],"names":["calculateBackoffWaitUntil","handleWorkflowError","error","job","req","state","workflowConfig","hasFinalError","reachedMaxRetries","maxRetries","retries","attempts","waitUntil","Date","totalTried","retriesConfig","toISOString","payload","logger","err","msg","workflowSlug","taskSlug","id"],"mappings":"AAIA,SAASA,yBAAyB,QAAQ,iCAAgC;AAE1E;;;CAGC,GACD,OAAO,SAASC,oBAAoB,EAClCC,KAAK,EACLC,GAAG,EACHC,GAAG,EACHC,KAAK,EACLC,cAAc,EAOf;IAGC,IAAIC,gBAAgBF,MAAMG,iBAAiB,CAAC,wDAAwD;;IACpG,MAAMC,aACJ,OAAOH,eAAeI,OAAO,KAAK,WAC9BJ,eAAeI,OAAO,CAACC,QAAQ,GAC/BL,eAAeI,OAAO;IAC5B,oCAAoC;IACpC,IAAI,CAACH,iBAAiBD,eAAeI,OAAO,EAAE;QAC5C,IAAIP,IAAIS,SAAS,EAAE;YACjB,oCAAoC;YACpC,MAAMA,YAAY,IAAIC,KAAKV,IAAIS,SAAS;YACxC,IAAIA,YAAY,IAAIC,QAAQ;gBAC1B,gCAAgC;gBAChC,OAAOV,IAAIS,SAAS;YACtB;QACF;QACA,IAAIT,IAAIW,UAAU,IAAIL,YAAY;YAChCJ,MAAMG,iBAAiB,GAAG;YAC1BD,gBAAgB;QAClB,OAAO;YACL,wCAAwC;YACxC,MAAMK,YAAkBZ,0BAA0B;gBAChDe,eAAeT,eAAeI,OAAO;gBACrCI,YAAYX,IAAIW,UAAU,IAAI;YAChC;YAEA,8EAA8E;YAC9E,IAAI,CAACX,IAAIS,SAAS,IAAIA,YAAY,IAAIC,KAAKV,IAAIS,SAAS,GAAG;gBACzDT,IAAIS,SAAS,GAAGA,UAAUI,WAAW;YACvC;QACF;IACF;IAEAZ,IAAIa,OAAO,CAACC,MAAM,CAAChB,KAAK,CAAC;QACvBiB,KAAKjB;QACLkB,KAAK,CAAC,kBAAkB,EAAEjB,IAAIkB,YAAY,CAAC,CAAC,EAAElB,IAAImB,QAAQ,CAAC,KAAK,EAAEnB,IAAIoB,EAAE,CAAC,SAAS,EAAEpB,IAAIW,UAAU,CAAC,CAAC,EAAEL,WAAW,CAAC;IACpH;IAEA,OAAO;QACLF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/handleWorkflowError.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type { BaseJob, WorkflowConfig, WorkflowTypes } from '../../../config/types/workflowTypes.js'\nimport type { RunTaskFunctionState } from './getRunTaskFunction.js'\n\nimport { calculateBackoffWaitUntil } from './calculateBackoffWaitUntil.js'\n\n/**\n * This is called if a workflow catches an error. It determines if it's a final error\n * or not and handles logging.\n */\nexport function handleWorkflowError({\n error,\n job,\n req,\n state,\n workflowConfig,\n}: {\n error: Error\n job: BaseJob\n req: PayloadRequest\n state: RunTaskFunctionState\n workflowConfig: WorkflowConfig<WorkflowTypes>\n}): {\n hasFinalError: boolean\n} {\n const jobLabel = job.workflowSlug || `Task: ${job.taskSlug}`\n\n let hasFinalError = state.reachedMaxRetries // If any TASK reached max retries, the job has an error\n const maxWorkflowRetries: number =\n (typeof workflowConfig.retries === 'object'\n ? workflowConfig.retries.attempts\n : workflowConfig.retries) ?? undefined\n\n if (\n maxWorkflowRetries !== undefined &&\n maxWorkflowRetries !== null &&\n job.totalTried >= maxWorkflowRetries\n ) {\n hasFinalError = true\n state.reachedMaxRetries = true\n }\n\n // Now let's handle workflow retries\n if (!hasFinalError) {\n if (job.waitUntil) {\n // Check if waitUntil is in the past\n const waitUntil = new Date(job.waitUntil)\n if (waitUntil < new Date()) {\n // Outdated waitUntil, remove it\n delete job.waitUntil\n }\n }\n\n // Job will retry. Let's determine when!\n const waitUntil: Date = calculateBackoffWaitUntil({\n retriesConfig: workflowConfig.retries,\n totalTried: job.totalTried ?? 0,\n })\n\n // Update job's waitUntil only if this waitUntil is later than the current one\n if (!job.waitUntil || waitUntil > new Date(job.waitUntil)) {\n job.waitUntil = waitUntil.toISOString()\n }\n }\n\n req.payload.logger.error({\n err: error,\n msg: `Error running job ${jobLabel} id: ${job.id} attempt ${job.totalTried + 1}${maxWorkflowRetries !== undefined ? '/' + (maxWorkflowRetries + 1) : ''}`,\n })\n\n return {\n hasFinalError,\n }\n}\n"],"names":["calculateBackoffWaitUntil","handleWorkflowError","error","job","req","state","workflowConfig","jobLabel","workflowSlug","taskSlug","hasFinalError","reachedMaxRetries","maxWorkflowRetries","retries","attempts","undefined","totalTried","waitUntil","Date","retriesConfig","toISOString","payload","logger","err","msg","id"],"mappings":"AAIA,SAASA,yBAAyB,QAAQ,iCAAgC;AAE1E;;;CAGC,GACD,OAAO,SAASC,oBAAoB,EAClCC,KAAK,EACLC,GAAG,EACHC,GAAG,EACHC,KAAK,EACLC,cAAc,EAOf;IAGC,MAAMC,WAAWJ,IAAIK,YAAY,IAAI,CAAC,MAAM,EAAEL,IAAIM,QAAQ,EAAE;IAE5D,IAAIC,gBAAgBL,MAAMM,iBAAiB,CAAC,wDAAwD;;IACpG,MAAMC,qBACJ,AAAC,CAAA,OAAON,eAAeO,OAAO,KAAK,WAC/BP,eAAeO,OAAO,CAACC,QAAQ,GAC/BR,eAAeO,OAAO,AAAD,KAAME;IAEjC,IACEH,uBAAuBG,aACvBH,uBAAuB,QACvBT,IAAIa,UAAU,IAAIJ,oBAClB;QACAF,gBAAgB;QAChBL,MAAMM,iBAAiB,GAAG;IAC5B;IAEA,oCAAoC;IACpC,IAAI,CAACD,eAAe;QAClB,IAAIP,IAAIc,SAAS,EAAE;YACjB,oCAAoC;YACpC,MAAMA,YAAY,IAAIC,KAAKf,IAAIc,SAAS;YACxC,IAAIA,YAAY,IAAIC,QAAQ;gBAC1B,gCAAgC;gBAChC,OAAOf,IAAIc,SAAS;YACtB;QACF;QAEA,wCAAwC;QACxC,MAAMA,YAAkBjB,0BAA0B;YAChDmB,eAAeb,eAAeO,OAAO;YACrCG,YAAYb,IAAIa,UAAU,IAAI;QAChC;QAEA,8EAA8E;QAC9E,IAAI,CAACb,IAAIc,SAAS,IAAIA,YAAY,IAAIC,KAAKf,IAAIc,SAAS,GAAG;YACzDd,IAAIc,SAAS,GAAGA,UAAUG,WAAW;QACvC;IACF;IAEAhB,IAAIiB,OAAO,CAACC,MAAM,CAACpB,KAAK,CAAC;QACvBqB,KAAKrB;QACLsB,KAAK,CAAC,kBAAkB,EAAEjB,SAAS,KAAK,EAAEJ,IAAIsB,EAAE,CAAC,SAAS,EAAEtB,IAAIa,UAAU,GAAG,IAAIJ,uBAAuBG,YAAY,MAAOH,CAAAA,qBAAqB,CAAA,IAAK,IAAI;IAC3J;IAEA,OAAO;QACLF;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"importHandlerPath.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/importHandlerPath.ts"],"names":[],"mappings":"AAEA,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAyBnE"}
1
+ {"version":3,"file":"importHandlerPath.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/importHandlerPath.ts"],"names":[],"mappings":"AAEA,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAkCnE"}
@@ -2,7 +2,14 @@ import { pathToFileURL } from 'url';
2
2
  export async function importHandlerPath(path) {
3
3
  let runner;
4
4
  const [runnerPath, runnerImportName] = path.split('#');
5
- const runnerModule = typeof require === 'function' ? await eval(`require('${runnerPath.replaceAll('\\', '/')}')`) : await eval(`import('${pathToFileURL(runnerPath).href}')`);
5
+ let runnerModule;
6
+ try {
7
+ // We need to check for `require` for compatibility with outdated frameworks that do not
8
+ // properly support ESM, like Jest. This is not done to support projects without "type": "module" set
9
+ runnerModule = typeof require === 'function' ? await eval(`require('${runnerPath.replaceAll('\\', '/')}')`) : await eval(`import('${pathToFileURL(runnerPath).href}')`);
10
+ } catch (e) {
11
+ throw new Error(`Error importing job queue handler module for path ${path}. This is an advanced feature that may require a sophisticated build pipeline, especially when using it in production or within Next.js, e.g. by calling opening the /api/payload-jobs/run endpoint. You will have to transpile the handler files separately and ensure they are available in the same location when the job is run. If you're using an endpoint to execute your jobs, it's recommended to define your handlers as functions directly in your Payload Config, or use import paths handlers outside of Next.js. Import Error: \n${e.message}`);
12
+ }
6
13
  // If the path has indicated an #exportName, try to get it
7
14
  if (runnerImportName && runnerModule[runnerImportName]) {
8
15
  runner = runnerModule[runnerImportName];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/importHandlerPath.ts"],"sourcesContent":["import { pathToFileURL } from 'url'\n\nexport async function importHandlerPath<T>(path: string): Promise<T> {\n let runner: T\n const [runnerPath, runnerImportName] = path.split('#')\n\n const runnerModule =\n typeof require === 'function'\n ? await eval(`require('${runnerPath.replaceAll('\\\\', '/')}')`)\n : await eval(`import('${pathToFileURL(runnerPath).href}')`)\n\n // If the path has indicated an #exportName, try to get it\n if (runnerImportName && runnerModule[runnerImportName]) {\n runner = runnerModule[runnerImportName]\n }\n\n // If there is a default export, use it\n if (!runner && runnerModule.default) {\n runner = runnerModule.default\n }\n\n // Finally, use whatever was imported\n if (!runner) {\n runner = runnerModule\n }\n\n return runner\n}\n"],"names":["pathToFileURL","importHandlerPath","path","runner","runnerPath","runnerImportName","split","runnerModule","require","eval","replaceAll","href","default"],"mappings":"AAAA,SAASA,aAAa,QAAQ,MAAK;AAEnC,OAAO,eAAeC,kBAAqBC,IAAY;IACrD,IAAIC;IACJ,MAAM,CAACC,YAAYC,iBAAiB,GAAGH,KAAKI,KAAK,CAAC;IAElD,MAAMC,eACJ,OAAOC,YAAY,aACf,MAAMC,KAAK,CAAC,SAAS,EAAEL,WAAWM,UAAU,CAAC,MAAM,KAAK,EAAE,CAAC,IAC3D,MAAMD,KAAK,CAAC,QAAQ,EAAET,cAAcI,YAAYO,IAAI,CAAC,EAAE,CAAC;IAE9D,0DAA0D;IAC1D,IAAIN,oBAAoBE,YAAY,CAACF,iBAAiB,EAAE;QACtDF,SAASI,YAAY,CAACF,iBAAiB;IACzC;IAEA,uCAAuC;IACvC,IAAI,CAACF,UAAUI,aAAaK,OAAO,EAAE;QACnCT,SAASI,aAAaK,OAAO;IAC/B;IAEA,qCAAqC;IACrC,IAAI,CAACT,QAAQ;QACXA,SAASI;IACX;IAEA,OAAOJ;AACT"}
1
+ {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/importHandlerPath.ts"],"sourcesContent":["import { pathToFileURL } from 'url'\n\nexport async function importHandlerPath<T>(path: string): Promise<T> {\n let runner: T\n const [runnerPath, runnerImportName] = path.split('#')\n\n let runnerModule\n try {\n // We need to check for `require` for compatibility with outdated frameworks that do not\n // properly support ESM, like Jest. This is not done to support projects without \"type\": \"module\" set\n runnerModule =\n typeof require === 'function'\n ? await eval(`require('${runnerPath.replaceAll('\\\\', '/')}')`)\n : await eval(`import('${pathToFileURL(runnerPath).href}')`)\n } catch (e) {\n throw new Error(\n `Error importing job queue handler module for path ${path}. This is an advanced feature that may require a sophisticated build pipeline, especially when using it in production or within Next.js, e.g. by calling opening the /api/payload-jobs/run endpoint. You will have to transpile the handler files separately and ensure they are available in the same location when the job is run. If you're using an endpoint to execute your jobs, it's recommended to define your handlers as functions directly in your Payload Config, or use import paths handlers outside of Next.js. Import Error: \\n${e.message}`,\n )\n }\n\n // If the path has indicated an #exportName, try to get it\n if (runnerImportName && runnerModule[runnerImportName]) {\n runner = runnerModule[runnerImportName]\n }\n\n // If there is a default export, use it\n if (!runner && runnerModule.default) {\n runner = runnerModule.default\n }\n\n // Finally, use whatever was imported\n if (!runner) {\n runner = runnerModule\n }\n\n return runner\n}\n"],"names":["pathToFileURL","importHandlerPath","path","runner","runnerPath","runnerImportName","split","runnerModule","require","eval","replaceAll","href","e","Error","message","default"],"mappings":"AAAA,SAASA,aAAa,QAAQ,MAAK;AAEnC,OAAO,eAAeC,kBAAqBC,IAAY;IACrD,IAAIC;IACJ,MAAM,CAACC,YAAYC,iBAAiB,GAAGH,KAAKI,KAAK,CAAC;IAElD,IAAIC;IACJ,IAAI;QACF,wFAAwF;QACxF,qGAAqG;QACrGA,eACE,OAAOC,YAAY,aACf,MAAMC,KAAK,CAAC,SAAS,EAAEL,WAAWM,UAAU,CAAC,MAAM,KAAK,EAAE,CAAC,IAC3D,MAAMD,KAAK,CAAC,QAAQ,EAAET,cAAcI,YAAYO,IAAI,CAAC,EAAE,CAAC;IAChE,EAAE,OAAOC,GAAG;QACV,MAAM,IAAIC,MACR,CAAC,kDAAkD,EAAEX,KAAK,+gBAA+gB,EAAEU,EAAEE,OAAO,EAAE;IAE1lB;IAEA,0DAA0D;IAC1D,IAAIT,oBAAoBE,YAAY,CAACF,iBAAiB,EAAE;QACtDF,SAASI,YAAY,CAACF,iBAAiB;IACzC;IAEA,uCAAuC;IACvC,IAAI,CAACF,UAAUI,aAAaQ,OAAO,EAAE;QACnCZ,SAASI,aAAaQ,OAAO;IAC/B;IAEA,qCAAqC;IACrC,IAAI,CAACZ,QAAQ;QACXA,SAASI;IACX;IAEA,OAAOJ;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EACV,OAAO,EAEP,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,wCAAwC,CAAA;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAKlE,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,OAAO,CAAA;IACZ,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;IAC7C,eAAe,EAAE,eAAe,CAAC,aAAa,CAAC,CAAA;CAChD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,2BAA2B,GAAG,SAAS,CAAA;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,MAAM,8DAMhB,IAAI,KAAG,OAAO,CAAC,YAAY,CAgD7B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/queues/operations/runJobs/runJob/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,KAAK,EACV,OAAO,EAEP,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,wCAAwC,CAAA;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAKlE,KAAK,IAAI,GAAG;IACV,GAAG,EAAE,OAAO,CAAA;IACZ,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,cAAc,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;IAC7C,eAAe,EAAE,eAAe,CAAC,aAAa,CAAC,CAAA;CAChD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,2BAA2B,GAAG,SAAS,CAAA;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,MAAM,8DAMhB,IAAI,KAAG,OAAO,CAAC,YAAY,CAuD7B,CAAA"}
@@ -22,10 +22,15 @@ export const runJob = async ({ job, req, updateJob, workflowConfig, workflowHand
22
22
  state,
23
23
  workflowConfig
24
24
  });
25
+ const errorJSON = hasFinalError ? {
26
+ name: err.name,
27
+ message: err.message,
28
+ stack: err.stack
29
+ } : undefined;
25
30
  // Tasks update the job if they error - but in case there is an unhandled error (e.g. in the workflow itself, not in a task)
26
31
  // we need to ensure the job is updated to reflect the error
27
32
  await updateJob({
28
- error: hasFinalError ? err : undefined,
33
+ error: errorJSON,
29
34
  hasError: hasFinalError,
30
35
  processing: false,
31
36
  totalTried: (job.totalTried ?? 0) + 1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/index.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type {\n BaseJob,\n RunningJob,\n WorkflowConfig,\n WorkflowHandler,\n WorkflowTypes,\n} from '../../../config/types/workflowTypes.js'\nimport type { RunTaskFunctionState } from './getRunTaskFunction.js'\nimport type { UpdateJobFunction } from './getUpdateJobFunction.js'\n\nimport { getRunTaskFunction } from './getRunTaskFunction.js'\nimport { handleWorkflowError } from './handleWorkflowError.js'\n\ntype Args = {\n job: BaseJob\n req: PayloadRequest\n updateJob: UpdateJobFunction\n workflowConfig: WorkflowConfig<WorkflowTypes>\n workflowHandler: WorkflowHandler<WorkflowTypes>\n}\n\nexport type JobRunStatus = 'error' | 'error-reached-max-retries' | 'success'\n\nexport type RunJobResult = {\n status: JobRunStatus\n}\n\nexport const runJob = async ({\n job,\n req,\n updateJob,\n workflowConfig,\n workflowHandler,\n}: Args): Promise<RunJobResult> => {\n // Object so that we can pass contents by reference, not value.\n // We want any mutations to be reflected in here.\n const state: RunTaskFunctionState = {\n reachedMaxRetries: false,\n }\n\n // Run the job\n try {\n await workflowHandler({\n inlineTask: getRunTaskFunction(state, job, workflowConfig, req, true, updateJob),\n job: job as unknown as RunningJob<WorkflowTypes>, //TODO: Type this better\n req,\n tasks: getRunTaskFunction(state, job, workflowConfig, req, false, updateJob),\n })\n } catch (err) {\n const { hasFinalError } = handleWorkflowError({\n error: err,\n job,\n req,\n state,\n workflowConfig,\n })\n\n // Tasks update the job if they error - but in case there is an unhandled error (e.g. in the workflow itself, not in a task)\n // we need to ensure the job is updated to reflect the error\n await updateJob({\n error: hasFinalError ? err : undefined,\n hasError: hasFinalError, // If reached max retries => final error. If hasError is true this job will not be retried\n processing: false,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n status: hasFinalError ? 'error-reached-max-retries' : 'error',\n }\n }\n\n // Workflow has completed\n await updateJob({\n completedAt: new Date().toISOString(),\n processing: false,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n status: 'success',\n }\n}\n"],"names":["getRunTaskFunction","handleWorkflowError","runJob","job","req","updateJob","workflowConfig","workflowHandler","state","reachedMaxRetries","inlineTask","tasks","err","hasFinalError","error","undefined","hasError","processing","totalTried","status","completedAt","Date","toISOString"],"mappings":"AAWA,SAASA,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,mBAAmB,QAAQ,2BAA0B;AAgB9D,OAAO,MAAMC,SAAS,OAAO,EAC3BC,GAAG,EACHC,GAAG,EACHC,SAAS,EACTC,cAAc,EACdC,eAAe,EACV;IACL,+DAA+D;IAC/D,iDAAiD;IACjD,MAAMC,QAA8B;QAClCC,mBAAmB;IACrB;IAEA,cAAc;IACd,IAAI;QACF,MAAMF,gBAAgB;YACpBG,YAAYV,mBAAmBQ,OAAOL,KAAKG,gBAAgBF,KAAK,MAAMC;YACtEF,KAAKA;YACLC;YACAO,OAAOX,mBAAmBQ,OAAOL,KAAKG,gBAAgBF,KAAK,OAAOC;QACpE;IACF,EAAE,OAAOO,KAAK;QACZ,MAAM,EAAEC,aAAa,EAAE,GAAGZ,oBAAoB;YAC5Ca,OAAOF;YACPT;YACAC;YACAI;YACAF;QACF;QAEA,4HAA4H;QAC5H,4DAA4D;QAC5D,MAAMD,UAAU;YACdS,OAAOD,gBAAgBD,MAAMG;YAC7BC,UAAUH;YACVI,YAAY;YACZC,YAAY,AAACf,CAAAA,IAAIe,UAAU,IAAI,CAAA,IAAK;QACtC;QAEA,OAAO;YACLC,QAAQN,gBAAgB,8BAA8B;QACxD;IACF;IAEA,yBAAyB;IACzB,MAAMR,UAAU;QACde,aAAa,IAAIC,OAAOC,WAAW;QACnCL,YAAY;QACZC,YAAY,AAACf,CAAAA,IAAIe,UAAU,IAAI,CAAA,IAAK;IACtC;IAEA,OAAO;QACLC,QAAQ;IACV;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../../../src/queues/operations/runJobs/runJob/index.ts"],"sourcesContent":["import type { PayloadRequest } from '../../../../types/index.js'\nimport type {\n BaseJob,\n RunningJob,\n WorkflowConfig,\n WorkflowHandler,\n WorkflowTypes,\n} from '../../../config/types/workflowTypes.js'\nimport type { RunTaskFunctionState } from './getRunTaskFunction.js'\nimport type { UpdateJobFunction } from './getUpdateJobFunction.js'\n\nimport { getRunTaskFunction } from './getRunTaskFunction.js'\nimport { handleWorkflowError } from './handleWorkflowError.js'\n\ntype Args = {\n job: BaseJob\n req: PayloadRequest\n updateJob: UpdateJobFunction\n workflowConfig: WorkflowConfig<WorkflowTypes>\n workflowHandler: WorkflowHandler<WorkflowTypes>\n}\n\nexport type JobRunStatus = 'error' | 'error-reached-max-retries' | 'success'\n\nexport type RunJobResult = {\n status: JobRunStatus\n}\n\nexport const runJob = async ({\n job,\n req,\n updateJob,\n workflowConfig,\n workflowHandler,\n}: Args): Promise<RunJobResult> => {\n // Object so that we can pass contents by reference, not value.\n // We want any mutations to be reflected in here.\n const state: RunTaskFunctionState = {\n reachedMaxRetries: false,\n }\n\n // Run the job\n try {\n await workflowHandler({\n inlineTask: getRunTaskFunction(state, job, workflowConfig, req, true, updateJob),\n job: job as unknown as RunningJob<WorkflowTypes>, //TODO: Type this better\n req,\n tasks: getRunTaskFunction(state, job, workflowConfig, req, false, updateJob),\n })\n } catch (err) {\n const { hasFinalError } = handleWorkflowError({\n error: err,\n job,\n req,\n state,\n workflowConfig,\n })\n\n const errorJSON = hasFinalError\n ? {\n name: err.name,\n message: err.message,\n stack: err.stack,\n }\n : undefined\n // Tasks update the job if they error - but in case there is an unhandled error (e.g. in the workflow itself, not in a task)\n // we need to ensure the job is updated to reflect the error\n await updateJob({\n error: errorJSON,\n hasError: hasFinalError, // If reached max retries => final error. If hasError is true this job will not be retried\n processing: false,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n status: hasFinalError ? 'error-reached-max-retries' : 'error',\n }\n }\n\n // Workflow has completed\n await updateJob({\n completedAt: new Date().toISOString(),\n processing: false,\n totalTried: (job.totalTried ?? 0) + 1,\n })\n\n return {\n status: 'success',\n }\n}\n"],"names":["getRunTaskFunction","handleWorkflowError","runJob","job","req","updateJob","workflowConfig","workflowHandler","state","reachedMaxRetries","inlineTask","tasks","err","hasFinalError","error","errorJSON","name","message","stack","undefined","hasError","processing","totalTried","status","completedAt","Date","toISOString"],"mappings":"AAWA,SAASA,kBAAkB,QAAQ,0BAAyB;AAC5D,SAASC,mBAAmB,QAAQ,2BAA0B;AAgB9D,OAAO,MAAMC,SAAS,OAAO,EAC3BC,GAAG,EACHC,GAAG,EACHC,SAAS,EACTC,cAAc,EACdC,eAAe,EACV;IACL,+DAA+D;IAC/D,iDAAiD;IACjD,MAAMC,QAA8B;QAClCC,mBAAmB;IACrB;IAEA,cAAc;IACd,IAAI;QACF,MAAMF,gBAAgB;YACpBG,YAAYV,mBAAmBQ,OAAOL,KAAKG,gBAAgBF,KAAK,MAAMC;YACtEF,KAAKA;YACLC;YACAO,OAAOX,mBAAmBQ,OAAOL,KAAKG,gBAAgBF,KAAK,OAAOC;QACpE;IACF,EAAE,OAAOO,KAAK;QACZ,MAAM,EAAEC,aAAa,EAAE,GAAGZ,oBAAoB;YAC5Ca,OAAOF;YACPT;YACAC;YACAI;YACAF;QACF;QAEA,MAAMS,YAAYF,gBACd;YACEG,MAAMJ,IAAII,IAAI;YACdC,SAASL,IAAIK,OAAO;YACpBC,OAAON,IAAIM,KAAK;QAClB,IACAC;QACJ,4HAA4H;QAC5H,4DAA4D;QAC5D,MAAMd,UAAU;YACdS,OAAOC;YACPK,UAAUP;YACVQ,YAAY;YACZC,YAAY,AAACnB,CAAAA,IAAImB,UAAU,IAAI,CAAA,IAAK;QACtC;QAEA,OAAO;YACLC,QAAQV,gBAAgB,8BAA8B;QACxD;IACF;IAEA,yBAAyB;IACzB,MAAMR,UAAU;QACdmB,aAAa,IAAIC,OAAOC,WAAW;QACnCL,YAAY;QACZC,YAAY,AAACnB,CAAAA,IAAImB,UAAU,IAAI,CAAA,IAAK;IACtC;IAEA,OAAO;QACLC,QAAQ;IACV;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getJobTaskStatus.d.ts","sourceRoot":"","sources":["../../../src/queues/utilities/getJobTaskStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAE9E,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IACtB,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAA;CACpC,CAAA;AAED,eAAO,MAAM,gBAAgB,eAAgB,IAAI,KAAG,aA6BnD,CAAA"}
1
+ {"version":3,"file":"getJobTaskStatus.d.ts","sourceRoot":"","sources":["../../../src/queues/utilities/getJobTaskStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAE9E,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IACtB,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAA;CACpC,CAAA;AAED,eAAO,MAAM,gBAAgB,eAAgB,IAAI,KAAG,aAkCnD,CAAA"}
@@ -19,6 +19,11 @@ export const getJobTaskStatus = ({ jobLog })=>{
19
19
  newTaskStatus.totalTried += 1;
20
20
  if (loggedJob.state === 'succeeded') {
21
21
  newTaskStatus.complete = true;
22
+ // As the task currently saved in taskStatus has likely failed and thus has no
23
+ // Output data, we need to update it with the new data from the successful task
24
+ newTaskStatus.output = loggedJob.output;
25
+ newTaskStatus.input = loggedJob.input;
26
+ newTaskStatus.taskSlug = loggedJob.taskSlug;
22
27
  }
23
28
  taskStatus[loggedJob.taskSlug][loggedJob.taskID] = newTaskStatus;
24
29
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/queues/utilities/getJobTaskStatus.ts"],"sourcesContent":["import type { TaskConfig, TaskType } from '../config/types/taskTypes.js'\nimport type { BaseJob, JobTaskStatus } from '../config/types/workflowTypes.js'\n\ntype Args = {\n jobLog: BaseJob['log']\n tasksConfig: TaskConfig<TaskType>[]\n}\n\nexport const getJobTaskStatus = ({ jobLog }: Args): JobTaskStatus => {\n const taskStatus: JobTaskStatus = {}\n\n // First, add (in order) the steps from the config to\n // our status map\n for (const loggedJob of jobLog) {\n if (!taskStatus[loggedJob.taskSlug]) {\n taskStatus[loggedJob.taskSlug] = {}\n }\n if (!taskStatus[loggedJob.taskSlug][loggedJob.taskID]) {\n taskStatus[loggedJob.taskSlug][loggedJob.taskID] = {\n complete: loggedJob.state === 'succeeded',\n input: loggedJob.input,\n output: loggedJob.output,\n taskSlug: loggedJob.taskSlug,\n totalTried: 1,\n }\n } else {\n const newTaskStatus = taskStatus[loggedJob.taskSlug][loggedJob.taskID]\n newTaskStatus.totalTried += 1\n\n if (loggedJob.state === 'succeeded') {\n newTaskStatus.complete = true\n }\n taskStatus[loggedJob.taskSlug][loggedJob.taskID] = newTaskStatus\n }\n }\n\n return taskStatus\n}\n"],"names":["getJobTaskStatus","jobLog","taskStatus","loggedJob","taskSlug","taskID","complete","state","input","output","totalTried","newTaskStatus"],"mappings":"AAQA,OAAO,MAAMA,mBAAmB,CAAC,EAAEC,MAAM,EAAQ;IAC/C,MAAMC,aAA4B,CAAC;IAEnC,qDAAqD;IACrD,iBAAiB;IACjB,KAAK,MAAMC,aAAaF,OAAQ;QAC9B,IAAI,CAACC,UAAU,CAACC,UAAUC,QAAQ,CAAC,EAAE;YACnCF,UAAU,CAACC,UAAUC,QAAQ,CAAC,GAAG,CAAC;QACpC;QACA,IAAI,CAACF,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,EAAE;YACrDH,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,GAAG;gBACjDC,UAAUH,UAAUI,KAAK,KAAK;gBAC9BC,OAAOL,UAAUK,KAAK;gBACtBC,QAAQN,UAAUM,MAAM;gBACxBL,UAAUD,UAAUC,QAAQ;gBAC5BM,YAAY;YACd;QACF,OAAO;YACL,MAAMC,gBAAgBT,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC;YACtEM,cAAcD,UAAU,IAAI;YAE5B,IAAIP,UAAUI,KAAK,KAAK,aAAa;gBACnCI,cAAcL,QAAQ,GAAG;YAC3B;YACAJ,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,GAAGM;QACrD;IACF;IAEA,OAAOT;AACT,EAAC"}
1
+ {"version":3,"sources":["../../../src/queues/utilities/getJobTaskStatus.ts"],"sourcesContent":["import type { TaskConfig, TaskType } from '../config/types/taskTypes.js'\nimport type { BaseJob, JobTaskStatus } from '../config/types/workflowTypes.js'\n\ntype Args = {\n jobLog: BaseJob['log']\n tasksConfig: TaskConfig<TaskType>[]\n}\n\nexport const getJobTaskStatus = ({ jobLog }: Args): JobTaskStatus => {\n const taskStatus: JobTaskStatus = {}\n\n // First, add (in order) the steps from the config to\n // our status map\n for (const loggedJob of jobLog) {\n if (!taskStatus[loggedJob.taskSlug]) {\n taskStatus[loggedJob.taskSlug] = {}\n }\n if (!taskStatus[loggedJob.taskSlug][loggedJob.taskID]) {\n taskStatus[loggedJob.taskSlug][loggedJob.taskID] = {\n complete: loggedJob.state === 'succeeded',\n input: loggedJob.input,\n output: loggedJob.output,\n taskSlug: loggedJob.taskSlug,\n totalTried: 1,\n }\n } else {\n const newTaskStatus = taskStatus[loggedJob.taskSlug][loggedJob.taskID]\n newTaskStatus.totalTried += 1\n\n if (loggedJob.state === 'succeeded') {\n newTaskStatus.complete = true\n // As the task currently saved in taskStatus has likely failed and thus has no\n // Output data, we need to update it with the new data from the successful task\n newTaskStatus.output = loggedJob.output\n newTaskStatus.input = loggedJob.input\n newTaskStatus.taskSlug = loggedJob.taskSlug\n }\n taskStatus[loggedJob.taskSlug][loggedJob.taskID] = newTaskStatus\n }\n }\n\n return taskStatus\n}\n"],"names":["getJobTaskStatus","jobLog","taskStatus","loggedJob","taskSlug","taskID","complete","state","input","output","totalTried","newTaskStatus"],"mappings":"AAQA,OAAO,MAAMA,mBAAmB,CAAC,EAAEC,MAAM,EAAQ;IAC/C,MAAMC,aAA4B,CAAC;IAEnC,qDAAqD;IACrD,iBAAiB;IACjB,KAAK,MAAMC,aAAaF,OAAQ;QAC9B,IAAI,CAACC,UAAU,CAACC,UAAUC,QAAQ,CAAC,EAAE;YACnCF,UAAU,CAACC,UAAUC,QAAQ,CAAC,GAAG,CAAC;QACpC;QACA,IAAI,CAACF,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,EAAE;YACrDH,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,GAAG;gBACjDC,UAAUH,UAAUI,KAAK,KAAK;gBAC9BC,OAAOL,UAAUK,KAAK;gBACtBC,QAAQN,UAAUM,MAAM;gBACxBL,UAAUD,UAAUC,QAAQ;gBAC5BM,YAAY;YACd;QACF,OAAO;YACL,MAAMC,gBAAgBT,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC;YACtEM,cAAcD,UAAU,IAAI;YAE5B,IAAIP,UAAUI,KAAK,KAAK,aAAa;gBACnCI,cAAcL,QAAQ,GAAG;gBACzB,8EAA8E;gBAC9E,+EAA+E;gBAC/EK,cAAcF,MAAM,GAAGN,UAAUM,MAAM;gBACvCE,cAAcH,KAAK,GAAGL,UAAUK,KAAK;gBACrCG,cAAcP,QAAQ,GAAGD,UAAUC,QAAQ;YAC7C;YACAF,UAAU,CAACC,UAAUC,QAAQ,CAAC,CAACD,UAAUE,MAAM,CAAC,GAAGM;QACrD;IACF;IAEA,OAAOT;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/uploads/deleteAssociatedFiles.ts"],"sourcesContent":["import fs from 'fs'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { FileData, FileToSave } from './types.js'\n\nimport { ErrorDeletingFile } from '../errors/index.js'\nimport fileExists from './fileExists.js'\n\ntype Args = {\n collectionConfig: SanitizedCollectionConfig\n config: SanitizedConfig\n doc: Record<string, unknown>\n files?: FileToSave[]\n overrideDelete: boolean\n req: PayloadRequest\n}\n\nexport const deleteAssociatedFiles: (args: Args) => Promise<void> = async ({\n collectionConfig,\n doc,\n files = [],\n overrideDelete,\n req,\n}) => {\n if (!collectionConfig.upload) {\n return\n }\n if (overrideDelete || files.length > 0) {\n const { staticDir: staticPath } = collectionConfig.upload\n\n const fileToDelete = `${staticPath}/${doc.filename as string}`\n\n try {\n if (await fileExists(fileToDelete)) {\n fs.unlinkSync(fileToDelete)\n }\n } catch (err) {\n throw new ErrorDeletingFile(req.t)\n }\n\n if (doc.sizes) {\n const sizes: FileData[] = Object.values(doc.sizes)\n // Since forEach will not wait until unlink is finished it could\n // happen that two operations will try to delete the same file.\n // To avoid this it is recommended to use \"sync\" instead\n\n for (const size of sizes) {\n const sizeToDelete = `${staticPath}/${size.filename}`\n try {\n if (await fileExists(sizeToDelete)) {\n fs.unlinkSync(sizeToDelete)\n }\n } catch (err) {\n throw new ErrorDeletingFile(req.t)\n }\n }\n }\n }\n}\n"],"names":["fs","ErrorDeletingFile","fileExists","deleteAssociatedFiles","collectionConfig","doc","files","overrideDelete","req","upload","length","staticDir","staticPath","fileToDelete","filename","unlinkSync","err","t","sizes","Object","values","size","sizeToDelete"],"mappings":"AAAA,OAAOA,QAAQ,KAAI;AAOnB,SAASC,iBAAiB,QAAQ,qBAAoB;AACtD,OAAOC,gBAAgB,kBAAiB;AAWxC,OAAO,MAAMC,wBAAuD,OAAO,EACzEC,gBAAgB,EAChBC,GAAG,EACHC,QAAQ,EAAE,EACVC,cAAc,EACdC,GAAG,EACJ;IACC,IAAI,CAACJ,iBAAiBK,MAAM,EAAE;QAC5B;IACF;IACA,IAAIF,kBAAkBD,MAAMI,MAAM,GAAG,GAAG;QACtC,MAAM,EAAEC,WAAWC,UAAU,EAAE,GAAGR,iBAAiBK,MAAM;QAEzD,MAAMI,eAAe,CAAC,EAAED,WAAW,CAAC,EAAEP,IAAIS,QAAQ,CAAW,CAAC;QAE9D,IAAI;YACF,IAAI,MAAMZ,WAAWW,eAAe;gBAClCb,GAAGe,UAAU,CAACF;YAChB;QACF,EAAE,OAAOG,KAAK;YACZ,MAAM,IAAIf,kBAAkBO,IAAIS,CAAC;QACnC;QAEA,IAAIZ,IAAIa,KAAK,EAAE;YACb,MAAMA,QAAoBC,OAAOC,MAAM,CAACf,IAAIa,KAAK;YACjD,gEAAgE;YAChE,+DAA+D;YAC/D,wDAAwD;YAExD,KAAK,MAAMG,QAAQH,MAAO;gBACxB,MAAMI,eAAe,CAAC,EAAEV,WAAW,CAAC,EAAES,KAAKP,QAAQ,CAAC,CAAC;gBACrD,IAAI;oBACF,IAAI,MAAMZ,WAAWoB,eAAe;wBAClCtB,GAAGe,UAAU,CAACO;oBAChB;gBACF,EAAE,OAAON,KAAK;oBACZ,MAAM,IAAIf,kBAAkBO,IAAIS,CAAC;gBACnC;YACF;QACF;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/uploads/deleteAssociatedFiles.ts"],"sourcesContent":["import fs from 'fs'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { FileData, FileToSave } from './types.js'\n\nimport { ErrorDeletingFile } from '../errors/index.js'\nimport fileExists from './fileExists.js'\n\ntype Args = {\n collectionConfig: SanitizedCollectionConfig\n config: SanitizedConfig\n doc: Record<string, unknown>\n files?: FileToSave[]\n overrideDelete: boolean\n req: PayloadRequest\n}\n\nexport const deleteAssociatedFiles: (args: Args) => Promise<void> = async ({\n collectionConfig,\n doc,\n files = [],\n overrideDelete,\n req,\n}) => {\n if (!collectionConfig.upload) {\n return\n }\n if (overrideDelete || files.length > 0) {\n const { staticDir: staticPath } = collectionConfig.upload\n\n const fileToDelete = `${staticPath}/${doc.filename as string}`\n\n try {\n if (await fileExists(fileToDelete)) {\n fs.unlinkSync(fileToDelete)\n }\n } catch (err) {\n throw new ErrorDeletingFile(req.t)\n }\n\n if (doc.sizes) {\n const sizes: FileData[] = Object.values(doc.sizes)\n // Since forEach will not wait until unlink is finished it could\n // happen that two operations will try to delete the same file.\n // To avoid this it is recommended to use \"sync\" instead\n\n for (const size of sizes) {\n const sizeToDelete = `${staticPath}/${size.filename}`\n try {\n if (await fileExists(sizeToDelete)) {\n fs.unlinkSync(sizeToDelete)\n }\n } catch (err) {\n throw new ErrorDeletingFile(req.t)\n }\n }\n }\n }\n}\n"],"names":["fs","ErrorDeletingFile","fileExists","deleteAssociatedFiles","collectionConfig","doc","files","overrideDelete","req","upload","length","staticDir","staticPath","fileToDelete","filename","unlinkSync","err","t","sizes","Object","values","size","sizeToDelete"],"mappings":"AAAA,OAAOA,QAAQ,KAAI;AAOnB,SAASC,iBAAiB,QAAQ,qBAAoB;AACtD,OAAOC,gBAAgB,kBAAiB;AAWxC,OAAO,MAAMC,wBAAuD,OAAO,EACzEC,gBAAgB,EAChBC,GAAG,EACHC,QAAQ,EAAE,EACVC,cAAc,EACdC,GAAG,EACJ;IACC,IAAI,CAACJ,iBAAiBK,MAAM,EAAE;QAC5B;IACF;IACA,IAAIF,kBAAkBD,MAAMI,MAAM,GAAG,GAAG;QACtC,MAAM,EAAEC,WAAWC,UAAU,EAAE,GAAGR,iBAAiBK,MAAM;QAEzD,MAAMI,eAAe,GAAGD,WAAW,CAAC,EAAEP,IAAIS,QAAQ,EAAY;QAE9D,IAAI;YACF,IAAI,MAAMZ,WAAWW,eAAe;gBAClCb,GAAGe,UAAU,CAACF;YAChB;QACF,EAAE,OAAOG,KAAK;YACZ,MAAM,IAAIf,kBAAkBO,IAAIS,CAAC;QACnC;QAEA,IAAIZ,IAAIa,KAAK,EAAE;YACb,MAAMA,QAAoBC,OAAOC,MAAM,CAACf,IAAIa,KAAK;YACjD,gEAAgE;YAChE,+DAA+D;YAC/D,wDAAwD;YAExD,KAAK,MAAMG,QAAQH,MAAO;gBACxB,MAAMI,eAAe,GAAGV,WAAW,CAAC,EAAES,KAAKP,QAAQ,EAAE;gBACrD,IAAI;oBACF,IAAI,MAAMZ,WAAWoB,eAAe;wBAClCtB,GAAGe,UAAU,CAACO;oBAChB;gBACF,EAAE,OAAON,KAAK;oBACZ,MAAM,IAAIf,kBAAkBO,IAAIS,CAAC;gBACnC;YACF;QACF;IACF;AACF,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/uploads/formatFilesize.ts"],"sourcesContent":["export function formatFilesize(bytes: number, decimals = 0): string {\n if (bytes === 0) {\n return '0 bytes'\n }\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = [' bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return `${parseFloat((bytes / k ** i).toFixed(dm))}${sizes[i]}`\n}\n"],"names":["formatFilesize","bytes","decimals","k","dm","sizes","i","Math","floor","log","parseFloat","toFixed"],"mappings":"AAAA,OAAO,SAASA,eAAeC,KAAa,EAAEC,WAAW,CAAC;IACxD,IAAID,UAAU,GAAG;QACf,OAAO;IACT;IAEA,MAAME,IAAI;IACV,MAAMC,KAAKF,WAAW,IAAI,IAAIA;IAC9B,MAAMG,QAAQ;QAAC;QAAU;QAAM;QAAM;QAAM;QAAM;QAAM;QAAM;QAAM;KAAK;IAExE,MAAMC,IAAIC,KAAKC,KAAK,CAACD,KAAKE,GAAG,CAACR,SAASM,KAAKE,GAAG,CAACN;IAEhD,OAAO,CAAC,EAAEO,WAAW,AAACT,CAAAA,QAAQE,KAAKG,CAAAA,EAAGK,OAAO,CAACP,KAAK,EAAEC,KAAK,CAACC,EAAE,CAAC,CAAC;AACjE"}
1
+ {"version":3,"sources":["../../src/uploads/formatFilesize.ts"],"sourcesContent":["export function formatFilesize(bytes: number, decimals = 0): string {\n if (bytes === 0) {\n return '0 bytes'\n }\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = [' bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return `${parseFloat((bytes / k ** i).toFixed(dm))}${sizes[i]}`\n}\n"],"names":["formatFilesize","bytes","decimals","k","dm","sizes","i","Math","floor","log","parseFloat","toFixed"],"mappings":"AAAA,OAAO,SAASA,eAAeC,KAAa,EAAEC,WAAW,CAAC;IACxD,IAAID,UAAU,GAAG;QACf,OAAO;IACT;IAEA,MAAME,IAAI;IACV,MAAMC,KAAKF,WAAW,IAAI,IAAIA;IAC9B,MAAMG,QAAQ;QAAC;QAAU;QAAM;QAAM;QAAM;QAAM;QAAM;QAAM;QAAM;KAAK;IAExE,MAAMC,IAAIC,KAAKC,KAAK,CAACD,KAAKE,GAAG,CAACR,SAASM,KAAKE,GAAG,CAACN;IAEhD,OAAO,GAAGO,WAAW,AAACT,CAAAA,QAAQE,KAAKG,CAAAA,EAAGK,OAAO,CAACP,OAAOC,KAAK,CAACC,EAAE,EAAE;AACjE"}