@openfairygui/cli 0.3.0-alpha.3 → 0.3.0-alpha.4

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 (2) hide show
  1. package/dist/cli.mjs +283 -9
  2. package/package.json +4 -4
package/dist/cli.mjs CHANGED
@@ -821,7 +821,7 @@ var ExtensibleProperty = class extends Property {
821
821
  };
822
822
  //#endregion
823
823
  //#region ../core/src/constants.ts
824
- const VERSION = `v0.3.0-alpha.3`;
824
+ const VERSION = `v0.3.0-alpha.4`;
825
825
  /** Binary package file magic number: "FGUI" as uint32. */
826
826
  const FGUI_MAGIC = 1179080009;
827
827
  /** Null string index in the binary string table. */
@@ -19366,8 +19366,8 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19366
19366
  const groupLayout = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.layout);
19367
19367
  if (groupLayout) g.setLayout({
19368
19368
  none: 0,
19369
- horizontal: 1,
19370
- vertical: 2
19369
+ hz: 1,
19370
+ vt: 2
19371
19371
  }[groupLayout] ?? 0);
19372
19372
  const groupLineGap = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.lineGap);
19373
19373
  if (groupLineGap !== void 0) g.setLineGap(parseInt2(groupLineGap));
@@ -20472,12 +20472,53 @@ function isProjectInt32(value) {
20472
20472
  const parsed = BigInt(trimmed);
20473
20473
  return parsed >= -2147483648n && parsed <= 2147483647n;
20474
20474
  }
20475
+ function isProjectFiniteNumber(value) {
20476
+ const trimmed = value.trim();
20477
+ return /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(trimmed) && Number.isFinite(Number(trimmed));
20478
+ }
20479
+ function isProjectBoolean(value) {
20480
+ return [
20481
+ "true",
20482
+ "false",
20483
+ "1",
20484
+ "0"
20485
+ ].includes(value.trim());
20486
+ }
20475
20487
  function hasInvalidProjectInt32Parts(value, partCount, allowSuffix = false) {
20476
20488
  const parts = String(value).split(",");
20477
20489
  if (allowSuffix ? parts.length < partCount : parts.length !== partCount) return true;
20478
20490
  return parts.slice(0, partCount).some((part) => !isProjectInt32(part));
20479
20491
  }
20480
- function validateComponentXmlGeometry(ctx, comp, sourcePath, componentNode) {
20492
+ function validateComponentXmlValues(ctx, comp, sourcePath, componentNode) {
20493
+ const addInvalidValue = (attrs, spec, path, expectation, isValid, nodeId) => {
20494
+ if (!spec) return;
20495
+ const value = readXmlAttr(attrs, spec);
20496
+ if (value === void 0 || isValid(String(value))) return;
20497
+ ctx.addDiagnostic({
20498
+ severity: "error",
20499
+ code: "invalid_project_value",
20500
+ path: `${path}.${spec.canonical}`,
20501
+ message: `Attribute "${spec.canonical}" must be ${expectation}; received ${JSON.stringify(String(value))}.`,
20502
+ resourceId: comp.getId(),
20503
+ ...nodeId ? { nodeId } : {},
20504
+ sourcePath
20505
+ });
20506
+ };
20507
+ const validateBooleanAttrs = (attrs, specs, path, nodeId) => {
20508
+ for (const spec of specs) addInvalidValue(attrs, spec, path, "true, false, 1, or 0", isProjectBoolean, nodeId);
20509
+ };
20510
+ const validateInt32Attrs = (attrs, specs, path, nodeId) => {
20511
+ for (const spec of specs) addInvalidValue(attrs, spec, path, "a signed 32-bit integer", isProjectInt32, nodeId);
20512
+ };
20513
+ const validateNumberTuple = (attrs, spec, partCount, path, nodeId) => {
20514
+ addInvalidValue(attrs, spec, path, `exactly ${partCount} finite number(s)`, (value) => {
20515
+ const parts = value.split(",");
20516
+ return parts.length === partCount && parts.every(isProjectFiniteNumber);
20517
+ }, nodeId);
20518
+ };
20519
+ const validateEnum = (attrs, spec, values, path, nodeId) => {
20520
+ addInvalidValue(attrs, spec, path, `one of ${values.map((value) => JSON.stringify(value)).join(", ")}`, (value) => values.includes(value.trim()), nodeId);
20521
+ };
20481
20522
  const addDiagnostics = (attrs, rules, path, nodeId) => {
20482
20523
  for (const [spec, partCount] of rules) {
20483
20524
  const value = readXmlAttr(attrs, spec);
@@ -20494,7 +20535,38 @@ function validateComponentXmlGeometry(ctx, comp, sourcePath, componentNode) {
20494
20535
  }
20495
20536
  };
20496
20537
  const componentPath = `components.${comp.getId()}`;
20497
- addDiagnostics(componentNode, COMPONENT_INT32_RULES, `${componentPath}.component`);
20538
+ const rootPath = `${componentPath}.component`;
20539
+ const rootAttrs = PROJECT_XML_PROTOCOL.componentRoot.attrs;
20540
+ addDiagnostics(componentNode, COMPONENT_INT32_RULES, rootPath);
20541
+ validateBooleanAttrs(componentNode, [
20542
+ rootAttrs.anchor,
20543
+ rootAttrs.opaque,
20544
+ rootAttrs.reversedMask,
20545
+ rootAttrs.bgColorEnabled
20546
+ ], rootPath);
20547
+ validateInt32Attrs(componentNode, [
20548
+ rootAttrs.scrollBarFlags,
20549
+ rootAttrs.designImageAlpha,
20550
+ rootAttrs.designImageLayer,
20551
+ rootAttrs.idnum
20552
+ ], rootPath);
20553
+ validateNumberTuple(componentNode, rootAttrs.pivot, 2, rootPath);
20554
+ validateEnum(componentNode, rootAttrs.overflow, [
20555
+ "visible",
20556
+ "hidden",
20557
+ "scroll"
20558
+ ], rootPath);
20559
+ validateEnum(componentNode, rootAttrs.scroll, [
20560
+ "horizontal",
20561
+ "vertical",
20562
+ "both"
20563
+ ], rootPath);
20564
+ validateEnum(componentNode, rootAttrs.scrollBar, [
20565
+ "default",
20566
+ "visible",
20567
+ "auto",
20568
+ "hidden"
20569
+ ], rootPath);
20498
20570
  const displayList = getXmlNode(componentNode.displayList);
20499
20571
  if (!displayList) return;
20500
20572
  let nodeIndex = 0;
@@ -20505,7 +20577,209 @@ function validateComponentXmlGeometry(ctx, comp, sourcePath, componentNode) {
20505
20577
  const nodePath = `${componentPath}.displayList.${nodeIndex++}`;
20506
20578
  addDiagnostics(attrs, DISPLAY_OBJECT_INT32_RULES, nodePath, nodeId);
20507
20579
  const normalizedTagName = tagName.toLowerCase();
20580
+ const displayAttrs = (Object.entries(PROJECT_XML_PROTOCOL.componentRoot.containers?.displayList?.items ?? {}).find(([name]) => name.toLowerCase() === normalizedTagName)?.[1])?.attrs;
20581
+ if (displayAttrs) {
20582
+ validateBooleanAttrs(attrs, [
20583
+ displayAttrs.locked,
20584
+ displayAttrs.aspect,
20585
+ displayAttrs.anchor,
20586
+ displayAttrs.visible,
20587
+ displayAttrs.touchable,
20588
+ displayAttrs.grayed
20589
+ ], nodePath, nodeId);
20590
+ for (const spec of [
20591
+ displayAttrs.pivot,
20592
+ displayAttrs.scale,
20593
+ displayAttrs.skew
20594
+ ]) validateNumberTuple(attrs, spec, 2, nodePath, nodeId);
20595
+ addInvalidValue(attrs, displayAttrs.rotation, nodePath, "a finite number", isProjectFiniteNumber, nodeId);
20596
+ addInvalidValue(attrs, displayAttrs.alpha, nodePath, "a finite number between 0 and 1", (value) => isProjectFiniteNumber(value) && Number(value) >= 0 && Number(value) <= 1, nodeId);
20597
+ }
20508
20598
  if (normalizedTagName === "list" || normalizedTagName === "tree") addDiagnostics(attrs, LIST_INT32_RULES, nodePath, nodeId);
20599
+ if (displayAttrs && [
20600
+ "text",
20601
+ "richtext",
20602
+ "inputtext"
20603
+ ].includes(normalizedTagName)) {
20604
+ validateBooleanAttrs(attrs, [
20605
+ displayAttrs.input,
20606
+ displayAttrs.singleLine,
20607
+ displayAttrs.autoClearText,
20608
+ displayAttrs.vars,
20609
+ displayAttrs.ubb,
20610
+ displayAttrs.underline,
20611
+ displayAttrs.italic,
20612
+ displayAttrs.bold,
20613
+ displayAttrs.strikethrough,
20614
+ displayAttrs.password
20615
+ ], nodePath, nodeId);
20616
+ validateInt32Attrs(attrs, [
20617
+ displayAttrs.leading,
20618
+ displayAttrs.letterSpacing,
20619
+ displayAttrs.maxLength,
20620
+ displayAttrs.keyboardType
20621
+ ], nodePath, nodeId);
20622
+ addInvalidValue(attrs, displayAttrs.fontSize, nodePath, "a positive signed 32-bit integer", (value) => isProjectInt32(value) && BigInt(value.trim()) > 0n, nodeId);
20623
+ for (const spec of [
20624
+ displayAttrs.strokeSize,
20625
+ displayAttrs.faceDilate,
20626
+ displayAttrs.underlaySoftness
20627
+ ]) addInvalidValue(attrs, spec, nodePath, "a finite number", isProjectFiniteNumber, nodeId);
20628
+ validateNumberTuple(attrs, displayAttrs.shadowOffset, 2, nodePath, nodeId);
20629
+ validateEnum(attrs, displayAttrs.align, [
20630
+ "left",
20631
+ "center",
20632
+ "right"
20633
+ ], nodePath, nodeId);
20634
+ validateEnum(attrs, displayAttrs.vAlign, [
20635
+ "top",
20636
+ "middle",
20637
+ "bottom"
20638
+ ], nodePath, nodeId);
20639
+ validateEnum(attrs, displayAttrs.autoSize, [
20640
+ "none",
20641
+ "both",
20642
+ "height",
20643
+ "shrink",
20644
+ "ellipsis"
20645
+ ], nodePath, nodeId);
20646
+ }
20647
+ if (displayAttrs && (normalizedTagName === "list" || normalizedTagName === "tree")) {
20648
+ validateBooleanAttrs(attrs, [
20649
+ displayAttrs.autoResizeItem,
20650
+ displayAttrs.treeView,
20651
+ displayAttrs.autoClearItems,
20652
+ displayAttrs.scrollItemToViewOnClick,
20653
+ displayAttrs.foldInvisibleItems
20654
+ ], nodePath, nodeId);
20655
+ validateInt32Attrs(attrs, [
20656
+ displayAttrs.lineGap,
20657
+ displayAttrs.columnGap,
20658
+ displayAttrs.lineItemCount,
20659
+ displayAttrs.lineItemCount2,
20660
+ displayAttrs.apexIndex,
20661
+ displayAttrs.scrollBarFlags,
20662
+ displayAttrs.indent,
20663
+ displayAttrs.clickToExpand
20664
+ ], nodePath, nodeId);
20665
+ validateEnum(attrs, displayAttrs.layout, [
20666
+ "singleColumn",
20667
+ "singleRow",
20668
+ "flowHorizontal",
20669
+ "flowVertical",
20670
+ "pagination",
20671
+ "single_column",
20672
+ "single_row",
20673
+ "flow_hz",
20674
+ "flow_vt",
20675
+ "column",
20676
+ "row"
20677
+ ], nodePath, nodeId);
20678
+ validateEnum(attrs, displayAttrs.align, [
20679
+ "left",
20680
+ "center",
20681
+ "right"
20682
+ ], nodePath, nodeId);
20683
+ validateEnum(attrs, displayAttrs.vAlign, [
20684
+ "top",
20685
+ "middle",
20686
+ "bottom"
20687
+ ], nodePath, nodeId);
20688
+ validateEnum(attrs, displayAttrs.childrenRenderOrder, [
20689
+ "ascent",
20690
+ "descent",
20691
+ "arch"
20692
+ ], nodePath, nodeId);
20693
+ validateEnum(attrs, displayAttrs.selectionMode, [
20694
+ "single",
20695
+ "multiple",
20696
+ "multipleSingleClick",
20697
+ "none"
20698
+ ], nodePath, nodeId);
20699
+ validateEnum(attrs, displayAttrs.overflow, [
20700
+ "visible",
20701
+ "hidden",
20702
+ "scroll"
20703
+ ], nodePath, nodeId);
20704
+ validateEnum(attrs, displayAttrs.scroll, [
20705
+ "horizontal",
20706
+ "vertical",
20707
+ "both"
20708
+ ], nodePath, nodeId);
20709
+ validateEnum(attrs, displayAttrs.scrollBar, [
20710
+ "default",
20711
+ "visible",
20712
+ "auto",
20713
+ "hidden"
20714
+ ], nodePath, nodeId);
20715
+ }
20716
+ if (displayAttrs && normalizedTagName === "group") {
20717
+ validateBooleanAttrs(attrs, [
20718
+ displayAttrs.advanced,
20719
+ displayAttrs.excludeInvisibles,
20720
+ displayAttrs.autoSizeDisabled
20721
+ ], nodePath, nodeId);
20722
+ validateInt32Attrs(attrs, [
20723
+ displayAttrs.lineGap,
20724
+ displayAttrs.columnGap,
20725
+ displayAttrs.mainGridIndex
20726
+ ], nodePath, nodeId);
20727
+ validateEnum(attrs, displayAttrs.layout, [
20728
+ "none",
20729
+ "hz",
20730
+ "vt"
20731
+ ], nodePath, nodeId);
20732
+ }
20733
+ if (displayAttrs && [
20734
+ "image",
20735
+ "loader",
20736
+ "loader3d"
20737
+ ].includes(normalizedTagName)) {
20738
+ validateBooleanAttrs(attrs, [
20739
+ displayAttrs.fillClockwise,
20740
+ displayAttrs.shrinkOnly,
20741
+ displayAttrs.autoSize,
20742
+ displayAttrs.useResize,
20743
+ displayAttrs.playing,
20744
+ displayAttrs.loop,
20745
+ displayAttrs.clearOnPublish
20746
+ ], nodePath, nodeId);
20747
+ validateInt32Attrs(attrs, [
20748
+ displayAttrs.frame,
20749
+ displayAttrs.fillOrigin,
20750
+ displayAttrs.fillAmount
20751
+ ], nodePath, nodeId);
20752
+ validateEnum(attrs, displayAttrs.align, [
20753
+ "left",
20754
+ "center",
20755
+ "right"
20756
+ ], nodePath, nodeId);
20757
+ validateEnum(attrs, displayAttrs.vAlign, [
20758
+ "top",
20759
+ "middle",
20760
+ "bottom"
20761
+ ], nodePath, nodeId);
20762
+ validateEnum(attrs, displayAttrs.fill, [
20763
+ "none",
20764
+ "scale",
20765
+ "scaleMatchHeight",
20766
+ "scaleMatchWidth",
20767
+ "scaleFree",
20768
+ "scaleNoBorder"
20769
+ ], nodePath, nodeId);
20770
+ validateEnum(attrs, displayAttrs.fillMethod, [
20771
+ "none",
20772
+ "hz",
20773
+ "vt",
20774
+ "radial90",
20775
+ "radial180",
20776
+ "radial360"
20777
+ ], nodePath, nodeId);
20778
+ }
20779
+ if (displayAttrs && (normalizedTagName === "movieclip" || normalizedTagName === "jta")) {
20780
+ validateBooleanAttrs(attrs, [displayAttrs.playing], nodePath, nodeId);
20781
+ validateInt32Attrs(attrs, [displayAttrs.frame], nodePath, nodeId);
20782
+ }
20509
20783
  for (const gearTag of ["gearXY", "gearSize"]) for (const [gearIndex, gearDefinition] of ensureArray(attrs[gearTag]).entries()) {
20510
20784
  const gear = getXmlNode(gearDefinition);
20511
20785
  if (!gear) continue;
@@ -20649,7 +20923,7 @@ var ProjectReader = class {
20649
20923
  assertWellFormedXml(compContent);
20650
20924
  const componentNode = getXmlNode(parseXML(compContent).component);
20651
20925
  if (!componentNode) throw new Error("Component XML must contain a component root element.");
20652
- validateComponentXmlGeometry(ctx, comp, compPath, componentNode);
20926
+ validateComponentXmlValues(ctx, comp, compPath, componentNode);
20653
20927
  }
20654
20928
  readComponentXml(ctx, comp, compContent);
20655
20929
  } catch (err) {
@@ -21970,8 +22244,8 @@ function serializeChild(obj) {
21970
22244
  const layout = typedObj.getLayout?.();
21971
22245
  if (layout !== void 0 && layout !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.layout, {
21972
22246
  0: "none",
21973
- 1: "horizontal",
21974
- 2: "vertical"
22247
+ 1: "hz",
22248
+ 2: "vt"
21975
22249
  }[layout] ?? "none");
21976
22250
  const lineGap = typedObj.getLineGap?.() ?? 0;
21977
22251
  if (lineGap !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.group.attrs.lineGap, String(lineGap));
@@ -31510,7 +31784,7 @@ function registerValidateCommand(program) {
31510
31784
  //#region src/utils/package-version.ts
31511
31785
  const require$1 = createRequire(import.meta.url);
31512
31786
  function getInjectedPackageVersion() {
31513
- const version = "0.3.0-alpha.3";
31787
+ const version = "0.3.0-alpha.4";
31514
31788
  return typeof version === "string" && true ? version : null;
31515
31789
  }
31516
31790
  function readPackageVersion() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfairygui/cli",
3
- "version": "0.3.0-alpha.3",
3
+ "version": "0.3.0-alpha.4",
4
4
  "description": "FairyGUI Headless Authoring SDK — command-line interface.",
5
5
  "author": "OpenFairyGUI Contributors",
6
6
  "license": "MIT",
@@ -33,13 +33,13 @@
33
33
  "restore"
34
34
  ],
35
35
  "devDependencies": {
36
- "@openfairygui/functions": "0.3.0-alpha.3",
37
- "@openfairygui/core": "0.3.0-alpha.3"
36
+ "@openfairygui/core": "0.3.0-alpha.4",
37
+ "@openfairygui/functions": "0.3.0-alpha.4"
38
38
  },
39
39
  "dependencies": {
40
40
  "commander": "^14.0.2",
41
41
  "jiti": "^2.7.0",
42
- "@openfairygui/backend": "0.3.0-alpha.3"
42
+ "@openfairygui/backend": "0.3.0-alpha.4"
43
43
  },
44
44
  "optionalDependencies": {
45
45
  "sharp": ">=0.33.0"