@openfairygui/cli 0.2.0-alpha.0 → 0.2.0-alpha.2
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/bin/cli.cjs +0 -0
- package/dist/cli.mjs +21 -7
- package/package.json +47 -47
- package/src/cli.ts +74 -45
package/bin/cli.cjs
CHANGED
|
File without changes
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { createNodeBackendRuntime } from "@openfairygui/backend/node";
|
|
2
3
|
import * as fs$1 from "node:fs/promises";
|
|
3
4
|
import fs from "node:fs/promises";
|
|
4
5
|
import * as path$1 from "node:path";
|
|
@@ -10142,6 +10143,10 @@ function parseComboBoxItemXmlNode(item) {
|
|
|
10142
10143
|
icon: readXmlAttr(item, specs.icon) ?? null
|
|
10143
10144
|
};
|
|
10144
10145
|
}
|
|
10146
|
+
function getProjectBasePath(fs, projectPath) {
|
|
10147
|
+
const basePath = fs.dirname(projectPath);
|
|
10148
|
+
return basePath === "." ? "" : basePath;
|
|
10149
|
+
}
|
|
10145
10150
|
var ProjectReader = class {
|
|
10146
10151
|
_fs;
|
|
10147
10152
|
constructor(fs) {
|
|
@@ -10150,7 +10155,7 @@ var ProjectReader = class {
|
|
|
10150
10155
|
async read(projectPath) {
|
|
10151
10156
|
const fs = this._fs;
|
|
10152
10157
|
const doc = new Document();
|
|
10153
|
-
const basePath =
|
|
10158
|
+
const basePath = getProjectBasePath(fs, projectPath);
|
|
10154
10159
|
const ctx = new ReaderContext(doc, basePath);
|
|
10155
10160
|
const projDesc = getXmlNode(parseXML(await fs.readFile(projectPath)).projectDescription);
|
|
10156
10161
|
if (projDesc) {
|
|
@@ -20721,8 +20726,8 @@ function getPixelHitTestEntry(resource) {
|
|
|
20721
20726
|
/**
|
|
20722
20727
|
* Abstract I/O base class for reading and writing FairyGUI projects.
|
|
20723
20728
|
*
|
|
20724
|
-
* Platform-specific
|
|
20725
|
-
*
|
|
20729
|
+
* Platform-specific adapters provide the file system abstraction required by
|
|
20730
|
+
* the reader/writer.
|
|
20726
20731
|
*
|
|
20727
20732
|
* @category I/O
|
|
20728
20733
|
*/
|
|
@@ -20748,7 +20753,7 @@ var PlatformIO = class {
|
|
|
20748
20753
|
* Usage:
|
|
20749
20754
|
*
|
|
20750
20755
|
* ```ts
|
|
20751
|
-
* import { NodeIO } from '@openfairygui/core';
|
|
20756
|
+
* import { NodeIO } from '@openfairygui/core/node';
|
|
20752
20757
|
*
|
|
20753
20758
|
* const io = new NodeIO();
|
|
20754
20759
|
* const doc = await io.readProject('./path/to/project.fairy');
|
|
@@ -24525,6 +24530,15 @@ Options:
|
|
|
24525
24530
|
Input can be a .fairy file or a project root directory (auto-discovers .fairy file).
|
|
24526
24531
|
File extension and binary format are read from project settings.
|
|
24527
24532
|
`;
|
|
24533
|
+
const require = createRequire(import.meta.url);
|
|
24534
|
+
function readPackageVersion() {
|
|
24535
|
+
try {
|
|
24536
|
+
const pkg = require("../package.json");
|
|
24537
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
|
|
24538
|
+
} catch {}
|
|
24539
|
+
return "0.2.0-alpha.2";
|
|
24540
|
+
}
|
|
24541
|
+
const PACKAGE_VERSION = readPackageVersion();
|
|
24528
24542
|
/** Resolve input to a .fairy file path. Accepts a directory or a .fairy file. */
|
|
24529
24543
|
async function resolveFairyPath(input) {
|
|
24530
24544
|
const resolved = path.resolve(input);
|
|
@@ -24545,7 +24559,7 @@ async function main() {
|
|
|
24545
24559
|
return;
|
|
24546
24560
|
}
|
|
24547
24561
|
if (args.includes("--version") || args.includes("-v")) {
|
|
24548
|
-
console.log(
|
|
24562
|
+
console.log(PACKAGE_VERSION);
|
|
24549
24563
|
return;
|
|
24550
24564
|
}
|
|
24551
24565
|
const command = args[0];
|
|
@@ -24859,7 +24873,7 @@ async function cmdBackendCapabilities(args) {
|
|
|
24859
24873
|
console.error("Usage: ofgui backend-capabilities <project-dir>");
|
|
24860
24874
|
process.exit(1);
|
|
24861
24875
|
}
|
|
24862
|
-
const runtime =
|
|
24876
|
+
const runtime = createNodeBackendRuntime();
|
|
24863
24877
|
const opened = await runtime.openSession({ projectPath: path.resolve(args[0]) });
|
|
24864
24878
|
if (!opened.ok) {
|
|
24865
24879
|
console.error(`backend-capabilities: ${opened.error.message}`);
|
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
2
|
+
"name": "@openfairygui/cli",
|
|
3
|
+
"version": "0.2.0-alpha.2",
|
|
4
|
+
"description": "FairyGUI Headless Authoring SDK — command-line interface.",
|
|
5
|
+
"author": "OpenFairyGUI Contributors",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/OpenFairyGUI/OpenFairyGUI.git",
|
|
10
|
+
"directory": "packages/cli"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/OpenFairyGUI/OpenFairyGUI#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/OpenFairyGUI/OpenFairyGUI/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"bin": {
|
|
18
|
+
"ofgui": "bin/cli.cjs",
|
|
19
|
+
"openfairygui": "bin/cli.cjs"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist/",
|
|
23
|
+
"bin/",
|
|
24
|
+
"src/"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"fairygui",
|
|
28
|
+
"cli",
|
|
29
|
+
"ui",
|
|
30
|
+
"headless",
|
|
31
|
+
"authoring",
|
|
32
|
+
"publish",
|
|
33
|
+
"restore"
|
|
34
|
+
],
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@openfairygui/core": "0.2.0-alpha.2",
|
|
37
|
+
"@openfairygui/functions": "0.2.0-alpha.2"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@openfairygui/backend": "0.2.0-alpha.2"
|
|
41
|
+
},
|
|
42
|
+
"optionalDependencies": {
|
|
43
|
+
"sharp": ">=0.33.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsdown src/cli.ts --format esm --platform node --no-dts --external sharp --env.PACKAGE_VERSION=$npm_package_version"
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
ProjectType,
|
|
5
|
-
} from '@openfairygui/core';
|
|
1
|
+
import { createNodeBackendRuntime } from '@openfairygui/backend/node';
|
|
2
|
+
import { ProjectType } from '@openfairygui/core';
|
|
3
|
+
import { NodeIO } from '@openfairygui/core/node';
|
|
6
4
|
import {
|
|
7
5
|
inspect,
|
|
8
6
|
publish,
|
|
@@ -17,6 +15,7 @@ import {
|
|
|
17
15
|
type RestoreImageExtractor,
|
|
18
16
|
} from '@openfairygui/functions';
|
|
19
17
|
import fs from 'node:fs/promises';
|
|
18
|
+
import { createRequire } from 'node:module';
|
|
20
19
|
import path from 'node:path';
|
|
21
20
|
import { parseArgs } from 'node:util';
|
|
22
21
|
|
|
@@ -53,6 +52,22 @@ Input can be a .fairy file or a project root directory (auto-discovers .fairy fi
|
|
|
53
52
|
File extension and binary format are read from project settings.
|
|
54
53
|
`;
|
|
55
54
|
|
|
55
|
+
const require = createRequire(import.meta.url);
|
|
56
|
+
|
|
57
|
+
function readPackageVersion(): string {
|
|
58
|
+
try {
|
|
59
|
+
const pkg = require('../package.json') as { version?: unknown };
|
|
60
|
+
if (typeof pkg.version === 'string' && pkg.version.length > 0) {
|
|
61
|
+
return pkg.version;
|
|
62
|
+
}
|
|
63
|
+
} catch {
|
|
64
|
+
// Keep the CLI usable when executed from a bundled artifact missing package.json.
|
|
65
|
+
}
|
|
66
|
+
return '0.2.0-alpha.2';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const PACKAGE_VERSION = readPackageVersion();
|
|
70
|
+
|
|
56
71
|
/** Resolve input to a .fairy file path. Accepts a directory or a .fairy file. */
|
|
57
72
|
async function resolveFairyPath(input: string): Promise<string> {
|
|
58
73
|
const resolved = path.resolve(input);
|
|
@@ -70,7 +85,9 @@ async function resolveFairyPath(input: string): Promise<string> {
|
|
|
70
85
|
return path.join(resolved, fairyFiles[0]);
|
|
71
86
|
}
|
|
72
87
|
if (fairyFiles.length > 1) {
|
|
73
|
-
throw new Error(
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Multiple .fairy files found in ${resolved}: ${fairyFiles.join(', ')}. Please specify one.`,
|
|
90
|
+
);
|
|
74
91
|
}
|
|
75
92
|
throw new Error(`No .fairy file found in ${resolved}`);
|
|
76
93
|
}
|
|
@@ -87,7 +104,7 @@ async function main(): Promise<void> {
|
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
if (args.includes('--version') || args.includes('-v')) {
|
|
90
|
-
console.log(
|
|
107
|
+
console.log(PACKAGE_VERSION);
|
|
91
108
|
return;
|
|
92
109
|
}
|
|
93
110
|
|
|
@@ -195,24 +212,25 @@ async function createRestoreImageProcessors(): Promise<RestoreImageProcessors> {
|
|
|
195
212
|
});
|
|
196
213
|
if (input.rotated) image = image.rotate(90);
|
|
197
214
|
const { data, info } = await image.png().toBuffer({ resolveWithObject: true });
|
|
198
|
-
const needsOriginalCanvas =
|
|
199
|
-
input.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
215
|
+
const needsOriginalCanvas =
|
|
216
|
+
input.expectedWidth > 0 &&
|
|
217
|
+
input.expectedHeight > 0 &&
|
|
218
|
+
(input.offsetX !== 0 ||
|
|
219
|
+
input.offsetY !== 0 ||
|
|
220
|
+
info.width !== input.expectedWidth ||
|
|
221
|
+
info.height !== input.expectedHeight);
|
|
204
222
|
|
|
205
223
|
if (needsOriginalCanvas) {
|
|
206
224
|
if (
|
|
207
|
-
input.offsetX < 0
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
225
|
+
input.offsetX < 0 ||
|
|
226
|
+
input.offsetY < 0 ||
|
|
227
|
+
input.offsetX + info.width > input.expectedWidth ||
|
|
228
|
+
input.offsetY + info.height > input.expectedHeight
|
|
211
229
|
) {
|
|
212
230
|
throw new Error(
|
|
213
|
-
`restore: Cropped image does not fit original canvas for ${targetPath}: `
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
`restore: Cropped image does not fit original canvas for ${targetPath}: ` +
|
|
232
|
+
`crop ${info.width}x${info.height} at ${input.offsetX},${input.offsetY}, ` +
|
|
233
|
+
`canvas ${input.expectedWidth}x${input.expectedHeight}`,
|
|
216
234
|
);
|
|
217
235
|
}
|
|
218
236
|
const composed = await sharp({
|
|
@@ -227,26 +245,26 @@ async function createRestoreImageProcessors(): Promise<RestoreImageProcessors> {
|
|
|
227
245
|
.png()
|
|
228
246
|
.toBuffer({ resolveWithObject: true });
|
|
229
247
|
if (
|
|
230
|
-
input.expectedWidth > 0
|
|
231
|
-
|
|
232
|
-
|
|
248
|
+
input.expectedWidth > 0 &&
|
|
249
|
+
input.expectedHeight > 0 &&
|
|
250
|
+
(composed.info.width !== input.expectedWidth || composed.info.height !== input.expectedHeight)
|
|
233
251
|
) {
|
|
234
252
|
throw new Error(
|
|
235
|
-
`restore: Cropped image size mismatch for ${targetPath}: `
|
|
236
|
-
|
|
253
|
+
`restore: Cropped image size mismatch for ${targetPath}: ` +
|
|
254
|
+
`expected ${input.expectedWidth}x${input.expectedHeight}, got ${composed.info.width}x${composed.info.height}`,
|
|
237
255
|
);
|
|
238
256
|
}
|
|
239
257
|
return composed.data;
|
|
240
258
|
}
|
|
241
259
|
|
|
242
260
|
if (
|
|
243
|
-
input.expectedWidth > 0
|
|
244
|
-
|
|
245
|
-
|
|
261
|
+
input.expectedWidth > 0 &&
|
|
262
|
+
input.expectedHeight > 0 &&
|
|
263
|
+
(info.width !== input.expectedWidth || info.height !== input.expectedHeight)
|
|
246
264
|
) {
|
|
247
265
|
throw new Error(
|
|
248
|
-
`restore: Cropped image size mismatch for ${targetPath}: `
|
|
249
|
-
|
|
266
|
+
`restore: Cropped image size mismatch for ${targetPath}: ` +
|
|
267
|
+
`expected ${input.expectedWidth}x${input.expectedHeight}, got ${info.width}x${info.height}`,
|
|
250
268
|
);
|
|
251
269
|
}
|
|
252
270
|
return data;
|
|
@@ -294,7 +312,9 @@ function printReport(report: InspectReport): void {
|
|
|
294
312
|
console.log('\nPackage details:');
|
|
295
313
|
for (const pkg of report.packages) {
|
|
296
314
|
const res = pkg.resources;
|
|
297
|
-
console.log(
|
|
315
|
+
console.log(
|
|
316
|
+
` ${pkg.name} (${pkg.id}): ${res.images.count} img, ${res.sounds.count} snd, ${res.fonts.count} font, ${res.components.count} comp`,
|
|
317
|
+
);
|
|
298
318
|
}
|
|
299
319
|
}
|
|
300
320
|
|
|
@@ -347,7 +367,12 @@ async function cmdRestore(args: string[]): Promise<void> {
|
|
|
347
367
|
|
|
348
368
|
const releaseDir = path.resolve(positionals[0]);
|
|
349
369
|
const outputDir = path.resolve(values.output);
|
|
350
|
-
const pkgFilter = values.packages
|
|
370
|
+
const pkgFilter = values.packages
|
|
371
|
+
? values.packages
|
|
372
|
+
.split(',')
|
|
373
|
+
.map((s) => s.trim())
|
|
374
|
+
.filter(Boolean)
|
|
375
|
+
: undefined;
|
|
351
376
|
const projectType = parseProjectType(values['project-type']);
|
|
352
377
|
const { cropImage, extractImage } = await createRestoreImageProcessors();
|
|
353
378
|
|
|
@@ -385,7 +410,9 @@ async function cmdPublish(args: string[]): Promise<void> {
|
|
|
385
410
|
});
|
|
386
411
|
|
|
387
412
|
if (positionals.length === 0 || !values.output) {
|
|
388
|
-
console.error(
|
|
413
|
+
console.error(
|
|
414
|
+
'Usage: ofgui publish <project-dir> --output <dir> [--compressed] [--packages a,b,c] [--branch name]',
|
|
415
|
+
);
|
|
389
416
|
process.exit(1);
|
|
390
417
|
}
|
|
391
418
|
|
|
@@ -454,17 +481,19 @@ async function cmdPublish(args: string[]): Promise<void> {
|
|
|
454
481
|
},
|
|
455
482
|
};
|
|
456
483
|
|
|
457
|
-
await doc.transform(
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
484
|
+
await doc.transform(
|
|
485
|
+
publish({
|
|
486
|
+
output: outputDir,
|
|
487
|
+
compressed: resolved.compressed,
|
|
488
|
+
fileExtension: resolved.fileExtension,
|
|
489
|
+
packages: resolved.packages,
|
|
490
|
+
fs: publishFs,
|
|
491
|
+
encoder,
|
|
492
|
+
basePath: path.join(projectDir, 'assets'),
|
|
493
|
+
atlas: atlasConfig,
|
|
494
|
+
branch: values.branch,
|
|
495
|
+
}),
|
|
496
|
+
);
|
|
468
497
|
|
|
469
498
|
console.log(`\nDone! Output: ${outputDir}`);
|
|
470
499
|
}
|
|
@@ -475,7 +504,7 @@ async function cmdBackendCapabilities(args: string[]): Promise<void> {
|
|
|
475
504
|
process.exit(1);
|
|
476
505
|
}
|
|
477
506
|
|
|
478
|
-
const runtime =
|
|
507
|
+
const runtime = createNodeBackendRuntime();
|
|
479
508
|
const opened = await runtime.openSession({ projectPath: path.resolve(args[0]) });
|
|
480
509
|
if (!opened.ok) {
|
|
481
510
|
const failure = opened as Extract<typeof opened, { ok: false }>;
|