@hot-updater/console 1.0.0-rc.2 → 1.0.0-rc.20
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/.output/nitro.json +1 -1
- package/.output/public/assets/ConsoleFeatureUnavailable-B9VYGA3N.js +1 -0
- package/.output/public/assets/HashValueDisplay-D880zntR.js +1 -0
- package/.output/public/assets/InsightsInfo-By_sPjTE.js +1 -0
- package/.output/public/assets/InsightsPageHeader-9_kx_LL7.js +1 -0
- package/.output/public/assets/NotFoundPage-Dys8C0cW.js +1 -0
- package/.output/public/assets/api-CtarlV0l.js +1 -0
- package/.output/public/assets/api-keys-DFF_QqtN.js +1 -0
- package/.output/public/assets/api-keys-evfsQ4sN.js +1 -0
- package/.output/public/assets/arrow-left-BP9D-ta_.js +1 -0
- package/.output/public/assets/arrow-up-right-CDP9Tevw.js +1 -0
- package/.output/public/assets/card-DzCPSRsh.js +1 -0
- package/.output/public/assets/console-features-api-yv7rm3DX.js +1 -0
- package/.output/public/assets/dialog-BDvCy_QO.js +1 -0
- package/.output/public/assets/dist-Clb6cQ9l.js +1 -0
- package/.output/public/assets/empty-C5x9mn_s.js +1 -0
- package/.output/public/assets/field-Bou7shoO.js +1 -0
- package/.output/public/assets/index-0eg3l8aC.js +10 -0
- package/.output/public/assets/input-group-DVtWFUUF.js +1 -0
- package/.output/public/assets/insights-2MbdiSNv.js +1 -0
- package/.output/public/assets/insights-C6tmCZHk.js +2 -0
- package/.output/public/assets/insights-CadS_aIA.js +42 -0
- package/.output/public/assets/insights-recovery-rpc-wvdyM4LD.js +1 -0
- package/.output/public/assets/insights-search-KIF7mRtB.js +1 -0
- package/.output/public/assets/insights-usage-rpc-qUkNtrWr.js +1 -0
- package/.output/public/assets/insights_.distribution-BhBs6PNA.js +1 -0
- package/.output/public/assets/insights_.distribution-CItZw3-8.js +1 -0
- package/.output/public/assets/insights_.distribution-CJUH_wAS.js +2 -0
- package/.output/public/assets/installations-CH2H7JQt.js +2 -0
- package/.output/public/assets/installations-DMeMuwsW.js +1 -0
- package/.output/public/assets/installations-DnvxI9Dt.js +1 -0
- package/.output/public/assets/loader-circle-Ca7C9YY1.js +1 -0
- package/.output/public/assets/mutation-x9L28_CD.js +1 -0
- package/.output/public/assets/preload-helper-BN-UkjOE.js +1 -0
- package/.output/public/assets/refresh-cw-CVGqvy8Z.js +1 -0
- package/.output/public/assets/routes-BhK8DuZA.js +1 -0
- package/.output/public/assets/routes-veKtDW39.js +2 -0
- package/.output/public/assets/sidebar-B45aMqRm.js +3 -0
- package/.output/public/assets/styles-Dn0pK1EX.css +2 -0
- package/.output/public/assets/table-CwLnN6KX.js +1 -0
- package/.output/public/assets/useCompositeListItem-CF7vsfcA.js +1 -0
- package/.output/public/assets/useMutation-CN1ygYEr.js +1 -0
- package/.output/public/assets/useOpenInteractionType-AnAMWYIY.js +1 -0
- package/.output/public/assets/valueToPercent-C-t8FT0y.js +1 -0
- package/.output/server/{__23tanstack-start-server-fn-resolver-B7ioJhtE.mjs → __23tanstack-start-server-fn-resolver-CUQLz7hs.mjs} +52 -40
- package/.output/server/_libs/@base-ui/react+[...].mjs +7044 -3622
- package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +1554 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +49 -3
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +4 -4
- package/.output/server/_libs/d3-array.mjs +231 -0
- package/.output/server/_libs/d3-color.mjs +330 -0
- package/.output/server/_libs/d3-format.mjs +252 -0
- package/.output/server/_libs/d3-interpolate.mjs +207 -0
- package/.output/server/_libs/d3-path.mjs +77 -0
- package/.output/server/_libs/d3-scale+[...].mjs +1907 -0
- package/.output/server/_libs/d3-shape.mjs +818 -0
- package/.output/server/_libs/decimal.js-light.mjs +884 -0
- package/.output/server/_libs/es-toolkit.mjs +1159 -0
- package/.output/server/_libs/eventemitter3.mjs +236 -0
- package/.output/server/_libs/immer.mjs +532 -0
- package/.output/server/_libs/lucide-react.mjs +46 -32
- package/.output/server/_libs/next-themes.mjs +2 -2
- package/.output/server/_libs/react-redux+[...].mjs +205 -0
- package/.output/server/_libs/recharts+[...].mjs +14350 -0
- package/.output/server/_libs/sonner.mjs +2 -2
- package/.output/server/_libs/tanstack__react-query.mjs +8 -3
- package/.output/server/_libs/verkit.mjs +99 -1
- package/.output/server/_runtime.mjs +10 -1
- package/.output/server/_ssr/ConsoleFeatureUnavailable-DoxET2AT.mjs +58 -0
- package/.output/server/_ssr/{HashValueDisplay-DwpGLfrl.mjs → HashValueDisplay-BplboHEb.mjs} +3 -3
- package/.output/server/_ssr/InsightsInfo-o2YPd5Qc.mjs +37 -0
- package/.output/server/_ssr/InsightsPageHeader-NExCJL1I.mjs +154 -0
- package/.output/server/_ssr/NotFoundPage-Cd-A8ock.mjs +37 -0
- package/.output/server/_ssr/api-B1Ro0uys.mjs +202 -0
- package/.output/server/_ssr/api-C0G9MTMI.mjs +4205 -0
- package/.output/server/_ssr/{api-keys-CZeTPQys.mjs → api-keys-CT3HG7KT.mjs} +49 -9
- package/.output/server/_ssr/api-keys-Dvvy1sem.mjs +5 -0
- package/.output/server/_ssr/api-keys-rpc-b1qTTFfG.mjs +52 -0
- package/.output/server/_ssr/api-rpc-Cbns2MGx.mjs +338 -0
- package/.output/server/_ssr/{auth-rpc-DUaeOWKK.mjs → auth-rpc-DChS7m9y.mjs} +6 -6
- package/.output/server/_ssr/auth.server-Ccqz2iVv.mjs +37 -0
- package/.output/server/_ssr/bundleActivity-D17Pb_h5.mjs +19 -0
- package/.output/server/_ssr/card-DMbcvlPz.mjs +49 -0
- package/.output/server/_ssr/config-DMEJdhoW.mjs +13 -0
- package/.output/server/_ssr/config.server-DyypN6cQ.mjs +60 -0
- package/.output/server/_ssr/console-access-KpPv5lin.mjs +17 -0
- package/.output/server/_ssr/console-features-CsbyHYfK.mjs +55 -0
- package/.output/server/_ssr/console-features-api-B-KVuo4p.mjs +43 -0
- package/.output/server/_ssr/console-features-rpc-Djyo5740.mjs +19 -0
- package/.output/server/_ssr/{createServerFn-B2hcXoPM.mjs → createMiddleware-B_I3Ll4M.mjs} +28 -2
- package/.output/server/_ssr/{createServerRpc-DB29C_5p.mjs → createServerRpc-DuNm5mmo.mjs} +2 -2
- package/.output/server/_ssr/databaseRows-CXxf_VIB.mjs +132 -0
- package/.output/server/_ssr/{deleteBundle-BTGwBgzx.mjs → deleteBundle-Dcc21Lbd.mjs} +9 -19
- package/.output/server/_ssr/{dialog-DS-nw-pA.mjs → dialog-cOmLTUV2.mjs} +2 -2
- package/.output/server/_ssr/{dist-CyzPaI5v.mjs → dist-B-r4u3Lg.mjs} +28 -5
- package/.output/server/_ssr/{downloadBundle-CNnYxYO2.mjs → downloadBundle-CexOFoZ4.mjs} +6 -7
- package/.output/server/_ssr/empty-BHoY_5jt.mjs +49 -0
- package/.output/server/_ssr/{table-CnZmon_Z.mjs → field-mjhcNEXD.mjs} +63 -51
- package/.output/server/_ssr/getBundleChildren-DbDXe9wB.mjs +22 -0
- package/.output/server/_ssr/{input-group-BpsnmvZw.mjs → input-group-96H30HWC.mjs} +2 -2
- package/.output/server/_ssr/insights-D25VDVaz.mjs +5 -0
- package/.output/server/_ssr/insights-D359GJFL.mjs +14 -0
- package/.output/server/_ssr/insights-DgFv1NsO.mjs +1238 -0
- package/.output/server/_ssr/insights-api-ChAKrbhG.mjs +105 -0
- package/.output/server/_ssr/insights-failures-WQ-ttjOx.mjs +44 -0
- package/.output/server/_ssr/insights-failures-rpc-BFsqlltN.mjs +21 -0
- package/.output/server/_ssr/insights-recovery-DkL6bxMW.mjs +28 -0
- package/.output/server/_ssr/insights-recovery-rpc-2P5m8F62.mjs +46 -0
- package/.output/server/_ssr/insights-recovery-rpc-Tj8vNC19.mjs +20 -0
- package/.output/server/_ssr/{insights-rpc-38DujK0G.mjs → insights-rpc-DrkVmV9o.mjs} +22 -14
- package/.output/server/_ssr/insights-search-BsalnNw-.mjs +25 -0
- package/.output/server/_ssr/insights-usage-1nVTQrLy.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-Ct_4xHhZ.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-DaYIRtFK.mjs +41 -0
- package/.output/server/_ssr/insightsRecovery-CpGucWN1.mjs +45 -0
- package/.output/server/_ssr/insightsUsage-JYpKZAF7.mjs +56 -0
- package/.output/server/_ssr/insights_.distribution-Bcu6uYs_.mjs +5 -0
- package/.output/server/_ssr/insights_.distribution-D3Csuyjw.mjs +14 -0
- package/.output/server/_ssr/insights_.distribution-jQZEF07J.mjs +335 -0
- package/.output/server/_ssr/installations-B8Vh54lH.mjs +69 -0
- package/.output/server/_ssr/installations-BI5kelHv.mjs +5 -0
- package/.output/server/_ssr/{installations-DiVKEF5T.mjs → installations-Cxikllmx.mjs} +517 -54
- package/.output/server/_ssr/listReleases-DqU9t1l3.mjs +79 -0
- package/.output/server/_ssr/releaseManagement-B3e7I8J9.mjs +11 -0
- package/.output/server/_ssr/{router-B9wG_9f8.mjs → router-CRkm-wHD.mjs} +117 -124
- package/.output/server/_ssr/routes-B3IJo_jL.mjs +292 -0
- package/.output/server/_ssr/{routes-D7Yh_jfj.mjs → routes-CNAi0Mmv.mjs} +176 -455
- package/.output/server/_ssr/runtime.server-NucbYjc7.mjs +1372 -0
- package/.output/server/_ssr/select-BkPAJFL7.mjs +107 -0
- package/.output/server/_ssr/{server-D_C2rMzf.mjs → server-DKJYsaCP.mjs} +6 -32
- package/.output/server/_ssr/{createSsrRpc-DjWNJ0uc.mjs → sidebar-Cw1VuC7d.mjs} +117 -63
- package/.output/server/_ssr/ssr.mjs +1 -1
- package/.output/server/_ssr/table-q0P9wz7x.mjs +53 -0
- package/.output/server/_ssr/updateFailures-DMU9f0pK.mjs +24 -0
- package/.output/server/_ssr/{uuidv7-D0QFkPL_.mjs → uuidv7-BzSO-fr-.mjs} +2 -2
- package/.output/server/_tanstack-start-manifest_v-Bb0gKDbb.mjs +124 -0
- package/.output/server/index.mjs +273 -168
- package/README.md +71 -65
- package/lib/index.d.mts +13 -11
- package/lib/vite-internal.mjs +6 -3
- package/package.json +8 -8
- package/src/components/AppSidebar.tsx +91 -71
- package/src/components/ConsoleAccessPage.tsx +5 -1
- package/src/components/ConsoleFeatureUnavailable.tsx +82 -0
- package/src/components/NotFoundPage.tsx +7 -7
- package/src/components/features/FeatureSlots.tsx +99 -0
- package/src/components/features/api-keys/apiKeysFeatureUi.tsx +15 -0
- package/src/components/features/bundles/BundleMetadata.tsx +7 -4
- package/src/components/features/channels/ChannelManagementDialog.tsx +2 -5
- package/src/components/features/insights/AppUsage.tsx +370 -0
- package/src/components/features/insights/EstimatedCount.tsx +18 -0
- package/src/components/features/insights/EventDetails.tsx +117 -37
- package/src/components/features/insights/EventHistoryCard.tsx +112 -26
- package/src/components/features/insights/EventHistoryList.tsx +2 -2
- package/src/components/features/insights/InsightsControls.tsx +265 -102
- package/src/components/features/insights/InsightsErrorAlert.tsx +14 -1
- package/src/components/features/insights/InsightsInfo.tsx +48 -0
- package/src/components/features/insights/InsightsOverview.tsx +176 -173
- package/src/components/features/insights/InsightsPageHeader.tsx +35 -20
- package/src/components/features/insights/InsightsPeriodSelector.tsx +89 -0
- package/src/components/features/insights/InstallationHistoryCard.tsx +52 -10
- package/src/components/features/insights/InstallationMatchesCard.tsx +1 -1
- package/src/components/features/insights/ReleaseActivity.tsx +188 -0
- package/src/components/features/insights/ReportingDevicesSummary.tsx +65 -0
- package/src/components/features/insights/UpdateFailures.tsx +319 -0
- package/src/components/features/insights/insightsFeatureUi.tsx +35 -0
- package/src/components/features/releases/ReleaseEditorSheet.tsx +24 -1
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/empty.tsx +101 -0
- package/src/components/ui/scroll-area.tsx +52 -0
- package/src/components/ui/sidebar.tsx +22 -29
- package/src/components/ui/tabs.tsx +81 -0
- package/src/index.ts +12 -17
- package/src/lib/api-keys-api.ts +0 -28
- package/src/lib/api-keys-rpc.ts +27 -38
- package/src/lib/api-rpc.ts +197 -221
- package/src/lib/api.ts +11 -13
- package/src/lib/bundle-activity.ts +31 -0
- package/src/lib/console-access.ts +20 -0
- package/src/lib/console-features-api.ts +68 -0
- package/src/lib/console-features-rpc.ts +13 -0
- package/src/lib/console-features.ts +91 -0
- package/src/lib/insights-api.ts +37 -1
- package/src/lib/insights-failures-rpc.ts +21 -0
- package/src/lib/insights-failures.ts +129 -0
- package/src/lib/insights-recovery-rpc.ts +51 -0
- package/src/lib/insights-recovery.ts +68 -0
- package/src/lib/insights-retention.ts +21 -0
- package/src/lib/insights-rpc.ts +30 -12
- package/src/lib/insights-search.ts +58 -0
- package/src/lib/insights-usage-rpc.ts +29 -0
- package/src/lib/insights-usage.ts +74 -0
- package/src/lib/insights-view.ts +38 -2
- package/src/lib/scroll-restoration.ts +21 -0
- package/src/lib/server/adminInsights.ts +124 -0
- package/src/lib/server/auth.server.ts +13 -5
- package/src/lib/server/bundleActivity.ts +37 -0
- package/src/lib/server/config.server.ts +16 -32
- package/src/lib/server/console-feature-apis.ts +59 -0
- package/src/lib/server/console-runtime.server.ts +6 -40
- package/src/lib/server/deleteBundle.ts +16 -25
- package/src/lib/server/downloadBundle.ts +7 -10
- package/src/lib/server/getBundleChildren.ts +31 -122
- package/src/lib/server/insightsRecovery.ts +55 -0
- package/src/lib/server/insightsUsage.ts +63 -0
- package/src/lib/server/listReleases.ts +109 -44
- package/src/lib/server/releaseReachability.ts +4 -3
- package/src/lib/server/runtime.server.ts +132 -31
- package/src/lib/server/updateFailures.ts +31 -0
- package/src/routeTree.gen.ts +21 -21
- package/src/router.tsx +3 -2
- package/src/routes/-installations-search.ts +32 -8
- package/src/routes/-releases-search.ts +76 -29
- package/src/routes/__root.tsx +10 -4
- package/src/routes/api/bundles/$bundleId/download.ts +2 -5
- package/src/routes/api-keys.tsx +5 -2
- package/src/routes/index.tsx +167 -104
- package/src/routes/insights.tsx +100 -59
- package/src/routes/insights_.distribution.tsx +398 -0
- package/src/routes/installations.tsx +98 -41
- package/src/vite-internal.ts +6 -3
- package/.output/public/assets/HashValueDisplay-CB0Eskit.js +0 -1
- package/.output/public/assets/InsightsPageHeader-Car5LNiZ.js +0 -1
- package/.output/public/assets/api-keys-BzKocqRy.js +0 -1
- package/.output/public/assets/api-keys-api-BHcODB7q.js +0 -1
- package/.output/public/assets/card-Dhr_eFYj.js +0 -1
- package/.output/public/assets/chart-no-axes-combined-Dy4WJv2U.js +0 -1
- package/.output/public/assets/composite-Bp98A0Ld.js +0 -1
- package/.output/public/assets/createServerFn-CA8fs7QD.js +0 -3
- package/.output/public/assets/dialog-CUTrcPlB.js +0 -1
- package/.output/public/assets/dist-C_NydL0e.js +0 -1
- package/.output/public/assets/index-DdAz-CXv.js +0 -10
- package/.output/public/assets/input-group-cSOG4wh_.js +0 -1
- package/.output/public/assets/insights-C0PBSZ-n.js +0 -1
- package/.output/public/assets/installations-CE33wgbY.js +0 -2
- package/.output/public/assets/installations-CStZja8x.js +0 -1
- package/.output/public/assets/lazyRouteComponent-Ccp3bwBY.js +0 -1
- package/.output/public/assets/link-CI8idAUi.js +0 -1
- package/.output/public/assets/loader-circle-BoxLrsOu.js +0 -1
- package/.output/public/assets/preload-helper-CQ36nxok.js +0 -1
- package/.output/public/assets/refresh-cw-Bqc72UZG.js +0 -1
- package/.output/public/assets/routes-DGVXdzpw.js +0 -2
- package/.output/public/assets/routes-DTlwOr8I.js +0 -1
- package/.output/public/assets/shield-check-uK3MHWJZ.js +0 -1
- package/.output/public/assets/signing-CMf4aqDO.js +0 -1
- package/.output/public/assets/styles-BCvbtKsm.css +0 -2
- package/.output/public/assets/table-2vcV89QB.js +0 -1
- package/.output/public/assets/useCompositeListItem-CHLITE_4.js +0 -1
- package/.output/public/assets/x-DCd0j8c6.js +0 -1
- package/.output/server/_ssr/InsightsPageHeader-Df4Brj8u.mjs +0 -484
- package/.output/server/_ssr/api-keys-api-BUPQVSpk.mjs +0 -60
- package/.output/server/_ssr/api-keys-rpc-Cs7tS5_j.mjs +0 -136
- package/.output/server/_ssr/api-rpc-tAupfGQm.mjs +0 -1399
- package/.output/server/_ssr/auth.server-DW71WzsD.mjs +0 -47
- package/.output/server/_ssr/bundle-signing-rpc-BhnBw0-d.mjs +0 -16
- package/.output/server/_ssr/bundle-signing.server-C4NW5mWx.mjs +0 -12
- package/.output/server/_ssr/card-BRiPmi0C.mjs +0 -108
- package/.output/server/_ssr/config-Dv8qLDZ0.mjs +0 -13
- package/.output/server/_ssr/config.server-afDuAwaG.mjs +0 -368
- package/.output/server/_ssr/databaseJsonValue-d6I3nAS4.mjs +0 -45
- package/.output/server/_ssr/databaseRows-5bCRTxm-.mjs +0 -126
- package/.output/server/_ssr/getBundleChildren-C0vh4ZvE.mjs +0 -50
- package/.output/server/_ssr/insights-BdS364Xu.mjs +0 -460
- package/.output/server/_ssr/insightsContract-fjJDBeEE.mjs +0 -303
- package/.output/server/_ssr/installations-CtA59MQG.mjs +0 -29
- package/.output/server/_ssr/routes-CKrrS2q2.mjs +0 -37
- package/.output/server/_ssr/runtime.server-DacU1TBV.mjs +0 -438
- package/.output/server/_ssr/signing-Dz1WkZOf.mjs +0 -133
- package/.output/server/_tanstack-start-manifest_v-2MjTyxil.mjs +0 -97
- package/src/components/features/insights/InsightsBundleReports.tsx +0 -51
- package/src/components/features/signing/BundleSigningPage.tsx +0 -139
- package/src/lib/bundle-signing-api.ts +0 -14
- package/src/lib/bundle-signing-rpc.ts +0 -16
- package/src/lib/server/bundle-signing.server.ts +0 -23
- package/src/routes/signing.tsx +0 -37
package/src/lib/api-rpc.ts
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
type ChannelInsertInput,
|
|
6
|
-
type DatabaseBundleQueryOptions,
|
|
7
|
-
deleteRelease as deleteReleaseMutation,
|
|
8
|
-
preflightReleasePolicy,
|
|
9
|
-
promoteRelease as promoteReleaseMutation,
|
|
2
|
+
type ChannelDeleteResult,
|
|
3
|
+
type ChannelRow,
|
|
4
|
+
type ReleaseFilter,
|
|
10
5
|
type ReleasePolicyPatch,
|
|
11
|
-
|
|
6
|
+
rowToBundle,
|
|
12
7
|
} from "@hot-updater/plugin-core";
|
|
13
8
|
import { createServerFn } from "@tanstack/react-start";
|
|
14
9
|
|
|
10
|
+
import { consoleAccess } from "./console-access";
|
|
15
11
|
import { DEFAULT_PAGE_LIMIT } from "./constants";
|
|
16
12
|
import { withPublicBundleMutationErrors } from "./public-bundle-error";
|
|
17
|
-
import { listReleases } from "./server/listReleases";
|
|
13
|
+
import { listReleases, readReleaseFilter } from "./server/listReleases";
|
|
18
14
|
import { addReleaseReachability } from "./server/releaseReachability";
|
|
19
15
|
|
|
20
16
|
type GetBundlesInput = {
|
|
21
17
|
platform?: "ios" | "android";
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
limit?: number;
|
|
19
|
+
/** Bundles older than this id: the next page. */
|
|
24
20
|
after?: string;
|
|
21
|
+
/** Bundles newer than this id: the previous page. */
|
|
25
22
|
before?: string;
|
|
26
23
|
};
|
|
27
24
|
|
|
@@ -46,15 +43,13 @@ type DeleteBundlesInput = {
|
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
type GetReleasesInput = {
|
|
49
|
-
|
|
46
|
+
/** One of the filter sets the release indexes serve. */
|
|
47
|
+
filter?: ReleaseFilter;
|
|
48
|
+
/** Releases older than this id: the next page. */
|
|
50
49
|
beforeReleaseId?: string;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
enabled?: boolean;
|
|
54
|
-
platform?: "ios" | "android";
|
|
50
|
+
/** Releases newer than this id: the previous page. */
|
|
51
|
+
afterReleaseId?: string;
|
|
55
52
|
limit?: number;
|
|
56
|
-
page?: number;
|
|
57
|
-
targetAppVersion?: string;
|
|
58
53
|
};
|
|
59
54
|
|
|
60
55
|
type ReleaseMutationInput = {
|
|
@@ -68,78 +63,78 @@ type DeleteReleaseInput = {
|
|
|
68
63
|
releaseId: string;
|
|
69
64
|
};
|
|
70
65
|
|
|
66
|
+
const MAX_PAGE_LIMIT = 100;
|
|
67
|
+
|
|
68
|
+
const pageLimit = (limit: number | undefined) => {
|
|
69
|
+
const value = limit ?? DEFAULT_PAGE_LIMIT;
|
|
70
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_PAGE_LIMIT) {
|
|
71
|
+
throw new Error(`limit must be between 1 and ${MAX_PAGE_LIMIT}.`);
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const prepare = async () => {
|
|
77
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
78
|
+
return prepareConfig();
|
|
79
|
+
};
|
|
80
|
+
|
|
71
81
|
export const getReleases = createServerFn({ method: "GET" })
|
|
72
|
-
.
|
|
82
|
+
.middleware([consoleAccess])
|
|
83
|
+
.validator((input: GetReleasesInput | undefined) => ({
|
|
84
|
+
filter: readReleaseFilter(input?.filter),
|
|
85
|
+
...(input?.afterReleaseId === undefined
|
|
86
|
+
? {}
|
|
87
|
+
: { afterReleaseId: input.afterReleaseId }),
|
|
88
|
+
...(input?.beforeReleaseId === undefined
|
|
89
|
+
? {}
|
|
90
|
+
: { beforeReleaseId: input.beforeReleaseId }),
|
|
91
|
+
limit: pageLimit(input?.limit),
|
|
92
|
+
}))
|
|
73
93
|
.handler(async ({ data }) => {
|
|
74
|
-
const {
|
|
75
|
-
const
|
|
76
|
-
const result = await listReleases(config.database.models.releases, {
|
|
77
|
-
...(data?.afterReleaseId === undefined
|
|
78
|
-
? {}
|
|
79
|
-
: { afterReleaseId: data.afterReleaseId }),
|
|
80
|
-
...(data?.beforeReleaseId === undefined
|
|
81
|
-
? {}
|
|
82
|
-
: { beforeReleaseId: data.beforeReleaseId }),
|
|
83
|
-
...(data?.bundleId === undefined ? {} : { bundleId: data.bundleId }),
|
|
84
|
-
...(data?.channelId === undefined ? {} : { channelId: data.channelId }),
|
|
85
|
-
...(data?.enabled === undefined ? {} : { enabled: data.enabled }),
|
|
86
|
-
...(data?.page === undefined ? {} : { page: data.page }),
|
|
87
|
-
...(data?.platform === undefined ? {} : { platform: data.platform }),
|
|
88
|
-
...(data?.targetAppVersion === undefined
|
|
89
|
-
? {}
|
|
90
|
-
: { targetAppVersion: data.targetAppVersion }),
|
|
91
|
-
limit: data?.limit ?? DEFAULT_PAGE_LIMIT,
|
|
92
|
-
});
|
|
93
|
-
const releases = await addReleaseReachability(
|
|
94
|
-
config.database.models.releaseCatalogs,
|
|
95
|
-
result.data,
|
|
96
|
-
);
|
|
94
|
+
const { core } = await prepare();
|
|
95
|
+
const result = await listReleases(core, data);
|
|
97
96
|
return {
|
|
98
97
|
...result,
|
|
99
|
-
data:
|
|
98
|
+
data: await addReleaseReachability(core, result.data),
|
|
100
99
|
};
|
|
101
100
|
});
|
|
102
101
|
|
|
103
102
|
export const getRelease = createServerFn({ method: "GET" })
|
|
104
|
-
.
|
|
105
|
-
.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
103
|
+
.middleware([consoleAccess])
|
|
104
|
+
.validator((input: { releaseId: string }) => input)
|
|
105
|
+
.handler(async ({ data }) =>
|
|
106
|
+
(await prepare()).core.getRelease(data.releaseId),
|
|
107
|
+
);
|
|
110
108
|
|
|
111
109
|
export const updateRelease = createServerFn({ method: "POST" })
|
|
112
|
-
.
|
|
110
|
+
.middleware([consoleAccess])
|
|
111
|
+
.validator((input: ReleaseMutationInput) => input)
|
|
113
112
|
.handler(async ({ data }) => {
|
|
114
|
-
const {
|
|
115
|
-
|
|
116
|
-
return withPublicBundleMutationErrors(() =>
|
|
117
|
-
updateReleasePolicy({ database: config.database, ...data }),
|
|
118
|
-
);
|
|
113
|
+
const { core } = await prepare();
|
|
114
|
+
return withPublicBundleMutationErrors(() => core.updateReleasePolicy(data));
|
|
119
115
|
});
|
|
120
116
|
|
|
121
117
|
export const preflightRelease = createServerFn({ method: "POST" })
|
|
122
|
-
.
|
|
118
|
+
.middleware([consoleAccess])
|
|
119
|
+
.validator((input: ReleaseMutationInput) => input)
|
|
123
120
|
.handler(async ({ data }) => {
|
|
124
|
-
const {
|
|
125
|
-
const { config } = await prepareConfig();
|
|
121
|
+
const { core } = await prepare();
|
|
126
122
|
return withPublicBundleMutationErrors(() =>
|
|
127
|
-
preflightReleasePolicy(
|
|
123
|
+
core.preflightReleasePolicy(data),
|
|
128
124
|
);
|
|
129
125
|
});
|
|
130
126
|
|
|
131
127
|
export const deleteRelease = createServerFn({ method: "POST" })
|
|
132
|
-
.
|
|
128
|
+
.middleware([consoleAccess])
|
|
129
|
+
.validator((input: DeleteReleaseInput) => input)
|
|
133
130
|
.handler(async ({ data }) => {
|
|
134
|
-
const {
|
|
135
|
-
|
|
136
|
-
return withPublicBundleMutationErrors(() =>
|
|
137
|
-
deleteReleaseMutation({ database: config.database, ...data }),
|
|
138
|
-
);
|
|
131
|
+
const { core } = await prepare();
|
|
132
|
+
return withPublicBundleMutationErrors(() => core.deleteRelease(data));
|
|
139
133
|
});
|
|
140
134
|
|
|
141
135
|
export const promoteRelease = createServerFn({ method: "POST" })
|
|
142
|
-
.
|
|
136
|
+
.middleware([consoleAccess])
|
|
137
|
+
.validator(
|
|
143
138
|
(input: {
|
|
144
139
|
action: "copy" | "move";
|
|
145
140
|
expectedRevision?: number;
|
|
@@ -148,54 +143,60 @@ export const promoteRelease = createServerFn({ method: "POST" })
|
|
|
148
143
|
}) => input,
|
|
149
144
|
)
|
|
150
145
|
.handler(async ({ data }) => {
|
|
151
|
-
const {
|
|
152
|
-
|
|
153
|
-
return withPublicBundleMutationErrors(() =>
|
|
154
|
-
promoteReleaseMutation({ database: config.database, ...data }),
|
|
155
|
-
);
|
|
146
|
+
const { core } = await prepare();
|
|
147
|
+
return withPublicBundleMutationErrors(() => core.promoteRelease(data));
|
|
156
148
|
});
|
|
157
149
|
|
|
158
150
|
export const getReleaseCatalogDiagnostics = createServerFn({ method: "GET" })
|
|
159
|
-
.
|
|
160
|
-
.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
151
|
+
.middleware([consoleAccess])
|
|
152
|
+
.validator((input: { scopeKey: string }) => input)
|
|
153
|
+
.handler(async ({ data }) =>
|
|
154
|
+
(await prepare()).core.getReleaseCatalogRow(data.scopeKey),
|
|
155
|
+
);
|
|
165
156
|
|
|
166
157
|
// GET /api/config
|
|
167
|
-
export const getConfig = createServerFn()
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
158
|
+
export const getConfig = createServerFn()
|
|
159
|
+
.middleware([consoleAccess])
|
|
160
|
+
.handler(async () => {
|
|
161
|
+
try {
|
|
162
|
+
const { config } = await prepare();
|
|
163
|
+
return { console: config.console };
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error("Error during config retrieval:", error);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
177
169
|
|
|
178
170
|
// GET /api/channels
|
|
179
|
-
export const getChannels = createServerFn()
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
});
|
|
171
|
+
export const getChannels = createServerFn()
|
|
172
|
+
.middleware([consoleAccess])
|
|
173
|
+
.handler(async (): Promise<ChannelRow[]> => {
|
|
174
|
+
try {
|
|
175
|
+
return await (await prepare()).core.listChannels();
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error("Error during channel retrieval:", error);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
190
181
|
|
|
191
182
|
// POST /api/channels
|
|
192
183
|
export const createChannel = createServerFn({ method: "POST" })
|
|
193
|
-
.
|
|
184
|
+
.middleware([consoleAccess])
|
|
185
|
+
.validator((input: { name: string }) => {
|
|
186
|
+
const name = typeof input?.name === "string" ? input.name.trim() : "";
|
|
187
|
+
if (name.length === 0) throw new Error("Channel name is required.");
|
|
188
|
+
return { name };
|
|
189
|
+
})
|
|
194
190
|
.handler(async ({ data }) => {
|
|
195
191
|
try {
|
|
196
|
-
const {
|
|
197
|
-
const
|
|
198
|
-
|
|
192
|
+
const { core } = await prepare();
|
|
193
|
+
const existing = await core.findChannelByName(data.name);
|
|
194
|
+
if (existing !== null) {
|
|
195
|
+
return { data: { row: existing, inserted: false } };
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
data: { row: await core.ensureChannel(data.name), inserted: true },
|
|
199
|
+
};
|
|
199
200
|
} catch (error) {
|
|
200
201
|
console.error("Error during channel creation:", error);
|
|
201
202
|
throw error;
|
|
@@ -204,12 +205,11 @@ export const createChannel = createServerFn({ method: "POST" })
|
|
|
204
205
|
|
|
205
206
|
// DELETE /api/channels/:id
|
|
206
207
|
export const deleteChannel = createServerFn({ method: "POST" })
|
|
207
|
-
.
|
|
208
|
-
.
|
|
208
|
+
.middleware([consoleAccess])
|
|
209
|
+
.validator((input: { id: string }) => input)
|
|
210
|
+
.handler(async ({ data }): Promise<{ data: ChannelDeleteResult }> => {
|
|
209
211
|
try {
|
|
210
|
-
|
|
211
|
-
const { databaseClient } = await prepareConfig();
|
|
212
|
-
return { data: await databaseClient.deleteChannel(data) };
|
|
212
|
+
return { data: await (await prepare()).core.deleteChannel(data.id) };
|
|
213
213
|
} catch (error) {
|
|
214
214
|
console.error("Error during channel deletion:", error);
|
|
215
215
|
throw error;
|
|
@@ -217,78 +217,71 @@ export const deleteChannel = createServerFn({ method: "POST" })
|
|
|
217
217
|
});
|
|
218
218
|
|
|
219
219
|
// GET /api/config-loaded
|
|
220
|
-
export const getConfigLoaded = createServerFn()
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
import("./server/
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
throw error;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
220
|
+
export const getConfigLoaded = createServerFn()
|
|
221
|
+
.middleware([consoleAccess])
|
|
222
|
+
.handler(async () => {
|
|
223
|
+
try {
|
|
224
|
+
const { isConfigLoaded } = await import("./server/config.server");
|
|
225
|
+
const configLoaded = isConfigLoaded();
|
|
226
|
+
return { configLoaded };
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error("Error during config loaded retrieval:", error);
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
235
232
|
|
|
236
|
-
// GET /api/bundles
|
|
233
|
+
// GET /api/bundles: newest first, one page by key; the total is one counter row.
|
|
237
234
|
export const getBundles = createServerFn({ method: "GET" })
|
|
238
|
-
.
|
|
235
|
+
.middleware([consoleAccess])
|
|
236
|
+
.validator((input: GetBundlesInput | undefined) => {
|
|
237
|
+
if (input?.after !== undefined && input.before !== undefined) {
|
|
238
|
+
throw new Error("Page by after or before, not both.");
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
...(input?.platform === undefined ? {} : { platform: input.platform }),
|
|
242
|
+
...(input?.after === undefined ? {} : { after: input.after }),
|
|
243
|
+
...(input?.before === undefined ? {} : { before: input.before }),
|
|
244
|
+
limit: pageLimit(input?.limit),
|
|
245
|
+
};
|
|
246
|
+
})
|
|
239
247
|
.handler(async ({ data }) => {
|
|
240
248
|
try {
|
|
241
|
-
const {
|
|
242
|
-
const
|
|
243
|
-
platform: data
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
const { core } = await prepare();
|
|
250
|
+
const platform =
|
|
251
|
+
data.platform === undefined ? {} : { platform: data.platform };
|
|
252
|
+
const [page, total] = await Promise.all([
|
|
253
|
+
data.before === undefined
|
|
254
|
+
? core.listBundles({
|
|
255
|
+
...platform,
|
|
256
|
+
order: "desc",
|
|
257
|
+
limit: data.limit,
|
|
258
|
+
...(data.after === undefined ? {} : { after: data.after }),
|
|
259
|
+
})
|
|
260
|
+
: core
|
|
261
|
+
.listBundles({
|
|
262
|
+
...platform,
|
|
263
|
+
order: "asc",
|
|
264
|
+
limit: data.limit,
|
|
265
|
+
after: data.before,
|
|
266
|
+
})
|
|
267
|
+
.then((rows) => rows.reverse()),
|
|
268
|
+
core.countBundles(data.platform),
|
|
269
|
+
]);
|
|
270
|
+
const full = page.length === data.limit;
|
|
271
|
+
const first = page[0]?.bundle.id;
|
|
272
|
+
const last = page.at(-1)?.bundle.id;
|
|
273
|
+
return {
|
|
274
|
+
data: page.map(({ bundle, patches }) => rowToBundle(bundle, patches)),
|
|
275
|
+
total,
|
|
276
|
+
// A full page may have more past it; a short one ended the range.
|
|
277
|
+
...(last !== undefined && (data.before !== undefined || full)
|
|
278
|
+
? { next: last }
|
|
279
|
+
: {}),
|
|
280
|
+
...(first !== undefined &&
|
|
281
|
+
(data.after !== undefined || (data.before !== undefined && full))
|
|
282
|
+
? { previous: first }
|
|
283
|
+
: {}),
|
|
253
284
|
};
|
|
254
|
-
if (
|
|
255
|
-
(query.after !== undefined && query.before !== undefined) ||
|
|
256
|
-
(query.page !== undefined &&
|
|
257
|
-
(query.after !== undefined || query.before !== undefined))
|
|
258
|
-
) {
|
|
259
|
-
throw new DatabasePluginInputError("invalid-pagination");
|
|
260
|
-
}
|
|
261
|
-
const pagination =
|
|
262
|
-
query.page !== undefined
|
|
263
|
-
? { page: query.page }
|
|
264
|
-
: query.after !== undefined
|
|
265
|
-
? { cursor: { after: query.after } }
|
|
266
|
-
: query.before !== undefined
|
|
267
|
-
? { cursor: { before: query.before } }
|
|
268
|
-
: {};
|
|
269
|
-
|
|
270
|
-
const { databaseClient } = await prepareConfig();
|
|
271
|
-
const bundleQueryOptions: DatabaseBundleQueryOptions = {
|
|
272
|
-
where: {
|
|
273
|
-
platform: query.platform,
|
|
274
|
-
},
|
|
275
|
-
limit: query.limit,
|
|
276
|
-
...pagination,
|
|
277
|
-
};
|
|
278
|
-
const bundles = await databaseClient.getBundles(bundleQueryOptions);
|
|
279
|
-
|
|
280
|
-
return (
|
|
281
|
-
bundles ?? {
|
|
282
|
-
data: [],
|
|
283
|
-
pagination: {
|
|
284
|
-
total: 0,
|
|
285
|
-
hasNextPage: false,
|
|
286
|
-
hasPreviousPage: false,
|
|
287
|
-
currentPage: 1,
|
|
288
|
-
totalPages: 0,
|
|
289
|
-
},
|
|
290
|
-
}
|
|
291
|
-
);
|
|
292
285
|
} catch (error) {
|
|
293
286
|
console.error("Error during bundle retrieval:", error);
|
|
294
287
|
throw error;
|
|
@@ -297,13 +290,14 @@ export const getBundles = createServerFn({ method: "GET" })
|
|
|
297
290
|
|
|
298
291
|
// GET /api/bundles/:bundleId
|
|
299
292
|
export const getBundle = createServerFn({ method: "GET" })
|
|
300
|
-
.
|
|
293
|
+
.middleware([consoleAccess])
|
|
294
|
+
.validator((input: GetBundleInput) => input)
|
|
301
295
|
.handler(async ({ data }) => {
|
|
302
296
|
try {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
const detail = await (await prepare()).core.getBundle(data.bundleId);
|
|
298
|
+
return detail === null
|
|
299
|
+
? null
|
|
300
|
+
: rowToBundle(detail.bundle, detail.patches);
|
|
307
301
|
} catch (error) {
|
|
308
302
|
console.error("Error during bundle retrieval:", error);
|
|
309
303
|
throw error;
|
|
@@ -311,17 +305,13 @@ export const getBundle = createServerFn({ method: "GET" })
|
|
|
311
305
|
});
|
|
312
306
|
|
|
313
307
|
export const getBundleChildren = createServerFn({ method: "GET" })
|
|
314
|
-
.
|
|
308
|
+
.middleware([consoleAccess])
|
|
309
|
+
.validator((input: GetBundleChildrenInput) => input)
|
|
315
310
|
.handler(async ({ data }) => {
|
|
316
311
|
try {
|
|
317
|
-
const {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const { databaseClient } = await prepareConfig();
|
|
321
|
-
|
|
322
|
-
return await getBundleChildrenWithConfig(data, {
|
|
323
|
-
databaseClient,
|
|
324
|
-
});
|
|
312
|
+
const [{ core }, { getBundleChildren: readBundleChildren }] =
|
|
313
|
+
await Promise.all([prepare(), import("./server/getBundleChildren")]);
|
|
314
|
+
return await readBundleChildren(core, data.baseBundleId);
|
|
325
315
|
} catch (error) {
|
|
326
316
|
console.error("Error during bundle children retrieval:", error);
|
|
327
317
|
throw error;
|
|
@@ -329,50 +319,36 @@ export const getBundleChildren = createServerFn({ method: "GET" })
|
|
|
329
319
|
});
|
|
330
320
|
|
|
331
321
|
export const getBundleChildCounts = createServerFn({ method: "GET" })
|
|
332
|
-
.
|
|
333
|
-
.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const { getBundleChildCounts: getBundleChildCountsWithConfig } =
|
|
337
|
-
await import("./server/getBundleChildren");
|
|
338
|
-
const { databaseClient } = await prepareConfig();
|
|
339
|
-
|
|
340
|
-
return await getBundleChildCountsWithConfig(data.bundleIds, {
|
|
341
|
-
databaseClient,
|
|
342
|
-
});
|
|
343
|
-
} catch (error) {
|
|
344
|
-
console.error("Error during bundle child count retrieval:", error);
|
|
345
|
-
throw error;
|
|
322
|
+
.middleware([consoleAccess])
|
|
323
|
+
.validator((input: GetBundleChildCountsInput) => {
|
|
324
|
+
if (!Array.isArray(input?.bundleIds) || input.bundleIds.length > 100) {
|
|
325
|
+
throw new Error("Choose up to 100 bundles.");
|
|
346
326
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// POST /api/bundles
|
|
350
|
-
export const createBundle = createServerFn({ method: "POST" })
|
|
351
|
-
.inputValidator((input: Bundle) => input)
|
|
327
|
+
return input;
|
|
328
|
+
})
|
|
352
329
|
.handler(async ({ data }) => {
|
|
353
330
|
try {
|
|
354
|
-
const {
|
|
355
|
-
|
|
356
|
-
await
|
|
357
|
-
return { success: true, bundleId: data.id };
|
|
331
|
+
const [{ core }, { getBundleChildCounts: readBundleChildCounts }] =
|
|
332
|
+
await Promise.all([prepare(), import("./server/getBundleChildren")]);
|
|
333
|
+
return await readBundleChildCounts(core, data.bundleIds);
|
|
358
334
|
} catch (error) {
|
|
359
|
-
console.error("Error during bundle
|
|
335
|
+
console.error("Error during bundle child count retrieval:", error);
|
|
360
336
|
throw error;
|
|
361
337
|
}
|
|
362
338
|
});
|
|
363
339
|
|
|
364
340
|
// DELETE /api/bundles/:bundleId
|
|
365
341
|
export const deleteBundle = createServerFn({ method: "POST" })
|
|
366
|
-
.
|
|
342
|
+
.middleware([consoleAccess])
|
|
343
|
+
.validator((input: DeleteBundleInput) => input)
|
|
367
344
|
.handler(async ({ data }) => {
|
|
368
345
|
try {
|
|
369
|
-
const { prepareConfig } = await import("./server/config.server");
|
|
370
346
|
const { deleteBundle: deleteBundleWithStorage } =
|
|
371
347
|
await import("./server/deleteBundle");
|
|
372
|
-
const {
|
|
348
|
+
const { core, storagePlugin } = await prepare();
|
|
373
349
|
|
|
374
350
|
await deleteBundleWithStorage(data, {
|
|
375
|
-
|
|
351
|
+
core,
|
|
376
352
|
storagePlugin,
|
|
377
353
|
waitForStorageCleanup: false,
|
|
378
354
|
});
|
|
@@ -385,16 +361,16 @@ export const deleteBundle = createServerFn({ method: "POST" })
|
|
|
385
361
|
});
|
|
386
362
|
|
|
387
363
|
export const deleteBundles = createServerFn({ method: "POST" })
|
|
388
|
-
.
|
|
364
|
+
.middleware([consoleAccess])
|
|
365
|
+
.validator((input: DeleteBundlesInput) => input)
|
|
389
366
|
.handler(async ({ data }) => {
|
|
390
367
|
try {
|
|
391
|
-
const { prepareConfig } = await import("./server/config.server");
|
|
392
368
|
const { deleteBundles: deleteBundlesWithStorage } =
|
|
393
369
|
await import("./server/deleteBundle");
|
|
394
|
-
const {
|
|
370
|
+
const { core, storagePlugin } = await prepare();
|
|
395
371
|
|
|
396
372
|
const result = await deleteBundlesWithStorage(data, {
|
|
397
|
-
|
|
373
|
+
core,
|
|
398
374
|
storagePlugin,
|
|
399
375
|
waitForStorageCleanup: false,
|
|
400
376
|
});
|
package/src/lib/api.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
ChannelInsertInput,
|
|
2
|
+
ReleaseFilter,
|
|
4
3
|
ReleasePolicyPatch,
|
|
5
4
|
} from "@hot-updater/plugin-core";
|
|
6
5
|
import {
|
|
@@ -34,9 +33,10 @@ import {
|
|
|
34
33
|
|
|
35
34
|
type BundleFilters = {
|
|
36
35
|
platform?: "ios" | "android";
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
limit?: number;
|
|
37
|
+
/** Bundles older than this id: the next page. */
|
|
39
38
|
after?: string;
|
|
39
|
+
/** Bundles newer than this id: the previous page. */
|
|
40
40
|
before?: string;
|
|
41
41
|
};
|
|
42
42
|
|
|
@@ -71,15 +71,13 @@ export const queryKeys = {
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
export type ReleaseFilters = {
|
|
74
|
-
|
|
74
|
+
/** One of the filter sets the release indexes serve; none lists every release. */
|
|
75
|
+
filter?: ReleaseFilter;
|
|
76
|
+
/** Releases older than this id: the next page. */
|
|
75
77
|
beforeReleaseId?: string;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
enabled?: boolean;
|
|
79
|
-
platform?: "ios" | "android";
|
|
78
|
+
/** Releases newer than this id: the previous page. */
|
|
79
|
+
afterReleaseId?: string;
|
|
80
80
|
limit?: number;
|
|
81
|
-
page?: number;
|
|
82
|
-
targetAppVersion?: string;
|
|
83
81
|
};
|
|
84
82
|
|
|
85
83
|
function removeBundleFromQueryData(
|
|
@@ -213,7 +211,7 @@ export function useCreateChannelMutation() {
|
|
|
213
211
|
const queryClient = useQueryClient();
|
|
214
212
|
|
|
215
213
|
return useMutation({
|
|
216
|
-
mutationFn: (input:
|
|
214
|
+
mutationFn: (input: { name: string }) =>
|
|
217
215
|
createChannelApi({ data: input }).then((response) => response.data),
|
|
218
216
|
onSuccess: async () => {
|
|
219
217
|
await queryClient.invalidateQueries({ queryKey: queryKeys.channels });
|
|
@@ -225,7 +223,7 @@ export function useDeleteChannelMutation() {
|
|
|
225
223
|
const queryClient = useQueryClient();
|
|
226
224
|
|
|
227
225
|
return useMutation({
|
|
228
|
-
mutationFn: (input:
|
|
226
|
+
mutationFn: (input: { id: string }) =>
|
|
229
227
|
deleteChannelApi({ data: input }).then((response) => response.data),
|
|
230
228
|
onSettled: async () => {
|
|
231
229
|
await queryClient.invalidateQueries({ queryKey: queryKeys.channels });
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
|
|
3
|
+
import type { RecoveryInput } from "./insights-recovery";
|
|
4
|
+
import { getBundleActivityRpc } from "./insights-recovery-rpc";
|
|
5
|
+
|
|
6
|
+
export type BundleActivityInput = Pick<
|
|
7
|
+
RecoveryInput,
|
|
8
|
+
"platform" | "channel"
|
|
9
|
+
> & { readonly releaseId: string };
|
|
10
|
+
|
|
11
|
+
export type BundleActivityReport = {
|
|
12
|
+
readonly downloads: number;
|
|
13
|
+
/** Each installation once for each UTC day it launched the release. */
|
|
14
|
+
readonly activeDays: number;
|
|
15
|
+
readonly failedLaunches: number;
|
|
16
|
+
readonly measuredAtMs: number;
|
|
17
|
+
readonly coverage: import("@hot-updater/server/plugins/insights").InsightsCoverage;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Release activity for bundle rows; mounted only where the console reads it. */
|
|
21
|
+
export function useBundleActivityQuery(inputs: readonly BundleActivityInput[]) {
|
|
22
|
+
const sorted = [...inputs].sort((a, b) =>
|
|
23
|
+
a.releaseId.localeCompare(b.releaseId),
|
|
24
|
+
);
|
|
25
|
+
return useQuery({
|
|
26
|
+
queryKey: ["bundle-activity", sorted],
|
|
27
|
+
queryFn: () => getBundleActivityRpc({ data: sorted }),
|
|
28
|
+
enabled: sorted.length > 0,
|
|
29
|
+
staleTime: 30_000,
|
|
30
|
+
});
|
|
31
|
+
}
|