@dendotdev/grunt 1.0.3 → 1.0.5

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
  *
@@ -1268,7 +1366,7 @@ var GameCmsModule = class extends ModuleBase {
1268
1366
  * @returns Medal metadata
1269
1367
  */
1270
1368
  getMedalMetadata() {
1271
- return this.get("/hi/Progression/file/medals/metadata");
1369
+ return this.get("/hi/Waypoint/file/medals/metadata.json");
1272
1370
  }
1273
1371
  /**
1274
1372
  * Get general game metadata.
@@ -1337,6 +1435,232 @@ var GameCmsModule = class extends ModuleBase {
1337
1435
  this.assertNotEmpty(filePath, "filePath");
1338
1436
  return this.get(`/hi/Progression/file/${filePath}`);
1339
1437
  }
1438
+ // ─────────────────────────────────────────────────────────────────
1439
+ // Achievements & Settings
1440
+ // ─────────────────────────────────────────────────────────────────
1441
+ /**
1442
+ * Get all available achievements.
1443
+ *
1444
+ * @returns Achievement collection
1445
+ */
1446
+ getAchievements() {
1447
+ return this.get("/hi/Multiplayer/file/Live/Achievements.json");
1448
+ }
1449
+ /**
1450
+ * Get the Play Now button settings (fallback playlist).
1451
+ *
1452
+ * @returns Fallback playlist settings
1453
+ */
1454
+ getPlayNowButtonSettings() {
1455
+ return this.get(
1456
+ "/hi/Multiplayer/file/playlists/playNowButton/settings.json"
1457
+ );
1458
+ }
1459
+ /**
1460
+ * Get custom game default settings.
1461
+ *
1462
+ * @returns Custom game definition
1463
+ */
1464
+ getCustomGameDefaults() {
1465
+ return this.get("/hi/Multiplayer/file/NonMatchmaking/customgame.json");
1466
+ }
1467
+ /**
1468
+ * Get lobby error messages.
1469
+ *
1470
+ * @param flightId - Flight ID
1471
+ * @returns Lobby error message list
1472
+ */
1473
+ getLobbyErrorMessages(flightId) {
1474
+ this.assertNotEmpty(flightId, "flightId");
1475
+ return this.get(
1476
+ `/hi/Multiplayer/file/gameStartErrorMessages/LobbyHoppperErrorMessageList.json?flight=${flightId}`
1477
+ );
1478
+ }
1479
+ /**
1480
+ * Get network configuration.
1481
+ *
1482
+ * @param flightId - Flight ID
1483
+ * @returns Network configuration
1484
+ */
1485
+ getNetworkConfiguration(flightId) {
1486
+ this.assertNotEmpty(flightId, "flightId");
1487
+ return this.get(
1488
+ `/hi/Multiplayer/file/network/config.json?flight=${flightId}`
1489
+ );
1490
+ }
1491
+ /**
1492
+ * Get a multiplayer playlist configuration.
1493
+ *
1494
+ * @param playlistFile - Playlist file name (e.g., "uuid.json")
1495
+ * @returns Playlist configuration
1496
+ */
1497
+ getMultiplayerPlaylistConfiguration(playlistFile) {
1498
+ this.assertNotEmpty(playlistFile, "playlistFile");
1499
+ return this.get(
1500
+ `/hi/Multiplayer/file/playlists/assets/${playlistFile}`
1501
+ );
1502
+ }
1503
+ // ─────────────────────────────────────────────────────────────────
1504
+ // Graphics & Specs
1505
+ // ─────────────────────────────────────────────────────────────────
1506
+ /**
1507
+ * Get async compute overrides.
1508
+ *
1509
+ * @returns Async compute override configuration
1510
+ */
1511
+ getAsyncComputeOverrides() {
1512
+ return this.get("/hi/Specs/file/graphics/AsyncComputeOverrides.json");
1513
+ }
1514
+ /**
1515
+ * Get CPU presets.
1516
+ *
1517
+ * @returns CPU preset configuration
1518
+ */
1519
+ getCpuPresets() {
1520
+ return this.get("/hi/Specs/file/cpu/presets.json");
1521
+ }
1522
+ /**
1523
+ * Get device preset overrides.
1524
+ *
1525
+ * @returns Device preset overrides
1526
+ */
1527
+ getDevicePresetOverrides() {
1528
+ return this.get("/hi/Specs/file/graphics/DevicePresetOverrides.json");
1529
+ }
1530
+ /**
1531
+ * Get graphics spec control overrides.
1532
+ *
1533
+ * @returns Graphics spec control overrides
1534
+ */
1535
+ getGraphicsSpecControlOverrides() {
1536
+ return this.get(
1537
+ "/hi/Specs/file/graphics/GraphicsSpecControlOverrides.json"
1538
+ );
1539
+ }
1540
+ /**
1541
+ * Get graphics specs/overrides.
1542
+ *
1543
+ * @returns Graphics overrides
1544
+ */
1545
+ getGraphicSpecs() {
1546
+ return this.get("/hi/Specs/file/graphics/overrides.json");
1547
+ }
1548
+ /**
1549
+ * Get recommended drivers.
1550
+ *
1551
+ * @returns Driver manifest
1552
+ */
1553
+ getRecommendedDrivers() {
1554
+ return this.get("/hi/Specs/file/graphics/RecommendedDrivers.json");
1555
+ }
1556
+ // ─────────────────────────────────────────────────────────────────
1557
+ // Title Authorization & Access
1558
+ // ─────────────────────────────────────────────────────────────────
1559
+ /**
1560
+ * Get claw (clawback) access list.
1561
+ *
1562
+ * @param flightId - Flight ID
1563
+ * @returns Claw access snapshot
1564
+ */
1565
+ getClawAccess(flightId) {
1566
+ this.assertNotEmpty(flightId, "flightId");
1567
+ return this.get(
1568
+ `/hi/TitleAuthorization/file/claw/access.json?flight=${flightId}`
1569
+ );
1570
+ }
1571
+ /**
1572
+ * Get not allowed in title message.
1573
+ *
1574
+ * @returns OE configuration message
1575
+ */
1576
+ getNotAllowedInTitleMessage() {
1577
+ const url = `https://${HALO_CORE_ENDPOINTS.GAME_CMS_ORIGIN}.${HALO_CORE_ENDPOINTS.SERVICE_DOMAIN}/branches/hi/OEConfiguration/data/authfail/Default.json`;
1578
+ return this.getFullUrl(url, { useSpartanToken: false });
1579
+ }
1580
+ // ─────────────────────────────────────────────────────────────────
1581
+ // Guides (File Listings)
1582
+ // ─────────────────────────────────────────────────────────────────
1583
+ /**
1584
+ * Get guide for images files.
1585
+ *
1586
+ * @param flightId - Flight ID
1587
+ * @returns Guide container with file listings
1588
+ */
1589
+ getGuideImages(flightId) {
1590
+ this.assertNotEmpty(flightId, "flightId");
1591
+ return this.get(`/hi/images/guide/xo?flight=${flightId}`);
1592
+ }
1593
+ /**
1594
+ * Get guide for multiplayer files.
1595
+ *
1596
+ * @param flightId - Flight ID
1597
+ * @returns Guide container with file listings
1598
+ */
1599
+ getGuideMultiplayer(flightId) {
1600
+ this.assertNotEmpty(flightId, "flightId");
1601
+ return this.get(`/hi/Multiplayer/guide/xo?flight=${flightId}`);
1602
+ }
1603
+ /**
1604
+ * Get guide for news files.
1605
+ *
1606
+ * @param flightId - Flight ID
1607
+ * @returns Guide container with file listings
1608
+ */
1609
+ getGuideNews(flightId) {
1610
+ this.assertNotEmpty(flightId, "flightId");
1611
+ return this.get(`/hi/News/guide/xo?flight=${flightId}`);
1612
+ }
1613
+ /**
1614
+ * Get guide for progression files.
1615
+ *
1616
+ * @param flightId - Flight ID
1617
+ * @returns Guide container with file listings
1618
+ */
1619
+ getGuideProgression(flightId) {
1620
+ this.assertNotEmpty(flightId, "flightId");
1621
+ return this.get(`/hi/Progression/guide/xo?flight=${flightId}`);
1622
+ }
1623
+ /**
1624
+ * Get guide for spec files.
1625
+ *
1626
+ * @param flightId - Flight ID
1627
+ * @returns Guide container with file listings
1628
+ */
1629
+ getGuideSpecs(flightId) {
1630
+ this.assertNotEmpty(flightId, "flightId");
1631
+ return this.get(`/hi/Specs/guide/xo?flight=${flightId}`);
1632
+ }
1633
+ /**
1634
+ * Get guide for title authorization files.
1635
+ *
1636
+ * @param flightId - Flight ID
1637
+ * @returns Guide container with file listings
1638
+ */
1639
+ getGuideTitleAuthorization(flightId) {
1640
+ this.assertNotEmpty(flightId, "flightId");
1641
+ return this.get(`/hi/TitleAuthorization/guide/xo?flight=${flightId}`);
1642
+ }
1643
+ // ─────────────────────────────────────────────────────────────────
1644
+ // Waypoint Files
1645
+ // ─────────────────────────────────────────────────────────────────
1646
+ /**
1647
+ * Get emblem mapping configuration.
1648
+ *
1649
+ * @returns Emblem mapping dictionary
1650
+ */
1651
+ getEmblemMapping() {
1652
+ return this.get("/hi/Waypoint/file/images/emblems/mapping.json");
1653
+ }
1654
+ /**
1655
+ * Get a generic file from Waypoint service.
1656
+ *
1657
+ * @param filePath - Path to the file
1658
+ * @returns File data as bytes
1659
+ */
1660
+ getGenericWaypointFile(filePath) {
1661
+ this.assertNotEmpty(filePath, "filePath");
1662
+ return this.get(`/hi/Waypoint/file/${filePath}`, { returnRaw: true });
1663
+ }
1340
1664
  };
1341
1665
 
1342
1666
  // src/modules/halo-infinite/lobby.module.ts
@@ -1420,6 +1744,100 @@ var SettingsModule = class extends ModuleBase {
1420
1744
  useSpartanToken: true
1421
1745
  });
1422
1746
  }
1747
+ /**
1748
+ * Get a list of features enabled for a given flight.
1749
+ *
1750
+ * @param flightId - Clearance ID/flight that is being used
1751
+ * @returns Flighted feature flags
1752
+ */
1753
+ getFlightedFeatureFlags(flightId) {
1754
+ this.assertNotEmpty(flightId, "flightId");
1755
+ return this.get(`/featureflags/hi?flight=${flightId}`);
1756
+ }
1757
+ /**
1758
+ * Get the currently active clearance.
1759
+ *
1760
+ * @param release - Release identifier (e.g., "1.4", "1.5", "1.6")
1761
+ * @returns Player clearance data
1762
+ */
1763
+ getActiveClearance(release) {
1764
+ this.assertNotEmpty(release, "release");
1765
+ return this.get(`/hi/clearances/active?release=${release}`, {
1766
+ useSpartanToken: false
1767
+ });
1768
+ }
1769
+ /**
1770
+ * Get the currently active flight.
1771
+ *
1772
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1773
+ * @param buildNumber - Game build number (e.g., "211755.22.01.23.0549-0")
1774
+ * @param release - Release identifier (e.g., "1.4", "1.5")
1775
+ * @returns Player clearance data
1776
+ */
1777
+ getActiveFlight(sandbox, buildNumber, release) {
1778
+ this.assertNotEmpty(sandbox, "sandbox");
1779
+ this.assertNotEmpty(buildNumber, "buildNumber");
1780
+ this.assertNotEmpty(release, "release");
1781
+ return this.get(
1782
+ `/oban/flight-configurations/titles/hi/audiences/RETAIL/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1783
+ );
1784
+ }
1785
+ /**
1786
+ * Get the clearance/flight ID for a specific audience.
1787
+ *
1788
+ * @param audience - Audience targeting (e.g., "RETAIL")
1789
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1790
+ * @param buildNumber - Game build number
1791
+ * @param release - Release identifier
1792
+ * @returns Player clearance data
1793
+ */
1794
+ getClearance(audience, sandbox, buildNumber, release) {
1795
+ this.assertNotEmpty(audience, "audience");
1796
+ this.assertNotEmpty(sandbox, "sandbox");
1797
+ this.assertNotEmpty(buildNumber, "buildNumber");
1798
+ this.assertNotEmpty(release, "release");
1799
+ return this.get(
1800
+ `/oban/flight-configurations/titles/hi/audiences/${audience}/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1801
+ );
1802
+ }
1803
+ /**
1804
+ * Get the player clearance/flight ID for a specific audience.
1805
+ *
1806
+ * @param audience - Audience targeting (e.g., "RETAIL")
1807
+ * @param player - Player XUID
1808
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1809
+ * @param buildNumber - Game build number
1810
+ * @param release - Release identifier
1811
+ * @returns Player clearance data
1812
+ */
1813
+ getPlayerClearance(audience, player, sandbox, buildNumber, release) {
1814
+ this.assertNotEmpty(audience, "audience");
1815
+ this.assertNotEmpty(player, "player");
1816
+ this.assertNotEmpty(sandbox, "sandbox");
1817
+ this.assertNotEmpty(buildNumber, "buildNumber");
1818
+ this.assertNotEmpty(release, "release");
1819
+ return this.get(
1820
+ `/oban/flight-configurations/titles/hi/audiences/${audience}/players/xuid(${player})/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1821
+ );
1822
+ }
1823
+ /**
1824
+ * Get the player clearance/flight ID for RETAIL audience.
1825
+ *
1826
+ * @param player - Player XUID
1827
+ * @param sandbox - Sandbox identifier (typically "UNUSED")
1828
+ * @param buildNumber - Game build number
1829
+ * @param release - Release identifier
1830
+ * @returns Player clearance data
1831
+ */
1832
+ getPlayerClearanceRetail(player, sandbox, buildNumber, release) {
1833
+ this.assertNotEmpty(player, "player");
1834
+ this.assertNotEmpty(sandbox, "sandbox");
1835
+ this.assertNotEmpty(buildNumber, "buildNumber");
1836
+ this.assertNotEmpty(release, "release");
1837
+ return this.get(
1838
+ `/oban/flight-configurations/titles/hi/audiences/RETAIL/players/xuid(${player})/active?sandbox=${sandbox}&build=${buildNumber}&release=${release}`
1839
+ );
1840
+ }
1423
1841
  };
1424
1842
 
1425
1843
  // src/modules/halo-infinite/skill.module.ts
@@ -1601,6 +2019,28 @@ var TextModerationModule = class extends ModuleBase {
1601
2019
  getModerationKey() {
1602
2020
  return this.get("/hi/moderation/key");
1603
2021
  }
2022
+ /**
2023
+ * Get a specific moderation proof signing key.
2024
+ *
2025
+ * @param keyId - Key ID (can be obtained from getSigningKeys)
2026
+ * @returns Signing key data
2027
+ */
2028
+ getSigningKey(keyId) {
2029
+ this.assertNotEmpty(keyId, "keyId");
2030
+ return this.get(`/hi/moderation-proof-keys/${keyId}`, {
2031
+ useSpartanToken: false
2032
+ });
2033
+ }
2034
+ /**
2035
+ * Get all available moderation proof signing keys.
2036
+ *
2037
+ * @returns Container with all signing keys
2038
+ */
2039
+ getSigningKeys() {
2040
+ return this.get("/hi/moderation-proof-keys", {
2041
+ useSpartanToken: false
2042
+ });
2043
+ }
1604
2044
  };
1605
2045
 
1606
2046
  // src/modules/halo-infinite/ugc.module.ts
@@ -1637,6 +2077,18 @@ var UgcModule = class extends ModuleBase {
1637
2077
  this.assertNotEmpty(assetId, "assetId");
1638
2078
  return this.get(`/${title}/${assetType}/${assetId}/versions/latest`);
1639
2079
  }
2080
+ /**
2081
+ * Get the latest version of a film asset.
2082
+ *
2083
+ * @param title - Game title
2084
+ * @param assetId - Film asset GUID
2085
+ * @returns Latest film asset version
2086
+ */
2087
+ getLatestAssetVersionFilm(title, assetId) {
2088
+ this.assertNotEmpty(title, "title");
2089
+ this.assertNotEmpty(assetId, "assetId");
2090
+ return this.get(`/${title}/films/${assetId}/versions/latest`);
2091
+ }
1640
2092
  /**
1641
2093
  * Get a specific version of an asset.
1642
2094
  *
@@ -1812,18 +2264,31 @@ var UgcModule = class extends ModuleBase {
1812
2264
  // Asset Management
1813
2265
  // ─────────────────────────────────────────────────────────────────
1814
2266
  /**
1815
- * Delete an asset and all its versions.
2267
+ * Delete an asset.
1816
2268
  *
1817
2269
  * @param title - Game title
1818
2270
  * @param assetType - Type of asset
1819
2271
  * @param assetId - Asset GUID
1820
2272
  * @returns Success status
1821
2273
  */
1822
- deleteAllVersions(title, assetType, assetId) {
2274
+ deleteAsset(title, assetType, assetId) {
1823
2275
  this.assertNotEmpty(title, "title");
1824
2276
  this.assertNotEmpty(assetId, "assetId");
1825
2277
  return this.delete(`/${title}/${assetType}/${assetId}`);
1826
2278
  }
2279
+ /**
2280
+ * Delete all versions of an asset.
2281
+ *
2282
+ * @param title - Game title
2283
+ * @param assetType - Type of asset
2284
+ * @param assetId - Asset GUID
2285
+ * @returns Success status
2286
+ */
2287
+ deleteAllVersions(title, assetType, assetId) {
2288
+ this.assertNotEmpty(title, "title");
2289
+ this.assertNotEmpty(assetId, "assetId");
2290
+ return this.delete(`/${title}/${assetType}/${assetId}/versions`);
2291
+ }
1827
2292
  /**
1828
2293
  * Delete a specific version of an asset.
1829
2294
  *
@@ -1839,6 +2304,34 @@ var UgcModule = class extends ModuleBase {
1839
2304
  this.assertNotEmpty(versionId, "versionId");
1840
2305
  return this.delete(`/${title}/${assetType}/${assetId}/versions/${versionId}`);
1841
2306
  }
2307
+ /**
2308
+ * Undelete a previously deleted asset.
2309
+ *
2310
+ * @param title - Game title
2311
+ * @param assetType - Type of asset
2312
+ * @param assetId - Asset GUID
2313
+ * @returns Success status
2314
+ */
2315
+ undeleteAsset(title, assetType, assetId) {
2316
+ this.assertNotEmpty(title, "title");
2317
+ this.assertNotEmpty(assetId, "assetId");
2318
+ return this.post(`/${title}/${assetType}/${assetId}/recover`);
2319
+ }
2320
+ /**
2321
+ * Undelete a previously deleted asset version.
2322
+ *
2323
+ * @param title - Game title
2324
+ * @param assetType - Type of asset
2325
+ * @param assetId - Asset GUID
2326
+ * @param versionId - Version GUID
2327
+ * @returns Success status
2328
+ */
2329
+ undeleteVersion(title, assetType, assetId, versionId) {
2330
+ this.assertNotEmpty(title, "title");
2331
+ this.assertNotEmpty(assetId, "assetId");
2332
+ this.assertNotEmpty(versionId, "versionId");
2333
+ return this.post(`/${title}/${assetType}/${assetId}/versions/${versionId}/recover`);
2334
+ }
1842
2335
  /**
1843
2336
  * Publish an asset version.
1844
2337
  *
@@ -1937,6 +2430,21 @@ var UgcModule = class extends ModuleBase {
1937
2430
  this.assertNotEmpty(assetId, "assetId");
1938
2431
  return this.delete(`/${title}/${assetType}/${assetId}/sessions`);
1939
2432
  }
2433
+ /**
2434
+ * Spawn (create) a new asset.
2435
+ *
2436
+ * @param title - Game title
2437
+ * @param assetType - Type of asset (e.g., "UgcGameVariants", "Maps", "Prefabs")
2438
+ * @param asset - Asset definition
2439
+ * @returns Created asset
2440
+ */
2441
+ spawnAsset(title, assetType, asset) {
2442
+ this.assertNotEmpty(title, "title");
2443
+ return this.postJson(
2444
+ `/${title}/${assetType}`,
2445
+ asset
2446
+ );
2447
+ }
1940
2448
  /**
1941
2449
  * Create a new asset version.
1942
2450
  *
@@ -1994,6 +2502,9 @@ var UgcDiscoveryModule = class extends ModuleBase {
1994
2502
  constructor(client) {
1995
2503
  super(client, HALO_CORE_ENDPOINTS.DISCOVERY_ORIGIN);
1996
2504
  }
2505
+ // ─────────────────────────────────────────────────────────────────
2506
+ // Search & Browse
2507
+ // ─────────────────────────────────────────────────────────────────
1997
2508
  /**
1998
2509
  * Search for user-generated content.
1999
2510
  *
@@ -2030,6 +2541,27 @@ var UgcDiscoveryModule = class extends ModuleBase {
2030
2541
  if (params.start !== void 0) {
2031
2542
  queryParts.push(`start=${params.start}`);
2032
2543
  }
2544
+ if (params.averageRatingMin !== void 0) {
2545
+ queryParts.push(`averageRatingMin=${params.averageRatingMin}`);
2546
+ }
2547
+ if (params.fromDateCreatedUtc) {
2548
+ queryParts.push(`fromDateCreatedUtc=${encodeURIComponent(params.fromDateCreatedUtc.toISOString())}`);
2549
+ }
2550
+ if (params.toDateCreatedUtc) {
2551
+ queryParts.push(`toDateCreatedUtc=${encodeURIComponent(params.toDateCreatedUtc.toISOString())}`);
2552
+ }
2553
+ if (params.fromDateModifiedUtc) {
2554
+ queryParts.push(`fromDateModifiedUtc=${encodeURIComponent(params.fromDateModifiedUtc.toISOString())}`);
2555
+ }
2556
+ if (params.toDateModifiedUtc) {
2557
+ queryParts.push(`toDateModifiedUtc=${encodeURIComponent(params.toDateModifiedUtc.toISOString())}`);
2558
+ }
2559
+ if (params.fromDatePublishedUtc) {
2560
+ queryParts.push(`fromDatePublishedUtc=${encodeURIComponent(params.fromDatePublishedUtc.toISOString())}`);
2561
+ }
2562
+ if (params.toDatePublishedUtc) {
2563
+ queryParts.push(`toDatePublishedUtc=${encodeURIComponent(params.toDatePublishedUtc.toISOString())}`);
2564
+ }
2033
2565
  const queryString = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
2034
2566
  return this.get(`/hi/search${queryString}`);
2035
2567
  }
@@ -2109,15 +2641,298 @@ var UgcDiscoveryModule = class extends ModuleBase {
2109
2641
  return this.get(`/hi/${assetKind}/${assetId}`);
2110
2642
  }
2111
2643
  /**
2112
- * Get film asset for a match.
2644
+ * Get tags information.
2645
+ *
2646
+ * @returns Available tags info
2647
+ */
2648
+ getTagsInfo() {
2649
+ return this.get("/hi/info/tags");
2650
+ }
2651
+ // ─────────────────────────────────────────────────────────────────
2652
+ // Manifests
2653
+ // ─────────────────────────────────────────────────────────────────
2654
+ /**
2655
+ * Get the game manifest by build GUID.
2656
+ *
2657
+ * @param buildGuid - Build GUID
2658
+ * @returns Manifest data
2659
+ */
2660
+ getManifestByBuildGuid(buildGuid) {
2661
+ this.assertNotEmpty(buildGuid, "buildGuid");
2662
+ return this.get(`/hi/manifests/guids/${buildGuid}/game`);
2663
+ }
2664
+ /**
2665
+ * Get the game manifest by build number.
2666
+ *
2667
+ * @param buildNumber - Build number (e.g., "6.10022.10499")
2668
+ * @returns Manifest data
2669
+ */
2670
+ getManifestByBuild(buildNumber) {
2671
+ this.assertNotEmpty(buildNumber, "buildNumber");
2672
+ return this.get(`/hi/manifests/builds/${buildNumber}/game`);
2673
+ }
2674
+ /**
2675
+ * Get a specific manifest version.
2676
+ *
2677
+ * @param assetId - Manifest asset ID
2678
+ * @param versionId - Manifest version ID
2679
+ * @param clearanceId - Active flight clearance ID
2680
+ * @returns Manifest data
2681
+ */
2682
+ getManifest(assetId, versionId, clearanceId) {
2683
+ this.assertNotEmpty(assetId, "assetId");
2684
+ this.assertNotEmpty(versionId, "versionId");
2685
+ return this.get(
2686
+ `/hi/manifests/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2687
+ );
2688
+ }
2689
+ // ─────────────────────────────────────────────────────────────────
2690
+ // Maps
2691
+ // ─────────────────────────────────────────────────────────────────
2692
+ /**
2693
+ * Get a specific map version.
2694
+ *
2695
+ * @param assetId - Map asset ID
2696
+ * @param versionId - Map version ID
2697
+ * @returns Map data
2698
+ */
2699
+ getMap(assetId, versionId) {
2700
+ this.assertNotEmpty(assetId, "assetId");
2701
+ this.assertNotEmpty(versionId, "versionId");
2702
+ return this.get(`/hi/maps/${assetId}/versions/${versionId}`);
2703
+ }
2704
+ /**
2705
+ * Get a map without specifying version (returns latest).
2706
+ *
2707
+ * @param assetId - Map asset ID
2708
+ * @returns Map data
2709
+ */
2710
+ getMapWithoutVersion(assetId) {
2711
+ this.assertNotEmpty(assetId, "assetId");
2712
+ return this.get(`/hi/maps/${assetId}`);
2713
+ }
2714
+ // ─────────────────────────────────────────────────────────────────
2715
+ // Map Mode Pairs
2716
+ // ─────────────────────────────────────────────────────────────────
2717
+ /**
2718
+ * Get a specific map mode pair version.
2719
+ *
2720
+ * @param assetId - Map mode pair asset ID
2721
+ * @param versionId - Version ID
2722
+ * @param clearanceId - Active flight clearance ID
2723
+ * @returns Map mode pair data
2724
+ */
2725
+ getMapModePair(assetId, versionId, clearanceId) {
2726
+ this.assertNotEmpty(assetId, "assetId");
2727
+ this.assertNotEmpty(versionId, "versionId");
2728
+ return this.get(
2729
+ `/hi/mapModePairs/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2730
+ );
2731
+ }
2732
+ /**
2733
+ * Get a map mode pair without specifying version.
2734
+ *
2735
+ * @param assetId - Map mode pair asset ID
2736
+ * @returns Map mode pair data
2737
+ */
2738
+ getMapModePairWithoutVersion(assetId) {
2739
+ this.assertNotEmpty(assetId, "assetId");
2740
+ return this.get(`/hi/mapModePairs/${assetId}`);
2741
+ }
2742
+ // ─────────────────────────────────────────────────────────────────
2743
+ // Playlists
2744
+ // ─────────────────────────────────────────────────────────────────
2745
+ /**
2746
+ * Get a specific playlist version.
2747
+ *
2748
+ * @param assetId - Playlist asset ID
2749
+ * @param versionId - Version ID
2750
+ * @param clearanceId - Active flight clearance ID
2751
+ * @returns Playlist data
2752
+ */
2753
+ getPlaylist(assetId, versionId, clearanceId) {
2754
+ this.assertNotEmpty(assetId, "assetId");
2755
+ this.assertNotEmpty(versionId, "versionId");
2756
+ return this.get(
2757
+ `/hi/playlists/${assetId}/versions/${versionId}?clearanceId=${clearanceId}`
2758
+ );
2759
+ }
2760
+ /**
2761
+ * Get a playlist without specifying version.
2762
+ *
2763
+ * @param assetId - Playlist asset ID
2764
+ * @returns Playlist data
2765
+ */
2766
+ getPlaylistWithoutVersion(assetId) {
2767
+ this.assertNotEmpty(assetId, "assetId");
2768
+ return this.get(`/hi/playlists/${assetId}`);
2769
+ }
2770
+ // ─────────────────────────────────────────────────────────────────
2771
+ // Prefabs
2772
+ // ─────────────────────────────────────────────────────────────────
2773
+ /**
2774
+ * Get a specific prefab version.
2775
+ *
2776
+ * @param assetId - Prefab asset ID
2777
+ * @param versionId - Version ID
2778
+ * @returns Prefab data
2779
+ */
2780
+ getPrefab(assetId, versionId) {
2781
+ this.assertNotEmpty(assetId, "assetId");
2782
+ this.assertNotEmpty(versionId, "versionId");
2783
+ return this.get(`/hi/prefabs/${assetId}/versions/${versionId}`);
2784
+ }
2785
+ /**
2786
+ * Get a prefab without specifying version.
2787
+ *
2788
+ * @param assetId - Prefab asset ID
2789
+ * @returns Prefab data
2790
+ */
2791
+ getPrefabWithoutVersion(assetId) {
2792
+ this.assertNotEmpty(assetId, "assetId");
2793
+ return this.get(`/hi/prefabs/${assetId}`);
2794
+ }
2795
+ // ─────────────────────────────────────────────────────────────────
2796
+ // Projects
2797
+ // ─────────────────────────────────────────────────────────────────
2798
+ /**
2799
+ * Get a specific project version.
2800
+ *
2801
+ * @param assetId - Project asset ID
2802
+ * @param versionId - Version ID
2803
+ * @returns Project data
2804
+ */
2805
+ getProject(assetId, versionId) {
2806
+ this.assertNotEmpty(assetId, "assetId");
2807
+ this.assertNotEmpty(versionId, "versionId");
2808
+ return this.get(`/hi/projects/${assetId}/versions/${versionId}`);
2809
+ }
2810
+ /**
2811
+ * Get a project without specifying version.
2812
+ *
2813
+ * @param assetId - Project asset ID
2814
+ * @returns Project data
2815
+ */
2816
+ getProjectWithoutVersion(assetId) {
2817
+ this.assertNotEmpty(assetId, "assetId");
2818
+ return this.get(`/hi/projects/${assetId}`);
2819
+ }
2820
+ /**
2821
+ * Get the Forge templates (canvases).
2822
+ *
2823
+ * @returns Forge templates project
2824
+ */
2825
+ getForgeTemplates() {
2826
+ return this.get("/hi/projects/bf0e9bab-6fed-47a4-8bf7-bfd4422ee552");
2827
+ }
2828
+ /**
2829
+ * Get the Forge mode categories.
2830
+ *
2831
+ * @returns Forge mode categories project
2832
+ */
2833
+ getForgeModeCategories() {
2834
+ return this.get("/hi/projects/aff73c44-0771-468f-b9cf-5c52eee7ab4c");
2835
+ }
2836
+ /**
2837
+ * Get the community tab assets.
2838
+ *
2839
+ * @returns Community tab project
2840
+ */
2841
+ getCommunityTab() {
2842
+ return this.get("/hi/projects/90f9e508-99ce-411c-bf88-7bf12b5e9f52");
2843
+ }
2844
+ /**
2845
+ * Get 343 recommended assets.
2846
+ *
2847
+ * @returns 343 recommended project
2848
+ */
2849
+ get343Recommended() {
2850
+ return this.get("/hi/projects/712add52-f989-48e1-b3bb-ac7cd8a1c17a");
2851
+ }
2852
+ // ─────────────────────────────────────────────────────────────────
2853
+ // Game Variants
2854
+ // ─────────────────────────────────────────────────────────────────
2855
+ /**
2856
+ * Get a specific engine game variant version.
2857
+ *
2858
+ * @param assetId - Engine game variant asset ID
2859
+ * @param versionId - Version ID
2860
+ * @returns Engine game variant data
2861
+ */
2862
+ getEngineGameVariant(assetId, versionId) {
2863
+ this.assertNotEmpty(assetId, "assetId");
2864
+ this.assertNotEmpty(versionId, "versionId");
2865
+ return this.get(
2866
+ `/hi/engineGameVariants/${assetId}/versions/${versionId}`
2867
+ );
2868
+ }
2869
+ /**
2870
+ * Get an engine game variant without specifying version.
2871
+ *
2872
+ * @param assetId - Engine game variant asset ID
2873
+ * @returns Engine game variant data
2874
+ */
2875
+ getEngineGameVariantWithoutVersion(assetId) {
2876
+ this.assertNotEmpty(assetId, "assetId");
2877
+ return this.get(`/hi/engineGameVariants/${assetId}`);
2878
+ }
2879
+ /**
2880
+ * Get a specific UGC game variant version.
2881
+ *
2882
+ * @param assetId - UGC game variant asset ID
2883
+ * @param versionId - Version ID
2884
+ * @returns UGC game variant data
2885
+ */
2886
+ getUgcGameVariant(assetId, versionId) {
2887
+ this.assertNotEmpty(assetId, "assetId");
2888
+ this.assertNotEmpty(versionId, "versionId");
2889
+ return this.get(
2890
+ `/hi/ugcGameVariants/${assetId}/versions/${versionId}`
2891
+ );
2892
+ }
2893
+ /**
2894
+ * Get a UGC game variant without specifying version.
2895
+ *
2896
+ * @param assetId - UGC game variant asset ID
2897
+ * @returns UGC game variant data
2898
+ */
2899
+ getUgcGameVariantWithoutVersion(assetId) {
2900
+ this.assertNotEmpty(assetId, "assetId");
2901
+ return this.get(`/hi/ugcGameVariants/${assetId}`);
2902
+ }
2903
+ // ─────────────────────────────────────────────────────────────────
2904
+ // Films
2905
+ // ─────────────────────────────────────────────────────────────────
2906
+ /**
2907
+ * Get a film by asset ID.
2908
+ *
2909
+ * @param assetId - Film asset ID
2910
+ * @returns Film data
2911
+ */
2912
+ getFilm(assetId) {
2913
+ this.assertNotEmpty(assetId, "assetId");
2914
+ return this.get(`/hi/films/${assetId}`);
2915
+ }
2916
+ /**
2917
+ * Get film asset for a match (spectate).
2113
2918
  *
2114
2919
  * @param matchId - Match GUID
2115
2920
  * @returns Film asset if available
2116
2921
  */
2117
- getFilmByMatchId(matchId) {
2922
+ spectateByMatchId(matchId) {
2118
2923
  this.assertNotEmpty(matchId, "matchId");
2119
2924
  return this.get(`/hi/films/matches/${matchId}/spectate`);
2120
2925
  }
2926
+ /**
2927
+ * Get film asset for a match.
2928
+ *
2929
+ * @param matchId - Match GUID
2930
+ * @returns Film asset if available
2931
+ * @deprecated Use spectateByMatchId instead
2932
+ */
2933
+ getFilmByMatchId(matchId) {
2934
+ return this.spectateByMatchId(matchId);
2935
+ }
2121
2936
  };
2122
2937
 
2123
2938
  // src/clients/halo-infinite-client.ts