@lobehub/editor 4.8.0 → 4.8.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.
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+
3
+ const crypto = require('node:crypto');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+
7
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
8
+ const PATCH_FILE = path.join(PACKAGE_ROOT, 'patches', 'lexical@0.42.0.patch');
9
+ const SUPPORTED_VERSION = '0.42.0';
10
+
11
+ const FILE_HASHES = {
12
+ 'Lexical.dev.js': {
13
+ original: 'a7627f790028c3d6cd13b28bb0efdd8e5b48f85a1f0d62df5696e52c8b5f790d',
14
+ patched: '7c81a9785b397dc09ce0ecc9f3126d3e4903cdfd12d5c51318965ed74b0e3ccb',
15
+ },
16
+ 'Lexical.dev.mjs': {
17
+ original: '0dd55914d1f967694a77f4fa842ecbbdc9376f7832b8cca380a213e30c4153b3',
18
+ patched: '880f22f2ec2d873e1699766de39edce5123b4730009bb88bb33d7e4da98a4ad9',
19
+ },
20
+ 'Lexical.prod.js': {
21
+ original: 'dea32eb95962fa45df8251a42144f63821f7745f7dcfcc24d63f33d9cfb79a76',
22
+ patched: '9f97867340b84853cf82bbd2d60ef9f944ee61ef058daa37007b820c2780a103',
23
+ },
24
+ 'Lexical.prod.mjs': {
25
+ original: 'b4c3af0707687a7d14519233cf9d373cb62261a281be6239649a4a1b36000e4b',
26
+ patched: 'f7b2993582b2cc0573ca468373831b17971e0bb7383f5ca8785d4b93ab967c0b',
27
+ },
28
+ };
29
+
30
+ function sha256(content) {
31
+ return crypto.createHash('sha256').update(content).digest('hex');
32
+ }
33
+
34
+ function splitLines(text) {
35
+ return text.split('\n');
36
+ }
37
+
38
+ function parsePatch(patchText) {
39
+ const lines = splitLines(patchText);
40
+ const patches = new Map();
41
+ let currentFile = null;
42
+ let currentHunk = null;
43
+
44
+ for (const line of lines) {
45
+ if (line.startsWith('diff --git ')) {
46
+ currentFile = null;
47
+ currentHunk = null;
48
+ continue;
49
+ }
50
+
51
+ if (line.startsWith('+++ b/')) {
52
+ const filename = line.slice('+++ b/'.length);
53
+ currentFile = { filename, hunks: [] };
54
+ patches.set(filename, currentFile);
55
+ continue;
56
+ }
57
+
58
+ if (!currentFile) continue;
59
+
60
+ if (line.startsWith('@@ ')) {
61
+ const match = /@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(line);
62
+
63
+ if (!match) {
64
+ throw new Error(`Invalid patch hunk header: ${line}`);
65
+ }
66
+
67
+ currentHunk = {
68
+ lines: [],
69
+ oldStart: Number(match[1]),
70
+ };
71
+ currentFile.hunks.push(currentHunk);
72
+ continue;
73
+ }
74
+
75
+ if (!currentHunk) continue;
76
+
77
+ if (
78
+ line.startsWith(' ') ||
79
+ line.startsWith('+') ||
80
+ line.startsWith('-') ||
81
+ line === '\'
82
+ ) {
83
+ currentHunk.lines.push(line);
84
+ }
85
+ }
86
+
87
+ return patches;
88
+ }
89
+
90
+ function applyPatchToContent(content, filePatch) {
91
+ const source = splitLines(content);
92
+ const output = [];
93
+ let cursor = 0;
94
+
95
+ for (const hunk of filePatch.hunks) {
96
+ const targetIndex = hunk.oldStart - 1;
97
+
98
+ output.push(...source.slice(cursor, targetIndex));
99
+
100
+ let sourceIndex = targetIndex;
101
+
102
+ for (const line of hunk.lines) {
103
+ if (line === '\') continue;
104
+
105
+ const prefix = line[0];
106
+ const body = line.slice(1);
107
+
108
+ if (prefix === ' ') {
109
+ if (source[sourceIndex] !== body) {
110
+ throw new Error(`Patch context mismatch in ${filePatch.filename}`);
111
+ }
112
+
113
+ output.push(body);
114
+ sourceIndex += 1;
115
+ continue;
116
+ }
117
+
118
+ if (prefix === '-') {
119
+ if (source[sourceIndex] !== body) {
120
+ throw new Error(`Patch removal mismatch in ${filePatch.filename}`);
121
+ }
122
+
123
+ sourceIndex += 1;
124
+ continue;
125
+ }
126
+
127
+ if (prefix === '+') {
128
+ output.push(body);
129
+ continue;
130
+ }
131
+ }
132
+
133
+ cursor = sourceIndex;
134
+ }
135
+
136
+ output.push(...source.slice(cursor));
137
+
138
+ return output.join('\n');
139
+ }
140
+
141
+ function resolveLexicalRoot() {
142
+ const override = process.env.LOBE_EDITOR_LEXICAL_ROOT;
143
+
144
+ if (override) {
145
+ return path.resolve(override);
146
+ }
147
+
148
+ const lexicalEntryPath = require.resolve('lexical', {
149
+ paths: [PACKAGE_ROOT],
150
+ });
151
+
152
+ return path.dirname(lexicalEntryPath);
153
+ }
154
+
155
+ function patchLexical() {
156
+ const lexicalRoot = resolveLexicalRoot();
157
+ const lexicalPackage = JSON.parse(
158
+ fs.readFileSync(path.join(lexicalRoot, 'package.json'), 'utf8'),
159
+ );
160
+
161
+ if (lexicalPackage.version !== SUPPORTED_VERSION) {
162
+ console.warn(
163
+ `[lobe-editor] Skip Lexical patch: expected ${SUPPORTED_VERSION}, found ${lexicalPackage.version}.`,
164
+ );
165
+ return;
166
+ }
167
+
168
+ const patchText = fs.readFileSync(PATCH_FILE, 'utf8');
169
+ const patches = parsePatch(patchText);
170
+ const patchedFiles = [];
171
+
172
+ for (const [filename, hashes] of Object.entries(FILE_HASHES)) {
173
+ const targetPath = path.join(lexicalRoot, filename);
174
+
175
+ if (!fs.existsSync(targetPath)) {
176
+ throw new Error(`[lobe-editor] Missing Lexical file: ${targetPath}`);
177
+ }
178
+
179
+ const currentContent = fs.readFileSync(targetPath, 'utf8');
180
+ const currentHash = sha256(currentContent);
181
+
182
+ if (currentHash === hashes.patched) {
183
+ continue;
184
+ }
185
+
186
+ const filePatch = patches.get(filename);
187
+
188
+ if (!filePatch) {
189
+ throw new Error(`[lobe-editor] Missing patch entry for ${filename}`);
190
+ }
191
+
192
+ if (currentHash !== hashes.original) {
193
+ throw new Error(
194
+ `[lobe-editor] Refuse to patch ${filename}: unknown content hash ${currentHash}.`,
195
+ );
196
+ }
197
+
198
+ const patchedContent = applyPatchToContent(currentContent, filePatch);
199
+ const patchedHash = sha256(patchedContent);
200
+
201
+ if (patchedHash !== hashes.patched) {
202
+ throw new Error(
203
+ `[lobe-editor] Patched ${filename} hash mismatch: expected ${hashes.patched}, got ${patchedHash}.`,
204
+ );
205
+ }
206
+
207
+ fs.writeFileSync(targetPath, patchedContent);
208
+ patchedFiles.push(filename);
209
+ }
210
+
211
+ if (patchedFiles.length > 0) {
212
+ console.log(`[lobe-editor] Applied Lexical compatibility patch to ${patchedFiles.join(', ')}.`);
213
+ }
214
+ }
215
+
216
+ try {
217
+ patchLexical();
218
+ } catch (error) {
219
+ console.error(
220
+ `[lobe-editor] Failed to patch Lexical automatically: ${error instanceof Error ? error.message : String(error)}`,
221
+ );
222
+ process.exitCode = 1;
223
+ }