@easyling/sanity-connector 1.3.0-rc.9 → 1.4.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 +32 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +1 -1
- package/dist-types/components/dialogs/LocaleSelectionDialog.d.ts +22 -0
- package/dist-types/services/collisionDetectionService.d.ts +85 -0
- package/dist-types/services/documentCreationService.d.ts +66 -0
- package/dist-types/services/unifiedConfigStorage.d.ts +25 -0
- package/dist-types/types/dialog.d.ts +12 -0
- package/dist-types/types/pluginConfig.d.ts +18 -0
- package/package.json +1 -1
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import type { LocaleDefinition } from '../../types/locale';
|
|
9
|
+
import type { CollisionResolutionMode, ExistingDocumentHandling } from '../../types/pluginConfig';
|
|
10
|
+
/**
|
|
11
|
+
* Result returned when user confirms locale selection
|
|
12
|
+
*/
|
|
13
|
+
export interface LocaleSelectionResult {
|
|
14
|
+
/** Selected locale codes */
|
|
15
|
+
locales: string[];
|
|
16
|
+
/** Document creation mode */
|
|
17
|
+
creationMode?: 'draft' | 'published';
|
|
18
|
+
/** Collision resolution mode (if override is enabled) */
|
|
19
|
+
collisionResolutionMode?: CollisionResolutionMode;
|
|
20
|
+
/** Existing document handling (if override is enabled) */
|
|
21
|
+
existingDocumentHandling?: ExistingDocumentHandling;
|
|
22
|
+
}
|
|
9
23
|
export interface LocaleSelectionDialogProps {
|
|
10
24
|
/** Whether the dialog is open */
|
|
11
25
|
open: boolean;
|
|
@@ -29,8 +43,16 @@ export interface LocaleSelectionDialogProps {
|
|
|
29
43
|
showCreationModeOption?: boolean;
|
|
30
44
|
/** Default creation mode to pre-select */
|
|
31
45
|
defaultCreationMode?: 'draft' | 'published';
|
|
46
|
+
/** Whether to show collision resolution override options */
|
|
47
|
+
showCollisionResolutionOverride?: boolean;
|
|
48
|
+
/** Default collision resolution mode from config */
|
|
49
|
+
defaultCollisionResolutionMode?: CollisionResolutionMode;
|
|
50
|
+
/** Default existing document handling from config */
|
|
51
|
+
defaultExistingDocumentHandling?: ExistingDocumentHandling;
|
|
32
52
|
/** Callback when user confirms selection */
|
|
33
53
|
onConfirm: (selectedLocales: string[], creationMode?: 'draft' | 'published') => void;
|
|
54
|
+
/** Enhanced callback with full result object */
|
|
55
|
+
onConfirmWithOptions?: (result: LocaleSelectionResult) => void;
|
|
34
56
|
/** Callback when user cancels */
|
|
35
57
|
onCancel: () => void;
|
|
36
58
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collision Detection Service
|
|
3
|
+
* Requirements: Translation Collision Handling - EARS 2.1, 2.2
|
|
4
|
+
*
|
|
5
|
+
* Detects existing translated documents for the same source document and target locale
|
|
6
|
+
* to enable collision resolution handling.
|
|
7
|
+
*/
|
|
8
|
+
import { SanityClient, SanityDocument } from 'sanity';
|
|
9
|
+
/**
|
|
10
|
+
* Result of a collision detection check
|
|
11
|
+
*/
|
|
12
|
+
export interface CollisionResult {
|
|
13
|
+
/** Whether a collision was detected */
|
|
14
|
+
detected: boolean;
|
|
15
|
+
/** The existing translated document if collision was detected */
|
|
16
|
+
existingDocument?: SanityDocument;
|
|
17
|
+
/** How the collision was identified */
|
|
18
|
+
matchedBy?: 'parent' | 'slug-locale';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Options for collision detection
|
|
22
|
+
*/
|
|
23
|
+
export interface CollisionDetectionOptions {
|
|
24
|
+
/** The source document ID (the original document being translated) */
|
|
25
|
+
sourceDocumentId: string;
|
|
26
|
+
/** The target locale code for the translation */
|
|
27
|
+
targetLocale: string;
|
|
28
|
+
/** The slug of the translated document (optional, used for slug-locale matching) */
|
|
29
|
+
slug?: string;
|
|
30
|
+
/** The document type to search within */
|
|
31
|
+
documentType?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Error type for collision detection operations
|
|
35
|
+
*/
|
|
36
|
+
export declare class CollisionDetectionError extends Error {
|
|
37
|
+
code: string;
|
|
38
|
+
details?: unknown | undefined;
|
|
39
|
+
constructor(message: string, code: string, details?: unknown | undefined);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Service for detecting translation collisions
|
|
43
|
+
*
|
|
44
|
+
* A collision occurs when a translated document already exists for the same
|
|
45
|
+
* source document and target locale. The service identifies collisions using:
|
|
46
|
+
* 1. Parent reference matching: parentDocument._ref == sourceDocumentId AND locale == targetLocale
|
|
47
|
+
* 2. Slug-locale matching: slug.current == slug AND locale == targetLocale
|
|
48
|
+
*/
|
|
49
|
+
export declare class CollisionDetectionService {
|
|
50
|
+
private client;
|
|
51
|
+
constructor(client: SanityClient);
|
|
52
|
+
/**
|
|
53
|
+
* Detect if a collision exists for the given source document and target locale
|
|
54
|
+
*
|
|
55
|
+
* @param options - Options specifying the source document, target locale, and optional slug
|
|
56
|
+
* @returns CollisionResult indicating whether a collision was found and details
|
|
57
|
+
*/
|
|
58
|
+
detectCollision(options: CollisionDetectionOptions): Promise<CollisionResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Find an existing document by parent reference and locale
|
|
61
|
+
*
|
|
62
|
+
* @param sourceDocumentId - The ID of the source/parent document
|
|
63
|
+
* @param targetLocale - The target locale code
|
|
64
|
+
* @param documentType - Optional document type to filter by
|
|
65
|
+
*/
|
|
66
|
+
private findByParentReference;
|
|
67
|
+
/**
|
|
68
|
+
* Find an existing document by slug and locale
|
|
69
|
+
*
|
|
70
|
+
* @param slug - The document slug to match
|
|
71
|
+
* @param targetLocale - The target locale code
|
|
72
|
+
* @param documentType - Optional document type to filter by
|
|
73
|
+
*/
|
|
74
|
+
private findBySlugAndLocale;
|
|
75
|
+
/**
|
|
76
|
+
* Check if multiple collisions exist for bulk translation operations
|
|
77
|
+
*
|
|
78
|
+
* @param sourceDocumentId - The source document being translated
|
|
79
|
+
* @param targetLocales - Array of target locale codes
|
|
80
|
+
* @param slug - Optional slug for slug-locale matching
|
|
81
|
+
* @param documentType - Optional document type to filter by
|
|
82
|
+
* @returns Map of locale code to collision result
|
|
83
|
+
*/
|
|
84
|
+
detectBulkCollisions(sourceDocumentId: string, targetLocales: string[], slug?: string, documentType?: string): Promise<Map<string, CollisionResult>>;
|
|
85
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SanityDocument, SanityClient } from 'sanity';
|
|
2
2
|
import { TranslationResponse } from './translationService';
|
|
3
|
+
import { CollisionResolutionMode, ExistingDocumentHandling } from '../types/pluginConfig';
|
|
3
4
|
/**
|
|
4
5
|
* Options for document creation from translation
|
|
5
6
|
*/
|
|
@@ -31,6 +32,18 @@ export interface DocumentCreationOptions {
|
|
|
31
32
|
* Used to write translated content back to the correct location.
|
|
32
33
|
*/
|
|
33
34
|
bodyFieldName?: string;
|
|
35
|
+
/**
|
|
36
|
+
* How to handle collisions when a translated document already exists.
|
|
37
|
+
* - 'replace': Overwrite the existing document with new translations
|
|
38
|
+
* - 'create': Create a new document (default behavior if not specified)
|
|
39
|
+
*/
|
|
40
|
+
collisionResolutionMode?: CollisionResolutionMode;
|
|
41
|
+
/**
|
|
42
|
+
* How to handle the existing document when creating a new one (only for 'create' mode).
|
|
43
|
+
* - 'draft': Set the existing document to draft state
|
|
44
|
+
* - 'delete': Delete the existing document
|
|
45
|
+
*/
|
|
46
|
+
existingDocumentHandling?: ExistingDocumentHandling;
|
|
34
47
|
}
|
|
35
48
|
export interface SlugFallbackInfo {
|
|
36
49
|
documentId: string;
|
|
@@ -39,12 +52,29 @@ export interface SlugFallbackInfo {
|
|
|
39
52
|
locale: string;
|
|
40
53
|
reason: string;
|
|
41
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Information about a collision that was detected and resolved
|
|
57
|
+
*/
|
|
58
|
+
export interface CollisionResolutionInfo {
|
|
59
|
+
/** Whether a collision was detected */
|
|
60
|
+
collisionDetected: boolean;
|
|
61
|
+
/** The resolution action that was taken */
|
|
62
|
+
resolutionAction?: 'replaced' | 'created_new' | 'none';
|
|
63
|
+
/** The ID of the document that was replaced, updated, or deleted */
|
|
64
|
+
existingDocumentId?: string;
|
|
65
|
+
/** How the existing document was handled (for 'create' mode) */
|
|
66
|
+
existingDocumentAction?: 'set_to_draft' | 'deleted' | 'none';
|
|
67
|
+
/** How the collision was detected */
|
|
68
|
+
matchedBy?: 'parent' | 'slug-locale';
|
|
69
|
+
}
|
|
42
70
|
export interface DocumentCreationResult {
|
|
43
71
|
success: boolean;
|
|
44
72
|
documentId?: string;
|
|
45
73
|
document?: SanityDocument;
|
|
46
74
|
error?: string;
|
|
47
75
|
slugFallback?: SlugFallbackInfo;
|
|
76
|
+
/** Information about collision detection and resolution */
|
|
77
|
+
collisionInfo?: CollisionResolutionInfo;
|
|
48
78
|
}
|
|
49
79
|
export interface BulkDocumentCreationResult {
|
|
50
80
|
totalDocuments: number;
|
|
@@ -63,12 +93,48 @@ export interface RollbackInfo {
|
|
|
63
93
|
export declare class DocumentCreationService {
|
|
64
94
|
private client;
|
|
65
95
|
private defaultCreationMode;
|
|
96
|
+
private collisionDetectionService;
|
|
97
|
+
private defaultCollisionResolutionMode;
|
|
98
|
+
private defaultExistingDocumentHandling;
|
|
66
99
|
constructor(client: SanityClient, defaultCreationMode?: 'draft' | 'published');
|
|
67
100
|
/**
|
|
68
101
|
* Set the default document creation mode
|
|
69
102
|
* @param mode - The creation mode to use by default ('draft' or 'published')
|
|
70
103
|
*/
|
|
71
104
|
setDefaultCreationMode(mode: 'draft' | 'published'): void;
|
|
105
|
+
/**
|
|
106
|
+
* Set the default collision resolution mode
|
|
107
|
+
* @param mode - How to handle collisions ('replace' or 'create')
|
|
108
|
+
*/
|
|
109
|
+
setDefaultCollisionResolutionMode(mode: CollisionResolutionMode): void;
|
|
110
|
+
/**
|
|
111
|
+
* Set the default existing document handling mode
|
|
112
|
+
* @param handling - How to handle existing documents when creating new ('draft' or 'delete')
|
|
113
|
+
*/
|
|
114
|
+
setDefaultExistingDocumentHandling(handling: ExistingDocumentHandling): void;
|
|
115
|
+
/**
|
|
116
|
+
* Configure collision resolution defaults
|
|
117
|
+
* @param mode - Collision resolution mode
|
|
118
|
+
* @param handling - Existing document handling (only applicable when mode is 'create')
|
|
119
|
+
*/
|
|
120
|
+
setCollisionResolutionConfig(mode: CollisionResolutionMode, handling?: ExistingDocumentHandling): void;
|
|
121
|
+
/**
|
|
122
|
+
* Replace an existing document with new translated content
|
|
123
|
+
* Requirements: EARS 4 - Resolution Behavior - Replace
|
|
124
|
+
*
|
|
125
|
+
* @param existingDocument - The document to replace
|
|
126
|
+
* @param newDocument - The new translated document content
|
|
127
|
+
* @param creationMode - Whether to create as draft or published
|
|
128
|
+
*/
|
|
129
|
+
private replaceExistingDocument;
|
|
130
|
+
/**
|
|
131
|
+
* Handle an existing document when creating a new translation (for 'create' mode)
|
|
132
|
+
* Requirements: EARS 5 - Resolution Behavior - Create
|
|
133
|
+
*
|
|
134
|
+
* @param existingDocument - The existing document to handle
|
|
135
|
+
* @param handling - How to handle the existing document ('draft' or 'delete')
|
|
136
|
+
*/
|
|
137
|
+
private handleExistingDocument;
|
|
72
138
|
/**
|
|
73
139
|
* Create a new Sanity document from translation response
|
|
74
140
|
* Requirements: 1.1, 1.2, 2.1, 3.2, 3.4
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { SanityClient } from 'sanity';
|
|
13
13
|
import { OAuthConfig } from '../types/oauth';
|
|
14
14
|
import { LocaleConfig } from '../types/locale';
|
|
15
|
+
import { CollisionResolutionMode, ExistingDocumentHandling } from '../types/pluginConfig';
|
|
15
16
|
/**
|
|
16
17
|
* Unified plugin configuration structure
|
|
17
18
|
*/
|
|
@@ -24,6 +25,9 @@ export interface UnifiedPluginConfig {
|
|
|
24
25
|
requestContentType?: 'application/json' | 'application/x-protobuf';
|
|
25
26
|
responseAcceptHeader?: 'application/json' | 'application/x-protobuf';
|
|
26
27
|
defaultDocumentCreationMode?: 'draft' | 'published';
|
|
28
|
+
/** Collision resolution settings */
|
|
29
|
+
collisionResolutionMode?: CollisionResolutionMode;
|
|
30
|
+
existingDocumentHandling?: ExistingDocumentHandling;
|
|
27
31
|
/** Locale configuration */
|
|
28
32
|
locales?: LocaleConfig['locales'];
|
|
29
33
|
defaultLocale?: string;
|
|
@@ -122,6 +126,27 @@ export declare class UnifiedConfigStorage {
|
|
|
122
126
|
* Get default document creation mode with fallback to default
|
|
123
127
|
*/
|
|
124
128
|
getDefaultDocumentCreationMode(): Promise<'draft' | 'published'>;
|
|
129
|
+
/**
|
|
130
|
+
* Get collision resolution mode with fallback to default ('replace')
|
|
131
|
+
*/
|
|
132
|
+
getCollisionResolutionMode(): Promise<CollisionResolutionMode>;
|
|
133
|
+
/**
|
|
134
|
+
* Get existing document handling mode with fallback to default ('draft')
|
|
135
|
+
* Only applicable when collision resolution mode is 'create'
|
|
136
|
+
*/
|
|
137
|
+
getExistingDocumentHandling(): Promise<ExistingDocumentHandling>;
|
|
138
|
+
/**
|
|
139
|
+
* Get complete collision resolution configuration
|
|
140
|
+
* Returns both the resolution mode and existing document handling settings
|
|
141
|
+
*/
|
|
142
|
+
getCollisionResolutionConfig(): Promise<{
|
|
143
|
+
collisionResolutionMode: CollisionResolutionMode;
|
|
144
|
+
existingDocumentHandling: ExistingDocumentHandling;
|
|
145
|
+
}>;
|
|
146
|
+
/**
|
|
147
|
+
* Set collision resolution configuration
|
|
148
|
+
*/
|
|
149
|
+
setCollisionResolutionConfig(mode: CollisionResolutionMode, handling?: ExistingDocumentHandling): Promise<void>;
|
|
125
150
|
/**
|
|
126
151
|
* Get debug mode status
|
|
127
152
|
*/
|
|
@@ -68,6 +68,12 @@ export interface LocaleSelectionDialogOptions extends BaseDialogOptions {
|
|
|
68
68
|
showCreationModeOption?: boolean;
|
|
69
69
|
/** Default creation mode to pre-select */
|
|
70
70
|
defaultCreationMode?: 'draft' | 'published';
|
|
71
|
+
/** Whether to show collision resolution override options */
|
|
72
|
+
showCollisionResolutionOverride?: boolean;
|
|
73
|
+
/** Default collision resolution mode from config */
|
|
74
|
+
defaultCollisionResolutionMode?: CollisionResolutionMode;
|
|
75
|
+
/** Default existing document handling from config */
|
|
76
|
+
defaultExistingDocumentHandling?: ExistingDocumentHandling;
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
73
79
|
* Locale selection result
|
|
@@ -77,6 +83,10 @@ export interface LocaleSelectionResult {
|
|
|
77
83
|
locales: string[];
|
|
78
84
|
/** Selected creation mode (if showCreationModeOption was true) */
|
|
79
85
|
creationMode?: 'draft' | 'published';
|
|
86
|
+
/** Collision resolution mode (if override was enabled) */
|
|
87
|
+
collisionResolutionMode?: CollisionResolutionMode;
|
|
88
|
+
/** Existing document handling (if override was enabled) */
|
|
89
|
+
existingDocumentHandling?: ExistingDocumentHandling;
|
|
80
90
|
}
|
|
81
91
|
/**
|
|
82
92
|
* Dialog result types
|
|
@@ -103,4 +113,6 @@ export interface DialogManager {
|
|
|
103
113
|
closeAll(): void;
|
|
104
114
|
}
|
|
105
115
|
import type { LocaleDefinition } from './locale';
|
|
116
|
+
import type { CollisionResolutionMode, ExistingDocumentHandling } from './pluginConfig';
|
|
106
117
|
export type { LocaleDefinition } from './locale';
|
|
118
|
+
export type { CollisionResolutionMode, ExistingDocumentHandling } from './pluginConfig';
|
|
@@ -14,6 +14,20 @@ export type DocumentCreationMode = 'draft' | 'published';
|
|
|
14
14
|
* Specifies the serialization format for translation API communication
|
|
15
15
|
*/
|
|
16
16
|
export type ContentType = 'application/json' | 'application/x-protobuf';
|
|
17
|
+
/**
|
|
18
|
+
* Collision resolution mode options
|
|
19
|
+
* Determines how to handle existing translated documents when a collision is detected
|
|
20
|
+
* - 'replace': Overwrite the existing translated document with new translations
|
|
21
|
+
* - 'create': Create a new translated document alongside the existing one
|
|
22
|
+
*/
|
|
23
|
+
export type CollisionResolutionMode = 'replace' | 'create';
|
|
24
|
+
/**
|
|
25
|
+
* Existing document handling options (only applicable when CollisionResolutionMode is 'create')
|
|
26
|
+
* Determines what happens to the existing translated document when creating a new one
|
|
27
|
+
* - 'draft': Set the existing document to draft state
|
|
28
|
+
* - 'delete': Delete the existing document
|
|
29
|
+
*/
|
|
30
|
+
export type ExistingDocumentHandling = 'draft' | 'delete';
|
|
17
31
|
/**
|
|
18
32
|
* Complete plugin configuration interface
|
|
19
33
|
* Represents all configurable settings for the Easyling Translation Plugin
|
|
@@ -31,6 +45,10 @@ export interface PluginConfiguration {
|
|
|
31
45
|
responseAcceptHeader?: ContentType;
|
|
32
46
|
/** Default mode for creating translated documents (draft or published) */
|
|
33
47
|
defaultDocumentCreationMode?: DocumentCreationMode;
|
|
48
|
+
/** How to handle collisions when a translated document already exists for the same source and locale */
|
|
49
|
+
collisionResolutionMode?: CollisionResolutionMode;
|
|
50
|
+
/** How to handle existing documents when creating new translations (only applicable when mode is 'create') */
|
|
51
|
+
existingDocumentHandling?: ExistingDocumentHandling;
|
|
34
52
|
/** Array of configured locales for translation */
|
|
35
53
|
locales?: LocaleDefinition[];
|
|
36
54
|
/** Default source locale code */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easyling/sanity-connector",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A *Sanity Studio v4* plugin that enables document translation with support for single and bulk operations, using Easyling's AI translation capabilities.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|