@openfairygui/functions 0.3.0-alpha.4 → 0.3.1

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.
Files changed (37) hide show
  1. package/dist/{atlas-C6tbl7nn.d.ts → atlas-BtWa1DwO.d.ts} +6 -0
  2. package/dist/{atlas-CHsu2Y8i.d.cts → atlas-CSqHsG0X.d.cts} +6 -0
  3. package/dist/index.cjs +2 -2
  4. package/dist/index.d.cts +2 -2
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +2 -2
  7. package/dist/node.cjs +128 -30
  8. package/dist/node.d.cts +2 -2
  9. package/dist/node.d.ts +2 -2
  10. package/dist/node.js +128 -30
  11. package/dist/{publish-CyBj2o7n.js → publish-Cy09yjfn.js} +122 -54
  12. package/dist/{publish-C7qHwEiP.cjs → publish-DhMv_lEP.cjs} +122 -54
  13. package/dist/{restore-BeWaJNjR.d.cts → restore-CbscKkNw.d.ts} +9 -4
  14. package/dist/{restore-DVo1hXpN.js → restore-DB_L_xq4.js} +1 -1
  15. package/dist/{restore-Dh0-Nvms.d.ts → restore-k3oX26Fs.d.cts} +9 -4
  16. package/dist/{restore-LXbDQqmT.cjs → restore-n61oZ4nw.cjs} +1 -1
  17. package/dist/web.cjs +47 -64
  18. package/dist/web.d.cts +2 -2
  19. package/dist/web.d.ts +2 -2
  20. package/dist/web.js +49 -66
  21. package/package.json +5 -2
  22. package/src/adapters/node/plugins.ts +29 -13
  23. package/src/adapters/node/publish.ts +74 -4
  24. package/src/adapters/node/validate.ts +1 -0
  25. package/src/adapters/web/publish.ts +2 -0
  26. package/src/adapters/web/raster.ts +55 -72
  27. package/src/atlas/packing.ts +22 -13
  28. package/src/atlas.ts +22 -3
  29. package/src/codegen.ts +24 -11
  30. package/src/plugins/types.ts +7 -0
  31. package/src/publish/contracts.ts +3 -0
  32. package/src/publish/external-resources.ts +12 -6
  33. package/src/publish/options.ts +21 -7
  34. package/src/publish/package-context.ts +35 -11
  35. package/src/publish/resource-references.ts +21 -6
  36. package/src/publish.ts +26 -4
  37. package/src/utils.ts +2 -2
@@ -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 [
@@ -2407,6 +2439,9 @@ const FGUI_TYPESCRIPT_BINDER_TEMPLATE = `{{generatedMark}}
2407
2439
  function formatPluginError(error) {
2408
2440
  return error instanceof Error ? error.message : String(error);
2409
2441
  }
2442
+ function shouldAbortPluginFailure(plugin) {
2443
+ return plugin.failureMode !== "warn";
2444
+ }
2410
2445
  //#endregion
2411
2446
  //#region src/path-utils.ts
2412
2447
  function trimTrailingSlashes(value) {
@@ -2468,23 +2503,34 @@ const FGUI_TYPESCRIPT_RUNTIME_TYPES = new Set([
2468
2503
  "GTree",
2469
2504
  "Transition"
2470
2505
  ]);
2471
- const SHARED_FGUI_TYPESCRIPT_VARIANT = {
2506
+ const LAYABOX_TYPESCRIPT_VARIANT = {
2472
2507
  binderMethod: "setExtension",
2473
- runtimeNamespace: "fgui"
2508
+ runtimeNamespace: "fgui",
2509
+ runtimeImport: ""
2510
+ };
2511
+ const COCOS_CREATOR_TYPESCRIPT_VARIANT = {
2512
+ ...LAYABOX_TYPESCRIPT_VARIANT,
2513
+ runtimeImport: "import * as fgui from \"fairygui-cc\";"
2474
2514
  };
2475
2515
  async function publishCodeGeneration(doc, options) {
2476
2516
  const logger = doc.getLogger();
2477
2517
  const settings = resolveCodeGenerationSettings(doc);
2478
2518
  if (!settings.allowGenCode) return;
2479
- const plugins = options.plugins?.filter((plugin) => typeof plugin.plugin.genCode === "function") ?? [];
2519
+ const plugins = options.plugins ?? [];
2480
2520
  if (plugins.length > 0) {
2481
2521
  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)}`);
2522
+ for (const plugin of plugins) {
2523
+ const genCode = plugin.plugin.genCode;
2524
+ if (!genCode) continue;
2525
+ try {
2526
+ await genCode(doc, settings, options);
2527
+ handled = true;
2528
+ logger.info(`publish: Generated code using plugin "${plugin.name}"`);
2529
+ } catch (error) {
2530
+ const message = `publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`;
2531
+ if (shouldAbortPluginFailure(plugin)) throw new Error(message);
2532
+ logger.warn(message);
2533
+ }
2488
2534
  }
2489
2535
  if (handled) return;
2490
2536
  }
@@ -2548,8 +2594,9 @@ function supportsCodeGenerationLane(doc, codeType) {
2548
2594
  }
2549
2595
  function resolveFguiTypescriptVariant(doc) {
2550
2596
  const projectType = doc.getRoot().getProjectType();
2551
- if (projectType !== _openfairygui_core.ProjectType.LayaBox && projectType !== _openfairygui_core.ProjectType.CocosCreator) return null;
2552
- return SHARED_FGUI_TYPESCRIPT_VARIANT;
2597
+ if (projectType === _openfairygui_core.ProjectType.LayaBox) return LAYABOX_TYPESCRIPT_VARIANT;
2598
+ if (projectType === _openfairygui_core.ProjectType.CocosCreator) return COCOS_CREATOR_TYPESCRIPT_VARIANT;
2599
+ return null;
2553
2600
  }
2554
2601
  async function generateUnityCode(doc, pkg, plan, fs) {
2555
2602
  const packageDir = fs.join(plan.outputDir, plan.packageFolderName);
@@ -2732,7 +2779,8 @@ function renderFguiTypescriptComponentClass(classInfo, plan, variant) {
2732
2779
  }
2733
2780
  function renderFguiTypescriptBinder(classes, plan, variant) {
2734
2781
  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");
2782
+ const classImports = classes.map((classInfo) => `import ${classInfo.encodedClassName} from "./${classInfo.encodedClassName}";`).join("\n");
2783
+ const importLines = [variant.runtimeImport, classImports].filter(Boolean).join("\n");
2736
2784
  return renderTemplate(FGUI_TYPESCRIPT_BINDER_TEMPLATE, {
2737
2785
  binderClassName: plan.binderClassName,
2738
2786
  bindLines: bindLines ? `${bindLines}\n` : "",
@@ -2796,6 +2844,7 @@ function normalizeTypeName(value) {
2796
2844
  }
2797
2845
  function collectFguiTypescriptImports(classInfo, variant) {
2798
2846
  const imports = /* @__PURE__ */ new Set();
2847
+ if (variant.runtimeImport) imports.add(variant.runtimeImport);
2799
2848
  for (const member of classInfo.members) {
2800
2849
  if (member.ignored) continue;
2801
2850
  const translated = translateFguiTypescriptType(member.type, variant);
@@ -2858,23 +2907,24 @@ async function exportPackageExternalResources(pkg, outputDir, basePath, fs, read
2858
2907
  if (exportedResourceIds.size === 0) return;
2859
2908
  if (!basePath || !readFileRaw) {
2860
2909
  if (pkg.listResources().some((resource) => {
2861
- return (isMiscResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
2910
+ return (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
2862
2911
  })) throw new Error(`publish: External resources in package "${pkg.getName()}" require basePath and readFileRaw for output.`);
2863
2912
  return;
2864
2913
  }
2865
2914
  for (const resource of pkg.listResources()) {
2866
2915
  const resourceId = resource.getId();
2867
- const isSkeletonExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSkeletonResource(resource));
2916
+ const isExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource));
2868
2917
  const isSkeletonImageDependency = skeletonDependencyImageIds.has(resourceId) && isImageResource(resource);
2869
- if (!isSkeletonExternal && !isSkeletonImageDependency) continue;
2918
+ if (!isExternal && !isSkeletonImageDependency) continue;
2870
2919
  let sourcePath;
2871
2920
  let targetName;
2872
2921
  if (isSkeletonImageDependency) {
2873
2922
  sourcePath = resolveImagePath(resource, pkg, basePath);
2874
2923
  targetName = resolveImageFileName(resource);
2875
- } else if (isMiscResource(resource) || isSkeletonResource(resource)) {
2924
+ } else if (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) {
2876
2925
  sourcePath = resolveGenericResourcePath(resource, pkg, basePath);
2877
- targetName = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
2926
+ const publishedFile = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
2927
+ targetName = isMiscResource(resource) || isSwfResource(resource) ? `${pkg.getPublishName() || pkg.getName()}_${publishedFile}` : publishedFile;
2878
2928
  } else continue;
2879
2929
  const targetPath = fs.join(outputDir, targetName);
2880
2930
  try {
@@ -2914,16 +2964,20 @@ function resolvePublishOptions(doc, overrides = {}) {
2914
2964
  const root = doc.getRoot();
2915
2965
  const publishSettings = (root.getSettings?.() ?? {}).publish ?? {};
2916
2966
  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;
2967
+ const projectType = overrides.targetProjectType ?? root.getProjectType();
2968
+ const explicitLayaboxTarget = overrides.targetProjectType === _openfairygui_core.ProjectType.LayaBox;
2969
+ const fileExtension = overrides.fileExtension ?? (explicitLayaboxTarget ? "fui" : resolveDefaultPublishFileExtension(projectType, publishSettings));
2970
+ const runtimeRejectsCompression = projectType === UNITY_PROJECT_TYPE || projectType === COCOS_CREATOR_PROJECT_TYPE;
2971
+ if (runtimeRejectsCompression && overrides.compressed === true) throw new Error("publish: The selected target runtime does not support compressed package data.");
2972
+ const compressed = runtimeRejectsCompression ? false : overrides.compressed ?? publishSettings.compressDesc ?? false;
2921
2973
  const atlasOptions = {
2922
2974
  maxSize: overrides.atlas?.maxSize ?? atlasSetting.maxSize ?? 2048,
2923
2975
  fast: overrides.atlas?.fast ?? atlasSetting.fast ?? true,
2924
- allowRotation: overrides.atlas?.allowRotation ?? atlasSetting.allowRotation ?? false,
2976
+ allowRotation: overrides.atlas?.allowRotation ?? (explicitLayaboxTarget ? false : atlasSetting.allowRotation ?? false),
2925
2977
  padding: overrides.atlas?.padding ?? atlasSetting.padding ?? 2,
2926
2978
  powerOfTwo: overrides.atlas?.powerOfTwo ?? atlasSetting.sizeOption === "pot",
2979
+ maxAtlasIndex: overrides.atlas?.maxAtlasIndex ?? 10,
2980
+ multipleOfFour: overrides.atlas?.multipleOfFour ?? atlasSetting.sizeOption === "mof",
2927
2981
  square: overrides.atlas?.square ?? atlasSetting.forceSquare ?? false,
2928
2982
  multiPage: overrides.atlas?.multiPage ?? atlasSetting.paging ?? true,
2929
2983
  trimImage: overrides.atlas?.trimImage ?? atlasSetting.trimImage ?? false,
@@ -2946,7 +3000,9 @@ async function runPublishPluginHook(plugins, hook, doc, options) {
2946
3000
  try {
2947
3001
  await fn(doc, options);
2948
3002
  } catch (error) {
2949
- logger.warn(`publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`);
3003
+ const message = `publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`;
3004
+ if (shouldAbortPluginFailure(plugin)) throw new Error(message);
3005
+ logger.warn(message);
2950
3006
  }
2951
3007
  }
2952
3008
  }
@@ -3043,6 +3099,19 @@ function publish(options) {
3043
3099
  }
3044
3100
  }
3045
3101
  const publishName = pkg.getPublishName() || pkg.getName();
3102
+ const sourceAtlas = pkg.getSourceAtlasSettings();
3103
+ const usePackageAtlas = !sourceAtlas.useGlobal;
3104
+ const atlas = {
3105
+ ...config.atlas,
3106
+ maxSize: options.atlas?.maxSize ?? (usePackageAtlas ? sourceAtlas.maxSize : config.atlas.maxSize),
3107
+ allowRotation: config.projectType === _openfairygui_core.ProjectType.LayaBox ? false : options.atlas?.allowRotation ?? (usePackageAtlas ? sourceAtlas.allowRotation : config.atlas.allowRotation),
3108
+ powerOfTwo: options.atlas?.powerOfTwo ?? (usePackageAtlas ? sourceAtlas.sizeOption === "pot" : config.atlas.powerOfTwo),
3109
+ maxAtlasIndex: options.atlas?.maxAtlasIndex ?? sourceAtlas.maxIndex,
3110
+ multipleOfFour: options.atlas?.multipleOfFour ?? (usePackageAtlas ? sourceAtlas.sizeOption === "mof" : config.atlas.multipleOfFour),
3111
+ square: options.atlas?.square ?? (usePackageAtlas ? sourceAtlas.forceSquare : config.atlas.square),
3112
+ multiPage: options.atlas?.multiPage ?? (usePackageAtlas ? sourceAtlas.paging : config.atlas.multiPage),
3113
+ extractAlpha: config.projectType === _openfairygui_core.ProjectType.Unity && (options.atlas?.extractAlpha ?? (usePackageAtlas || sourceAtlas.extractAlpha ? sourceAtlas.extractAlpha : config.atlas.extractAlpha))
3114
+ };
3046
3115
  return {
3047
3116
  pkg,
3048
3117
  outputDir,
@@ -3054,7 +3123,7 @@ function publish(options) {
3054
3123
  activeBranch: config.activeBranch,
3055
3124
  includeHighResolution: config.includeHighResolution,
3056
3125
  separatedAtlasForBranch: config.separatedAtlasForBranch,
3057
- atlas: config.atlas
3126
+ atlas
3058
3127
  };
3059
3128
  };
3060
3129
  const createNoopPublishFs = () => ({
@@ -3074,7 +3143,6 @@ function publish(options) {
3074
3143
  const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(plan.fileExtension);
3075
3144
  await atlas({
3076
3145
  ...plan.atlas,
3077
- ...options.atlas ?? {},
3078
3146
  separatedAtlasForBranch: plan.separatedAtlasForBranch,
3079
3147
  encoder: options.encoder,
3080
3148
  basePath: options.basePath,
@@ -1,4 +1,4 @@
1
- import { l as PublishFileSystem, r as AtlasRasterBackend, t as AtlasOptions } from "./atlas-CHsu2Y8i.cjs";
1
+ import { l as PublishFileSystem, r as AtlasRasterBackend, t as AtlasOptions } from "./atlas-BtWa1DwO.js";
2
2
  import { Component, Document, FileSystem, Package, ProjectSettings, PublishSettings, Transform } from "@openfairygui/core";
3
3
 
4
4
  //#region src/publish/options.d.ts
@@ -59,8 +59,10 @@ interface PublishOptions {
59
59
  */
60
60
  codeGeneration?: boolean;
61
61
  }
62
- interface ResolvedPublishAtlasOptions extends Pick<AtlasOptions, 'maxSize' | 'fast' | 'allowRotation' | 'padding' | 'powerOfTwo' | 'square' | 'multiPage' | 'trimImage' | 'extractAlpha'> {}
62
+ interface ResolvedPublishAtlasOptions extends Pick<AtlasOptions, 'maxSize' | 'fast' | 'allowRotation' | 'padding' | 'powerOfTwo' | 'maxAtlasIndex' | 'multipleOfFour' | 'square' | 'multiPage' | 'trimImage' | 'extractAlpha'> {}
63
63
  interface ResolvePublishOptionsOverrides {
64
+ /** Select a target profile between direct overrides and persisted project settings. */
65
+ targetProjectType?: number;
64
66
  compressed?: boolean;
65
67
  fileExtension?: string;
66
68
  packages?: string[];
@@ -164,6 +166,8 @@ interface PluginManifest {
164
166
  };
165
167
  icon?: string;
166
168
  main: string;
169
+ required?: boolean;
170
+ failureMode?: 'abort' | 'warn';
167
171
  }
168
172
  interface ICodeWriterConfig {
169
173
  blockStart?: string;
@@ -192,6 +196,7 @@ interface Plugin {
192
196
  interface LoadedPlugin {
193
197
  name: string;
194
198
  plugin: Plugin;
199
+ failureMode?: 'abort' | 'warn';
195
200
  }
196
201
  type PluginModule = Plugin & {
197
202
  default?: Plugin;
@@ -210,7 +215,7 @@ interface ResolvedPackageCodegenPlan {
210
215
  packageFolderName: string;
211
216
  packageNamespace: string;
212
217
  binderClassName: string;
213
- settings: CliCodeGenerationSettings;
218
+ settings: Required<CliCodeGenerationSettings>;
214
219
  }
215
220
  interface CodegenMember {
216
221
  index: number;
@@ -236,7 +241,7 @@ interface CodegenClass {
236
241
  members: CodegenMember[];
237
242
  }
238
243
  declare function publishCodeGeneration(doc: Document, options: PublishCodeGenerationOptions): Promise<void>;
239
- declare function resolvePackageCodegenPlan(pkg: Package, settings: CliCodeGenerationSettings, options: PublishCodeGenerationOptions): ResolvedPackageCodegenPlan | null;
244
+ declare function resolvePackageCodegenPlan(pkg: Package, settings: Required<CliCodeGenerationSettings>, options: PublishCodeGenerationOptions): ResolvedPackageCodegenPlan | null;
240
245
  declare function buildCodegenClasses(doc: Document, pkg: Package, plan: ResolvedPackageCodegenPlan): CodegenClass[];
241
246
  declare function encodeText(value: string): Uint8Array;
242
247
  declare function decodeText(value: Uint8Array): string;
@@ -1,4 +1,4 @@
1
- import { d as basename, f as normalizeComparablePath, p as trimTrailingSlashes } from "./publish-CyBj2o7n.js";
1
+ import { d as basename, f as normalizeComparablePath, p as trimTrailingSlashes } from "./publish-Cy09yjfn.js";
2
2
  import { BinaryReader, ProjectType, ProjectWriter, generateId } from "@openfairygui/core";
3
3
  //#region src/restore-internals/output-transaction.ts
4
4
  function isPathWithin(root, candidate) {
@@ -1,4 +1,4 @@
1
- import { l as PublishFileSystem, r as AtlasRasterBackend, t as AtlasOptions } from "./atlas-C6tbl7nn.js";
1
+ import { l as PublishFileSystem, r as AtlasRasterBackend, t as AtlasOptions } from "./atlas-CSqHsG0X.cjs";
2
2
  import { Component, Document, FileSystem, Package, ProjectSettings, PublishSettings, Transform } from "@openfairygui/core";
3
3
 
4
4
  //#region src/publish/options.d.ts
@@ -59,8 +59,10 @@ interface PublishOptions {
59
59
  */
60
60
  codeGeneration?: boolean;
61
61
  }
62
- interface ResolvedPublishAtlasOptions extends Pick<AtlasOptions, 'maxSize' | 'fast' | 'allowRotation' | 'padding' | 'powerOfTwo' | 'square' | 'multiPage' | 'trimImage' | 'extractAlpha'> {}
62
+ interface ResolvedPublishAtlasOptions extends Pick<AtlasOptions, 'maxSize' | 'fast' | 'allowRotation' | 'padding' | 'powerOfTwo' | 'maxAtlasIndex' | 'multipleOfFour' | 'square' | 'multiPage' | 'trimImage' | 'extractAlpha'> {}
63
63
  interface ResolvePublishOptionsOverrides {
64
+ /** Select a target profile between direct overrides and persisted project settings. */
65
+ targetProjectType?: number;
64
66
  compressed?: boolean;
65
67
  fileExtension?: string;
66
68
  packages?: string[];
@@ -164,6 +166,8 @@ interface PluginManifest {
164
166
  };
165
167
  icon?: string;
166
168
  main: string;
169
+ required?: boolean;
170
+ failureMode?: 'abort' | 'warn';
167
171
  }
168
172
  interface ICodeWriterConfig {
169
173
  blockStart?: string;
@@ -192,6 +196,7 @@ interface Plugin {
192
196
  interface LoadedPlugin {
193
197
  name: string;
194
198
  plugin: Plugin;
199
+ failureMode?: 'abort' | 'warn';
195
200
  }
196
201
  type PluginModule = Plugin & {
197
202
  default?: Plugin;
@@ -210,7 +215,7 @@ interface ResolvedPackageCodegenPlan {
210
215
  packageFolderName: string;
211
216
  packageNamespace: string;
212
217
  binderClassName: string;
213
- settings: CliCodeGenerationSettings;
218
+ settings: Required<CliCodeGenerationSettings>;
214
219
  }
215
220
  interface CodegenMember {
216
221
  index: number;
@@ -236,7 +241,7 @@ interface CodegenClass {
236
241
  members: CodegenMember[];
237
242
  }
238
243
  declare function publishCodeGeneration(doc: Document, options: PublishCodeGenerationOptions): Promise<void>;
239
- declare function resolvePackageCodegenPlan(pkg: Package, settings: CliCodeGenerationSettings, options: PublishCodeGenerationOptions): ResolvedPackageCodegenPlan | null;
244
+ declare function resolvePackageCodegenPlan(pkg: Package, settings: Required<CliCodeGenerationSettings>, options: PublishCodeGenerationOptions): ResolvedPackageCodegenPlan | null;
240
245
  declare function buildCodegenClasses(doc: Document, pkg: Package, plan: ResolvedPackageCodegenPlan): CodegenClass[];
241
246
  declare function encodeText(value: string): Uint8Array;
242
247
  declare function decodeText(value: Uint8Array): string;
@@ -1,4 +1,4 @@
1
- const require_publish = require("./publish-C7qHwEiP.cjs");
1
+ const require_publish = require("./publish-DhMv_lEP.cjs");
2
2
  let _openfairygui_core = require("@openfairygui/core");
3
3
  //#region src/restore-internals/output-transaction.ts
4
4
  function isPathWithin(root, candidate) {