@openfairygui/functions 0.2.0-alpha.0 → 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/README.md +4 -0
- package/dist/index.cjs +872 -282
- package/dist/index.d.cts +143 -79
- package/dist/index.d.ts +143 -79
- package/dist/index.js +869 -283
- package/dist/uam-transaction.cjs +79 -0
- package/dist/uam-transaction.d.cts +42 -0
- package/dist/uam-transaction.d.ts +42 -0
- package/dist/uam-transaction.js +78 -0
- package/package.json +66 -53
- package/src/atlas.ts +502 -146
- package/src/codegen.ts +104 -66
- package/src/index.ts +25 -1
- package/src/plugins/loader.ts +85 -0
- package/src/plugins/types.ts +47 -0
- package/src/publish.ts +499 -105
- package/src/restore.ts +12 -5
- package/src/shared-types.ts +1 -0
- package/src/uam-transaction.ts +69 -1
- package/src/utils.ts +28 -0
package/src/publish.ts
CHANGED
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
} from '@openfairygui/core';
|
|
18
18
|
import { createTransform } from './utils.js';
|
|
19
19
|
import { atlas, type AtlasOptions } from './atlas.js';
|
|
20
|
-
import { publishCodeGeneration } from './codegen.js';
|
|
20
|
+
import { publishCodeGeneration, resolveProjectBasePath } from './codegen.js';
|
|
21
|
+
import { formatPluginError, loadPlugins, type LoadedPlugin } from './plugins/loader.js';
|
|
21
22
|
import type {
|
|
22
23
|
CliPublishSettings,
|
|
23
24
|
HasOptionalFont,
|
|
@@ -28,10 +29,10 @@ import type {
|
|
|
28
29
|
|
|
29
30
|
export interface PublishOptions {
|
|
30
31
|
/**
|
|
31
|
-
* Output directory for published files (.fui + atlas PNGs).
|
|
32
|
-
*
|
|
32
|
+
* Output directory override for published files (.fui + atlas PNGs).
|
|
33
|
+
* When omitted, publish uses package-level or project-level publish paths.
|
|
33
34
|
*/
|
|
34
|
-
output
|
|
35
|
+
output?: string;
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Compress the binary data with zlib raw deflate. Default: false.
|
|
@@ -96,6 +97,58 @@ export interface ResolvedPublishOptions {
|
|
|
96
97
|
atlas: ResolvedPublishAtlasOptions;
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
interface ResolvedProjectPublishConfig extends ResolvedPublishOptions {
|
|
101
|
+
projectType: number;
|
|
102
|
+
includeBranches: boolean;
|
|
103
|
+
activeBranch: string;
|
|
104
|
+
includeHighResolution: number;
|
|
105
|
+
separatedAtlasForBranch: boolean;
|
|
106
|
+
globalOutputPath: string;
|
|
107
|
+
globalBranchOutputPath: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface ResolvedPackagePublishPlan {
|
|
111
|
+
pkg: Package;
|
|
112
|
+
outputDir?: string;
|
|
113
|
+
publishName: string;
|
|
114
|
+
fileName: string;
|
|
115
|
+
compressed: boolean;
|
|
116
|
+
fileExtension: string;
|
|
117
|
+
includeBranches: boolean;
|
|
118
|
+
activeBranch: string;
|
|
119
|
+
includeHighResolution: number;
|
|
120
|
+
separatedAtlasForBranch: boolean;
|
|
121
|
+
atlas: ResolvedPublishAtlasOptions;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function runPublishPluginHook(
|
|
125
|
+
plugins: LoadedPlugin[],
|
|
126
|
+
hook: 'onPublishStart' | 'onPublishEnd',
|
|
127
|
+
doc: Document,
|
|
128
|
+
options: PublishOptions,
|
|
129
|
+
): Promise<void> {
|
|
130
|
+
const logger = doc.getLogger();
|
|
131
|
+
for (const plugin of plugins) {
|
|
132
|
+
const fn = plugin.plugin[hook];
|
|
133
|
+
if (typeof fn !== 'function') continue;
|
|
134
|
+
try {
|
|
135
|
+
await fn(doc, options);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
logger.warn(`publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resolvePublishPluginsDir(doc: Document, options: PublishOptions): string {
|
|
143
|
+
const fs = options.fs;
|
|
144
|
+
const projectDir = doc.getProjectDir?.() ?? '';
|
|
145
|
+
if (projectDir) return fs?.join ? fs.join(projectDir, 'plugins') : `${projectDir.replace(/[/\\]+$/, '')}/plugins`;
|
|
146
|
+
|
|
147
|
+
const projectBasePath = resolveProjectBasePath(options.basePath);
|
|
148
|
+
if (!projectBasePath) return '';
|
|
149
|
+
return fs?.join ? fs.join(projectBasePath, 'plugins') : `${projectBasePath.replace(/[/\\]+$/, '')}/plugins`;
|
|
150
|
+
}
|
|
151
|
+
|
|
99
152
|
interface ImageResourceExtras extends Record<string, unknown> {
|
|
100
153
|
_fileName?: string;
|
|
101
154
|
}
|
|
@@ -112,7 +165,9 @@ interface BranchAwarePublishedResource {
|
|
|
112
165
|
interface PackagePublishContext {
|
|
113
166
|
referencedIds: Set<string>;
|
|
114
167
|
publishedResourceIds: Set<string>;
|
|
168
|
+
exportedResourceIds: Set<string>;
|
|
115
169
|
pixelHitTestImageIds: Set<string>;
|
|
170
|
+
highResolutionItemIds: Map<string, Array<string | null>>;
|
|
116
171
|
effectiveResourceIds: Map<string, string>;
|
|
117
172
|
includeBranches: boolean;
|
|
118
173
|
}
|
|
@@ -138,8 +193,10 @@ interface TransitionWithPublishRefs {
|
|
|
138
193
|
|
|
139
194
|
interface ChildWithPublishRefs extends HasOptionalFont {
|
|
140
195
|
getId?(): string;
|
|
196
|
+
getPackageId?(): string;
|
|
141
197
|
getSrc?(): string;
|
|
142
198
|
getUrl?(): string;
|
|
199
|
+
getInstanceSound?(): string;
|
|
143
200
|
getDefaultItem?(): string;
|
|
144
201
|
getIcon?(): string;
|
|
145
202
|
getSelectedIcon?(): string;
|
|
@@ -273,6 +330,24 @@ export function resolvePublishOptions(
|
|
|
273
330
|
};
|
|
274
331
|
}
|
|
275
332
|
|
|
333
|
+
function trimTrailingSlashes(value: string): string {
|
|
334
|
+
return value.replace(/[/\\]+$/, '');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function isAbsolutePathLike(value: string): boolean {
|
|
338
|
+
return /^(?:[a-zA-Z]:[/\\]|[/\\]{1,2})/u.test(value);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function joinPathSegments(left: string, right: string): string {
|
|
342
|
+
const normalizedLeft = trimTrailingSlashes(left);
|
|
343
|
+
const normalizedRight = right.replace(/^[/\\]+/, '');
|
|
344
|
+
if (!normalizedLeft) return normalizedRight;
|
|
345
|
+
if (!normalizedRight) return normalizedLeft;
|
|
346
|
+
const separator = normalizedLeft.includes('\\') ? '\\' : '/';
|
|
347
|
+
return `${normalizedLeft}${separator}${normalizedRight}`;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
|
|
276
351
|
function dirname(filePath: string): string {
|
|
277
352
|
const trimmed = filePath.replace(/[/\\]+$/, '');
|
|
278
353
|
const match = trimmed.match(/^(.*)[/\\][^/\\]+$/);
|
|
@@ -311,6 +386,10 @@ function isMovieClipResource(resource: ReturnType<Package['listResources']>[numb
|
|
|
311
386
|
return resource.propertyType === 'MovieClipResource';
|
|
312
387
|
}
|
|
313
388
|
|
|
389
|
+
function isHighResolutionResource(resource: ReturnType<Package['listResources']>[number]): resource is ImageResource | MovieClipResource {
|
|
390
|
+
return isImageResource(resource) || isMovieClipResource(resource);
|
|
391
|
+
}
|
|
392
|
+
|
|
314
393
|
function isMiscResource(resource: ReturnType<Package['listResources']>[number]): resource is MiscResource {
|
|
315
394
|
return resource.propertyType === 'MiscResource';
|
|
316
395
|
}
|
|
@@ -423,14 +502,15 @@ function extname(fileName: string): string {
|
|
|
423
502
|
return normalized.slice(lastDot);
|
|
424
503
|
}
|
|
425
504
|
|
|
426
|
-
function resolvePublishedMiscFileName(resource: MiscResource): string {
|
|
505
|
+
function resolvePublishedMiscFileName(resource: MiscResource, projectType: number): string {
|
|
427
506
|
const file = resource.getFile();
|
|
507
|
+
if (projectType !== UNITY_PROJECT_TYPE) return file;
|
|
428
508
|
if (file.toLowerCase().endsWith('.atlas')) return `${file}.txt`;
|
|
429
509
|
return file;
|
|
430
510
|
}
|
|
431
511
|
|
|
432
|
-
function resolvePublishedSkeletonFileName(resource: SpineResource | DragonBonesResource): string {
|
|
433
|
-
if (isSpineResource(resource) && resource.getFile().toLowerCase().endsWith('.skel')) {
|
|
512
|
+
function resolvePublishedSkeletonFileName(resource: SpineResource | DragonBonesResource, projectType: number): string {
|
|
513
|
+
if (projectType === UNITY_PROJECT_TYPE && isSpineResource(resource) && resource.getFile().toLowerCase().endsWith('.skel')) {
|
|
434
514
|
return `${resource.getFile()}.bytes`;
|
|
435
515
|
}
|
|
436
516
|
return resource.getFile();
|
|
@@ -481,11 +561,93 @@ function buildBranchResourceKey(resource: {
|
|
|
481
561
|
return `${resource.propertyType}|${resource.getPath() ?? ''}|${resource.getName() ?? ''}`;
|
|
482
562
|
}
|
|
483
563
|
|
|
564
|
+
const HIGH_RESOLUTION_LEVELS = [
|
|
565
|
+
{ scale: 2, bit: 1, slot: 0 },
|
|
566
|
+
{ scale: 3, bit: 2, slot: 1 },
|
|
567
|
+
{ scale: 4, bit: 4, slot: 2 },
|
|
568
|
+
] as const;
|
|
569
|
+
|
|
570
|
+
function buildHighResolutionResourceKey(resource: {
|
|
571
|
+
propertyType: string;
|
|
572
|
+
getPath(): string;
|
|
573
|
+
getName(): string;
|
|
574
|
+
getBranch?(): string;
|
|
575
|
+
}, name = resource.getName()): string {
|
|
576
|
+
return `${resource.propertyType}|${resource.getBranch?.() ?? ''}|${resource.getPath() ?? ''}|${name}`;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
function isHighResolutionVariantName(name: string): boolean {
|
|
580
|
+
return /@(?:2|3|4)x(?:\.[^./\\]+)?$/iu.test(name);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function appendHighResolutionScaleToName(name: string, scale: number): string {
|
|
584
|
+
const extensionIndex = name.lastIndexOf('.');
|
|
585
|
+
if (extensionIndex > 0) {
|
|
586
|
+
return `${name.slice(0, extensionIndex)}@${scale}x${name.slice(extensionIndex)}`;
|
|
587
|
+
}
|
|
588
|
+
return `${name}@${scale}x`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
function trimTrailingMissingHighResolutionIds(ids: Array<string | null>): Array<string | null> {
|
|
592
|
+
while (ids.length > 0 && !ids[ids.length - 1]) {
|
|
593
|
+
ids.pop();
|
|
594
|
+
}
|
|
595
|
+
return ids;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function collectHighResolutionItemIds(
|
|
599
|
+
resources: ReturnType<Package['listResources']>,
|
|
600
|
+
publishedResourceIds: Set<string>,
|
|
601
|
+
includeHighResolution: number,
|
|
602
|
+
): Map<string, Array<string | null>> {
|
|
603
|
+
const result = new Map<string, Array<string | null>>();
|
|
604
|
+
if (includeHighResolution <= 0) return result;
|
|
605
|
+
|
|
606
|
+
const highResolutionResourceByKey = new Map<string, ImageResource | MovieClipResource>();
|
|
607
|
+
for (const resource of resources) {
|
|
608
|
+
if (!isHighResolutionResource(resource)) continue;
|
|
609
|
+
highResolutionResourceByKey.set(buildHighResolutionResourceKey(resource), resource);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
for (const resource of resources) {
|
|
613
|
+
if (!isHighResolutionResource(resource)) continue;
|
|
614
|
+
if (!publishedResourceIds.has(resource.getId())) continue;
|
|
615
|
+
if (isHighResolutionVariantName(resource.getName())) continue;
|
|
616
|
+
|
|
617
|
+
const ids: Array<string | null> = [];
|
|
618
|
+
for (const level of HIGH_RESOLUTION_LEVELS) {
|
|
619
|
+
if ((includeHighResolution & level.bit) === 0) {
|
|
620
|
+
ids[level.slot] = null;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const highResolutionResource = highResolutionResourceByKey.get(
|
|
625
|
+
buildHighResolutionResourceKey(resource, appendHighResolutionScaleToName(resource.getName(), level.scale)),
|
|
626
|
+
);
|
|
627
|
+
if (!highResolutionResource) {
|
|
628
|
+
ids[level.slot] = null;
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const highResolutionId = highResolutionResource.getId();
|
|
633
|
+
publishedResourceIds.add(highResolutionId);
|
|
634
|
+
ids[level.slot] = highResolutionId;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
trimTrailingMissingHighResolutionIds(ids);
|
|
638
|
+
if (ids.length > 0) result.set(resource.getId(), ids);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
|
|
484
644
|
function collectPackagePublishContext(
|
|
485
645
|
pkg: Package,
|
|
486
646
|
options: {
|
|
647
|
+
projectType: number;
|
|
487
648
|
includeBranches: boolean;
|
|
488
649
|
activeBranch: string;
|
|
650
|
+
includeHighResolution: number;
|
|
489
651
|
},
|
|
490
652
|
): PackagePublishContext {
|
|
491
653
|
const pkgId = pkg.getId();
|
|
@@ -494,6 +656,27 @@ function collectPackagePublishContext(
|
|
|
494
656
|
const referencedIds = new Set<string>();
|
|
495
657
|
const pixelHitTestImageIds = new Set<string>();
|
|
496
658
|
const spriteItemIds = new Set<string>();
|
|
659
|
+
const collectExportedResourceIds = (
|
|
660
|
+
sourceResources: ReturnType<Package['listResources']>,
|
|
661
|
+
sourcePublishedResourceIds: Set<string>,
|
|
662
|
+
): Set<string> => {
|
|
663
|
+
const exportedResourceIds = new Set<string>(sourcePublishedResourceIds);
|
|
664
|
+
const resourcesById = new Map(sourceResources.map((resource) => [resource.getId(), resource] as const));
|
|
665
|
+
let changed = true;
|
|
666
|
+
while (changed) {
|
|
667
|
+
changed = false;
|
|
668
|
+
for (const resourceId of [...exportedResourceIds]) {
|
|
669
|
+
const resource = resourcesById.get(resourceId);
|
|
670
|
+
if (!resource || !isSkeletonResource(resource)) continue;
|
|
671
|
+
for (const requiredId of resource.getRequireIds()) {
|
|
672
|
+
if (!requiredId || exportedResourceIds.has(requiredId)) continue;
|
|
673
|
+
exportedResourceIds.add(requiredId);
|
|
674
|
+
changed = true;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return exportedResourceIds;
|
|
679
|
+
};
|
|
497
680
|
|
|
498
681
|
for (const atlas of pkg.listAtlases()) {
|
|
499
682
|
for (const sprite of atlas.listSprites()) {
|
|
@@ -531,6 +714,7 @@ function collectPackagePublishContext(
|
|
|
531
714
|
child.getSelectedIcon?.(),
|
|
532
715
|
child.getDropdown?.(),
|
|
533
716
|
child.getSound?.(),
|
|
717
|
+
child.getInstanceSound?.(),
|
|
534
718
|
child.getInstanceIcon?.(),
|
|
535
719
|
child.getInstanceSelectedIcon?.(),
|
|
536
720
|
child.getVtScrollBarRes?.(),
|
|
@@ -608,20 +792,16 @@ function collectPackagePublishContext(
|
|
|
608
792
|
}
|
|
609
793
|
}
|
|
610
794
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
changed = false;
|
|
614
|
-
for (const resource of resources) {
|
|
615
|
-
if (!isSkeletonResource(resource)) continue;
|
|
616
|
-
if (!publishedResourceIds.has(resource.getId())) continue;
|
|
617
|
-
for (const requiredId of resource.getRequireIds()) {
|
|
618
|
-
if (!requiredId || publishedResourceIds.has(requiredId)) continue;
|
|
619
|
-
publishedResourceIds.add(requiredId);
|
|
620
|
-
changed = true;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
795
|
+
for (const resourceId of collectExportedResourceIds(resources, publishedResourceIds)) {
|
|
796
|
+
publishedResourceIds.add(resourceId);
|
|
623
797
|
}
|
|
624
798
|
|
|
799
|
+
const highResolutionItemIds = collectHighResolutionItemIds(
|
|
800
|
+
resources,
|
|
801
|
+
publishedResourceIds,
|
|
802
|
+
options.includeHighResolution,
|
|
803
|
+
);
|
|
804
|
+
|
|
625
805
|
if (!options.includeBranches) {
|
|
626
806
|
const mainByKey = new Map<string, ReturnType<Package['listResources']>[number]>();
|
|
627
807
|
const activeBranchByKey = new Map<string, ReturnType<Package['listResources']>[number]>();
|
|
@@ -685,7 +865,9 @@ function collectPackagePublishContext(
|
|
|
685
865
|
return {
|
|
686
866
|
referencedIds,
|
|
687
867
|
publishedResourceIds,
|
|
868
|
+
exportedResourceIds: collectExportedResourceIds(resources, publishedResourceIds),
|
|
688
869
|
pixelHitTestImageIds,
|
|
870
|
+
highResolutionItemIds,
|
|
689
871
|
effectiveResourceIds,
|
|
690
872
|
includeBranches: false,
|
|
691
873
|
};
|
|
@@ -694,7 +876,9 @@ function collectPackagePublishContext(
|
|
|
694
876
|
return {
|
|
695
877
|
referencedIds,
|
|
696
878
|
publishedResourceIds,
|
|
879
|
+
exportedResourceIds: collectExportedResourceIds(resources, publishedResourceIds),
|
|
697
880
|
pixelHitTestImageIds,
|
|
881
|
+
highResolutionItemIds,
|
|
698
882
|
effectiveResourceIds: new Map([...publishedResourceIds].map((resourceId) => [resourceId, resourceId])),
|
|
699
883
|
includeBranches: true,
|
|
700
884
|
};
|
|
@@ -768,29 +952,42 @@ async function annotatePackagePublishArtifacts(
|
|
|
768
952
|
basePath: string | undefined,
|
|
769
953
|
encoder: PublishEncoder | undefined,
|
|
770
954
|
options: {
|
|
955
|
+
projectType: number;
|
|
771
956
|
includeBranches: boolean;
|
|
772
957
|
activeBranch: string;
|
|
958
|
+
includeHighResolution: number;
|
|
773
959
|
},
|
|
774
960
|
): Promise<void> {
|
|
775
|
-
const {
|
|
961
|
+
const {
|
|
962
|
+
publishedResourceIds,
|
|
963
|
+
exportedResourceIds,
|
|
964
|
+
pixelHitTestImageIds,
|
|
965
|
+
highResolutionItemIds,
|
|
966
|
+
effectiveResourceIds,
|
|
967
|
+
includeBranches,
|
|
968
|
+
} = collectPackagePublishContext(pkg, options);
|
|
776
969
|
for (const resource of pkg.listResources()) {
|
|
777
970
|
setPublishedIdExtra(resource, effectiveResourceIds.get(resource.getId()) ?? null);
|
|
971
|
+
if (isHighResolutionResource(resource)) {
|
|
972
|
+
resource.setHighResolutionItemIds(highResolutionItemIds.get(resource.getId()) ?? []);
|
|
973
|
+
}
|
|
778
974
|
}
|
|
779
975
|
await applyPixelHitTests(pkg, pixelHitTestImageIds, basePath, encoder);
|
|
780
976
|
const extras = (pkg.getExtras() as PackagePublishArtifactsExtras | undefined) ?? {};
|
|
781
977
|
pkg.setExtras({
|
|
782
978
|
...extras,
|
|
783
979
|
publishedResourceIds: [...publishedResourceIds].sort((a, b) => a.localeCompare(b)),
|
|
980
|
+
exportedResourceIds: [...exportedResourceIds].sort((a, b) => a.localeCompare(b)),
|
|
784
981
|
publishedIncludeBranches: includeBranches,
|
|
785
982
|
publishedEffectiveResourceIds: Object.fromEntries(effectiveResourceIds),
|
|
786
983
|
});
|
|
787
984
|
for (const resource of pkg.listResources()) {
|
|
788
985
|
if (isMiscResource(resource)) {
|
|
789
|
-
setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource));
|
|
986
|
+
setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource, options.projectType));
|
|
790
987
|
continue;
|
|
791
988
|
}
|
|
792
989
|
if (isSkeletonResource(resource)) {
|
|
793
|
-
setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource));
|
|
990
|
+
setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource, options.projectType));
|
|
794
991
|
}
|
|
795
992
|
}
|
|
796
993
|
}
|
|
@@ -800,6 +997,11 @@ function getAnnotatedPublishedResourceIds(pkg: Package): Set<string> {
|
|
|
800
997
|
return new Set(extras.publishedResourceIds ?? []);
|
|
801
998
|
}
|
|
802
999
|
|
|
1000
|
+
function getAnnotatedExportedResourceIds(pkg: Package): Set<string> {
|
|
1001
|
+
const extras = (pkg.getExtras() as PackagePublishArtifactsExtras | undefined) ?? {};
|
|
1002
|
+
return new Set(extras.exportedResourceIds ?? []);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
803
1005
|
function getPublishedSkeletonDependencyImageIds(
|
|
804
1006
|
pkg: Package,
|
|
805
1007
|
publishedResourceIds: Set<string>,
|
|
@@ -863,14 +1065,14 @@ async function exportPackageExternalResources(
|
|
|
863
1065
|
readFileRaw: PublishFileSystem['readFileRaw'] | undefined,
|
|
864
1066
|
logger: Document['getLogger'] extends () => infer T ? T : never,
|
|
865
1067
|
): Promise<void> {
|
|
866
|
-
const
|
|
867
|
-
const skeletonDependencyImageIds = getPublishedSkeletonDependencyImageIds(pkg,
|
|
868
|
-
if (
|
|
1068
|
+
const exportedResourceIds = getAnnotatedExportedResourceIds(pkg);
|
|
1069
|
+
const skeletonDependencyImageIds = getPublishedSkeletonDependencyImageIds(pkg, exportedResourceIds);
|
|
1070
|
+
if (exportedResourceIds.size === 0) return;
|
|
869
1071
|
if (!basePath || !readFileRaw) {
|
|
870
1072
|
const hasPublishedExternal = pkg.listResources().some((resource) => {
|
|
871
1073
|
return (
|
|
872
1074
|
(isMiscResource(resource) || isSkeletonResource(resource))
|
|
873
|
-
&&
|
|
1075
|
+
&& exportedResourceIds.has(resource.getId())
|
|
874
1076
|
) || skeletonDependencyImageIds.has(resource.getId());
|
|
875
1077
|
});
|
|
876
1078
|
if (hasPublishedExternal) {
|
|
@@ -881,7 +1083,7 @@ async function exportPackageExternalResources(
|
|
|
881
1083
|
|
|
882
1084
|
for (const resource of pkg.listResources()) {
|
|
883
1085
|
const resourceId = resource.getId();
|
|
884
|
-
const isSkeletonExternal =
|
|
1086
|
+
const isSkeletonExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSkeletonResource(resource));
|
|
885
1087
|
const isSkeletonImageDependency = skeletonDependencyImageIds.has(resourceId) && isImageResource(resource);
|
|
886
1088
|
if (!isSkeletonExternal && !isSkeletonImageDependency) continue;
|
|
887
1089
|
|
|
@@ -932,17 +1134,145 @@ async function exportPackageExternalResources(
|
|
|
932
1134
|
*/
|
|
933
1135
|
export function publish(options: PublishOptions): Transform {
|
|
934
1136
|
return createTransform('publish', async (doc: Document): Promise<void> => {
|
|
1137
|
+
const resolveConfiguredOutputPath = (value?: string, projectBasePath?: string): string | undefined => {
|
|
1138
|
+
const trimmed = value?.trim();
|
|
1139
|
+
if (!trimmed) return undefined;
|
|
1140
|
+
if (isAbsolutePathLike(trimmed) || !projectBasePath) {
|
|
1141
|
+
return trimTrailingSlashes(trimmed);
|
|
1142
|
+
}
|
|
1143
|
+
return trimTrailingSlashes(options.fs ? options.fs.join(projectBasePath, trimmed) : joinPathSegments(projectBasePath, trimmed));
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
const resolveProjectPublishConfig = (): ResolvedProjectPublishConfig => {
|
|
1147
|
+
const settings = (doc.getRoot().getSettings?.() ?? {}) as RootProjectSettings;
|
|
1148
|
+
const publishSettings: CliPublishSettings = settings.publish ?? {};
|
|
1149
|
+
const resolved = resolvePublishOptions(doc, {
|
|
1150
|
+
compressed: options.compressed,
|
|
1151
|
+
fileExtension: options.fileExtension,
|
|
1152
|
+
packages: options.packages,
|
|
1153
|
+
atlas: options.atlas,
|
|
1154
|
+
});
|
|
1155
|
+
const branchProcessing = publishSettings.branchProcessing ?? 0;
|
|
1156
|
+
const includeBranches = branchProcessing === 0;
|
|
1157
|
+
|
|
1158
|
+
return {
|
|
1159
|
+
...resolved,
|
|
1160
|
+
projectType: doc.getRoot().getProjectType(),
|
|
1161
|
+
includeBranches,
|
|
1162
|
+
activeBranch: includeBranches ? '' : (options.branch ?? ''),
|
|
1163
|
+
includeHighResolution: publishSettings.includeHighResolution ?? 0,
|
|
1164
|
+
separatedAtlasForBranch: includeBranches && publishSettings.seperatedAtlasForBranch === true,
|
|
1165
|
+
globalOutputPath: publishSettings.path?.trim() ?? '',
|
|
1166
|
+
globalBranchOutputPath: publishSettings.branchPath?.trim() ?? '',
|
|
1167
|
+
};
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
const resolvePackagePublishPlan = (pkg: Package, config: ResolvedProjectPublishConfig, projectBasePath?: string): ResolvedPackagePublishPlan => {
|
|
1171
|
+
let outputDir: string | undefined;
|
|
1172
|
+
|
|
1173
|
+
if (options.output) {
|
|
1174
|
+
outputDir = trimTrailingSlashes(options.output);
|
|
1175
|
+
} else {
|
|
1176
|
+
const candidates: Array<string | undefined> = [];
|
|
1177
|
+
if (!config.includeBranches && config.activeBranch) {
|
|
1178
|
+
candidates.push(pkg.getPublishBranchPath(), config.globalBranchOutputPath);
|
|
1179
|
+
}
|
|
1180
|
+
candidates.push(pkg.getPublishPath(), config.globalOutputPath);
|
|
1181
|
+
|
|
1182
|
+
for (const candidate of candidates) {
|
|
1183
|
+
const resolved = resolveConfiguredOutputPath(candidate, projectBasePath);
|
|
1184
|
+
if (!resolved) continue;
|
|
1185
|
+
outputDir = resolved;
|
|
1186
|
+
break;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
const publishName = pkg.getPublishName() || pkg.getName();
|
|
1190
|
+
|
|
1191
|
+
return {
|
|
1192
|
+
pkg,
|
|
1193
|
+
outputDir,
|
|
1194
|
+
publishName,
|
|
1195
|
+
fileName: resolvePublishFileName(publishName, config.fileExtension),
|
|
1196
|
+
compressed: config.compressed,
|
|
1197
|
+
fileExtension: config.fileExtension,
|
|
1198
|
+
includeBranches: config.includeBranches,
|
|
1199
|
+
activeBranch: config.activeBranch,
|
|
1200
|
+
includeHighResolution: config.includeHighResolution,
|
|
1201
|
+
separatedAtlasForBranch: config.separatedAtlasForBranch,
|
|
1202
|
+
atlas: config.atlas,
|
|
1203
|
+
};
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
const createNoopPublishFs = (): PublishFileSystem => ({
|
|
1207
|
+
async writeFileRaw(): Promise<void> {
|
|
1208
|
+
// No-op for layout-only publish flows.
|
|
1209
|
+
},
|
|
1210
|
+
async mkdir(): Promise<void> {
|
|
1211
|
+
// No-op for layout-only publish flows.
|
|
1212
|
+
},
|
|
1213
|
+
join(...paths: string[]): string {
|
|
1214
|
+
return paths.join('/');
|
|
1215
|
+
},
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
const publishPackage = async ( plan: ResolvedPackagePublishPlan, writerFs: FileSystem, packageIndex: number) => {
|
|
1219
|
+
const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(plan.fileExtension);
|
|
1220
|
+
await atlas({
|
|
1221
|
+
...plan.atlas,
|
|
1222
|
+
...(options.atlas ?? {}),
|
|
1223
|
+
separatedAtlasForBranch: plan.separatedAtlasForBranch,
|
|
1224
|
+
encoder: options.encoder,
|
|
1225
|
+
basePath: options.basePath,
|
|
1226
|
+
outputPath: options.fs ? plan.outputDir : undefined,
|
|
1227
|
+
mkdir: options.fs ? options.fs.mkdir : undefined,
|
|
1228
|
+
readFileRaw: options.atlas?.readFileRaw ?? options.fs?.readFileRaw,
|
|
1229
|
+
packages: [plan.pkg.getName()],
|
|
1230
|
+
...atlasRuntimeOptions,
|
|
1231
|
+
})(doc);
|
|
1232
|
+
|
|
1233
|
+
if (!options.fs) return;
|
|
1234
|
+
if (!plan.outputDir) {
|
|
1235
|
+
throw new Error('publish: no output directory resolved. Provide --output, or configure global publish.path / package publishPath.');
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
await options.fs.mkdir(plan.outputDir);
|
|
1239
|
+
|
|
1240
|
+
const filePath = options.fs.join(plan.outputDir, plan.fileName);
|
|
1241
|
+
const bwOptions: BinaryWriterOptions = {
|
|
1242
|
+
compressed: plan.compressed,
|
|
1243
|
+
packageIndex,
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
const bw = new BinaryWriter(writerFs);
|
|
1247
|
+
await bw.write(doc, filePath, bwOptions);
|
|
1248
|
+
await exportPackageSounds(
|
|
1249
|
+
plan.pkg,
|
|
1250
|
+
plan.outputDir,
|
|
1251
|
+
options.basePath,
|
|
1252
|
+
options.fs,
|
|
1253
|
+
options.atlas?.readFileRaw ?? options.fs.readFileRaw,
|
|
1254
|
+
logger,
|
|
1255
|
+
);
|
|
1256
|
+
await exportPackageExternalResources(
|
|
1257
|
+
plan.pkg,
|
|
1258
|
+
plan.outputDir,
|
|
1259
|
+
options.basePath,
|
|
1260
|
+
options.fs,
|
|
1261
|
+
options.atlas?.readFileRaw ?? options.fs.readFileRaw,
|
|
1262
|
+
logger,
|
|
1263
|
+
);
|
|
1264
|
+
|
|
1265
|
+
logger.info(`publish: Written ${plan.fileName}`);
|
|
1266
|
+
};
|
|
1267
|
+
|
|
935
1268
|
const root = doc.getRoot();
|
|
936
1269
|
const logger = doc.getLogger();
|
|
937
|
-
const
|
|
938
|
-
const
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
atlas: options.atlas,
|
|
944
|
-
});
|
|
945
|
-
const ext = resolved.fileExtension;
|
|
1270
|
+
const projectBasePath = resolveProjectBasePath(options.basePath) || doc.getProjectDir?.() || '';
|
|
1271
|
+
const pluginsDir = resolvePublishPluginsDir(doc, options);
|
|
1272
|
+
const plugins = pluginsDir ? await loadPlugins(doc, pluginsDir) : [];
|
|
1273
|
+
await runPublishPluginHook(plugins, 'onPublishStart', doc, options);
|
|
1274
|
+
|
|
1275
|
+
const resolved = resolveProjectPublishConfig();
|
|
946
1276
|
|
|
947
1277
|
// Step 1: Determine which packages to publish
|
|
948
1278
|
let allPackages = root.listPackages();
|
|
@@ -953,14 +1283,10 @@ export function publish(options: PublishOptions): Transform {
|
|
|
953
1283
|
|
|
954
1284
|
if (allPackages.length === 0) {
|
|
955
1285
|
logger.warn('publish: No packages to publish.');
|
|
1286
|
+
await runPublishPluginHook(plugins, 'onPublishEnd', doc, options);
|
|
956
1287
|
return;
|
|
957
1288
|
}
|
|
958
1289
|
|
|
959
|
-
const branchProcessing = publishSettings.branchProcessing ?? 0;
|
|
960
|
-
const includeBranches = branchProcessing === 0;
|
|
961
|
-
const activeBranch = includeBranches ? '' : (options.branch ?? '');
|
|
962
|
-
const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(ext);
|
|
963
|
-
|
|
964
1290
|
const allDocPackages = root.listPackages();
|
|
965
1291
|
// Build a pkgId→name map for dependency resolution
|
|
966
1292
|
const pkgMap = new Map<string, Package>();
|
|
@@ -971,82 +1297,61 @@ export function publish(options: PublishOptions): Transform {
|
|
|
971
1297
|
for (const pkg of allPackages) {
|
|
972
1298
|
// Compute dependency list and selected publish artifacts before atlas packing,
|
|
973
1299
|
// so merged-branch publishes can pack the overridden resources with main IDs.
|
|
974
|
-
_computeDependencies(pkg, pkgMap);
|
|
1300
|
+
_computeDependencies(doc, pkg, pkgMap);
|
|
975
1301
|
await annotatePackagePublishArtifacts(
|
|
976
1302
|
pkg,
|
|
977
1303
|
options.basePath,
|
|
978
1304
|
options.encoder as PublishEncoder | undefined,
|
|
979
1305
|
{
|
|
980
|
-
|
|
981
|
-
|
|
1306
|
+
projectType: resolved.projectType,
|
|
1307
|
+
includeBranches: resolved.includeBranches,
|
|
1308
|
+
activeBranch: resolved.activeBranch,
|
|
1309
|
+
includeHighResolution: resolved.includeHighResolution,
|
|
982
1310
|
},
|
|
983
1311
|
);
|
|
984
1312
|
}
|
|
985
1313
|
|
|
986
|
-
|
|
987
|
-
const atlasOpts: AtlasOptions = {
|
|
988
|
-
...resolved.atlas,
|
|
989
|
-
...(options.atlas ?? {}),
|
|
990
|
-
separatedAtlasForBranch: includeBranches && publishSettings.seperatedAtlasForBranch === true,
|
|
991
|
-
encoder: options.encoder,
|
|
992
|
-
basePath: options.basePath,
|
|
993
|
-
outputPath: options.fs ? options.output : undefined,
|
|
994
|
-
mkdir: options.fs ? options.fs.mkdir : undefined,
|
|
995
|
-
readFileRaw: options.atlas?.readFileRaw ?? options.fs?.readFileRaw,
|
|
996
|
-
...atlasRuntimeOptions,
|
|
997
|
-
};
|
|
998
|
-
await atlas(atlasOpts)(doc);
|
|
1314
|
+
const plans = allPackages.map((pkg) => resolvePackagePublishPlan(pkg, resolved, projectBasePath));
|
|
999
1315
|
|
|
1000
|
-
// Step 3: Write .fui binary per package
|
|
1001
1316
|
if (!options.fs) {
|
|
1002
1317
|
logger.info(`publish: No fs provided — layout computed for ${allPackages.length} package(s), skipping file output.`);
|
|
1318
|
+
const noopWriterFs = toBinaryWriterFileSystem(createNoopPublishFs());
|
|
1319
|
+
for (const plan of plans) {
|
|
1320
|
+
await publishPackage(plan, noopWriterFs, allDocPackages.indexOf(plan.pkg));
|
|
1321
|
+
}
|
|
1322
|
+
await runPublishPluginHook(plugins, 'onPublishEnd', doc, options);
|
|
1003
1323
|
return;
|
|
1004
1324
|
}
|
|
1005
1325
|
|
|
1006
|
-
|
|
1326
|
+
const unresolvedPlan = plans.find((plan) => !plan.outputDir);
|
|
1327
|
+
if (unresolvedPlan) {
|
|
1328
|
+
throw new Error(
|
|
1329
|
+
`publish: no output directory resolved for package "${unresolvedPlan.pkg.getName()}". ` +
|
|
1330
|
+
'Provide --output, or configure global publish.path / package publishPath.',
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1007
1333
|
|
|
1008
1334
|
const writerFs = toBinaryWriterFileSystem(options.fs);
|
|
1009
1335
|
|
|
1010
|
-
for (const
|
|
1011
|
-
const pkgIndex = allDocPackages.indexOf(pkg);
|
|
1012
|
-
|
|
1013
|
-
const fileName = resolvePublishFileName(publishName, ext);
|
|
1014
|
-
const filePath = options.fs.join(options.output, fileName);
|
|
1015
|
-
|
|
1016
|
-
const bwOptions: BinaryWriterOptions = {
|
|
1017
|
-
compressed: resolved.compressed,
|
|
1018
|
-
packageIndex: pkgIndex,
|
|
1019
|
-
};
|
|
1020
|
-
|
|
1021
|
-
const bw = new BinaryWriter(writerFs);
|
|
1022
|
-
await bw.write(doc, filePath, bwOptions);
|
|
1023
|
-
await exportPackageSounds(
|
|
1024
|
-
pkg,
|
|
1025
|
-
options.output,
|
|
1026
|
-
options.basePath,
|
|
1027
|
-
options.fs,
|
|
1028
|
-
options.atlas?.readFileRaw ?? options.fs.readFileRaw,
|
|
1029
|
-
logger,
|
|
1030
|
-
);
|
|
1031
|
-
await exportPackageExternalResources(
|
|
1032
|
-
pkg,
|
|
1033
|
-
options.output,
|
|
1034
|
-
options.basePath,
|
|
1035
|
-
options.fs,
|
|
1036
|
-
options.atlas?.readFileRaw ?? options.fs.readFileRaw,
|
|
1037
|
-
logger,
|
|
1038
|
-
);
|
|
1039
|
-
|
|
1040
|
-
logger.info(`publish: Written ${fileName}`);
|
|
1336
|
+
for (const plan of plans) {
|
|
1337
|
+
const pkgIndex = allDocPackages.indexOf(plan.pkg);
|
|
1338
|
+
await publishPackage(plan, writerFs, pkgIndex);
|
|
1041
1339
|
}
|
|
1042
1340
|
|
|
1043
1341
|
await publishCodeGeneration(doc, {
|
|
1044
1342
|
basePath: options.basePath,
|
|
1045
1343
|
fs: options.fs,
|
|
1046
1344
|
packages: allPackages,
|
|
1345
|
+
plugins,
|
|
1047
1346
|
});
|
|
1048
1347
|
|
|
1049
|
-
|
|
1348
|
+
const publishedTargets = [...new Set(plans.map((plan) => plan.outputDir).filter((value): value is string => Boolean(value)))];
|
|
1349
|
+
logger.info(
|
|
1350
|
+
publishedTargets.length > 0
|
|
1351
|
+
? `publish: Published ${allPackages.length} package(s) to ${publishedTargets.join(', ')}`
|
|
1352
|
+
: `publish: Published ${allPackages.length} package(s)`,
|
|
1353
|
+
);
|
|
1354
|
+
await runPublishPluginHook(plugins, 'onPublishEnd', doc, options);
|
|
1050
1355
|
});
|
|
1051
1356
|
}
|
|
1052
1357
|
|
|
@@ -1055,25 +1360,109 @@ export function publish(options: PublishOptions): Transform {
|
|
|
1055
1360
|
* The editor only adds dependencies for packages referenced via bitmap font URLs.
|
|
1056
1361
|
* @internal
|
|
1057
1362
|
*/
|
|
1058
|
-
function _computeDependencies(pkg: Package, pkgMap: Map<string, Package>): void {
|
|
1363
|
+
function _computeDependencies(doc: Document, pkg: Package, pkgMap: Map<string, Package>): void {
|
|
1059
1364
|
const referencedPkgIds = new Set<string>();
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
const
|
|
1064
|
-
if (
|
|
1065
|
-
|
|
1365
|
+
const pkgId = pkg.getId();
|
|
1366
|
+
const packageOrder = new Map(doc.getRoot().listPackages().map((entry, index) => [entry.getId(), index] as const));
|
|
1367
|
+
const addDependencyPackageId = (dependencyPkgId: string | null | undefined): void => {
|
|
1368
|
+
const normalized = dependencyPkgId?.trim() ?? '';
|
|
1369
|
+
if (!normalized || normalized === pkgId) return;
|
|
1370
|
+
referencedPkgIds.add(normalized);
|
|
1371
|
+
};
|
|
1372
|
+
const extractPackageIdFromUiUrl = (value: string): string | null => {
|
|
1373
|
+
if (!value.startsWith('ui://')) return null;
|
|
1374
|
+
const rest = value.slice(5);
|
|
1375
|
+
if (!rest) return null;
|
|
1376
|
+
const slashIndex = rest.indexOf('/');
|
|
1377
|
+
if (slashIndex >= 0) {
|
|
1378
|
+
return rest.slice(0, slashIndex) || null;
|
|
1379
|
+
}
|
|
1066
1380
|
if (rest.length >= 8) {
|
|
1067
|
-
|
|
1068
|
-
if (depPkgId !== pkg.getId()) referencedPkgIds.add(depPkgId);
|
|
1381
|
+
return rest.slice(0, 8);
|
|
1069
1382
|
}
|
|
1070
|
-
|
|
1383
|
+
return null;
|
|
1384
|
+
};
|
|
1385
|
+
const addDependencyPackageIdFromUiValue = (value: string | null | undefined): void => {
|
|
1386
|
+
if (!value || typeof value !== 'string') return;
|
|
1387
|
+
addDependencyPackageId(extractPackageIdFromUiUrl(value));
|
|
1388
|
+
};
|
|
1389
|
+
const addDependencyPackageIdsFromText = (value: string | null | undefined): void => {
|
|
1390
|
+
if (!value || typeof value !== 'string') return;
|
|
1391
|
+
const matches = value.matchAll(/ui:\/\/([0-9a-z]{8})/giu);
|
|
1392
|
+
for (const match of matches) {
|
|
1393
|
+
addDependencyPackageId(match[1] ?? '');
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
const addDependencyPackageIdsFromUnknown = (value: unknown): void => {
|
|
1397
|
+
if (Array.isArray(value)) {
|
|
1398
|
+
for (const entry of value) addDependencyPackageIdsFromUnknown(entry);
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
if (typeof value === 'string') {
|
|
1402
|
+
addDependencyPackageIdFromUiValue(value);
|
|
1403
|
+
addDependencyPackageIdsFromText(value);
|
|
1404
|
+
}
|
|
1405
|
+
};
|
|
1406
|
+
const addDependencyFontRef = (value: string | string[] | null | undefined): void => {
|
|
1407
|
+
if (Array.isArray(value)) {
|
|
1408
|
+
for (const entry of value) addDependencyPackageIdFromUiValue(entry);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
addDependencyPackageIdFromUiValue(value ?? undefined);
|
|
1412
|
+
};
|
|
1071
1413
|
|
|
1072
1414
|
for (const res of pkg.listResources()) {
|
|
1073
1415
|
if (res.propertyType !== 'Component') continue;
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1416
|
+
const component = res as ComponentWithPublishRefs;
|
|
1417
|
+
for (const child of component.listChildren?.() ?? []) {
|
|
1418
|
+
addDependencyPackageId(child.getPackageId?.());
|
|
1419
|
+
addDependencyFontRef(child.getFont?.());
|
|
1420
|
+
addDependencyPackageIdsFromText(child.getText?.());
|
|
1421
|
+
for (const ref of [
|
|
1422
|
+
child.getUrl?.(),
|
|
1423
|
+
child.getDefaultItem?.(),
|
|
1424
|
+
child.getIcon?.(),
|
|
1425
|
+
child.getSelectedIcon?.(),
|
|
1426
|
+
child.getDropdown?.(),
|
|
1427
|
+
child.getSound?.(),
|
|
1428
|
+
child.getInstanceSound?.(),
|
|
1429
|
+
child.getInstanceIcon?.(),
|
|
1430
|
+
child.getInstanceSelectedIcon?.(),
|
|
1431
|
+
child.getVtScrollBarRes?.(),
|
|
1432
|
+
child.getHzScrollBarRes?.(),
|
|
1433
|
+
child.getHeaderRes?.(),
|
|
1434
|
+
child.getFooterRes?.(),
|
|
1435
|
+
]) {
|
|
1436
|
+
addDependencyPackageIdFromUiValue(ref);
|
|
1437
|
+
}
|
|
1438
|
+
for (const item of child.getInstanceComboItems?.() ?? []) {
|
|
1439
|
+
addDependencyPackageIdFromUiValue(item.icon ?? undefined);
|
|
1440
|
+
}
|
|
1441
|
+
for (const item of child.getListItems?.() ?? []) {
|
|
1442
|
+
addDependencyPackageIdFromUiValue(item.icon ?? undefined);
|
|
1443
|
+
addDependencyPackageIdFromUiValue(item.url ?? undefined);
|
|
1444
|
+
}
|
|
1445
|
+
for (const gear of child.listGears?.() ?? []) {
|
|
1446
|
+
addDependencyPackageIdsFromUnknown(gear.getValues?.());
|
|
1447
|
+
addDependencyPackageIdsFromUnknown(gear.getDefaultValue?.());
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
addDependencyFontRef(component.getFont?.());
|
|
1451
|
+
for (const ref of [
|
|
1452
|
+
component.getDropdown?.(),
|
|
1453
|
+
component.getHeaderRes?.(),
|
|
1454
|
+
component.getFooterRes?.(),
|
|
1455
|
+
component.getVtScrollBarRes?.(),
|
|
1456
|
+
component.getHzScrollBarRes?.(),
|
|
1457
|
+
component.getSound?.(),
|
|
1458
|
+
]) {
|
|
1459
|
+
addDependencyPackageIdFromUiValue(ref);
|
|
1460
|
+
}
|
|
1461
|
+
for (const transition of component.listTransitions?.() ?? []) {
|
|
1462
|
+
for (const item of transition.listItems?.() ?? []) {
|
|
1463
|
+
addDependencyPackageIdsFromUnknown(item.getStartValue?.());
|
|
1464
|
+
addDependencyPackageIdsFromUnknown(item.getEndValue?.());
|
|
1465
|
+
}
|
|
1077
1466
|
}
|
|
1078
1467
|
}
|
|
1079
1468
|
|
|
@@ -1082,7 +1471,12 @@ function _computeDependencies(pkg: Package, pkgMap: Map<string, Package>): void
|
|
|
1082
1471
|
}
|
|
1083
1472
|
|
|
1084
1473
|
if (referencedPkgIds.size > 0) {
|
|
1085
|
-
const sortedIds = [...referencedPkgIds].sort((a, b) =>
|
|
1474
|
+
const sortedIds = [...referencedPkgIds].sort((a, b) => {
|
|
1475
|
+
const orderA = packageOrder.get(a) ?? Number.MAX_SAFE_INTEGER;
|
|
1476
|
+
const orderB = packageOrder.get(b) ?? Number.MAX_SAFE_INTEGER;
|
|
1477
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
1478
|
+
return a.localeCompare(b);
|
|
1479
|
+
});
|
|
1086
1480
|
for (const refId of sortedIds) {
|
|
1087
1481
|
const depPkg = pkgMap.get(refId);
|
|
1088
1482
|
if (depPkg) {
|