@qwanyx/ai-editor 1.3.13 → 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/dist/components/PageEditor.d.ts +10 -0
- package/dist/components/PageEditor.d.ts.map +1 -0
- package/dist/components/PageEditor.js +294 -0
- package/dist/components/PageViewer.d.ts +8 -0
- package/dist/components/PageViewer.d.ts.map +1 -0
- package/dist/components/PageViewer.js +38 -0
- package/dist/components/RichTextEditor.d.ts +5 -1
- package/dist/components/RichTextEditor.d.ts.map +1 -1
- package/dist/components/RichTextEditor.js +11 -2
- package/dist/components/RichTextViewer.d.ts +3 -1
- package/dist/components/RichTextViewer.d.ts.map +1 -1
- package/dist/components/RichTextViewer.js +7 -2
- package/dist/components/Section.d.ts +10 -0
- package/dist/components/Section.d.ts.map +1 -0
- package/dist/components/Section.js +117 -0
- package/dist/components/SmartEditor.d.ts +58 -0
- package/dist/components/SmartEditor.d.ts.map +1 -0
- package/dist/components/SmartEditor.js +123 -0
- package/dist/context/PageContext.d.ts +35 -0
- package/dist/context/PageContext.d.ts.map +1 -0
- package/dist/context/PageContext.js +277 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -1
- package/dist/layouts/OgilvyLayout.d.ts +5 -0
- package/dist/layouts/OgilvyLayout.d.ts.map +1 -0
- package/dist/layouts/OgilvyLayout.js +301 -0
- package/dist/layouts/RichTextLayout.d.ts +7 -0
- package/dist/layouts/RichTextLayout.d.ts.map +1 -0
- package/dist/layouts/RichTextLayout.js +47 -0
- package/dist/layouts/index.d.ts +30 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +71 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/page.d.ts +151 -0
- package/dist/types/page.d.ts.map +1 -0
- package/dist/types/page.js +54 -0
- package/dist/utils/format.d.ts +71 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +190 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/package.json +1 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Types pour le système de Pages et Sections
|
|
4
|
+
* Extension de qwanyx-ai-editor
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DEFAULT_DROP_CAP = exports.VIDEO_PRESETS = exports.PRINT_PRESETS = void 0;
|
|
8
|
+
exports.generateId = generateId;
|
|
9
|
+
exports.createSection = createSection;
|
|
10
|
+
exports.createEmptyPage = createEmptyPage;
|
|
11
|
+
// Presets communs
|
|
12
|
+
exports.PRINT_PRESETS = {
|
|
13
|
+
A4: { width: 210, height: 297, unit: 'mm', name: 'A4' },
|
|
14
|
+
A3: { width: 297, height: 420, unit: 'mm', name: 'A3' },
|
|
15
|
+
Letter: { width: 8.5, height: 11, unit: 'in', name: 'Letter' },
|
|
16
|
+
Legal: { width: 8.5, height: 14, unit: 'in', name: 'Legal' },
|
|
17
|
+
};
|
|
18
|
+
exports.VIDEO_PRESETS = {
|
|
19
|
+
'Full HD': { width: 1920, height: 1080, name: 'Full HD (16:9)' },
|
|
20
|
+
'4K': { width: 3840, height: 2160, name: '4K UHD (16:9)' },
|
|
21
|
+
'HD': { width: 1280, height: 720, name: 'HD (16:9)' },
|
|
22
|
+
'Square': { width: 1080, height: 1080, name: 'Carré (1:1)' },
|
|
23
|
+
'Portrait': { width: 1080, height: 1920, name: 'Portrait (9:16)' },
|
|
24
|
+
'4:3': { width: 1024, height: 768, name: 'Standard (4:3)' },
|
|
25
|
+
};
|
|
26
|
+
exports.DEFAULT_DROP_CAP = {
|
|
27
|
+
enabled: true,
|
|
28
|
+
type: 'letter',
|
|
29
|
+
fontSize: 3,
|
|
30
|
+
lineHeight: 3,
|
|
31
|
+
};
|
|
32
|
+
// ============================================
|
|
33
|
+
// Helpers
|
|
34
|
+
// ============================================
|
|
35
|
+
function generateId() {
|
|
36
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
37
|
+
}
|
|
38
|
+
function createSection(layoutType, content, animation) {
|
|
39
|
+
return {
|
|
40
|
+
id: generateId(),
|
|
41
|
+
layoutType,
|
|
42
|
+
content,
|
|
43
|
+
animation,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function createEmptyPage(format = 'web') {
|
|
47
|
+
return {
|
|
48
|
+
id: generateId(),
|
|
49
|
+
format,
|
|
50
|
+
sections: [],
|
|
51
|
+
createdAt: new Date().toISOString(),
|
|
52
|
+
updatedAt: new Date().toISOString(),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilitaires pour la détection et conversion de formats
|
|
3
|
+
*
|
|
4
|
+
* Gère la rétrocompatibilité entre:
|
|
5
|
+
* - Ancien format: JSON Lexical brut (string)
|
|
6
|
+
* - Nouveau format: PageDocument avec sections
|
|
7
|
+
*/
|
|
8
|
+
import { PageDocument } from '../types/page';
|
|
9
|
+
export type ContentFormat = 'lexical' | 'page-document' | 'empty' | 'unknown';
|
|
10
|
+
export interface FormatDetectionResult {
|
|
11
|
+
format: ContentFormat;
|
|
12
|
+
data: PageDocument | string | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Détecte le format du contenu
|
|
16
|
+
*
|
|
17
|
+
* @param content - Le contenu à analyser (string JSON ou objet)
|
|
18
|
+
* @returns Le type de format détecté et les données parsées
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectFormat(content: string | PageDocument | null | undefined): FormatDetectionResult;
|
|
21
|
+
/**
|
|
22
|
+
* Vérifie si un objet est un PageDocument valide
|
|
23
|
+
*/
|
|
24
|
+
export declare function isPageDocument(obj: unknown): obj is PageDocument;
|
|
25
|
+
/**
|
|
26
|
+
* Vérifie si un objet est un état Lexical valide
|
|
27
|
+
*/
|
|
28
|
+
export declare function isLexicalState(obj: unknown): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Convertit du contenu Lexical brut en PageDocument
|
|
31
|
+
* Crée une page avec une seule section "text-only" contenant l'éditeur
|
|
32
|
+
*
|
|
33
|
+
* @param lexicalContent - Le JSON Lexical (string ou objet)
|
|
34
|
+
* @param format - Le format de page souhaité (défaut: 'web')
|
|
35
|
+
* @returns Un PageDocument avec le contenu Lexical dans une section
|
|
36
|
+
*/
|
|
37
|
+
export declare function lexicalToPageDocument(lexicalContent: string | object, format?: 'web' | 'print' | 'video'): PageDocument;
|
|
38
|
+
/**
|
|
39
|
+
* Extrait le contenu Lexical d'un PageDocument
|
|
40
|
+
* Si le document a une seule section "text-only", retourne le Lexical brut
|
|
41
|
+
* Sinon, retourne null (le document utilise le nouveau format)
|
|
42
|
+
*
|
|
43
|
+
* @param document - Le PageDocument à analyser
|
|
44
|
+
* @returns Le JSON Lexical si applicable, sinon null
|
|
45
|
+
*/
|
|
46
|
+
export declare function pageDocumentToLexical(document: PageDocument): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Convertit automatiquement le contenu vers PageDocument si nécessaire
|
|
49
|
+
*
|
|
50
|
+
* @param content - Le contenu (peut être Lexical ou PageDocument)
|
|
51
|
+
* @returns Un PageDocument valide
|
|
52
|
+
*/
|
|
53
|
+
export declare function ensurePageDocument(content: string | PageDocument | null | undefined): PageDocument;
|
|
54
|
+
/**
|
|
55
|
+
* Vérifie si un PageDocument est "simple" (une seule section text-only)
|
|
56
|
+
* Utile pour décider comment sauvegarder
|
|
57
|
+
*/
|
|
58
|
+
export declare function isSimpleDocument(document: PageDocument): boolean;
|
|
59
|
+
export interface SaveOptions {
|
|
60
|
+
/** Si true, sauvegarde en Lexical brut si possible (rétrocompatibilité) */
|
|
61
|
+
preferLegacyFormat?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Prépare le contenu pour la sauvegarde
|
|
65
|
+
*
|
|
66
|
+
* @param document - Le PageDocument à sauvegarder
|
|
67
|
+
* @param options - Options de sauvegarde
|
|
68
|
+
* @returns String JSON à sauvegarder
|
|
69
|
+
*/
|
|
70
|
+
export declare function prepareForSave(document: PageDocument, options?: SaveOptions): string;
|
|
71
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EAIb,MAAM,eAAe,CAAA;AAOtB,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,eAAe,GAAG,OAAO,GAAG,SAAS,CAAA;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAAA;CACnC;AAMD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,CA4CrG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,CAahE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAYpD;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,GAAG,MAAM,EAC/B,MAAM,GAAE,KAAK,GAAG,OAAO,GAAG,OAAe,GACxC,YAAY,CAoBd;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAQ3E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,CAelG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAKhE;AAMD,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAaxF"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utilitaires pour la détection et conversion de formats
|
|
4
|
+
*
|
|
5
|
+
* Gère la rétrocompatibilité entre:
|
|
6
|
+
* - Ancien format: JSON Lexical brut (string)
|
|
7
|
+
* - Nouveau format: PageDocument avec sections
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.detectFormat = detectFormat;
|
|
11
|
+
exports.isPageDocument = isPageDocument;
|
|
12
|
+
exports.isLexicalState = isLexicalState;
|
|
13
|
+
exports.lexicalToPageDocument = lexicalToPageDocument;
|
|
14
|
+
exports.pageDocumentToLexical = pageDocumentToLexical;
|
|
15
|
+
exports.ensurePageDocument = ensurePageDocument;
|
|
16
|
+
exports.isSimpleDocument = isSimpleDocument;
|
|
17
|
+
exports.prepareForSave = prepareForSave;
|
|
18
|
+
const page_1 = require("../types/page");
|
|
19
|
+
// ============================================
|
|
20
|
+
// Détection du format
|
|
21
|
+
// ============================================
|
|
22
|
+
/**
|
|
23
|
+
* Détecte le format du contenu
|
|
24
|
+
*
|
|
25
|
+
* @param content - Le contenu à analyser (string JSON ou objet)
|
|
26
|
+
* @returns Le type de format détecté et les données parsées
|
|
27
|
+
*/
|
|
28
|
+
function detectFormat(content) {
|
|
29
|
+
// Cas vide
|
|
30
|
+
if (!content) {
|
|
31
|
+
return { format: 'empty', data: null };
|
|
32
|
+
}
|
|
33
|
+
// Si c'est déjà un objet
|
|
34
|
+
if (typeof content === 'object') {
|
|
35
|
+
if (isPageDocument(content)) {
|
|
36
|
+
return { format: 'page-document', data: content };
|
|
37
|
+
}
|
|
38
|
+
// Objet mais pas un PageDocument - probablement du Lexical parsé
|
|
39
|
+
return { format: 'lexical', data: JSON.stringify(content) };
|
|
40
|
+
}
|
|
41
|
+
// C'est une string - essayer de parser
|
|
42
|
+
if (typeof content === 'string') {
|
|
43
|
+
// String vide
|
|
44
|
+
if (!content.trim()) {
|
|
45
|
+
return { format: 'empty', data: null };
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(content);
|
|
49
|
+
// Vérifier si c'est un PageDocument
|
|
50
|
+
if (isPageDocument(parsed)) {
|
|
51
|
+
return { format: 'page-document', data: parsed };
|
|
52
|
+
}
|
|
53
|
+
// Vérifier si c'est du Lexical (a un "root" avec "children")
|
|
54
|
+
if (isLexicalState(parsed)) {
|
|
55
|
+
return { format: 'lexical', data: content };
|
|
56
|
+
}
|
|
57
|
+
// JSON valide mais format inconnu
|
|
58
|
+
return { format: 'unknown', data: content };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Pas du JSON - texte brut, on le traite comme vide ou texte simple
|
|
62
|
+
return { format: 'unknown', data: content };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { format: 'unknown', data: null };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Vérifie si un objet est un PageDocument valide
|
|
69
|
+
*/
|
|
70
|
+
function isPageDocument(obj) {
|
|
71
|
+
if (!obj || typeof obj !== 'object')
|
|
72
|
+
return false;
|
|
73
|
+
const doc = obj;
|
|
74
|
+
// Doit avoir un id et un format
|
|
75
|
+
if (typeof doc.id !== 'string')
|
|
76
|
+
return false;
|
|
77
|
+
if (!['web', 'print', 'video'].includes(doc.format))
|
|
78
|
+
return false;
|
|
79
|
+
// Doit avoir un array sections
|
|
80
|
+
if (!Array.isArray(doc.sections))
|
|
81
|
+
return false;
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Vérifie si un objet est un état Lexical valide
|
|
86
|
+
*/
|
|
87
|
+
function isLexicalState(obj) {
|
|
88
|
+
if (!obj || typeof obj !== 'object')
|
|
89
|
+
return false;
|
|
90
|
+
const state = obj;
|
|
91
|
+
// Lexical state a toujours un "root" avec des "children"
|
|
92
|
+
if (!state.root || typeof state.root !== 'object')
|
|
93
|
+
return false;
|
|
94
|
+
const root = state.root;
|
|
95
|
+
if (!Array.isArray(root.children))
|
|
96
|
+
return false;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// ============================================
|
|
100
|
+
// Conversion de format
|
|
101
|
+
// ============================================
|
|
102
|
+
/**
|
|
103
|
+
* Convertit du contenu Lexical brut en PageDocument
|
|
104
|
+
* Crée une page avec une seule section "text-only" contenant l'éditeur
|
|
105
|
+
*
|
|
106
|
+
* @param lexicalContent - Le JSON Lexical (string ou objet)
|
|
107
|
+
* @param format - Le format de page souhaité (défaut: 'web')
|
|
108
|
+
* @returns Un PageDocument avec le contenu Lexical dans une section
|
|
109
|
+
*/
|
|
110
|
+
function lexicalToPageDocument(lexicalContent, format = 'web') {
|
|
111
|
+
const lexicalString = typeof lexicalContent === 'string'
|
|
112
|
+
? lexicalContent
|
|
113
|
+
: JSON.stringify(lexicalContent);
|
|
114
|
+
const section = {
|
|
115
|
+
id: (0, page_1.generateId)(),
|
|
116
|
+
layoutType: 'text-only',
|
|
117
|
+
content: {
|
|
118
|
+
lexicalState: lexicalString,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
id: (0, page_1.generateId)(),
|
|
123
|
+
format,
|
|
124
|
+
sections: [section],
|
|
125
|
+
createdAt: new Date().toISOString(),
|
|
126
|
+
updatedAt: new Date().toISOString(),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Extrait le contenu Lexical d'un PageDocument
|
|
131
|
+
* Si le document a une seule section "text-only", retourne le Lexical brut
|
|
132
|
+
* Sinon, retourne null (le document utilise le nouveau format)
|
|
133
|
+
*
|
|
134
|
+
* @param document - Le PageDocument à analyser
|
|
135
|
+
* @returns Le JSON Lexical si applicable, sinon null
|
|
136
|
+
*/
|
|
137
|
+
function pageDocumentToLexical(document) {
|
|
138
|
+
// Si le document a exactement une section de type "text-only"
|
|
139
|
+
if (document.sections.length === 1 && document.sections[0].layoutType === 'text-only') {
|
|
140
|
+
const content = document.sections[0].content;
|
|
141
|
+
return content.lexicalState || null;
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Convertit automatiquement le contenu vers PageDocument si nécessaire
|
|
147
|
+
*
|
|
148
|
+
* @param content - Le contenu (peut être Lexical ou PageDocument)
|
|
149
|
+
* @returns Un PageDocument valide
|
|
150
|
+
*/
|
|
151
|
+
function ensurePageDocument(content) {
|
|
152
|
+
const detection = detectFormat(content);
|
|
153
|
+
switch (detection.format) {
|
|
154
|
+
case 'page-document':
|
|
155
|
+
return detection.data;
|
|
156
|
+
case 'lexical':
|
|
157
|
+
return lexicalToPageDocument(detection.data);
|
|
158
|
+
case 'empty':
|
|
159
|
+
case 'unknown':
|
|
160
|
+
default:
|
|
161
|
+
return (0, page_1.createEmptyPage)('web');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Vérifie si un PageDocument est "simple" (une seule section text-only)
|
|
166
|
+
* Utile pour décider comment sauvegarder
|
|
167
|
+
*/
|
|
168
|
+
function isSimpleDocument(document) {
|
|
169
|
+
return (document.sections.length === 1 &&
|
|
170
|
+
document.sections[0].layoutType === 'text-only');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Prépare le contenu pour la sauvegarde
|
|
174
|
+
*
|
|
175
|
+
* @param document - Le PageDocument à sauvegarder
|
|
176
|
+
* @param options - Options de sauvegarde
|
|
177
|
+
* @returns String JSON à sauvegarder
|
|
178
|
+
*/
|
|
179
|
+
function prepareForSave(document, options = {}) {
|
|
180
|
+
const { preferLegacyFormat = false } = options;
|
|
181
|
+
// Si on préfère le format legacy et que c'est possible
|
|
182
|
+
if (preferLegacyFormat && isSimpleDocument(document)) {
|
|
183
|
+
const lexical = pageDocumentToLexical(document);
|
|
184
|
+
if (lexical) {
|
|
185
|
+
return lexical;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Sinon, sauvegarder comme PageDocument
|
|
189
|
+
return JSON.stringify(document);
|
|
190
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,UAAU,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* Re-export all utilities
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./format"), exports);
|