@letpeoplework/lighthouse-client 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  getClientPackageContract: () => getClientPackageContract,
26
26
  getDefaultMetricsDateRange: () => getDefaultMetricsDateRange,
27
27
  getStandaloneDiscoveryLockfilePath: () => getStandaloneDiscoveryLockfilePath,
28
+ isServerVersionNewerThan: () => isServerVersionNewerThan,
28
29
  loadStandaloneDiscoveryContract: () => loadStandaloneDiscoveryContract,
29
30
  parseStandaloneDiscoveryContract: () => parseStandaloneDiscoveryContract,
30
31
  pollCliAuthSession: () => pollCliAuthSession,
@@ -578,6 +579,47 @@ var toApiError = (statusCode, reason) => ({
578
579
  reason,
579
580
  statusCode
580
581
  });
582
+ var CONCURRENCY_CONFLICT_STATUS = 409;
583
+ var CONCURRENCY_CONFLICT_GUIDANCE = "This edit conflicts because the item was changed by someone else. Re-fetch the current settings to obtain the latest concurrency token, then re-apply your change.";
584
+ var getProblemDetailsMessage = (body) => {
585
+ if (!isObjectRecord(body)) {
586
+ return void 0;
587
+ }
588
+ for (const key of ["detail", "title", "message"]) {
589
+ const value = body[key];
590
+ if (typeof value === "string" && value.trim().length > 0) {
591
+ return value.trim();
592
+ }
593
+ }
594
+ return void 0;
595
+ };
596
+ var getResponseBody = async (response) => {
597
+ try {
598
+ if (response.json !== void 0) {
599
+ return await response.json();
600
+ }
601
+ return JSON.parse(await response.text());
602
+ } catch {
603
+ return void 0;
604
+ }
605
+ };
606
+ var toConcurrencyConflictError = (serverMessage) => ({
607
+ category: "concurrency-conflict",
608
+ reason: serverMessage === void 0 ? CONCURRENCY_CONFLICT_GUIDANCE : `${serverMessage} ${CONCURRENCY_CONFLICT_GUIDANCE}`,
609
+ statusCode: CONCURRENCY_CONFLICT_STATUS
610
+ });
611
+ var toResponseError = async (response) => {
612
+ if (response.status === CONCURRENCY_CONFLICT_STATUS) {
613
+ const serverMessage = getProblemDetailsMessage(
614
+ await getResponseBody(response)
615
+ );
616
+ return toConcurrencyConflictError(serverMessage);
617
+ }
618
+ return toApiError(
619
+ response.status,
620
+ `Request failed with status ${response.status}.`
621
+ );
622
+ };
581
623
  var requestText = async (configuration, dependencies, route) => {
582
624
  const fetchDependency = getFetchDependency(dependencies);
583
625
  const connectivityResult = await validateLighthouseConnectivity(
@@ -596,12 +638,7 @@ var requestText = async (configuration, dependencies, route) => {
596
638
  getRequestInit(configuration.auth)
597
639
  );
598
640
  if (!response.ok) {
599
- return getErrorResult(
600
- toApiError(
601
- response.status,
602
- `Request failed with status ${response.status}.`
603
- )
604
- );
641
+ return getErrorResult(await toResponseError(response));
605
642
  }
606
643
  return {
607
644
  ok: true,
@@ -635,12 +672,7 @@ var requestJson = async (configuration, dependencies, route, requestOptions) =>
635
672
  getRequestInit(configuration.auth, requestOptions)
636
673
  );
637
674
  if (!response.ok) {
638
- return getErrorResult(
639
- toApiError(
640
- response.status,
641
- `Request failed with status ${response.status}.`
642
- )
643
- );
675
+ return getErrorResult(await toResponseError(response));
644
676
  }
645
677
  if (response.json === void 0) {
646
678
  return {
@@ -681,12 +713,7 @@ var requestNoContent = async (configuration, dependencies, route, requestOptions
681
713
  getRequestInit(configuration.auth, requestOptions)
682
714
  );
683
715
  if (!response.ok) {
684
- return getErrorResult(
685
- toApiError(
686
- response.status,
687
- `Request failed with status ${response.status}.`
688
- )
689
- );
716
+ return getErrorResult(await toResponseError(response));
690
717
  }
691
718
  return {
692
719
  ok: true,
@@ -703,6 +730,7 @@ var requestNoContent = async (configuration, dependencies, route, requestOptions
703
730
  var getResolvedMetricsDateRange = (range) => range ?? getDefaultMetricsDateRange();
704
731
  var getMetricsDateRangeQuery = (range) => `startDate=${encodeURIComponent(range.startDate)}&endDate=${encodeURIComponent(range.endDate)}`;
705
732
  var getMetricsAsOfDateQuery = (asOfDate) => `asOfDate=${encodeURIComponent(asOfDate)}`;
733
+ var getItemIdsQuerySuffix = (itemIds) => itemIds && itemIds.length > 0 ? itemIds.map((id) => `&itemIds=${encodeURIComponent(id)}`).join("") : "";
706
734
  var getViewQuerySuffix = (view) => view === "filtered" ? "&view=filtered" : "";
707
735
  var addUtcDays = (dateStr, days) => {
708
736
  const d = /* @__PURE__ */ new Date(`${dateStr}T00:00:00Z`);
@@ -753,408 +781,614 @@ var deriveTotalWorkItemAgeOverTime = (startDate, endDate, wipData) => {
753
781
  daily.sort((a, b) => a.date.localeCompare(b.date));
754
782
  return { startDate, endDate, daily };
755
783
  };
756
- var createLighthouseClient = (configuration, dependencies = {}) => ({
757
- checkConnectivity: async () => {
758
- const fetchDependency = getFetchDependency(dependencies);
759
- return validateLighthouseConnectivity(
760
- configuration.connection,
761
- {
762
- fetch: fetchDependency
763
- },
764
- getRequestInit(configuration.auth)
765
- );
766
- },
767
- getVersion: async () => requestText(configuration, dependencies, "/v1/version/current"),
768
- listWorkTrackingConnections: async () => requestJson(
769
- configuration,
770
- dependencies,
771
- "/v1/worktrackingsystemconnections",
772
- {
773
- method: "GET"
774
- }
775
- ),
776
- getWorkTrackingConnection: async (connectionId) => requestJson(
777
- configuration,
778
- dependencies,
779
- `/v1/worktrackingsystemconnections/${connectionId}`,
780
- {
781
- method: "GET"
782
- }
783
- ),
784
- createWorkTrackingConnection: async (payload) => requestJson(
785
- configuration,
786
- dependencies,
787
- "/v1/worktrackingsystemconnections",
788
- {
789
- method: "POST",
790
- body: payload
791
- }
792
- ),
793
- updateWorkTrackingConnection: async (connectionId, payload) => requestJson(
794
- configuration,
795
- dependencies,
796
- `/v1/worktrackingsystemconnections/${connectionId}`,
797
- {
798
- method: "PUT",
799
- body: payload
800
- }
801
- ),
802
- deleteWorkTrackingConnection: async (connectionId) => requestNoContent(
803
- configuration,
804
- dependencies,
805
- `/v1/worktrackingsystemconnections/${connectionId}`,
806
- {
807
- method: "DELETE"
808
- }
809
- ),
810
- listTeams: async () => requestJson(configuration, dependencies, "/v1/teams", {
811
- method: "GET"
812
- }),
813
- getTeam: async (teamId) => requestJson(configuration, dependencies, `/v1/teams/${teamId}`, {
814
- method: "GET"
815
- }),
816
- createTeam: async (payload) => requestJson(configuration, dependencies, "/v1/teams", {
817
- method: "POST",
818
- body: payload
819
- }),
820
- updateTeam: async (teamId, payload) => requestJson(configuration, dependencies, `/v1/teams/${teamId}`, {
821
- method: "PUT",
822
- body: payload
823
- }),
824
- deleteTeam: async (teamId) => requestNoContent(configuration, dependencies, `/v1/teams/${teamId}`, {
825
- method: "DELETE"
826
- }),
827
- refreshTeam: async (teamId) => requestNoContent(configuration, dependencies, `/v1/teams/${teamId}`, {
828
- method: "POST"
829
- }),
830
- listPortfolios: async () => requestJson(
831
- configuration,
832
- dependencies,
833
- "/v1/portfolios",
834
- {
835
- method: "GET"
784
+ var FEATURE_REQUIRES_SERVER_NEWER_THAN = {
785
+ cumulativeStateTime: "v26.5.24.10",
786
+ recurringBlackoutRules: "v26.5.29.5"
787
+ };
788
+ var parseServerVersion = (raw) => {
789
+ const trimmed = raw.trim().replace(/^v/iu, "");
790
+ if (trimmed.length === 0) {
791
+ return null;
792
+ }
793
+ const segments = trimmed.split(".");
794
+ const parsed = [];
795
+ for (const segment of segments) {
796
+ if (!/^\d+$/u.test(segment)) {
797
+ return null;
836
798
  }
837
- ),
838
- getPortfolio: async (portfolioId) => requestJson(
839
- configuration,
840
- dependencies,
841
- `/v1/portfolios/${portfolioId}`,
842
- {
843
- method: "GET"
799
+ parsed.push(Number(segment));
800
+ }
801
+ return parsed.length > 0 ? parsed : null;
802
+ };
803
+ var isServerVersionNewerThan = (candidate, baseline) => {
804
+ const left = parseServerVersion(candidate);
805
+ const right = parseServerVersion(baseline);
806
+ if (left === null || right === null) {
807
+ return null;
808
+ }
809
+ const length = Math.max(left.length, right.length);
810
+ for (let index = 0; index < length; index += 1) {
811
+ const l = left[index] ?? 0;
812
+ const r = right[index] ?? 0;
813
+ if (l !== r) {
814
+ return l > r;
844
815
  }
845
- ),
846
- createPortfolio: async (payload) => requestJson(configuration, dependencies, "/v1/portfolios", {
847
- method: "POST",
848
- body: payload
849
- }),
850
- updatePortfolio: async (portfolioId, payload) => requestJson(
851
- configuration,
852
- dependencies,
853
- `/v1/portfolios/${portfolioId}`,
854
- {
855
- method: "PUT",
856
- body: payload
816
+ }
817
+ return false;
818
+ };
819
+ var createLighthouseClient = (configuration, dependencies = {}) => {
820
+ let cachedServerVersion;
821
+ const getCachedServerVersion = async () => {
822
+ if (cachedServerVersion === void 0) {
823
+ const result = await requestText(
824
+ configuration,
825
+ dependencies,
826
+ "/v1/version/current"
827
+ );
828
+ cachedServerVersion = result.ok ? result.value : null;
857
829
  }
858
- ),
859
- deletePortfolio: async (portfolioId) => requestNoContent(
860
- configuration,
861
- dependencies,
862
- `/v1/portfolios/${portfolioId}`,
863
- {
864
- method: "DELETE"
830
+ return cachedServerVersion;
831
+ };
832
+ const ensureServerSupports = async (feature) => {
833
+ const version = await getCachedServerVersion();
834
+ if (version === null) {
835
+ return null;
865
836
  }
866
- ),
867
- refreshPortfolio: async (portfolioId) => requestNoContent(
868
- configuration,
869
- dependencies,
870
- `/v1/portfolios/${portfolioId}/refresh`,
871
- {
872
- method: "POST"
837
+ const baseline = FEATURE_REQUIRES_SERVER_NEWER_THAN[feature];
838
+ const newer = isServerVersionNewerThan(version, baseline);
839
+ if (newer === null || newer) {
840
+ return null;
873
841
  }
874
- ),
875
- getTeamThroughput: async (teamId, range, view) => {
876
- const r = getResolvedMetricsDateRange(range);
877
- return requestJson(
842
+ return {
843
+ ok: false,
844
+ error: {
845
+ category: "misconfigured",
846
+ reason: `This Lighthouse server (${version}) does not support "${feature}" \u2014 it requires a version newer than ${baseline}. Upgrade Lighthouse to use this client feature.`
847
+ }
848
+ };
849
+ };
850
+ return {
851
+ checkConnectivity: async () => {
852
+ const fetchDependency = getFetchDependency(dependencies);
853
+ return validateLighthouseConnectivity(
854
+ configuration.connection,
855
+ {
856
+ fetch: fetchDependency
857
+ },
858
+ getRequestInit(configuration.auth)
859
+ );
860
+ },
861
+ getVersion: async () => requestText(configuration, dependencies, "/v1/version/current"),
862
+ listWorkTrackingConnections: async () => requestJson(
878
863
  configuration,
879
864
  dependencies,
880
- `/v1/teams/${teamId}/metrics/throughput?${getMetricsDateRangeQuery(r)}${getViewQuerySuffix(view)}`,
881
- { method: "GET" }
882
- );
883
- },
884
- getTeamArrivals: async (teamId, range) => {
885
- const r = getResolvedMetricsDateRange(range);
886
- return requestJson(
865
+ "/v1/worktrackingsystemconnections",
866
+ {
867
+ method: "GET"
868
+ }
869
+ ),
870
+ getWorkTrackingConnection: async (connectionId) => requestJson(
887
871
  configuration,
888
872
  dependencies,
889
- `/v1/teams/${teamId}/metrics/arrivals?${getMetricsDateRangeQuery(r)}`,
890
- { method: "GET" }
891
- );
892
- },
893
- getTeamWipOverTime: async (teamId, range) => {
894
- const r = getResolvedMetricsDateRange(range);
895
- return requestJson(
873
+ `/v1/worktrackingsystemconnections/${connectionId}`,
874
+ {
875
+ method: "GET"
876
+ }
877
+ ),
878
+ createWorkTrackingConnection: async (payload) => requestJson(
896
879
  configuration,
897
880
  dependencies,
898
- `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
899
- { method: "GET" }
900
- );
901
- },
902
- getTeamWip: async (teamId, asOfDate) => requestJson(
903
- configuration,
904
- dependencies,
905
- `/v1/teams/${teamId}/metrics/wip?${getMetricsAsOfDateQuery(asOfDate)}`,
906
- { method: "GET" }
907
- ),
908
- getTeamCycleTimePercentiles: async (teamId, range) => {
909
- const r = getResolvedMetricsDateRange(range);
910
- return requestJson(
881
+ "/v1/worktrackingsystemconnections",
882
+ {
883
+ method: "POST",
884
+ body: payload
885
+ }
886
+ ),
887
+ updateWorkTrackingConnection: async (connectionId, payload) => requestJson(
911
888
  configuration,
912
889
  dependencies,
913
- `/v1/teams/${teamId}/metrics/cycleTimePercentiles?${getMetricsDateRangeQuery(r)}`,
914
- { method: "GET" }
915
- );
916
- },
917
- getTeamCycleTimeData: async (teamId, range) => {
918
- const r = getResolvedMetricsDateRange(range);
919
- return requestJson(
890
+ `/v1/worktrackingsystemconnections/${connectionId}`,
891
+ {
892
+ method: "PUT",
893
+ body: payload
894
+ }
895
+ ),
896
+ deleteWorkTrackingConnection: async (connectionId) => requestNoContent(
920
897
  configuration,
921
898
  dependencies,
922
- `/v1/teams/${teamId}/metrics/cycleTimeData?${getMetricsDateRangeQuery(r)}`,
923
- { method: "GET" }
924
- );
925
- },
926
- getTeamPredictabilityScore: async (teamId, range, view) => {
927
- const r = getResolvedMetricsDateRange(range);
928
- return requestJson(
899
+ `/v1/worktrackingsystemconnections/${connectionId}`,
900
+ {
901
+ method: "DELETE"
902
+ }
903
+ ),
904
+ listTeams: async () => requestJson(
929
905
  configuration,
930
906
  dependencies,
931
- `/v1/teams/${teamId}/metrics/multiitemforecastpredictabilityscore?${getMetricsDateRangeQuery(r)}${getViewQuerySuffix(view)}`,
932
- { method: "GET" }
933
- );
934
- },
935
- getTeamTotalWorkItemAge: async (teamId, asOfDate) => requestJson(
936
- configuration,
937
- dependencies,
938
- `/v1/teams/${teamId}/metrics/totalWorkItemAge?${getMetricsAsOfDateQuery(asOfDate)}`,
939
- { method: "GET" }
940
- ),
941
- getTeamTotalWorkItemAgeInfo: async (teamId, range) => {
942
- const r = getResolvedMetricsDateRange(range);
943
- return requestJson(
907
+ "/v1/teams",
908
+ {
909
+ method: "GET"
910
+ }
911
+ ),
912
+ getTeam: async (teamId) => requestJson(configuration, dependencies, `/v1/teams/${teamId}`, {
913
+ method: "GET"
914
+ }),
915
+ createTeam: async (payload) => requestJson(configuration, dependencies, "/v1/teams", {
916
+ method: "POST",
917
+ body: payload
918
+ }),
919
+ updateTeam: async (teamId, payload) => requestJson(configuration, dependencies, `/v1/teams/${teamId}`, {
920
+ method: "PUT",
921
+ body: payload
922
+ }),
923
+ deleteTeam: async (teamId) => requestNoContent(configuration, dependencies, `/v1/teams/${teamId}`, {
924
+ method: "DELETE"
925
+ }),
926
+ refreshTeam: async (teamId) => requestNoContent(configuration, dependencies, `/v1/teams/${teamId}`, {
927
+ method: "POST"
928
+ }),
929
+ listPortfolios: async () => requestJson(
944
930
  configuration,
945
931
  dependencies,
946
- `/v1/teams/${teamId}/metrics/totalWorkItemAgeInfo?${getMetricsDateRangeQuery(r)}`,
947
- { method: "GET" }
948
- );
949
- },
950
- getTeamWorkItemAgeOverTime: async (teamId, range) => {
951
- const r = getResolvedMetricsDateRange(range);
952
- const wipResult = await requestJson(
932
+ "/v1/portfolios",
933
+ {
934
+ method: "GET"
935
+ }
936
+ ),
937
+ getPortfolio: async (portfolioId) => requestJson(
953
938
  configuration,
954
939
  dependencies,
955
- `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
956
- { method: "GET" }
957
- );
958
- if (!wipResult.ok) {
959
- return wipResult;
960
- }
961
- return {
962
- ok: true,
963
- value: deriveWorkItemAgeOverTime(r.startDate, r.endDate, wipResult.value)
964
- };
965
- },
966
- getTeamTotalWorkItemAgeOverTime: async (teamId, range) => {
967
- const r = getResolvedMetricsDateRange(range);
968
- const wipResult = await requestJson(
940
+ `/v1/portfolios/${portfolioId}`,
941
+ {
942
+ method: "GET"
943
+ }
944
+ ),
945
+ createPortfolio: async (payload) => requestJson(configuration, dependencies, "/v1/portfolios", {
946
+ method: "POST",
947
+ body: payload
948
+ }),
949
+ updatePortfolio: async (portfolioId, payload) => requestJson(
969
950
  configuration,
970
951
  dependencies,
971
- `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
972
- { method: "GET" }
973
- );
974
- if (!wipResult.ok) {
975
- return wipResult;
976
- }
977
- return {
978
- ok: true,
979
- value: deriveTotalWorkItemAgeOverTime(
980
- r.startDate,
981
- r.endDate,
982
- wipResult.value
983
- )
984
- };
985
- },
986
- getPortfolioThroughput: async (portfolioId, range) => {
987
- const r = getResolvedMetricsDateRange(range);
988
- return requestJson(
952
+ `/v1/portfolios/${portfolioId}`,
953
+ {
954
+ method: "PUT",
955
+ body: payload
956
+ }
957
+ ),
958
+ deletePortfolio: async (portfolioId) => requestNoContent(
989
959
  configuration,
990
960
  dependencies,
991
- `/v1/portfolios/${portfolioId}/metrics/throughput?${getMetricsDateRangeQuery(r)}`,
992
- { method: "GET" }
993
- );
994
- },
995
- getPortfolioCycleTimePercentiles: async (portfolioId, range) => {
996
- const r = getResolvedMetricsDateRange(range);
997
- return requestJson(
961
+ `/v1/portfolios/${portfolioId}`,
962
+ {
963
+ method: "DELETE"
964
+ }
965
+ ),
966
+ refreshPortfolio: async (portfolioId) => requestNoContent(
998
967
  configuration,
999
968
  dependencies,
1000
- `/v1/portfolios/${portfolioId}/metrics/cycleTimePercentiles?${getMetricsDateRangeQuery(r)}`,
1001
- { method: "GET" }
1002
- );
1003
- },
1004
- getPortfolioArrivals: async (portfolioId, range) => {
1005
- const r = getResolvedMetricsDateRange(range);
1006
- return requestJson(
969
+ `/v1/portfolios/${portfolioId}/refresh`,
970
+ {
971
+ method: "POST"
972
+ }
973
+ ),
974
+ getTeamThroughput: async (teamId, range, view) => {
975
+ const r = getResolvedMetricsDateRange(range);
976
+ return requestJson(
977
+ configuration,
978
+ dependencies,
979
+ `/v1/teams/${teamId}/metrics/throughput?${getMetricsDateRangeQuery(r)}${getViewQuerySuffix(view)}`,
980
+ { method: "GET" }
981
+ );
982
+ },
983
+ getTeamArrivals: async (teamId, range) => {
984
+ const r = getResolvedMetricsDateRange(range);
985
+ return requestJson(
986
+ configuration,
987
+ dependencies,
988
+ `/v1/teams/${teamId}/metrics/arrivals?${getMetricsDateRangeQuery(r)}`,
989
+ { method: "GET" }
990
+ );
991
+ },
992
+ getTeamWipOverTime: async (teamId, range) => {
993
+ const r = getResolvedMetricsDateRange(range);
994
+ return requestJson(
995
+ configuration,
996
+ dependencies,
997
+ `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
998
+ { method: "GET" }
999
+ );
1000
+ },
1001
+ getTeamWip: async (teamId, asOfDate) => requestJson(
1007
1002
  configuration,
1008
1003
  dependencies,
1009
- `/v1/portfolios/${portfolioId}/metrics/arrivals?${getMetricsDateRangeQuery(r)}`,
1004
+ `/v1/teams/${teamId}/metrics/wip?${getMetricsAsOfDateQuery(asOfDate)}`,
1010
1005
  { method: "GET" }
1011
- );
1012
- },
1013
- getPortfolioWipOverTime: async (portfolioId, range) => {
1014
- const r = getResolvedMetricsDateRange(range);
1015
- return requestJson(
1006
+ ),
1007
+ getTeamCycleTimePercentiles: async (teamId, range) => {
1008
+ const r = getResolvedMetricsDateRange(range);
1009
+ return requestJson(
1010
+ configuration,
1011
+ dependencies,
1012
+ `/v1/teams/${teamId}/metrics/cycleTimePercentiles?${getMetricsDateRangeQuery(r)}`,
1013
+ { method: "GET" }
1014
+ );
1015
+ },
1016
+ getTeamCycleTimeData: async (teamId, range) => {
1017
+ const r = getResolvedMetricsDateRange(range);
1018
+ return requestJson(
1019
+ configuration,
1020
+ dependencies,
1021
+ `/v1/teams/${teamId}/metrics/cycleTimeData?${getMetricsDateRangeQuery(r)}`,
1022
+ { method: "GET" }
1023
+ );
1024
+ },
1025
+ getTeamPredictabilityScore: async (teamId, range, view) => {
1026
+ const r = getResolvedMetricsDateRange(range);
1027
+ return requestJson(
1028
+ configuration,
1029
+ dependencies,
1030
+ `/v1/teams/${teamId}/metrics/multiitemforecastpredictabilityscore?${getMetricsDateRangeQuery(r)}${getViewQuerySuffix(view)}`,
1031
+ { method: "GET" }
1032
+ );
1033
+ },
1034
+ getTeamTotalWorkItemAge: async (teamId, asOfDate) => requestJson(
1016
1035
  configuration,
1017
1036
  dependencies,
1018
- `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1037
+ `/v1/teams/${teamId}/metrics/totalWorkItemAge?${getMetricsAsOfDateQuery(asOfDate)}`,
1019
1038
  { method: "GET" }
1020
- );
1021
- },
1022
- getPortfolioWip: async (portfolioId, asOfDate) => requestJson(
1023
- configuration,
1024
- dependencies,
1025
- `/v1/portfolios/${portfolioId}/metrics/wip?${getMetricsAsOfDateQuery(asOfDate)}`,
1026
- { method: "GET" }
1027
- ),
1028
- getPortfolioCycleTimeData: async (portfolioId, range) => {
1029
- const r = getResolvedMetricsDateRange(range);
1030
- return requestJson(
1039
+ ),
1040
+ getTeamTotalWorkItemAgeInfo: async (teamId, range) => {
1041
+ const r = getResolvedMetricsDateRange(range);
1042
+ return requestJson(
1043
+ configuration,
1044
+ dependencies,
1045
+ `/v1/teams/${teamId}/metrics/totalWorkItemAgeInfo?${getMetricsDateRangeQuery(r)}`,
1046
+ { method: "GET" }
1047
+ );
1048
+ },
1049
+ getTeamWorkItemAgeOverTime: async (teamId, range) => {
1050
+ const r = getResolvedMetricsDateRange(range);
1051
+ const wipResult = await requestJson(
1052
+ configuration,
1053
+ dependencies,
1054
+ `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1055
+ { method: "GET" }
1056
+ );
1057
+ if (!wipResult.ok) {
1058
+ return wipResult;
1059
+ }
1060
+ return {
1061
+ ok: true,
1062
+ value: deriveWorkItemAgeOverTime(
1063
+ r.startDate,
1064
+ r.endDate,
1065
+ wipResult.value
1066
+ )
1067
+ };
1068
+ },
1069
+ getTeamTotalWorkItemAgeOverTime: async (teamId, range) => {
1070
+ const r = getResolvedMetricsDateRange(range);
1071
+ const wipResult = await requestJson(
1072
+ configuration,
1073
+ dependencies,
1074
+ `/v1/teams/${teamId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1075
+ { method: "GET" }
1076
+ );
1077
+ if (!wipResult.ok) {
1078
+ return wipResult;
1079
+ }
1080
+ return {
1081
+ ok: true,
1082
+ value: deriveTotalWorkItemAgeOverTime(
1083
+ r.startDate,
1084
+ r.endDate,
1085
+ wipResult.value
1086
+ )
1087
+ };
1088
+ },
1089
+ getPortfolioThroughput: async (portfolioId, range) => {
1090
+ const r = getResolvedMetricsDateRange(range);
1091
+ return requestJson(
1092
+ configuration,
1093
+ dependencies,
1094
+ `/v1/portfolios/${portfolioId}/metrics/throughput?${getMetricsDateRangeQuery(r)}`,
1095
+ { method: "GET" }
1096
+ );
1097
+ },
1098
+ getPortfolioCycleTimePercentiles: async (portfolioId, range) => {
1099
+ const r = getResolvedMetricsDateRange(range);
1100
+ return requestJson(
1101
+ configuration,
1102
+ dependencies,
1103
+ `/v1/portfolios/${portfolioId}/metrics/cycleTimePercentiles?${getMetricsDateRangeQuery(r)}`,
1104
+ { method: "GET" }
1105
+ );
1106
+ },
1107
+ getPortfolioArrivals: async (portfolioId, range) => {
1108
+ const r = getResolvedMetricsDateRange(range);
1109
+ return requestJson(
1110
+ configuration,
1111
+ dependencies,
1112
+ `/v1/portfolios/${portfolioId}/metrics/arrivals?${getMetricsDateRangeQuery(r)}`,
1113
+ { method: "GET" }
1114
+ );
1115
+ },
1116
+ getPortfolioWipOverTime: async (portfolioId, range) => {
1117
+ const r = getResolvedMetricsDateRange(range);
1118
+ return requestJson(
1119
+ configuration,
1120
+ dependencies,
1121
+ `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1122
+ { method: "GET" }
1123
+ );
1124
+ },
1125
+ getPortfolioWip: async (portfolioId, asOfDate) => requestJson(
1031
1126
  configuration,
1032
1127
  dependencies,
1033
- `/v1/portfolios/${portfolioId}/metrics/cycleTimeData?${getMetricsDateRangeQuery(r)}`,
1128
+ `/v1/portfolios/${portfolioId}/metrics/wip?${getMetricsAsOfDateQuery(asOfDate)}`,
1034
1129
  { method: "GET" }
1035
- );
1036
- },
1037
- getPortfolioPredictabilityScore: async (portfolioId, range) => {
1038
- const r = getResolvedMetricsDateRange(range);
1039
- return requestJson(
1130
+ ),
1131
+ getPortfolioCycleTimeData: async (portfolioId, range) => {
1132
+ const r = getResolvedMetricsDateRange(range);
1133
+ return requestJson(
1134
+ configuration,
1135
+ dependencies,
1136
+ `/v1/portfolios/${portfolioId}/metrics/cycleTimeData?${getMetricsDateRangeQuery(r)}`,
1137
+ { method: "GET" }
1138
+ );
1139
+ },
1140
+ getPortfolioPredictabilityScore: async (portfolioId, range) => {
1141
+ const r = getResolvedMetricsDateRange(range);
1142
+ return requestJson(
1143
+ configuration,
1144
+ dependencies,
1145
+ `/v1/portfolios/${portfolioId}/metrics/multiitemforecastpredictabilityscore?${getMetricsDateRangeQuery(r)}`,
1146
+ { method: "GET" }
1147
+ );
1148
+ },
1149
+ getPortfolioTotalWorkItemAge: async (portfolioId, asOfDate) => requestJson(
1040
1150
  configuration,
1041
1151
  dependencies,
1042
- `/v1/portfolios/${portfolioId}/metrics/multiitemforecastpredictabilityscore?${getMetricsDateRangeQuery(r)}`,
1152
+ `/v1/portfolios/${portfolioId}/metrics/totalWorkItemAge?${getMetricsAsOfDateQuery(asOfDate)}`,
1043
1153
  { method: "GET" }
1044
- );
1045
- },
1046
- getPortfolioTotalWorkItemAge: async (portfolioId, asOfDate) => requestJson(
1047
- configuration,
1048
- dependencies,
1049
- `/v1/portfolios/${portfolioId}/metrics/totalWorkItemAge?${getMetricsAsOfDateQuery(asOfDate)}`,
1050
- { method: "GET" }
1051
- ),
1052
- getPortfolioTotalWorkItemAgeInfo: async (portfolioId, range) => {
1053
- const r = getResolvedMetricsDateRange(range);
1054
- return requestJson(
1154
+ ),
1155
+ getPortfolioTotalWorkItemAgeInfo: async (portfolioId, range) => {
1156
+ const r = getResolvedMetricsDateRange(range);
1157
+ return requestJson(
1158
+ configuration,
1159
+ dependencies,
1160
+ `/v1/portfolios/${portfolioId}/metrics/totalWorkItemAgeInfo?${getMetricsDateRangeQuery(r)}`,
1161
+ { method: "GET" }
1162
+ );
1163
+ },
1164
+ getPortfolioWorkItemAgeOverTime: async (portfolioId, range) => {
1165
+ const r = getResolvedMetricsDateRange(range);
1166
+ const wipResult = await requestJson(
1167
+ configuration,
1168
+ dependencies,
1169
+ `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1170
+ { method: "GET" }
1171
+ );
1172
+ if (!wipResult.ok) {
1173
+ return wipResult;
1174
+ }
1175
+ return {
1176
+ ok: true,
1177
+ value: deriveWorkItemAgeOverTime(
1178
+ r.startDate,
1179
+ r.endDate,
1180
+ wipResult.value
1181
+ )
1182
+ };
1183
+ },
1184
+ getPortfolioTotalWorkItemAgeOverTime: async (portfolioId, range) => {
1185
+ const r = getResolvedMetricsDateRange(range);
1186
+ const wipResult = await requestJson(
1187
+ configuration,
1188
+ dependencies,
1189
+ `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1190
+ { method: "GET" }
1191
+ );
1192
+ if (!wipResult.ok) {
1193
+ return wipResult;
1194
+ }
1195
+ return {
1196
+ ok: true,
1197
+ value: deriveTotalWorkItemAgeOverTime(
1198
+ r.startDate,
1199
+ r.endDate,
1200
+ wipResult.value
1201
+ )
1202
+ };
1203
+ },
1204
+ getTeamCumulativeStateTime: async (teamId, range, itemIds) => {
1205
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1206
+ if (unsupported) {
1207
+ return unsupported;
1208
+ }
1209
+ const r = getResolvedMetricsDateRange(range);
1210
+ return requestJson(
1211
+ configuration,
1212
+ dependencies,
1213
+ `/v1/teams/${teamId}/metrics/cumulativeStateTime?${getMetricsDateRangeQuery(r)}${getItemIdsQuerySuffix(itemIds)}`,
1214
+ { method: "GET" }
1215
+ );
1216
+ },
1217
+ getTeamCumulativeStateTimeItems: async (teamId, state, range, itemIds) => {
1218
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1219
+ if (unsupported) {
1220
+ return unsupported;
1221
+ }
1222
+ const r = getResolvedMetricsDateRange(range);
1223
+ return requestJson(
1224
+ configuration,
1225
+ dependencies,
1226
+ `/v1/teams/${teamId}/metrics/cumulativeStateTime/items?state=${encodeURIComponent(state)}&${getMetricsDateRangeQuery(r)}${getItemIdsQuerySuffix(itemIds)}`,
1227
+ { method: "GET" }
1228
+ );
1229
+ },
1230
+ getTeamCumulativeStateTimeCandidates: async (teamId, range) => {
1231
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1232
+ if (unsupported) {
1233
+ return unsupported;
1234
+ }
1235
+ const r = getResolvedMetricsDateRange(range);
1236
+ return requestJson(
1237
+ configuration,
1238
+ dependencies,
1239
+ `/v1/teams/${teamId}/metrics/cumulativeStateTime/candidates?${getMetricsDateRangeQuery(r)}`,
1240
+ { method: "GET" }
1241
+ );
1242
+ },
1243
+ getPortfolioCumulativeStateTime: async (portfolioId, range, itemIds) => {
1244
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1245
+ if (unsupported) {
1246
+ return unsupported;
1247
+ }
1248
+ const r = getResolvedMetricsDateRange(range);
1249
+ return requestJson(
1250
+ configuration,
1251
+ dependencies,
1252
+ `/v1/portfolios/${portfolioId}/metrics/cumulativeStateTime?${getMetricsDateRangeQuery(r)}${getItemIdsQuerySuffix(itemIds)}`,
1253
+ { method: "GET" }
1254
+ );
1255
+ },
1256
+ getPortfolioCumulativeStateTimeItems: async (portfolioId, state, range, itemIds) => {
1257
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1258
+ if (unsupported) {
1259
+ return unsupported;
1260
+ }
1261
+ const r = getResolvedMetricsDateRange(range);
1262
+ return requestJson(
1263
+ configuration,
1264
+ dependencies,
1265
+ `/v1/portfolios/${portfolioId}/metrics/cumulativeStateTime/items?state=${encodeURIComponent(state)}&${getMetricsDateRangeQuery(r)}${getItemIdsQuerySuffix(itemIds)}`,
1266
+ { method: "GET" }
1267
+ );
1268
+ },
1269
+ getPortfolioCumulativeStateTimeCandidates: async (portfolioId, range) => {
1270
+ const unsupported = await ensureServerSupports("cumulativeStateTime");
1271
+ if (unsupported) {
1272
+ return unsupported;
1273
+ }
1274
+ const r = getResolvedMetricsDateRange(range);
1275
+ return requestJson(
1276
+ configuration,
1277
+ dependencies,
1278
+ `/v1/portfolios/${portfolioId}/metrics/cumulativeStateTime/candidates?${getMetricsDateRangeQuery(r)}`,
1279
+ { method: "GET" }
1280
+ );
1281
+ },
1282
+ getFeaturesByIds: async (ids) => {
1283
+ const queryString = ids.map((id) => `ids=${encodeURIComponent(id)}`).join("&");
1284
+ return requestJson(
1285
+ configuration,
1286
+ dependencies,
1287
+ `/v1/features?${queryString}`,
1288
+ { method: "GET" }
1289
+ );
1290
+ },
1291
+ getFeaturesByReferences: async (refs) => {
1292
+ const queryString = refs.map((r) => `featureReferences=${encodeURIComponent(r)}`).join("&");
1293
+ return requestJson(
1294
+ configuration,
1295
+ dependencies,
1296
+ `/v1/features/references?${queryString}`,
1297
+ { method: "GET" }
1298
+ );
1299
+ },
1300
+ getFeatureWorkItems: async (featureId) => requestJson(
1055
1301
  configuration,
1056
1302
  dependencies,
1057
- `/v1/portfolios/${portfolioId}/metrics/totalWorkItemAgeInfo?${getMetricsDateRangeQuery(r)}`,
1303
+ `/v1/features/${featureId}/workitems`,
1058
1304
  { method: "GET" }
1059
- );
1060
- },
1061
- getPortfolioWorkItemAgeOverTime: async (portfolioId, range) => {
1062
- const r = getResolvedMetricsDateRange(range);
1063
- const wipResult = await requestJson(
1305
+ ),
1306
+ listDeliveries: async (portfolioId) => requestJson(
1064
1307
  configuration,
1065
1308
  dependencies,
1066
- `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1309
+ `/v1/deliveries/portfolio/${portfolioId}`,
1067
1310
  { method: "GET" }
1068
- );
1069
- if (!wipResult.ok) {
1070
- return wipResult;
1071
- }
1072
- return {
1073
- ok: true,
1074
- value: deriveWorkItemAgeOverTime(r.startDate, r.endDate, wipResult.value)
1075
- };
1076
- },
1077
- getPortfolioTotalWorkItemAgeOverTime: async (portfolioId, range) => {
1078
- const r = getResolvedMetricsDateRange(range);
1079
- const wipResult = await requestJson(
1311
+ ),
1312
+ createDelivery: async (portfolioId, payload) => requestJson(
1080
1313
  configuration,
1081
1314
  dependencies,
1082
- `/v1/portfolios/${portfolioId}/metrics/wipOverTime?${getMetricsDateRangeQuery(r)}`,
1083
- { method: "GET" }
1084
- );
1085
- if (!wipResult.ok) {
1086
- return wipResult;
1087
- }
1088
- return {
1089
- ok: true,
1090
- value: deriveTotalWorkItemAgeOverTime(
1091
- r.startDate,
1092
- r.endDate,
1093
- wipResult.value
1094
- )
1095
- };
1096
- },
1097
- getFeaturesByIds: async (ids) => {
1098
- const queryString = ids.map((id) => `ids=${encodeURIComponent(id)}`).join("&");
1099
- return requestJson(
1315
+ `/v1/deliveries/portfolio/${portfolioId}`,
1316
+ { method: "POST", body: payload }
1317
+ ),
1318
+ updateDelivery: async (deliveryId, payload) => requestJson(
1100
1319
  configuration,
1101
1320
  dependencies,
1102
- `/v1/features?${queryString}`,
1103
- { method: "GET" }
1104
- );
1105
- },
1106
- getFeaturesByReferences: async (refs) => {
1107
- const queryString = refs.map((r) => `featureReferences=${encodeURIComponent(r)}`).join("&");
1108
- return requestJson(
1321
+ `/v1/deliveries/${deliveryId}`,
1322
+ { method: "PUT", body: payload }
1323
+ ),
1324
+ deleteDelivery: async (deliveryId) => requestNoContent(
1109
1325
  configuration,
1110
1326
  dependencies,
1111
- `/v1/features/references?${queryString}`,
1112
- { method: "GET" }
1113
- );
1114
- },
1115
- getFeatureWorkItems: async (featureId) => requestJson(
1116
- configuration,
1117
- dependencies,
1118
- `/v1/features/${featureId}/workitems`,
1119
- { method: "GET" }
1120
- ),
1121
- listDeliveries: async (portfolioId) => requestJson(
1122
- configuration,
1123
- dependencies,
1124
- `/v1/deliveries/portfolio/${portfolioId}`,
1125
- { method: "GET" }
1126
- ),
1127
- createDelivery: async (portfolioId, payload) => requestJson(
1128
- configuration,
1129
- dependencies,
1130
- `/v1/deliveries/portfolio/${portfolioId}`,
1131
- { method: "POST", body: payload }
1132
- ),
1133
- updateDelivery: async (deliveryId, payload) => requestJson(
1134
- configuration,
1135
- dependencies,
1136
- `/v1/deliveries/${deliveryId}`,
1137
- { method: "PUT", body: payload }
1138
- ),
1139
- deleteDelivery: async (deliveryId) => requestNoContent(
1140
- configuration,
1141
- dependencies,
1142
- `/v1/deliveries/${deliveryId}`,
1143
- { method: "DELETE" }
1144
- ),
1145
- runManualForecast: async (teamId, payload) => requestJson(
1146
- configuration,
1147
- dependencies,
1148
- `/v1/forecast/manual/${teamId}`,
1149
- { method: "POST", body: payload }
1150
- ),
1151
- runBacktest: async (teamId, payload) => requestJson(
1152
- configuration,
1153
- dependencies,
1154
- `/v1/forecast/backtest/${teamId}`,
1155
- { method: "POST", body: payload }
1156
- )
1157
- });
1327
+ `/v1/deliveries/${deliveryId}`,
1328
+ { method: "DELETE" }
1329
+ ),
1330
+ getRecurringBlackoutRules: async () => {
1331
+ const unsupported = await ensureServerSupports("recurringBlackoutRules");
1332
+ if (unsupported) {
1333
+ return unsupported;
1334
+ }
1335
+ return requestJson(
1336
+ configuration,
1337
+ dependencies,
1338
+ "/v1/recurring-blackout-rules",
1339
+ { method: "GET" }
1340
+ );
1341
+ },
1342
+ createRecurringBlackoutRule: async (payload) => {
1343
+ const unsupported = await ensureServerSupports("recurringBlackoutRules");
1344
+ if (unsupported) {
1345
+ return unsupported;
1346
+ }
1347
+ return requestJson(
1348
+ configuration,
1349
+ dependencies,
1350
+ "/v1/recurring-blackout-rules",
1351
+ { method: "POST", body: payload }
1352
+ );
1353
+ },
1354
+ updateRecurringBlackoutRule: async (id, payload) => {
1355
+ const unsupported = await ensureServerSupports("recurringBlackoutRules");
1356
+ if (unsupported) {
1357
+ return unsupported;
1358
+ }
1359
+ return requestJson(
1360
+ configuration,
1361
+ dependencies,
1362
+ `/v1/recurring-blackout-rules/${id}`,
1363
+ { method: "PUT", body: payload }
1364
+ );
1365
+ },
1366
+ deleteRecurringBlackoutRule: async (id) => {
1367
+ const unsupported = await ensureServerSupports("recurringBlackoutRules");
1368
+ if (unsupported) {
1369
+ return unsupported;
1370
+ }
1371
+ return requestNoContent(
1372
+ configuration,
1373
+ dependencies,
1374
+ `/v1/recurring-blackout-rules/${id}`,
1375
+ { method: "DELETE" }
1376
+ );
1377
+ },
1378
+ runManualForecast: async (teamId, payload) => requestJson(
1379
+ configuration,
1380
+ dependencies,
1381
+ `/v1/forecast/manual/${teamId}`,
1382
+ { method: "POST", body: payload }
1383
+ ),
1384
+ runBacktest: async (teamId, payload) => requestJson(
1385
+ configuration,
1386
+ dependencies,
1387
+ `/v1/forecast/backtest/${teamId}`,
1388
+ { method: "POST", body: payload }
1389
+ )
1390
+ };
1391
+ };
1158
1392
  // Annotate the CommonJS export names for ESM import in node:
1159
1393
  0 && (module.exports = {
1160
1394
  createLighthouseAuthContext,
@@ -1162,6 +1396,7 @@ var createLighthouseClient = (configuration, dependencies = {}) => ({
1162
1396
  getClientPackageContract,
1163
1397
  getDefaultMetricsDateRange,
1164
1398
  getStandaloneDiscoveryLockfilePath,
1399
+ isServerVersionNewerThan,
1165
1400
  loadStandaloneDiscoveryContract,
1166
1401
  parseStandaloneDiscoveryContract,
1167
1402
  pollCliAuthSession,