@focus-reactive/payload-plugin-translator 0.10.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -10
- package/dist/index.d.ts +8 -3
- package/dist/index.js +4 -3
- package/dist/translation-providers/index.d.ts +1 -0
- package/dist/translation-providers/index.js +1 -7
- package/dist/translation-providers/openai/OpenAI.shapes.d.ts +52 -0
- package/dist/translation-providers/openai/OpenAI.shapes.js +13 -0
- package/dist/translation-providers/openai/OpenAITranslation.provider.d.ts +51 -112
- package/dist/translation-providers/openai/OpenAITranslation.provider.js +49 -137
- package/dist/translation-providers/openai/OpenAITranslationLegacy.provider.d.ts +11 -0
- package/dist/translation-providers/openai/OpenAITranslationLegacy.provider.js +15 -0
- package/dist/translation-providers/openai/index.d.ts +6 -1
- package/dist/translation-providers/openai/index.js +3 -3
- package/dist/translation-providers/openai/loadOpenAIClient.d.ts +24 -0
- package/dist/translation-providers/openai/loadOpenAIClient.js +79 -0
- package/dist/translation-providers/openai/openAIComplete.d.ts +39 -0
- package/dist/translation-providers/openai/openAIComplete.js +84 -0
- package/dist/translation-providers/shared/CompletionProvider.provider.d.ts +65 -0
- package/dist/translation-providers/shared/CompletionProvider.provider.js +93 -0
- package/dist/translation-providers/shared/buildResponseSchema.d.ts +13 -0
- package/dist/translation-providers/shared/buildResponseSchema.js +22 -0
- package/dist/translation-providers/shared/buildSystemPrompt.d.ts +28 -0
- package/dist/translation-providers/shared/buildSystemPrompt.js +25 -0
- package/dist/translation-providers/shared/errors/KeySetMismatchError.d.ts +15 -0
- package/dist/translation-providers/shared/errors/KeySetMismatchError.js +26 -0
- package/dist/translation-providers/shared/errors/NoContentError.d.ts +9 -0
- package/dist/translation-providers/shared/errors/NoContentError.js +10 -0
- package/dist/translation-providers/shared/errors/ProviderConfigurationError.d.ts +10 -0
- package/dist/translation-providers/shared/errors/ProviderConfigurationError.js +11 -0
- package/dist/translation-providers/shared/errors/TranslationProviderError.d.ts +18 -0
- package/dist/translation-providers/shared/errors/TranslationProviderError.js +21 -0
- package/dist/translation-providers/shared/errors/TransportError.d.ts +10 -0
- package/dist/translation-providers/shared/errors/TransportError.js +11 -0
- package/dist/translation-providers/shared/errors/UnparseableReplyError.d.ts +9 -0
- package/dist/translation-providers/shared/errors/UnparseableReplyError.js +10 -0
- package/dist/translation-providers/shared/errors/errorMessageLower.d.ts +1 -0
- package/dist/translation-providers/shared/errors/errorMessageLower.js +8 -0
- package/dist/translation-providers/shared/errors/index.d.ts +9 -0
- package/dist/translation-providers/shared/errors/index.js +10 -0
- package/dist/translation-providers/shared/errors/wrapTransportError.d.ts +7 -0
- package/dist/translation-providers/shared/errors/wrapTransportError.js +14 -0
- package/dist/translation-providers/shared/index.d.ts +8 -0
- package/dist/translation-providers/shared/index.js +5 -0
- package/dist/translation-providers/shared/parseAndValidateReply.d.ts +13 -0
- package/dist/translation-providers/shared/parseAndValidateReply.js +46 -0
- package/dist/translation-providers/shared/runDryRun.d.ts +20 -0
- package/dist/translation-providers/shared/runDryRun.js +17 -0
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context handed to a {@link SystemPromptBuilder}.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.11.0
|
|
5
|
+
*/
|
|
6
|
+
export type SystemPromptContext = {
|
|
7
|
+
/** Source language code (e.g. 'en', 'de'). Empty when the provider should auto-detect. */
|
|
8
|
+
sourceLang: string;
|
|
9
|
+
targetLang: string;
|
|
10
|
+
defaultPrompt: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Builds a custom system prompt for translation.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.11.0
|
|
16
|
+
*/
|
|
17
|
+
export type SystemPromptBuilder = (context: SystemPromptContext) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Produces the system prompt sent with a translation request.
|
|
20
|
+
*
|
|
21
|
+
* The default wording is handed to `systemPrompt` builders as `defaultPrompt`, so consumers extend
|
|
22
|
+
* this exact string — changing it changes every custom prompt built on it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildSystemPrompt(args: {
|
|
25
|
+
sourceLng: string;
|
|
26
|
+
targetLng: string;
|
|
27
|
+
override?: SystemPromptBuilder;
|
|
28
|
+
}): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context handed to a {@link SystemPromptBuilder}.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.11.0
|
|
5
|
+
*/ /**
|
|
6
|
+
* Produces the system prompt sent with a translation request.
|
|
7
|
+
*
|
|
8
|
+
* The default wording is handed to `systemPrompt` builders as `defaultPrompt`, so consumers extend
|
|
9
|
+
* this exact string — changing it changes every custom prompt built on it.
|
|
10
|
+
*/ export function buildSystemPrompt(args) {
|
|
11
|
+
const { sourceLng, targetLng, override } = args;
|
|
12
|
+
const defaultPrompt = `Translate the values from the JSON that the user will send you${sourceLng ? ` from ${sourceLng}` : ""} into ${targetLng}. Keep all JSON keys exactly as they are, only translate the values.
|
|
13
|
+
The response should be a valid JSON object with the same structure and keys as the input, but with translated values.
|
|
14
|
+
Maintain any special formatting, placeholders, or variables within the values if they exist.`;
|
|
15
|
+
if (override) {
|
|
16
|
+
return override({
|
|
17
|
+
sourceLang: sourceLng,
|
|
18
|
+
targetLang: targetLng,
|
|
19
|
+
defaultPrompt
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return defaultPrompt;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=buildSystemPrompt.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* Nothing in the reply could be applied — either its keys did not overlap the input's, or they did
|
|
4
|
+
* and none of the values was a string. A partial gap is not an error; see `parseAndValidateReply`.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/
|
|
8
|
+
export declare class KeySetMismatchError extends TranslationProviderError {
|
|
9
|
+
readonly code: "key-set-mismatch";
|
|
10
|
+
/** Input keys left without a usable translation. */
|
|
11
|
+
readonly missingInputKeys: number[];
|
|
12
|
+
/** Keys the reply carried but nobody asked for — model output, so untrusted text. */
|
|
13
|
+
readonly unrequestedReplyKeys: string[];
|
|
14
|
+
constructor(message: string, missingInputKeys: number[], unrequestedReplyKeys: string[], options?: ErrorOptions);
|
|
15
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* Nothing in the reply could be applied — either its keys did not overlap the input's, or they did
|
|
4
|
+
* and none of the values was a string. A partial gap is not an error; see `parseAndValidateReply`.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/ export class KeySetMismatchError extends TranslationProviderError {
|
|
8
|
+
code = "key-set-mismatch";
|
|
9
|
+
/** Input keys left without a usable translation. */ missingInputKeys;
|
|
10
|
+
/** Keys the reply carried but nobody asked for — model output, so untrusted text. */ unrequestedReplyKeys;
|
|
11
|
+
constructor(message, missingInputKeys, unrequestedReplyKeys, options){
|
|
12
|
+
super(message, options);
|
|
13
|
+
this.missingInputKeys = missingInputKeys;
|
|
14
|
+
this.unrequestedReplyKeys = unrequestedReplyKeys;
|
|
15
|
+
// Model-invented strings: enumerable, they would land in `JSON.stringify(error)` and every
|
|
16
|
+
// structured logger.
|
|
17
|
+
Object.defineProperty(this, "missingInputKeys", {
|
|
18
|
+
enumerable: false
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "unrequestedReplyKeys", {
|
|
21
|
+
enumerable: false
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=KeySetMismatchError.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The provider produced no usable text — an empty reply, or a response the vendor filtered.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/
|
|
7
|
+
export declare class NoContentError extends TranslationProviderError {
|
|
8
|
+
readonly code: "no-content";
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The provider produced no usable text — an empty reply, or a response the vendor filtered.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/ export class NoContentError extends TranslationProviderError {
|
|
7
|
+
code = "no-content";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=NoContentError.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The provider is configured in a way that cannot work — most often an optional SDK that is not
|
|
4
|
+
* installed.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/
|
|
8
|
+
export declare class ProviderConfigurationError extends TranslationProviderError {
|
|
9
|
+
readonly code: "config";
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The provider is configured in a way that cannot work — most often an optional SDK that is not
|
|
4
|
+
* installed.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/ export class ProviderConfigurationError extends TranslationProviderError {
|
|
8
|
+
code = "config";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=ProviderConfigurationError.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Failure causes a translation provider can report.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.11.0
|
|
5
|
+
*/
|
|
6
|
+
export type TranslationFailureCode = "no-content" | "unparseable-reply" | "key-set-mismatch" | "transport" | "config";
|
|
7
|
+
/**
|
|
8
|
+
* Base class for every failure a built-in translation provider reports.
|
|
9
|
+
*
|
|
10
|
+
* The original failure travels on `cause` and is never interpolated into `message`: a vendor SDK
|
|
11
|
+
* error can carry an API key, and `message` reaches an HTTP response body.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.11.0
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class TranslationProviderError extends Error {
|
|
16
|
+
abstract readonly code: TranslationFailureCode;
|
|
17
|
+
constructor(message: string, options?: ErrorOptions);
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Failure causes a translation provider can report.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.11.0
|
|
5
|
+
*/ /**
|
|
6
|
+
* Base class for every failure a built-in translation provider reports.
|
|
7
|
+
*
|
|
8
|
+
* The original failure travels on `cause` and is never interpolated into `message`: a vendor SDK
|
|
9
|
+
* error can carry an API key, and `message` reaches an HTTP response body.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.11.0
|
|
12
|
+
*/ export class TranslationProviderError extends Error {
|
|
13
|
+
constructor(message, options){
|
|
14
|
+
// Never `this.cause = cause`: an assigned property is enumerable, so JSON.stringify and pino
|
|
15
|
+
// serialize the vendor error whole — headers and API key with it. `super` installs it non-enumerably.
|
|
16
|
+
super(message, options);
|
|
17
|
+
this.name = new.target.name;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=TranslationProviderError.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The call to the provider failed — network, auth, rate limit, timeout. The vendor's own error is on
|
|
4
|
+
* `cause`.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/
|
|
8
|
+
export declare class TransportError extends TranslationProviderError {
|
|
9
|
+
readonly code: "transport";
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The call to the provider failed — network, auth, rate limit, timeout. The vendor's own error is on
|
|
4
|
+
* `cause`.
|
|
5
|
+
*
|
|
6
|
+
* @since 0.11.0
|
|
7
|
+
*/ export class TransportError extends TranslationProviderError {
|
|
8
|
+
code = "transport";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=TransportError.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The reply was not JSON, or parsed to something that is not an object — arrays included.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/
|
|
7
|
+
export declare class UnparseableReplyError extends TranslationProviderError {
|
|
8
|
+
readonly code: "unparseable-reply";
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* The reply was not JSON, or parsed to something that is not an object — arrays included.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.11.0
|
|
6
|
+
*/ export class UnparseableReplyError extends TranslationProviderError {
|
|
7
|
+
code = "unparseable-reply";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=UnparseableReplyError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function errorMessageLower(cause: unknown): string | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { isObject } from "../../../core/kernel/utils/isObject";
|
|
2
|
+
export function errorMessageLower(cause) {
|
|
3
|
+
if (!isObject(cause)) return null;
|
|
4
|
+
const message = cause.message;
|
|
5
|
+
return typeof message === "string" ? message.toLowerCase() : null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=errorMessageLower.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
export type { TranslationFailureCode } from "./TranslationProviderError";
|
|
3
|
+
export { NoContentError } from "./NoContentError";
|
|
4
|
+
export { UnparseableReplyError } from "./UnparseableReplyError";
|
|
5
|
+
export { KeySetMismatchError } from "./KeySetMismatchError";
|
|
6
|
+
export { TransportError } from "./TransportError";
|
|
7
|
+
export { ProviderConfigurationError } from "./ProviderConfigurationError";
|
|
8
|
+
export { wrapTransportError } from "./wrapTransportError";
|
|
9
|
+
export { errorMessageLower } from "./errorMessageLower";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
export { NoContentError } from "./NoContentError";
|
|
3
|
+
export { UnparseableReplyError } from "./UnparseableReplyError";
|
|
4
|
+
export { KeySetMismatchError } from "./KeySetMismatchError";
|
|
5
|
+
export { TransportError } from "./TransportError";
|
|
6
|
+
export { ProviderConfigurationError } from "./ProviderConfigurationError";
|
|
7
|
+
export { wrapTransportError } from "./wrapTransportError";
|
|
8
|
+
export { errorMessageLower } from "./errorMessageLower";
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
2
|
+
/**
|
|
3
|
+
* Turns anything a transport threw into a {@link TransportError}, keeping the original on `cause`.
|
|
4
|
+
* A value that is already one of ours passes through: re-wrapping would bury a specific cause under
|
|
5
|
+
* a generic transport failure.
|
|
6
|
+
*/
|
|
7
|
+
export declare function wrapTransportError(cause: unknown): TranslationProviderError;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TransportError } from "./TransportError";
|
|
2
|
+
import { TranslationProviderError } from "./TranslationProviderError";
|
|
3
|
+
/**
|
|
4
|
+
* Turns anything a transport threw into a {@link TransportError}, keeping the original on `cause`.
|
|
5
|
+
* A value that is already one of ours passes through: re-wrapping would bury a specific cause under
|
|
6
|
+
* a generic transport failure.
|
|
7
|
+
*/ export function wrapTransportError(cause) {
|
|
8
|
+
if (cause instanceof TranslationProviderError) return cause;
|
|
9
|
+
return new TransportError("The translation request failed before a reply could be read. The provider's own error is on this error's `cause` property.", {
|
|
10
|
+
cause
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=wrapTransportError.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createTranslationProvider } from "./CompletionProvider.provider";
|
|
2
|
+
export type { CompletionFn, CompletionRequest, TranslationProviderConfig, } from "./CompletionProvider.provider";
|
|
3
|
+
export type { JsonSchemaObject } from "./buildResponseSchema";
|
|
4
|
+
export type { SystemPromptBuilder, SystemPromptContext } from "./buildSystemPrompt";
|
|
5
|
+
export type { DryRunConfig, DryRunTransformer } from "./runDryRun";
|
|
6
|
+
export { errorMessageLower } from "./errors";
|
|
7
|
+
export { TranslationProviderError, NoContentError, UnparseableReplyError, KeySetMismatchError, TransportError, ProviderConfigurationError, } from "./errors";
|
|
8
|
+
export type { TranslationFailureCode } from "./errors";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createTranslationProvider } from "./CompletionProvider.provider";
|
|
2
|
+
export { errorMessageLower } from "./errors";
|
|
3
|
+
export { TranslationProviderError, NoContentError, UnparseableReplyError, KeySetMismatchError, TransportError, ProviderConfigurationError } from "./errors";
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TranslationInput, TranslationOutput } from "../../core/domain/translation-providers";
|
|
2
|
+
export type ParsedReply = {
|
|
3
|
+
translations: TranslationOutput;
|
|
4
|
+
missingInputKeys: number[];
|
|
5
|
+
unrequestedReplyKeys: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Parses an untrusted reply into a {@link TranslationOutput} and reports the key-set gap.
|
|
9
|
+
*
|
|
10
|
+
* A partial answer is applied, not rejected — the gap is returned so the caller can report it. Only
|
|
11
|
+
* a reply that answers nothing is a failure ({@link KeySetMismatchError}).
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseAndValidateReply(input: TranslationInput, raw: string): ParsedReply;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isObject } from "../../core/kernel/utils/isObject";
|
|
2
|
+
import { KeySetMismatchError, UnparseableReplyError } from "./errors";
|
|
3
|
+
/**
|
|
4
|
+
* Parses an untrusted reply into a {@link TranslationOutput} and reports the key-set gap.
|
|
5
|
+
*
|
|
6
|
+
* A partial answer is applied, not rejected — the gap is returned so the caller can report it. Only
|
|
7
|
+
* a reply that answers nothing is a failure ({@link KeySetMismatchError}).
|
|
8
|
+
*/ export function parseAndValidateReply(input, raw) {
|
|
9
|
+
let parsed;
|
|
10
|
+
try {
|
|
11
|
+
parsed = JSON.parse(raw);
|
|
12
|
+
} catch (cause) {
|
|
13
|
+
throw new UnparseableReplyError("The provider's reply was not valid JSON.", {
|
|
14
|
+
cause
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
// `isObject` admits arrays: `["a"]` has key "0", so a 0-based input would accept it by coincidence.
|
|
18
|
+
if (!isObject(parsed) || Array.isArray(parsed)) {
|
|
19
|
+
throw new UnparseableReplyError("The provider's reply was JSON, but not an object.");
|
|
20
|
+
}
|
|
21
|
+
const expectedKeys = new Set(Object.keys(input));
|
|
22
|
+
const translations = {};
|
|
23
|
+
const missingInputKeys = [];
|
|
24
|
+
for (const key of expectedKeys){
|
|
25
|
+
const value = parsed[key];
|
|
26
|
+
if (typeof value === "string") {
|
|
27
|
+
translations[Number(key)] = value;
|
|
28
|
+
} else {
|
|
29
|
+
missingInputKeys.push(Number(key));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const unrequestedReplyKeys = Object.keys(parsed).filter((key)=>!expectedKeys.has(key));
|
|
33
|
+
if (expectedKeys.size > 0 && Object.keys(translations).length === 0) {
|
|
34
|
+
const answeredAnyKey = [
|
|
35
|
+
...expectedKeys
|
|
36
|
+
].some((key)=>Object.hasOwn(parsed, key));
|
|
37
|
+
throw new KeySetMismatchError(answeredAnyKey ? `The provider's reply carried the requested keys, but none of the ${expectedKeys.size} values was a string.` : `The provider's reply answered none of the ${expectedKeys.size} requested keys.`, missingInputKeys, unrequestedReplyKeys);
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
translations,
|
|
41
|
+
missingInputKeys,
|
|
42
|
+
unrequestedReplyKeys
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=parseAndValidateReply.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TranslationInput, TranslationOutput } from "../../core/domain/translation-providers";
|
|
2
|
+
export type DryRunTransformer = (text: string) => string | Promise<string>;
|
|
3
|
+
/**
|
|
4
|
+
* Dry-run configuration: a transformer, and optionally a delay that imitates network latency.
|
|
5
|
+
*
|
|
6
|
+
* @deprecated Supply your own fake `complete` instead. Remove in next major.
|
|
7
|
+
* See docs/DEPRECATIONS.md#provider-dry-run
|
|
8
|
+
*/
|
|
9
|
+
export type DryRunConfig = {
|
|
10
|
+
/** Applied to every non-blank value. */
|
|
11
|
+
transform: DryRunTransformer;
|
|
12
|
+
/** Milliseconds to wait before returning. */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Simulates a translation without calling anything. Blank values pass through untouched.
|
|
17
|
+
*
|
|
18
|
+
* Logs the field count and never field content: the log reaches shared infrastructure.
|
|
19
|
+
*/
|
|
20
|
+
export declare function runDryRun(input: TranslationInput, config: boolean | DryRunConfig): Promise<TranslationOutput>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const reverse = (text)=>text.split("").reverse().join("");
|
|
2
|
+
/**
|
|
3
|
+
* Simulates a translation without calling anything. Blank values pass through untouched.
|
|
4
|
+
*
|
|
5
|
+
* Logs the field count and never field content: the log reaches shared infrastructure.
|
|
6
|
+
*/ export async function runDryRun(input, config) {
|
|
7
|
+
console.info(`[payload-plugin-translator] Dry run: simulated ${Object.keys(input).length} field(s), no API call made.`);
|
|
8
|
+
const { transform = reverse, timeout = 0 } = typeof config === "object" ? config : {};
|
|
9
|
+
if (timeout > 0) await new Promise((resolve)=>setTimeout(resolve, timeout));
|
|
10
|
+
const output = {};
|
|
11
|
+
for (const [key, value] of Object.entries(input)){
|
|
12
|
+
output[Number(key)] = value.trim() ? await transform(value) : value;
|
|
13
|
+
}
|
|
14
|
+
return output;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=runDryRun.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@focus-reactive/payload-plugin-translator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Translation plugin for Payload CMS 3.x. Automatically translate your localized content using any translation provider.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|