@openfairygui/cli 0.2.0-alpha.1 → 0.2.0-alpha.11
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 +1435 -725
- package/package.json +49 -47
- package/src/cli.ts +28 -497
- package/src/commands/backend-capabilities.ts +37 -0
- package/src/commands/inspect.ts +44 -0
- package/src/commands/publish.ts +108 -0
- package/src/commands/restore.ts +209 -0
- package/src/utils/package-version.ts +22 -0
- package/src/utils/project-input.ts +26 -0
- package/src/utils/project-type.ts +31 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,178 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { Command } from "commander";
|
|
1
3
|
import { createNodeBackendRuntime } from "@openfairygui/backend/node";
|
|
2
|
-
import * as fs$1 from "node:fs/promises";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { createJiti } from "jiti";
|
|
7
|
+
import * as fs$1 from "node:fs/promises";
|
|
8
|
+
import fs from "node:fs/promises";
|
|
9
|
+
//#region src/commands/backend-capabilities.ts
|
|
10
|
+
function registerBackendCapabilitiesCommand(program) {
|
|
11
|
+
program.command("backend-capabilities").description("Open a backend session, print runtime capabilities, then close it").argument("<project-dir>", "Project root directory").action(async (projectDir) => {
|
|
12
|
+
const runtime = createNodeBackendRuntime();
|
|
13
|
+
const opened = await runtime.openSession({ projectPath: path.resolve(projectDir) });
|
|
14
|
+
if (!opened.ok) throw new Error(`backend-capabilities: ${opened.error.message}`);
|
|
15
|
+
const capabilities = runtime.getCapabilities();
|
|
16
|
+
if (!capabilities.ok) {
|
|
17
|
+
await runtime.closeSession({ sessionId: opened.data.sessionId });
|
|
18
|
+
throw new Error("backend-capabilities: failed to read capabilities");
|
|
19
|
+
}
|
|
20
|
+
console.log(`Session: ${opened.data.sessionId}`);
|
|
21
|
+
console.log(`Project: ${opened.data.canonicalProjectPath}`);
|
|
22
|
+
console.log(`Revision: ${opened.data.revision}`);
|
|
23
|
+
console.log(`Runtime owner: ${capabilities.data.runtimeOwner}`);
|
|
24
|
+
console.log(`Transaction owner: ${capabilities.data.transactionKernelOwner}`);
|
|
25
|
+
console.log(`App seam owner: ${capabilities.data.appSeamOwner}`);
|
|
26
|
+
const closed = await runtime.closeSession({ sessionId: opened.data.sessionId });
|
|
27
|
+
if (!closed.ok) throw new Error(`backend-capabilities: ${closed.error.message}`);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region ../functions/src/inspect.ts
|
|
32
|
+
function mapResource(resource) {
|
|
33
|
+
return {
|
|
34
|
+
name: resource.getName(),
|
|
35
|
+
id: resource.getId(),
|
|
36
|
+
path: resource.getPath?.() ?? "/",
|
|
37
|
+
exported: resource.getExported?.() ?? false
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function mapComponentDetail(component, totals) {
|
|
41
|
+
const children = component.listChildren();
|
|
42
|
+
const controllers = component.listControllers();
|
|
43
|
+
const transitions = component.listTransitions();
|
|
44
|
+
totals.displayObjects += children.length;
|
|
45
|
+
totals.controllers += controllers.length;
|
|
46
|
+
totals.transitions += transitions.length;
|
|
47
|
+
for (const child of children) totals.gears += child.listGears().length;
|
|
48
|
+
return {
|
|
49
|
+
name: component.getName(),
|
|
50
|
+
id: component.getId(),
|
|
51
|
+
childCount: children.length,
|
|
52
|
+
controllerCount: controllers.length,
|
|
53
|
+
transitionCount: transitions.length
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Generates a detailed report of the project contents.
|
|
58
|
+
*
|
|
59
|
+
* Unlike other transforms, `inspect()` does NOT modify the document —
|
|
60
|
+
* it returns a structured report.
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* const report = inspect(doc);
|
|
64
|
+
* console.log(`${report.totals.packages} packages, ${report.totals.components} components`);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
function inspect(doc) {
|
|
68
|
+
const root = doc.getRoot();
|
|
69
|
+
const totals = {
|
|
70
|
+
packages: 0,
|
|
71
|
+
images: 0,
|
|
72
|
+
sounds: 0,
|
|
73
|
+
fonts: 0,
|
|
74
|
+
movieClips: 0,
|
|
75
|
+
components: 0,
|
|
76
|
+
displayObjects: 0,
|
|
77
|
+
gears: 0,
|
|
78
|
+
controllers: 0,
|
|
79
|
+
transitions: 0
|
|
80
|
+
};
|
|
81
|
+
const packages = root.listPackages().map((pkg) => {
|
|
82
|
+
totals.packages++;
|
|
83
|
+
const resources = pkg.listResources();
|
|
84
|
+
const images = resources.filter((r) => r.propertyType === "ImageResource");
|
|
85
|
+
const sounds = resources.filter((r) => r.propertyType === "SoundResource");
|
|
86
|
+
const fonts = resources.filter((r) => r.propertyType === "FontResource");
|
|
87
|
+
const movieClips = resources.filter((r) => r.propertyType === "MovieClipResource");
|
|
88
|
+
const components = pkg.listComponents();
|
|
89
|
+
totals.images += images.length;
|
|
90
|
+
totals.sounds += sounds.length;
|
|
91
|
+
totals.fonts += fonts.length;
|
|
92
|
+
totals.movieClips += movieClips.length;
|
|
93
|
+
totals.components += components.length;
|
|
94
|
+
const componentDetails = components.map((component) => mapComponentDetail(component, totals));
|
|
95
|
+
return {
|
|
96
|
+
name: pkg.getName(),
|
|
97
|
+
id: pkg.getId(),
|
|
98
|
+
publishName: pkg.getPublishName() || pkg.getName(),
|
|
99
|
+
resources: {
|
|
100
|
+
images: {
|
|
101
|
+
count: images.length,
|
|
102
|
+
details: images.map(mapResource)
|
|
103
|
+
},
|
|
104
|
+
sounds: {
|
|
105
|
+
count: sounds.length,
|
|
106
|
+
details: sounds.map(mapResource)
|
|
107
|
+
},
|
|
108
|
+
fonts: {
|
|
109
|
+
count: fonts.length,
|
|
110
|
+
details: fonts.map(mapResource)
|
|
111
|
+
},
|
|
112
|
+
movieClips: {
|
|
113
|
+
count: movieClips.length,
|
|
114
|
+
details: movieClips.map(mapResource)
|
|
115
|
+
},
|
|
116
|
+
components: {
|
|
117
|
+
count: components.length,
|
|
118
|
+
details: components.map(mapResource)
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
componentDetails
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
projectId: root.getProjectId(),
|
|
126
|
+
projectType: root.getProjectType(),
|
|
127
|
+
version: root.getVersion(),
|
|
128
|
+
packages,
|
|
129
|
+
totals
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region ../functions/src/utils.ts
|
|
134
|
+
/**
|
|
135
|
+
* Wraps a transform function, assigning it a name for the transform stack.
|
|
136
|
+
*/
|
|
137
|
+
function createTransform(name, fn) {
|
|
138
|
+
Object.defineProperty(fn, "name", { value: name });
|
|
139
|
+
return fn;
|
|
140
|
+
}
|
|
141
|
+
function parseTextureSetMode(value) {
|
|
142
|
+
const raw = value?.trim() ?? "";
|
|
143
|
+
if (!raw) return {
|
|
144
|
+
kind: "auto",
|
|
145
|
+
raw: ""
|
|
146
|
+
};
|
|
147
|
+
if (raw === "alone") return {
|
|
148
|
+
kind: "standalone",
|
|
149
|
+
raw,
|
|
150
|
+
sizeMode: "default"
|
|
151
|
+
};
|
|
152
|
+
if (raw === "alone_npot") return {
|
|
153
|
+
kind: "standalone",
|
|
154
|
+
raw,
|
|
155
|
+
sizeMode: "npot"
|
|
156
|
+
};
|
|
157
|
+
if (raw === "alone_mof") return {
|
|
158
|
+
kind: "standalone",
|
|
159
|
+
raw,
|
|
160
|
+
sizeMode: "multipleOf4"
|
|
161
|
+
};
|
|
162
|
+
if (/^\d+$/.test(raw)) {
|
|
163
|
+
const pageIndex = Number(raw);
|
|
164
|
+
if (pageIndex >= 0 && pageIndex <= 10) return {
|
|
165
|
+
kind: "page",
|
|
166
|
+
raw,
|
|
167
|
+
pageIndex
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
kind: "auto",
|
|
172
|
+
raw
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
7
176
|
//#region ../../node_modules/.pnpm/property-graph@4.1.0/node_modules/property-graph/dist/index.mjs
|
|
8
177
|
var EventDispatcher = class {
|
|
9
178
|
_listeners = {};
|
|
@@ -1262,6 +1431,7 @@ var ImageResource = class extends ExtensibleProperty {
|
|
|
1262
1431
|
path: "",
|
|
1263
1432
|
branch: "",
|
|
1264
1433
|
branchItemIds: [],
|
|
1434
|
+
highResolutionItemIds: [],
|
|
1265
1435
|
width: 0,
|
|
1266
1436
|
height: 0,
|
|
1267
1437
|
exported: false,
|
|
@@ -1308,6 +1478,12 @@ var ImageResource = class extends ExtensibleProperty {
|
|
|
1308
1478
|
setBranchItemIds(ids) {
|
|
1309
1479
|
return this.set("branchItemIds", [...ids]);
|
|
1310
1480
|
}
|
|
1481
|
+
getHighResolutionItemIds() {
|
|
1482
|
+
return [...this.get("highResolutionItemIds")];
|
|
1483
|
+
}
|
|
1484
|
+
setHighResolutionItemIds(ids) {
|
|
1485
|
+
return this.set("highResolutionItemIds", [...ids]);
|
|
1486
|
+
}
|
|
1311
1487
|
getWidth() {
|
|
1312
1488
|
return this.get("width");
|
|
1313
1489
|
}
|
|
@@ -1677,8 +1853,10 @@ var MovieClipResource = class extends ExtensibleProperty {
|
|
|
1677
1853
|
path: "",
|
|
1678
1854
|
branch: "",
|
|
1679
1855
|
branchItemIds: [],
|
|
1856
|
+
highResolutionItemIds: [],
|
|
1680
1857
|
fileName: "",
|
|
1681
1858
|
exported: false,
|
|
1859
|
+
textureSetMode: "",
|
|
1682
1860
|
width: 0,
|
|
1683
1861
|
height: 0,
|
|
1684
1862
|
interval: 0,
|
|
@@ -1712,6 +1890,12 @@ var MovieClipResource = class extends ExtensibleProperty {
|
|
|
1712
1890
|
setBranchItemIds(ids) {
|
|
1713
1891
|
return this.set("branchItemIds", [...ids]);
|
|
1714
1892
|
}
|
|
1893
|
+
getHighResolutionItemIds() {
|
|
1894
|
+
return [...this.get("highResolutionItemIds")];
|
|
1895
|
+
}
|
|
1896
|
+
setHighResolutionItemIds(ids) {
|
|
1897
|
+
return this.set("highResolutionItemIds", [...ids]);
|
|
1898
|
+
}
|
|
1715
1899
|
getFileName() {
|
|
1716
1900
|
return this.get("fileName");
|
|
1717
1901
|
}
|
|
@@ -1724,6 +1908,12 @@ var MovieClipResource = class extends ExtensibleProperty {
|
|
|
1724
1908
|
setExported(v) {
|
|
1725
1909
|
return this.set("exported", v);
|
|
1726
1910
|
}
|
|
1911
|
+
getTextureSetMode() {
|
|
1912
|
+
return this.get("textureSetMode");
|
|
1913
|
+
}
|
|
1914
|
+
setTextureSetMode(v) {
|
|
1915
|
+
return this.set("textureSetMode", v);
|
|
1916
|
+
}
|
|
1727
1917
|
getWidth() {
|
|
1728
1918
|
return this.get("width");
|
|
1729
1919
|
}
|
|
@@ -2775,6 +2965,7 @@ var GObject = class extends ExtensibleProperty {
|
|
|
2775
2965
|
sourceHeight: 0,
|
|
2776
2966
|
initWidth: 0,
|
|
2777
2967
|
initHeight: 0,
|
|
2968
|
+
customData: "",
|
|
2778
2969
|
relations: [],
|
|
2779
2970
|
gears: new RefList()
|
|
2780
2971
|
});
|
|
@@ -2815,6 +3006,12 @@ var GObject = class extends ExtensibleProperty {
|
|
|
2815
3006
|
setInitHeight(v) {
|
|
2816
3007
|
return this.setObjectProp("initHeight", v);
|
|
2817
3008
|
}
|
|
3009
|
+
getCustomData() {
|
|
3010
|
+
return this.getObjectProp("customData");
|
|
3011
|
+
}
|
|
3012
|
+
setCustomData(v) {
|
|
3013
|
+
return this.setObjectProp("customData", v);
|
|
3014
|
+
}
|
|
2818
3015
|
/****** Relations ******/
|
|
2819
3016
|
getRelations() {
|
|
2820
3017
|
return this.getObjectProp("relations");
|
|
@@ -4429,6 +4626,8 @@ var GComponent = class extends GObject {
|
|
|
4429
4626
|
instanceController: "",
|
|
4430
4627
|
instancePage: "",
|
|
4431
4628
|
instanceChecked: false,
|
|
4629
|
+
instanceSound: "",
|
|
4630
|
+
instanceSoundVolumeScale: 1,
|
|
4432
4631
|
instancePromptText: "",
|
|
4433
4632
|
instanceSelectionController: "",
|
|
4434
4633
|
instanceVisibleItemCount: 0,
|
|
@@ -4701,6 +4900,18 @@ var GComponent = class extends GObject {
|
|
|
4701
4900
|
setInstanceChecked(v) {
|
|
4702
4901
|
return this.setComponentProp("instanceChecked", v);
|
|
4703
4902
|
}
|
|
4903
|
+
getInstanceSound() {
|
|
4904
|
+
return firstString$1(this.getComponentProp("instanceSound"));
|
|
4905
|
+
}
|
|
4906
|
+
setInstanceSound(v) {
|
|
4907
|
+
return this.setComponentProp("instanceSound", v);
|
|
4908
|
+
}
|
|
4909
|
+
getInstanceSoundVolumeScale() {
|
|
4910
|
+
return this.getComponentProp("instanceSoundVolumeScale");
|
|
4911
|
+
}
|
|
4912
|
+
setInstanceSoundVolumeScale(v) {
|
|
4913
|
+
return this.setComponentProp("instanceSoundVolumeScale", v);
|
|
4914
|
+
}
|
|
4704
4915
|
getInstancePromptText() {
|
|
4705
4916
|
return firstString$1(this.getComponentProp("instancePromptText"));
|
|
4706
4917
|
}
|
|
@@ -9059,6 +9270,7 @@ var Document = class Document {
|
|
|
9059
9270
|
_graph = new Graph();
|
|
9060
9271
|
_root = new Root(this._graph);
|
|
9061
9272
|
_logger = Logger.DEFAULT_INSTANCE;
|
|
9273
|
+
_projectDir = "";
|
|
9062
9274
|
static _GRAPH_DOCUMENTS = /* @__PURE__ */ new WeakMap();
|
|
9063
9275
|
static fromGraph(graph) {
|
|
9064
9276
|
return Document._GRAPH_DOCUMENTS.get(graph) || null;
|
|
@@ -9080,6 +9292,13 @@ var Document = class Document {
|
|
|
9080
9292
|
this._logger = logger;
|
|
9081
9293
|
return this;
|
|
9082
9294
|
}
|
|
9295
|
+
getProjectDir() {
|
|
9296
|
+
return this._projectDir;
|
|
9297
|
+
}
|
|
9298
|
+
setProjectDir(projectDir) {
|
|
9299
|
+
this._projectDir = projectDir;
|
|
9300
|
+
return this;
|
|
9301
|
+
}
|
|
9083
9302
|
async transform(...transforms) {
|
|
9084
9303
|
const stack = transforms.map((fn) => fn.name);
|
|
9085
9304
|
for (const transform of transforms) await transform(this, { stack });
|
|
@@ -9260,6 +9479,7 @@ const PACKAGE_FONT_RESOURCE_ATTRS = {
|
|
|
9260
9479
|
renderMode: { canonical: "renderMode" },
|
|
9261
9480
|
samplePointSize: { canonical: "samplePointSize" }
|
|
9262
9481
|
};
|
|
9482
|
+
const PACKAGE_MOVIE_CLIP_RESOURCE_ATTRS = { atlas: { canonical: "atlas" } };
|
|
9263
9483
|
const PACKAGE_SKELETON_RESOURCE_ATTRS = {
|
|
9264
9484
|
width: { canonical: "width" },
|
|
9265
9485
|
height: { canonical: "height" },
|
|
@@ -9496,7 +9716,10 @@ const LIST_PANEL_ATTRS = {
|
|
|
9496
9716
|
const BUTTON_EXTENSION_ATTRS = {
|
|
9497
9717
|
mode: { canonical: "mode" },
|
|
9498
9718
|
sound: { canonical: "sound" },
|
|
9499
|
-
soundVolumeScale: {
|
|
9719
|
+
soundVolumeScale: {
|
|
9720
|
+
canonical: "soundVolumeScale",
|
|
9721
|
+
aliases: ["volume"]
|
|
9722
|
+
},
|
|
9500
9723
|
downEffect: { canonical: "downEffect" },
|
|
9501
9724
|
downEffectValue: { canonical: "downEffectValue" },
|
|
9502
9725
|
title: { canonical: "title" },
|
|
@@ -9622,6 +9845,7 @@ const PACKAGE_PUBLISH_NODE = defineNode(PACKAGE_PUBLISH_ATTRS, { atlas: PACKAGE_
|
|
|
9622
9845
|
const PACKAGE_RESOURCE_NODE = defineNode(PACKAGE_RESOURCE_BASE_ATTRS);
|
|
9623
9846
|
const PACKAGE_IMAGE_RESOURCE_NODE = defineNode(PACKAGE_IMAGE_RESOURCE_ATTRS);
|
|
9624
9847
|
const PACKAGE_FONT_RESOURCE_NODE = defineNode(PACKAGE_FONT_RESOURCE_ATTRS);
|
|
9848
|
+
const PACKAGE_MOVIE_CLIP_RESOURCE_NODE = defineNode(PACKAGE_MOVIE_CLIP_RESOURCE_ATTRS);
|
|
9625
9849
|
const PACKAGE_SKELETON_RESOURCE_NODE = defineNode(PACKAGE_SKELETON_RESOURCE_ATTRS);
|
|
9626
9850
|
const DISPLAY_OBJECT_NODE = defineNode(DISPLAY_OBJECT_IDENTITY_ATTRS);
|
|
9627
9851
|
const BUTTON_EXTENSION_NODE = defineNode(BUTTON_EXTENSION_ATTRS);
|
|
@@ -9682,13 +9906,13 @@ const IMAGE_NODE = defineNode(mergeAttrs(IMAGE_PANEL_ATTRS, XY_SIZE_ATTRS, LOCKE
|
|
|
9682
9906
|
const GRAPH_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, LOCKED_ATTRS, RESTRICT_SIZE_ATTRS, PIVOT_ATTRS, ANCHOR_ATTRS, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, GRAPH_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9683
9907
|
const MOVIE_CLIP_NODE = defineNode(mergeAttrs(MOVIE_CLIP_PANEL_ATTRS, XY_SIZE_ATTRS, PIVOT_ATTRS, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, GRAYED_ATTRS, RESOURCE_LINK_ATTRS, FILTER_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9684
9908
|
const COMPONENT_INSTANCE_NODE = defineNode(mergeAttrs(COMPONENT_INSTANCE_PANEL_ATTRS, XY_SIZE_ATTRS, LOCKED_ATTRS, RESTRICT_SIZE_ATTRS, ASPECT_ATTRS, PIVOT_ATTRS, ANCHOR_ATTRS, SCALE_ATTRS, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, GRAYED_ATTRS, INSTANCE_MISC_PANEL_ATTRS, RESOURCE_LINK_ATTRS, FILTER_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN, WITH_INSTANCE_EXTENSION_CHILDREN));
|
|
9685
|
-
const LOADER_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, PIVOT_ATTRS, SCALE_ATTRS, GROUP_REF_ATTRS, GRAYED_ATTRS, LOADER_PANEL_ATTRS, FILTER_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9686
|
-
const LOADER3D_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, LOADER3D_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9687
|
-
const TEXT_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, RESTRICT_SIZE_ATTRS, { customData: { canonical: "customData" } }, GROUP_REF_ATTRS, TEXT_PANEL_ATTRS, TEXT_INPUT_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9688
|
-
const TEXT_INPUT_NODE = defineNode(mergeAttrs(TEXT_INPUT_PANEL_ATTRS));
|
|
9689
|
-
const RICH_TEXT_NODE = defineNode(mergeAttrs(RICH_TEXT_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9909
|
+
const LOADER_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, PIVOT_ATTRS, SCALE_ATTRS, GROUP_REF_ATTRS, VISIBLE_ATTRS, GRAYED_ATTRS, LOADER_PANEL_ATTRS, FILTER_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9910
|
+
const LOADER3D_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, VISIBLE_ATTRS, LOADER3D_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9911
|
+
const TEXT_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, RESTRICT_SIZE_ATTRS, { customData: { canonical: "customData" } }, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, GRAYED_ATTRS, TEXT_PANEL_ATTRS, TEXT_INPUT_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9912
|
+
const TEXT_INPUT_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, RESTRICT_SIZE_ATTRS, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, GRAYED_ATTRS, TEXT_PANEL_ATTRS, TEXT_INPUT_PANEL_ATTRS));
|
|
9913
|
+
const RICH_TEXT_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, GROUP_REF_ATTRS, ROTATION_ALPHA_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, GRAYED_ATTRS, TEXT_PANEL_ATTRS, RICH_TEXT_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN));
|
|
9690
9914
|
const GROUP_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, LOCKED_ATTRS, GROUP_REF_ATTRS, VISIBLE_ATTRS, GROUP_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GROUP_GEAR_CHILDREN));
|
|
9691
|
-
const LIST_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, GROUP_REF_ATTRS, TOUCHABLE_ATTRS, LIST_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN, WITH_LIST_ITEM_CHILDREN));
|
|
9915
|
+
const LIST_NODE = defineNode(mergeAttrs(XY_SIZE_ATTRS, GROUP_REF_ATTRS, VISIBLE_ATTRS, TOUCHABLE_ATTRS, LIST_PANEL_ATTRS), mergeChildren(WITH_RELATION_CHILDREN, WITH_GEAR_CHILDREN, WITH_LIST_ITEM_CHILDREN));
|
|
9692
9916
|
const DISPLAY_LIST_CONTAINER$2 = defineContainer({
|
|
9693
9917
|
image: IMAGE_NODE,
|
|
9694
9918
|
graph: GRAPH_NODE,
|
|
@@ -9712,6 +9936,7 @@ const PROJECT_XML_PROTOCOL = {
|
|
|
9712
9936
|
packageResource: PACKAGE_RESOURCE_NODE,
|
|
9713
9937
|
packageImageResource: PACKAGE_IMAGE_RESOURCE_NODE,
|
|
9714
9938
|
packageFontResource: PACKAGE_FONT_RESOURCE_NODE,
|
|
9939
|
+
packageMovieClipResource: PACKAGE_MOVIE_CLIP_RESOURCE_NODE,
|
|
9715
9940
|
packageSkeletonResource: PACKAGE_SKELETON_RESOURCE_NODE,
|
|
9716
9941
|
displayObject: DISPLAY_OBJECT_NODE,
|
|
9717
9942
|
image: IMAGE_NODE,
|
|
@@ -10142,6 +10367,10 @@ function parseComboBoxItemXmlNode(item) {
|
|
|
10142
10367
|
icon: readXmlAttr(item, specs.icon) ?? null
|
|
10143
10368
|
};
|
|
10144
10369
|
}
|
|
10370
|
+
function getProjectBasePath(fs, projectPath) {
|
|
10371
|
+
const basePath = fs.dirname(projectPath);
|
|
10372
|
+
return basePath === "." ? "" : basePath;
|
|
10373
|
+
}
|
|
10145
10374
|
var ProjectReader = class {
|
|
10146
10375
|
_fs;
|
|
10147
10376
|
constructor(fs) {
|
|
@@ -10150,7 +10379,8 @@ var ProjectReader = class {
|
|
|
10150
10379
|
async read(projectPath) {
|
|
10151
10380
|
const fs = this._fs;
|
|
10152
10381
|
const doc = new Document();
|
|
10153
|
-
const basePath =
|
|
10382
|
+
const basePath = getProjectBasePath(fs, projectPath);
|
|
10383
|
+
doc.setProjectDir(basePath);
|
|
10154
10384
|
const ctx = new ReaderContext(doc, basePath);
|
|
10155
10385
|
const projDesc = getXmlNode(parseXML(await fs.readFile(projectPath)).projectDescription);
|
|
10156
10386
|
if (projDesc) {
|
|
@@ -10467,6 +10697,8 @@ var ProjectReader = class {
|
|
|
10467
10697
|
res.setBranch(branchName);
|
|
10468
10698
|
res.setFileName(name);
|
|
10469
10699
|
res.setExported(exported);
|
|
10700
|
+
const textureSetMode = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageMovieClipResource.attrs.atlas);
|
|
10701
|
+
if (textureSetMode !== void 0) res.setTextureSetMode(textureSetMode);
|
|
10470
10702
|
pkg.addResource(res);
|
|
10471
10703
|
ctx.registerResource(pkg.getId(), id, res);
|
|
10472
10704
|
return res;
|
|
@@ -10871,6 +11103,16 @@ var ProjectReader = class {
|
|
|
10871
11103
|
}
|
|
10872
11104
|
const textGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.group);
|
|
10873
11105
|
if (textGroup) g.setGroup(textGroup);
|
|
11106
|
+
const textRotation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.rotation);
|
|
11107
|
+
if (textRotation !== void 0) g.setRotation(parseFloat2(textRotation));
|
|
11108
|
+
const textAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.alpha);
|
|
11109
|
+
if (textAlpha !== void 0) g.setAlpha(parseFloat2(textAlpha, 1));
|
|
11110
|
+
const textVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.visible);
|
|
11111
|
+
if (textVisible !== void 0) g.setVisible(parseBool(textVisible));
|
|
11112
|
+
const textTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.touchable);
|
|
11113
|
+
if (textTouchable !== void 0) g.setTouchable(parseBool(textTouchable));
|
|
11114
|
+
const textGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.grayed);
|
|
11115
|
+
if (textGrayed !== void 0) g.setGrayed(parseBool(textGrayed));
|
|
10874
11116
|
const textCustomData = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.customData);
|
|
10875
11117
|
if (textCustomData !== void 0) g.setCustomData(textCustomData);
|
|
10876
11118
|
const textValue = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
|
|
@@ -10981,6 +11223,16 @@ var ProjectReader = class {
|
|
|
10981
11223
|
}
|
|
10982
11224
|
const richTextGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.group);
|
|
10983
11225
|
if (richTextGroup) g.setGroup(richTextGroup);
|
|
11226
|
+
const richTextRotation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.rotation);
|
|
11227
|
+
if (richTextRotation !== void 0) g.setRotation(parseFloat2(richTextRotation));
|
|
11228
|
+
const richTextAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.alpha);
|
|
11229
|
+
if (richTextAlpha !== void 0) g.setAlpha(parseFloat2(richTextAlpha, 1));
|
|
11230
|
+
const richTextVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.visible);
|
|
11231
|
+
if (richTextVisible !== void 0) g.setVisible(parseBool(richTextVisible));
|
|
11232
|
+
const richTextTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.touchable);
|
|
11233
|
+
if (richTextTouchable !== void 0) g.setTouchable(parseBool(richTextTouchable));
|
|
11234
|
+
const richTextGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.grayed);
|
|
11235
|
+
if (richTextGrayed !== void 0) g.setGrayed(parseBool(richTextGrayed));
|
|
10984
11236
|
const richText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
|
|
10985
11237
|
if (richText !== void 0) g.setText(String(richText));
|
|
10986
11238
|
const richTextFontSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.fontSize);
|
|
@@ -11069,6 +11321,16 @@ var ProjectReader = class {
|
|
|
11069
11321
|
}
|
|
11070
11322
|
const inputGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.group);
|
|
11071
11323
|
if (inputGroup) g.setGroup(inputGroup);
|
|
11324
|
+
const inputRotation = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.rotation);
|
|
11325
|
+
if (inputRotation !== void 0) g.setRotation(parseFloat2(inputRotation));
|
|
11326
|
+
const inputAlpha = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.alpha);
|
|
11327
|
+
if (inputAlpha !== void 0) g.setAlpha(parseFloat2(inputAlpha, 1));
|
|
11328
|
+
const inputVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.visible);
|
|
11329
|
+
if (inputVisible !== void 0) g.setVisible(parseBool(inputVisible));
|
|
11330
|
+
const inputTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.touchable);
|
|
11331
|
+
if (inputTouchable !== void 0) g.setTouchable(parseBool(inputTouchable));
|
|
11332
|
+
const inputGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.textInput.attrs.grayed);
|
|
11333
|
+
if (inputGrayed !== void 0) g.setGrayed(parseBool(inputGrayed));
|
|
11072
11334
|
const inputText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.text);
|
|
11073
11335
|
if (inputText !== void 0) g.setText(String(inputText));
|
|
11074
11336
|
const inputFontSize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.fontSize);
|
|
@@ -11275,6 +11537,8 @@ var ProjectReader = class {
|
|
|
11275
11537
|
}
|
|
11276
11538
|
const loaderGrayed = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.grayed);
|
|
11277
11539
|
if (loaderGrayed !== void 0) g.setGrayed(parseBool(loaderGrayed));
|
|
11540
|
+
const loaderVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.visible);
|
|
11541
|
+
if (loaderVisible !== void 0) g.setVisible(parseBool(loaderVisible));
|
|
11278
11542
|
const loaderUrl = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.url);
|
|
11279
11543
|
if (loaderUrl) g.setUrl(loaderUrl);
|
|
11280
11544
|
const loaderAlign = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.align);
|
|
@@ -11348,6 +11612,8 @@ var ProjectReader = class {
|
|
|
11348
11612
|
const [w, h] = parseSizeString(loader3dSize);
|
|
11349
11613
|
g.setSize(w, h);
|
|
11350
11614
|
}
|
|
11615
|
+
const loader3dVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.visible);
|
|
11616
|
+
if (loader3dVisible !== void 0) g.setVisible(parseBool(loader3dVisible));
|
|
11351
11617
|
const loader3dUrl = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.url);
|
|
11352
11618
|
if (loader3dUrl) g.setUrl(loader3dUrl);
|
|
11353
11619
|
const loader3dAlign = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.align);
|
|
@@ -11530,6 +11796,8 @@ var ProjectReader = class {
|
|
|
11530
11796
|
}
|
|
11531
11797
|
const listGroup = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.group);
|
|
11532
11798
|
if (listGroup) g.setGroup(listGroup);
|
|
11799
|
+
const listVisible = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.visible);
|
|
11800
|
+
if (listVisible !== void 0) g.setVisible(parseBool(listVisible));
|
|
11533
11801
|
const listTouchable = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.touchable);
|
|
11534
11802
|
if (listTouchable !== void 0) g.setTouchable(parseBool(listTouchable));
|
|
11535
11803
|
const defaultItem = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.defaultItem);
|
|
@@ -11690,6 +11958,10 @@ var ProjectReader = class {
|
|
|
11690
11958
|
if (page !== void 0) componentObj.setInstancePage?.(page);
|
|
11691
11959
|
const checked = extSpecs.checked ? readXmlAttr(extAttrs, extSpecs.checked) : void 0;
|
|
11692
11960
|
if (checked !== void 0) componentObj.setInstanceChecked?.(parseBool(checked));
|
|
11961
|
+
const sound = extSpecs.sound ? readXmlAttr(extAttrs, extSpecs.sound) : void 0;
|
|
11962
|
+
if (sound !== void 0) componentObj.setInstanceSound?.(sound);
|
|
11963
|
+
const soundVolumeScale = extSpecs.soundVolumeScale ? readXmlAttr(extAttrs, extSpecs.soundVolumeScale) : void 0;
|
|
11964
|
+
if (soundVolumeScale !== void 0) componentObj.setInstanceSoundVolumeScale?.(parseFloat2(soundVolumeScale, 1));
|
|
11693
11965
|
const prompt = extSpecs.prompt ? readXmlAttr(extAttrs, extSpecs.prompt) : void 0;
|
|
11694
11966
|
if (prompt !== void 0) componentObj.setInstancePromptText?.(prompt);
|
|
11695
11967
|
const selectionController = extSpecs.selectionController ? readXmlAttr(extAttrs, extSpecs.selectionController) : void 0;
|
|
@@ -12356,6 +12628,10 @@ var ProjectWriter = class {
|
|
|
12356
12628
|
const samplePointSize = fontRes.getSamplePointSize?.() ?? 0;
|
|
12357
12629
|
if (samplePointSize !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageFontResource.attrs.samplePointSize, String(samplePointSize));
|
|
12358
12630
|
}
|
|
12631
|
+
if (res.propertyType === "MovieClipResource") {
|
|
12632
|
+
const textureSetMode = res.getTextureSetMode?.() ?? "";
|
|
12633
|
+
if (textureSetMode) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageMovieClipResource.attrs.atlas, textureSetMode);
|
|
12634
|
+
}
|
|
12359
12635
|
if (res.propertyType === "SpineResource" || res.propertyType === "DragonBonesResource") {
|
|
12360
12636
|
const skeletonRes = res;
|
|
12361
12637
|
writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.packageSkeletonResource.attrs.width, String(skeletonRes.getWidth?.() ?? 0));
|
|
@@ -12715,6 +12991,7 @@ var ProjectWriter = class {
|
|
|
12715
12991
|
if (pivotX !== 0 || pivotY !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.pivot, `${pivotX},${pivotY}`);
|
|
12716
12992
|
const [scaleX, scaleY] = [typedObj.getScaleX?.() ?? 1, typedObj.getScaleY?.() ?? 1];
|
|
12717
12993
|
if (scaleX !== 1 || scaleY !== 1) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.scale, `${scaleX},${scaleY}`);
|
|
12994
|
+
if (typedObj.getVisible?.() === false) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.visible, "false");
|
|
12718
12995
|
if (typedObj.getGrayed?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.grayed, "true");
|
|
12719
12996
|
const url = typedObj.getUrl?.();
|
|
12720
12997
|
if (url) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.url, url);
|
|
@@ -12776,6 +13053,7 @@ var ProjectWriter = class {
|
|
|
12776
13053
|
if (typedObj.getFilterData?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.movieClip.attrs.filterData, typedObj.getFilterData?.());
|
|
12777
13054
|
}
|
|
12778
13055
|
if (type === "GTextField" || type === "GRichTextField" || type === "GTextInput") {
|
|
13056
|
+
const textNodeProtocol = type === "GRichTextField" ? PROJECT_XML_PROTOCOL.richText : type === "GTextInput" ? PROJECT_XML_PROTOCOL.textInput : PROJECT_XML_PROTOCOL.text;
|
|
12779
13057
|
const [x, y] = [typedObj.getX?.() ?? 0, typedObj.getY?.() ?? 0];
|
|
12780
13058
|
writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.xy, `${x},${y}`);
|
|
12781
13059
|
const [w, h] = [typedObj.getWidth?.() ?? 0, typedObj.getHeight?.() ?? 0];
|
|
@@ -12802,6 +13080,11 @@ var ProjectWriter = class {
|
|
|
12802
13080
|
if (underlaySoftness !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.underlaySoftness, String(underlaySoftness));
|
|
12803
13081
|
}
|
|
12804
13082
|
if (typedObj.getGroup?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.group, typedObj.getGroup?.());
|
|
13083
|
+
if ((typedObj.getRotation?.() ?? 0) !== 0) writeXmlAttr(attrs, textNodeProtocol.attrs.rotation, String(typedObj.getRotation?.() ?? 0));
|
|
13084
|
+
if ((typedObj.getAlpha?.() ?? 1) !== 1) writeXmlAttr(attrs, textNodeProtocol.attrs.alpha, formatDisplayAlpha(typedObj.getAlpha?.() ?? 1));
|
|
13085
|
+
if (typedObj.getVisible?.() === false) writeXmlAttr(attrs, textNodeProtocol.attrs.visible, "false");
|
|
13086
|
+
if (typedObj.getTouchable?.() === false) writeXmlAttr(attrs, textNodeProtocol.attrs.touchable, "false");
|
|
13087
|
+
if (typedObj.getGrayed?.()) writeXmlAttr(attrs, textNodeProtocol.attrs.grayed, "true");
|
|
12805
13088
|
if (typedObj.getCustomData?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.customData, typedObj.getCustomData?.());
|
|
12806
13089
|
}
|
|
12807
13090
|
if ((type === "GList" || type === "GTree") && typedObj.getGroup?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.group, typedObj.getGroup?.());
|
|
@@ -12810,12 +13093,14 @@ var ProjectWriter = class {
|
|
|
12810
13093
|
writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.xy, `${x},${y}`);
|
|
12811
13094
|
const [w, h] = [typedObj.getWidth?.() ?? 0, typedObj.getHeight?.() ?? 0];
|
|
12812
13095
|
if (w !== 0 || h !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.size, `${w},${h}`);
|
|
13096
|
+
if (typedObj.getVisible?.() === false) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.visible, "false");
|
|
12813
13097
|
}
|
|
12814
13098
|
if (type === "GLoader3D") {
|
|
12815
13099
|
const [x, y] = [typedObj.getX?.() ?? 0, typedObj.getY?.() ?? 0];
|
|
12816
13100
|
writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.xy, `${x},${y}`);
|
|
12817
13101
|
const [w, h] = [typedObj.getWidth?.() ?? 0, typedObj.getHeight?.() ?? 0];
|
|
12818
13102
|
if (w !== 0 || h !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.size, `${w},${h}`);
|
|
13103
|
+
if (typedObj.getVisible?.() === false) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.visible, "false");
|
|
12819
13104
|
const url = typedObj.getUrl?.();
|
|
12820
13105
|
if (url) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader3D.attrs.url, url);
|
|
12821
13106
|
const align = typedObj.getAlign?.();
|
|
@@ -13028,6 +13313,8 @@ var ProjectWriter = class {
|
|
|
13028
13313
|
if (typedObj.getInstanceController?.() && extSpecs.controller) writeXmlAttr(extAttrs, extSpecs.controller, typedObj.getInstanceController?.());
|
|
13029
13314
|
if (typedObj.getInstancePage?.() && extSpecs.page) writeXmlAttr(extAttrs, extSpecs.page, typedObj.getInstancePage?.());
|
|
13030
13315
|
if (typedObj.getInstanceChecked?.() && extSpecs.checked) writeXmlAttr(extAttrs, extSpecs.checked, "1");
|
|
13316
|
+
if (typedObj.getInstanceSound?.() && extSpecs.sound) writeXmlAttr(extAttrs, extSpecs.sound, typedObj.getInstanceSound?.());
|
|
13317
|
+
if ((typedObj.getInstanceSoundVolumeScale?.() ?? 1) !== 1 && extSpecs.soundVolumeScale) writeXmlAttr(extAttrs, extSpecs.soundVolumeScale, String(typedObj.getInstanceSoundVolumeScale?.() ?? 1));
|
|
13031
13318
|
if (typedObj.getInstancePromptText?.() && extSpecs.prompt) writeXmlAttr(extAttrs, extSpecs.prompt, typedObj.getInstancePromptText?.());
|
|
13032
13319
|
if (typedObj.getInstanceSelectionController?.() && extSpecs.selectionController) writeXmlAttr(extAttrs, extSpecs.selectionController, typedObj.getInstanceSelectionController?.());
|
|
13033
13320
|
if ((typedObj.getInstanceVisibleItemCount?.() ?? 0) > 0 && extSpecs.visibleItemCount) writeXmlAttr(extAttrs, extSpecs.visibleItemCount, String(typedObj.getInstanceVisibleItemCount?.() ?? 0));
|
|
@@ -17498,8 +17785,8 @@ function decodeChildBlock6(resource, child, childBuf) {
|
|
|
17498
17785
|
if (relatedControllerIndex >= 0) component.setInstanceController(resource.listControllers()[relatedControllerIndex]?.getName() ?? "");
|
|
17499
17786
|
}
|
|
17500
17787
|
component.setInstancePage(childBuf.readS() ?? "");
|
|
17501
|
-
childBuf.readS();
|
|
17502
|
-
if (childBuf.readBool() && remainingBytes(childBuf) >= 4) childBuf.getFloat32();
|
|
17788
|
+
component.setInstanceSound(childBuf.readS() ?? "");
|
|
17789
|
+
if (childBuf.readBool() && remainingBytes(childBuf) >= 4) component.setInstanceSoundVolumeScale(childBuf.getFloat32());
|
|
17503
17790
|
if (remainingBytes(childBuf) >= 1) component.setInstanceChecked(childBuf.readBool());
|
|
17504
17791
|
break;
|
|
17505
17792
|
case "Label":
|
|
@@ -18073,8 +18360,9 @@ const BinItemType$1 = {
|
|
|
18073
18360
|
Font: 5,
|
|
18074
18361
|
Swf: 6,
|
|
18075
18362
|
Misc: 7,
|
|
18076
|
-
|
|
18077
|
-
|
|
18363
|
+
Unknown: 8,
|
|
18364
|
+
Spine: 9,
|
|
18365
|
+
DragonBones: 10
|
|
18078
18366
|
};
|
|
18079
18367
|
function normalizePackageResourcePath(path) {
|
|
18080
18368
|
const normalized = path.replace(/\\/g, "/").trim();
|
|
@@ -18375,11 +18663,13 @@ var BinaryReader = class {
|
|
|
18375
18663
|
if (branchCnt2 > 0) if (branchIncluded) branchItemIds = buf.readSArray(branchCnt2);
|
|
18376
18664
|
else branchItemIds = [buf.readS() ?? ""];
|
|
18377
18665
|
const highResCnt = buf.getUint8();
|
|
18378
|
-
|
|
18666
|
+
const highResolutionItemIds = [];
|
|
18667
|
+
for (let highResIndex = 0; highResIndex < highResCnt; highResIndex++) highResolutionItemIds.push(buf.readS());
|
|
18379
18668
|
if (createdResource) {
|
|
18380
18669
|
createdResource.setPath(itemPath);
|
|
18381
18670
|
createdResource.setBranch(branchName);
|
|
18382
18671
|
createdResource.setBranchItemIds(branchItemIds);
|
|
18672
|
+
createdResource.setHighResolutionItemIds?.(highResolutionItemIds);
|
|
18383
18673
|
}
|
|
18384
18674
|
}
|
|
18385
18675
|
buf.pos = nextPos;
|
|
@@ -19910,8 +20200,13 @@ function _writeExtensionInstanceData(buf, extType, child, comp, pkg, version) {
|
|
|
19910
20200
|
buf.writeInt16(ctrlIdx >= 0 ? ctrlIdx : -1);
|
|
19911
20201
|
} else buf.writeInt16(-1);
|
|
19912
20202
|
buf.writeS(child.getInstancePage?.() ?? null);
|
|
19913
|
-
|
|
19914
|
-
buf.
|
|
20203
|
+
const sound = child.getInstanceSound?.() ?? null;
|
|
20204
|
+
buf.writeSEx(remapLocalUiUrl(pkg, sound) ?? null, false, false);
|
|
20205
|
+
const soundVolume = child.getInstanceSoundVolumeScale?.();
|
|
20206
|
+
if (soundVolume !== void 0 && soundVolume !== null && soundVolume !== 1) {
|
|
20207
|
+
buf.writeBool(true);
|
|
20208
|
+
buf.writeFloat32(soundVolume);
|
|
20209
|
+
} else buf.writeBool(false);
|
|
19915
20210
|
buf.writeBool(child.getInstanceChecked?.() ?? false);
|
|
19916
20211
|
break;
|
|
19917
20212
|
}
|
|
@@ -20092,8 +20387,9 @@ const BinItemType = {
|
|
|
20092
20387
|
Atlas: 4,
|
|
20093
20388
|
Font: 5,
|
|
20094
20389
|
Misc: 7,
|
|
20095
|
-
|
|
20096
|
-
|
|
20390
|
+
Unknown: 8,
|
|
20391
|
+
Spine: 9,
|
|
20392
|
+
DragonBones: 10
|
|
20097
20393
|
};
|
|
20098
20394
|
/**
|
|
20099
20395
|
* Maps our PropertyType to the editor's type string used for sorting.
|
|
@@ -20422,7 +20718,9 @@ var BinaryWriter = class {
|
|
|
20422
20718
|
data.writeSEx(branchName || null);
|
|
20423
20719
|
data.writeUint8(branchItemIds.length);
|
|
20424
20720
|
for (const branchItemId of branchItemIds) data.writeSEx(branchItemId || null);
|
|
20425
|
-
|
|
20721
|
+
const highResolutionItemIds = getItemHighResolutionItemIds(res, publishedItemIdMap, packageItemIds);
|
|
20722
|
+
data.writeUint8(highResolutionItemIds.length);
|
|
20723
|
+
for (const highResolutionItemId of highResolutionItemIds) data.writeS(highResolutionItemId);
|
|
20426
20724
|
}
|
|
20427
20725
|
const nextPos = data.pos;
|
|
20428
20726
|
const savedPos = data.pos;
|
|
@@ -20693,6 +20991,15 @@ function getItemBranchItemIds(item, branchNames, branchItemIdsMap) {
|
|
|
20693
20991
|
if (!inferred) return [];
|
|
20694
20992
|
return inferred.some((value) => !!value) ? [...inferred] : [];
|
|
20695
20993
|
}
|
|
20994
|
+
function getItemHighResolutionItemIds(item, publishedItemIdMap, packageItemIds) {
|
|
20995
|
+
const resolvedIds = (item.getHighResolutionItemIds?.() ?? []).map((id) => {
|
|
20996
|
+
if (!id) return null;
|
|
20997
|
+
const publishedId = publishedItemIdMap.get(id) ?? id;
|
|
20998
|
+
return packageItemIds.has(publishedId) ? publishedId : null;
|
|
20999
|
+
});
|
|
21000
|
+
while (resolvedIds.length > 0 && !resolvedIds[resolvedIds.length - 1]) resolvedIds.pop();
|
|
21001
|
+
return resolvedIds;
|
|
21002
|
+
}
|
|
20696
21003
|
function getAtlasId(atlas) {
|
|
20697
21004
|
return `atlas${atlas.getIndex()}`;
|
|
20698
21005
|
}
|
|
@@ -20721,8 +21028,8 @@ function getPixelHitTestEntry(resource) {
|
|
|
20721
21028
|
/**
|
|
20722
21029
|
* Abstract I/O base class for reading and writing FairyGUI projects.
|
|
20723
21030
|
*
|
|
20724
|
-
* Platform-specific
|
|
20725
|
-
*
|
|
21031
|
+
* Platform-specific adapters provide the file system abstraction required by
|
|
21032
|
+
* the reader/writer.
|
|
20726
21033
|
*
|
|
20727
21034
|
* @category I/O
|
|
20728
21035
|
*/
|
|
@@ -20741,183 +21048,15 @@ var PlatformIO = class {
|
|
|
20741
21048
|
}
|
|
20742
21049
|
};
|
|
20743
21050
|
//#endregion
|
|
20744
|
-
//#region ../
|
|
20745
|
-
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
20749
|
-
|
|
20750
|
-
|
|
20751
|
-
|
|
20752
|
-
|
|
20753
|
-
* const io = new NodeIO();
|
|
20754
|
-
* const doc = await io.readProject('./path/to/project.fairy');
|
|
20755
|
-
* await io.writeProject(doc, './path/to/output.fairy');
|
|
20756
|
-
* const doc2 = await io.readBinary('./path/to/package_fui.bytes');
|
|
20757
|
-
* ```
|
|
20758
|
-
*
|
|
20759
|
-
* @category I/O
|
|
20760
|
-
*/
|
|
20761
|
-
var NodeIO = class extends PlatformIO {
|
|
20762
|
-
createFileSystem() {
|
|
20763
|
-
return {
|
|
20764
|
-
async readFile(filePath) {
|
|
20765
|
-
return fs$1.readFile(filePath, "utf-8");
|
|
20766
|
-
},
|
|
20767
|
-
async readFileRaw(filePath) {
|
|
20768
|
-
const buf = await fs$1.readFile(filePath);
|
|
20769
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
20770
|
-
},
|
|
20771
|
-
async writeFile(filePath, content) {
|
|
20772
|
-
await fs$1.writeFile(filePath, content, "utf-8");
|
|
20773
|
-
},
|
|
20774
|
-
async writeFileRaw(filePath, data) {
|
|
20775
|
-
await fs$1.writeFile(filePath, data);
|
|
20776
|
-
},
|
|
20777
|
-
async mkdir(dirPath) {
|
|
20778
|
-
await fs$1.mkdir(dirPath, { recursive: true });
|
|
20779
|
-
},
|
|
20780
|
-
async readdir(dirPath) {
|
|
20781
|
-
return (await fs$1.readdir(dirPath, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
20782
|
-
},
|
|
20783
|
-
async exists(filePath) {
|
|
20784
|
-
try {
|
|
20785
|
-
await fs$1.access(filePath);
|
|
20786
|
-
return true;
|
|
20787
|
-
} catch {
|
|
20788
|
-
return false;
|
|
20789
|
-
}
|
|
20790
|
-
},
|
|
20791
|
-
join(...paths) {
|
|
20792
|
-
return path$1.join(...paths);
|
|
20793
|
-
},
|
|
20794
|
-
dirname(filePath) {
|
|
20795
|
-
return path$1.dirname(filePath);
|
|
20796
|
-
}
|
|
20797
|
-
};
|
|
20798
|
-
}
|
|
20799
|
-
};
|
|
20800
|
-
//#endregion
|
|
20801
|
-
//#region ../functions/src/inspect.ts
|
|
20802
|
-
function mapResource(resource) {
|
|
20803
|
-
return {
|
|
20804
|
-
name: resource.getName(),
|
|
20805
|
-
id: resource.getId(),
|
|
20806
|
-
path: resource.getPath?.() ?? "/",
|
|
20807
|
-
exported: resource.getExported?.() ?? false
|
|
20808
|
-
};
|
|
20809
|
-
}
|
|
20810
|
-
function mapComponentDetail(component, totals) {
|
|
20811
|
-
const children = component.listChildren();
|
|
20812
|
-
const controllers = component.listControllers();
|
|
20813
|
-
const transitions = component.listTransitions();
|
|
20814
|
-
totals.displayObjects += children.length;
|
|
20815
|
-
totals.controllers += controllers.length;
|
|
20816
|
-
totals.transitions += transitions.length;
|
|
20817
|
-
for (const child of children) totals.gears += child.listGears().length;
|
|
20818
|
-
return {
|
|
20819
|
-
name: component.getName(),
|
|
20820
|
-
id: component.getId(),
|
|
20821
|
-
childCount: children.length,
|
|
20822
|
-
controllerCount: controllers.length,
|
|
20823
|
-
transitionCount: transitions.length
|
|
20824
|
-
};
|
|
20825
|
-
}
|
|
20826
|
-
/**
|
|
20827
|
-
* Generates a detailed report of the project contents.
|
|
20828
|
-
*
|
|
20829
|
-
* Unlike other transforms, `inspect()` does NOT modify the document —
|
|
20830
|
-
* it returns a structured report.
|
|
20831
|
-
*
|
|
20832
|
-
* ```ts
|
|
20833
|
-
* const report = inspect(doc);
|
|
20834
|
-
* console.log(`${report.totals.packages} packages, ${report.totals.components} components`);
|
|
20835
|
-
* ```
|
|
20836
|
-
*/
|
|
20837
|
-
function inspect(doc) {
|
|
20838
|
-
const root = doc.getRoot();
|
|
20839
|
-
const totals = {
|
|
20840
|
-
packages: 0,
|
|
20841
|
-
images: 0,
|
|
20842
|
-
sounds: 0,
|
|
20843
|
-
fonts: 0,
|
|
20844
|
-
movieClips: 0,
|
|
20845
|
-
components: 0,
|
|
20846
|
-
displayObjects: 0,
|
|
20847
|
-
gears: 0,
|
|
20848
|
-
controllers: 0,
|
|
20849
|
-
transitions: 0
|
|
20850
|
-
};
|
|
20851
|
-
const packages = root.listPackages().map((pkg) => {
|
|
20852
|
-
totals.packages++;
|
|
20853
|
-
const resources = pkg.listResources();
|
|
20854
|
-
const images = resources.filter((r) => r.propertyType === "ImageResource");
|
|
20855
|
-
const sounds = resources.filter((r) => r.propertyType === "SoundResource");
|
|
20856
|
-
const fonts = resources.filter((r) => r.propertyType === "FontResource");
|
|
20857
|
-
const movieClips = resources.filter((r) => r.propertyType === "MovieClipResource");
|
|
20858
|
-
const components = pkg.listComponents();
|
|
20859
|
-
totals.images += images.length;
|
|
20860
|
-
totals.sounds += sounds.length;
|
|
20861
|
-
totals.fonts += fonts.length;
|
|
20862
|
-
totals.movieClips += movieClips.length;
|
|
20863
|
-
totals.components += components.length;
|
|
20864
|
-
const componentDetails = components.map((component) => mapComponentDetail(component, totals));
|
|
20865
|
-
return {
|
|
20866
|
-
name: pkg.getName(),
|
|
20867
|
-
id: pkg.getId(),
|
|
20868
|
-
publishName: pkg.getPublishName() || pkg.getName(),
|
|
20869
|
-
resources: {
|
|
20870
|
-
images: {
|
|
20871
|
-
count: images.length,
|
|
20872
|
-
details: images.map(mapResource)
|
|
20873
|
-
},
|
|
20874
|
-
sounds: {
|
|
20875
|
-
count: sounds.length,
|
|
20876
|
-
details: sounds.map(mapResource)
|
|
20877
|
-
},
|
|
20878
|
-
fonts: {
|
|
20879
|
-
count: fonts.length,
|
|
20880
|
-
details: fonts.map(mapResource)
|
|
20881
|
-
},
|
|
20882
|
-
movieClips: {
|
|
20883
|
-
count: movieClips.length,
|
|
20884
|
-
details: movieClips.map(mapResource)
|
|
20885
|
-
},
|
|
20886
|
-
components: {
|
|
20887
|
-
count: components.length,
|
|
20888
|
-
details: components.map(mapResource)
|
|
20889
|
-
}
|
|
20890
|
-
},
|
|
20891
|
-
componentDetails
|
|
20892
|
-
};
|
|
20893
|
-
});
|
|
20894
|
-
return {
|
|
20895
|
-
projectId: root.getProjectId(),
|
|
20896
|
-
projectType: root.getProjectType(),
|
|
20897
|
-
version: root.getVersion(),
|
|
20898
|
-
packages,
|
|
20899
|
-
totals
|
|
20900
|
-
};
|
|
20901
|
-
}
|
|
20902
|
-
//#endregion
|
|
20903
|
-
//#region ../functions/src/utils.ts
|
|
20904
|
-
/**
|
|
20905
|
-
* Wraps a transform function, assigning it a name for the transform stack.
|
|
20906
|
-
*/
|
|
20907
|
-
function createTransform(name, fn) {
|
|
20908
|
-
Object.defineProperty(fn, "name", { value: name });
|
|
20909
|
-
return fn;
|
|
20910
|
-
}
|
|
20911
|
-
//#endregion
|
|
20912
|
-
//#region ../functions/src/max-rects-compat.ts
|
|
20913
|
-
const NO_ROTATION = 2;
|
|
20914
|
-
const MAX_SCORE = 2147483647;
|
|
20915
|
-
const MAX_RECTS_METHOD = {
|
|
20916
|
-
BestShortSideFit: 0,
|
|
20917
|
-
BestLongSideFit: 1,
|
|
20918
|
-
BestAreaFit: 2,
|
|
20919
|
-
BottomLeftRule: 3,
|
|
20920
|
-
ContactPointRule: 4
|
|
21051
|
+
//#region ../functions/src/max-rects-compat.ts
|
|
21052
|
+
const NO_ROTATION = 2;
|
|
21053
|
+
const MAX_SCORE = 2147483647;
|
|
21054
|
+
const MAX_RECTS_METHOD = {
|
|
21055
|
+
BestShortSideFit: 0,
|
|
21056
|
+
BestLongSideFit: 1,
|
|
21057
|
+
BestAreaFit: 2,
|
|
21058
|
+
BottomLeftRule: 3,
|
|
21059
|
+
ContactPointRule: 4
|
|
20921
21060
|
};
|
|
20922
21061
|
const COMPAT_NODE_RECT_FLAGS = {
|
|
20923
21062
|
DUPLICATE_PADDING: 1,
|
|
@@ -21623,6 +21762,19 @@ const ATLAS_DEFAULTS = {
|
|
|
21623
21762
|
function getPublishedItemId(resource) {
|
|
21624
21763
|
return (resource.getExtras() ?? {})._publishedId ?? resource.getId();
|
|
21625
21764
|
}
|
|
21765
|
+
function getSelectedSkeletonDependencyImageIds(resources) {
|
|
21766
|
+
const imageIds = /* @__PURE__ */ new Set();
|
|
21767
|
+
const resourcesById = new Map(resources.map((resource) => [resource.getId(), resource]));
|
|
21768
|
+
for (const resource of resources) {
|
|
21769
|
+
if (!isSkeletonResource$1(resource)) continue;
|
|
21770
|
+
for (const requiredId of resource.getRequireIds()) {
|
|
21771
|
+
if (!requiredId) continue;
|
|
21772
|
+
const required = resourcesById.get(requiredId);
|
|
21773
|
+
if (required && isImageResource$1(required)) imageIds.add(requiredId);
|
|
21774
|
+
}
|
|
21775
|
+
}
|
|
21776
|
+
return imageIds;
|
|
21777
|
+
}
|
|
21626
21778
|
function resolveFontFileName(fontName) {
|
|
21627
21779
|
return /\.fnt$/i.test(fontName) ? fontName : `${fontName}.fnt`;
|
|
21628
21780
|
}
|
|
@@ -21759,12 +21911,18 @@ function atlas(_options = {}) {
|
|
|
21759
21911
|
const logger = doc.getLogger();
|
|
21760
21912
|
const encoder = options.encoder;
|
|
21761
21913
|
const doTrim = options.trimImage && !!encoder && !!options.basePath;
|
|
21914
|
+
const packageFilter = options.packages ? new Set(options.packages) : null;
|
|
21762
21915
|
for (const pkg of root.listPackages()) {
|
|
21916
|
+
if (packageFilter && !packageFilter.has(pkg.getName())) continue;
|
|
21763
21917
|
const selectedPublishIds = new Set((pkg.getExtras() ?? {}).publishedResourceIds ?? []);
|
|
21764
21918
|
const allResources = selectedPublishIds.size > 0 ? pkg.listResources().filter((resource) => selectedPublishIds.has(resource.getId())) : pkg.listResources();
|
|
21919
|
+
const skeletonDependencyImageIds = getSelectedSkeletonDependencyImageIds(allResources);
|
|
21765
21920
|
const orderedResources = await resolveEditorCompatibleResourceOrder(pkg, allResources, options);
|
|
21766
21921
|
const orderedAllResources = sortResourcesByOrder(allResources, new Map(orderedResources.map((resource, index) => [resource.getId(), index])), new Map(allResources.map((resource, index) => [resource.getId(), index])));
|
|
21767
|
-
if (!allResources.some((resource) =>
|
|
21922
|
+
if (!allResources.some((resource) => {
|
|
21923
|
+
if (isImageResource$1(resource) && skeletonDependencyImageIds.has(resource.getId())) return false;
|
|
21924
|
+
return isPackableResource(resource);
|
|
21925
|
+
})) continue;
|
|
21768
21926
|
const inputs = [];
|
|
21769
21927
|
const referencedIds = /* @__PURE__ */ new Set();
|
|
21770
21928
|
const resourceMap = /* @__PURE__ */ new Map();
|
|
@@ -21833,148 +21991,72 @@ function atlas(_options = {}) {
|
|
|
21833
21991
|
}
|
|
21834
21992
|
for (const res of orderedAllResources) if (isImageResource$1(res)) {
|
|
21835
21993
|
const resId = res.getId();
|
|
21836
|
-
if (
|
|
21994
|
+
if (skeletonDependencyImageIds.has(resId)) continue;
|
|
21995
|
+
if (selectedPublishIds.size === 0 && !res.getExported() && referencedIds.size > 0 && !referencedIds.has(resId)) continue;
|
|
21837
21996
|
await _collectImage(res, pkg, inputs, encoder, options, doTrim, logger);
|
|
21838
21997
|
} else if (isMovieClipResource$1(res)) {
|
|
21839
21998
|
const resId = res.getId();
|
|
21840
|
-
if (!res.getExported() && referencedIds.size > 0 && !referencedIds.has(resId)) continue;
|
|
21999
|
+
if (selectedPublishIds.size === 0 && !res.getExported() && referencedIds.size > 0 && !referencedIds.has(resId)) continue;
|
|
21841
22000
|
await _collectMovieClipFrames(doc, res, pkg, inputs, encoder, options, logger);
|
|
21842
22001
|
} else if (isFontResource$1(res)) {
|
|
21843
22002
|
const resId = res.getId();
|
|
21844
|
-
if (!res.getExported() && referencedIds.size > 0 && !referencedIds.has(resId)) continue;
|
|
22003
|
+
if (selectedPublishIds.size === 0 && !res.getExported() && referencedIds.size > 0 && !referencedIds.has(resId)) continue;
|
|
21845
22004
|
await _collectFontTexture(doc, res, pkg, options);
|
|
21846
22005
|
}
|
|
21847
22006
|
if (inputs.length === 0) continue;
|
|
21848
|
-
const branchGroups = buildBranchAtlasGroups(doc, inputs, options);
|
|
21849
22007
|
let totalPageCount = 0;
|
|
21850
22008
|
let usedDirectOutput = false;
|
|
22009
|
+
const { autoInputs, fixedPageGroups, standaloneGroups, reservedPageIndexes } = groupStandaloneInputs(doc, inputs, options);
|
|
22010
|
+
const branchGroups = buildBranchAtlasGroups(doc, autoInputs, options);
|
|
22011
|
+
const branchPageOffsets = /* @__PURE__ */ new Map();
|
|
21851
22012
|
for (const group of branchGroups) {
|
|
21852
|
-
const directOutput = resolveDirectImageOutput(group.inputs, options);
|
|
22013
|
+
const directOutput = fixedPageGroups.length === 0 && standaloneGroups.length === 0 ? resolveDirectImageOutput(group.inputs, options) : null;
|
|
21853
22014
|
if (directOutput) {
|
|
21854
22015
|
await emitDirectImageOutput(doc, pkg, directOutput, encoder, options, logger, group.branchName, group.branchOrdinal);
|
|
21855
22016
|
usedDirectOutput = true;
|
|
21856
22017
|
totalPageCount += 1;
|
|
21857
22018
|
continue;
|
|
21858
22019
|
}
|
|
21859
|
-
const
|
|
21860
|
-
|
|
22020
|
+
const pageStart = reserveAutoPageStart(branchPageOffsets, group.branchOrdinal, reservedPageIndexes);
|
|
22021
|
+
const emittedPageCount = await emitPagedAtlasGroup(doc, pkg, allResources, group.inputs, {
|
|
22022
|
+
branchName: group.branchName,
|
|
22023
|
+
branchOrdinal: group.branchOrdinal,
|
|
22024
|
+
pageStart,
|
|
22025
|
+
fileNameAt: (pageIndex) => resolveAtlasOutputFileName(pkg, pageIndex, group.branchName),
|
|
22026
|
+
options,
|
|
22027
|
+
encoder,
|
|
22028
|
+
logger
|
|
21861
22029
|
});
|
|
21862
|
-
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
|
|
21873
|
-
|
|
21874
|
-
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
|
|
21882
|
-
|
|
21883
|
-
|
|
21884
|
-
|
|
21885
|
-
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
21889
|
-
|
|
21890
|
-
|
|
21891
|
-
|
|
21892
|
-
const rotated = pr.rotated;
|
|
21893
|
-
const sprite = doc.createSprite();
|
|
21894
|
-
sprite.setItemId(input.id);
|
|
21895
|
-
sprite.setRectX(pr.x);
|
|
21896
|
-
sprite.setRectY(pr.y);
|
|
21897
|
-
sprite.setRectWidth(packedSize.width);
|
|
21898
|
-
sprite.setRectHeight(packedSize.height);
|
|
21899
|
-
sprite.setRotated(rotated);
|
|
21900
|
-
sprite.setOffsetX(input.offsetX);
|
|
21901
|
-
sprite.setOffsetY(input.offsetY);
|
|
21902
|
-
sprite.setOriginalWidth(input.originalWidth);
|
|
21903
|
-
sprite.setOriginalHeight(input.originalHeight);
|
|
21904
|
-
sprite.setAtlas(atlasNode);
|
|
21905
|
-
atlasNode.addSprite(sprite);
|
|
21906
|
-
}
|
|
21907
|
-
for (const res of allResources) {
|
|
21908
|
-
if (!isFontResource$1(res)) continue;
|
|
21909
|
-
const alias = res.getExtras()?._fontSpriteAlias;
|
|
21910
|
-
if (!alias) continue;
|
|
21911
|
-
const imgSprite = page.outputRects.find((result) => group.inputs[result.index]?.id === alias.textureId);
|
|
21912
|
-
if (!imgSprite) continue;
|
|
21913
|
-
const imgInput = group.inputs[imgSprite.index];
|
|
21914
|
-
const fontSprite = doc.createSprite();
|
|
21915
|
-
fontSprite.setItemId(alias.fontId);
|
|
21916
|
-
fontSprite.setRectX(imgSprite.x);
|
|
21917
|
-
fontSprite.setRectY(imgSprite.y);
|
|
21918
|
-
fontSprite.setRectWidth(imgSprite.width);
|
|
21919
|
-
fontSprite.setRectHeight(imgSprite.height);
|
|
21920
|
-
fontSprite.setRotated(imgSprite.rotated);
|
|
21921
|
-
if (imgInput) {
|
|
21922
|
-
fontSprite.setOffsetX(imgInput.offsetX);
|
|
21923
|
-
fontSprite.setOffsetY(imgInput.offsetY);
|
|
21924
|
-
fontSprite.setOriginalWidth(imgInput.originalWidth);
|
|
21925
|
-
fontSprite.setOriginalHeight(imgInput.originalHeight);
|
|
21926
|
-
}
|
|
21927
|
-
fontSprite.setAtlas(atlasNode);
|
|
21928
|
-
atlasNode.addSprite(fontSprite);
|
|
21929
|
-
}
|
|
21930
|
-
}
|
|
21931
|
-
if (encoder && options.outputPath) {
|
|
21932
|
-
if (options.mkdir) await options.mkdir(options.outputPath);
|
|
21933
|
-
for (let p = 0; p < pages.length; p++) {
|
|
21934
|
-
const page = pages[p];
|
|
21935
|
-
const compositeInputs = [];
|
|
21936
|
-
for (const pr of page.outputRects) {
|
|
21937
|
-
const input = group.inputs[pr.index];
|
|
21938
|
-
if (!input) continue;
|
|
21939
|
-
if (pr.width <= 0 || pr.height <= 0 || input.width <= 0 || input.height <= 0) continue;
|
|
21940
|
-
try {
|
|
21941
|
-
let imgBuffer;
|
|
21942
|
-
if (input.trimBuffer) {
|
|
21943
|
-
imgBuffer = input.trimBuffer;
|
|
21944
|
-
if (imgBuffer.length === 0) continue;
|
|
21945
|
-
} else {
|
|
21946
|
-
if (!isImageResource$1(input.resource)) {
|
|
21947
|
-
logger.warn(`atlas: Non-image input "${input.id}" is missing inline buffer, skipping compositing.`);
|
|
21948
|
-
continue;
|
|
21949
|
-
}
|
|
21950
|
-
imgBuffer = await encoder(_resolveImagePath(input.resource, pkg, options.basePath)).toBuffer();
|
|
21951
|
-
}
|
|
21952
|
-
if (pr.rotated) imgBuffer = await encoder(imgBuffer).rotate(270).toBuffer();
|
|
21953
|
-
compositeInputs.push({
|
|
21954
|
-
input: imgBuffer,
|
|
21955
|
-
left: pr.x,
|
|
21956
|
-
top: pr.y
|
|
21957
|
-
});
|
|
21958
|
-
} catch {
|
|
21959
|
-
logger.warn(`atlas: Could not read image "${input.id}" for compositing.`);
|
|
21960
|
-
}
|
|
21961
|
-
}
|
|
21962
|
-
const atlasFileName = resolveAtlasOutputFileName(pkg, p, group.branchName);
|
|
21963
|
-
const outputFile = `${options.outputPath}/${atlasFileName}`;
|
|
21964
|
-
await encoder({ create: {
|
|
21965
|
-
width: page.width,
|
|
21966
|
-
height: page.height,
|
|
21967
|
-
channels: 4,
|
|
21968
|
-
background: {
|
|
21969
|
-
r: 0,
|
|
21970
|
-
g: 0,
|
|
21971
|
-
b: 0,
|
|
21972
|
-
alpha: 0
|
|
21973
|
-
}
|
|
21974
|
-
} }).composite(compositeInputs).png().toFile(outputFile);
|
|
21975
|
-
logger.info(`atlas: Generated ${atlasFileName} (${page.width}x${page.height}, ${page.outputRects.length} sprites)`);
|
|
21976
|
-
}
|
|
21977
|
-
}
|
|
22030
|
+
totalPageCount += emittedPageCount;
|
|
22031
|
+
branchPageOffsets.set(group.branchOrdinal, pageStart + emittedPageCount);
|
|
22032
|
+
}
|
|
22033
|
+
for (const group of fixedPageGroups) {
|
|
22034
|
+
const emittedPageCount = await emitPagedAtlasGroup(doc, pkg, allResources, group.inputs, {
|
|
22035
|
+
branchName: group.branchName,
|
|
22036
|
+
branchOrdinal: group.branchOrdinal,
|
|
22037
|
+
pageStart: group.pageIndex,
|
|
22038
|
+
forceSinglePage: true,
|
|
22039
|
+
fileNameAt: () => resolveAtlasOutputFileName(pkg, group.pageIndex, group.branchName),
|
|
22040
|
+
options,
|
|
22041
|
+
encoder,
|
|
22042
|
+
logger
|
|
22043
|
+
});
|
|
22044
|
+
totalPageCount += emittedPageCount;
|
|
22045
|
+
}
|
|
22046
|
+
const standalonePageOffsets = new Map(branchPageOffsets);
|
|
22047
|
+
for (const group of fixedPageGroups) {
|
|
22048
|
+
const nextPageIndex = group.pageIndex + 1;
|
|
22049
|
+
if (nextPageIndex > (standalonePageOffsets.get(group.branchOrdinal) ?? 0)) standalonePageOffsets.set(group.branchOrdinal, nextPageIndex);
|
|
22050
|
+
}
|
|
22051
|
+
for (const group of standaloneGroups) {
|
|
22052
|
+
const emittedPageCount = await emitStandaloneAtlasGroup(doc, pkg, group, {
|
|
22053
|
+
atlasIndexStart: standalonePageOffsets.get(group.branchOrdinal) ?? 0,
|
|
22054
|
+
options,
|
|
22055
|
+
encoder,
|
|
22056
|
+
logger
|
|
22057
|
+
});
|
|
22058
|
+
totalPageCount += emittedPageCount;
|
|
22059
|
+
standalonePageOffsets.set(group.branchOrdinal, (standalonePageOffsets.get(group.branchOrdinal) ?? 0) + emittedPageCount);
|
|
21978
22060
|
}
|
|
21979
22061
|
if (usedDirectOutput) logger.info(`atlas: Direct output for single image package "${pkg.getName()}".`);
|
|
21980
22062
|
logger.info(`atlas: Packed ${inputs.length} images into ${totalPageCount} atlas(es) for package "${pkg.getName()}".`);
|
|
@@ -22011,6 +22093,171 @@ function buildBranchAtlasGroups(doc, inputs, options) {
|
|
|
22011
22093
|
inputs: groups.get(branchName) ?? []
|
|
22012
22094
|
}));
|
|
22013
22095
|
}
|
|
22096
|
+
function reserveAutoPageStart(branchPageOffsets, branchOrdinal, reservedPageIndexes) {
|
|
22097
|
+
let pageIndex = branchPageOffsets.get(branchOrdinal) ?? 0;
|
|
22098
|
+
while (branchOrdinal === 0 && reservedPageIndexes.has(pageIndex)) pageIndex += 1;
|
|
22099
|
+
return pageIndex;
|
|
22100
|
+
}
|
|
22101
|
+
async function emitPagedAtlasGroup(doc, pkg, allResources, inputs, context) {
|
|
22102
|
+
if (inputs.length === 0) return 0;
|
|
22103
|
+
const pages = packAtlasPages(inputs, context.options, context.forceSinglePage === true);
|
|
22104
|
+
if (pages.length === 0) return 0;
|
|
22105
|
+
for (let pageOffset = 0; pageOffset < pages.length; pageOffset += 1) {
|
|
22106
|
+
const page = pages[pageOffset];
|
|
22107
|
+
const pageIndex = context.pageStart + pageOffset;
|
|
22108
|
+
const atlasNode = doc.createAtlas(`atlas${resolveAtlasIndex(context.branchOrdinal, pageIndex)}`);
|
|
22109
|
+
atlasNode.setIndex(resolveAtlasIndex(context.branchOrdinal, pageIndex));
|
|
22110
|
+
atlasNode.setFile(context.fileNameAt(pageIndex));
|
|
22111
|
+
atlasNode.setWidth(page.width);
|
|
22112
|
+
atlasNode.setHeight(page.height);
|
|
22113
|
+
pkg.addAtlas(atlasNode);
|
|
22114
|
+
attachSpritesToAtlas(doc, allResources, inputs, page.outputRects, atlasNode);
|
|
22115
|
+
await writeAtlasPageImage(pkg, inputs, page, atlasNode.getFile(), context.encoder, context.options, context.logger);
|
|
22116
|
+
}
|
|
22117
|
+
return pages.length;
|
|
22118
|
+
}
|
|
22119
|
+
async function emitStandaloneAtlasGroup(doc, pkg, group, context) {
|
|
22120
|
+
if (group.inputs.length === 0) return 0;
|
|
22121
|
+
const pages = packAtlasPages(group.inputs, context.options, true, group.sizeMode === "npot" ? {
|
|
22122
|
+
powerOfTwo: false,
|
|
22123
|
+
multipleOfFour: false,
|
|
22124
|
+
square: false
|
|
22125
|
+
} : group.sizeMode === "multipleOf4" ? {
|
|
22126
|
+
powerOfTwo: false,
|
|
22127
|
+
multipleOfFour: true,
|
|
22128
|
+
square: false
|
|
22129
|
+
} : void 0);
|
|
22130
|
+
if (pages.length === 0) return 0;
|
|
22131
|
+
for (let pageOffset = 0; pageOffset < pages.length; pageOffset += 1) {
|
|
22132
|
+
const page = pages[pageOffset];
|
|
22133
|
+
const baseFileName = resolveStandaloneAtlasOutputFileName(pkg, group.resource, group.branchName);
|
|
22134
|
+
const atlasFileName = pages.length <= 1 ? baseFileName : insertFileNameSuffix(baseFileName, `_${pageOffset}`);
|
|
22135
|
+
const atlasIndex = context.atlasIndexStart + pageOffset;
|
|
22136
|
+
const atlasNode = doc.createAtlas(`atlas${resolveAtlasIndex(group.branchOrdinal, atlasIndex)}`);
|
|
22137
|
+
atlasNode.setIndex(resolveAtlasIndex(group.branchOrdinal, atlasIndex));
|
|
22138
|
+
atlasNode.setFile(atlasFileName);
|
|
22139
|
+
const standaloneSize = resolveStandaloneAtlasSize(page.width, page.height, group.sizeMode, context.options);
|
|
22140
|
+
atlasNode.setWidth(standaloneSize.width);
|
|
22141
|
+
atlasNode.setHeight(standaloneSize.height);
|
|
22142
|
+
pkg.addAtlas(atlasNode);
|
|
22143
|
+
attachSpritesToAtlas(doc, [], group.inputs, page.outputRects, atlasNode);
|
|
22144
|
+
await writeAtlasPageImage(pkg, group.inputs, {
|
|
22145
|
+
...page,
|
|
22146
|
+
width: standaloneSize.width,
|
|
22147
|
+
height: standaloneSize.height
|
|
22148
|
+
}, atlasFileName, context.encoder, context.options, context.logger);
|
|
22149
|
+
}
|
|
22150
|
+
return pages.length;
|
|
22151
|
+
}
|
|
22152
|
+
function packAtlasPages(inputs, options, forceSinglePage, sizeOverrides) {
|
|
22153
|
+
const hasDuplicatePadding = inputs.some((input) => {
|
|
22154
|
+
return isImageResource$1(input.resource) && input.resource.getDuplicatePadding?.() === true;
|
|
22155
|
+
});
|
|
22156
|
+
return new MaxRectsPackerCompat({
|
|
22157
|
+
pot: sizeOverrides?.powerOfTwo ?? options.powerOfTwo,
|
|
22158
|
+
mof: sizeOverrides?.multipleOfFour ?? !options.powerOfTwo,
|
|
22159
|
+
padding: options.padding,
|
|
22160
|
+
rotation: options.allowRotation,
|
|
22161
|
+
minWidth: 16,
|
|
22162
|
+
minHeight: 16,
|
|
22163
|
+
maxWidth: options.maxSize,
|
|
22164
|
+
maxHeight: options.maxSize,
|
|
22165
|
+
square: sizeOverrides?.square ?? options.square,
|
|
22166
|
+
fast: options.fast,
|
|
22167
|
+
edgePadding: false,
|
|
22168
|
+
duplicatePadding: hasDuplicatePadding,
|
|
22169
|
+
multiPage: forceSinglePage ? false : options.multiPage,
|
|
22170
|
+
preserveInputOrderOnTie: options.preserveInputOrderOnTie
|
|
22171
|
+
}).pack(inputs.map((input, index) => inputToCompatRect(input, index))) ?? [];
|
|
22172
|
+
}
|
|
22173
|
+
function attachSpritesToAtlas(doc, allResources, inputs, outputRects, atlasNode) {
|
|
22174
|
+
for (const packedRect of outputRects) {
|
|
22175
|
+
const input = inputs[packedRect.index];
|
|
22176
|
+
if (!input) continue;
|
|
22177
|
+
const packedSize = resolvePackedRectSize(input, packedRect.width, packedRect.height, packedRect.rotated);
|
|
22178
|
+
const sprite = doc.createSprite();
|
|
22179
|
+
sprite.setItemId(input.id);
|
|
22180
|
+
sprite.setRectX(packedRect.x);
|
|
22181
|
+
sprite.setRectY(packedRect.y);
|
|
22182
|
+
sprite.setRectWidth(packedSize.width);
|
|
22183
|
+
sprite.setRectHeight(packedSize.height);
|
|
22184
|
+
sprite.setRotated(packedRect.rotated);
|
|
22185
|
+
sprite.setOffsetX(input.offsetX);
|
|
22186
|
+
sprite.setOffsetY(input.offsetY);
|
|
22187
|
+
sprite.setOriginalWidth(input.originalWidth);
|
|
22188
|
+
sprite.setOriginalHeight(input.originalHeight);
|
|
22189
|
+
sprite.setAtlas(atlasNode);
|
|
22190
|
+
atlasNode.addSprite(sprite);
|
|
22191
|
+
}
|
|
22192
|
+
for (const resource of allResources) {
|
|
22193
|
+
if (!isFontResource$1(resource)) continue;
|
|
22194
|
+
const alias = resource.getExtras()?._fontSpriteAlias;
|
|
22195
|
+
if (!alias) continue;
|
|
22196
|
+
const imageSprite = outputRects.find((result) => inputs[result.index]?.id === alias.textureId);
|
|
22197
|
+
if (!imageSprite) continue;
|
|
22198
|
+
const imageInput = inputs[imageSprite.index];
|
|
22199
|
+
const fontSprite = doc.createSprite();
|
|
22200
|
+
fontSprite.setItemId(alias.fontId);
|
|
22201
|
+
fontSprite.setRectX(imageSprite.x);
|
|
22202
|
+
fontSprite.setRectY(imageSprite.y);
|
|
22203
|
+
fontSprite.setRectWidth(imageSprite.width);
|
|
22204
|
+
fontSprite.setRectHeight(imageSprite.height);
|
|
22205
|
+
fontSprite.setRotated(imageSprite.rotated);
|
|
22206
|
+
if (imageInput) {
|
|
22207
|
+
fontSprite.setOffsetX(imageInput.offsetX);
|
|
22208
|
+
fontSprite.setOffsetY(imageInput.offsetY);
|
|
22209
|
+
fontSprite.setOriginalWidth(imageInput.originalWidth);
|
|
22210
|
+
fontSprite.setOriginalHeight(imageInput.originalHeight);
|
|
22211
|
+
}
|
|
22212
|
+
fontSprite.setAtlas(atlasNode);
|
|
22213
|
+
atlasNode.addSprite(fontSprite);
|
|
22214
|
+
}
|
|
22215
|
+
}
|
|
22216
|
+
async function writeAtlasPageImage(pkg, inputs, page, atlasFileName, encoder, options, logger) {
|
|
22217
|
+
if (!encoder || !options.outputPath) return;
|
|
22218
|
+
if (options.mkdir) await options.mkdir(options.outputPath);
|
|
22219
|
+
const compositeInputs = [];
|
|
22220
|
+
for (const packedRect of page.outputRects) {
|
|
22221
|
+
const input = inputs[packedRect.index];
|
|
22222
|
+
if (!input) continue;
|
|
22223
|
+
if (packedRect.width <= 0 || packedRect.height <= 0 || input.width <= 0 || input.height <= 0) continue;
|
|
22224
|
+
try {
|
|
22225
|
+
let imageBuffer;
|
|
22226
|
+
if (input.trimBuffer) {
|
|
22227
|
+
imageBuffer = input.trimBuffer;
|
|
22228
|
+
if (imageBuffer.length === 0) continue;
|
|
22229
|
+
} else if (input.rasterizedBuffer) imageBuffer = input.rasterizedBuffer;
|
|
22230
|
+
else {
|
|
22231
|
+
if (!isImageResource$1(input.resource)) {
|
|
22232
|
+
logger.warn(`atlas: Non-image input "${input.id}" is missing inline buffer, skipping compositing.`);
|
|
22233
|
+
continue;
|
|
22234
|
+
}
|
|
22235
|
+
imageBuffer = await encoder(_resolveImagePath(input.resource, pkg, options.basePath)).toBuffer();
|
|
22236
|
+
}
|
|
22237
|
+
if (packedRect.rotated) imageBuffer = await encoder(imageBuffer).rotate(270).toBuffer();
|
|
22238
|
+
compositeInputs.push({
|
|
22239
|
+
input: imageBuffer,
|
|
22240
|
+
left: packedRect.x,
|
|
22241
|
+
top: packedRect.y
|
|
22242
|
+
});
|
|
22243
|
+
} catch {
|
|
22244
|
+
logger.warn(`atlas: Could not read image "${input.id}" for compositing.`);
|
|
22245
|
+
}
|
|
22246
|
+
}
|
|
22247
|
+
const outputFile = `${options.outputPath}/${atlasFileName}`;
|
|
22248
|
+
await encoder({ create: {
|
|
22249
|
+
width: page.width,
|
|
22250
|
+
height: page.height,
|
|
22251
|
+
channels: 4,
|
|
22252
|
+
background: {
|
|
22253
|
+
r: 0,
|
|
22254
|
+
g: 0,
|
|
22255
|
+
b: 0,
|
|
22256
|
+
alpha: 0
|
|
22257
|
+
}
|
|
22258
|
+
} }).composite(compositeInputs).toFile(outputFile);
|
|
22259
|
+
logger.info(`atlas: Generated ${atlasFileName} (${page.width}x${page.height}, ${page.outputRects.length} sprites)`);
|
|
22260
|
+
}
|
|
22014
22261
|
function inputToCompatRect(input, index) {
|
|
22015
22262
|
const duplicatePadding = isImageResource$1(input.resource) && input.resource.getDuplicatePadding?.() === true;
|
|
22016
22263
|
return {
|
|
@@ -22125,14 +22372,47 @@ function resolveAtlasOutputFileName(pkg, pageIndex, branchName) {
|
|
|
22125
22372
|
const suffix = branchName ? `_${branchName}` : "";
|
|
22126
22373
|
return `${pkg.getPublishName() || pkg.getName()}_atlas${pageIndex}${suffix}.png`;
|
|
22127
22374
|
}
|
|
22375
|
+
function resolveStandaloneAtlasOutputFileName(pkg, resource, branchName) {
|
|
22376
|
+
const baseName = `${pkg.getPublishName() || pkg.getName()}_atlas_${getPublishedItemId(resource)}`;
|
|
22377
|
+
const suffix = branchName ? `_${branchName}` : "";
|
|
22378
|
+
if (isImageResource$1(resource)) return `${baseName}${suffix}${extname$1(resolveImageFileName$1(resource)) || ".png"}`;
|
|
22379
|
+
return `${baseName}${suffix}.png`;
|
|
22380
|
+
}
|
|
22381
|
+
function resolveStandaloneAtlasSize(width, height, sizeMode, options) {
|
|
22382
|
+
if (sizeMode === "npot") return {
|
|
22383
|
+
width,
|
|
22384
|
+
height
|
|
22385
|
+
};
|
|
22386
|
+
if (sizeMode === "multipleOf4") return {
|
|
22387
|
+
width: roundUpToMultiple(width, 4),
|
|
22388
|
+
height: roundUpToMultiple(height, 4)
|
|
22389
|
+
};
|
|
22390
|
+
return resolveDirectOutputAtlasSize(width, height, options);
|
|
22391
|
+
}
|
|
22128
22392
|
function resolveImageFileName$1(resource) {
|
|
22129
22393
|
const extras = resource.getExtras();
|
|
22130
22394
|
return resource.getFileName() || extras._fileName || resource.getName();
|
|
22131
22395
|
}
|
|
22396
|
+
function extname$1(fileName) {
|
|
22397
|
+
const normalized = fileName.replace(/\\/g, "/");
|
|
22398
|
+
const lastSlash = normalized.lastIndexOf("/");
|
|
22399
|
+
const lastDot = normalized.lastIndexOf(".");
|
|
22400
|
+
if (lastDot <= lastSlash) return "";
|
|
22401
|
+
return normalized.slice(lastDot);
|
|
22402
|
+
}
|
|
22403
|
+
function insertFileNameSuffix(fileName, suffix) {
|
|
22404
|
+
const extension = extname$1(fileName);
|
|
22405
|
+
if (!extension) return `${fileName}${suffix}`;
|
|
22406
|
+
return `${fileName.slice(0, -extension.length)}${suffix}${extension}`;
|
|
22407
|
+
}
|
|
22132
22408
|
function nextPow2(value) {
|
|
22133
22409
|
if (value <= 1) return 1;
|
|
22134
22410
|
return 2 ** Math.ceil(Math.log2(value));
|
|
22135
22411
|
}
|
|
22412
|
+
function roundUpToMultiple(value, base) {
|
|
22413
|
+
if (value <= 0) return 0;
|
|
22414
|
+
return Math.ceil(value / base) * base;
|
|
22415
|
+
}
|
|
22136
22416
|
function sortResourcesByOrder(resources, orderMap, inputOrderMap) {
|
|
22137
22417
|
const ordered = [...resources];
|
|
22138
22418
|
ordered.sort((left, right) => {
|
|
@@ -22148,14 +22428,71 @@ function sortResourcesByOrder(resources, orderMap, inputOrderMap) {
|
|
|
22148
22428
|
});
|
|
22149
22429
|
return ordered;
|
|
22150
22430
|
}
|
|
22431
|
+
function getResourceTextureSetMode(resource) {
|
|
22432
|
+
if (isImageResource$1(resource)) return parseTextureSetMode(resource.getTextureSetMode?.());
|
|
22433
|
+
return parseTextureSetMode(resource.getTextureSetMode?.());
|
|
22434
|
+
}
|
|
22435
|
+
function groupStandaloneInputs(doc, inputs, options) {
|
|
22436
|
+
const autoInputs = [];
|
|
22437
|
+
const fixedInputsByPage = /* @__PURE__ */ new Map();
|
|
22438
|
+
const standaloneGroups = /* @__PURE__ */ new Map();
|
|
22439
|
+
const reservedPageIndexes = /* @__PURE__ */ new Set();
|
|
22440
|
+
const discoveredBranchNames = [...new Set(inputs.map((input) => getInputBranchName(input)).filter((branchName) => !!branchName))];
|
|
22441
|
+
const orderedBranchNames = doc.getRoot().listBranches().filter((branchName) => discoveredBranchNames.includes(branchName));
|
|
22442
|
+
for (const branchName of discoveredBranchNames) if (!orderedBranchNames.includes(branchName)) orderedBranchNames.push(branchName);
|
|
22443
|
+
const branchOrdinalByName = /* @__PURE__ */ new Map();
|
|
22444
|
+
branchOrdinalByName.set("", 0);
|
|
22445
|
+
if (options.separatedAtlasForBranch) {
|
|
22446
|
+
let ordinal = 1;
|
|
22447
|
+
for (const branchName of orderedBranchNames) branchOrdinalByName.set(branchName, ordinal++);
|
|
22448
|
+
} else for (const branchName of orderedBranchNames) branchOrdinalByName.set(branchName, 0);
|
|
22449
|
+
for (const input of inputs) {
|
|
22450
|
+
const branchName = getInputBranchName(input);
|
|
22451
|
+
const branchOrdinal = branchOrdinalByName.get(branchName) ?? 0;
|
|
22452
|
+
const mode = getResourceTextureSetMode(input.resource);
|
|
22453
|
+
if (mode.kind === "standalone") {
|
|
22454
|
+
const key = `${branchName}\u0000${getPublishedItemId(input.resource)}`;
|
|
22455
|
+
const existing = standaloneGroups.get(key);
|
|
22456
|
+
if (existing) existing.inputs.push(input);
|
|
22457
|
+
else standaloneGroups.set(key, {
|
|
22458
|
+
resource: input.resource,
|
|
22459
|
+
branchName,
|
|
22460
|
+
branchOrdinal,
|
|
22461
|
+
sizeMode: mode.sizeMode,
|
|
22462
|
+
inputs: [input]
|
|
22463
|
+
});
|
|
22464
|
+
continue;
|
|
22465
|
+
}
|
|
22466
|
+
if (mode.kind === "page") {
|
|
22467
|
+
reservedPageIndexes.add(mode.pageIndex);
|
|
22468
|
+
const key = `${branchName}\u0000${mode.pageIndex}`;
|
|
22469
|
+
const existing = fixedInputsByPage.get(key);
|
|
22470
|
+
if (existing) existing.inputs.push(input);
|
|
22471
|
+
else fixedInputsByPage.set(key, {
|
|
22472
|
+
pageIndex: mode.pageIndex,
|
|
22473
|
+
branchName,
|
|
22474
|
+
branchOrdinal,
|
|
22475
|
+
inputs: [input]
|
|
22476
|
+
});
|
|
22477
|
+
continue;
|
|
22478
|
+
}
|
|
22479
|
+
autoInputs.push(input);
|
|
22480
|
+
}
|
|
22481
|
+
return {
|
|
22482
|
+
autoInputs,
|
|
22483
|
+
fixedPageGroups: [...fixedInputsByPage.values()].sort((left, right) => left.branchOrdinal - right.branchOrdinal || left.pageIndex - right.pageIndex),
|
|
22484
|
+
standaloneGroups: [...standaloneGroups.values()].sort((left, right) => left.branchOrdinal - right.branchOrdinal || getPublishedItemId(left.resource).localeCompare(getPublishedItemId(right.resource))),
|
|
22485
|
+
reservedPageIndexes
|
|
22486
|
+
};
|
|
22487
|
+
}
|
|
22151
22488
|
/**
|
|
22152
22489
|
* Trim transparent edges from an image using sharp.
|
|
22153
22490
|
* Returns the trimmed buffer, dimensions, and offsets.
|
|
22154
22491
|
* Falls back to the original image if trim fails (e.g. no alpha channel, no transparent edges).
|
|
22155
22492
|
*/
|
|
22156
|
-
async function _trimImage(encoder,
|
|
22493
|
+
async function _trimImage(encoder, input, originalWidth, originalHeight) {
|
|
22157
22494
|
try {
|
|
22158
|
-
const trimResult = await encoder(
|
|
22495
|
+
const trimResult = await encoder(input).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
22159
22496
|
if (!isResolvedBuffer(trimResult)) throw new Error("atlas: encoder raw alpha trim did not return resolved metadata.");
|
|
22160
22497
|
const { data, info } = trimResult;
|
|
22161
22498
|
const width = info.width;
|
|
@@ -22184,7 +22521,7 @@ async function _trimImage(encoder, filePath, originalWidth, originalHeight) {
|
|
|
22184
22521
|
const trimmedWidth = maxX - minX + 1;
|
|
22185
22522
|
const trimmedHeight = maxY - minY + 1;
|
|
22186
22523
|
return {
|
|
22187
|
-
buffer: await encoder(
|
|
22524
|
+
buffer: await encoder(input).extract({
|
|
22188
22525
|
left: minX,
|
|
22189
22526
|
top: minY,
|
|
22190
22527
|
width: trimmedWidth,
|
|
@@ -22199,7 +22536,7 @@ async function _trimImage(encoder, filePath, originalWidth, originalHeight) {
|
|
|
22199
22536
|
};
|
|
22200
22537
|
} catch {
|
|
22201
22538
|
return {
|
|
22202
|
-
buffer: await encoder(
|
|
22539
|
+
buffer: await encoder(input).png().toBuffer(),
|
|
22203
22540
|
width: originalWidth,
|
|
22204
22541
|
height: originalHeight,
|
|
22205
22542
|
offsetX: 0,
|
|
@@ -22223,7 +22560,10 @@ function _resolveImagePath(resource, pkg, basePath) {
|
|
|
22223
22560
|
async function _collectImage(resource, pkg, inputs, encoder, options, doTrim, logger) {
|
|
22224
22561
|
let origW = resource.getWidth() ?? 0;
|
|
22225
22562
|
let origH = resource.getHeight() ?? 0;
|
|
22563
|
+
const declaredWidth = origW;
|
|
22564
|
+
const declaredHeight = origH;
|
|
22226
22565
|
let sourceHasAlpha = false;
|
|
22566
|
+
let rasterizedBuffer;
|
|
22227
22567
|
if (encoder && options.basePath) {
|
|
22228
22568
|
const filePath = _resolveImagePath(resource, pkg, options.basePath);
|
|
22229
22569
|
try {
|
|
@@ -22235,6 +22575,10 @@ async function _collectImage(resource, pkg, inputs, encoder, options, doTrim, lo
|
|
|
22235
22575
|
resource.setHeight(origH);
|
|
22236
22576
|
}
|
|
22237
22577
|
sourceHasAlpha = metadata.hasAlpha === true || metadata.channels === 4;
|
|
22578
|
+
if (/\.svg$/i.test(resolveImageFileName$1(resource)) && declaredWidth > 0 && declaredHeight > 0) {
|
|
22579
|
+
rasterizedBuffer = await encoder(filePath).resize(declaredWidth, declaredHeight, { fit: "fill" }).png().toBuffer();
|
|
22580
|
+
sourceHasAlpha = true;
|
|
22581
|
+
}
|
|
22238
22582
|
} catch {
|
|
22239
22583
|
if (origW === 0 || origH === 0) {
|
|
22240
22584
|
logger.warn(`atlas: Could not read image "${filePath}", skipping.`);
|
|
@@ -22248,7 +22592,7 @@ async function _collectImage(resource, pkg, inputs, encoder, options, doTrim, lo
|
|
|
22248
22592
|
if (doTrim && sourceHasAlpha && options.basePath && encoder) {
|
|
22249
22593
|
const filePath = _resolveImagePath(resource, pkg, options.basePath);
|
|
22250
22594
|
try {
|
|
22251
|
-
const trimResult = await _trimImage(encoder, filePath, origW, origH);
|
|
22595
|
+
const trimResult = await _trimImage(encoder, rasterizedBuffer ?? filePath, origW, origH);
|
|
22252
22596
|
packW = trimResult.width;
|
|
22253
22597
|
packH = trimResult.height;
|
|
22254
22598
|
offX = trimResult.offsetX;
|
|
@@ -22268,6 +22612,7 @@ async function _collectImage(resource, pkg, inputs, encoder, options, doTrim, lo
|
|
|
22268
22612
|
offsetY: offY,
|
|
22269
22613
|
resource,
|
|
22270
22614
|
trimBuffer: trimBuf,
|
|
22615
|
+
rasterizedBuffer,
|
|
22271
22616
|
sourceKind: "image"
|
|
22272
22617
|
});
|
|
22273
22618
|
}
|
|
@@ -22700,6 +23045,62 @@ const FGUI_TYPESCRIPT_BINDER_TEMPLATE = `{{generatedMark}}
|
|
|
22700
23045
|
}
|
|
22701
23046
|
`;
|
|
22702
23047
|
//#endregion
|
|
23048
|
+
//#region ../functions/src/plugins/loader.ts
|
|
23049
|
+
const importNative = new Function("id", "return import(id)");
|
|
23050
|
+
async function loadPlugins(doc, pluginsDir) {
|
|
23051
|
+
if (!pluginsDir) return [];
|
|
23052
|
+
const fs = await importNative("node:fs/promises");
|
|
23053
|
+
const path = await importNative("node:path");
|
|
23054
|
+
let entries;
|
|
23055
|
+
try {
|
|
23056
|
+
entries = await fs.readdir(pluginsDir, { withFileTypes: true });
|
|
23057
|
+
} catch {
|
|
23058
|
+
return [];
|
|
23059
|
+
}
|
|
23060
|
+
const plugins = [];
|
|
23061
|
+
for (const entry of entries) {
|
|
23062
|
+
if (!entry.isDirectory()) continue;
|
|
23063
|
+
const pluginDir = path.join(pluginsDir, entry.name);
|
|
23064
|
+
try {
|
|
23065
|
+
const manifest = await readPluginManifest(fs, path, pluginDir);
|
|
23066
|
+
if (!manifest) continue;
|
|
23067
|
+
const plugin = await loadPlugin(resolvePluginMain(path, pluginDir, manifest));
|
|
23068
|
+
plugins.push({
|
|
23069
|
+
name: manifest.name,
|
|
23070
|
+
plugin
|
|
23071
|
+
});
|
|
23072
|
+
} catch (error) {
|
|
23073
|
+
doc.getLogger().warn(`publish: Plugin "${entry.name}" was skipped: ${formatPluginError(error)}`);
|
|
23074
|
+
}
|
|
23075
|
+
}
|
|
23076
|
+
return plugins;
|
|
23077
|
+
}
|
|
23078
|
+
function formatPluginError(error) {
|
|
23079
|
+
return error instanceof Error ? error.message : String(error);
|
|
23080
|
+
}
|
|
23081
|
+
async function readPluginManifest(fs, path, pluginDir) {
|
|
23082
|
+
const manifestPath = path.join(pluginDir, "package.json");
|
|
23083
|
+
const content = await fs.readFile(manifestPath, "utf-8");
|
|
23084
|
+
const manifest = JSON.parse(content);
|
|
23085
|
+
if (!manifest.name) throw new Error(`Codegen plugin at ${pluginDir} is missing package.json name.`);
|
|
23086
|
+
if (!manifest.main) throw new Error(`Codegen plugin "${manifest.name}" is missing package.json main.`);
|
|
23087
|
+
return manifest;
|
|
23088
|
+
}
|
|
23089
|
+
function resolvePluginMain(path, pluginDir, manifest) {
|
|
23090
|
+
const mainPath = path.resolve(pluginDir, manifest.main);
|
|
23091
|
+
const relative = path.relative(pluginDir, mainPath);
|
|
23092
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) throw new Error(`Codegen plugin "${manifest.name}" main must resolve inside its plugin directory.`);
|
|
23093
|
+
return mainPath;
|
|
23094
|
+
}
|
|
23095
|
+
async function loadPlugin(mainPath) {
|
|
23096
|
+
const mod = await createJiti(import.meta.url).import(mainPath);
|
|
23097
|
+
const defaultExport = mod.default;
|
|
23098
|
+
return isObject(defaultExport) ? defaultExport : mod;
|
|
23099
|
+
}
|
|
23100
|
+
function isObject(value) {
|
|
23101
|
+
return value !== null && typeof value === "object";
|
|
23102
|
+
}
|
|
23103
|
+
//#endregion
|
|
22703
23104
|
//#region ../functions/src/codegen.ts
|
|
22704
23105
|
const AUTO_GENERATED_CODE_MARK = "/** This is an automatically generated class by FairyGUI. Please do not modify it. **/";
|
|
22705
23106
|
const DEFAULT_CLASS_NAME_PREFIX = "UI_";
|
|
@@ -22735,6 +23136,18 @@ async function publishCodeGeneration(doc, options) {
|
|
|
22735
23136
|
const logger = doc.getLogger();
|
|
22736
23137
|
const settings = resolveCodeGenerationSettings(doc);
|
|
22737
23138
|
if (!settings.allowGenCode) return;
|
|
23139
|
+
const plugins = options.plugins?.filter((plugin) => typeof plugin.plugin.genCode === "function") ?? [];
|
|
23140
|
+
if (plugins.length > 0) {
|
|
23141
|
+
let handled = false;
|
|
23142
|
+
for (const plugin of plugins) try {
|
|
23143
|
+
await plugin.plugin.genCode(doc, settings, options);
|
|
23144
|
+
handled = true;
|
|
23145
|
+
logger.info(`publish: Generated code using plugin "${plugin.name}"`);
|
|
23146
|
+
} catch (error) {
|
|
23147
|
+
logger.warn(`publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`);
|
|
23148
|
+
}
|
|
23149
|
+
if (handled) return;
|
|
23150
|
+
}
|
|
22738
23151
|
for (const pkg of options.packages) {
|
|
22739
23152
|
if (!pkg.getGenCode()) continue;
|
|
22740
23153
|
const plan = resolvePackageCodegenPlan(pkg, settings, options);
|
|
@@ -22833,9 +23246,9 @@ async function cleanupGeneratedFiles(directory, fs, extension = ".cs") {
|
|
|
22833
23246
|
}
|
|
22834
23247
|
}
|
|
22835
23248
|
function buildCodegenClasses(doc, pkg, plan) {
|
|
22836
|
-
const
|
|
23249
|
+
const codegenComponents = pkg.listComponents().sort((left, right) => left.getId().localeCompare(right.getId()));
|
|
22837
23250
|
const generatedById = /* @__PURE__ */ new Map();
|
|
22838
|
-
for (const component of
|
|
23251
|
+
for (const component of codegenComponents) {
|
|
22839
23252
|
const encodedClassName = `${plan.settings.classNamePrefix}${normalizeTypeName(component.getName()) || "Component"}`;
|
|
22840
23253
|
generatedById.set(component.getId(), {
|
|
22841
23254
|
classId: component.getId(),
|
|
@@ -22848,7 +23261,13 @@ function buildCodegenClasses(doc, pkg, plan) {
|
|
|
22848
23261
|
members: []
|
|
22849
23262
|
});
|
|
22850
23263
|
}
|
|
22851
|
-
for (const component of
|
|
23264
|
+
for (const component of codegenComponents) {
|
|
23265
|
+
const classInfo = generatedById.get(component.getId());
|
|
23266
|
+
if (!classInfo) continue;
|
|
23267
|
+
classInfo.members = buildCodegenMembers(doc, pkg, component, plan, generatedById);
|
|
23268
|
+
}
|
|
23269
|
+
for (const [componentId, classInfo] of generatedById) if (classInfo.members.every((member) => member.ignored)) generatedById.delete(componentId);
|
|
23270
|
+
for (const component of codegenComponents) {
|
|
22852
23271
|
const classInfo = generatedById.get(component.getId());
|
|
22853
23272
|
if (!classInfo) continue;
|
|
22854
23273
|
classInfo.members = buildCodegenMembers(doc, pkg, component, plan, generatedById);
|
|
@@ -22862,7 +23281,12 @@ function buildCodegenMembers(doc, pkg, component, plan, generatedById) {
|
|
|
22862
23281
|
let childIndex = 0;
|
|
22863
23282
|
let transitionIndex = 0;
|
|
22864
23283
|
for (const controller of component.listControllers()) members.push(createMember(ownerType, "controller", "Controller", controller.getName(), controllerIndex++, plan));
|
|
22865
|
-
for (const child of component.listChildren())
|
|
23284
|
+
for (const child of component.listChildren()) {
|
|
23285
|
+
if (!isRuntimeChild(child)) continue;
|
|
23286
|
+
const index = childIndex++;
|
|
23287
|
+
const resolvedChild = resolveChildType(doc, pkg, child, generatedById);
|
|
23288
|
+
members.push(createMember(ownerType, "child", resolvedChild.type, child.getName(), index, plan, resolvedChild.referencedComponent));
|
|
23289
|
+
}
|
|
22866
23290
|
for (const transition of component.listTransitions()) members.push(createMember(ownerType, "transition", "Transition", transition.getName(), transitionIndex++, plan));
|
|
22867
23291
|
const usedNames = /* @__PURE__ */ new Map();
|
|
22868
23292
|
for (const member of members) {
|
|
@@ -22874,7 +23298,10 @@ function buildCodegenMembers(doc, pkg, component, plan, generatedById) {
|
|
|
22874
23298
|
}
|
|
22875
23299
|
return members;
|
|
22876
23300
|
}
|
|
22877
|
-
function
|
|
23301
|
+
function isRuntimeChild(child) {
|
|
23302
|
+
return child.propertyType !== "GGroup" || child.getAdvanced?.() === true;
|
|
23303
|
+
}
|
|
23304
|
+
function createMember(ownerType, kind, type, originalName, index, plan, referencedComponent) {
|
|
22878
23305
|
const ignored = plan.settings.ignoreNoname && isDefaultMemberName(ownerType, kind, originalName);
|
|
22879
23306
|
return {
|
|
22880
23307
|
index,
|
|
@@ -22882,30 +23309,41 @@ function createMember(ownerType, kind, type, originalName, index, plan) {
|
|
|
22882
23309
|
name: applyMemberNamePrefix(originalName, plan.settings.memberNamePrefix),
|
|
22883
23310
|
originalName,
|
|
22884
23311
|
type,
|
|
22885
|
-
ignored
|
|
23312
|
+
ignored,
|
|
23313
|
+
referencedComponent
|
|
22886
23314
|
};
|
|
22887
23315
|
}
|
|
22888
23316
|
function resolveChildType(doc, pkg, child, generatedById) {
|
|
22889
23317
|
const src = child.getSrc?.();
|
|
22890
23318
|
if (src) {
|
|
22891
|
-
|
|
22892
|
-
if (
|
|
23319
|
+
let referencedComponent = null;
|
|
23320
|
+
if (src.startsWith("ui://")) {
|
|
23321
|
+
const rest = src.slice(5);
|
|
23322
|
+
const pkgId = rest.slice(0, 8);
|
|
23323
|
+
const resourceId = rest.slice(8);
|
|
23324
|
+
const targetPackage = doc.getRoot().listPackages().find((candidate) => candidate.getId() === pkgId);
|
|
23325
|
+
const targetResource = targetPackage?.getResourceById(resourceId);
|
|
23326
|
+
if (targetPackage && targetResource?.propertyType === "Component") referencedComponent = {
|
|
23327
|
+
component: targetResource,
|
|
23328
|
+
package: targetPackage
|
|
23329
|
+
};
|
|
23330
|
+
} else {
|
|
23331
|
+
const packageId = child.getPackageId?.();
|
|
23332
|
+
const targetPackage = packageId ? doc.getRoot().listPackages().find((candidate) => candidate.getId() === packageId) : pkg;
|
|
23333
|
+
const targetResource = targetPackage?.getResourceById(src);
|
|
23334
|
+
if (targetPackage && targetResource?.propertyType === "Component") referencedComponent = {
|
|
23335
|
+
component: targetResource,
|
|
23336
|
+
package: targetPackage
|
|
23337
|
+
};
|
|
23338
|
+
}
|
|
23339
|
+
if (referencedComponent) return {
|
|
23340
|
+
type: (referencedComponent.package === pkg ? generatedById.get(referencedComponent.component.getId()) : void 0)?.encodedClassName ?? resolveComponentBaseType(referencedComponent.component),
|
|
23341
|
+
referencedComponent
|
|
23342
|
+
};
|
|
22893
23343
|
}
|
|
22894
23344
|
const instanceExtType = child.getInstanceExtType?.();
|
|
22895
|
-
if (instanceExtType) return `G${instanceExtType}
|
|
22896
|
-
return child.propertyType;
|
|
22897
|
-
}
|
|
22898
|
-
function resolveChildSourceComponent(doc, pkg, src) {
|
|
22899
|
-
if (!src) return null;
|
|
22900
|
-
if (src.startsWith("ui://")) {
|
|
22901
|
-
const rest = src.slice(5);
|
|
22902
|
-
const pkgId = rest.slice(0, 8);
|
|
22903
|
-
const resourceId = rest.slice(8);
|
|
22904
|
-
const targetResource = doc.getRoot().listPackages().find((candidate) => candidate.getId() === pkgId)?.getResourceById(resourceId);
|
|
22905
|
-
return targetResource?.propertyType === "Component" ? targetResource : null;
|
|
22906
|
-
}
|
|
22907
|
-
const localResource = pkg.getResourceById(src);
|
|
22908
|
-
return localResource?.propertyType === "Component" ? localResource : null;
|
|
23345
|
+
if (instanceExtType) return { type: `G${instanceExtType}` };
|
|
23346
|
+
return { type: child.propertyType };
|
|
22909
23347
|
}
|
|
22910
23348
|
function resolveComponentBaseType(component) {
|
|
22911
23349
|
const extensionType = component.getExtensionType();
|
|
@@ -22976,21 +23414,21 @@ function renderFguiTypescriptMemberAssignment(member, getMemberByName, variant)
|
|
|
22976
23414
|
return getMemberByName ? `\t\tthis.${member.name} = <${translatedType}><any>(this.getChild("${escapeTypeScriptString(member.originalName)}"));` : `\t\tthis.${member.name} = <${translatedType}><any>(this.getChildAt(${member.index}));`;
|
|
22977
23415
|
}
|
|
22978
23416
|
function resolveCodePath(codePath, basePath, fs) {
|
|
22979
|
-
if (isAbsolutePath(codePath)) return trimTrailingSlashes$
|
|
23417
|
+
if (isAbsolutePath(codePath)) return trimTrailingSlashes$2(codePath);
|
|
22980
23418
|
const projectBasePath = resolveProjectBasePath(basePath);
|
|
22981
|
-
return projectBasePath ? trimTrailingSlashes$
|
|
23419
|
+
return projectBasePath ? trimTrailingSlashes$2(fs.join(projectBasePath, codePath)) : trimTrailingSlashes$2(codePath);
|
|
22982
23420
|
}
|
|
22983
23421
|
function resolveProjectBasePath(basePath) {
|
|
22984
23422
|
if (!basePath) return "";
|
|
22985
|
-
const normalized = trimTrailingSlashes$
|
|
23423
|
+
const normalized = trimTrailingSlashes$2(basePath);
|
|
22986
23424
|
const assetsMatch = normalized.match(/^(.*)[/\\]assets(?:_[^/\\]+)?$/i);
|
|
22987
23425
|
if (assetsMatch?.[1]) return assetsMatch[1];
|
|
22988
23426
|
return dirname$2(normalized);
|
|
22989
23427
|
}
|
|
22990
23428
|
function dirname$2(filePath) {
|
|
22991
|
-
return trimTrailingSlashes$
|
|
23429
|
+
return trimTrailingSlashes$2(filePath).match(/^(.*)[/\\][^/\\]+$/)?.[1] ?? "";
|
|
22992
23430
|
}
|
|
22993
|
-
function trimTrailingSlashes$
|
|
23431
|
+
function trimTrailingSlashes$2(value) {
|
|
22994
23432
|
return value.replace(/[/\\]+$/, "");
|
|
22995
23433
|
}
|
|
22996
23434
|
function isAbsolutePath(value) {
|
|
@@ -22999,9 +23437,15 @@ function isAbsolutePath(value) {
|
|
|
22999
23437
|
function isDefaultMemberName(ownerType, kind, name) {
|
|
23000
23438
|
if (kind === "controller") return (ownerType === "GButton" || ownerType === "GComboBox") && name === "button";
|
|
23001
23439
|
if (kind === "transition") return false;
|
|
23002
|
-
if (ownerType === "GButton" || ownerType === "GLabel" || ownerType === "GComboBox")
|
|
23003
|
-
|
|
23004
|
-
|
|
23440
|
+
if (ownerType === "GButton" || ownerType === "GLabel" || ownerType === "GComboBox") {
|
|
23441
|
+
if (name === "title" || name === "icon") return true;
|
|
23442
|
+
}
|
|
23443
|
+
if (ownerType === "GProgressBar") {
|
|
23444
|
+
if (name === "bar" || name === "bar_v" || name === "title" || name === "ani") return true;
|
|
23445
|
+
}
|
|
23446
|
+
if (ownerType === "GSlider") {
|
|
23447
|
+
if (name === "bar" || name === "bar_v" || name === "grip" || name === "title" || name === "ani") return true;
|
|
23448
|
+
}
|
|
23005
23449
|
return /^n\d+(?:_.*)?$/i.test(name);
|
|
23006
23450
|
}
|
|
23007
23451
|
function applyMemberNamePrefix(name, prefix) {
|
|
@@ -23290,11 +23734,11 @@ function inferPackageName(fileName) {
|
|
|
23290
23734
|
if (/\.fui$/i.test(fileName)) return fileName.replace(/\.fui$/i, "");
|
|
23291
23735
|
return fileName.replace(/\.bin$/i, "");
|
|
23292
23736
|
}
|
|
23293
|
-
function trimTrailingSlashes(value) {
|
|
23737
|
+
function trimTrailingSlashes$1(value) {
|
|
23294
23738
|
return value.replace(/[/\\]+$/, "");
|
|
23295
23739
|
}
|
|
23296
23740
|
function normalizeComparablePath(value) {
|
|
23297
|
-
const normalized = trimTrailingSlashes(value).replace(/\\/g, "/");
|
|
23741
|
+
const normalized = trimTrailingSlashes$1(value).replace(/\\/g, "/");
|
|
23298
23742
|
const driveMatch = normalized.match(/^([a-z]:)(?:\/(.*))?$/i);
|
|
23299
23743
|
const drivePrefix = driveMatch?.[1].toLowerCase() ?? "";
|
|
23300
23744
|
const remainder = driveMatch ? driveMatch[2] ?? "" : normalized;
|
|
@@ -23314,14 +23758,14 @@ function normalizeComparablePath(value) {
|
|
|
23314
23758
|
return (drivePrefix ? `${drivePrefix}/${joined}`.replace(/\/$/, "") : hasRoot ? `/${joined}`.replace(/\/$/, "") : joined || ".").toLowerCase();
|
|
23315
23759
|
}
|
|
23316
23760
|
function dirname$1(filePath) {
|
|
23317
|
-
return trimTrailingSlashes(filePath).match(/^(.*)[/\\][^/\\]+$/)?.[1] ?? "";
|
|
23761
|
+
return trimTrailingSlashes$1(filePath).match(/^(.*)[/\\][^/\\]+$/)?.[1] ?? "";
|
|
23318
23762
|
}
|
|
23319
23763
|
function basename(filePath) {
|
|
23320
|
-
return trimTrailingSlashes(filePath).match(/([^/\\]+)$/)?.[1] ?? "";
|
|
23764
|
+
return trimTrailingSlashes$1(filePath).match(/([^/\\]+)$/)?.[1] ?? "";
|
|
23321
23765
|
}
|
|
23322
23766
|
function resolveOutputProjectPath(output, fs) {
|
|
23323
23767
|
if (/\.fairy$/i.test(output)) return output;
|
|
23324
|
-
const normalizedOutput = trimTrailingSlashes(output);
|
|
23768
|
+
const normalizedOutput = trimTrailingSlashes$1(output);
|
|
23325
23769
|
const projectName = basename(normalizedOutput) || "Restored";
|
|
23326
23770
|
return fs.join(normalizedOutput, `${projectName}.fairy`);
|
|
23327
23771
|
}
|
|
@@ -23367,7 +23811,7 @@ async function prepareRestoreOutputDir(inputDir, outputDir, outputProjectPath, f
|
|
|
23367
23811
|
await fs.mkdir(outputDir);
|
|
23368
23812
|
}
|
|
23369
23813
|
async function restore(options) {
|
|
23370
|
-
const sourceDir = trimTrailingSlashes(options.inputDir);
|
|
23814
|
+
const sourceDir = trimTrailingSlashes$1(options.inputDir);
|
|
23371
23815
|
const outputIsProjectFile = /\.fairy$/i.test(options.output);
|
|
23372
23816
|
const outputProjectPath = resolveOutputProjectPath(options.output, options.fs);
|
|
23373
23817
|
await prepareRestoreOutputDir(sourceDir, dirname$1(outputProjectPath) || ".", outputProjectPath, options.fs, options.force === true, outputIsProjectFile);
|
|
@@ -23509,16 +23953,23 @@ var RestoreWorkflow = class {
|
|
|
23509
23953
|
async _ensureLooseImageResource(doc, pkg, owner, sourceDir, fileName) {
|
|
23510
23954
|
const resources = pkg.listResources();
|
|
23511
23955
|
const existing = this._findResourceByFile(resources, owner, "ImageResource", fileName);
|
|
23512
|
-
if (existing) return existing;
|
|
23513
23956
|
const sourcePath = await this._resolveLooseSourceFile(pkg, sourceDir, fileName);
|
|
23514
|
-
if (!sourcePath) return null;
|
|
23957
|
+
if (!sourcePath) return existing ?? null;
|
|
23958
|
+
if (existing) {
|
|
23959
|
+
existing.setExtras?.({
|
|
23960
|
+
...existing.getExtras?.() ?? {},
|
|
23961
|
+
_publishedFile: fileBaseName(sourcePath),
|
|
23962
|
+
_restoreAsLooseImage: true
|
|
23963
|
+
});
|
|
23964
|
+
return existing;
|
|
23965
|
+
}
|
|
23515
23966
|
const resource = doc.createImageResource(stripExtension(fileName));
|
|
23516
23967
|
resource.setId(generateId()).setPath(owner.getPath?.() ?? "/").setBranch(owner.getBranch?.() ?? "").setBranchItemIds(owner.getBranchItemIds?.() ?? []).setExported(false).setFileName(fileName);
|
|
23517
23968
|
resource.setExtras?.({
|
|
23518
23969
|
...resource.getExtras?.() ?? {},
|
|
23519
23970
|
_publishedFile: fileBaseName(sourcePath),
|
|
23520
23971
|
_suppressPackageSize: true,
|
|
23521
|
-
|
|
23972
|
+
_restoreAsLooseImage: true
|
|
23522
23973
|
});
|
|
23523
23974
|
pkg.addResource(resource);
|
|
23524
23975
|
return resource;
|
|
@@ -23692,13 +24143,13 @@ var RestoreWorkflow = class {
|
|
|
23692
24143
|
}
|
|
23693
24144
|
async _copyLooseResources(pkg, options, warnings) {
|
|
23694
24145
|
for (const resource of pkg.listResources()) {
|
|
23695
|
-
const
|
|
24146
|
+
const restoreAsLooseImage = resource.getExtras?.()?._restoreAsLooseImage === true;
|
|
23696
24147
|
if (![
|
|
23697
24148
|
"SoundResource",
|
|
23698
24149
|
"MiscResource",
|
|
23699
24150
|
"SpineResource",
|
|
23700
24151
|
"DragonBonesResource"
|
|
23701
|
-
].includes(resource.propertyType) && !
|
|
24152
|
+
].includes(resource.propertyType) && !restoreAsLooseImage) continue;
|
|
23702
24153
|
const fileName = resourceFileName(resource);
|
|
23703
24154
|
if (!fileName) continue;
|
|
23704
24155
|
const sourcePath = await this._resolveSourceFile(options.sourceDir, this._sourceFileCandidates(pkg, resourcePublishedFileName(resource), fileName));
|
|
@@ -23868,6 +24319,26 @@ var RestoreWorkflow = class {
|
|
|
23868
24319
|
};
|
|
23869
24320
|
//#endregion
|
|
23870
24321
|
//#region ../functions/src/publish.ts
|
|
24322
|
+
async function runPublishPluginHook(plugins, hook, doc, options) {
|
|
24323
|
+
const logger = doc.getLogger();
|
|
24324
|
+
for (const plugin of plugins) {
|
|
24325
|
+
const fn = plugin.plugin[hook];
|
|
24326
|
+
if (typeof fn !== "function") continue;
|
|
24327
|
+
try {
|
|
24328
|
+
await fn(doc, options);
|
|
24329
|
+
} catch (error) {
|
|
24330
|
+
logger.warn(`publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`);
|
|
24331
|
+
}
|
|
24332
|
+
}
|
|
24333
|
+
}
|
|
24334
|
+
function resolvePublishPluginsDir(doc, options) {
|
|
24335
|
+
const fs = options.fs;
|
|
24336
|
+
const projectDir = doc.getProjectDir?.() ?? "";
|
|
24337
|
+
if (projectDir) return fs?.join ? fs.join(projectDir, "plugins") : `${projectDir.replace(/[/\\]+$/, "")}/plugins`;
|
|
24338
|
+
const projectBasePath = resolveProjectBasePath(options.basePath);
|
|
24339
|
+
if (!projectBasePath) return "";
|
|
24340
|
+
return fs?.join ? fs.join(projectBasePath, "plugins") : `${projectBasePath.replace(/[/\\]+$/, "")}/plugins`;
|
|
24341
|
+
}
|
|
23871
24342
|
const UNITY_PROJECT_TYPE = ProjectType.Unity;
|
|
23872
24343
|
const COCOS_CREATOR_PROJECT_TYPE = ProjectType.CocosCreator;
|
|
23873
24344
|
function resolveDefaultPublishFileExtension(projectType, publishSettings) {
|
|
@@ -23917,6 +24388,19 @@ function resolvePublishOptions(doc, overrides = {}) {
|
|
|
23917
24388
|
atlas: atlasOptions
|
|
23918
24389
|
};
|
|
23919
24390
|
}
|
|
24391
|
+
function trimTrailingSlashes(value) {
|
|
24392
|
+
return value.replace(/[/\\]+$/, "");
|
|
24393
|
+
}
|
|
24394
|
+
function isAbsolutePathLike(value) {
|
|
24395
|
+
return /^(?:[a-zA-Z]:[/\\]|[/\\]{1,2})/u.test(value);
|
|
24396
|
+
}
|
|
24397
|
+
function joinPathSegments(left, right) {
|
|
24398
|
+
const normalizedLeft = trimTrailingSlashes(left);
|
|
24399
|
+
const normalizedRight = right.replace(/^[/\\]+/, "");
|
|
24400
|
+
if (!normalizedLeft) return normalizedRight;
|
|
24401
|
+
if (!normalizedRight) return normalizedLeft;
|
|
24402
|
+
return `${normalizedLeft}${normalizedLeft.includes("\\") ? "\\" : "/"}${normalizedRight}`;
|
|
24403
|
+
}
|
|
23920
24404
|
function dirname(filePath) {
|
|
23921
24405
|
return filePath.replace(/[/\\]+$/, "").match(/^(.*)[/\\][^/\\]+$/)?.[1] ?? "";
|
|
23922
24406
|
}
|
|
@@ -23947,6 +24431,9 @@ function isImageResource(resource) {
|
|
|
23947
24431
|
function isMovieClipResource(resource) {
|
|
23948
24432
|
return resource.propertyType === "MovieClipResource";
|
|
23949
24433
|
}
|
|
24434
|
+
function isHighResolutionResource(resource) {
|
|
24435
|
+
return isImageResource(resource) || isMovieClipResource(resource);
|
|
24436
|
+
}
|
|
23950
24437
|
function isMiscResource(resource) {
|
|
23951
24438
|
return resource.propertyType === "MiscResource";
|
|
23952
24439
|
}
|
|
@@ -24029,13 +24516,14 @@ function extname(fileName) {
|
|
|
24029
24516
|
if (lastDot <= lastSlash) return "";
|
|
24030
24517
|
return normalized.slice(lastDot);
|
|
24031
24518
|
}
|
|
24032
|
-
function resolvePublishedMiscFileName(resource) {
|
|
24519
|
+
function resolvePublishedMiscFileName(resource, projectType) {
|
|
24033
24520
|
const file = resource.getFile();
|
|
24521
|
+
if (projectType !== UNITY_PROJECT_TYPE) return file;
|
|
24034
24522
|
if (file.toLowerCase().endsWith(".atlas")) return `${file}.txt`;
|
|
24035
24523
|
return file;
|
|
24036
24524
|
}
|
|
24037
|
-
function resolvePublishedSkeletonFileName(resource) {
|
|
24038
|
-
if (isSpineResource(resource) && resource.getFile().toLowerCase().endsWith(".skel")) return `${resource.getFile()}.bytes`;
|
|
24525
|
+
function resolvePublishedSkeletonFileName(resource, projectType) {
|
|
24526
|
+
if (projectType === UNITY_PROJECT_TYPE && isSpineResource(resource) && resource.getFile().toLowerCase().endsWith(".skel")) return `${resource.getFile()}.bytes`;
|
|
24039
24527
|
return resource.getFile();
|
|
24040
24528
|
}
|
|
24041
24529
|
function setPublishedFileExtra(resource, fileName) {
|
|
@@ -24067,6 +24555,70 @@ function getBranchName(resource) {
|
|
|
24067
24555
|
function buildBranchResourceKey(resource) {
|
|
24068
24556
|
return `${resource.propertyType}|${resource.getPath() ?? ""}|${resource.getName() ?? ""}`;
|
|
24069
24557
|
}
|
|
24558
|
+
const HIGH_RESOLUTION_LEVELS = [
|
|
24559
|
+
{
|
|
24560
|
+
scale: 2,
|
|
24561
|
+
bit: 1,
|
|
24562
|
+
slot: 0
|
|
24563
|
+
},
|
|
24564
|
+
{
|
|
24565
|
+
scale: 3,
|
|
24566
|
+
bit: 2,
|
|
24567
|
+
slot: 1
|
|
24568
|
+
},
|
|
24569
|
+
{
|
|
24570
|
+
scale: 4,
|
|
24571
|
+
bit: 4,
|
|
24572
|
+
slot: 2
|
|
24573
|
+
}
|
|
24574
|
+
];
|
|
24575
|
+
function buildHighResolutionResourceKey(resource, name = resource.getName()) {
|
|
24576
|
+
return `${resource.propertyType}|${resource.getBranch?.() ?? ""}|${resource.getPath() ?? ""}|${name}`;
|
|
24577
|
+
}
|
|
24578
|
+
function isHighResolutionVariantName(name) {
|
|
24579
|
+
return /@(?:2|3|4)x(?:\.[^./\\]+)?$/iu.test(name);
|
|
24580
|
+
}
|
|
24581
|
+
function appendHighResolutionScaleToName(name, scale) {
|
|
24582
|
+
const extensionIndex = name.lastIndexOf(".");
|
|
24583
|
+
if (extensionIndex > 0) return `${name.slice(0, extensionIndex)}@${scale}x${name.slice(extensionIndex)}`;
|
|
24584
|
+
return `${name}@${scale}x`;
|
|
24585
|
+
}
|
|
24586
|
+
function trimTrailingMissingHighResolutionIds(ids) {
|
|
24587
|
+
while (ids.length > 0 && !ids[ids.length - 1]) ids.pop();
|
|
24588
|
+
return ids;
|
|
24589
|
+
}
|
|
24590
|
+
function collectHighResolutionItemIds(resources, publishedResourceIds, includeHighResolution) {
|
|
24591
|
+
const result = /* @__PURE__ */ new Map();
|
|
24592
|
+
if (includeHighResolution <= 0) return result;
|
|
24593
|
+
const highResolutionResourceByKey = /* @__PURE__ */ new Map();
|
|
24594
|
+
for (const resource of resources) {
|
|
24595
|
+
if (!isHighResolutionResource(resource)) continue;
|
|
24596
|
+
highResolutionResourceByKey.set(buildHighResolutionResourceKey(resource), resource);
|
|
24597
|
+
}
|
|
24598
|
+
for (const resource of resources) {
|
|
24599
|
+
if (!isHighResolutionResource(resource)) continue;
|
|
24600
|
+
if (!publishedResourceIds.has(resource.getId())) continue;
|
|
24601
|
+
if (isHighResolutionVariantName(resource.getName())) continue;
|
|
24602
|
+
const ids = [];
|
|
24603
|
+
for (const level of HIGH_RESOLUTION_LEVELS) {
|
|
24604
|
+
if ((includeHighResolution & level.bit) === 0) {
|
|
24605
|
+
ids[level.slot] = null;
|
|
24606
|
+
continue;
|
|
24607
|
+
}
|
|
24608
|
+
const highResolutionResource = highResolutionResourceByKey.get(buildHighResolutionResourceKey(resource, appendHighResolutionScaleToName(resource.getName(), level.scale)));
|
|
24609
|
+
if (!highResolutionResource) {
|
|
24610
|
+
ids[level.slot] = null;
|
|
24611
|
+
continue;
|
|
24612
|
+
}
|
|
24613
|
+
const highResolutionId = highResolutionResource.getId();
|
|
24614
|
+
publishedResourceIds.add(highResolutionId);
|
|
24615
|
+
ids[level.slot] = highResolutionId;
|
|
24616
|
+
}
|
|
24617
|
+
trimTrailingMissingHighResolutionIds(ids);
|
|
24618
|
+
if (ids.length > 0) result.set(resource.getId(), ids);
|
|
24619
|
+
}
|
|
24620
|
+
return result;
|
|
24621
|
+
}
|
|
24070
24622
|
function collectPackagePublishContext(pkg, options) {
|
|
24071
24623
|
const pkgId = pkg.getId();
|
|
24072
24624
|
const resources = pkg.listResources();
|
|
@@ -24074,6 +24626,24 @@ function collectPackagePublishContext(pkg, options) {
|
|
|
24074
24626
|
const referencedIds = /* @__PURE__ */ new Set();
|
|
24075
24627
|
const pixelHitTestImageIds = /* @__PURE__ */ new Set();
|
|
24076
24628
|
const spriteItemIds = /* @__PURE__ */ new Set();
|
|
24629
|
+
const collectExportedResourceIds = (sourceResources, sourcePublishedResourceIds) => {
|
|
24630
|
+
const exportedResourceIds = new Set(sourcePublishedResourceIds);
|
|
24631
|
+
const resourcesById = new Map(sourceResources.map((resource) => [resource.getId(), resource]));
|
|
24632
|
+
let changed = true;
|
|
24633
|
+
while (changed) {
|
|
24634
|
+
changed = false;
|
|
24635
|
+
for (const resourceId of [...exportedResourceIds]) {
|
|
24636
|
+
const resource = resourcesById.get(resourceId);
|
|
24637
|
+
if (!resource || !isSkeletonResource(resource)) continue;
|
|
24638
|
+
for (const requiredId of resource.getRequireIds()) {
|
|
24639
|
+
if (!requiredId || exportedResourceIds.has(requiredId)) continue;
|
|
24640
|
+
exportedResourceIds.add(requiredId);
|
|
24641
|
+
changed = true;
|
|
24642
|
+
}
|
|
24643
|
+
}
|
|
24644
|
+
}
|
|
24645
|
+
return exportedResourceIds;
|
|
24646
|
+
};
|
|
24077
24647
|
for (const atlas of pkg.listAtlases()) for (const sprite of atlas.listSprites()) spriteItemIds.add(sprite.getItemId());
|
|
24078
24648
|
for (const resource of resources) {
|
|
24079
24649
|
if (!isComponentResource(resource)) continue;
|
|
@@ -24100,6 +24670,7 @@ function collectPackagePublishContext(pkg, options) {
|
|
|
24100
24670
|
child.getSelectedIcon?.(),
|
|
24101
24671
|
child.getDropdown?.(),
|
|
24102
24672
|
child.getSound?.(),
|
|
24673
|
+
child.getInstanceSound?.(),
|
|
24103
24674
|
child.getInstanceIcon?.(),
|
|
24104
24675
|
child.getInstanceSelectedIcon?.(),
|
|
24105
24676
|
child.getVtScrollBarRes?.(),
|
|
@@ -24157,19 +24728,8 @@ function collectPackagePublishContext(pkg, options) {
|
|
|
24157
24728
|
}
|
|
24158
24729
|
if (resource.getExported() || referencedIds.has(resourceId)) publishedResourceIds.add(resourceId);
|
|
24159
24730
|
}
|
|
24160
|
-
|
|
24161
|
-
|
|
24162
|
-
changed = false;
|
|
24163
|
-
for (const resource of resources) {
|
|
24164
|
-
if (!isSkeletonResource(resource)) continue;
|
|
24165
|
-
if (!publishedResourceIds.has(resource.getId())) continue;
|
|
24166
|
-
for (const requiredId of resource.getRequireIds()) {
|
|
24167
|
-
if (!requiredId || publishedResourceIds.has(requiredId)) continue;
|
|
24168
|
-
publishedResourceIds.add(requiredId);
|
|
24169
|
-
changed = true;
|
|
24170
|
-
}
|
|
24171
|
-
}
|
|
24172
|
-
}
|
|
24731
|
+
for (const resourceId of collectExportedResourceIds(resources, publishedResourceIds)) publishedResourceIds.add(resourceId);
|
|
24732
|
+
const highResolutionItemIds = collectHighResolutionItemIds(resources, publishedResourceIds, options.includeHighResolution);
|
|
24173
24733
|
if (!options.includeBranches) {
|
|
24174
24734
|
const mainByKey = /* @__PURE__ */ new Map();
|
|
24175
24735
|
const activeBranchByKey = /* @__PURE__ */ new Map();
|
|
@@ -24217,7 +24777,9 @@ function collectPackagePublishContext(pkg, options) {
|
|
|
24217
24777
|
return {
|
|
24218
24778
|
referencedIds,
|
|
24219
24779
|
publishedResourceIds,
|
|
24780
|
+
exportedResourceIds: collectExportedResourceIds(resources, publishedResourceIds),
|
|
24220
24781
|
pixelHitTestImageIds,
|
|
24782
|
+
highResolutionItemIds,
|
|
24221
24783
|
effectiveResourceIds,
|
|
24222
24784
|
includeBranches: false
|
|
24223
24785
|
};
|
|
@@ -24225,7 +24787,9 @@ function collectPackagePublishContext(pkg, options) {
|
|
|
24225
24787
|
return {
|
|
24226
24788
|
referencedIds,
|
|
24227
24789
|
publishedResourceIds,
|
|
24790
|
+
exportedResourceIds: collectExportedResourceIds(resources, publishedResourceIds),
|
|
24228
24791
|
pixelHitTestImageIds,
|
|
24792
|
+
highResolutionItemIds,
|
|
24229
24793
|
effectiveResourceIds: new Map([...publishedResourceIds].map((resourceId) => [resourceId, resourceId])),
|
|
24230
24794
|
includeBranches: true
|
|
24231
24795
|
};
|
|
@@ -24274,28 +24838,36 @@ async function applyPixelHitTests(pkg, imageIds, basePath, encoder) {
|
|
|
24274
24838
|
}
|
|
24275
24839
|
}
|
|
24276
24840
|
async function annotatePackagePublishArtifacts(pkg, basePath, encoder, options) {
|
|
24277
|
-
const { publishedResourceIds, pixelHitTestImageIds, effectiveResourceIds, includeBranches } = collectPackagePublishContext(pkg, options);
|
|
24278
|
-
for (const resource of pkg.listResources())
|
|
24841
|
+
const { publishedResourceIds, exportedResourceIds, pixelHitTestImageIds, highResolutionItemIds, effectiveResourceIds, includeBranches } = collectPackagePublishContext(pkg, options);
|
|
24842
|
+
for (const resource of pkg.listResources()) {
|
|
24843
|
+
setPublishedIdExtra(resource, effectiveResourceIds.get(resource.getId()) ?? null);
|
|
24844
|
+
if (isHighResolutionResource(resource)) resource.setHighResolutionItemIds(highResolutionItemIds.get(resource.getId()) ?? []);
|
|
24845
|
+
}
|
|
24279
24846
|
await applyPixelHitTests(pkg, pixelHitTestImageIds, basePath, encoder);
|
|
24280
24847
|
const extras = pkg.getExtras() ?? {};
|
|
24281
24848
|
pkg.setExtras({
|
|
24282
24849
|
...extras,
|
|
24283
24850
|
publishedResourceIds: [...publishedResourceIds].sort((a, b) => a.localeCompare(b)),
|
|
24851
|
+
exportedResourceIds: [...exportedResourceIds].sort((a, b) => a.localeCompare(b)),
|
|
24284
24852
|
publishedIncludeBranches: includeBranches,
|
|
24285
24853
|
publishedEffectiveResourceIds: Object.fromEntries(effectiveResourceIds)
|
|
24286
24854
|
});
|
|
24287
24855
|
for (const resource of pkg.listResources()) {
|
|
24288
24856
|
if (isMiscResource(resource)) {
|
|
24289
|
-
setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource));
|
|
24857
|
+
setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource, options.projectType));
|
|
24290
24858
|
continue;
|
|
24291
24859
|
}
|
|
24292
|
-
if (isSkeletonResource(resource)) setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource));
|
|
24860
|
+
if (isSkeletonResource(resource)) setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource, options.projectType));
|
|
24293
24861
|
}
|
|
24294
24862
|
}
|
|
24295
24863
|
function getAnnotatedPublishedResourceIds(pkg) {
|
|
24296
24864
|
const extras = pkg.getExtras() ?? {};
|
|
24297
24865
|
return new Set(extras.publishedResourceIds ?? []);
|
|
24298
24866
|
}
|
|
24867
|
+
function getAnnotatedExportedResourceIds(pkg) {
|
|
24868
|
+
const extras = pkg.getExtras() ?? {};
|
|
24869
|
+
return new Set(extras.exportedResourceIds ?? []);
|
|
24870
|
+
}
|
|
24299
24871
|
function getPublishedSkeletonDependencyImageIds(pkg, publishedResourceIds) {
|
|
24300
24872
|
const imageIds = /* @__PURE__ */ new Set();
|
|
24301
24873
|
const resourcesById = new Map(pkg.listResources().map((resource) => [resource.getId(), resource]));
|
|
@@ -24334,18 +24906,18 @@ async function exportPackageSounds(pkg, outputDir, basePath, fs, readFileRaw, lo
|
|
|
24334
24906
|
}
|
|
24335
24907
|
}
|
|
24336
24908
|
async function exportPackageExternalResources(pkg, outputDir, basePath, fs, readFileRaw, logger) {
|
|
24337
|
-
const
|
|
24338
|
-
const skeletonDependencyImageIds = getPublishedSkeletonDependencyImageIds(pkg,
|
|
24339
|
-
if (
|
|
24909
|
+
const exportedResourceIds = getAnnotatedExportedResourceIds(pkg);
|
|
24910
|
+
const skeletonDependencyImageIds = getPublishedSkeletonDependencyImageIds(pkg, exportedResourceIds);
|
|
24911
|
+
if (exportedResourceIds.size === 0) return;
|
|
24340
24912
|
if (!basePath || !readFileRaw) {
|
|
24341
24913
|
if (pkg.listResources().some((resource) => {
|
|
24342
|
-
return (isMiscResource(resource) || isSkeletonResource(resource)) &&
|
|
24914
|
+
return (isMiscResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
|
|
24343
24915
|
})) logger.warn(`publish: External resources in package "${pkg.getName()}" were not exported because basePath/readFileRaw is unavailable.`);
|
|
24344
24916
|
return;
|
|
24345
24917
|
}
|
|
24346
24918
|
for (const resource of pkg.listResources()) {
|
|
24347
24919
|
const resourceId = resource.getId();
|
|
24348
|
-
const isSkeletonExternal =
|
|
24920
|
+
const isSkeletonExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSkeletonResource(resource));
|
|
24349
24921
|
const isSkeletonImageDependency = skeletonDependencyImageIds.has(resourceId) && isImageResource(resource);
|
|
24350
24922
|
if (!isSkeletonExternal && !isSkeletonImageDependency) continue;
|
|
24351
24923
|
let sourcePath;
|
|
@@ -24391,74 +24963,145 @@ async function exportPackageExternalResources(pkg, outputDir, basePath, fs, read
|
|
|
24391
24963
|
*/
|
|
24392
24964
|
function publish(options) {
|
|
24393
24965
|
return createTransform("publish", async (doc) => {
|
|
24394
|
-
const
|
|
24395
|
-
|
|
24396
|
-
|
|
24397
|
-
|
|
24398
|
-
|
|
24399
|
-
|
|
24400
|
-
|
|
24401
|
-
|
|
24402
|
-
|
|
24403
|
-
|
|
24404
|
-
|
|
24405
|
-
|
|
24406
|
-
|
|
24407
|
-
|
|
24408
|
-
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
|
|
24966
|
+
const resolveConfiguredOutputPath = (value, projectBasePath) => {
|
|
24967
|
+
const trimmed = value?.trim();
|
|
24968
|
+
if (!trimmed) return void 0;
|
|
24969
|
+
if (isAbsolutePathLike(trimmed) || !projectBasePath) return trimTrailingSlashes(trimmed);
|
|
24970
|
+
return trimTrailingSlashes(options.fs ? options.fs.join(projectBasePath, trimmed) : joinPathSegments(projectBasePath, trimmed));
|
|
24971
|
+
};
|
|
24972
|
+
const resolveProjectPublishConfig = () => {
|
|
24973
|
+
const publishSettings = (doc.getRoot().getSettings?.() ?? {}).publish ?? {};
|
|
24974
|
+
const resolved = resolvePublishOptions(doc, {
|
|
24975
|
+
compressed: options.compressed,
|
|
24976
|
+
fileExtension: options.fileExtension,
|
|
24977
|
+
packages: options.packages,
|
|
24978
|
+
atlas: options.atlas
|
|
24979
|
+
});
|
|
24980
|
+
const includeBranches = (publishSettings.branchProcessing ?? 0) === 0;
|
|
24981
|
+
return {
|
|
24982
|
+
...resolved,
|
|
24983
|
+
projectType: doc.getRoot().getProjectType(),
|
|
24984
|
+
includeBranches,
|
|
24985
|
+
activeBranch: includeBranches ? "" : options.branch ?? "",
|
|
24986
|
+
includeHighResolution: publishSettings.includeHighResolution ?? 0,
|
|
24987
|
+
separatedAtlasForBranch: includeBranches && publishSettings.seperatedAtlasForBranch === true,
|
|
24988
|
+
globalOutputPath: publishSettings.path?.trim() ?? "",
|
|
24989
|
+
globalBranchOutputPath: publishSettings.branchPath?.trim() ?? ""
|
|
24990
|
+
};
|
|
24991
|
+
};
|
|
24992
|
+
const resolvePackagePublishPlan = (pkg, config, projectBasePath) => {
|
|
24993
|
+
let outputDir;
|
|
24994
|
+
if (options.output) outputDir = trimTrailingSlashes(options.output);
|
|
24995
|
+
else {
|
|
24996
|
+
const candidates = [];
|
|
24997
|
+
if (!config.includeBranches && config.activeBranch) candidates.push(pkg.getPublishBranchPath(), config.globalBranchOutputPath);
|
|
24998
|
+
candidates.push(pkg.getPublishPath(), config.globalOutputPath);
|
|
24999
|
+
for (const candidate of candidates) {
|
|
25000
|
+
const resolved = resolveConfiguredOutputPath(candidate, projectBasePath);
|
|
25001
|
+
if (!resolved) continue;
|
|
25002
|
+
outputDir = resolved;
|
|
25003
|
+
break;
|
|
25004
|
+
}
|
|
25005
|
+
}
|
|
25006
|
+
const publishName = pkg.getPublishName() || pkg.getName();
|
|
25007
|
+
return {
|
|
25008
|
+
pkg,
|
|
25009
|
+
outputDir,
|
|
25010
|
+
publishName,
|
|
25011
|
+
fileName: resolvePublishFileName(publishName, config.fileExtension),
|
|
25012
|
+
compressed: config.compressed,
|
|
25013
|
+
fileExtension: config.fileExtension,
|
|
25014
|
+
includeBranches: config.includeBranches,
|
|
25015
|
+
activeBranch: config.activeBranch,
|
|
25016
|
+
includeHighResolution: config.includeHighResolution,
|
|
25017
|
+
separatedAtlasForBranch: config.separatedAtlasForBranch,
|
|
25018
|
+
atlas: config.atlas
|
|
25019
|
+
};
|
|
25020
|
+
};
|
|
25021
|
+
const createNoopPublishFs = () => ({
|
|
25022
|
+
async writeFileRaw() {},
|
|
25023
|
+
async mkdir() {},
|
|
25024
|
+
join(...paths) {
|
|
25025
|
+
return paths.join("/");
|
|
25026
|
+
}
|
|
25027
|
+
});
|
|
25028
|
+
const publishPackage = async (plan, writerFs, packageIndex) => {
|
|
25029
|
+
const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(plan.fileExtension);
|
|
25030
|
+
await atlas({
|
|
25031
|
+
...plan.atlas,
|
|
25032
|
+
...options.atlas ?? {},
|
|
25033
|
+
separatedAtlasForBranch: plan.separatedAtlasForBranch,
|
|
25034
|
+
encoder: options.encoder,
|
|
25035
|
+
basePath: options.basePath,
|
|
25036
|
+
outputPath: options.fs ? plan.outputDir : void 0,
|
|
25037
|
+
mkdir: options.fs ? options.fs.mkdir : void 0,
|
|
25038
|
+
readFileRaw: options.atlas?.readFileRaw ?? options.fs?.readFileRaw,
|
|
25039
|
+
packages: [plan.pkg.getName()],
|
|
25040
|
+
...atlasRuntimeOptions
|
|
25041
|
+
})(doc);
|
|
25042
|
+
if (!options.fs) return;
|
|
25043
|
+
if (!plan.outputDir) throw new Error("publish: no output directory resolved. Provide --output, or configure global publish.path / package publishPath.");
|
|
25044
|
+
await options.fs.mkdir(plan.outputDir);
|
|
25045
|
+
const filePath = options.fs.join(plan.outputDir, plan.fileName);
|
|
25046
|
+
const bwOptions = {
|
|
25047
|
+
compressed: plan.compressed,
|
|
25048
|
+
packageIndex
|
|
25049
|
+
};
|
|
25050
|
+
await new BinaryWriter(writerFs).write(doc, filePath, bwOptions);
|
|
25051
|
+
await exportPackageSounds(plan.pkg, plan.outputDir, options.basePath, options.fs, options.atlas?.readFileRaw ?? options.fs.readFileRaw, logger);
|
|
25052
|
+
await exportPackageExternalResources(plan.pkg, plan.outputDir, options.basePath, options.fs, options.atlas?.readFileRaw ?? options.fs.readFileRaw, logger);
|
|
25053
|
+
logger.info(`publish: Written ${plan.fileName}`);
|
|
25054
|
+
};
|
|
25055
|
+
const root = doc.getRoot();
|
|
25056
|
+
const logger = doc.getLogger();
|
|
25057
|
+
const projectBasePath = resolveProjectBasePath(options.basePath) || doc.getProjectDir?.() || "";
|
|
25058
|
+
const pluginsDir = resolvePublishPluginsDir(doc, options);
|
|
25059
|
+
const plugins = pluginsDir ? await loadPlugins(doc, pluginsDir) : [];
|
|
25060
|
+
await runPublishPluginHook(plugins, "onPublishStart", doc, options);
|
|
25061
|
+
const resolved = resolveProjectPublishConfig();
|
|
25062
|
+
let allPackages = root.listPackages();
|
|
25063
|
+
if (resolved.packages && resolved.packages.length > 0) {
|
|
25064
|
+
const names = new Set(resolved.packages);
|
|
25065
|
+
allPackages = allPackages.filter((p) => names.has(p.getName()));
|
|
25066
|
+
}
|
|
25067
|
+
if (allPackages.length === 0) {
|
|
25068
|
+
logger.warn("publish: No packages to publish.");
|
|
25069
|
+
await runPublishPluginHook(plugins, "onPublishEnd", doc, options);
|
|
25070
|
+
return;
|
|
24412
25071
|
}
|
|
24413
|
-
const includeBranches = (publishSettings.branchProcessing ?? 0) === 0;
|
|
24414
|
-
const activeBranch = includeBranches ? "" : options.branch ?? "";
|
|
24415
|
-
const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(ext);
|
|
24416
25072
|
const allDocPackages = root.listPackages();
|
|
24417
25073
|
const pkgMap = /* @__PURE__ */ new Map();
|
|
24418
25074
|
for (const p of allDocPackages) pkgMap.set(p.getId(), p);
|
|
24419
25075
|
for (const pkg of allPackages) {
|
|
24420
|
-
_computeDependencies(pkg, pkgMap);
|
|
25076
|
+
_computeDependencies(doc, pkg, pkgMap);
|
|
24421
25077
|
await annotatePackagePublishArtifacts(pkg, options.basePath, options.encoder, {
|
|
24422
|
-
|
|
24423
|
-
|
|
25078
|
+
projectType: resolved.projectType,
|
|
25079
|
+
includeBranches: resolved.includeBranches,
|
|
25080
|
+
activeBranch: resolved.activeBranch,
|
|
25081
|
+
includeHighResolution: resolved.includeHighResolution
|
|
24424
25082
|
});
|
|
24425
25083
|
}
|
|
24426
|
-
|
|
24427
|
-
...resolved.atlas,
|
|
24428
|
-
...options.atlas ?? {},
|
|
24429
|
-
separatedAtlasForBranch: includeBranches && publishSettings.seperatedAtlasForBranch === true,
|
|
24430
|
-
encoder: options.encoder,
|
|
24431
|
-
basePath: options.basePath,
|
|
24432
|
-
outputPath: options.fs ? options.output : void 0,
|
|
24433
|
-
mkdir: options.fs ? options.fs.mkdir : void 0,
|
|
24434
|
-
readFileRaw: options.atlas?.readFileRaw ?? options.fs?.readFileRaw,
|
|
24435
|
-
...atlasRuntimeOptions
|
|
24436
|
-
})(doc);
|
|
25084
|
+
const plans = allPackages.map((pkg) => resolvePackagePublishPlan(pkg, resolved, projectBasePath));
|
|
24437
25085
|
if (!options.fs) {
|
|
24438
25086
|
logger.info(`publish: No fs provided — layout computed for ${allPackages.length} package(s), skipping file output.`);
|
|
25087
|
+
const noopWriterFs = toBinaryWriterFileSystem(createNoopPublishFs());
|
|
25088
|
+
for (const plan of plans) await publishPackage(plan, noopWriterFs, allDocPackages.indexOf(plan.pkg));
|
|
25089
|
+
await runPublishPluginHook(plugins, "onPublishEnd", doc, options);
|
|
24439
25090
|
return;
|
|
24440
25091
|
}
|
|
24441
|
-
|
|
25092
|
+
const unresolvedPlan = plans.find((plan) => !plan.outputDir);
|
|
25093
|
+
if (unresolvedPlan) throw new Error(`publish: no output directory resolved for package "${unresolvedPlan.pkg.getName()}". Provide --output, or configure global publish.path / package publishPath.`);
|
|
24442
25094
|
const writerFs = toBinaryWriterFileSystem(options.fs);
|
|
24443
|
-
for (const
|
|
24444
|
-
const pkgIndex = allDocPackages.indexOf(pkg);
|
|
24445
|
-
const fileName = resolvePublishFileName(pkg.getPublishName() || pkg.getName(), ext);
|
|
24446
|
-
const filePath = options.fs.join(options.output, fileName);
|
|
24447
|
-
const bwOptions = {
|
|
24448
|
-
compressed: resolved.compressed,
|
|
24449
|
-
packageIndex: pkgIndex
|
|
24450
|
-
};
|
|
24451
|
-
await new BinaryWriter(writerFs).write(doc, filePath, bwOptions);
|
|
24452
|
-
await exportPackageSounds(pkg, options.output, options.basePath, options.fs, options.atlas?.readFileRaw ?? options.fs.readFileRaw, logger);
|
|
24453
|
-
await exportPackageExternalResources(pkg, options.output, options.basePath, options.fs, options.atlas?.readFileRaw ?? options.fs.readFileRaw, logger);
|
|
24454
|
-
logger.info(`publish: Written ${fileName}`);
|
|
24455
|
-
}
|
|
25095
|
+
for (const plan of plans) await publishPackage(plan, writerFs, allDocPackages.indexOf(plan.pkg));
|
|
24456
25096
|
await publishCodeGeneration(doc, {
|
|
24457
25097
|
basePath: options.basePath,
|
|
24458
25098
|
fs: options.fs,
|
|
24459
|
-
packages: allPackages
|
|
25099
|
+
packages: allPackages,
|
|
25100
|
+
plugins
|
|
24460
25101
|
});
|
|
24461
|
-
|
|
25102
|
+
const publishedTargets = [...new Set(plans.map((plan) => plan.outputDir).filter((value) => Boolean(value)))];
|
|
25103
|
+
logger.info(publishedTargets.length > 0 ? `publish: Published ${allPackages.length} package(s) to ${publishedTargets.join(", ")}` : `publish: Published ${allPackages.length} package(s)`);
|
|
25104
|
+
await runPublishPluginHook(plugins, "onPublishEnd", doc, options);
|
|
24462
25105
|
});
|
|
24463
25106
|
}
|
|
24464
25107
|
/**
|
|
@@ -24466,25 +25109,104 @@ function publish(options) {
|
|
|
24466
25109
|
* The editor only adds dependencies for packages referenced via bitmap font URLs.
|
|
24467
25110
|
* @internal
|
|
24468
25111
|
*/
|
|
24469
|
-
function _computeDependencies(pkg, pkgMap) {
|
|
25112
|
+
function _computeDependencies(doc, pkg, pkgMap) {
|
|
24470
25113
|
const referencedPkgIds = /* @__PURE__ */ new Set();
|
|
24471
|
-
|
|
24472
|
-
|
|
24473
|
-
|
|
24474
|
-
|
|
24475
|
-
|
|
24476
|
-
|
|
24477
|
-
|
|
24478
|
-
|
|
25114
|
+
const pkgId = pkg.getId();
|
|
25115
|
+
const packageOrder = new Map(doc.getRoot().listPackages().map((entry, index) => [entry.getId(), index]));
|
|
25116
|
+
const addDependencyPackageId = (dependencyPkgId) => {
|
|
25117
|
+
const normalized = dependencyPkgId?.trim() ?? "";
|
|
25118
|
+
if (!normalized || normalized === pkgId) return;
|
|
25119
|
+
referencedPkgIds.add(normalized);
|
|
25120
|
+
};
|
|
25121
|
+
const extractPackageIdFromUiUrl = (value) => {
|
|
25122
|
+
if (!value.startsWith("ui://")) return null;
|
|
25123
|
+
const rest = value.slice(5);
|
|
25124
|
+
if (!rest) return null;
|
|
25125
|
+
const slashIndex = rest.indexOf("/");
|
|
25126
|
+
if (slashIndex >= 0) return rest.slice(0, slashIndex) || null;
|
|
25127
|
+
if (rest.length >= 8) return rest.slice(0, 8);
|
|
25128
|
+
return null;
|
|
25129
|
+
};
|
|
25130
|
+
const addDependencyPackageIdFromUiValue = (value) => {
|
|
25131
|
+
if (!value || typeof value !== "string") return;
|
|
25132
|
+
addDependencyPackageId(extractPackageIdFromUiUrl(value));
|
|
25133
|
+
};
|
|
25134
|
+
const addDependencyPackageIdsFromText = (value) => {
|
|
25135
|
+
if (!value || typeof value !== "string") return;
|
|
25136
|
+
const matches = value.matchAll(/ui:\/\/([0-9a-z]{8})/giu);
|
|
25137
|
+
for (const match of matches) addDependencyPackageId(match[1] ?? "");
|
|
25138
|
+
};
|
|
25139
|
+
const addDependencyPackageIdsFromUnknown = (value) => {
|
|
25140
|
+
if (Array.isArray(value)) {
|
|
25141
|
+
for (const entry of value) addDependencyPackageIdsFromUnknown(entry);
|
|
25142
|
+
return;
|
|
24479
25143
|
}
|
|
24480
|
-
|
|
25144
|
+
if (typeof value === "string") {
|
|
25145
|
+
addDependencyPackageIdFromUiValue(value);
|
|
25146
|
+
addDependencyPackageIdsFromText(value);
|
|
25147
|
+
}
|
|
25148
|
+
};
|
|
25149
|
+
const addDependencyFontRef = (value) => {
|
|
25150
|
+
if (Array.isArray(value)) {
|
|
25151
|
+
for (const entry of value) addDependencyPackageIdFromUiValue(entry);
|
|
25152
|
+
return;
|
|
25153
|
+
}
|
|
25154
|
+
addDependencyPackageIdFromUiValue(value ?? void 0);
|
|
25155
|
+
};
|
|
24481
25156
|
for (const res of pkg.listResources()) {
|
|
24482
25157
|
if (res.propertyType !== "Component") continue;
|
|
24483
|
-
|
|
25158
|
+
const component = res;
|
|
25159
|
+
for (const child of component.listChildren?.() ?? []) {
|
|
25160
|
+
addDependencyPackageId(child.getPackageId?.());
|
|
25161
|
+
addDependencyFontRef(child.getFont?.());
|
|
25162
|
+
addDependencyPackageIdsFromText(child.getText?.());
|
|
25163
|
+
for (const ref of [
|
|
25164
|
+
child.getUrl?.(),
|
|
25165
|
+
child.getDefaultItem?.(),
|
|
25166
|
+
child.getIcon?.(),
|
|
25167
|
+
child.getSelectedIcon?.(),
|
|
25168
|
+
child.getDropdown?.(),
|
|
25169
|
+
child.getSound?.(),
|
|
25170
|
+
child.getInstanceSound?.(),
|
|
25171
|
+
child.getInstanceIcon?.(),
|
|
25172
|
+
child.getInstanceSelectedIcon?.(),
|
|
25173
|
+
child.getVtScrollBarRes?.(),
|
|
25174
|
+
child.getHzScrollBarRes?.(),
|
|
25175
|
+
child.getHeaderRes?.(),
|
|
25176
|
+
child.getFooterRes?.()
|
|
25177
|
+
]) addDependencyPackageIdFromUiValue(ref);
|
|
25178
|
+
for (const item of child.getInstanceComboItems?.() ?? []) addDependencyPackageIdFromUiValue(item.icon ?? void 0);
|
|
25179
|
+
for (const item of child.getListItems?.() ?? []) {
|
|
25180
|
+
addDependencyPackageIdFromUiValue(item.icon ?? void 0);
|
|
25181
|
+
addDependencyPackageIdFromUiValue(item.url ?? void 0);
|
|
25182
|
+
}
|
|
25183
|
+
for (const gear of child.listGears?.() ?? []) {
|
|
25184
|
+
addDependencyPackageIdsFromUnknown(gear.getValues?.());
|
|
25185
|
+
addDependencyPackageIdsFromUnknown(gear.getDefaultValue?.());
|
|
25186
|
+
}
|
|
25187
|
+
}
|
|
25188
|
+
addDependencyFontRef(component.getFont?.());
|
|
25189
|
+
for (const ref of [
|
|
25190
|
+
component.getDropdown?.(),
|
|
25191
|
+
component.getHeaderRes?.(),
|
|
25192
|
+
component.getFooterRes?.(),
|
|
25193
|
+
component.getVtScrollBarRes?.(),
|
|
25194
|
+
component.getHzScrollBarRes?.(),
|
|
25195
|
+
component.getSound?.()
|
|
25196
|
+
]) addDependencyPackageIdFromUiValue(ref);
|
|
25197
|
+
for (const transition of component.listTransitions?.() ?? []) for (const item of transition.listItems?.() ?? []) {
|
|
25198
|
+
addDependencyPackageIdsFromUnknown(item.getStartValue?.());
|
|
25199
|
+
addDependencyPackageIdsFromUnknown(item.getEndValue?.());
|
|
25200
|
+
}
|
|
24484
25201
|
}
|
|
24485
25202
|
for (const dep of pkg.listDependencies()) pkg.removeDependency(dep);
|
|
24486
25203
|
if (referencedPkgIds.size > 0) {
|
|
24487
|
-
const sortedIds = [...referencedPkgIds].sort((a, b) =>
|
|
25204
|
+
const sortedIds = [...referencedPkgIds].sort((a, b) => {
|
|
25205
|
+
const orderA = packageOrder.get(a) ?? Number.MAX_SAFE_INTEGER;
|
|
25206
|
+
const orderB = packageOrder.get(b) ?? Number.MAX_SAFE_INTEGER;
|
|
25207
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
25208
|
+
return a.localeCompare(b);
|
|
25209
|
+
});
|
|
24488
25210
|
for (const refId of sortedIds) {
|
|
24489
25211
|
const depPkg = pkgMap.get(refId);
|
|
24490
25212
|
if (depPkg) pkg.addDependency(depPkg);
|
|
@@ -24492,83 +25214,238 @@ function _computeDependencies(pkg, pkgMap) {
|
|
|
24492
25214
|
}
|
|
24493
25215
|
}
|
|
24494
25216
|
//#endregion
|
|
24495
|
-
//#region src/
|
|
24496
|
-
|
|
24497
|
-
|
|
24498
|
-
|
|
24499
|
-
|
|
24500
|
-
|
|
24501
|
-
|
|
24502
|
-
|
|
24503
|
-
|
|
24504
|
-
|
|
24505
|
-
|
|
24506
|
-
|
|
24507
|
-
|
|
24508
|
-
|
|
24509
|
-
|
|
24510
|
-
|
|
24511
|
-
|
|
24512
|
-
|
|
24513
|
-
|
|
24514
|
-
|
|
24515
|
-
|
|
24516
|
-
|
|
24517
|
-
|
|
24518
|
-
|
|
24519
|
-
|
|
24520
|
-
|
|
24521
|
-
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
|
|
24525
|
-
|
|
24526
|
-
|
|
24527
|
-
|
|
25217
|
+
//#region ../core/src/io/node-io.ts
|
|
25218
|
+
/**
|
|
25219
|
+
* Node.js I/O implementation for reading and writing FairyGUI projects.
|
|
25220
|
+
*
|
|
25221
|
+
* Usage:
|
|
25222
|
+
*
|
|
25223
|
+
* ```ts
|
|
25224
|
+
* import { NodeIO } from '@openfairygui/core/node';
|
|
25225
|
+
*
|
|
25226
|
+
* const io = new NodeIO();
|
|
25227
|
+
* const doc = await io.readProject('./path/to/project.fairy');
|
|
25228
|
+
* await io.writeProject(doc, './path/to/output.fairy');
|
|
25229
|
+
* const doc2 = await io.readBinary('./path/to/package_fui.bytes');
|
|
25230
|
+
* ```
|
|
25231
|
+
*
|
|
25232
|
+
* @category I/O
|
|
25233
|
+
*/
|
|
25234
|
+
var NodeIO = class extends PlatformIO {
|
|
25235
|
+
createFileSystem() {
|
|
25236
|
+
return {
|
|
25237
|
+
async readFile(filePath) {
|
|
25238
|
+
return fs$1.readFile(filePath, "utf-8");
|
|
25239
|
+
},
|
|
25240
|
+
async readFileRaw(filePath) {
|
|
25241
|
+
const buf = await fs$1.readFile(filePath);
|
|
25242
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
25243
|
+
},
|
|
25244
|
+
async writeFile(filePath, content) {
|
|
25245
|
+
await fs$1.writeFile(filePath, content, "utf-8");
|
|
25246
|
+
},
|
|
25247
|
+
async writeFileRaw(filePath, data) {
|
|
25248
|
+
await fs$1.writeFile(filePath, data);
|
|
25249
|
+
},
|
|
25250
|
+
async mkdir(dirPath) {
|
|
25251
|
+
await fs$1.mkdir(dirPath, { recursive: true });
|
|
25252
|
+
},
|
|
25253
|
+
async readdir(dirPath) {
|
|
25254
|
+
const entries = await fs$1.readdir(dirPath, { withFileTypes: true });
|
|
25255
|
+
return (await Promise.all(entries.map(async (entry) => {
|
|
25256
|
+
if (entry.isDirectory()) return entry.name;
|
|
25257
|
+
if (!entry.isSymbolicLink()) return null;
|
|
25258
|
+
try {
|
|
25259
|
+
return (await fs$1.stat(path$1.join(dirPath, entry.name))).isDirectory() ? entry.name : null;
|
|
25260
|
+
} catch {
|
|
25261
|
+
return null;
|
|
25262
|
+
}
|
|
25263
|
+
}))).filter((entry) => entry !== null);
|
|
25264
|
+
},
|
|
25265
|
+
async exists(filePath) {
|
|
25266
|
+
try {
|
|
25267
|
+
await fs$1.access(filePath);
|
|
25268
|
+
return true;
|
|
25269
|
+
} catch {
|
|
25270
|
+
return false;
|
|
25271
|
+
}
|
|
25272
|
+
},
|
|
25273
|
+
join(...paths) {
|
|
25274
|
+
return path$1.join(...paths);
|
|
25275
|
+
},
|
|
25276
|
+
dirname(filePath) {
|
|
25277
|
+
return path$1.dirname(filePath);
|
|
25278
|
+
}
|
|
25279
|
+
};
|
|
25280
|
+
}
|
|
25281
|
+
};
|
|
25282
|
+
//#endregion
|
|
25283
|
+
//#region src/utils/project-input.ts
|
|
24528
25284
|
/** Resolve input to a .fairy file path. Accepts a directory or a .fairy file. */
|
|
24529
25285
|
async function resolveFairyPath(input) {
|
|
24530
25286
|
const resolved = path.resolve(input);
|
|
24531
25287
|
const stat = await fs.stat(resolved);
|
|
24532
25288
|
if (stat.isFile() && resolved.endsWith(".fairy")) return resolved;
|
|
24533
25289
|
if (stat.isDirectory()) {
|
|
24534
|
-
const fairyFiles = (await fs.readdir(resolved)).filter((
|
|
25290
|
+
const fairyFiles = (await fs.readdir(resolved)).filter((entry) => entry.endsWith(".fairy"));
|
|
24535
25291
|
if (fairyFiles.length === 1) return path.join(resolved, fairyFiles[0]);
|
|
24536
25292
|
if (fairyFiles.length > 1) throw new Error(`Multiple .fairy files found in ${resolved}: ${fairyFiles.join(", ")}. Please specify one.`);
|
|
24537
25293
|
throw new Error(`No .fairy file found in ${resolved}`);
|
|
24538
25294
|
}
|
|
24539
25295
|
throw new Error(`Input is not a .fairy file or directory: ${resolved}`);
|
|
24540
25296
|
}
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24544
|
-
|
|
24545
|
-
|
|
24546
|
-
|
|
24547
|
-
|
|
24548
|
-
|
|
24549
|
-
|
|
24550
|
-
|
|
24551
|
-
|
|
24552
|
-
|
|
24553
|
-
|
|
24554
|
-
|
|
24555
|
-
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24562
|
-
|
|
24563
|
-
|
|
24564
|
-
|
|
24565
|
-
|
|
24566
|
-
|
|
24567
|
-
console.error(`Unknown command: ${command}\n`);
|
|
24568
|
-
console.log(HELP);
|
|
24569
|
-
process.exit(1);
|
|
25297
|
+
//#endregion
|
|
25298
|
+
//#region src/commands/inspect.ts
|
|
25299
|
+
function registerInspectCommand(program) {
|
|
25300
|
+
program.command("inspect").description("Show project contents report").argument("<project-dir>", "Project root directory or .fairy file").action(async (projectDir) => {
|
|
25301
|
+
const fairyPath = await resolveFairyPath(projectDir);
|
|
25302
|
+
console.log(`Project: ${fairyPath}\n`);
|
|
25303
|
+
printReport(inspect(await new NodeIO().readProject(fairyPath)));
|
|
25304
|
+
});
|
|
25305
|
+
}
|
|
25306
|
+
function printReport(report) {
|
|
25307
|
+
console.log(`ID: ${report.projectId}`);
|
|
25308
|
+
console.log(`Type: ${report.projectType}, Version: ${report.version}`);
|
|
25309
|
+
console.log(`\nPackages: ${report.totals.packages}`);
|
|
25310
|
+
console.log(` Images: ${report.totals.images}`);
|
|
25311
|
+
console.log(` Sounds: ${report.totals.sounds}`);
|
|
25312
|
+
console.log(` Fonts: ${report.totals.fonts}`);
|
|
25313
|
+
console.log(` MovieClips: ${report.totals.movieClips}`);
|
|
25314
|
+
console.log(` Components: ${report.totals.components}`);
|
|
25315
|
+
console.log(` DisplayObjs: ${report.totals.displayObjects}`);
|
|
25316
|
+
console.log(` Gears: ${report.totals.gears}`);
|
|
25317
|
+
console.log(` Controllers: ${report.totals.controllers}`);
|
|
25318
|
+
console.log(` Transitions: ${report.totals.transitions}`);
|
|
25319
|
+
console.log("\nPackage details:");
|
|
25320
|
+
for (const pkg of report.packages) {
|
|
25321
|
+
const res = pkg.resources;
|
|
25322
|
+
console.log(` ${pkg.name} (${pkg.id}): ${res.images.count} img, ${res.sounds.count} snd, ${res.fonts.count} font, ${res.components.count} comp`);
|
|
24570
25323
|
}
|
|
24571
25324
|
}
|
|
25325
|
+
//#endregion
|
|
25326
|
+
//#region src/utils/project-type.ts
|
|
25327
|
+
function parseProjectType(value) {
|
|
25328
|
+
if (!value) return void 0;
|
|
25329
|
+
const trimmed = value.trim();
|
|
25330
|
+
if (trimmed === "") return void 0;
|
|
25331
|
+
if (/^\d+$/u.test(trimmed)) return Number(trimmed);
|
|
25332
|
+
const normalized = trimmed.toLowerCase();
|
|
25333
|
+
const map = {
|
|
25334
|
+
unity: ProjectType.Unity,
|
|
25335
|
+
flash: ProjectType.Flash,
|
|
25336
|
+
starling: ProjectType.Starling,
|
|
25337
|
+
cocoscreator: ProjectType.CocosCreator,
|
|
25338
|
+
cocos: ProjectType.CocosCreator,
|
|
25339
|
+
layabox: ProjectType.LayaBox,
|
|
25340
|
+
laya: ProjectType.LayaBox,
|
|
25341
|
+
egret: ProjectType.Egret,
|
|
25342
|
+
haxe: ProjectType.Haxe,
|
|
25343
|
+
pixi: ProjectType.Pixi,
|
|
25344
|
+
libgdx: ProjectType.LibGDX,
|
|
25345
|
+
unreal: ProjectType.Unreal,
|
|
25346
|
+
cryengine: ProjectType.CryEngine,
|
|
25347
|
+
monogame: ProjectType.MonoGame,
|
|
25348
|
+
vision: ProjectType.Vision
|
|
25349
|
+
};
|
|
25350
|
+
const resolved = map[normalized];
|
|
25351
|
+
if (resolved === void 0) throw new Error(`Unknown project type: ${value}. Use a numeric id or one of: ${Object.keys(map).join(", ")}`);
|
|
25352
|
+
return resolved;
|
|
25353
|
+
}
|
|
25354
|
+
//#endregion
|
|
25355
|
+
//#region src/commands/publish.ts
|
|
25356
|
+
function registerPublishCommand(program) {
|
|
25357
|
+
program.command("publish").description("Publish project to binary outputs and configured generated code").argument("<project-dir>", "Project root directory or .fairy file").option("-o, --output <dir>", "Override project or package publish output directory").option("-c, --compressed", "Compress binary data (overrides project setting)").option("-p, --packages <a,b,c>", "Only publish specific packages (comma-separated)").option("-b, --branch <name>", "Active branch used by \"主干合并活跃分支\"; omit for main branch").option("-t, --project-type <name|id>", "Override project type (for example: unity, layabox, cocoscreator, 0, 4, 3)").action(async (projectDir, options) => {
|
|
25358
|
+
const fairyPath = await resolveFairyPath(projectDir);
|
|
25359
|
+
const projectRootDir = path.dirname(fairyPath);
|
|
25360
|
+
const outputDir = options.output ? path.resolve(options.output) : void 0;
|
|
25361
|
+
console.log(`Reading project: ${fairyPath}`);
|
|
25362
|
+
const doc = await new NodeIO().readProject(fairyPath);
|
|
25363
|
+
const projectType = parseProjectType(options.projectType);
|
|
25364
|
+
if (projectType !== void 0) doc.getRoot().setProjectType(projectType);
|
|
25365
|
+
const pkgFilter = options.packages?.split(",").map((value) => value.trim());
|
|
25366
|
+
const resolved = resolvePublishOptions(doc, {
|
|
25367
|
+
compressed: options.compressed,
|
|
25368
|
+
packages: pkgFilter
|
|
25369
|
+
});
|
|
25370
|
+
console.log(`Settings: ext=${resolved.fileExtension}, compressed=${resolved.compressed}`);
|
|
25371
|
+
if (options.branch) console.log(`Active branch: ${options.branch}`);
|
|
25372
|
+
const atlasConfig = {
|
|
25373
|
+
...resolved.atlas,
|
|
25374
|
+
readFileRaw: async (filePath) => {
|
|
25375
|
+
const buf = await fs.readFile(filePath);
|
|
25376
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
25377
|
+
}
|
|
25378
|
+
};
|
|
25379
|
+
let encoder;
|
|
25380
|
+
try {
|
|
25381
|
+
const sharp = await import("sharp");
|
|
25382
|
+
encoder = sharp.default ?? sharp;
|
|
25383
|
+
console.log("Sharp loaded — atlas PNGs will be generated.");
|
|
25384
|
+
} catch {
|
|
25385
|
+
console.log("Sharp not available — atlas PNGs will NOT be generated (layout only).");
|
|
25386
|
+
console.log(" Install sharp to enable: pnpm add sharp");
|
|
25387
|
+
}
|
|
25388
|
+
await doc.transform(publish({
|
|
25389
|
+
output: outputDir,
|
|
25390
|
+
compressed: resolved.compressed,
|
|
25391
|
+
fileExtension: resolved.fileExtension,
|
|
25392
|
+
packages: resolved.packages,
|
|
25393
|
+
fs: {
|
|
25394
|
+
async readFileRaw(filePath) {
|
|
25395
|
+
const buf = await fs.readFile(filePath);
|
|
25396
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
25397
|
+
},
|
|
25398
|
+
async writeFileRaw(filePath, data) {
|
|
25399
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
25400
|
+
await fs.writeFile(filePath, data);
|
|
25401
|
+
},
|
|
25402
|
+
async mkdir(dirPath) {
|
|
25403
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
25404
|
+
},
|
|
25405
|
+
async readdir(dirPath) {
|
|
25406
|
+
return fs.readdir(dirPath);
|
|
25407
|
+
},
|
|
25408
|
+
async deleteFile(filePath) {
|
|
25409
|
+
await fs.rm(filePath, { force: true });
|
|
25410
|
+
},
|
|
25411
|
+
join(...paths) {
|
|
25412
|
+
return path.join(...paths);
|
|
25413
|
+
}
|
|
25414
|
+
},
|
|
25415
|
+
encoder,
|
|
25416
|
+
basePath: path.join(projectRootDir, "assets"),
|
|
25417
|
+
atlas: atlasConfig,
|
|
25418
|
+
branch: options.branch
|
|
25419
|
+
}));
|
|
25420
|
+
console.log(`\nDone!${outputDir ? ` Output override: ${outputDir}` : ""}`);
|
|
25421
|
+
});
|
|
25422
|
+
}
|
|
25423
|
+
//#endregion
|
|
25424
|
+
//#region src/commands/restore.ts
|
|
25425
|
+
function registerRestoreCommand(program) {
|
|
25426
|
+
program.command("restore").description("Restore a FairyGUI project from published binaries").argument("<release-dir>", "Published release directory").requiredOption("-o, --output <dir>", "Output project directory").option("-p, --packages <a,b,c>", "Only restore specific packages (comma-separated)").option("-f, --force", "Overwrite a non-empty output directory").option("-t, --project-type <name|id>", "Override restored project type; default is unity").action(async (releaseDir, options) => {
|
|
25427
|
+
const inputDir = path.resolve(releaseDir);
|
|
25428
|
+
const outputDir = path.resolve(options.output);
|
|
25429
|
+
const pkgFilter = options.packages ? options.packages.split(",").map((value) => value.trim()).filter(Boolean) : void 0;
|
|
25430
|
+
const projectType = parseProjectType(options.projectType);
|
|
25431
|
+
const { cropImage, extractImage } = await createRestoreImageProcessors();
|
|
25432
|
+
console.log(`Restoring published FairyGUI project: ${inputDir}`);
|
|
25433
|
+
const result = await restore({
|
|
25434
|
+
inputDir,
|
|
25435
|
+
output: outputDir,
|
|
25436
|
+
fs: createNodeRestoreFs(),
|
|
25437
|
+
packages: pkgFilter,
|
|
25438
|
+
force: options.force,
|
|
25439
|
+
projectType,
|
|
25440
|
+
cropImage,
|
|
25441
|
+
extractImage
|
|
25442
|
+
});
|
|
25443
|
+
const packages = result.document.getRoot().listPackages();
|
|
25444
|
+
console.log(`\nDone! Output: ${result.projectPath}`);
|
|
25445
|
+
console.log(`Packages: ${packages.map((pkg) => pkg.getName()).join(", ")}`);
|
|
25446
|
+
for (const warning of result.warnings) console.warn(`Warning: ${warning}`);
|
|
25447
|
+
});
|
|
25448
|
+
}
|
|
24572
25449
|
function createNodeRestoreFs() {
|
|
24573
25450
|
return {
|
|
24574
25451
|
async readFile(filePath) {
|
|
@@ -24677,214 +25554,47 @@ async function createRestoreImageProcessors() {
|
|
|
24677
25554
|
}
|
|
24678
25555
|
};
|
|
24679
25556
|
}
|
|
24680
|
-
|
|
24681
|
-
|
|
24682
|
-
|
|
24683
|
-
|
|
24684
|
-
|
|
24685
|
-
|
|
24686
|
-
|
|
24687
|
-
|
|
24688
|
-
|
|
24689
|
-
|
|
24690
|
-
|
|
24691
|
-
|
|
24692
|
-
|
|
24693
|
-
|
|
24694
|
-
|
|
24695
|
-
console.log(` Fonts: ${report.totals.fonts}`);
|
|
24696
|
-
console.log(` MovieClips: ${report.totals.movieClips}`);
|
|
24697
|
-
console.log(` Components: ${report.totals.components}`);
|
|
24698
|
-
console.log(` DisplayObjs: ${report.totals.displayObjects}`);
|
|
24699
|
-
console.log(` Gears: ${report.totals.gears}`);
|
|
24700
|
-
console.log(` Controllers: ${report.totals.controllers}`);
|
|
24701
|
-
console.log(` Transitions: ${report.totals.transitions}`);
|
|
24702
|
-
console.log("\nPackage details:");
|
|
24703
|
-
for (const pkg of report.packages) {
|
|
24704
|
-
const res = pkg.resources;
|
|
24705
|
-
console.log(` ${pkg.name} (${pkg.id}): ${res.images.count} img, ${res.sounds.count} snd, ${res.fonts.count} font, ${res.components.count} comp`);
|
|
24706
|
-
}
|
|
25557
|
+
//#endregion
|
|
25558
|
+
//#region src/utils/package-version.ts
|
|
25559
|
+
const require = createRequire(import.meta.url);
|
|
25560
|
+
function getInjectedPackageVersion() {
|
|
25561
|
+
const version = import.meta.env?.PACKAGE_VERSION;
|
|
25562
|
+
return typeof version === "string" && version.length > 0 ? version : null;
|
|
25563
|
+
}
|
|
25564
|
+
function readPackageVersion() {
|
|
25565
|
+
const injectedVersion = getInjectedPackageVersion();
|
|
25566
|
+
if (injectedVersion) return injectedVersion;
|
|
25567
|
+
try {
|
|
25568
|
+
const pkg = require("../../package.json");
|
|
25569
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
|
|
25570
|
+
} catch {}
|
|
25571
|
+
return "0.0.0-dev";
|
|
24707
25572
|
}
|
|
24708
|
-
|
|
24709
|
-
|
|
24710
|
-
|
|
24711
|
-
|
|
24712
|
-
|
|
24713
|
-
|
|
24714
|
-
|
|
24715
|
-
|
|
24716
|
-
|
|
24717
|
-
|
|
24718
|
-
|
|
24719
|
-
|
|
24720
|
-
|
|
24721
|
-
|
|
24722
|
-
|
|
24723
|
-
|
|
24724
|
-
|
|
24725
|
-
|
|
24726
|
-
|
|
24727
|
-
cryengine: ProjectType.CryEngine,
|
|
24728
|
-
monogame: ProjectType.MonoGame,
|
|
24729
|
-
vision: ProjectType.Vision
|
|
24730
|
-
};
|
|
24731
|
-
const resolved = map[normalized];
|
|
24732
|
-
if (resolved === void 0) throw new Error(`Unknown project type: ${value}. Use a numeric id or one of: ${Object.keys(map).join(", ")}`);
|
|
24733
|
-
return resolved;
|
|
25573
|
+
//#endregion
|
|
25574
|
+
//#region src/cli.ts
|
|
25575
|
+
const PACKAGE_VERSION = readPackageVersion();
|
|
25576
|
+
function createProgram() {
|
|
25577
|
+
const program = new Command("ofgui");
|
|
25578
|
+
program.description("FairyGUI Headless Authoring CLI").version(PACKAGE_VERSION).showHelpAfterError();
|
|
25579
|
+
registerInspectCommand(program);
|
|
25580
|
+
registerPublishCommand(program);
|
|
25581
|
+
registerRestoreCommand(program);
|
|
25582
|
+
registerBackendCapabilitiesCommand(program);
|
|
25583
|
+
program.addHelpText("after", [
|
|
25584
|
+
"",
|
|
25585
|
+
"Alias:",
|
|
25586
|
+
" openfairygui",
|
|
25587
|
+
"",
|
|
25588
|
+
"Input can be a .fairy file or a project root directory (auto-discovers .fairy file).",
|
|
25589
|
+
"File extension and binary format are read from project settings."
|
|
25590
|
+
].join("\n"));
|
|
25591
|
+
return program;
|
|
24734
25592
|
}
|
|
24735
|
-
async function
|
|
24736
|
-
|
|
24737
|
-
args,
|
|
24738
|
-
options: {
|
|
24739
|
-
output: {
|
|
24740
|
-
type: "string",
|
|
24741
|
-
short: "o"
|
|
24742
|
-
},
|
|
24743
|
-
packages: { type: "string" },
|
|
24744
|
-
force: { type: "boolean" },
|
|
24745
|
-
"project-type": { type: "string" }
|
|
24746
|
-
},
|
|
24747
|
-
allowPositionals: true
|
|
24748
|
-
});
|
|
24749
|
-
if (positionals.length === 0 || !values.output) {
|
|
24750
|
-
console.error("Usage: ofgui restore <release-dir> --output <dir> [--packages a,b,c] [--force]");
|
|
24751
|
-
process.exit(1);
|
|
24752
|
-
}
|
|
24753
|
-
const releaseDir = path.resolve(positionals[0]);
|
|
24754
|
-
const outputDir = path.resolve(values.output);
|
|
24755
|
-
const pkgFilter = values.packages ? values.packages.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
24756
|
-
const projectType = parseProjectType(values["project-type"]);
|
|
24757
|
-
const { cropImage, extractImage } = await createRestoreImageProcessors();
|
|
24758
|
-
console.log(`Restoring published FairyGUI project: ${releaseDir}`);
|
|
24759
|
-
const result = await restore({
|
|
24760
|
-
inputDir: releaseDir,
|
|
24761
|
-
output: outputDir,
|
|
24762
|
-
fs: createNodeRestoreFs(),
|
|
24763
|
-
packages: pkgFilter,
|
|
24764
|
-
force: values.force,
|
|
24765
|
-
projectType,
|
|
24766
|
-
cropImage,
|
|
24767
|
-
extractImage
|
|
24768
|
-
});
|
|
24769
|
-
const packages = result.document.getRoot().listPackages();
|
|
24770
|
-
console.log(`\nDone! Output: ${result.projectPath}`);
|
|
24771
|
-
console.log(`Packages: ${packages.map((pkg) => pkg.getName()).join(", ")}`);
|
|
24772
|
-
for (const warning of result.warnings) console.warn(`Warning: ${warning}`);
|
|
24773
|
-
}
|
|
24774
|
-
async function cmdPublish(args) {
|
|
24775
|
-
const { values, positionals } = parseArgs({
|
|
24776
|
-
args,
|
|
24777
|
-
options: {
|
|
24778
|
-
output: {
|
|
24779
|
-
type: "string",
|
|
24780
|
-
short: "o"
|
|
24781
|
-
},
|
|
24782
|
-
compressed: { type: "boolean" },
|
|
24783
|
-
packages: { type: "string" },
|
|
24784
|
-
branch: { type: "string" },
|
|
24785
|
-
"project-type": { type: "string" }
|
|
24786
|
-
},
|
|
24787
|
-
allowPositionals: true
|
|
24788
|
-
});
|
|
24789
|
-
if (positionals.length === 0 || !values.output) {
|
|
24790
|
-
console.error("Usage: ofgui publish <project-dir> --output <dir> [--compressed] [--packages a,b,c] [--branch name]");
|
|
24791
|
-
process.exit(1);
|
|
24792
|
-
}
|
|
24793
|
-
const fairyPath = await resolveFairyPath(positionals[0]);
|
|
24794
|
-
const projectDir = path.dirname(fairyPath);
|
|
24795
|
-
const outputDir = path.resolve(values.output);
|
|
24796
|
-
console.log(`Reading project: ${fairyPath}`);
|
|
24797
|
-
const doc = await new NodeIO().readProject(fairyPath);
|
|
24798
|
-
const projectType = parseProjectType(values["project-type"]);
|
|
24799
|
-
if (projectType !== void 0) doc.getRoot().setProjectType(projectType);
|
|
24800
|
-
const pkgFilter = values.packages ? values.packages.split(",").map((s) => s.trim()) : void 0;
|
|
24801
|
-
const resolved = resolvePublishOptions(doc, {
|
|
24802
|
-
compressed: values.compressed,
|
|
24803
|
-
packages: pkgFilter
|
|
24804
|
-
});
|
|
24805
|
-
console.log(`Settings: ext=${resolved.fileExtension}, compressed=${resolved.compressed}`);
|
|
24806
|
-
if (values.branch) console.log(`Active branch: ${values.branch}`);
|
|
24807
|
-
const atlasConfig = {
|
|
24808
|
-
...resolved.atlas,
|
|
24809
|
-
readFileRaw: async (filePath) => {
|
|
24810
|
-
const buf = await fs.readFile(filePath);
|
|
24811
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
24812
|
-
}
|
|
24813
|
-
};
|
|
24814
|
-
let encoder;
|
|
24815
|
-
try {
|
|
24816
|
-
const sharp = await import("sharp");
|
|
24817
|
-
encoder = sharp.default ?? sharp;
|
|
24818
|
-
console.log("Sharp loaded — atlas PNGs will be generated.");
|
|
24819
|
-
} catch {
|
|
24820
|
-
console.log("Sharp not available — atlas PNGs will NOT be generated (layout only).");
|
|
24821
|
-
console.log(" Install sharp to enable: pnpm add sharp");
|
|
24822
|
-
}
|
|
24823
|
-
await doc.transform(publish({
|
|
24824
|
-
output: outputDir,
|
|
24825
|
-
compressed: resolved.compressed,
|
|
24826
|
-
fileExtension: resolved.fileExtension,
|
|
24827
|
-
packages: resolved.packages,
|
|
24828
|
-
fs: {
|
|
24829
|
-
async readFileRaw(filePath) {
|
|
24830
|
-
const buf = await fs.readFile(filePath);
|
|
24831
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
24832
|
-
},
|
|
24833
|
-
async writeFileRaw(filePath, data) {
|
|
24834
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
24835
|
-
await fs.writeFile(filePath, data);
|
|
24836
|
-
},
|
|
24837
|
-
async mkdir(dirPath) {
|
|
24838
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
24839
|
-
},
|
|
24840
|
-
async readdir(dirPath) {
|
|
24841
|
-
return fs.readdir(dirPath);
|
|
24842
|
-
},
|
|
24843
|
-
async deleteFile(filePath) {
|
|
24844
|
-
await fs.rm(filePath, { force: true });
|
|
24845
|
-
},
|
|
24846
|
-
join(...paths) {
|
|
24847
|
-
return path.join(...paths);
|
|
24848
|
-
}
|
|
24849
|
-
},
|
|
24850
|
-
encoder,
|
|
24851
|
-
basePath: path.join(projectDir, "assets"),
|
|
24852
|
-
atlas: atlasConfig,
|
|
24853
|
-
branch: values.branch
|
|
24854
|
-
}));
|
|
24855
|
-
console.log(`\nDone! Output: ${outputDir}`);
|
|
24856
|
-
}
|
|
24857
|
-
async function cmdBackendCapabilities(args) {
|
|
24858
|
-
if (args.length === 0) {
|
|
24859
|
-
console.error("Usage: ofgui backend-capabilities <project-dir>");
|
|
24860
|
-
process.exit(1);
|
|
24861
|
-
}
|
|
24862
|
-
const runtime = createNodeBackendRuntime();
|
|
24863
|
-
const opened = await runtime.openSession({ projectPath: path.resolve(args[0]) });
|
|
24864
|
-
if (!opened.ok) {
|
|
24865
|
-
console.error(`backend-capabilities: ${opened.error.message}`);
|
|
24866
|
-
process.exit(1);
|
|
24867
|
-
}
|
|
24868
|
-
const capabilities = runtime.getCapabilities();
|
|
24869
|
-
if (!capabilities.ok) {
|
|
24870
|
-
console.error("backend-capabilities: failed to read capabilities");
|
|
24871
|
-
await runtime.closeSession({ sessionId: opened.data.sessionId });
|
|
24872
|
-
process.exit(1);
|
|
24873
|
-
}
|
|
24874
|
-
console.log(`Session: ${opened.data.sessionId}`);
|
|
24875
|
-
console.log(`Project: ${opened.data.canonicalProjectPath}`);
|
|
24876
|
-
console.log(`Revision: ${opened.data.revision}`);
|
|
24877
|
-
console.log(`Runtime owner: ${capabilities.data.runtimeOwner}`);
|
|
24878
|
-
console.log(`Transaction owner: ${capabilities.data.transactionKernelOwner}`);
|
|
24879
|
-
console.log(`App seam owner: ${capabilities.data.appSeamOwner}`);
|
|
24880
|
-
const closed = await runtime.closeSession({ sessionId: opened.data.sessionId });
|
|
24881
|
-
if (!closed.ok) {
|
|
24882
|
-
console.error(`backend-capabilities: ${closed.error.message}`);
|
|
24883
|
-
process.exit(1);
|
|
24884
|
-
}
|
|
25593
|
+
async function main() {
|
|
25594
|
+
await createProgram().parseAsync(process.argv);
|
|
24885
25595
|
}
|
|
24886
25596
|
main().catch((err) => {
|
|
24887
|
-
console.error(err);
|
|
25597
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
24888
25598
|
process.exit(1);
|
|
24889
25599
|
});
|
|
24890
25600
|
//#endregion
|