pixifact-cli 0.19.0 → 0.20.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.
- package/README.md +3 -1
- package/editor/assets/browserAll-BK5tSRnW.js +1 -0
- package/editor/assets/capture-C7kX9ccS.js +1 -0
- package/editor/assets/{captureCompilerScenePreview-BYHGr0JS.js → captureCompilerScenePreview-D1crYVOi.js} +84 -84
- package/editor/assets/editor-DXfKrkh3.js +5 -0
- package/editor/assets/init-ChKChotc.js +1 -0
- package/editor/assets/webworkerAll-DUy-YwIE.js +1 -0
- package/editor/capture.html +2 -2
- package/editor/index.html +2 -2
- package/package.json +2 -2
- package/src/editorServer.ts +66 -10
- package/src/viteTarget.ts +2 -1
- package/editor/assets/browserAll-D2RthxQz.js +0 -1
- package/editor/assets/capture-BGSCjpR1.js +0 -1
- package/editor/assets/editor-DdhHqfDl.js +0 -5
- package/editor/assets/init-BOfNyIRQ.js +0 -1
- package/editor/assets/webworkerAll-C87VP9vG.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as e,d as t,l as n,u as r}from"./captureCompilerScenePreview-D1crYVOi.js";e.add(n,t),e.add(r);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./captureCompilerScenePreview-D1crYVOi.js";import"./init-ChKChotc.js";
|
package/editor/capture.html
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<title>Pixifact Scene Capture</title>
|
|
6
|
-
<script type="module" crossorigin src="/assets/capture-
|
|
7
|
-
<link rel="modulepreload" crossorigin href="/assets/captureCompilerScenePreview-
|
|
6
|
+
<script type="module" crossorigin src="/assets/capture-C7kX9ccS.js"></script>
|
|
7
|
+
<link rel="modulepreload" crossorigin href="/assets/captureCompilerScenePreview-D1crYVOi.js">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
</body>
|
package/editor/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Pixifact Editor</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/editor-
|
|
8
|
-
<link rel="modulepreload" crossorigin href="/assets/captureCompilerScenePreview-
|
|
7
|
+
<script type="module" crossorigin src="/assets/editor-DXfKrkh3.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="/assets/captureCompilerScenePreview-D1crYVOi.js">
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/editor-DmOIioK0.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixifact-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "Pixifact Scene 自动化 CLI。",
|
|
5
5
|
"packageManager": "bun@1.3.13",
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"start": "bun src/pixifact-cli.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"pixifact": "^0.
|
|
35
|
+
"pixifact": "^0.20.1",
|
|
36
36
|
"playwright": "1.58.2",
|
|
37
37
|
"vite": "^8.0.10"
|
|
38
38
|
}
|
package/src/editorServer.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash, randomBytes } from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import childProcess from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
5
6
|
import {
|
|
6
7
|
normalizeSceneAssetId,
|
|
7
8
|
pairedSceneScriptPath,
|
|
@@ -138,8 +139,8 @@ function listProjectFiles(projectRoot: string) {
|
|
|
138
139
|
return files.sort((left, right) => left.path.localeCompare(right.path));
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
function readProjectSceneBindings(projectRoot: string) {
|
|
142
|
-
const scenePaths =
|
|
142
|
+
function readProjectSceneBindings(projectRoot: string, files: readonly EditorProjectFile[]) {
|
|
143
|
+
const scenePaths = files
|
|
143
144
|
.filter((file) => file.kind === 'scene')
|
|
144
145
|
.map((file) => normalizeSceneAssetId(file.path));
|
|
145
146
|
return extractSceneScriptInterfaces(scenePaths.map((scene) => {
|
|
@@ -249,12 +250,27 @@ function serveStaticFile(staticRoot: string, pathname: string) {
|
|
|
249
250
|
export function createEditorProjectService(options: EditorProjectServiceOptions) {
|
|
250
251
|
const projectRoot = fs.realpathSync(options.projectRoot);
|
|
251
252
|
const staticRoot = fs.realpathSync(options.staticRoot);
|
|
253
|
+
let files: EditorProjectFile[] | undefined;
|
|
254
|
+
let bindings: ReturnType<typeof readProjectSceneBindings> | undefined;
|
|
255
|
+
|
|
256
|
+
function invalidate(changedPath: string) {
|
|
257
|
+
const known = files?.some((file) => file.path === changedPath);
|
|
258
|
+
const entry = fs.statSync(path.resolve(projectRoot, changedPath), { throwIfNoEntry: false });
|
|
259
|
+
if (!known || !entry?.isFile()) files = undefined;
|
|
260
|
+
if (!known || !entry?.isFile() || scriptExtensions.has(path.extname(changedPath))) {
|
|
261
|
+
bindings = undefined;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
252
264
|
|
|
253
265
|
async function fetch(request: Request): Promise<Response> {
|
|
254
266
|
try {
|
|
255
267
|
const url = new URL(request.url);
|
|
256
268
|
if (url.pathname === '/api/project' && request.method === 'GET') {
|
|
257
|
-
|
|
269
|
+
if (url.searchParams.get('refresh') === '1') {
|
|
270
|
+
files = undefined;
|
|
271
|
+
bindings = undefined;
|
|
272
|
+
}
|
|
273
|
+
files ??= listProjectFiles(projectRoot);
|
|
258
274
|
return jsonResponse({
|
|
259
275
|
name: path.basename(projectRoot),
|
|
260
276
|
root: projectRoot,
|
|
@@ -283,7 +299,9 @@ export function createEditorProjectService(options: EditorProjectServiceOptions)
|
|
|
283
299
|
return jsonResponse({ path: scenePath, source, version: sceneVersion(source) });
|
|
284
300
|
}
|
|
285
301
|
if (url.pathname === '/api/scene-bindings' && request.method === 'GET') {
|
|
286
|
-
|
|
302
|
+
files ??= listProjectFiles(projectRoot);
|
|
303
|
+
bindings ??= readProjectSceneBindings(projectRoot, files);
|
|
304
|
+
return jsonResponse(bindings);
|
|
287
305
|
}
|
|
288
306
|
if (url.pathname === '/api/scene' && request.method === 'PUT') {
|
|
289
307
|
const scenePath = requestPath(url);
|
|
@@ -300,6 +318,7 @@ export function createEditorProjectService(options: EditorProjectServiceOptions)
|
|
|
300
318
|
throw new EditorRequestError(409, 'Scene file version changed.');
|
|
301
319
|
}
|
|
302
320
|
fs.writeFileSync(filePath, body.source, 'utf8');
|
|
321
|
+
invalidate(scenePath);
|
|
303
322
|
return jsonResponse({ path: scenePath, version: sceneVersion(body.source) });
|
|
304
323
|
}
|
|
305
324
|
if (url.pathname === '/api/file' && request.method === 'GET') {
|
|
@@ -308,9 +327,33 @@ export function createEditorProjectService(options: EditorProjectServiceOptions)
|
|
|
308
327
|
return new Response(fs.readFileSync(filePath), {
|
|
309
328
|
headers: {
|
|
310
329
|
'content-type': contentTypes[extension] ?? 'application/octet-stream',
|
|
330
|
+
'cache-control': 'no-store',
|
|
311
331
|
},
|
|
312
332
|
});
|
|
313
333
|
}
|
|
334
|
+
if (url.pathname === '/api/open-file' && request.method === 'POST') {
|
|
335
|
+
if (request.headers.get('origin') !== url.origin) {
|
|
336
|
+
throw new EditorRequestError(403, '资源打开请求必须来自当前 Editor。');
|
|
337
|
+
}
|
|
338
|
+
let filePath: string;
|
|
339
|
+
try {
|
|
340
|
+
filePath = resolveInsideRoot(projectRoot, requestPath(url));
|
|
341
|
+
if (!fs.statSync(filePath).isFile()) {
|
|
342
|
+
throw new EditorRequestError(400, '只能使用系统默认程序打开项目内的文件。');
|
|
343
|
+
}
|
|
344
|
+
} catch (error) {
|
|
345
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
346
|
+
throw new EditorRequestError(404, '资源文件不存在,请刷新资产列表。');
|
|
347
|
+
}
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
await openSystemFile(filePath);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
throw new EditorRequestError(500, `无法使用系统默认程序打开文件:${error instanceof Error ? error.message : String(error)}`);
|
|
354
|
+
}
|
|
355
|
+
return jsonResponse({ ok: true });
|
|
356
|
+
}
|
|
314
357
|
if (url.pathname.startsWith('/api/')) {
|
|
315
358
|
return jsonResponse({ ok: false, error: 'Editor API route was not found.' }, 404);
|
|
316
359
|
}
|
|
@@ -323,32 +366,42 @@ export function createEditorProjectService(options: EditorProjectServiceOptions)
|
|
|
323
366
|
}
|
|
324
367
|
}
|
|
325
368
|
|
|
326
|
-
return { fetch };
|
|
369
|
+
return { fetch, invalidate };
|
|
327
370
|
}
|
|
328
371
|
|
|
329
372
|
function defaultEditorStaticRoot() {
|
|
330
373
|
return path.resolve(import.meta.dir, '..', 'editor');
|
|
331
374
|
}
|
|
332
375
|
|
|
376
|
+
async function openSystemFile(filePath: string) {
|
|
377
|
+
const command = process.platform === 'win32'
|
|
378
|
+
? [
|
|
379
|
+
'powershell.exe', '-NoProfile', '-NonInteractive', '-Command',
|
|
380
|
+
`Start-Process -FilePath ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('${Buffer.from(filePath).toString('base64')}'))) -ErrorAction Stop`,
|
|
381
|
+
]
|
|
382
|
+
: [process.platform === 'darwin' ? 'open' : 'xdg-open', filePath];
|
|
383
|
+
await promisify(childProcess.execFile)(command[0], command.slice(1), { windowsHide: true });
|
|
384
|
+
}
|
|
385
|
+
|
|
333
386
|
function openBrowser(url: string) {
|
|
334
387
|
const command = process.platform === 'darwin'
|
|
335
388
|
? ['open', url]
|
|
336
389
|
: process.platform === 'win32'
|
|
337
390
|
? ['cmd', '/c', 'start', '', url]
|
|
338
391
|
: ['xdg-open', url];
|
|
339
|
-
spawn(command[0], command.slice(1), { detached: true, stdio: 'ignore' }).unref();
|
|
392
|
+
childProcess.spawn(command[0], command.slice(1), { detached: true, stdio: 'ignore' }).unref();
|
|
340
393
|
}
|
|
341
394
|
|
|
342
395
|
export function watchEditorProject(projectRoot: string, onProjectFileChanged: (path: string) => void) {
|
|
343
396
|
const changedPathTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
|
344
|
-
const watcher = fs.watch(projectRoot, { recursive: true }, (
|
|
397
|
+
const watcher = fs.watch(projectRoot, { recursive: true }, (event, fileName) => {
|
|
345
398
|
if (!fileName) return;
|
|
346
399
|
const filePath = String(fileName);
|
|
347
400
|
if (filePath.split(/[\\/]/).some((segment) => ignoredDirectories.has(segment))) {
|
|
348
401
|
return;
|
|
349
402
|
}
|
|
350
403
|
const absolutePath = path.resolve(projectRoot, filePath);
|
|
351
|
-
if (fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
|
|
404
|
+
if (event !== 'rename' && fs.existsSync(absolutePath) && fs.statSync(absolutePath).isDirectory()) {
|
|
352
405
|
return;
|
|
353
406
|
}
|
|
354
407
|
const changedPath = filePath.split(path.sep).join('/');
|
|
@@ -414,7 +467,10 @@ export async function startEditorServer(options: StartEditorOptions): Promise<Ed
|
|
|
414
467
|
},
|
|
415
468
|
},
|
|
416
469
|
});
|
|
417
|
-
const stopWatcher = watchEditorProject(projectRoot,
|
|
470
|
+
const stopWatcher = watchEditorProject(projectRoot, (changedPath) => {
|
|
471
|
+
service.invalidate(changedPath);
|
|
472
|
+
hostSession.notifyProjectFileChanged(changedPath);
|
|
473
|
+
});
|
|
418
474
|
const url = `http://${server.hostname}:${server.port}`;
|
|
419
475
|
const descriptor: EditorSessionDescriptor = {
|
|
420
476
|
protocolVersion: editorSessionProtocolVersion,
|
package/src/viteTarget.ts
CHANGED
|
@@ -71,6 +71,7 @@ export async function validatePixifactTarget(projectRootInput: string, mode: str
|
|
|
71
71
|
'pixifact-platform',
|
|
72
72
|
'pixifact-assets',
|
|
73
73
|
'pixifact-resources',
|
|
74
|
+
'pixifact-code-packages',
|
|
74
75
|
'pixifact-minigame',
|
|
75
76
|
]) {
|
|
76
77
|
if (!pluginNames.has(name)) {
|
|
@@ -232,7 +233,7 @@ async function collectDiagnostics(
|
|
|
232
233
|
if (gameJson[property] !== undefined) {
|
|
233
234
|
diagnostics.push({
|
|
234
235
|
asset: `platforms/${platform}/game.json`,
|
|
235
|
-
message: `${property} 由 Pixifact
|
|
236
|
+
message: `${property} 由 Pixifact 根据资源包和代码分包生成,不能在源模板中重复声明。`,
|
|
236
237
|
});
|
|
237
238
|
}
|
|
238
239
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as e,d as t,f as n,g as r,h as i,p as a,y as o}from"./captureCompilerScenePreview-BYHGr0JS.js";import"./init-BOfNyIRQ.js";o.add(r),o.mixin(e,i),o.add(a),o.add(n),o.mixin(e,t);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as e,C as t,T as n,m as r,n as i,r as a,t as o,x as s}from"./captureCompilerScenePreview-BYHGr0JS.js";window.capturePixifactScene=async c=>{let[l,u]=await Promise.all([t(),n(c)]),d=await i({document:{template:e(u.source),sceneInterfaces:{}},projectTree:s(l),scenePath:c}),f=new r,p=!1;try{return await f.init({width:d.width,height:d.height,backgroundAlpha:0,antialias:!0,autoStart:!1,resolution:1}),p=!0,f.stage.addChild(d.root),{scenePath:u.path,revision:u.version,width:d.width,height:d.height,dataUrl:await o(f,d)}}finally{p&&(f.stage.removeChild(d.root),f.destroy({removeView:!0},{children:!1})),a(d)}};
|