@dendotdev/grunt 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -949,6 +949,44 @@ var EconomyModule = class extends ModuleBase {
949
949
  `/hi/players/xuid(${player})/customization/appearance`
950
950
  );
951
951
  }
952
+ /**
953
+ * Get customization for multiple players.
954
+ *
955
+ * @param playerIds - List of player XUIDs
956
+ * @returns Player customization collection
957
+ */
958
+ getMultiplePlayersCustomization(playerIds) {
959
+ if (!playerIds.length) {
960
+ throw new Error("playerIds cannot be empty");
961
+ }
962
+ const formattedPlayers = playerIds.map((id) => `xuid(${id})`).join(",");
963
+ return this.get(`/hi/customization?players=${formattedPlayers}`);
964
+ }
965
+ // ─────────────────────────────────────────────────────────────────
966
+ // Cores
967
+ // ─────────────────────────────────────────────────────────────────
968
+ /**
969
+ * Get details about all owned cores for a player.
970
+ *
971
+ * @param player - Player's numeric XUID
972
+ * @returns All player cores
973
+ */
974
+ getAllOwnedCoresDetails(player) {
975
+ this.assertNotEmpty(player, "player");
976
+ return this.get(`/hi/players/xuid(${player})/cores`);
977
+ }
978
+ /**
979
+ * Get details about a specific owned core.
980
+ *
981
+ * @param player - Player's numeric XUID
982
+ * @param coreId - Core identifier
983
+ * @returns Core details
984
+ */
985
+ getOwnedCoreDetails(player, coreId) {
986
+ this.assertNotEmpty(player, "player");
987
+ this.assertNotEmpty(coreId, "coreId");
988
+ return this.get(`/hi/players/xuid(${player})/cores/${coreId}`);
989
+ }
952
990
  // ─────────────────────────────────────────────────────────────────
953
991
  // Stores
954
992
  // ─────────────────────────────────────────────────────────────────
@@ -1012,6 +1050,66 @@ var EconomyModule = class extends ModuleBase {
1012
1050
  this.assertNotEmpty(player, "player");
1013
1051
  return this.get(`/hi/players/xuid(${player})/stores/operations`);
1014
1052
  }
1053
+ /**
1054
+ * Get the operation reward levels store.
1055
+ *
1056
+ * @param player - Player's numeric XUID
1057
+ * @returns Store items
1058
+ */
1059
+ getOperationRewardLevelsStore(player) {
1060
+ this.assertNotEmpty(player, "player");
1061
+ return this.get(`/hi/players/xuid(${player})/stores/operationrewardlevels`);
1062
+ }
1063
+ /**
1064
+ * Get the XP grants store.
1065
+ *
1066
+ * @param player - Player's numeric XUID
1067
+ * @returns Store items
1068
+ */
1069
+ getXpGrantsStore(player) {
1070
+ this.assertNotEmpty(player, "player");
1071
+ return this.get(`/hi/players/xuid(${player})/stores/xpgrants`);
1072
+ }
1073
+ /**
1074
+ * Get items from a credit sub-store.
1075
+ *
1076
+ * Credit sub-stores (0-5) contain different categories of items
1077
+ * purchasable with credits.
1078
+ *
1079
+ * @param player - Player's numeric XUID
1080
+ * @param storeIndex - Sub-store index (0-5)
1081
+ * @returns Store items
1082
+ */
1083
+ getCreditSubStore(player, storeIndex) {
1084
+ this.assertNotEmpty(player, "player");
1085
+ if (storeIndex < 0 || storeIndex > 5) {
1086
+ throw new Error("storeIndex must be between 0 and 5");
1087
+ }
1088
+ const paddedIndex = storeIndex.toString().padStart(2, "0");
1089
+ return this.get(
1090
+ `/hi/players/xuid(${player})/stores/creditsubstorefront${paddedIndex}`
1091
+ );
1092
+ }
1093
+ /**
1094
+ * Get items from a soft currency (Spartan Points) sub-store.
1095
+ *
1096
+ * Soft currency sub-stores (0-15) contain different categories of items
1097
+ * purchasable with Spartan Points on The Exchange.
1098
+ *
1099
+ * @param player - Player's numeric XUID
1100
+ * @param storeIndex - Sub-store index (0-15)
1101
+ * @returns Store items
1102
+ */
1103
+ getSoftCurrencySubStore(player, storeIndex) {
1104
+ this.assertNotEmpty(player, "player");
1105
+ if (storeIndex < 0 || storeIndex > 15) {
1106
+ throw new Error("storeIndex must be between 0 and 15");
1107
+ }
1108
+ const paddedIndex = storeIndex.toString().padStart(2, "0");
1109
+ return this.get(
1110
+ `/hi/players/xuid(${player})/stores/softcurrencysubstorefront${paddedIndex}`
1111
+ );
1112
+ }
1015
1113
  /**
1016
1114
  * Get scheduled storefront offerings.
1017
1115
  *
@@ -1107,9 +1205,10 @@ var EconomyModule = class extends ModuleBase {
1107
1205
  throw new Error("playerIds cannot be empty");
1108
1206
  }
1109
1207
  this.assertNotEmpty(careerPathId, "careerPathId");
1110
- const playersQuery = playerIds.map((id) => `players=xuid(${id})`).join("&");
1208
+ const formattedPlayerList = playerIds.map((id) => `xuid(${id})`).join(",");
1111
1209
  return this.get(
1112
- `/hi/careerranks/${careerPathId}?${playersQuery}`
1210
+ `/hi/careerranks/${careerPathId}?players=${formattedPlayerList}`,
1211
+ { useClearance: true }
1113
1212
  );
1114
1213
  }
1115
1214
  };
@@ -1227,7 +1326,10 @@ var GameCmsModule = class extends ModuleBase {
1227
1326
  */
1228
1327
  getCareerRanks(careerPathId) {
1229
1328
  this.assertNotEmpty(careerPathId, "careerPathId");
1230
- return this.get(`/hi/Progression/file/careerranks/${careerPathId}`);
1329
+ return this.get(
1330
+ `/hi/Progression/file/RewardTracks/CareerRanks/${careerPathId}.json`,
1331
+ { useClearance: true }
1332
+ );
1231
1333
  }
1232
1334
  /**
1233
1335
  * Get the season calendar.
@@ -1268,7 +1370,7 @@ var GameCmsModule = class extends ModuleBase {
1268
1370
  * @returns Medal metadata
1269
1371
  */
1270
1372
  getMedalMetadata() {
1271
- return this.get("/hi/Progression/file/medals/metadata");
1373
+ return this.get("/hi/Waypoint/file/medals/metadata.json");
1272
1374
  }
1273
1375
  /**
1274
1376
  * Get general game metadata.
@@ -1337,6 +1439,232 @@ var GameCmsModule = class extends ModuleBase {
1337
1439
  this.assertNotEmpty(filePath, "filePath");
1338
1440
  return this.get(`/hi/Progression/file/${filePath}`);
1339
1441
  }
1442
+ // ─────────────────────────────────────────────────────────────────
1443
+ // Achievements & Settings
1444
+ // ─────────────────────────────────────────────────────────────────
1445
+ /**
1446
+ * Get all available achievements.
1447
+ *
1448
+ * @returns Achievement collection
1449
+ */
1450
+ getAchievements() {
1451
+ return this.get("/hi/Multiplayer/file/Live/Achievements.json");
1452
+ }
1453
+ /**
1454
+ * Get the Play Now button settings (fallback playlist).
1455
+ *
1456
+ * @returns Fallback playlist settings
1457
+ */
1458
+ getPlayNowButtonSettings() {
1459
+ return this.get(
1460
+ "/hi/Multiplayer/file/playlists/playNowButton/settings.json"
1461
+ );
1462
+ }
1463
+ /**
1464
+ * Get custom game default settings.
1465
+ *
1466
+ * @returns Custom game definition
1467
+ */
1468
+ getCustomGameDefaults() {
1469
+ return this.get("/hi/Multiplayer/file/NonMatchmaking/customgame.json");
1470
+ }
1471
+ /**
1472
+ * Get lobby error messages.
1473
+ *
1474
+ * @param flightId - Flight ID
1475
+ * @returns Lobby error message list
1476
+ */
1477
+ getLobbyErrorMessages(flightId) {
1478
+ this.assertNotEmpty(flightId, "flightId");
1479
+ return this.get(
1480
+ `/hi/Multiplayer/file/gameStartErrorMessages/LobbyHoppperErrorMessageList.json?flight=${flightId}`
1481
+ );
1482
+ }
1483
+ /**
1484
+ * Get network configuration.
1485
+ *
1486
+ * @param flightId - Flight ID
1487
+ * @returns Network configuration
1488
+ */
1489
+ getNetworkConfiguration(flightId) {
1490
+ this.assertNotEmpty(flightId, "flightId");
1491
+ return this.get(
1492
+ `/hi/Multiplayer/file/network/config.json?flight=${flightId}`
1493
+ );
1494
+ }
1495
+ /**
1496
+ * Get a multiplayer playlist configuration.
1497
+ *
1498
+ * @param playlistFile - Playlist file name (e.g., "uuid.json")
1499
+ * @returns Playlist configuration
1500
+ */
1501
+ getMultiplayerPlaylistConfiguration(playlistFile) {
1502
+ this.assertNotEmpty(playlistFile, "playlistFile");
1503
+ return this.get(
1504
+ `/hi/Multiplayer/file/playlists/assets/${playlistFile}`
1505
+ );
1506
+ }
1507
+ // ─────────────────────────────────────────────────────────────────
1508
+ // Graphics & Specs
1509
+ // ─────────────────────────────────────────────────────────────────
1510
+ /**
1511
+ * Get async compute overrides.
1512
+ *
1513
+ * @returns Async compute override configuration
1514
+ */
1515
+ getAsyncComputeOverrides() {
1516
+ return this.get("/hi/Specs/file/graphics/AsyncComputeOverrides.json");
1517
+ }
1518
+ /**
1519
+ * Get CPU presets.
1520
+ *
1521
+ * @returns CPU preset configuration
1522
+ */
1523
+ getCpuPresets() {
1524
+ return this.get("/hi/Specs/file/cpu/presets.json");
1525
+ }
1526
+ /**
1527
+ * Get device preset overrides.
1528
+ *
1529
+ * @returns Device preset overrides
1530
+ */
1531
+ getDevicePresetOverrides() {
1532
+ return this.get("/hi/Specs/file/graphics/DevicePresetOverrides.json");
1533
+ }
1534
+ /**
1535
+ * Get graphics spec control overrides.
1536
+ *
1537
+ * @returns Graphics spec control overrides
1538
+ */
1539
+ getGraphicsSpecControlOverrides() {
1540
+ return this.get(
1541
+ "/hi/Specs/file/graphics/GraphicsSpecControlOverrides.json"
1542
+ );
1543
+ }
1544
+ /**
1545
+ * Get graphics specs/overrides.
1546
+ *
1547
+ * @returns Graphics overrides
1548
+ */
1549
+ getGraphicSpecs() {
1550
+ return this.get("/hi/Specs/file/graphics/overrides.json");
1551
+ }
1552
+ /**
1553
+ * Get recommended drivers.
1554
+ *
1555
+ * @returns Driver manifest
1556
+ */
1557
+ getRecommendedDrivers() {
1558
+ return this.get("/hi/Specs/file/graphics/RecommendedDrivers.json");
1559
+ }
1560
+ // ─────────────────────────────────────────────────────────────────
1561
+ // Title Authorization & Access
1562
+ // ─────────────────────────────────────────────────────────────────
1563
+ /**
1564
+ * Get claw (clawback) access list.
1565
+ *
1566
+ * @param flightId - Flight ID
1567
+ * @returns Claw access snapshot
1568
+ */
1569
+ getClawAccess(flightId) {
1570
+ this.assertNotEmpty(flightId, "flightId");
1571
+ return this.get(
1572
+ `/hi/TitleAuthorization/file/claw/access.json?flight=${flightId}`
1573
+ );
1574
+ }
1575
+ /**
1576
+ * Get not allowed in title message.
1577
+ *
1578
+ * @returns OE configuration message
1579
+ */
1580
+ getNotAllowedInTitleMessage() {
1581
+ const url = `https://${HALO_CORE_ENDPOINTS.GAME_CMS_ORIGIN}.${HALO_CORE_ENDPOINTS.SERVICE_DOMAIN}/branches/hi/OEConfiguration/data/authfail/Default.json`;
1582
+ return this.getFullUrl(url, { useSpartanToken: false });
1583
+ }
1584
+ // ─────────────────────────────────────────────────────────────────
1585
+ // Guides (File Listings)
1586
+ // ─────────────────────────────────────────────────────────────────
1587
+ /**
1588
+ * Get guide for images files.
1589
+ *
1590
+ * @param flightId - Flight ID
1591
+ * @returns Guide container with file listings
1592
+ */
1593
+ getGuideImages(flightId) {
1594
+ this.assertNotEmpty(flightId, "flightId");
1595
+ return this.get(`/hi/images/guide/xo?flight=${flightId}`);
1596
+ }
1597
+ /**
1598
+ * Get guide for multiplayer files.
1599
+ *
1600
+ * @param flightId - Flight ID
1601
+ * @returns Guide container with file listings
1602
+ */
1603
+ getGuideMultiplayer(flightId) {
1604
+ this.assertNotEmpty(flightId, "flightId");
1605
+ return this.get(`/hi/Multiplayer/guide/xo?flight=${flightId}`);
1606
+ }
1607
+ /**
1608
+ * Get guide for news files.
1609
+ *
1610
+ * @param flightId - Flight ID
1611
+ * @returns Guide container with file listings
1612
+ */
1613
+ getGuideNews(flightId) {
1614
+ this.assertNotEmpty(flightId, "flightId");
1615
+ return this.get(`/hi/News/guide/xo?flight=${flightId}`);
1616
+ }
1617
+ /**
1618
+ * Get guide for progression files.
1619
+ *
1620
+ * @param flightId - Flight ID
1621
+ * @returns Guide container with file listings
1622
+ */
1623
+ getGuideProgression(flightId) {
1624
+ this.assertNotEmpty(flightId, "flightId");
1625
+ return this.get(`/hi/Progression/guide/xo?flight=${flightId}`);
1626
+ }
1627
+ /**
1628
+ * Get guide for spec files.
1629
+ *
1630
+ * @param flightId - Flight ID
1631
+ * @returns Guide container with file listings
1632
+ */
1633
+ getGuideSpecs(flightId) {
1634
+ this.assertNotEmpty(flightId, "flightId");
1635
+ return this.get(`/hi/Specs/guide/xo?flight=${flightId}`);
1636
+ }
1637
+ /**
1638
+ * Get guide for title authorization files.
1639
+ *
1640
+ * @param flightId - Flight ID
1641
+ * @returns Guide container with file listings
1642
+ */
1643
+ getGuideTitleAuthorization(flightId) {
1644
+ this.assertNotEmpty(flightId, "flightId");
1645
+ return this.get(`/hi/TitleAuthorization/guide/xo?flight=${flightId}`);
1646
+ }
1647
+ // ─────────────────────────────────────────────────────────────────
1648
+ // Waypoint Files
1649
+ // ─────────────────────────────────────────────────────────────────
1650
+ /**
1651
+ * Get emblem mapping configuration.
1652
+ *
1653
+ * @returns Emblem mapping dictionary
1654
+ */
1655
+ getEmblemMapping() {
1656
+ return this.get("/hi/Waypoint/file/images/emblems/mapping.json");
1657
+ }
1658
+ /**
1659
+ * Get a generic file from Waypoint service.
1660
+ *
1661
+ * @param filePath - Path to the file
1662
+ * @returns File data as bytes
1663
+ */
1664
+ getGenericWaypointFile(filePath) {
1665
+ this.assertNotEmpty(filePath, "filePath");
1666
+ return this.get(`/hi/Waypoint/file/${filePath}`, { returnRaw: true });
1667
+ }
1340
1668
  };
1341
1669
 
1342
1670
  // src/modules/halo-infinite/lobby.module.ts
@@ -1420,6 +1748,100 @@ var SettingsModule = class extends ModuleBase {
1420
1748
  useSpartanToken: true
1421
1749
  });
1422
1750
  }
1751
+ /**
1752
+ * Get a list of features enabled for a given flight.
1753
+ *
1754
+ * @param flightId - Clearance ID/flight that is being used
1755
+ * @returns Flighted feature flags
1756
+ */
1757
+ getFlightedFeatureFlags(flightId) {
1758
+ this.assertNotEmpty(flightId, "flightId");
1759
+ return this.get(`/featureflags/hi?flight=${flightId}`);
1760
+ }
1761
+ /**
1762
+ * Get the currently active clearance.
1763
+ *
1764
+ * @param release - Release identifier (e.g., "1.4", "1.5", "1.6")
1765
+ * @returns Player clearance data
1766
+ */
1767
+ getActiveClearance(release) {
1768
+ this.assertNotEmpty(release, "release");
1769
+ return this.get(`/hi/clearances/active?release=${release}`, {
1770
+ useSpartanToken: false
1771
+ });
1772
+ }
1773
+ /**
1774
+ * Get the currently active flight.
1775
+ *
1776
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1777
+ * @param buildNumber - Game build number (e.g., "211755.22.01.23.0549-0")
1778
+ * @param release - Release identifier (e.g., "1.4", "1.5")
1779
+ * @returns Player clearance data
1780
+ */
1781
+ getActiveFlight(sandbox, buildNumber, release) {
1782
+ this.assertNotEmpty(sandbox, "sandbox");
1783
+ this.assertNotEmpty(buildNumber, "buildNumber");
1784
+ this.assertNotEmpty(release, "release");
1785
+ return this.get(
1786
+ `/oban/flight-configurations/titles/hi/audiences/RETAIL/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1787
+ );
1788
+ }
1789
+ /**
1790
+ * Get the clearance/flight ID for a specific audience.
1791
+ *
1792
+ * @param audience - Audience targeting (e.g., "RETAIL")
1793
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1794
+ * @param buildNumber - Game build number
1795
+ * @param release - Release identifier
1796
+ * @returns Player clearance data
1797
+ */
1798
+ getClearance(audience, sandbox, buildNumber, release) {
1799
+ this.assertNotEmpty(audience, "audience");
1800
+ this.assertNotEmpty(sandbox, "sandbox");
1801
+ this.assertNotEmpty(buildNumber, "buildNumber");
1802
+ this.assertNotEmpty(release, "release");
1803
+ return this.get(
1804
+ `/oban/flight-configurations/titles/hi/audiences/${audience}/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1805
+ );
1806
+ }
1807
+ /**
1808
+ * Get the player clearance/flight ID for a specific audience.
1809
+ *
1810
+ * @param audience - Audience targeting (e.g., "RETAIL")
1811
+ * @param player - Player XUID
1812
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1813
+ * @param buildNumber - Game build number
1814
+ * @param release - Release identifier
1815
+ * @returns Player clearance data
1816
+ */
1817
+ getPlayerClearance(audience, player, sandbox, buildNumber, release) {
1818
+ this.assertNotEmpty(audience, "audience");
1819
+ this.assertNotEmpty(player, "player");
1820
+ this.assertNotEmpty(sandbox, "sandbox");
1821
+ this.assertNotEmpty(buildNumber, "buildNumber");
1822
+ this.assertNotEmpty(release, "release");
1823
+ return this.get(
1824
+ `/oban/flight-configurations/titles/hi/audiences/${audience}/players/xuid(${player})/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1825
+ );
1826
+ }
1827
+ /**
1828
+ * Get the player clearance/flight ID for RETAIL audience.
1829
+ *
1830
+ * @param player - Player XUID
1831
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1832
+ * @param buildNumber - Game build number
1833
+ * @param release - Release identifier
1834
+ * @returns Player clearance data
1835
+ */
1836
+ getPlayerClearanceRetail(player, sandbox, buildNumber, release) {
1837
+ this.assertNotEmpty(player, "player");
1838
+ this.assertNotEmpty(sandbox, "sandbox");
1839
+ this.assertNotEmpty(buildNumber, "buildNumber");
1840
+ this.assertNotEmpty(release, "release");
1841
+ return this.get(
1842
+ `/oban/flight-configurations/titles/hi/audiences/RETAIL/players/xuid(${player})/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1843
+ );
1844
+ }
1423
1845
  };
1424
1846
 
1425
1847
  // src/modules/halo-infinite/skill.module.ts
@@ -1601,6 +2023,28 @@ var TextModerationModule = class extends ModuleBase {
1601
2023
  getModerationKey() {
1602
2024
  return this.get("/hi/moderation/key");
1603
2025
  }
2026
+ /**
2027
+ * Get a specific moderation proof signing key.
2028
+ *
2029
+ * @param keyId - Key ID (can be obtained from getSigningKeys)
2030
+ * @returns Signing key data
2031
+ */
2032
+ getSigningKey(keyId) {
2033
+ this.assertNotEmpty(keyId, "keyId");
2034
+ return this.get(`/hi/moderation-proof-keys/${keyId}`, {
2035
+ useSpartanToken: false
2036
+ });
2037
+ }
2038
+ /**
2039
+ * Get all available moderation proof signing keys.
2040
+ *
2041
+ * @returns Container with all signing keys
2042
+ */
2043
+ getSigningKeys() {
2044
+ return this.get("/hi/moderation-proof-keys", {
2045
+ useSpartanToken: false
2046
+ });
2047
+ }
1604
2048
  };
1605
2049
 
1606
2050
  // src/modules/halo-infinite/ugc.module.ts
@@ -1637,6 +2081,18 @@ var UgcModule = class extends ModuleBase {
1637
2081
  this.assertNotEmpty(assetId, "assetId");
1638
2082
  return this.get(`/${title}/${assetType}/${assetId}/versions/latest`);
1639
2083
  }
2084
+ /**
2085
+ * Get the latest version of a film asset.
2086
+ *
2087
+ * @param title - Game title
2088
+ * @param assetId - Film asset GUID
2089
+ * @returns Latest film asset version
2090
+ */
2091
+ getLatestAssetVersionFilm(title, assetId) {
2092
+ this.assertNotEmpty(title, "title");
2093
+ this.assertNotEmpty(assetId, "assetId");
2094
+ return this.get(`/${title}/films/${assetId}/versions/latest`);
2095
+ }
1640
2096
  /**
1641
2097
  * Get a specific version of an asset.
1642
2098
  *
@@ -1812,18 +2268,31 @@ var UgcModule = class extends ModuleBase {
1812
2268
  // Asset Management
1813
2269
  // ─────────────────────────────────────────────────────────────────
1814
2270
  /**
1815
- * Delete an asset and all its versions.
2271
+ * Delete an asset.
1816
2272
  *
1817
2273
  * @param title - Game title
1818
2274
  * @param assetType - Type of asset
1819
2275
  * @param assetId - Asset GUID
1820
2276
  * @returns Success status
1821
2277
  */
1822
- deleteAllVersions(title, assetType, assetId) {
2278
+ deleteAsset(title, assetType, assetId) {
1823
2279
  this.assertNotEmpty(title, "title");
1824
2280
  this.assertNotEmpty(assetId, "assetId");
1825
2281
  return this.delete(`/${title}/${assetType}/${assetId}`);
1826
2282
  }
2283
+ /**
2284
+ * Delete all versions of an asset.
2285
+ *
2286
+ * @param title - Game title
2287
+ * @param assetType - Type of asset
2288
+ * @param assetId - Asset GUID
2289
+ * @returns Success status
2290
+ */
2291
+ deleteAllVersions(title, assetType, assetId) {
2292
+ this.assertNotEmpty(title, "title");
2293
+ this.assertNotEmpty(assetId, "assetId");
2294
+ return this.delete(`/${title}/${assetType}/${assetId}/versions`);
2295
+ }
1827
2296
  /**
1828
2297
  * Delete a specific version of an asset.
1829
2298
  *
@@ -1839,6 +2308,34 @@ var UgcModule = class extends ModuleBase {
1839
2308
  this.assertNotEmpty(versionId, "versionId");
1840
2309
  return this.delete(`/${title}/${assetType}/${assetId}/versions/${versionId}`);
1841
2310
  }
2311
+ /**
2312
+ * Undelete a previously deleted asset.
2313
+ *
2314
+ * @param title - Game title
2315
+ * @param assetType - Type of asset
2316
+ * @param assetId - Asset GUID
2317
+ * @returns Success status
2318
+ */
2319
+ undeleteAsset(title, assetType, assetId) {
2320
+ this.assertNotEmpty(title, "title");
2321
+ this.assertNotEmpty(assetId, "assetId");
2322
+ return this.post(`/${title}/${assetType}/${assetId}/recover`);
2323
+ }
2324
+ /**
2325
+ * Undelete a previously deleted asset version.
2326
+ *
2327
+ * @param title - Game title
2328
+ * @param assetType - Type of asset
2329
+ * @param assetId - Asset GUID
2330
+ * @param versionId - Version GUID
2331
+ * @returns Success status
2332
+ */
2333
+ undeleteVersion(title, assetType, assetId, versionId) {
2334
+ this.assertNotEmpty(title, "title");
2335
+ this.assertNotEmpty(assetId, "assetId");
2336
+ this.assertNotEmpty(versionId, "versionId");
2337
+ return this.post(`/${title}/${assetType}/${assetId}/versions/${versionId}/recover`);
2338
+ }
1842
2339
  /**
1843
2340
  * Publish an asset version.
1844
2341
  *
@@ -1937,6 +2434,21 @@ var UgcModule = class extends ModuleBase {
1937
2434
  this.assertNotEmpty(assetId, "assetId");
1938
2435
  return this.delete(`/${title}/${assetType}/${assetId}/sessions`);
1939
2436
  }
2437
+ /**
2438
+ * Spawn (create) a new asset.
2439
+ *
2440
+ * @param title - Game title
2441
+ * @param assetType - Type of asset (e.g., "UgcGameVariants", "Maps", "Prefabs")
2442
+ * @param asset - Asset definition
2443
+ * @returns Created asset
2444
+ */
2445
+ spawnAsset(title, assetType, asset) {
2446
+ this.assertNotEmpty(title, "title");
2447
+ return this.postJson(
2448
+ `/${title}/${assetType}`,
2449
+ asset
2450
+ );
2451
+ }
1940
2452
  /**
1941
2453
  * Create a new asset version.
1942
2454
  *
@@ -1994,6 +2506,9 @@ var UgcDiscoveryModule = class extends ModuleBase {
1994
2506
  constructor(client) {
1995
2507
  super(client, HALO_CORE_ENDPOINTS.DISCOVERY_ORIGIN);
1996
2508
  }
2509
+ // ─────────────────────────────────────────────────────────────────
2510
+ // Search & Browse
2511
+ // ─────────────────────────────────────────────────────────────────
1997
2512
  /**
1998
2513
  * Search for user-generated content.
1999
2514
  *
@@ -2030,6 +2545,27 @@ var UgcDiscoveryModule = class extends ModuleBase {
2030
2545
  if (params.start !== void 0) {
2031
2546
  queryParts.push(`start=${params.start}`);
2032
2547
  }
2548
+ if (params.averageRatingMin !== void 0) {
2549
+ queryParts.push(`averageRatingMin=${params.averageRatingMin}`);
2550
+ }
2551
+ if (params.fromDateCreatedUtc) {
2552
+ queryParts.push(`fromDateCreatedUtc=${encodeURIComponent(params.fromDateCreatedUtc.toISOString())}`);
2553
+ }
2554
+ if (params.toDateCreatedUtc) {
2555
+ queryParts.push(`toDateCreatedUtc=${encodeURIComponent(params.toDateCreatedUtc.toISOString())}`);
2556
+ }
2557
+ if (params.fromDateModifiedUtc) {
2558
+ queryParts.push(`fromDateModifiedUtc=${encodeURIComponent(params.fromDateModifiedUtc.toISOString())}`);
2559
+ }
2560
+ if (params.toDateModifiedUtc) {
2561
+ queryParts.push(`toDateModifiedUtc=${encodeURIComponent(params.toDateModifiedUtc.toISOString())}`);
2562
+ }
2563
+ if (params.fromDatePublishedUtc) {
2564
+ queryParts.push(`fromDatePublishedUtc=${encodeURIComponent(params.fromDatePublishedUtc.toISOString())}`);
2565
+ }
2566
+ if (params.toDatePublishedUtc) {
2567
+ queryParts.push(`toDatePublishedUtc=${encodeURIComponent(params.toDatePublishedUtc.toISOString())}`);
2568
+ }
2033
2569
  const queryString = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
2034
2570
  return this.get(`/hi/search${queryString}`);
2035
2571
  }
@@ -2109,15 +2645,298 @@ var UgcDiscoveryModule = class extends ModuleBase {
2109
2645
  return this.get(`/hi/${assetKind}/${assetId}`);
2110
2646
  }
2111
2647
  /**
2112
- * Get film asset for a match.
2648
+ * Get tags information.
2649
+ *
2650
+ * @returns Available tags info
2651
+ */
2652
+ getTagsInfo() {
2653
+ return this.get("/hi/info/tags");
2654
+ }
2655
+ // ─────────────────────────────────────────────────────────────────
2656
+ // Manifests
2657
+ // ─────────────────────────────────────────────────────────────────
2658
+ /**
2659
+ * Get the game manifest by build GUID.
2660
+ *
2661
+ * @param buildGuid - Build GUID
2662
+ * @returns Manifest data
2663
+ */
2664
+ getManifestByBuildGuid(buildGuid) {
2665
+ this.assertNotEmpty(buildGuid, "buildGuid");
2666
+ return this.get(`/hi/manifests/guids/${buildGuid}/game`);
2667
+ }
2668
+ /**
2669
+ * Get the game manifest by build number.
2670
+ *
2671
+ * @param buildNumber - Build number (e.g., "6.10022.10499")
2672
+ * @returns Manifest data
2673
+ */
2674
+ getManifestByBuild(buildNumber) {
2675
+ this.assertNotEmpty(buildNumber, "buildNumber");
2676
+ return this.get(`/hi/manifests/builds/${buildNumber}/game`);
2677
+ }
2678
+ /**
2679
+ * Get a specific manifest version.
2680
+ *
2681
+ * @param assetId - Manifest asset ID
2682
+ * @param versionId - Manifest version ID
2683
+ * @param clearanceId - Active flight clearance ID
2684
+ * @returns Manifest data
2685
+ */
2686
+ getManifest(assetId, versionId, clearanceId) {
2687
+ this.assertNotEmpty(assetId, "assetId");
2688
+ this.assertNotEmpty(versionId, "versionId");
2689
+ return this.get(
2690
+ `/hi/manifests/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2691
+ );
2692
+ }
2693
+ // ─────────────────────────────────────────────────────────────────
2694
+ // Maps
2695
+ // ─────────────────────────────────────────────────────────────────
2696
+ /**
2697
+ * Get a specific map version.
2698
+ *
2699
+ * @param assetId - Map asset ID
2700
+ * @param versionId - Map version ID
2701
+ * @returns Map data
2702
+ */
2703
+ getMap(assetId, versionId) {
2704
+ this.assertNotEmpty(assetId, "assetId");
2705
+ this.assertNotEmpty(versionId, "versionId");
2706
+ return this.get(`/hi/maps/${assetId}/versions/${versionId}`);
2707
+ }
2708
+ /**
2709
+ * Get a map without specifying version (returns latest).
2710
+ *
2711
+ * @param assetId - Map asset ID
2712
+ * @returns Map data
2713
+ */
2714
+ getMapWithoutVersion(assetId) {
2715
+ this.assertNotEmpty(assetId, "assetId");
2716
+ return this.get(`/hi/maps/${assetId}`);
2717
+ }
2718
+ // ─────────────────────────────────────────────────────────────────
2719
+ // Map Mode Pairs
2720
+ // ─────────────────────────────────────────────────────────────────
2721
+ /**
2722
+ * Get a specific map mode pair version.
2723
+ *
2724
+ * @param assetId - Map mode pair asset ID
2725
+ * @param versionId - Version ID
2726
+ * @param clearanceId - Active flight clearance ID
2727
+ * @returns Map mode pair data
2728
+ */
2729
+ getMapModePair(assetId, versionId, clearanceId) {
2730
+ this.assertNotEmpty(assetId, "assetId");
2731
+ this.assertNotEmpty(versionId, "versionId");
2732
+ return this.get(
2733
+ `/hi/mapModePairs/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2734
+ );
2735
+ }
2736
+ /**
2737
+ * Get a map mode pair without specifying version.
2738
+ *
2739
+ * @param assetId - Map mode pair asset ID
2740
+ * @returns Map mode pair data
2741
+ */
2742
+ getMapModePairWithoutVersion(assetId) {
2743
+ this.assertNotEmpty(assetId, "assetId");
2744
+ return this.get(`/hi/mapModePairs/${assetId}`);
2745
+ }
2746
+ // ─────────────────────────────────────────────────────────────────
2747
+ // Playlists
2748
+ // ─────────────────────────────────────────────────────────────────
2749
+ /**
2750
+ * Get a specific playlist version.
2751
+ *
2752
+ * @param assetId - Playlist asset ID
2753
+ * @param versionId - Version ID
2754
+ * @param clearanceId - Active flight clearance ID
2755
+ * @returns Playlist data
2756
+ */
2757
+ getPlaylist(assetId, versionId, clearanceId) {
2758
+ this.assertNotEmpty(assetId, "assetId");
2759
+ this.assertNotEmpty(versionId, "versionId");
2760
+ return this.get(
2761
+ `/hi/playlists/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2762
+ );
2763
+ }
2764
+ /**
2765
+ * Get a playlist without specifying version.
2766
+ *
2767
+ * @param assetId - Playlist asset ID
2768
+ * @returns Playlist data
2769
+ */
2770
+ getPlaylistWithoutVersion(assetId) {
2771
+ this.assertNotEmpty(assetId, "assetId");
2772
+ return this.get(`/hi/playlists/${assetId}`);
2773
+ }
2774
+ // ─────────────────────────────────────────────────────────────────
2775
+ // Prefabs
2776
+ // ─────────────────────────────────────────────────────────────────
2777
+ /**
2778
+ * Get a specific prefab version.
2779
+ *
2780
+ * @param assetId - Prefab asset ID
2781
+ * @param versionId - Version ID
2782
+ * @returns Prefab data
2783
+ */
2784
+ getPrefab(assetId, versionId) {
2785
+ this.assertNotEmpty(assetId, "assetId");
2786
+ this.assertNotEmpty(versionId, "versionId");
2787
+ return this.get(`/hi/prefabs/${assetId}/versions/${versionId}`);
2788
+ }
2789
+ /**
2790
+ * Get a prefab without specifying version.
2791
+ *
2792
+ * @param assetId - Prefab asset ID
2793
+ * @returns Prefab data
2794
+ */
2795
+ getPrefabWithoutVersion(assetId) {
2796
+ this.assertNotEmpty(assetId, "assetId");
2797
+ return this.get(`/hi/prefabs/${assetId}`);
2798
+ }
2799
+ // ─────────────────────────────────────────────────────────────────
2800
+ // Projects
2801
+ // ─────────────────────────────────────────────────────────────────
2802
+ /**
2803
+ * Get a specific project version.
2804
+ *
2805
+ * @param assetId - Project asset ID
2806
+ * @param versionId - Version ID
2807
+ * @returns Project data
2808
+ */
2809
+ getProject(assetId, versionId) {
2810
+ this.assertNotEmpty(assetId, "assetId");
2811
+ this.assertNotEmpty(versionId, "versionId");
2812
+ return this.get(`/hi/projects/${assetId}/versions/${versionId}`);
2813
+ }
2814
+ /**
2815
+ * Get a project without specifying version.
2816
+ *
2817
+ * @param assetId - Project asset ID
2818
+ * @returns Project data
2819
+ */
2820
+ getProjectWithoutVersion(assetId) {
2821
+ this.assertNotEmpty(assetId, "assetId");
2822
+ return this.get(`/hi/projects/${assetId}`);
2823
+ }
2824
+ /**
2825
+ * Get the Forge templates (canvases).
2826
+ *
2827
+ * @returns Forge templates project
2828
+ */
2829
+ getForgeTemplates() {
2830
+ return this.get("/hi/projects/bf0e9bab-6fed-47a4-8bf7-bfd4422ee552");
2831
+ }
2832
+ /**
2833
+ * Get the Forge mode categories.
2834
+ *
2835
+ * @returns Forge mode categories project
2836
+ */
2837
+ getForgeModeCategories() {
2838
+ return this.get("/hi/projects/aff73c44-0771-468f-b9cf-5c52eee7ab4c");
2839
+ }
2840
+ /**
2841
+ * Get the community tab assets.
2842
+ *
2843
+ * @returns Community tab project
2844
+ */
2845
+ getCommunityTab() {
2846
+ return this.get("/hi/projects/90f9e508-99ce-411c-bf88-7bf12b5e9f52");
2847
+ }
2848
+ /**
2849
+ * Get 343 recommended assets.
2850
+ *
2851
+ * @returns 343 recommended project
2852
+ */
2853
+ get343Recommended() {
2854
+ return this.get("/hi/projects/712add52-f989-48e1-b3bb-ac7cd8a1c17a");
2855
+ }
2856
+ // ─────────────────────────────────────────────────────────────────
2857
+ // Game Variants
2858
+ // ─────────────────────────────────────────────────────────────────
2859
+ /**
2860
+ * Get a specific engine game variant version.
2861
+ *
2862
+ * @param assetId - Engine game variant asset ID
2863
+ * @param versionId - Version ID
2864
+ * @returns Engine game variant data
2865
+ */
2866
+ getEngineGameVariant(assetId, versionId) {
2867
+ this.assertNotEmpty(assetId, "assetId");
2868
+ this.assertNotEmpty(versionId, "versionId");
2869
+ return this.get(
2870
+ `/hi/engineGameVariants/${assetId}/versions/${versionId}`
2871
+ );
2872
+ }
2873
+ /**
2874
+ * Get an engine game variant without specifying version.
2875
+ *
2876
+ * @param assetId - Engine game variant asset ID
2877
+ * @returns Engine game variant data
2878
+ */
2879
+ getEngineGameVariantWithoutVersion(assetId) {
2880
+ this.assertNotEmpty(assetId, "assetId");
2881
+ return this.get(`/hi/engineGameVariants/${assetId}`);
2882
+ }
2883
+ /**
2884
+ * Get a specific UGC game variant version.
2885
+ *
2886
+ * @param assetId - UGC game variant asset ID
2887
+ * @param versionId - Version ID
2888
+ * @returns UGC game variant data
2889
+ */
2890
+ getUgcGameVariant(assetId, versionId) {
2891
+ this.assertNotEmpty(assetId, "assetId");
2892
+ this.assertNotEmpty(versionId, "versionId");
2893
+ return this.get(
2894
+ `/hi/ugcGameVariants/${assetId}/versions/${versionId}`
2895
+ );
2896
+ }
2897
+ /**
2898
+ * Get a UGC game variant without specifying version.
2899
+ *
2900
+ * @param assetId - UGC game variant asset ID
2901
+ * @returns UGC game variant data
2902
+ */
2903
+ getUgcGameVariantWithoutVersion(assetId) {
2904
+ this.assertNotEmpty(assetId, "assetId");
2905
+ return this.get(`/hi/ugcGameVariants/${assetId}`);
2906
+ }
2907
+ // ─────────────────────────────────────────────────────────────────
2908
+ // Films
2909
+ // ─────────────────────────────────────────────────────────────────
2910
+ /**
2911
+ * Get a film by asset ID.
2912
+ *
2913
+ * @param assetId - Film asset ID
2914
+ * @returns Film data
2915
+ */
2916
+ getFilm(assetId) {
2917
+ this.assertNotEmpty(assetId, "assetId");
2918
+ return this.get(`/hi/films/${assetId}`);
2919
+ }
2920
+ /**
2921
+ * Get film asset for a match (spectate).
2113
2922
  *
2114
2923
  * @param matchId - Match GUID
2115
2924
  * @returns Film asset if available
2116
2925
  */
2117
- getFilmByMatchId(matchId) {
2926
+ spectateByMatchId(matchId) {
2118
2927
  this.assertNotEmpty(matchId, "matchId");
2119
2928
  return this.get(`/hi/films/matches/${matchId}/spectate`);
2120
2929
  }
2930
+ /**
2931
+ * Get film asset for a match.
2932
+ *
2933
+ * @param matchId - Match GUID
2934
+ * @returns Film asset if available
2935
+ * @deprecated Use spectateByMatchId instead
2936
+ */
2937
+ getFilmByMatchId(matchId) {
2938
+ return this.spectateByMatchId(matchId);
2939
+ }
2121
2940
  };
2122
2941
 
2123
2942
  // src/clients/halo-infinite-client.ts