@openfairygui/functions 0.3.0-alpha.4 → 0.3.0

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.
@@ -61,6 +61,9 @@ type AtlasRasterInput = string | Uint8Array | {
61
61
  */
62
62
  interface AtlasRasterPipeline {
63
63
  ensureAlpha(): AtlasRasterPipeline;
64
+ removeAlpha(): AtlasRasterPipeline;
65
+ extractChannel(channel: 'alpha'): AtlasRasterPipeline;
66
+ joinChannel(images: Uint8Array[]): AtlasRasterPipeline;
64
67
  resize(options: {
65
68
  width: number;
66
69
  height: number;
@@ -114,6 +117,9 @@ interface AtlasOptions {
114
117
  padding?: number;
115
118
  /** Constrain atlas dimensions to powers of two. Default: false. */
116
119
  powerOfTwo?: boolean;
120
+ /** Highest fixed atlas page index accepted from resource textureSetMode. Default: 10. */
121
+ maxAtlasIndex?: number;
122
+ multipleOfFour?: boolean;
117
123
  /** Force square atlas (width === height). Default: false. */
118
124
  square?: boolean;
119
125
  /** Allow spilling into multiple atlas pages. Default: true. */
@@ -61,6 +61,9 @@ type AtlasRasterInput = string | Uint8Array | {
61
61
  */
62
62
  interface AtlasRasterPipeline {
63
63
  ensureAlpha(): AtlasRasterPipeline;
64
+ removeAlpha(): AtlasRasterPipeline;
65
+ extractChannel(channel: 'alpha'): AtlasRasterPipeline;
66
+ joinChannel(images: Uint8Array[]): AtlasRasterPipeline;
64
67
  resize(options: {
65
68
  width: number;
66
69
  height: number;
@@ -114,6 +117,9 @@ interface AtlasOptions {
114
117
  padding?: number;
115
118
  /** Constrain atlas dimensions to powers of two. Default: false. */
116
119
  powerOfTwo?: boolean;
120
+ /** Highest fixed atlas page index accepted from resource textureSetMode. Default: 10. */
121
+ maxAtlasIndex?: number;
122
+ multipleOfFour?: boolean;
117
123
  /** Force square atlas (width === height). Default: false. */
118
124
  square?: boolean;
119
125
  /** Allow spilling into multiple atlas pages. Default: true. */
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_publish = require("./publish-C7qHwEiP.cjs");
3
- const require_restore = require("./restore-LXbDQqmT.cjs");
2
+ const require_publish = require("./publish-CxKatE3e.cjs");
3
+ const require_restore = require("./restore-QScbHJ7Y.cjs");
4
4
  const require_uam_transaction = require("./uam-transaction.cjs");
5
5
  //#region src/inspect.ts
6
6
  function mapResource(resource) {
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as AtlasRasterInput, c as AtlasRasterResolvedBuffer, d as PublishSourceFileSystem, i as AtlasRasterCompositeInput, l as PublishFileSystem, n as atlas, o as AtlasRasterMetadata, r as AtlasRasterBackend, s as AtlasRasterPipeline, t as AtlasOptions, u as PublishOutputFileSystem } from "./atlas-CHsu2Y8i.cjs";
2
- import { A as ExtrasMap, B as ResolvedPublishOptions, C as MaybePromise, D as CliAtlasSettings, E as PluginModule, F as RootProjectSettings, I as publish, L as PublishOptions, M as HasOptionalSrc, N as HasOptionalUrl, O as CliCodeGenerationSettings, P as PublishDependency, R as ResolvePublishOptionsOverrides, S as LoadedPlugin, T as PluginManifest, V as resolvePublishOptions, _ as encodeText, a as RestoreImageExtractor, b as CodeWriter, c as restore, d as CodegenMember, f as CodegenReferencedComponent, g as decodeText, h as buildCodegenClasses, i as RestoreImageExtractInput, j as HasOptionalFont, k as CliPublishSettings, l as AUTO_GENERATED_CODE_MARK, m as ResolvedPackageCodegenPlan, n as RestoreImageCropInput, o as RestoreOptions, p as PublishCodeGenerationOptions, r as RestoreImageCropper, s as RestoreResult, t as RestoreFileSystem, u as CodegenClass, v as publishCodeGeneration, w as Plugin, x as ICodeWriterConfig, y as resolvePackageCodegenPlan, z as ResolvedPublishAtlasOptions } from "./restore-BeWaJNjR.cjs";
1
+ import { a as AtlasRasterInput, c as AtlasRasterResolvedBuffer, d as PublishSourceFileSystem, i as AtlasRasterCompositeInput, l as PublishFileSystem, n as atlas, o as AtlasRasterMetadata, r as AtlasRasterBackend, s as AtlasRasterPipeline, t as AtlasOptions, u as PublishOutputFileSystem } from "./atlas-CSqHsG0X.cjs";
2
+ import { A as ExtrasMap, B as ResolvedPublishOptions, C as MaybePromise, D as CliAtlasSettings, E as PluginModule, F as RootProjectSettings, I as publish, L as PublishOptions, M as HasOptionalSrc, N as HasOptionalUrl, O as CliCodeGenerationSettings, P as PublishDependency, R as ResolvePublishOptionsOverrides, S as LoadedPlugin, T as PluginManifest, V as resolvePublishOptions, _ as encodeText, a as RestoreImageExtractor, b as CodeWriter, c as restore, d as CodegenMember, f as CodegenReferencedComponent, g as decodeText, h as buildCodegenClasses, i as RestoreImageExtractInput, j as HasOptionalFont, k as CliPublishSettings, l as AUTO_GENERATED_CODE_MARK, m as ResolvedPackageCodegenPlan, n as RestoreImageCropInput, o as RestoreOptions, p as PublishCodeGenerationOptions, r as RestoreImageCropper, s as RestoreResult, t as RestoreFileSystem, u as CodegenClass, v as publishCodeGeneration, w as Plugin, x as ICodeWriterConfig, y as resolvePackageCodegenPlan, z as ResolvedPublishAtlasOptions } from "./restore-D6F1ELdM.cjs";
3
3
  import { ApplyUamTransactionAppDiagnostic, ApplyUamTransactionAppError, ApplyUamTransactionAppInput, ApplyUamTransactionAppResult, applyUamTransactionApp, applyUamTransactionAppAsync } from "./uam-transaction.cjs";
4
4
  import { Document, ProjectDiagnostic, ProjectValidationReport, Transform, UamProject } from "@openfairygui/core";
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as AtlasRasterInput, c as AtlasRasterResolvedBuffer, d as PublishSourceFileSystem, i as AtlasRasterCompositeInput, l as PublishFileSystem, n as atlas, o as AtlasRasterMetadata, r as AtlasRasterBackend, s as AtlasRasterPipeline, t as AtlasOptions, u as PublishOutputFileSystem } from "./atlas-C6tbl7nn.js";
2
- import { A as ExtrasMap, B as ResolvedPublishOptions, C as MaybePromise, D as CliAtlasSettings, E as PluginModule, F as RootProjectSettings, I as publish, L as PublishOptions, M as HasOptionalSrc, N as HasOptionalUrl, O as CliCodeGenerationSettings, P as PublishDependency, R as ResolvePublishOptionsOverrides, S as LoadedPlugin, T as PluginManifest, V as resolvePublishOptions, _ as encodeText, a as RestoreImageExtractor, b as CodeWriter, c as restore, d as CodegenMember, f as CodegenReferencedComponent, g as decodeText, h as buildCodegenClasses, i as RestoreImageExtractInput, j as HasOptionalFont, k as CliPublishSettings, l as AUTO_GENERATED_CODE_MARK, m as ResolvedPackageCodegenPlan, n as RestoreImageCropInput, o as RestoreOptions, p as PublishCodeGenerationOptions, r as RestoreImageCropper, s as RestoreResult, t as RestoreFileSystem, u as CodegenClass, v as publishCodeGeneration, w as Plugin, x as ICodeWriterConfig, y as resolvePackageCodegenPlan, z as ResolvedPublishAtlasOptions } from "./restore-Dh0-Nvms.js";
1
+ import { a as AtlasRasterInput, c as AtlasRasterResolvedBuffer, d as PublishSourceFileSystem, i as AtlasRasterCompositeInput, l as PublishFileSystem, n as atlas, o as AtlasRasterMetadata, r as AtlasRasterBackend, s as AtlasRasterPipeline, t as AtlasOptions, u as PublishOutputFileSystem } from "./atlas-BtWa1DwO.js";
2
+ import { A as ExtrasMap, B as ResolvedPublishOptions, C as MaybePromise, D as CliAtlasSettings, E as PluginModule, F as RootProjectSettings, I as publish, L as PublishOptions, M as HasOptionalSrc, N as HasOptionalUrl, O as CliCodeGenerationSettings, P as PublishDependency, R as ResolvePublishOptionsOverrides, S as LoadedPlugin, T as PluginManifest, V as resolvePublishOptions, _ as encodeText, a as RestoreImageExtractor, b as CodeWriter, c as restore, d as CodegenMember, f as CodegenReferencedComponent, g as decodeText, h as buildCodegenClasses, i as RestoreImageExtractInput, j as HasOptionalFont, k as CliPublishSettings, l as AUTO_GENERATED_CODE_MARK, m as ResolvedPackageCodegenPlan, n as RestoreImageCropInput, o as RestoreOptions, p as PublishCodeGenerationOptions, r as RestoreImageCropper, s as RestoreResult, t as RestoreFileSystem, u as CodegenClass, v as publishCodeGeneration, w as Plugin, x as ICodeWriterConfig, y as resolvePackageCodegenPlan, z as ResolvedPublishAtlasOptions } from "./restore-BOfsCM47.js";
3
3
  import { ApplyUamTransactionAppDiagnostic, ApplyUamTransactionAppError, ApplyUamTransactionAppInput, ApplyUamTransactionAppResult, applyUamTransactionApp, applyUamTransactionAppAsync } from "./uam-transaction.js";
4
4
  import { Document, ProjectDiagnostic, ProjectValidationReport, Transform, UamProject } from "@openfairygui/core";
5
5
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as validateProject, a as decodeText, g as createTransform, h as atlas, i as buildCodegenClasses, l as resolvePackageCodegenPlan, n as resolvePublishOptions, o as encodeText, r as AUTO_GENERATED_CODE_MARK, s as publishCodeGeneration, t as publish } from "./publish-CyBj2o7n.js";
2
- import { t as restore } from "./restore-DVo1hXpN.js";
1
+ import { _ as validateProject, a as decodeText, g as createTransform, h as atlas, i as buildCodegenClasses, l as resolvePackageCodegenPlan, n as resolvePublishOptions, o as encodeText, r as AUTO_GENERATED_CODE_MARK, s as publishCodeGeneration, t as publish } from "./publish-BBoK-yeR.js";
2
+ import { t as restore } from "./restore-DOcyfc0b.js";
3
3
  import { applyUamTransactionApp, applyUamTransactionAppAsync } from "./uam-transaction.js";
4
4
  //#region src/inspect.ts
5
5
  function mapResource(resource) {
package/dist/node.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_publish = require("./publish-C7qHwEiP.cjs");
3
- const require_restore = require("./restore-LXbDQqmT.cjs");
2
+ const require_publish = require("./publish-CxKatE3e.cjs");
3
+ const require_restore = require("./restore-QScbHJ7Y.cjs");
4
4
  let _openfairygui_core = require("@openfairygui/core");
5
5
  let _openfairygui_core_node = require("@openfairygui/core/node");
6
6
  //#region src/adapters/node/plugins.ts
@@ -302,18 +302,21 @@ async function validateProjectNode(projectPath) {
302
302
  }
303
303
  const decodedPaths = new Set(images.map(({ packageIndex, resourceIndex }) => `packages[${packageIndex}].resources[${resourceIndex}]`));
304
304
  diagnostics = diagnostics.filter((diagnostic) => diagnostic.code !== "decode_capability_unavailable" || !decodedPaths.has(diagnostic.path));
305
- for (const { pkg, packageIndex, resource, resourceIndex } of images) try {
306
- await sharp(resource.sourceBytes).raw().toBuffer();
307
- } catch (error) {
308
- diagnostics.push({
309
- severity: "error",
310
- code: "corrupt_source",
311
- path: `packages[${packageIndex}].resources[${resourceIndex}]`,
312
- message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
313
- packageId: pkg.id,
314
- resourceId: resource.id,
315
- sourcePath: sourceName(resource)
316
- });
305
+ for (const { pkg, packageIndex, resource, resourceIndex } of images) {
306
+ if (resource.kind !== "image") continue;
307
+ try {
308
+ await sharp(resource.sourceBytes).raw().toBuffer();
309
+ } catch (error) {
310
+ diagnostics.push({
311
+ severity: "error",
312
+ code: "corrupt_source",
313
+ path: `packages[${packageIndex}].resources[${resourceIndex}]`,
314
+ message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
315
+ packageId: pkg.id,
316
+ resourceId: resource.id,
317
+ sourcePath: sourceName(resource)
318
+ });
319
+ }
317
320
  }
318
321
  return (0, _openfairygui_core.createProjectValidationReport)(diagnostics, read.complete && !diagnostics.some((diagnostic) => diagnostic.code === "decode_capability_unavailable"));
319
322
  }
package/dist/node.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as AtlasRasterBackend } from "./atlas-CHsu2Y8i.cjs";
2
- import { L as PublishOptions, S as LoadedPlugin, o as RestoreOptions, s as RestoreResult } from "./restore-BeWaJNjR.cjs";
1
+ import { r as AtlasRasterBackend } from "./atlas-CSqHsG0X.cjs";
2
+ import { L as PublishOptions, S as LoadedPlugin, o as RestoreOptions, s as RestoreResult } from "./restore-D6F1ELdM.cjs";
3
3
  import { Document, ProjectValidationReport } from "@openfairygui/core";
4
4
 
5
5
  //#region src/adapters/node/publish.d.ts
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as AtlasRasterBackend } from "./atlas-C6tbl7nn.js";
2
- import { L as PublishOptions, S as LoadedPlugin, o as RestoreOptions, s as RestoreResult } from "./restore-Dh0-Nvms.js";
1
+ import { r as AtlasRasterBackend } from "./atlas-BtWa1DwO.js";
2
+ import { L as PublishOptions, S as LoadedPlugin, o as RestoreOptions, s as RestoreResult } from "./restore-BOfsCM47.js";
3
3
  import { Document, ProjectValidationReport } from "@openfairygui/core";
4
4
 
5
5
  //#region src/adapters/node/publish.d.ts
package/dist/node.js CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as validateProject, m as formatPluginError, t as publish, u as resolveProjectBasePath } from "./publish-CyBj2o7n.js";
2
- import { t as restore } from "./restore-DVo1hXpN.js";
1
+ import { _ as validateProject, m as formatPluginError, t as publish, u as resolveProjectBasePath } from "./publish-BBoK-yeR.js";
2
+ import { t as restore } from "./restore-DOcyfc0b.js";
3
3
  import { createProjectValidationReport, liftDocumentToUamProject } from "@openfairygui/core";
4
4
  import { NodeIO } from "@openfairygui/core/node";
5
5
  //#region src/adapters/node/plugins.ts
@@ -301,18 +301,21 @@ async function validateProjectNode(projectPath) {
301
301
  }
302
302
  const decodedPaths = new Set(images.map(({ packageIndex, resourceIndex }) => `packages[${packageIndex}].resources[${resourceIndex}]`));
303
303
  diagnostics = diagnostics.filter((diagnostic) => diagnostic.code !== "decode_capability_unavailable" || !decodedPaths.has(diagnostic.path));
304
- for (const { pkg, packageIndex, resource, resourceIndex } of images) try {
305
- await sharp(resource.sourceBytes).raw().toBuffer();
306
- } catch (error) {
307
- diagnostics.push({
308
- severity: "error",
309
- code: "corrupt_source",
310
- path: `packages[${packageIndex}].resources[${resourceIndex}]`,
311
- message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
312
- packageId: pkg.id,
313
- resourceId: resource.id,
314
- sourcePath: sourceName(resource)
315
- });
304
+ for (const { pkg, packageIndex, resource, resourceIndex } of images) {
305
+ if (resource.kind !== "image") continue;
306
+ try {
307
+ await sharp(resource.sourceBytes).raw().toBuffer();
308
+ } catch (error) {
309
+ diagnostics.push({
310
+ severity: "error",
311
+ code: "corrupt_source",
312
+ path: `packages[${packageIndex}].resources[${resourceIndex}]`,
313
+ message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
314
+ packageId: pkg.id,
315
+ resourceId: resource.id,
316
+ sourcePath: sourceName(resource)
317
+ });
318
+ }
316
319
  }
317
320
  return createProjectValidationReport(diagnostics, read.complete && !diagnostics.some((diagnostic) => diagnostic.code === "decode_capability_unavailable"));
318
321
  }
@@ -24,7 +24,7 @@ function createTransform(name, fn) {
24
24
  Object.defineProperty(fn, "name", { value: name });
25
25
  return fn;
26
26
  }
27
- function parseTextureSetMode(value) {
27
+ function parseTextureSetMode(value, maxAtlasIndex = 10) {
28
28
  const raw = value?.trim() ?? "";
29
29
  if (!raw) return {
30
30
  kind: "auto",
@@ -47,7 +47,7 @@ function parseTextureSetMode(value) {
47
47
  };
48
48
  if (/^\d+$/.test(raw)) {
49
49
  const pageIndex = Number(raw);
50
- if (pageIndex >= 0 && pageIndex <= 10) return {
50
+ if (pageIndex >= 0 && pageIndex <= maxAtlasIndex) return {
51
51
  kind: "page",
52
52
  raw,
53
53
  pageIndex
@@ -105,9 +105,9 @@ function collectComponentReferences(target, ownerPackageId, component) {
105
105
  const sourcePackageId = child.getPackageId?.()?.trim();
106
106
  if (sourcePackageId && sourcePackageId !== ownerPackageId) target.packageIds.add(sourcePackageId);
107
107
  addFontReferences(target, ownerPackageId, child.getFont?.());
108
- addTextReferences(target, ownerPackageId, child.getText?.());
108
+ if (!child.getAutoClearText?.()) addTextReferences(target, ownerPackageId, child.getText?.());
109
109
  for (const reference of [
110
- child.getUrl?.(),
110
+ child.getClearOnPublish?.() ? void 0 : child.getUrl?.(),
111
111
  child.getDefaultItem?.(),
112
112
  child.getIcon?.(),
113
113
  child.getSelectedIcon?.(),
@@ -121,11 +121,14 @@ function collectComponentReferences(target, ownerPackageId, component) {
121
121
  child.getHeaderRes?.(),
122
122
  child.getFooterRes?.()
123
123
  ]) addUiReference(target, ownerPackageId, reference);
124
- for (const item of child.getInstanceComboItems?.() ?? []) addUiReference(target, ownerPackageId, item.icon);
125
- for (const item of child.getListItems?.() ?? []) {
124
+ for (const item of child.getInstanceAutoClearItems?.() ? [] : child.getInstanceComboItems?.() ?? []) addUiReference(target, ownerPackageId, item.icon);
125
+ for (const item of child.getAutoClearItems?.() ? [] : child.getListItems?.() ?? []) {
126
126
  addUiReference(target, ownerPackageId, item.icon);
127
+ addUiReference(target, ownerPackageId, item.selectedIcon);
127
128
  addUiReference(target, ownerPackageId, item.url);
129
+ addUnknownReferences(target, ownerPackageId, item.propertyOverrides?.map((property) => property.value));
128
130
  }
131
+ addUnknownReferences(target, ownerPackageId, child.getPropertyOverrides?.().map((property) => property.value));
129
132
  for (const gear of child.listGears?.() ?? []) {
130
133
  addUnknownReferences(target, ownerPackageId, gear.getValues?.());
131
134
  addUnknownReferences(target, ownerPackageId, gear.getDefaultValue?.());
@@ -155,7 +158,8 @@ function collectPackageResourceReferences(pkg) {
155
158
  localResourceIds: /* @__PURE__ */ new Set(),
156
159
  packageIds: /* @__PURE__ */ new Set()
157
160
  };
158
- for (const resource of pkg.listResources()) if (resource.propertyType === "Component") collectComponentReferences(references, pkg.getId(), resource);
161
+ const excludedResourceIds = new Set(pkg.getSourceAtlasSettings().excludedResourceIds);
162
+ for (const resource of pkg.listResources()) if (resource.propertyType === "Component" && !excludedResourceIds.has(resource.getId())) collectComponentReferences(references, pkg.getId(), resource);
159
163
  return references;
160
164
  }
161
165
  //#endregion
@@ -182,6 +186,9 @@ function isFontResource(resource) {
182
186
  function isSoundResource(resource) {
183
187
  return resource.propertyType === "SoundResource";
184
188
  }
189
+ function isSwfResource(resource) {
190
+ return resource.propertyType === "SwfResource";
191
+ }
185
192
  function isSpineResource(resource) {
186
193
  return resource.propertyType === "SpineResource";
187
194
  }
@@ -223,10 +230,12 @@ function extname(fileName) {
223
230
  return normalized.slice(lastDot);
224
231
  }
225
232
  function resolvePublishedMiscFileName(resource, projectType) {
226
- const file = resource.getFile();
227
- if (projectType !== UNITY_PROJECT_TYPE$1) return file;
228
- if (file.toLowerCase().endsWith(".atlas")) return `${file}.txt`;
229
- return file;
233
+ const fileName = `${getPublishedId(resource)}${extname(resource.getFile())}`;
234
+ if (projectType === UNITY_PROJECT_TYPE$1 && fileName.toLowerCase().endsWith(".atlas")) return `${fileName}.txt`;
235
+ return fileName;
236
+ }
237
+ function resolvePublishedSwfFileName(resource) {
238
+ return `${getPublishedId(resource)}${extname(resource.getFile()) || ".swf"}`;
230
239
  }
231
240
  function resolvePublishedSkeletonFileName(resource, projectType) {
232
241
  if (projectType === UNITY_PROJECT_TYPE$1 && isSpineResource(resource) && resource.getFile().toLowerCase().endsWith(".skel")) return `${resource.getFile()}.bytes`;
@@ -293,16 +302,16 @@ function trimTrailingMissingHighResolutionIds(ids) {
293
302
  while (ids.length > 0 && !ids[ids.length - 1]) ids.pop();
294
303
  return ids;
295
304
  }
296
- function collectHighResolutionItemIds(resources, publishedResourceIds, includeHighResolution) {
305
+ function collectHighResolutionItemIds(resources, publishedResourceIds, includeHighResolution, excludedResourceIds) {
297
306
  const result = /* @__PURE__ */ new Map();
298
307
  if (includeHighResolution <= 0) return result;
299
308
  const highResolutionResourceByKey = /* @__PURE__ */ new Map();
300
309
  for (const resource of resources) {
301
- if (!isHighResolutionResource(resource)) continue;
310
+ if (!isHighResolutionResource(resource) || excludedResourceIds.has(resource.getId())) continue;
302
311
  highResolutionResourceByKey.set(buildHighResolutionResourceKey(resource), resource);
303
312
  }
304
313
  for (const resource of resources) {
305
- if (!isHighResolutionResource(resource)) continue;
314
+ if (!isHighResolutionResource(resource) || excludedResourceIds.has(resource.getId())) continue;
306
315
  if (!publishedResourceIds.has(resource.getId())) continue;
307
316
  if (isHighResolutionVariantName(resource.getName())) continue;
308
317
  const ids = [];
@@ -327,6 +336,7 @@ function collectHighResolutionItemIds(resources, publishedResourceIds, includeHi
327
336
  }
328
337
  function collectPackagePublishContext(pkg, options) {
329
338
  const resources = pkg.listResources();
339
+ const excludedResourceIds = new Set(pkg.getSourceAtlasSettings().excludedResourceIds);
330
340
  const resourceMap = new Map(resources.map((resource) => [resource.getId(), resource]));
331
341
  const referencedIds = collectPackageResourceReferences(pkg).localResourceIds;
332
342
  const pixelHitTestImageIds = /* @__PURE__ */ new Set();
@@ -338,10 +348,15 @@ function collectPackagePublishContext(pkg, options) {
338
348
  while (changed) {
339
349
  changed = false;
340
350
  for (const resourceId of [...exportedResourceIds]) {
351
+ if (excludedResourceIds.has(resourceId)) {
352
+ exportedResourceIds.delete(resourceId);
353
+ changed = true;
354
+ continue;
355
+ }
341
356
  const resource = resourcesById.get(resourceId);
342
357
  if (!resource || !isSkeletonResource(resource)) continue;
343
358
  for (const requiredId of resource.getRequireIds()) {
344
- if (!requiredId || exportedResourceIds.has(requiredId)) continue;
359
+ if (!requiredId || excludedResourceIds.has(requiredId) || exportedResourceIds.has(requiredId)) continue;
345
360
  exportedResourceIds.add(requiredId);
346
361
  changed = true;
347
362
  }
@@ -349,7 +364,7 @@ function collectPackagePublishContext(pkg, options) {
349
364
  }
350
365
  return exportedResourceIds;
351
366
  };
352
- for (const atlas of pkg.listAtlases()) for (const sprite of atlas.listSprites()) spriteItemIds.add(sprite.getItemId());
367
+ for (const atlas of pkg.listAtlases()) for (const sprite of atlas.listSprites()) if (!excludedResourceIds.has(sprite.getItemId())) spriteItemIds.add(sprite.getItemId());
353
368
  for (const resource of resources) {
354
369
  if (!isComponentResource(resource)) continue;
355
370
  const component = resource;
@@ -358,7 +373,7 @@ function collectPackagePublishContext(pkg, options) {
358
373
  const hitTest = component.getHitTest?.()?.trim();
359
374
  if (hitTest && !hitTest.includes(",")) {
360
375
  const sourceId = childMap.get(hitTest)?.getSrc?.();
361
- if (sourceId) {
376
+ if (sourceId && !excludedResourceIds.has(sourceId)) {
362
377
  const sourceResource = resourceMap.get(sourceId);
363
378
  if (sourceResource && isImageResource(sourceResource)) pixelHitTestImageIds.add(sourceId);
364
379
  }
@@ -367,7 +382,7 @@ function collectPackagePublishContext(pkg, options) {
367
382
  const publishedResourceIds = new Set(spriteItemIds);
368
383
  for (const resource of resources) {
369
384
  const resourceId = resource.getId();
370
- if (!resourceId) continue;
385
+ if (!resourceId || excludedResourceIds.has(resourceId)) continue;
371
386
  if (isComponentResource(resource)) {
372
387
  if (resource.getExported() || referencedIds.has(resourceId)) publishedResourceIds.add(resourceId);
373
388
  continue;
@@ -391,7 +406,7 @@ function collectPackagePublishContext(pkg, options) {
391
406
  if (resource.getExported() || referencedIds.has(resourceId)) publishedResourceIds.add(resourceId);
392
407
  }
393
408
  for (const resourceId of collectExportedResourceIds(resources, publishedResourceIds)) publishedResourceIds.add(resourceId);
394
- const highResolutionItemIds = collectHighResolutionItemIds(resources, publishedResourceIds, options.includeHighResolution);
409
+ const highResolutionItemIds = collectHighResolutionItemIds(resources, publishedResourceIds, options.includeHighResolution, excludedResourceIds);
395
410
  if (!options.includeBranches) {
396
411
  const mainByKey = /* @__PURE__ */ new Map();
397
412
  const activeBranchByKey = /* @__PURE__ */ new Map();
@@ -519,6 +534,10 @@ async function annotatePackagePublishArtifacts(pkg, basePath, encoder, options)
519
534
  setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource, options.projectType));
520
535
  continue;
521
536
  }
537
+ if (isSwfResource(resource)) {
538
+ setPublishedFileExtra(resource, resolvePublishedSwfFileName(resource));
539
+ continue;
540
+ }
522
541
  if (isSkeletonResource(resource)) setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource, options.projectType));
523
542
  }
524
543
  }
@@ -1777,7 +1796,7 @@ function packAtlasPages(inputs, options, forceSinglePage, sizeOverrides) {
1777
1796
  });
1778
1797
  return new MaxRectsPackerCompat({
1779
1798
  pot: sizeOverrides?.powerOfTwo ?? options.powerOfTwo,
1780
- mof: sizeOverrides?.multipleOfFour ?? !options.powerOfTwo,
1799
+ mof: sizeOverrides?.multipleOfFour ?? options.multipleOfFour,
1781
1800
  padding: options.padding,
1782
1801
  rotation: options.allowRotation,
1783
1802
  minWidth: 16,
@@ -1877,7 +1896,7 @@ async function writeAtlasPageImage(pkg, inputs, page, atlasFileName, encoder, op
1877
1896
  }
1878
1897
  }
1879
1898
  const outputFile = `${options.outputPath}/${atlasFileName}`;
1880
- await encoder({ create: {
1899
+ const atlasPipeline = encoder({ create: {
1881
1900
  width: page.width,
1882
1901
  height: page.height,
1883
1902
  channels: 4,
@@ -1887,7 +1906,13 @@ async function writeAtlasPageImage(pkg, inputs, page, atlasFileName, encoder, op
1887
1906
  b: 0,
1888
1907
  alpha: 0
1889
1908
  }
1890
- } }).composite(compositeInputs).toFile(outputFile);
1909
+ } }).composite(compositeInputs);
1910
+ if (options.extractAlpha) {
1911
+ const atlasBuffer = await atlasPipeline.png().toBuffer();
1912
+ await encoder(atlasBuffer).removeAlpha().png().toFile(outputFile);
1913
+ const alphaBuffer = await encoder(atlasBuffer).extractChannel("alpha").png().toBuffer();
1914
+ await encoder(alphaBuffer).joinChannel([alphaBuffer, alphaBuffer]).png().toFile(`${options.outputPath}/${insertFileNameSuffix(atlasFileName, "!a")}`);
1915
+ } else await atlasPipeline.toFile(outputFile);
1891
1916
  logger.info(`atlas: Generated ${atlasFileName} (${page.width}x${page.height}, ${page.outputRects.length} sprites)`);
1892
1917
  }
1893
1918
  function inputToCompatRect(input, index) {
@@ -1937,6 +1962,9 @@ function resolveDirectOutputAtlasSize(width, height, options) {
1937
1962
  if (options.powerOfTwo) {
1938
1963
  resolvedWidth = nextPow2(resolvedWidth);
1939
1964
  resolvedHeight = nextPow2(resolvedHeight);
1965
+ } else if (options.multipleOfFour) {
1966
+ resolvedWidth = roundUpToMultiple(resolvedWidth, 4);
1967
+ resolvedHeight = roundUpToMultiple(resolvedHeight, 4);
1940
1968
  }
1941
1969
  return {
1942
1970
  width: resolvedWidth,
@@ -2051,9 +2079,8 @@ function sortResourcesByOrder(resources, orderMap, inputOrderMap) {
2051
2079
  });
2052
2080
  return ordered;
2053
2081
  }
2054
- function getResourceTextureSetMode(resource) {
2055
- if (isImageResource(resource)) return parseTextureSetMode(resource.getTextureSetMode?.());
2056
- return parseTextureSetMode(resource.getTextureSetMode?.());
2082
+ function getResourceTextureSetMode(resource, maxAtlasIndex) {
2083
+ return parseTextureSetMode(resource.getTextureSetMode?.(), maxAtlasIndex);
2057
2084
  }
2058
2085
  function groupStandaloneInputs(doc, inputs, options) {
2059
2086
  const autoInputs = [];
@@ -2072,7 +2099,7 @@ function groupStandaloneInputs(doc, inputs, options) {
2072
2099
  for (const input of inputs) {
2073
2100
  const branchName = getInputBranchName(input);
2074
2101
  const branchOrdinal = branchOrdinalByName.get(branchName) ?? 0;
2075
- const mode = getResourceTextureSetMode(input.resource);
2102
+ const mode = getResourceTextureSetMode(input.resource, options.maxAtlasIndex ?? 10);
2076
2103
  if (mode.kind === "standalone") {
2077
2104
  const key = `${branchName}\u0000${getPublishedItemId(input.resource)}`;
2078
2105
  const existing = standaloneGroups.get(key);
@@ -2116,6 +2143,8 @@ const ATLAS_DEFAULTS = {
2116
2143
  allowRotation: true,
2117
2144
  padding: 1,
2118
2145
  powerOfTwo: false,
2146
+ maxAtlasIndex: 10,
2147
+ multipleOfFour: false,
2119
2148
  square: false,
2120
2149
  multiPage: true,
2121
2150
  trimImage: false,
@@ -2199,7 +2228,7 @@ async function resolveEditorCompatibleResourceOrder(pkg, allResources, options)
2199
2228
  const refChild = child;
2200
2229
  await addResource(resourceMap.get(refChild.getSrc?.() ?? ""));
2201
2230
  for (const ref of [
2202
- refChild.getUrl?.(),
2231
+ refChild.getClearOnPublish?.() ? void 0 : refChild.getUrl?.(),
2203
2232
  refChild.getDefaultItem?.(),
2204
2233
  refChild.getIcon?.(),
2205
2234
  refChild.getSelectedIcon?.(),
@@ -2213,11 +2242,14 @@ async function resolveEditorCompatibleResourceOrder(pkg, allResources, options)
2213
2242
  refChild.getInstanceIcon?.(),
2214
2243
  refChild.getInstanceSelectedIcon?.()
2215
2244
  ]) await addResourceByLocalUiUrl(ref);
2216
- for (const item of refChild.getInstanceComboItems?.() ?? []) await addResourceByLocalUiUrl(item.icon ?? void 0);
2217
- for (const item of refChild.getListItems?.() ?? []) {
2245
+ for (const item of refChild.getInstanceAutoClearItems?.() ? [] : refChild.getInstanceComboItems?.() ?? []) await addResourceByLocalUiUrl(item.icon ?? void 0);
2246
+ for (const item of refChild.getAutoClearItems?.() ? [] : refChild.getListItems?.() ?? []) {
2218
2247
  await addResourceByLocalUiUrl(item.icon ?? void 0);
2248
+ await addResourceByLocalUiUrl(item.selectedIcon ?? void 0);
2219
2249
  await addResourceByLocalUiUrl(item.url ?? void 0);
2250
+ for (const property of item.propertyOverrides ?? []) await addResourceByLocalUiUrl(property.value);
2220
2251
  }
2252
+ for (const property of refChild.getPropertyOverrides?.() ?? []) await addResourceByLocalUiUrl(property.value);
2221
2253
  for (const gear of refChild.listGears?.() ?? []) await addGearIconResources(gear);
2222
2254
  }
2223
2255
  for (const ref of [
@@ -2468,23 +2500,32 @@ const FGUI_TYPESCRIPT_RUNTIME_TYPES = new Set([
2468
2500
  "GTree",
2469
2501
  "Transition"
2470
2502
  ]);
2471
- const SHARED_FGUI_TYPESCRIPT_VARIANT = {
2503
+ const LAYABOX_TYPESCRIPT_VARIANT = {
2472
2504
  binderMethod: "setExtension",
2473
- runtimeNamespace: "fgui"
2505
+ runtimeNamespace: "fgui",
2506
+ runtimeImport: ""
2507
+ };
2508
+ const COCOS_CREATOR_TYPESCRIPT_VARIANT = {
2509
+ ...LAYABOX_TYPESCRIPT_VARIANT,
2510
+ runtimeImport: "import * as fgui from \"fairygui-cc\";"
2474
2511
  };
2475
2512
  async function publishCodeGeneration(doc, options) {
2476
2513
  const logger = doc.getLogger();
2477
2514
  const settings = resolveCodeGenerationSettings(doc);
2478
2515
  if (!settings.allowGenCode) return;
2479
- const plugins = options.plugins?.filter((plugin) => typeof plugin.plugin.genCode === "function") ?? [];
2516
+ const plugins = options.plugins ?? [];
2480
2517
  if (plugins.length > 0) {
2481
2518
  let handled = false;
2482
- for (const plugin of plugins) try {
2483
- await plugin.plugin.genCode(doc, settings, options);
2484
- handled = true;
2485
- logger.info(`publish: Generated code using plugin "${plugin.name}"`);
2486
- } catch (error) {
2487
- logger.warn(`publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`);
2519
+ for (const plugin of plugins) {
2520
+ const genCode = plugin.plugin.genCode;
2521
+ if (!genCode) continue;
2522
+ try {
2523
+ await genCode(doc, settings, options);
2524
+ handled = true;
2525
+ logger.info(`publish: Generated code using plugin "${plugin.name}"`);
2526
+ } catch (error) {
2527
+ logger.warn(`publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`);
2528
+ }
2488
2529
  }
2489
2530
  if (handled) return;
2490
2531
  }
@@ -2548,8 +2589,9 @@ function supportsCodeGenerationLane(doc, codeType) {
2548
2589
  }
2549
2590
  function resolveFguiTypescriptVariant(doc) {
2550
2591
  const projectType = doc.getRoot().getProjectType();
2551
- if (projectType !== ProjectType.LayaBox && projectType !== ProjectType.CocosCreator) return null;
2552
- return SHARED_FGUI_TYPESCRIPT_VARIANT;
2592
+ if (projectType === ProjectType.LayaBox) return LAYABOX_TYPESCRIPT_VARIANT;
2593
+ if (projectType === ProjectType.CocosCreator) return COCOS_CREATOR_TYPESCRIPT_VARIANT;
2594
+ return null;
2553
2595
  }
2554
2596
  async function generateUnityCode(doc, pkg, plan, fs) {
2555
2597
  const packageDir = fs.join(plan.outputDir, plan.packageFolderName);
@@ -2732,7 +2774,8 @@ function renderFguiTypescriptComponentClass(classInfo, plan, variant) {
2732
2774
  }
2733
2775
  function renderFguiTypescriptBinder(classes, plan, variant) {
2734
2776
  const bindLines = classes.map((classInfo) => `\t\t${variant.runtimeNamespace}.UIObjectFactory.${variant.binderMethod}(${classInfo.encodedClassName}.URL, ${classInfo.encodedClassName});`).join("\n");
2735
- const importLines = classes.map((classInfo) => `import ${classInfo.encodedClassName} from "./${classInfo.encodedClassName}";`).join("\n");
2777
+ const classImports = classes.map((classInfo) => `import ${classInfo.encodedClassName} from "./${classInfo.encodedClassName}";`).join("\n");
2778
+ const importLines = [variant.runtimeImport, classImports].filter(Boolean).join("\n");
2736
2779
  return renderTemplate(FGUI_TYPESCRIPT_BINDER_TEMPLATE, {
2737
2780
  binderClassName: plan.binderClassName,
2738
2781
  bindLines: bindLines ? `${bindLines}\n` : "",
@@ -2796,6 +2839,7 @@ function normalizeTypeName(value) {
2796
2839
  }
2797
2840
  function collectFguiTypescriptImports(classInfo, variant) {
2798
2841
  const imports = /* @__PURE__ */ new Set();
2842
+ if (variant.runtimeImport) imports.add(variant.runtimeImport);
2799
2843
  for (const member of classInfo.members) {
2800
2844
  if (member.ignored) continue;
2801
2845
  const translated = translateFguiTypescriptType(member.type, variant);
@@ -2858,23 +2902,24 @@ async function exportPackageExternalResources(pkg, outputDir, basePath, fs, read
2858
2902
  if (exportedResourceIds.size === 0) return;
2859
2903
  if (!basePath || !readFileRaw) {
2860
2904
  if (pkg.listResources().some((resource) => {
2861
- return (isMiscResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
2905
+ return (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
2862
2906
  })) throw new Error(`publish: External resources in package "${pkg.getName()}" require basePath and readFileRaw for output.`);
2863
2907
  return;
2864
2908
  }
2865
2909
  for (const resource of pkg.listResources()) {
2866
2910
  const resourceId = resource.getId();
2867
- const isSkeletonExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSkeletonResource(resource));
2911
+ const isExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource));
2868
2912
  const isSkeletonImageDependency = skeletonDependencyImageIds.has(resourceId) && isImageResource(resource);
2869
- if (!isSkeletonExternal && !isSkeletonImageDependency) continue;
2913
+ if (!isExternal && !isSkeletonImageDependency) continue;
2870
2914
  let sourcePath;
2871
2915
  let targetName;
2872
2916
  if (isSkeletonImageDependency) {
2873
2917
  sourcePath = resolveImagePath(resource, pkg, basePath);
2874
2918
  targetName = resolveImageFileName(resource);
2875
- } else if (isMiscResource(resource) || isSkeletonResource(resource)) {
2919
+ } else if (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) {
2876
2920
  sourcePath = resolveGenericResourcePath(resource, pkg, basePath);
2877
- targetName = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
2921
+ const publishedFile = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
2922
+ targetName = isMiscResource(resource) || isSwfResource(resource) ? `${pkg.getPublishName() || pkg.getName()}_${publishedFile}` : publishedFile;
2878
2923
  } else continue;
2879
2924
  const targetPath = fs.join(outputDir, targetName);
2880
2925
  try {
@@ -2914,16 +2959,20 @@ function resolvePublishOptions(doc, overrides = {}) {
2914
2959
  const root = doc.getRoot();
2915
2960
  const publishSettings = (root.getSettings?.() ?? {}).publish ?? {};
2916
2961
  const atlasSetting = publishSettings.atlasSetting ?? {};
2917
- const projectType = root.getProjectType();
2918
- const fileExtension = overrides.fileExtension ?? resolveDefaultPublishFileExtension(projectType, publishSettings);
2919
- let compressed = overrides.compressed ?? publishSettings.compressDesc ?? false;
2920
- if (projectType === UNITY_PROJECT_TYPE) compressed = overrides.compressed ?? false;
2962
+ const projectType = overrides.targetProjectType ?? root.getProjectType();
2963
+ const explicitLayaboxTarget = overrides.targetProjectType === ProjectType.LayaBox;
2964
+ const fileExtension = overrides.fileExtension ?? (explicitLayaboxTarget ? "fui" : resolveDefaultPublishFileExtension(projectType, publishSettings));
2965
+ const runtimeRejectsCompression = projectType === UNITY_PROJECT_TYPE || projectType === COCOS_CREATOR_PROJECT_TYPE;
2966
+ if (runtimeRejectsCompression && overrides.compressed === true) throw new Error("publish: The selected target runtime does not support compressed package data.");
2967
+ const compressed = runtimeRejectsCompression ? false : overrides.compressed ?? publishSettings.compressDesc ?? false;
2921
2968
  const atlasOptions = {
2922
2969
  maxSize: overrides.atlas?.maxSize ?? atlasSetting.maxSize ?? 2048,
2923
2970
  fast: overrides.atlas?.fast ?? atlasSetting.fast ?? true,
2924
- allowRotation: overrides.atlas?.allowRotation ?? atlasSetting.allowRotation ?? false,
2971
+ allowRotation: overrides.atlas?.allowRotation ?? (explicitLayaboxTarget ? false : atlasSetting.allowRotation ?? false),
2925
2972
  padding: overrides.atlas?.padding ?? atlasSetting.padding ?? 2,
2926
2973
  powerOfTwo: overrides.atlas?.powerOfTwo ?? atlasSetting.sizeOption === "pot",
2974
+ maxAtlasIndex: overrides.atlas?.maxAtlasIndex ?? 10,
2975
+ multipleOfFour: overrides.atlas?.multipleOfFour ?? atlasSetting.sizeOption === "mof",
2927
2976
  square: overrides.atlas?.square ?? atlasSetting.forceSquare ?? false,
2928
2977
  multiPage: overrides.atlas?.multiPage ?? atlasSetting.paging ?? true,
2929
2978
  trimImage: overrides.atlas?.trimImage ?? atlasSetting.trimImage ?? false,
@@ -3043,6 +3092,19 @@ function publish(options) {
3043
3092
  }
3044
3093
  }
3045
3094
  const publishName = pkg.getPublishName() || pkg.getName();
3095
+ const sourceAtlas = pkg.getSourceAtlasSettings();
3096
+ const usePackageAtlas = !sourceAtlas.useGlobal;
3097
+ const atlas = {
3098
+ ...config.atlas,
3099
+ maxSize: options.atlas?.maxSize ?? (usePackageAtlas ? sourceAtlas.maxSize : config.atlas.maxSize),
3100
+ allowRotation: config.projectType === ProjectType.LayaBox ? false : options.atlas?.allowRotation ?? (usePackageAtlas ? sourceAtlas.allowRotation : config.atlas.allowRotation),
3101
+ powerOfTwo: options.atlas?.powerOfTwo ?? (usePackageAtlas ? sourceAtlas.sizeOption === "pot" : config.atlas.powerOfTwo),
3102
+ maxAtlasIndex: options.atlas?.maxAtlasIndex ?? sourceAtlas.maxIndex,
3103
+ multipleOfFour: options.atlas?.multipleOfFour ?? (usePackageAtlas ? sourceAtlas.sizeOption === "mof" : config.atlas.multipleOfFour),
3104
+ square: options.atlas?.square ?? (usePackageAtlas ? sourceAtlas.forceSquare : config.atlas.square),
3105
+ multiPage: options.atlas?.multiPage ?? (usePackageAtlas ? sourceAtlas.paging : config.atlas.multiPage),
3106
+ extractAlpha: config.projectType === ProjectType.Unity && (options.atlas?.extractAlpha ?? (usePackageAtlas || sourceAtlas.extractAlpha ? sourceAtlas.extractAlpha : config.atlas.extractAlpha))
3107
+ };
3046
3108
  return {
3047
3109
  pkg,
3048
3110
  outputDir,
@@ -3054,7 +3116,7 @@ function publish(options) {
3054
3116
  activeBranch: config.activeBranch,
3055
3117
  includeHighResolution: config.includeHighResolution,
3056
3118
  separatedAtlasForBranch: config.separatedAtlasForBranch,
3057
- atlas: config.atlas
3119
+ atlas
3058
3120
  };
3059
3121
  };
3060
3122
  const createNoopPublishFs = () => ({
@@ -3074,7 +3136,6 @@ function publish(options) {
3074
3136
  const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(plan.fileExtension);
3075
3137
  await atlas({
3076
3138
  ...plan.atlas,
3077
- ...options.atlas ?? {},
3078
3139
  separatedAtlasForBranch: plan.separatedAtlasForBranch,
3079
3140
  encoder: options.encoder,
3080
3141
  basePath: options.basePath,