@lvce-editor/shared-process 0.77.10 → 0.77.12
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/package.json +3 -3
- package/src/parts/BuiltinExtensionsPath/BuiltinExtensionsPath.js +1 -1
- package/src/parts/Module/Module.js +2 -0
- package/src/parts/ModuleId/ModuleId.js +1 -0
- package/src/parts/ModuleMap/ModuleMap.js +4 -0
- package/src/parts/OAuthServer/OAuthServer.ipc.js +7 -0
- package/src/parts/OAuthServer/OAuthServer.js +276 -0
- package/src/parts/Platform/Platform.js +3 -3
- package/src/parts/PreloadUrl/PreloadUrl.js +1 -1
- package/src/parts/Workers/Workers.json +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.77.
|
|
3
|
+
"version": "0.77.12",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@lvce-editor/assert": "1.5.1",
|
|
21
|
-
"@lvce-editor/extension-host-helper-process": "0.77.
|
|
21
|
+
"@lvce-editor/extension-host-helper-process": "0.77.12",
|
|
22
22
|
"@lvce-editor/ipc": "15.0.0",
|
|
23
23
|
"@lvce-editor/json-rpc": "8.0.0",
|
|
24
24
|
"@lvce-editor/jsonc-parser": "1.5.0",
|
|
25
25
|
"@lvce-editor/pretty-error": "2.0.0",
|
|
26
|
-
"@lvce-editor/rpc-registry": "9.
|
|
26
|
+
"@lvce-editor/rpc-registry": "9.17.0",
|
|
27
27
|
"@lvce-editor/verror": "1.7.0",
|
|
28
28
|
"is-object": "^1.0.2",
|
|
29
29
|
"xdg-basedir": "^5.1.0"
|
|
@@ -2,6 +2,6 @@ import { join } from 'path';
|
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
export const getBuiltinExtensionsPath = () => {
|
|
4
4
|
const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'));
|
|
5
|
-
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '
|
|
5
|
+
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '9d77d9c', 'extensions');
|
|
6
6
|
return builtinExtensionsPath;
|
|
7
7
|
};
|
|
@@ -83,6 +83,8 @@ export const load = (moduleId) => {
|
|
|
83
83
|
return import('../Os/Os.ipc.js');
|
|
84
84
|
case ModuleId.PlatformPaths:
|
|
85
85
|
return import('../PlatformPaths/PlatformPaths.ipc.js');
|
|
86
|
+
case ModuleId.OAuthServer:
|
|
87
|
+
return import('../OAuthServer/OAuthServer.ipc.js');
|
|
86
88
|
case ModuleId.OutputChannel:
|
|
87
89
|
return import('../OutputChannel/OutputChannel.ipc.js');
|
|
88
90
|
case ModuleId.Performance:
|
|
@@ -188,6 +188,10 @@ export const getModuleId = (commandId) => {
|
|
|
188
188
|
return ModuleId.GetWindowId;
|
|
189
189
|
case 'Exec.exec':
|
|
190
190
|
return ModuleId.Exec;
|
|
191
|
+
case 'OAuthServer.create':
|
|
192
|
+
case 'OAuthServer.getCode':
|
|
193
|
+
case 'OAuthServer.dispose':
|
|
194
|
+
return ModuleId.OAuthServer;
|
|
191
195
|
case 'PlatformPaths.getDisabledExtensionsJsonPath':
|
|
192
196
|
case 'PlatformPaths.getDisabledExtensionsJsonUri':
|
|
193
197
|
return ModuleId.PlatformPaths;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import * as Assert from '../Assert/Assert.js';
|
|
3
|
+
/** @type {Record<string, {
|
|
4
|
+
server: import('node:http').Server | undefined,
|
|
5
|
+
portPromise: Promise<number> | undefined,
|
|
6
|
+
codeQueue: string[],
|
|
7
|
+
codePromise: Promise<string> | undefined,
|
|
8
|
+
resolveCode: ((value: string) => void) | undefined,
|
|
9
|
+
rejectCode: ((reason?: unknown) => void) | undefined,
|
|
10
|
+
}>} */
|
|
11
|
+
const states = Object.create(null);
|
|
12
|
+
const getOrCreateState = (id) => {
|
|
13
|
+
if (!states[id]) {
|
|
14
|
+
states[id] = {
|
|
15
|
+
server: undefined,
|
|
16
|
+
portPromise: undefined,
|
|
17
|
+
codeQueue: [],
|
|
18
|
+
codePromise: undefined,
|
|
19
|
+
resolveCode: undefined,
|
|
20
|
+
rejectCode: undefined,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return states[id];
|
|
24
|
+
};
|
|
25
|
+
const clearPendingCodePromise = (state) => {
|
|
26
|
+
state.codePromise = undefined;
|
|
27
|
+
state.resolveCode = undefined;
|
|
28
|
+
state.rejectCode = undefined;
|
|
29
|
+
};
|
|
30
|
+
const resolveCode = (state, code) => {
|
|
31
|
+
if (state.resolveCode) {
|
|
32
|
+
const { resolveCode } = state;
|
|
33
|
+
clearPendingCodePromise(state);
|
|
34
|
+
resolveCode(code);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
state.codeQueue.push(code);
|
|
38
|
+
};
|
|
39
|
+
const rejectPendingCode = (state, error) => {
|
|
40
|
+
if (!state.rejectCode) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const { rejectCode } = state;
|
|
44
|
+
clearPendingCodePromise(state);
|
|
45
|
+
rejectCode(error);
|
|
46
|
+
};
|
|
47
|
+
const getCodeFromRequest = (request) => {
|
|
48
|
+
if (!request.url) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const url = new URL(request.url, 'http://localhost');
|
|
52
|
+
const code = url.searchParams.get('code');
|
|
53
|
+
return code || undefined;
|
|
54
|
+
};
|
|
55
|
+
const getSuccessPage = () => {
|
|
56
|
+
return `<!doctype html>
|
|
57
|
+
<html lang="en">
|
|
58
|
+
<head>
|
|
59
|
+
<meta charset="utf-8">
|
|
60
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
61
|
+
<title>Authentication Complete</title>
|
|
62
|
+
<style>
|
|
63
|
+
:root {
|
|
64
|
+
color-scheme: light;
|
|
65
|
+
--background: linear-gradient(180deg, #f4f7fb 0%, #e9eef8 100%);
|
|
66
|
+
--panel: rgba(255, 255, 255, 0.92);
|
|
67
|
+
--panel-border: rgba(33, 52, 88, 0.08);
|
|
68
|
+
--text: #132238;
|
|
69
|
+
--muted: #5f6f86;
|
|
70
|
+
--accent: #1f7a5a;
|
|
71
|
+
--accent-soft: #e7f6ef;
|
|
72
|
+
--shadow: 0 24px 60px rgba(44, 65, 98, 0.16);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
* {
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
html,
|
|
80
|
+
body {
|
|
81
|
+
margin: 0;
|
|
82
|
+
min-height: 100%;
|
|
83
|
+
font-family: Inter, 'Segoe UI', sans-serif;
|
|
84
|
+
background: var(--background);
|
|
85
|
+
color: var(--text);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
body {
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
padding: 24px;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.card {
|
|
96
|
+
width: min(100%, 460px);
|
|
97
|
+
padding: 32px 28px;
|
|
98
|
+
border: 1px solid var(--panel-border);
|
|
99
|
+
border-radius: 20px;
|
|
100
|
+
background: var(--panel);
|
|
101
|
+
box-shadow: var(--shadow);
|
|
102
|
+
text-align: center;
|
|
103
|
+
backdrop-filter: blur(12px);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.badge {
|
|
107
|
+
display: inline-flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
110
|
+
width: 64px;
|
|
111
|
+
height: 64px;
|
|
112
|
+
margin-bottom: 20px;
|
|
113
|
+
border-radius: 999px;
|
|
114
|
+
background: var(--accent-soft);
|
|
115
|
+
color: var(--accent);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
h1 {
|
|
119
|
+
margin: 0;
|
|
120
|
+
font-size: 28px;
|
|
121
|
+
line-height: 1.15;
|
|
122
|
+
letter-spacing: -0.03em;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
p {
|
|
126
|
+
margin: 14px 0 0;
|
|
127
|
+
font-size: 15px;
|
|
128
|
+
line-height: 1.6;
|
|
129
|
+
color: var(--muted);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.hint {
|
|
133
|
+
margin-top: 22px;
|
|
134
|
+
padding: 12px 14px;
|
|
135
|
+
border-radius: 12px;
|
|
136
|
+
background: rgba(19, 34, 56, 0.04);
|
|
137
|
+
font-size: 14px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.button {
|
|
141
|
+
margin-top: 20px;
|
|
142
|
+
border: 0;
|
|
143
|
+
border-radius: 999px;
|
|
144
|
+
background: var(--text);
|
|
145
|
+
color: #fff;
|
|
146
|
+
padding: 10px 18px;
|
|
147
|
+
font: inherit;
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.button:hover {
|
|
152
|
+
background: #0d182a;
|
|
153
|
+
}
|
|
154
|
+
</style>
|
|
155
|
+
</head>
|
|
156
|
+
<body>
|
|
157
|
+
<main class="card">
|
|
158
|
+
<div class="badge" aria-hidden="true">
|
|
159
|
+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" role="presentation">
|
|
160
|
+
<path d="M20 7L10 17L5 12" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"></path>
|
|
161
|
+
</svg>
|
|
162
|
+
</div>
|
|
163
|
+
<h1>Authentication complete</h1>
|
|
164
|
+
<p>Your sign-in finished successfully. You can return to the app now.</p>
|
|
165
|
+
<p class="hint">This window is no longer needed and can be closed.</p>
|
|
166
|
+
<button class="button" type="button" id="close-button">Close Window</button>
|
|
167
|
+
</main>
|
|
168
|
+
<script>
|
|
169
|
+
const closeWindow = () => {
|
|
170
|
+
window.close()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
document.getElementById('close-button')?.addEventListener('click', closeWindow)
|
|
174
|
+
window.setTimeout(closeWindow, 1200)
|
|
175
|
+
</script>
|
|
176
|
+
</body>
|
|
177
|
+
</html>`;
|
|
178
|
+
};
|
|
179
|
+
const handleRequest = (id, request, response) => {
|
|
180
|
+
const state = states[id];
|
|
181
|
+
if (state) {
|
|
182
|
+
const code = getCodeFromRequest(request);
|
|
183
|
+
if (code) {
|
|
184
|
+
resolveCode(state, code);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
response.writeHead(200, {
|
|
188
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
189
|
+
'Cache-Control': 'no-store',
|
|
190
|
+
});
|
|
191
|
+
response.end(getSuccessPage());
|
|
192
|
+
};
|
|
193
|
+
const listen = (server) => {
|
|
194
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
195
|
+
const onError = (error) => {
|
|
196
|
+
server.off('listening', onListening);
|
|
197
|
+
reject(error);
|
|
198
|
+
};
|
|
199
|
+
const onListening = () => {
|
|
200
|
+
server.off('error', onError);
|
|
201
|
+
const address = server.address();
|
|
202
|
+
if (!address || typeof address === 'string') {
|
|
203
|
+
reject(new Error('failed to determine oauth server port'));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
resolve(address.port);
|
|
207
|
+
};
|
|
208
|
+
server.once('error', onError);
|
|
209
|
+
server.once('listening', onListening);
|
|
210
|
+
server.listen(0, 'localhost');
|
|
211
|
+
return promise;
|
|
212
|
+
};
|
|
213
|
+
const getOrCreateCodePromise = (state) => {
|
|
214
|
+
if (!state.codePromise) {
|
|
215
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
216
|
+
state.codePromise = promise;
|
|
217
|
+
state.resolveCode = resolve;
|
|
218
|
+
state.rejectCode = reject;
|
|
219
|
+
}
|
|
220
|
+
return state.codePromise;
|
|
221
|
+
};
|
|
222
|
+
export const create = async (id) => {
|
|
223
|
+
Assert.string(id);
|
|
224
|
+
const state = getOrCreateState(id);
|
|
225
|
+
if (state.portPromise) {
|
|
226
|
+
return state.portPromise;
|
|
227
|
+
}
|
|
228
|
+
const server = createServer((request, response) => {
|
|
229
|
+
handleRequest(id, request, response);
|
|
230
|
+
});
|
|
231
|
+
state.server = server;
|
|
232
|
+
state.portPromise = listen(server);
|
|
233
|
+
try {
|
|
234
|
+
return await state.portPromise;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
state.server = undefined;
|
|
238
|
+
state.portPromise = undefined;
|
|
239
|
+
delete states[id];
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
export const getCode = async (id) => {
|
|
244
|
+
Assert.string(id);
|
|
245
|
+
const state = states[id];
|
|
246
|
+
if (!state || !state.server) {
|
|
247
|
+
throw new Error(`oauth server ${id} not found`);
|
|
248
|
+
}
|
|
249
|
+
if (state.codeQueue.length > 0) {
|
|
250
|
+
return state.codeQueue.shift();
|
|
251
|
+
}
|
|
252
|
+
return getOrCreateCodePromise(state);
|
|
253
|
+
};
|
|
254
|
+
export const dispose = async (id) => {
|
|
255
|
+
Assert.string(id);
|
|
256
|
+
const state = getOrCreateState(id);
|
|
257
|
+
if (!state.server) {
|
|
258
|
+
delete states[id];
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const { server } = state;
|
|
262
|
+
state.server = undefined;
|
|
263
|
+
state.portPromise = undefined;
|
|
264
|
+
state.codeQueue = [];
|
|
265
|
+
rejectPendingCode(state, new Error('oauth server disposed'));
|
|
266
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
267
|
+
server.close((error) => {
|
|
268
|
+
if (error) {
|
|
269
|
+
reject(error);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
resolve(undefined);
|
|
273
|
+
});
|
|
274
|
+
await promise;
|
|
275
|
+
delete states[id];
|
|
276
|
+
};
|
|
@@ -41,9 +41,9 @@ export const getAppImageName = () => {
|
|
|
41
41
|
export const getSetupName = () => {
|
|
42
42
|
return 'Lvce-Setup';
|
|
43
43
|
};
|
|
44
|
-
export const version = '0.77.
|
|
45
|
-
export const commit = '
|
|
46
|
-
export const date = '2026-04-
|
|
44
|
+
export const version = '0.77.12';
|
|
45
|
+
export const commit = '9d77d9c';
|
|
46
|
+
export const date = '2026-04-07T13:03:24.000Z';
|
|
47
47
|
export const getVersion = () => {
|
|
48
48
|
return version;
|
|
49
49
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import * as Root from '../Root/Root.js';
|
|
3
3
|
export const getPreloadUrl = () => {
|
|
4
|
-
return join(Root.root, 'static', '
|
|
4
|
+
return join(Root.root, 'static', '9d77d9c', 'packages', 'preload', 'dist', 'index.js');
|
|
5
5
|
};
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
"hotReloadCommand": "ActivityBar.hotReload",
|
|
18
18
|
"contentSecurityPolicy": ["default-src 'none'", "sandbox allow-same-origin"]
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
"id": "authWorker",
|
|
22
|
+
"fileName": "authWorkerMain.js",
|
|
23
|
+
"defaultPath": "/packages/renderer-worker/node_modules/@lvce-editor/auth-worker/dist/authWorkerMain.js",
|
|
24
|
+
"productionPath": "/packages/auth-worker/dist/authWorkerMain.js",
|
|
25
|
+
"settingName": "develop.authWorkerPath",
|
|
26
|
+
"hotReloadCommand": "",
|
|
27
|
+
"contentSecurityPolicy": ["default-src 'none'", "connect-src *"]
|
|
28
|
+
},
|
|
20
29
|
{
|
|
21
30
|
"id": "chatDebug",
|
|
22
31
|
"fileName": "chatDebugViewWorkerMain.js",
|
|
@@ -87,7 +96,8 @@
|
|
|
87
96
|
"productionPath": "/packages/chat-view/dist/chatViewWorkerMain.js",
|
|
88
97
|
"settingName": "develop.chatViewWorkerPath",
|
|
89
98
|
"hotReloadCommand": "Chat.hotReload",
|
|
90
|
-
"contentSecurityPolicy": ["default-src 'none'", "connect-src
|
|
99
|
+
"contentSecurityPolicy": ["default-src 'none'", "connect-src *", "sandbox allow-same-origin"],
|
|
100
|
+
"comment": "TODO need to adjust csp for connect src. maybe use a separate worker for connections"
|
|
91
101
|
},
|
|
92
102
|
{
|
|
93
103
|
"id": "chatCoordinator",
|