@focus-reactive/payload-plugin-translator 0.4.0 → 0.5.1

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 (87) hide show
  1. package/README.md +44 -29
  2. package/dist/client/shared/ui/Button/Button.d.ts +4 -4
  3. package/dist/client/shared/ui/Button/Button.js +18 -18
  4. package/dist/client/shared/ui/Button/styles.module.scss +1 -1
  5. package/dist/client/shared/ui/Popup/Popup.d.ts +10 -4
  6. package/dist/client/shared/ui/Popup/Popup.js +4 -3
  7. package/dist/client/shared/ui/Select/Select.d.ts +9 -7
  8. package/dist/client/shared/ui/Select/Select.js +18 -17
  9. package/dist/client/shared/ui/Select/styles.module.scss +5 -0
  10. package/dist/index.d.ts +16 -14
  11. package/dist/index.js +9 -7
  12. package/dist/plugin.d.ts +15 -4
  13. package/dist/plugin.js +34 -57
  14. package/dist/server/features/cancel/handler.d.ts +2 -2
  15. package/dist/server/features/cancel/handler.js +3 -1
  16. package/dist/server/features/cancel/route.d.ts +4 -4
  17. package/dist/server/features/cancel/route.js +4 -4
  18. package/dist/server/features/cancel-by-collection/handler.d.ts +3 -3
  19. package/dist/server/features/cancel-by-collection/handler.js +1 -1
  20. package/dist/server/features/cancel-by-collection/route.d.ts +5 -5
  21. package/dist/server/features/cancel-by-collection/route.js +4 -4
  22. package/dist/server/features/createTranslationRoutes.d.ts +23 -0
  23. package/dist/server/features/createTranslationRoutes.js +27 -0
  24. package/dist/server/features/enqueue-translation/handler.d.ts +3 -3
  25. package/dist/server/features/enqueue-translation/handler.js +1 -1
  26. package/dist/server/features/enqueue-translation/route.d.ts +5 -5
  27. package/dist/server/features/enqueue-translation/route.js +4 -4
  28. package/dist/server/features/get-collection-status/handler.d.ts +3 -3
  29. package/dist/server/features/get-collection-status/handler.js +1 -1
  30. package/dist/server/features/get-collection-status/route.d.ts +5 -5
  31. package/dist/server/features/get-collection-status/route.js +4 -4
  32. package/dist/server/features/get-document-status/handler.d.ts +3 -3
  33. package/dist/server/features/get-document-status/handler.js +1 -1
  34. package/dist/server/features/get-document-status/route.d.ts +5 -5
  35. package/dist/server/features/get-document-status/route.js +4 -4
  36. package/dist/server/features/index.d.ts +7 -6
  37. package/dist/server/features/index.js +7 -6
  38. package/dist/server/features/run-translation/handler.d.ts +2 -2
  39. package/dist/server/features/run-translation/route.d.ts +4 -4
  40. package/dist/server/features/run-translation/route.js +4 -4
  41. package/dist/server/features/translate-document/handler.js +7 -11
  42. package/dist/server/features/translate-field/resolveFieldSubtree.d.ts +31 -0
  43. package/dist/server/features/translate-field/resolveFieldSubtree.js +45 -0
  44. package/dist/server/modules/task-runner/TaskRunnerProvider.interface.d.ts +18 -1
  45. package/dist/server/modules/task-runner/index.d.ts +6 -6
  46. package/dist/server/modules/task-runner/index.js +2 -2
  47. package/dist/server/modules/task-runner/payload-jobs-runner/PayloadJobsRunnerProvider.d.ts +16 -1
  48. package/dist/server/modules/task-runner/payload-jobs-runner/PayloadJobsRunnerProvider.js +16 -1
  49. package/dist/server/modules/task-runner/sync-runner/SyncRunnerProvider.d.ts +18 -10
  50. package/dist/server/modules/task-runner/sync-runner/SyncRunnerProvider.js +24 -14
  51. package/dist/server/modules/translation-levels/PluginConfigBuilder.d.ts +46 -0
  52. package/dist/server/modules/translation-levels/PluginConfigBuilder.js +108 -0
  53. package/dist/server/modules/translation-levels/collectionLevel.d.ts +15 -0
  54. package/dist/server/modules/translation-levels/collectionLevel.js +24 -0
  55. package/dist/server/modules/translation-levels/documentLevel.d.ts +19 -0
  56. package/dist/server/modules/translation-levels/documentLevel.js +28 -0
  57. package/dist/server/modules/translation-levels/index.d.ts +3 -0
  58. package/dist/server/modules/translation-levels/index.js +4 -0
  59. package/dist/server/modules/translation-levels/types.d.ts +42 -0
  60. package/dist/server/modules/translation-levels/types.js +10 -0
  61. package/dist/server/modules/translation-levels/useDocTranslationApi.d.ts +8 -0
  62. package/dist/server/modules/translation-levels/useDocTranslationApi.js +18 -0
  63. package/dist/server/modules/translation-pipeline/index.d.ts +5 -3
  64. package/dist/server/modules/translation-pipeline/index.js +3 -2
  65. package/dist/server/modules/translation-pipeline/stages/data-reconciler/DataReconciler.d.ts +3 -9
  66. package/dist/server/modules/translation-pipeline/stages/data-reconciler/DataReconciler.js +71 -78
  67. package/dist/server/modules/translation-pipeline/stages/field-collector/FieldChunkCollector.d.ts +11 -22
  68. package/dist/server/modules/translation-pipeline/stages/field-collector/FieldChunkCollector.js +85 -106
  69. package/dist/server/modules/translation-pipeline/translateContent.d.ts +35 -0
  70. package/dist/server/modules/translation-pipeline/translateContent.js +30 -0
  71. package/dist/server/modules/translation-providers/OpenAITranslation.provider.d.ts +4 -3
  72. package/dist/server/modules/translation-providers/OpenAITranslation.provider.js +15 -15
  73. package/dist/server/shared/field-traversal/findFieldByPath.d.ts +40 -0
  74. package/dist/server/shared/field-traversal/findFieldByPath.js +88 -0
  75. package/dist/server/shared/field-traversal/index.d.ts +5 -0
  76. package/dist/server/shared/field-traversal/index.js +5 -0
  77. package/dist/server/shared/field-traversal/kernel.d.ts +85 -0
  78. package/dist/server/shared/field-traversal/kernel.js +145 -0
  79. package/dist/server/shared/field-traversal/types.d.ts +191 -0
  80. package/dist/server/shared/field-traversal/types.js +41 -0
  81. package/dist/server/shared/field-traversal/walkFields.d.ts +51 -0
  82. package/dist/server/shared/field-traversal/walkFields.js +164 -0
  83. package/dist/server/shared/utils/filterLocalizedFields.d.ts +3 -3
  84. package/dist/server/shared/utils/filterLocalizedFields.js +52 -63
  85. package/dist/types/AccessGuard.d.ts +24 -1
  86. package/dist/types/AccessGuard.js +12 -1
  87. package/package.json +2 -2
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { CancelHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { CancelHandler } from "./handler";
3
3
  /**
4
4
  * Creates the batch cancel endpoint
5
- */ export function createCancelRoute(taskRunnerFactory, access, basePath = '/translate') {
5
+ */ export function createCancelRoute(taskRunnerFactory, access, basePath = "/translate") {
6
6
  const handler = new CancelHandler(taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/cancel`,
9
- method: 'delete',
9
+ method: "delete",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import type { PayloadRequest } from "payload";
2
- import type { TaskRunnerProvider } from "../../modules/task-runner";
3
- import type { CancelConfig } from './model';
2
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
3
+ import type { CancelConfig } from "./model";
4
4
  /**
5
5
  * Cancels all pending translation tasks for a collection
6
6
  */
7
7
  export declare class CancelByCollectionHandler {
8
8
  private readonly config;
9
9
  private readonly taskRunnerFactory;
10
- constructor(config: CancelConfig, taskRunnerFactory: TaskRunnerProvider);
10
+ constructor(config: CancelConfig, taskRunnerFactory: TaskRunnerFactory);
11
11
  handle(req: PayloadRequest): Promise<Response>;
12
12
  }
@@ -1,6 +1,6 @@
1
1
  import { ServerResponse } from "../../shared";
2
2
  import { isCollectionAvailable } from "../_lib/collection-utils";
3
- import { CancelByCollectionInputSchema } from './model';
3
+ import { CancelByCollectionInputSchema } from "./model";
4
4
  /**
5
5
  * Cancels all pending translation tasks for a collection
6
6
  */ export class CancelByCollectionHandler {
@@ -1,8 +1,8 @@
1
- import type { Endpoint } from 'payload';
2
- import type { AccessGuard } from '../../shared';
3
- import type { TaskRunnerProvider } from '../../modules/task-runner';
4
- import type { CancelConfig } from './model';
1
+ import type { Endpoint } from "payload";
2
+ import type { AccessGuard } from "../../shared";
3
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
4
+ import type { CancelConfig } from "./model";
5
5
  /**
6
6
  * Creates the cancel by collection endpoint
7
7
  */
8
- export declare function createCancelByCollectionRoute(config: CancelConfig, taskRunnerFactory: TaskRunnerProvider, access?: AccessGuard, basePath?: string): Endpoint;
8
+ export declare function createCancelByCollectionRoute(config: CancelConfig, taskRunnerFactory: TaskRunnerFactory, access?: AccessGuard, basePath?: string): Endpoint;
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { CancelByCollectionHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { CancelByCollectionHandler } from "./handler";
3
3
  /**
4
4
  * Creates the cancel by collection endpoint
5
- */ export function createCancelByCollectionRoute(config, taskRunnerFactory, access, basePath = '/translate') {
5
+ */ export function createCancelByCollectionRoute(config, taskRunnerFactory, access, basePath = "/translate") {
6
6
  const handler = new CancelByCollectionHandler(config, taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/cancel-by-collection/:collection_slug`,
9
- method: 'delete',
9
+ method: "delete",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -0,0 +1,23 @@
1
+ import type { CollectionSlug, Endpoint } from "payload";
2
+ import type { AccessGuard } from "../shared";
3
+ import type { TaskRunnerFactory } from "../modules/task-runner";
4
+ export type TranslationRoutesDeps = {
5
+ taskRunnerFactory: TaskRunnerFactory;
6
+ /** Collections the plugin manages — gates which slugs the routes accept. */
7
+ collectionConfig: {
8
+ availableCollections: Set<CollectionSlug>;
9
+ };
10
+ access?: AccessGuard;
11
+ basePath?: string;
12
+ };
13
+ /**
14
+ * The translator's HTTP surface as one shared bundle: the 6 job-API endpoints
15
+ * (enqueue / run / cancel / cancel-by-collection / document-status /
16
+ * collection-status), all wired to the same runner factory and access guard.
17
+ *
18
+ * Extracted from the plugin's `init()` so registration is a single unit. The
19
+ * document and collection levels each contribute this bundle via the level
20
+ * context; the plugin deduplicates by method + path, so it registers exactly
21
+ * once. Behaviour-preserving: same endpoints, same order, same wiring.
22
+ */
23
+ export declare function createTranslationRoutes({ taskRunnerFactory, collectionConfig, access, basePath }: TranslationRoutesDeps): Endpoint[];
@@ -0,0 +1,27 @@
1
+ import { createEnqueueRoute } from "./enqueue-translation";
2
+ import { createRunRoute } from "./run-translation";
3
+ import { createCancelRoute } from "./cancel";
4
+ import { createCancelByCollectionRoute } from "./cancel-by-collection";
5
+ import { createGetDocumentStatusRoute } from "./get-document-status";
6
+ import { createGetCollectionStatusRoute } from "./get-collection-status";
7
+ /**
8
+ * The translator's HTTP surface as one shared bundle: the 6 job-API endpoints
9
+ * (enqueue / run / cancel / cancel-by-collection / document-status /
10
+ * collection-status), all wired to the same runner factory and access guard.
11
+ *
12
+ * Extracted from the plugin's `init()` so registration is a single unit. The
13
+ * document and collection levels each contribute this bundle via the level
14
+ * context; the plugin deduplicates by method + path, so it registers exactly
15
+ * once. Behaviour-preserving: same endpoints, same order, same wiring.
16
+ */ export function createTranslationRoutes({ taskRunnerFactory, collectionConfig, access, basePath }) {
17
+ return [
18
+ createEnqueueRoute(taskRunnerFactory, collectionConfig, access, basePath),
19
+ createRunRoute(taskRunnerFactory, access, basePath),
20
+ createCancelRoute(taskRunnerFactory, access, basePath),
21
+ createCancelByCollectionRoute(collectionConfig, taskRunnerFactory, access, basePath),
22
+ createGetDocumentStatusRoute(collectionConfig, taskRunnerFactory, access, basePath),
23
+ createGetCollectionStatusRoute(collectionConfig, taskRunnerFactory, access, basePath)
24
+ ];
25
+ }
26
+
27
+ //# sourceMappingURL=createTranslationRoutes.js.map
@@ -1,12 +1,12 @@
1
1
  import type { PayloadRequest } from "payload";
2
- import type { TaskRunnerProvider } from "../../modules/task-runner";
3
- import type { EnqueueConfig } from './model';
2
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
3
+ import type { EnqueueConfig } from "./model";
4
4
  /**
5
5
  * Enqueues translation tasks for documents
6
6
  */
7
7
  export declare class EnqueueTranslationHandler {
8
8
  private readonly config;
9
9
  private readonly taskRunnerFactory;
10
- constructor(config: EnqueueConfig, taskRunnerFactory: TaskRunnerProvider);
10
+ constructor(config: EnqueueConfig, taskRunnerFactory: TaskRunnerFactory);
11
11
  handle(req: PayloadRequest): Promise<Response>;
12
12
  }
@@ -1,6 +1,6 @@
1
1
  import { ServerResponse } from "../../shared";
2
2
  import { isCollectionAvailable, getAllCollectionIds } from "../_lib/collection-utils";
3
- import { EnqueueInputSchema } from './model';
3
+ import { EnqueueInputSchema } from "./model";
4
4
  /**
5
5
  * Enqueues translation tasks for documents
6
6
  */ export class EnqueueTranslationHandler {
@@ -1,8 +1,8 @@
1
- import type { Endpoint } from 'payload';
2
- import type { AccessGuard } from '../../shared';
3
- import type { TaskRunnerProvider } from '../../modules/task-runner';
4
- import type { EnqueueConfig } from './model';
1
+ import type { Endpoint } from "payload";
2
+ import type { AccessGuard } from "../../shared";
3
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
4
+ import type { EnqueueConfig } from "./model";
5
5
  /**
6
6
  * Creates the enqueue translation endpoint
7
7
  */
8
- export declare function createEnqueueRoute(taskRunnerFactory: TaskRunnerProvider, config: EnqueueConfig, access?: AccessGuard, basePath?: string): Endpoint;
8
+ export declare function createEnqueueRoute(taskRunnerFactory: TaskRunnerFactory, config: EnqueueConfig, access?: AccessGuard, basePath?: string): Endpoint;
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { EnqueueTranslationHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { EnqueueTranslationHandler } from "./handler";
3
3
  /**
4
4
  * Creates the enqueue translation endpoint
5
- */ export function createEnqueueRoute(taskRunnerFactory, config, access, basePath = '/translate') {
5
+ */ export function createEnqueueRoute(taskRunnerFactory, config, access, basePath = "/translate") {
6
6
  const handler = new EnqueueTranslationHandler(config, taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/enqueue`,
9
- method: 'post',
9
+ method: "post",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import type { PayloadRequest } from "payload";
2
- import type { TaskRunnerProvider } from "../../modules/task-runner";
3
- import type { GetCollectionStatusConfig } from './model';
2
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
3
+ import type { GetCollectionStatusConfig } from "./model";
4
4
  /**
5
5
  * Gets translation status for all documents in a collection
6
6
  */
7
7
  export declare class GetCollectionStatusHandler {
8
8
  private readonly config;
9
9
  private readonly taskRunnerFactory;
10
- constructor(config: GetCollectionStatusConfig, taskRunnerFactory: TaskRunnerProvider);
10
+ constructor(config: GetCollectionStatusConfig, taskRunnerFactory: TaskRunnerFactory);
11
11
  handle(req: PayloadRequest): Promise<Response>;
12
12
  }
@@ -1,6 +1,6 @@
1
1
  import { ServerResponse } from "../../shared";
2
2
  import { isCollectionAvailable } from "../_lib/collection-utils";
3
- import { GetCollectionStatusInputSchema } from './model';
3
+ import { GetCollectionStatusInputSchema } from "./model";
4
4
  /**
5
5
  * Gets translation status for all documents in a collection
6
6
  */ export class GetCollectionStatusHandler {
@@ -1,8 +1,8 @@
1
- import type { Endpoint } from 'payload';
2
- import type { AccessGuard } from '../../shared';
3
- import type { TaskRunnerProvider } from '../../modules/task-runner';
4
- import type { GetCollectionStatusConfig } from './model';
1
+ import type { Endpoint } from "payload";
2
+ import type { AccessGuard } from "../../shared";
3
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
4
+ import type { GetCollectionStatusConfig } from "./model";
5
5
  /**
6
6
  * Creates the get collection status endpoint
7
7
  */
8
- export declare function createGetCollectionStatusRoute(config: GetCollectionStatusConfig, taskRunnerFactory: TaskRunnerProvider, access?: AccessGuard, basePath?: string): Endpoint;
8
+ export declare function createGetCollectionStatusRoute(config: GetCollectionStatusConfig, taskRunnerFactory: TaskRunnerFactory, access?: AccessGuard, basePath?: string): Endpoint;
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { GetCollectionStatusHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { GetCollectionStatusHandler } from "./handler";
3
3
  /**
4
4
  * Creates the get collection status endpoint
5
- */ export function createGetCollectionStatusRoute(config, taskRunnerFactory, access, basePath = '/translate') {
5
+ */ export function createGetCollectionStatusRoute(config, taskRunnerFactory, access, basePath = "/translate") {
6
6
  const handler = new GetCollectionStatusHandler(config, taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/collection/:collection_slug`,
9
- method: 'get',
9
+ method: "get",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import type { PayloadRequest } from "payload";
2
- import type { TaskRunnerProvider } from "../../modules/task-runner";
3
- import type { GetDocumentStatusConfig } from './model';
2
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
3
+ import type { GetDocumentStatusConfig } from "./model";
4
4
  /**
5
5
  * Gets the translation status for a specific document
6
6
  */
7
7
  export declare class GetDocumentStatusHandler {
8
8
  private readonly config;
9
9
  private readonly taskRunnerFactory;
10
- constructor(config: GetDocumentStatusConfig, taskRunnerFactory: TaskRunnerProvider);
10
+ constructor(config: GetDocumentStatusConfig, taskRunnerFactory: TaskRunnerFactory);
11
11
  handle(req: PayloadRequest): Promise<Response>;
12
12
  }
@@ -1,6 +1,6 @@
1
1
  import { ServerResponse } from "../../shared";
2
2
  import { isCollectionAvailable } from "../_lib/collection-utils";
3
- import { GetDocumentStatusInputSchema, taskToJobStatusOutput } from './model';
3
+ import { GetDocumentStatusInputSchema, taskToJobStatusOutput } from "./model";
4
4
  /**
5
5
  * Gets the translation status for a specific document
6
6
  */ export class GetDocumentStatusHandler {
@@ -1,8 +1,8 @@
1
- import type { Endpoint } from 'payload';
2
- import type { AccessGuard } from '../../shared';
3
- import type { TaskRunnerProvider } from '../../modules/task-runner';
4
- import type { GetDocumentStatusConfig } from './model';
1
+ import type { Endpoint } from "payload";
2
+ import type { AccessGuard } from "../../shared";
3
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
4
+ import type { GetDocumentStatusConfig } from "./model";
5
5
  /**
6
6
  * Creates the get document status endpoint
7
7
  */
8
- export declare function createGetDocumentStatusRoute(config: GetDocumentStatusConfig, taskRunnerFactory: TaskRunnerProvider, access?: AccessGuard, basePath?: string): Endpoint;
8
+ export declare function createGetDocumentStatusRoute(config: GetDocumentStatusConfig, taskRunnerFactory: TaskRunnerFactory, access?: AccessGuard, basePath?: string): Endpoint;
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { GetDocumentStatusHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { GetDocumentStatusHandler } from "./handler";
3
3
  /**
4
4
  * Creates the get document status endpoint
5
- */ export function createGetDocumentStatusRoute(config, taskRunnerFactory, access, basePath = '/translate') {
5
+ */ export function createGetDocumentStatusRoute(config, taskRunnerFactory, access, basePath = "/translate") {
6
6
  const handler = new GetDocumentStatusHandler(config, taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/document/:collection_slug/:collection_id`,
9
- method: 'get',
9
+ method: "get",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -1,6 +1,7 @@
1
- export * from './translate-document';
2
- export * from './enqueue-translation';
3
- export * from './run-translation';
4
- export * from './cancel';
5
- export * from './get-document-status';
6
- export * from './get-collection-status';
1
+ export * from "./createTranslationRoutes";
2
+ export * from "./translate-document";
3
+ export * from "./enqueue-translation";
4
+ export * from "./run-translation";
5
+ export * from "./cancel";
6
+ export * from "./get-document-status";
7
+ export * from "./get-collection-status";
@@ -1,8 +1,9 @@
1
- export * from './translate-document';
2
- export * from './enqueue-translation';
3
- export * from './run-translation';
4
- export * from './cancel';
5
- export * from './get-document-status';
6
- export * from './get-collection-status';
1
+ export * from "./createTranslationRoutes";
2
+ export * from "./translate-document";
3
+ export * from "./enqueue-translation";
4
+ export * from "./run-translation";
5
+ export * from "./cancel";
6
+ export * from "./get-document-status";
7
+ export * from "./get-collection-status";
7
8
 
8
9
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,10 @@
1
1
  import type { PayloadRequest } from "payload";
2
- import type { TaskRunnerProvider } from "../../modules/task-runner";
2
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
3
3
  /**
4
4
  * Runs a translation task by ID
5
5
  */
6
6
  export declare class RunTranslationHandler {
7
7
  private readonly taskRunnerFactory;
8
- constructor(taskRunnerFactory: TaskRunnerProvider);
8
+ constructor(taskRunnerFactory: TaskRunnerFactory);
9
9
  handle(req: PayloadRequest): Promise<Response>;
10
10
  }
@@ -1,7 +1,7 @@
1
- import type { Endpoint } from 'payload';
2
- import type { AccessGuard } from '../../shared';
3
- import type { TaskRunnerProvider } from '../../modules/task-runner';
1
+ import type { Endpoint } from "payload";
2
+ import type { AccessGuard } from "../../shared";
3
+ import type { TaskRunnerFactory } from "../../modules/task-runner";
4
4
  /**
5
5
  * Creates the run translation endpoint
6
6
  */
7
- export declare function createRunRoute(taskRunnerFactory: TaskRunnerProvider, access?: AccessGuard, basePath?: string): Endpoint;
7
+ export declare function createRunRoute(taskRunnerFactory: TaskRunnerFactory, access?: AccessGuard, basePath?: string): Endpoint;
@@ -1,12 +1,12 @@
1
- import { withErrorHandler, withAccessCheck } from '../../shared';
2
- import { RunTranslationHandler } from './handler';
1
+ import { withErrorHandler, withAccessCheck } from "../../shared";
2
+ import { RunTranslationHandler } from "./handler";
3
3
  /**
4
4
  * Creates the run translation endpoint
5
- */ export function createRunRoute(taskRunnerFactory, access, basePath = '/translate') {
5
+ */ export function createRunRoute(taskRunnerFactory, access, basePath = "/translate") {
6
6
  const handler = new RunTranslationHandler(taskRunnerFactory);
7
7
  return {
8
8
  path: `${basePath}/run/:id`,
9
- method: 'post',
9
+ method: "post",
10
10
  handler: withAccessCheck(withErrorHandler(handler.handle.bind(handler)), access)
11
11
  };
12
12
  }
@@ -1,6 +1,5 @@
1
1
  import { APIError } from "payload";
2
- import { TranslationPipeline } from "../../modules/translation-pipeline";
3
- import { createTranslationStrategy } from "../../modules/translation-pipeline/strategies";
2
+ import { translateContent } from "../../modules/translation-pipeline";
4
3
  /**
5
4
  * Translates a single document from source language to target language
6
5
  */ export class TranslateDocumentHandler {
@@ -28,23 +27,20 @@ import { createTranslationStrategy } from "../../modules/translation-pipeline/st
28
27
  fallbackLocale: false,
29
28
  depth: 0
30
29
  });
31
- const translationStrategy = createTranslationStrategy(strategy);
32
- const pipeline = new TranslationPipeline({
33
- translationProvider: this.translationProvider,
34
- translationStrategy
35
- });
36
- const result = await pipeline.execute({
30
+ const translatedData = await translateContent({
37
31
  schema,
38
32
  sourceData,
39
33
  targetData,
40
34
  sourceLng,
41
- targetLng
35
+ targetLng,
36
+ translationProvider: this.translationProvider,
37
+ strategy
42
38
  });
43
- if (!result) return {
39
+ if (!translatedData) return {
44
40
  success: true
45
41
  };
46
42
  const collectionConfig = payload.collections[collection].config;
47
- await this.saveTranslatedDocument(payload, collection, collectionId, result.translatedData, targetLng, sourceLng, collectionConfig, publishOnTranslation);
43
+ await this.saveTranslatedDocument(payload, collection, collectionId, translatedData, targetLng, sourceLng, collectionConfig, publishOnTranslation);
48
44
  return {
49
45
  success: true
50
46
  };
@@ -0,0 +1,31 @@
1
+ import type { Field } from "payload";
2
+ /**
3
+ * Outcome of mapping a declared field path to a translatable subtree.
4
+ *
5
+ * - `resolved` — the path lands on a translatable leaf; `schema` + `sourceData`
6
+ * are ready for `translateContent`, and `fieldName` is the key to unwrap the result.
7
+ * - `not-found` — the path resolves to no field at all (a typo) → caller returns 400.
8
+ * - `not-translatable` — resolves to a field that isn't a text-like leaf → caller no-ops.
9
+ * - `inside-blocks` — the path descends through a polymorphic `blocks` field, which
10
+ * can't be resolved from the path alone (the blockType lives in the data) → caller no-ops.
11
+ */
12
+ export type FieldSubtreeResolution = {
13
+ status: "resolved";
14
+ schema: Field[];
15
+ sourceData: Record<string, unknown>;
16
+ fieldName: string;
17
+ } | {
18
+ status: "not-found";
19
+ } | {
20
+ status: "not-translatable";
21
+ } | {
22
+ status: "inside-blocks";
23
+ };
24
+ /**
25
+ * Map a declared `fieldPath` to the `{ schema, sourceData }` pair `translateContent` expects.
26
+ * Walks the schema by field name (via the shared {@link findFieldByPath}), dropping array indices
27
+ * (a field's config is shared across array items). Descends transparently through presentational
28
+ * containers (row, collapsible, unnamed tabs) and through named group/array/tab containers. A path
29
+ * that descends through a `blocks` field returns `inside-blocks`.
30
+ */
31
+ export declare function resolveFieldSubtree(rootFields: Field[], fieldPath: string, value: unknown): FieldSubtreeResolution;
@@ -0,0 +1,45 @@
1
+ import { isTranslatableField } from "../../shared";
2
+ import { findFieldByPath } from "../../shared/field-traversal";
3
+ const isIndexSegment = (segment)=>/^\d+$/u.test(segment);
4
+ /**
5
+ * Map a declared `fieldPath` to the `{ schema, sourceData }` pair `translateContent` expects.
6
+ * Walks the schema by field name (via the shared {@link findFieldByPath}), dropping array indices
7
+ * (a field's config is shared across array items). Descends transparently through presentational
8
+ * containers (row, collapsible, unnamed tabs) and through named group/array/tab containers. A path
9
+ * that descends through a `blocks` field returns `inside-blocks`.
10
+ */ export function resolveFieldSubtree(rootFields, fieldPath, value) {
11
+ const segments = fieldPath.split(".").map((segment)=>segment.trim()).filter((segment)=>segment.length > 0 && !isIndexSegment(segment));
12
+ if (segments.length === 0) return {
13
+ status: "not-found"
14
+ };
15
+ const result = findFieldByPath(rootFields, segments);
16
+ switch(result.status){
17
+ case "leaf":
18
+ return isTranslatableField(result.field) ? {
19
+ status: "resolved",
20
+ schema: [
21
+ result.field
22
+ ],
23
+ sourceData: {
24
+ [result.field.name]: value
25
+ },
26
+ fieldName: result.field.name
27
+ } : {
28
+ status: "not-translatable"
29
+ };
30
+ case "container":
31
+ return {
32
+ status: "not-translatable"
33
+ };
34
+ case "inside-blocks":
35
+ return {
36
+ status: "inside-blocks"
37
+ };
38
+ case "not-found":
39
+ return {
40
+ status: "not-found"
41
+ };
42
+ }
43
+ }
44
+
45
+ //# sourceMappingURL=resolveFieldSubtree.js.map
@@ -24,6 +24,16 @@ export type TaskRunnerContext = {
24
24
  handler: TaskHandler;
25
25
  collections: CollectionSlug[];
26
26
  };
27
+ /**
28
+ * The runtime half of a runner: produces a `TaskRunner` for one request.
29
+ *
30
+ * Routes depend on this narrow surface — they only ever `create()`, never
31
+ * `configure()`. The plugin binds the {@link TaskRunnerContext} once at build
32
+ * time and hands routes a factory, so a `create()` call needs no ambient state.
33
+ */
34
+ export type TaskRunnerFactory = {
35
+ create(payload: Payload): TaskRunner;
36
+ };
27
37
  /**
28
38
  * Main interface for pluggable task runner providers.
29
39
  *
@@ -36,8 +46,15 @@ export type TaskRunnerContext = {
36
46
  export interface TaskRunnerProvider {
37
47
  /**
38
48
  * Creates a TaskRunner instance for runtime operations (enqueue, cancel, find).
49
+ *
50
+ * `handler` is supplied by the caller at create time (the plugin binds it
51
+ * into a {@link TaskRunnerFactory}) — so providers hold no mutable per-instance
52
+ * state and `create()` does not depend on `configure()` having run. It is the
53
+ * only runtime dependency (collection metadata is a `configure()`-time concern).
54
+ * `PayloadJobsRunner` ignores it (the handler is baked into the registered
55
+ * task at configure time); `SyncRunner` uses it to run translations inline.
39
56
  */
40
- create(payload: Payload): TaskRunner;
57
+ create(payload: Payload, handler: TaskHandler): TaskRunner;
41
58
  /**
42
59
  * Configures the runner and returns a Payload config modifier.
43
60
  * The modifier adds necessary tasks, jobs, queues to Payload config.
@@ -1,6 +1,6 @@
1
- export type { TaskRunnerProvider } from './TaskRunnerProvider.interface';
2
- export type { Task, TaskStatus } from './types';
3
- export { createPayloadJobsRunner } from './payload-jobs-runner';
4
- export type { PayloadJobsRunnerOptions } from './payload-jobs-runner';
5
- export { createSyncRunner } from './sync-runner';
6
- export type { TaskRunner } from './TaskRunner.interface';
1
+ export type { TaskRunnerProvider, TaskRunnerFactory, TaskRunnerContext } from "./TaskRunnerProvider.interface";
2
+ export type { Task, TaskStatus } from "./types";
3
+ export { createPayloadJobsRunner } from "./payload-jobs-runner";
4
+ export type { PayloadJobsRunnerOptions } from "./payload-jobs-runner";
5
+ export { createSyncRunner } from "./sync-runner";
6
+ export type { TaskRunner } from "./TaskRunner.interface";
@@ -1,4 +1,4 @@
1
- export { createPayloadJobsRunner } from './payload-jobs-runner';
2
- export { createSyncRunner } from './sync-runner';
1
+ export { createPayloadJobsRunner } from "./payload-jobs-runner";
2
+ export { createSyncRunner } from "./sync-runner";
3
3
 
4
4
  //# sourceMappingURL=index.js.map
@@ -14,6 +14,21 @@ export declare class PayloadJobsRunnerProvider implements TaskRunnerProvider {
14
14
  configure(context: TaskRunnerContext): (config: Config) => Config;
15
15
  }
16
16
  /**
17
- * Creates a TaskRunnerProvider that uses Payload Jobs for task execution.
17
+ * Creates the **recommended** task runner: translations run as Payload Jobs
18
+ * (queued, executed by autoRun cron or a manual run, with stale-lock recovery).
19
+ * Durable across restarts and suited to production/serverless. Pass the result
20
+ * as `translatorPlugin({ runner })`.
21
+ *
22
+ * @param options - Queue/task names, `autoRun` cron (or `false` to disable),
23
+ * `staleJobTimeoutMs`, and retry policy. See {@link PayloadJobsRunnerOptions}.
24
+ * @returns A {@link TaskRunnerProvider} for the plugin's `runner` option.
25
+ * @example
26
+ * ```ts
27
+ * translatorPlugin({
28
+ * collections: [Posts],
29
+ * translationProvider: createOpenAIProvider({ apiKey: process.env.OPENAI_API_KEY! }),
30
+ * runner: createPayloadJobsRunner({ autoRun: { cron: '* * * * *' } }),
31
+ * })
32
+ * ```
18
33
  */
19
34
  export declare function createPayloadJobsRunner(options?: PayloadJobsRunnerOptions): TaskRunnerProvider;
@@ -172,7 +172,22 @@ const defaultValues = {
172
172
  }
173
173
  }
174
174
  /**
175
- * Creates a TaskRunnerProvider that uses Payload Jobs for task execution.
175
+ * Creates the **recommended** task runner: translations run as Payload Jobs
176
+ * (queued, executed by autoRun cron or a manual run, with stale-lock recovery).
177
+ * Durable across restarts and suited to production/serverless. Pass the result
178
+ * as `translatorPlugin({ runner })`.
179
+ *
180
+ * @param options - Queue/task names, `autoRun` cron (or `false` to disable),
181
+ * `staleJobTimeoutMs`, and retry policy. See {@link PayloadJobsRunnerOptions}.
182
+ * @returns A {@link TaskRunnerProvider} for the plugin's `runner` option.
183
+ * @example
184
+ * ```ts
185
+ * translatorPlugin({
186
+ * collections: [Posts],
187
+ * translationProvider: createOpenAIProvider({ apiKey: process.env.OPENAI_API_KEY! }),
188
+ * runner: createPayloadJobsRunner({ autoRun: { cron: '* * * * *' } }),
189
+ * })
190
+ * ```
176
191
  */ export function createPayloadJobsRunner(options) {
177
192
  return new PayloadJobsRunnerProvider(options);
178
193
  }