@openfairygui/cli 0.2.0-alpha.13 → 0.2.0-alpha.14
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/cli.mjs +199 -31
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
|
@@ -1549,6 +1549,13 @@ var ImageResource = class extends ExtensibleProperty {
|
|
|
1549
1549
|
setImageData(buffer) {
|
|
1550
1550
|
return this.setRef("imageData", buffer);
|
|
1551
1551
|
}
|
|
1552
|
+
/** Primary source-file bytes for this image resource. */
|
|
1553
|
+
getSourceData() {
|
|
1554
|
+
return this.getImageData();
|
|
1555
|
+
}
|
|
1556
|
+
setSourceData(buffer) {
|
|
1557
|
+
return this.setImageData(buffer);
|
|
1558
|
+
}
|
|
1552
1559
|
getPixelHitTestData() {
|
|
1553
1560
|
const pixelWidth = this.get("pixelHitTestPixelWidth");
|
|
1554
1561
|
const scaleDenominator = this.get("pixelHitTestScaleDenominator");
|
|
@@ -1634,6 +1641,13 @@ var MiscResource = class extends ExtensibleProperty {
|
|
|
1634
1641
|
setResourceData(buffer) {
|
|
1635
1642
|
return this.setRef("resourceData", buffer);
|
|
1636
1643
|
}
|
|
1644
|
+
/** Primary source-file bytes for this miscellaneous resource. */
|
|
1645
|
+
getSourceData() {
|
|
1646
|
+
return this.getResourceData();
|
|
1647
|
+
}
|
|
1648
|
+
setSourceData(buffer) {
|
|
1649
|
+
return this.setResourceData(buffer);
|
|
1650
|
+
}
|
|
1637
1651
|
};
|
|
1638
1652
|
//#endregion
|
|
1639
1653
|
//#region ../core/src/properties/sound-resource.ts
|
|
@@ -1698,6 +1712,13 @@ var SoundResource = class extends ExtensibleProperty {
|
|
|
1698
1712
|
setSoundData(buffer) {
|
|
1699
1713
|
return this.setRef("soundData", buffer);
|
|
1700
1714
|
}
|
|
1715
|
+
/** Primary source-file bytes for this sound resource. */
|
|
1716
|
+
getSourceData() {
|
|
1717
|
+
return this.getSoundData();
|
|
1718
|
+
}
|
|
1719
|
+
setSourceData(buffer) {
|
|
1720
|
+
return this.setSoundData(buffer);
|
|
1721
|
+
}
|
|
1701
1722
|
};
|
|
1702
1723
|
//#endregion
|
|
1703
1724
|
//#region ../core/src/properties/font-resource.ts
|
|
@@ -1727,7 +1748,8 @@ var FontResource = class extends ExtensibleProperty {
|
|
|
1727
1748
|
fontSize: 0,
|
|
1728
1749
|
xAdvance: 0,
|
|
1729
1750
|
lineHeight: 0,
|
|
1730
|
-
glyphs: new RefList()
|
|
1751
|
+
glyphs: new RefList(),
|
|
1752
|
+
sourceData: null
|
|
1731
1753
|
});
|
|
1732
1754
|
}
|
|
1733
1755
|
getId() {
|
|
@@ -1835,6 +1857,13 @@ var FontResource = class extends ExtensibleProperty {
|
|
|
1835
1857
|
listGlyphs() {
|
|
1836
1858
|
return this.listRefs("glyphs");
|
|
1837
1859
|
}
|
|
1860
|
+
/** Primary source-file bytes for this font resource. */
|
|
1861
|
+
getSourceData() {
|
|
1862
|
+
return this.getRef("sourceData");
|
|
1863
|
+
}
|
|
1864
|
+
setSourceData(buffer) {
|
|
1865
|
+
return this.setRef("sourceData", buffer);
|
|
1866
|
+
}
|
|
1838
1867
|
};
|
|
1839
1868
|
//#endregion
|
|
1840
1869
|
//#region ../core/src/properties/movie-clip-resource.ts
|
|
@@ -1862,7 +1891,8 @@ var MovieClipResource = class extends ExtensibleProperty {
|
|
|
1862
1891
|
swing: false,
|
|
1863
1892
|
repeatDelay: 0,
|
|
1864
1893
|
smoothing: true,
|
|
1865
|
-
frames: new RefList()
|
|
1894
|
+
frames: new RefList(),
|
|
1895
|
+
sourceData: null
|
|
1866
1896
|
});
|
|
1867
1897
|
}
|
|
1868
1898
|
getId() {
|
|
@@ -1958,6 +1988,13 @@ var MovieClipResource = class extends ExtensibleProperty {
|
|
|
1958
1988
|
listFrames() {
|
|
1959
1989
|
return this.listRefs("frames");
|
|
1960
1990
|
}
|
|
1991
|
+
/** Primary source-file bytes for this movie-clip resource. */
|
|
1992
|
+
getSourceData() {
|
|
1993
|
+
return this.getRef("sourceData");
|
|
1994
|
+
}
|
|
1995
|
+
setSourceData(buffer) {
|
|
1996
|
+
return this.setRef("sourceData", buffer);
|
|
1997
|
+
}
|
|
1961
1998
|
};
|
|
1962
1999
|
//#endregion
|
|
1963
2000
|
//#region ../core/src/properties/skeleton-resource-base.ts
|
|
@@ -1979,7 +2016,8 @@ var SkeletonResourceBase = class extends ExtensibleProperty {
|
|
|
1979
2016
|
requireIds: [],
|
|
1980
2017
|
atlasNames: [],
|
|
1981
2018
|
anchorX: 0,
|
|
1982
|
-
anchorY: 0
|
|
2019
|
+
anchorY: 0,
|
|
2020
|
+
sourceData: null
|
|
1983
2021
|
});
|
|
1984
2022
|
}
|
|
1985
2023
|
getId() {
|
|
@@ -2058,6 +2096,13 @@ var SkeletonResourceBase = class extends ExtensibleProperty {
|
|
|
2058
2096
|
this.setAnchorX(x);
|
|
2059
2097
|
return this.setAnchorY(y);
|
|
2060
2098
|
}
|
|
2099
|
+
/** Primary source-file bytes for this skeleton resource. */
|
|
2100
|
+
getSourceData() {
|
|
2101
|
+
return this.getRef("sourceData");
|
|
2102
|
+
}
|
|
2103
|
+
setSourceData(buffer) {
|
|
2104
|
+
return this.setRef("sourceData", buffer);
|
|
2105
|
+
}
|
|
2061
2106
|
};
|
|
2062
2107
|
//#endregion
|
|
2063
2108
|
//#region ../core/src/properties/spine-resource.ts
|
|
@@ -10375,7 +10420,7 @@ var ProjectReader = class {
|
|
|
10375
10420
|
constructor(fs) {
|
|
10376
10421
|
this._fs = fs;
|
|
10377
10422
|
}
|
|
10378
|
-
async read(projectPath) {
|
|
10423
|
+
async read(projectPath, options = {}) {
|
|
10379
10424
|
const fs = this._fs;
|
|
10380
10425
|
const doc = new Document();
|
|
10381
10426
|
const basePath = getProjectBasePath(fs, projectPath);
|
|
@@ -10399,9 +10444,9 @@ var ProjectReader = class {
|
|
|
10399
10444
|
for (const dirName of packageDirs) {
|
|
10400
10445
|
const pkgXmlPath = fs.join(assetsPath, dirName, "package.xml");
|
|
10401
10446
|
if (!await fs.exists(pkgXmlPath)) continue;
|
|
10402
|
-
await this._readPackage(ctx, dirName, pkgXmlPath);
|
|
10447
|
+
await this._readPackage(ctx, dirName, pkgXmlPath, "", options);
|
|
10403
10448
|
}
|
|
10404
|
-
const branchNames = await this._readPackageBranches(ctx);
|
|
10449
|
+
const branchNames = await this._readPackageBranches(ctx, options);
|
|
10405
10450
|
if (branchNames.length > 0) doc.getRoot().setBranches(branchNames);
|
|
10406
10451
|
for (const [_key, resource] of ctx.resourceMap) {
|
|
10407
10452
|
if (resource.propertyType !== "Component") continue;
|
|
@@ -10417,7 +10462,7 @@ var ProjectReader = class {
|
|
|
10417
10462
|
}
|
|
10418
10463
|
return doc;
|
|
10419
10464
|
}
|
|
10420
|
-
async _readPackageBranches(ctx) {
|
|
10465
|
+
async _readPackageBranches(ctx, options) {
|
|
10421
10466
|
const fs = this._fs;
|
|
10422
10467
|
let dirNames = [];
|
|
10423
10468
|
try {
|
|
@@ -10437,7 +10482,7 @@ var ProjectReader = class {
|
|
|
10437
10482
|
for (const dirName of packageDirs) {
|
|
10438
10483
|
const pkgXmlPath = fs.join(branchAssetsPath, dirName, "package_branch.xml");
|
|
10439
10484
|
if (!await fs.exists(pkgXmlPath)) continue;
|
|
10440
|
-
await this._readPackage(ctx, dirName, pkgXmlPath, branchName);
|
|
10485
|
+
await this._readPackage(ctx, dirName, pkgXmlPath, branchName, options);
|
|
10441
10486
|
}
|
|
10442
10487
|
}
|
|
10443
10488
|
return branchNames;
|
|
@@ -10475,7 +10520,7 @@ var ProjectReader = class {
|
|
|
10475
10520
|
} catch {}
|
|
10476
10521
|
ctx.document.getRoot().setSettings(ctx.settings);
|
|
10477
10522
|
}
|
|
10478
|
-
async _readPackage(ctx, dirName, pkgXmlPath, branchName = "") {
|
|
10523
|
+
async _readPackage(ctx, dirName, pkgXmlPath, branchName = "", options = {}) {
|
|
10479
10524
|
const fs = this._fs;
|
|
10480
10525
|
const content = await fs.readFile(pkgXmlPath);
|
|
10481
10526
|
const xml = parseXML(content);
|
|
@@ -10513,6 +10558,7 @@ var ProjectReader = class {
|
|
|
10513
10558
|
if (resource) createdResources.push(resource);
|
|
10514
10559
|
}
|
|
10515
10560
|
await this._hydratePackageImageSizes(createdResources, packageDir);
|
|
10561
|
+
if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx.document, createdResources, packageDir);
|
|
10516
10562
|
return;
|
|
10517
10563
|
}
|
|
10518
10564
|
for (const tagName of [
|
|
@@ -10521,6 +10567,8 @@ var ProjectReader = class {
|
|
|
10521
10567
|
"font",
|
|
10522
10568
|
"sound",
|
|
10523
10569
|
"movieclip",
|
|
10570
|
+
"spine",
|
|
10571
|
+
"dragonbones",
|
|
10524
10572
|
"swf",
|
|
10525
10573
|
"misc",
|
|
10526
10574
|
"atlas"
|
|
@@ -10534,6 +10582,7 @@ var ProjectReader = class {
|
|
|
10534
10582
|
}
|
|
10535
10583
|
}
|
|
10536
10584
|
await this._hydratePackageImageSizes(createdResources, packageDir);
|
|
10585
|
+
if (options.hydrateResourceBytes) await this._hydratePackageResourceBytes(ctx.document, createdResources, packageDir);
|
|
10537
10586
|
}
|
|
10538
10587
|
async _hydratePackageImageSizes(resources, packageDir) {
|
|
10539
10588
|
const fs = this._fs;
|
|
@@ -10544,7 +10593,9 @@ var ProjectReader = class {
|
|
|
10544
10593
|
const fileName = image.getFileName?.() ?? "";
|
|
10545
10594
|
if (!fileName) continue;
|
|
10546
10595
|
const resourcePath = image.getPath?.() ?? "/";
|
|
10547
|
-
const
|
|
10596
|
+
const sourcePath = this._packageRelativeSourcePath(resourcePath, fileName);
|
|
10597
|
+
if (!sourcePath) continue;
|
|
10598
|
+
const filePath = fs.join(packageDir, sourcePath.replace(/^\/+/, ""));
|
|
10548
10599
|
if (!await fs.exists(filePath)) continue;
|
|
10549
10600
|
try {
|
|
10550
10601
|
const size = readImageSize(await fs.readFileRaw(filePath));
|
|
@@ -10554,6 +10605,44 @@ var ProjectReader = class {
|
|
|
10554
10605
|
} catch {}
|
|
10555
10606
|
}
|
|
10556
10607
|
}
|
|
10608
|
+
async _hydratePackageResourceBytes(doc, resources, packageDir) {
|
|
10609
|
+
const fs = this._fs;
|
|
10610
|
+
for (const resource of resources) {
|
|
10611
|
+
const fileName = this._primaryResourceFileName(resource);
|
|
10612
|
+
if (!fileName) continue;
|
|
10613
|
+
const resourcePath = resource.getPath?.() ?? "/";
|
|
10614
|
+
const sourcePath = this._packageRelativeSourcePath(resourcePath, fileName);
|
|
10615
|
+
if (!sourcePath) continue;
|
|
10616
|
+
const filePath = fs.join(packageDir, sourcePath.replace(/^\/+/, ""));
|
|
10617
|
+
if (!await fs.exists(filePath)) continue;
|
|
10618
|
+
try {
|
|
10619
|
+
const data = new Uint8Array(await fs.readFileRaw(filePath));
|
|
10620
|
+
const buffer = doc.createBuffer().setURI(sourcePath).setData(data);
|
|
10621
|
+
this._asSourceDataResource(resource).setSourceData(buffer);
|
|
10622
|
+
} catch {}
|
|
10623
|
+
}
|
|
10624
|
+
}
|
|
10625
|
+
_primaryResourceFileName(resource) {
|
|
10626
|
+
switch (resource.propertyType) {
|
|
10627
|
+
case "ImageResource":
|
|
10628
|
+
case "FontResource":
|
|
10629
|
+
case "MovieClipResource": return resource.getFileName();
|
|
10630
|
+
case "SoundResource":
|
|
10631
|
+
case "MiscResource":
|
|
10632
|
+
case "SpineResource":
|
|
10633
|
+
case "DragonBonesResource": return resource.getFile();
|
|
10634
|
+
default: return "";
|
|
10635
|
+
}
|
|
10636
|
+
}
|
|
10637
|
+
_packageRelativeSourcePath(resourcePath, fileName) {
|
|
10638
|
+
if (!fileName || /[\\/:]/.test(fileName) || fileName === "." || fileName === "..") return null;
|
|
10639
|
+
const segments = resourcePath.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
10640
|
+
if (segments.some((segment) => segment === "." || segment === ".." || segment.includes(":"))) return null;
|
|
10641
|
+
return `/${[...segments, fileName].join("/")}`;
|
|
10642
|
+
}
|
|
10643
|
+
_asSourceDataResource(resource) {
|
|
10644
|
+
return resource;
|
|
10645
|
+
}
|
|
10557
10646
|
_createResourceFromXML(ctx, pkg, tagName, attrs, packageDir, branchName = "") {
|
|
10558
10647
|
const doc = ctx.document;
|
|
10559
10648
|
const fs = this._fs;
|
|
@@ -12425,21 +12514,18 @@ function assertDisplayListVariantAllowed(propertyType, tagName, childName) {
|
|
|
12425
12514
|
const variantName = getDisplayListVariantName(propertyType, tagName);
|
|
12426
12515
|
if (!DISPLAY_LIST_ALLOWED_VARIANTS.has(variantName)) throw new Error(`displayList variant "${variantName}" derived from propertyType "${propertyType}" is not declared in protocol for child "${childName}"`);
|
|
12427
12516
|
}
|
|
12428
|
-
/**
|
|
12429
|
-
* Writes a {@link Document} to disk as a FairyGUI project
|
|
12430
|
-
* (.fairy file + settings JSON + assets directory with package.xml and component XML files).
|
|
12431
|
-
*
|
|
12432
|
-
* @category I/O
|
|
12433
|
-
*/
|
|
12434
12517
|
var ProjectWriter = class {
|
|
12435
12518
|
_fs;
|
|
12436
12519
|
constructor(fs) {
|
|
12437
12520
|
this._fs = fs;
|
|
12438
12521
|
}
|
|
12439
|
-
async write(doc, projectPath) {
|
|
12522
|
+
async write(doc, projectPath, options = {}) {
|
|
12440
12523
|
const fs = this._fs;
|
|
12441
12524
|
const root = doc.getRoot();
|
|
12442
12525
|
const basePath = fs.dirname(projectPath);
|
|
12526
|
+
const currentSourceFilePaths = /* @__PURE__ */ new Set();
|
|
12527
|
+
const staleSourceFilePaths = new Set((options.staleSourceFiles ?? []).map((source) => this._projectSourceFilePath(basePath, source)));
|
|
12528
|
+
for (const pkg of root.listPackages()) this._assertPackageOutputTargets(pkg);
|
|
12443
12529
|
const fairyXml = `<?xml version="1.0" encoding="utf-8"?>\n<projectDescription id="${root.getProjectId()}" type="${this._projectTypeName(root.getProjectType())}" version="${root.getVersion() || "3.0"}"/>\n`;
|
|
12444
12530
|
await fs.writeFile(projectPath, fairyXml);
|
|
12445
12531
|
const settings = root.getSettings?.() ?? {};
|
|
@@ -12452,10 +12538,12 @@ var ProjectWriter = class {
|
|
|
12452
12538
|
})) if (settings[key]) await fs.writeFile(fs.join(settingsPath, fileName), JSON.stringify(settings[key], null, " "));
|
|
12453
12539
|
const assetsPath = fs.join(basePath, "assets");
|
|
12454
12540
|
await fs.mkdir(assetsPath);
|
|
12455
|
-
for (const pkg of root.listPackages()) await this._writePackage(doc, pkg, assetsPath);
|
|
12541
|
+
for (const pkg of root.listPackages()) await this._writePackage(doc, pkg, assetsPath, currentSourceFilePaths);
|
|
12542
|
+
await this._removeStaleSourceFiles(currentSourceFilePaths, staleSourceFilePaths);
|
|
12456
12543
|
}
|
|
12457
|
-
async _writePackage(_doc, pkg, assetsPath) {
|
|
12544
|
+
async _writePackage(_doc, pkg, assetsPath, currentSourceFilePaths) {
|
|
12458
12545
|
const fs = this._fs;
|
|
12546
|
+
this._assertSafePathSegment(pkg.getName(), "package name");
|
|
12459
12547
|
const pkgDir = fs.join(assetsPath, pkg.getName());
|
|
12460
12548
|
await fs.mkdir(pkgDir);
|
|
12461
12549
|
const basePath = fs.dirname(assetsPath);
|
|
@@ -12496,14 +12584,94 @@ var ProjectWriter = class {
|
|
|
12496
12584
|
if (publishAtlases.length > 0) publishAttrs.atlas = publishAtlases;
|
|
12497
12585
|
await fs.writeFile(fs.join(pkgDir, "package.xml"), this._renderPackageDescriptionXml(packageDescriptionAttrs, mainResources, publishAttrs));
|
|
12498
12586
|
for (const comp of mainResources.filter((resource) => resource.propertyType === "Component")) await this._writeComponent(comp, pkgDir);
|
|
12587
|
+
await this._writeResourceSourceFiles(mainResources, pkgDir, currentSourceFilePaths);
|
|
12499
12588
|
for (const [branchName, branchResources] of resourcesByBranch) {
|
|
12500
12589
|
if (!branchName) continue;
|
|
12590
|
+
this._assertSafePathSegment(branchName, "branch name");
|
|
12501
12591
|
const branchPkgDir = fs.join(basePath, `assets_${branchName}`, pkg.getName());
|
|
12502
12592
|
await fs.mkdir(branchPkgDir);
|
|
12503
12593
|
await fs.writeFile(fs.join(branchPkgDir, "package_branch.xml"), this._renderBranchDescriptionXml(branchResources));
|
|
12504
12594
|
for (const comp of branchResources.filter((resource) => resource.propertyType === "Component")) await this._writeComponent(comp, branchPkgDir);
|
|
12595
|
+
await this._writeResourceSourceFiles(branchResources, branchPkgDir, currentSourceFilePaths);
|
|
12596
|
+
}
|
|
12597
|
+
}
|
|
12598
|
+
async _writeResourceSourceFiles(resources, packageDir, currentSourceFilePaths) {
|
|
12599
|
+
const fs = this._fs;
|
|
12600
|
+
for (const resource of resources) {
|
|
12601
|
+
if (resource.propertyType === "Component") continue;
|
|
12602
|
+
const fileName = this._resourceFileName(resource);
|
|
12603
|
+
if (!fileName) continue;
|
|
12604
|
+
const relativePath = this._resourceSourceRelativePath(resource, fileName);
|
|
12605
|
+
const targetPath = fs.join(packageDir, relativePath);
|
|
12606
|
+
currentSourceFilePaths.add(targetPath);
|
|
12607
|
+
const sourceData = resource.getSourceData?.();
|
|
12608
|
+
if (!sourceData) continue;
|
|
12609
|
+
const data = sourceData.getData();
|
|
12610
|
+
if (!data) continue;
|
|
12611
|
+
await fs.mkdir(fs.dirname(targetPath));
|
|
12612
|
+
await fs.writeFileRaw(targetPath, new Uint8Array(data));
|
|
12613
|
+
}
|
|
12614
|
+
}
|
|
12615
|
+
async _removeStaleSourceFiles(currentSourceFilePaths, staleSourceFilePaths) {
|
|
12616
|
+
const fs = this._fs;
|
|
12617
|
+
const candidates = [...staleSourceFilePaths].filter((filePath) => !currentSourceFilePaths.has(filePath));
|
|
12618
|
+
if (candidates.length === 0) return;
|
|
12619
|
+
if (!fs.unlink) throw new Error("Project source cleanup requires a FileSystem.unlink() implementation.");
|
|
12620
|
+
for (const filePath of candidates) {
|
|
12621
|
+
if (!await fs.exists(filePath)) continue;
|
|
12622
|
+
await fs.unlink(filePath);
|
|
12505
12623
|
}
|
|
12506
12624
|
}
|
|
12625
|
+
_assertPackageOutputTargets(pkg) {
|
|
12626
|
+
this._assertSafePathSegment(pkg.getName(), "package name");
|
|
12627
|
+
const resourcesByBranch = /* @__PURE__ */ new Map();
|
|
12628
|
+
for (const resource of pkg.listResources()) {
|
|
12629
|
+
const branchName = resource.getBranch?.() ?? "";
|
|
12630
|
+
const bucket = resourcesByBranch.get(branchName) ?? [];
|
|
12631
|
+
bucket.push(resource);
|
|
12632
|
+
resourcesByBranch.set(branchName, bucket);
|
|
12633
|
+
}
|
|
12634
|
+
for (const [branchName, resources] of resourcesByBranch) {
|
|
12635
|
+
if (branchName) this._assertSafePathSegment(branchName, "branch name");
|
|
12636
|
+
const targets = new Map([[branchName ? "package_branch.xml" : "package.xml", "package descriptor"]]);
|
|
12637
|
+
for (const resource of resources) {
|
|
12638
|
+
const target = resource.propertyType === "Component" ? this._componentSourceRelativePath(resource) : this._resourceSourceRelativePath(resource, this._resourceFileName(resource));
|
|
12639
|
+
if (!target) continue;
|
|
12640
|
+
const previous = targets.get(target);
|
|
12641
|
+
if (previous) throw new Error(`Package "${pkg.getName()}" output "${target}" conflicts with ${previous}.`);
|
|
12642
|
+
targets.set(target, `resource "${resource.getId?.() ?? resource.getName()}"`);
|
|
12643
|
+
}
|
|
12644
|
+
}
|
|
12645
|
+
}
|
|
12646
|
+
_projectSourceFilePath(basePath, source) {
|
|
12647
|
+
this._assertSafePathSegment(source.packageName, "stale source package name");
|
|
12648
|
+
if (source.branch) this._assertSafePathSegment(source.branch, "stale source branch name");
|
|
12649
|
+
this._assertSafePathSegment(source.fileName, "stale source file name");
|
|
12650
|
+
const relativePath = this._normalizeSourceRelativePath([source.path, source.fileName].filter(Boolean).join("/"));
|
|
12651
|
+
const assetRoot = source.branch ? `assets_${source.branch}` : "assets";
|
|
12652
|
+
return this._fs.join(basePath, assetRoot, source.packageName, relativePath);
|
|
12653
|
+
}
|
|
12654
|
+
_resourceSourceRelativePath(resource, fileName) {
|
|
12655
|
+
if (!fileName) return "";
|
|
12656
|
+
this._assertSafePathSegment(fileName, "resource file name");
|
|
12657
|
+
const normalizedPath = (resource.getPath?.() ?? "/").replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
|
|
12658
|
+
return this._normalizeSourceRelativePath([normalizedPath, fileName].filter(Boolean).join("/"));
|
|
12659
|
+
}
|
|
12660
|
+
_componentSourceRelativePath(component) {
|
|
12661
|
+
const typedComponent = component;
|
|
12662
|
+
const name = component.getName();
|
|
12663
|
+
this._assertSafePathSegment(name, "component name");
|
|
12664
|
+
const componentPath = typedComponent.getPath?.() ?? "/";
|
|
12665
|
+
return this._normalizeSourceRelativePath([componentPath, `${name}.xml`].filter(Boolean).join("/"));
|
|
12666
|
+
}
|
|
12667
|
+
_assertSafePathSegment(value, label) {
|
|
12668
|
+
if (!value || value === "." || value === ".." || /[\\/:]/.test(value)) throw new Error(`Invalid ${label} "${value}".`);
|
|
12669
|
+
}
|
|
12670
|
+
_normalizeSourceRelativePath(value) {
|
|
12671
|
+
const segments = value.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
12672
|
+
if (segments.some((segment) => segment === "." || segment === ".." || segment.includes(":"))) throw new Error(`Invalid project source path "${value}".`);
|
|
12673
|
+
return segments.join("/");
|
|
12674
|
+
}
|
|
12507
12675
|
_renderPackageDescriptionXml(packageDescriptionAttrs, resources, publishAttrs) {
|
|
12508
12676
|
const publishNodeAttrs = Object.fromEntries(Object.entries(publishAttrs).filter(([key]) => key !== "atlas"));
|
|
12509
12677
|
const lines = [
|
|
@@ -12647,11 +12815,8 @@ var ProjectWriter = class {
|
|
|
12647
12815
|
async _writeComponent(comp, pkgDir) {
|
|
12648
12816
|
const fs = this._fs;
|
|
12649
12817
|
const typedComp = comp;
|
|
12650
|
-
const
|
|
12651
|
-
|
|
12652
|
-
const subDir = path.replace(/^\//, "").replace(/\/$/, "");
|
|
12653
|
-
const fileDir = subDir ? fs.join(pkgDir, subDir) : pkgDir;
|
|
12654
|
-
if (subDir) await fs.mkdir(fileDir);
|
|
12818
|
+
const targetPath = fs.join(pkgDir, this._componentSourceRelativePath(comp));
|
|
12819
|
+
await fs.mkdir(fs.dirname(targetPath));
|
|
12655
12820
|
const compAttrs = {};
|
|
12656
12821
|
const [w, h] = [typedComp.getWidth?.() ?? 0, typedComp.getHeight?.() ?? 0];
|
|
12657
12822
|
if (w || h) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.size, `${w},${h}`);
|
|
@@ -12793,7 +12958,7 @@ var ProjectWriter = class {
|
|
|
12793
12958
|
},
|
|
12794
12959
|
component: compNode
|
|
12795
12960
|
};
|
|
12796
|
-
await fs.writeFile(
|
|
12961
|
+
await fs.writeFile(targetPath, builder.build(xmlObj));
|
|
12797
12962
|
}
|
|
12798
12963
|
_serializeController(ctrl) {
|
|
12799
12964
|
const pagesStr = ctrl.listPages().map((p) => `${p.getId()},${p.getName()}`).join(",");
|
|
@@ -21033,11 +21198,11 @@ function getPixelHitTestEntry(resource) {
|
|
|
21033
21198
|
* @category I/O
|
|
21034
21199
|
*/
|
|
21035
21200
|
var PlatformIO = class {
|
|
21036
|
-
async readProject(projectPath) {
|
|
21037
|
-
return new ProjectReader(this.createFileSystem()).read(projectPath);
|
|
21201
|
+
async readProject(projectPath, options) {
|
|
21202
|
+
return new ProjectReader(this.createFileSystem()).read(projectPath, options);
|
|
21038
21203
|
}
|
|
21039
|
-
async writeProject(doc, projectPath) {
|
|
21040
|
-
return new ProjectWriter(this.createFileSystem()).write(doc, projectPath);
|
|
21204
|
+
async writeProject(doc, projectPath, options) {
|
|
21205
|
+
return new ProjectWriter(this.createFileSystem()).write(doc, projectPath, options);
|
|
21041
21206
|
}
|
|
21042
21207
|
async readBinary(filePath) {
|
|
21043
21208
|
return new BinaryReader(this.createFileSystem()).read(filePath);
|
|
@@ -25216,6 +25381,9 @@ var NodeIO = class extends PlatformIO {
|
|
|
25216
25381
|
return false;
|
|
25217
25382
|
}
|
|
25218
25383
|
},
|
|
25384
|
+
async unlink(filePath) {
|
|
25385
|
+
await fs$1.unlink(filePath);
|
|
25386
|
+
},
|
|
25219
25387
|
join(...paths) {
|
|
25220
25388
|
return path$1.join(...paths);
|
|
25221
25389
|
},
|
|
@@ -25358,8 +25526,8 @@ async function resolveNodeAssetsPath(document, assetsPath) {
|
|
|
25358
25526
|
}
|
|
25359
25527
|
async function loadSharpBackend() {
|
|
25360
25528
|
try {
|
|
25361
|
-
const
|
|
25362
|
-
return
|
|
25529
|
+
const loaded = await importNative("sharp");
|
|
25530
|
+
return loaded.default ?? loaded;
|
|
25363
25531
|
} catch {
|
|
25364
25532
|
return;
|
|
25365
25533
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfairygui/cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.14",
|
|
4
4
|
"description": "FairyGUI Headless Authoring SDK — command-line interface.",
|
|
5
5
|
"author": "OpenFairyGUI Contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"restore"
|
|
34
34
|
],
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@openfairygui/
|
|
37
|
-
"@openfairygui/
|
|
36
|
+
"@openfairygui/functions": "0.2.0-alpha.14",
|
|
37
|
+
"@openfairygui/core": "0.2.0-alpha.14"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"commander": "^14.0.2",
|
|
41
41
|
"jiti": "^2.7.0",
|
|
42
|
-
"@openfairygui/backend": "0.2.0-alpha.
|
|
42
|
+
"@openfairygui/backend": "0.2.0-alpha.14"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
45
|
"sharp": ">=0.33.0"
|