@hot-updater/console 0.36.6 → 1.0.0-rc.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/.output/nitro.json +1 -1
- package/.output/public/assets/AnalyticsCapabilityContext-BCke57-7.js +1 -0
- package/.output/public/assets/BundleActivityChart-CnsBe_1J.js +42 -0
- package/.output/public/assets/BundleIdDisplay-Dky75zLU.js +1 -0
- package/.output/public/assets/alert-C-1KvDW8.js +1 -0
- package/.output/public/assets/analytics-Bqz0c-BT.js +1 -0
- package/.output/public/assets/analytics-api-CJdrTLLO.js +1 -0
- package/.output/public/assets/api-B_Rh-uzC.js +1 -0
- package/.output/public/assets/api-keys-BurCFhzH.js +1 -0
- package/.output/public/assets/api-keys-api-BEDJdQg3.js +1 -0
- package/.output/public/assets/badge-Bf0fZ-Gx.js +1 -0
- package/.output/public/assets/chart-no-axes-combined-FaYMGmQS.js +1 -0
- package/.output/public/assets/createServerFn-gM2-LFBy.js +3 -0
- package/.output/public/assets/dialog-BS60BRr2.js +1 -0
- package/.output/public/assets/dist-DspNKfMj.js +1 -0
- package/.output/public/assets/download-O-yNBc9H.js +1 -0
- package/.output/public/assets/field-Buq148-A.js +1 -0
- package/.output/public/assets/index-kFhd2S78.js +10 -0
- package/.output/public/assets/installations-BrQ-od41.js +2 -0
- package/.output/public/assets/installations-CGlZ3ROz.js +1 -0
- package/.output/public/assets/lazyRouteComponent-rPzgA7S-.js +1 -0
- package/.output/public/assets/loader-circle-DCYF-wJl.js +1 -0
- package/.output/public/assets/preload-helper-TKOBYGYD.js +1 -0
- package/.output/public/assets/refresh-cw-n8XYbPPj.js +1 -0
- package/.output/public/assets/routes-CrdokJ80.js +1 -0
- package/.output/public/assets/routes-DcQnVajO.js +2 -0
- package/.output/public/assets/search-DLhbWw3W.js +1 -0
- package/.output/public/assets/shield-check-DE_hVuHu.js +1 -0
- package/.output/public/assets/signing-HRexfjsH.js +1 -0
- package/.output/public/assets/styles-eB4EtvFS.css +2 -0
- package/.output/public/assets/table-D8CLieHX.js +1 -0
- package/.output/public/assets/textarea-YJLTVAoq.js +1 -0
- package/.output/public/assets/useMutation-JsGVjQMY.js +1 -0
- package/.output/public/assets/useOpenInteractionType-4cRD5xO0.js +1 -0
- package/.output/server/__23tanstack-start-server-fn-resolver-DBP9TQ7K.mjs +146 -0
- package/.output/server/_libs/@base-ui/react+[...].mjs +16124 -0
- package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +1554 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +41 -10
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +132 -0
- 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 +1134 -0
- package/.output/server/_libs/eventemitter3.mjs +236 -0
- package/.output/server/_libs/immer.mjs +532 -0
- package/.output/server/_libs/lucide-react.mjs +141 -13
- package/.output/server/_libs/next-themes.mjs +2 -2
- package/.output/server/_libs/react-redux+[...].mjs +205 -0
- package/.output/server/_libs/recharts+[...].mjs +14117 -0
- package/.output/server/_libs/sonner.mjs +2 -2
- package/.output/server/_libs/tanstack__query-core.mjs +114 -1
- package/.output/server/_libs/tanstack__react-query.mjs +3 -4
- package/.output/server/_runtime.mjs +10 -1
- package/.output/server/_ssr/AnalyticsCapabilityContext-ui4DX8GO.mjs +15 -0
- package/.output/server/_ssr/BundleActivityChart-BiB9ZORH.mjs +288 -0
- package/.output/server/_ssr/BundleIdDisplay-Czk6iR6p.mjs +13 -0
- package/.output/server/_ssr/alert-Dim3MGY5.mjs +86 -0
- package/.output/server/_ssr/analytics-DtMTn8fn.mjs +858 -0
- package/.output/server/_ssr/analytics-api-Cg1M5v_H.mjs +71 -0
- package/.output/server/_ssr/analytics-input-fRRRn0uA.mjs +96 -0
- package/.output/server/_ssr/analytics-rpc-DY5uXvHT.mjs +155 -0
- package/.output/server/_ssr/api-BTSv1tZb.mjs +282 -0
- package/.output/server/_ssr/api-keys-BnM_o2nS.mjs +300 -0
- package/.output/server/_ssr/api-keys-api-CIywsSF5.mjs +60 -0
- package/.output/server/_ssr/api-keys-rpc-BSp1wkIV.mjs +136 -0
- package/.output/server/_ssr/api-rpc-cG5wd_tO.mjs +1468 -0
- package/.output/server/_ssr/auth-BF8mbAgF.mjs +21 -0
- package/.output/server/_ssr/auth-rpc-BrJ6obHJ.mjs +24 -0
- package/.output/server/_ssr/auth.server-DwKoZoQM.mjs +50 -0
- package/.output/server/_ssr/badge-DCxbEeof.mjs +26 -0
- package/.output/server/_ssr/bundle-signing-rpc-COoQhW8E.mjs +16 -0
- package/.output/server/_ssr/bundle-signing.server-D5u8KkMp.mjs +51 -0
- package/.output/server/_ssr/config-Dv8qLDZ0.mjs +13 -0
- package/.output/server/_ssr/config.server-DEiLhKmy.mjs +361 -0
- package/.output/server/_ssr/{createServerFn-DzU0k62V.mjs → createServerFn-B2hcXoPM.mjs} +1 -1
- package/.output/server/_ssr/createServerRpc-DB29C_5p.mjs +12 -0
- package/.output/server/_ssr/{sidebar-Cv_H0_Jv.mjs → createSsrRpc-9P0S0lJ3.mjs} +68 -50
- package/.output/server/_ssr/databaseRows-CwbNwYSl.mjs +166 -0
- package/.output/server/_ssr/deleteBundle-Cu_XOMt0.mjs +66 -0
- package/.output/server/_ssr/dialog-CQuRMNZ4.mjs +170 -0
- package/.output/server/_ssr/dist-BVSLTpoP.mjs +250 -0
- package/.output/server/_ssr/downloadBundle-CNnYxYO2.mjs +24 -0
- package/.output/server/_ssr/{empty-plugin-adapters-B4HCzgmM.mjs → empty-plugin-adapters-B5QvGpEl.mjs} +1 -1
- package/.output/server/_ssr/field-DRIXKjZG.mjs +74 -0
- package/.output/server/_ssr/{getBundleChildren-CVtSiH5t.mjs → getBundleChildren-BcRMFoDF.mjs} +10 -18
- package/.output/server/_ssr/installations-B-azgAvX.mjs +19 -0
- package/.output/server/_ssr/installations-Ctvzp2JH.mjs +535 -0
- package/.output/server/_ssr/router-C-KUBfOi.mjs +513 -0
- package/.output/server/_ssr/routes-BM4ht9jb.mjs +2286 -0
- package/.output/server/_ssr/routes-Z7TwC6nC.mjs +37 -0
- package/.output/server/_ssr/runtime.server-awTLiiXW.mjs +527 -0
- package/.output/server/_ssr/server-BjzmvXnO.mjs +7468 -0
- package/.output/server/_ssr/signing-k8GxyBDF.mjs +202 -0
- package/.output/server/_ssr/ssr.mjs +4 -5740
- package/.output/server/_ssr/start-DpViQGnt.mjs +4 -0
- package/.output/server/_ssr/table-v1yCvYo7.mjs +53 -0
- package/.output/server/_ssr/textarea-DYHnskhb.mjs +14 -0
- package/.output/server/_ssr/uuidv7-BbJ-9D_I.mjs +31 -0
- package/.output/server/_tanstack-start-manifest_v-CH4StzJu.mjs +108 -0
- package/.output/server/index.mjs +249 -46
- package/README.md +29 -8
- package/lib/index.d.mts +36 -0
- package/lib/index.mjs +4 -0
- package/lib/vite-internal.mjs +127 -0
- package/lib/vite.d.mts +10 -0
- package/lib/vite.mjs +5 -0
- package/package.json +51 -29
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/logo.svg +1 -0
- package/public/manifest.json +30 -0
- package/public/robots.txt +3 -0
- package/src/components/AppSidebar.tsx +159 -0
- package/src/components/BundleIdDisplay.tsx +18 -0
- package/src/components/ChannelBadge.tsx +31 -0
- package/src/components/ConsoleAccessPage.tsx +122 -0
- package/src/components/EnabledStatusIcon.tsx +54 -0
- package/src/components/HashValueDisplay.tsx +85 -0
- package/src/components/HotUpdaterLogo.tsx +30 -0
- package/src/components/NotFoundPage.tsx +33 -0
- package/src/components/PlatformIcon.tsx +39 -0
- package/src/components/RolloutPercentageBadge.tsx +28 -0
- package/src/components/ThemeProvider.tsx +116 -0
- package/src/components/TimestampDisplay.tsx +41 -0
- package/src/components/features/analytics/ActivityChart.tsx +150 -0
- package/src/components/features/analytics/AnalyticsCapabilityContext.tsx +24 -0
- package/src/components/features/analytics/AnalyticsControls.tsx +115 -0
- package/src/components/features/analytics/AnalyticsErrorAlert.tsx +21 -0
- package/src/components/features/analytics/AnalyticsOverview.tsx +208 -0
- package/src/components/features/analytics/BundleDistribution.tsx +133 -0
- package/src/components/features/analytics/BundleSelector.tsx +114 -0
- package/src/components/features/analytics/InstallationHistoryCard.tsx +248 -0
- package/src/components/features/analytics/InstallationMatchesCard.tsx +132 -0
- package/src/components/features/analytics/InstallationPageHeader.tsx +138 -0
- package/src/components/features/analytics/InstallationPagination.tsx +48 -0
- package/src/components/features/analytics/InstallationSearch.tsx +230 -0
- package/src/components/features/analytics/UpdateOutcomes.tsx +147 -0
- package/src/components/features/api-keys/ApiKeysPage.tsx +377 -0
- package/src/components/features/bundles/BundleActivityChart.tsx +193 -0
- package/src/components/features/bundles/BundleAnalyticsSummary.tsx +123 -0
- package/src/components/features/bundles/BundleChildrenPanel.tsx +201 -0
- package/src/components/features/bundles/BundleMetadata.tsx +136 -0
- package/src/components/features/bundles/RolloutCohortsDialog.tsx +201 -0
- package/src/components/features/channels/ChannelManagementDialog.tsx +228 -0
- package/src/components/features/releases/ReleaseEditorSheet.tsx +879 -0
- package/src/components/features/releases/ReleaseStateBadge.tsx +20 -0
- package/src/components/features/signing/BundleSigningPage.tsx +247 -0
- package/src/components/ui/alert-dialog.tsx +185 -0
- package/src/components/ui/alert.tsx +76 -0
- package/src/components/ui/badge.tsx +49 -0
- package/src/components/ui/button.tsx +58 -0
- package/src/components/ui/card.tsx +89 -0
- package/src/components/ui/chart.tsx +371 -0
- package/src/components/ui/combobox.tsx +303 -0
- package/src/components/ui/dialog.tsx +156 -0
- package/src/components/ui/dropdown-menu.tsx +270 -0
- package/src/components/ui/field.tsx +235 -0
- package/src/components/ui/input-group.tsx +147 -0
- package/src/components/ui/input.tsx +19 -0
- package/src/components/ui/label.tsx +25 -0
- package/src/components/ui/progress.tsx +84 -0
- package/src/components/ui/select.tsx +205 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +132 -0
- package/src/components/ui/sidebar.tsx +779 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +56 -0
- package/src/components/ui/sonner.tsx +45 -0
- package/src/components/ui/switch.tsx +25 -0
- package/src/components/ui/table.tsx +114 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toggle-group.tsx +89 -0
- package/src/components/ui/toggle.tsx +43 -0
- package/src/components/ui/tooltip.tsx +66 -0
- package/src/hooks/use-mobile.ts +30 -0
- package/src/index.ts +48 -0
- package/src/lib/analytics-api.ts +145 -0
- package/src/lib/analytics-error.ts +19 -0
- package/src/lib/analytics-input.ts +187 -0
- package/src/lib/analytics-overview.ts +170 -0
- package/src/lib/analytics-rpc.ts +218 -0
- package/src/lib/api-keys-api.ts +69 -0
- package/src/lib/api-keys-rpc.ts +87 -0
- package/src/lib/api-rpc.ts +478 -0
- package/src/lib/api.ts +444 -0
- package/src/lib/auth-rpc.ts +16 -0
- package/src/lib/bundle-signing-api.ts +14 -0
- package/src/lib/bundle-signing-rpc.ts +16 -0
- package/src/lib/constants.ts +1 -0
- package/src/lib/git.ts +51 -0
- package/src/lib/server/auth.server.ts +43 -0
- package/src/lib/server/bundle-signing.server.ts +100 -0
- package/src/lib/server/config.server.ts +109 -0
- package/src/lib/server/console-runtime.server.ts +70 -0
- package/src/lib/server/deleteBundle.ts +145 -0
- package/src/lib/server/downloadBundle.ts +46 -0
- package/src/lib/server/getBundleChildren.ts +130 -0
- package/src/lib/server/listReleases.ts +61 -0
- package/src/lib/server/releaseActivity.ts +27 -0
- package/src/lib/server/releaseReachability.ts +95 -0
- package/src/lib/server/runtime.server.ts +172 -0
- package/src/lib/utils.ts +9 -0
- package/src/logo.svg +1 -0
- package/src/routeTree.gen.ts +199 -0
- package/src/router.tsx +21 -0
- package/src/routes/-installations-search.ts +19 -0
- package/src/routes/-releases-search.ts +74 -0
- package/src/routes/__root.tsx +174 -0
- package/src/routes/analytics.tsx +139 -0
- package/src/routes/api/auth/$.ts +19 -0
- package/src/routes/api/bundles/$bundleId/download.ts +17 -0
- package/src/routes/api-keys.tsx +37 -0
- package/src/routes/index.tsx +982 -0
- package/src/routes/installations.tsx +194 -0
- package/src/routes/signing.tsx +37 -0
- package/src/styles.css +152 -0
- package/src/virtual-modules.d.ts +21 -0
- package/src/vite-env.d.ts +1 -0
- package/src/vite-internal.ts +195 -0
- package/src/vite.ts +12 -0
- package/.output/public/assets/dist-DJX53faP.js +0 -3
- package/.output/public/assets/index-Iylis5kY.js +0 -10
- package/.output/public/assets/routes-HT21hs0C.js +0 -54
- package/.output/public/assets/styles-C0Re4quB.css +0 -2
- package/.output/server/__23tanstack-start-server-fn-resolver-CgwgZ0-i.mjs +0 -66
- package/.output/server/_libs/@floating-ui/core+[...].mjs +0 -698
- package/.output/server/_libs/@floating-ui/dom+[...].mjs +0 -644
- package/.output/server/_libs/@floating-ui/react-dom+[...].mjs +0 -839
- package/.output/server/_libs/@radix-ui/react-alert-dialog+[...].mjs +0 -2138
- package/.output/server/_libs/@radix-ui/react-popper+[...].mjs +0 -308
- package/.output/server/_libs/@radix-ui/react-select+[...].mjs +0 -1038
- package/.output/server/_libs/@tanstack/devtools-event-client+[...].mjs +0 -196
- package/.output/server/_libs/@tanstack/form-core+[...].mjs +0 -3228
- package/.output/server/_libs/@tanstack/react-form+[...].mjs +0 -430
- package/.output/server/_libs/@tanstack/react-table+[...].mjs +0 -2382
- package/.output/server/_libs/radix-ui__number.mjs +0 -6
- package/.output/server/_libs/radix-ui__primitive.mjs +0 -9
- package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
- package/.output/server/_libs/radix-ui__react-collection.mjs +0 -78
- package/.output/server/_libs/radix-ui__react-direction.mjs +0 -13
- package/.output/server/_libs/radix-ui__react-label.mjs +0 -22
- package/.output/server/_libs/radix-ui__react-separator.mjs +0 -30
- package/.output/server/_libs/radix-ui__react-slider.mjs +0 -510
- package/.output/server/_libs/radix-ui__react-switch.mjs +0 -157
- package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -493
- package/.output/server/_ssr/api-rpc-BIbDUKSz.mjs +0 -292
- package/.output/server/_ssr/config.server-BSS366KT.mjs +0 -41
- package/.output/server/_ssr/deleteBundle-BgbZTtpW.mjs +0 -141
- package/.output/server/_ssr/dist-KboydRVk.mjs +0 -120
- package/.output/server/_ssr/router-C3hqEy3k.mjs +0 -307
- package/.output/server/_ssr/routes-B0lQvvlC.mjs +0 -3048
- package/.output/server/_ssr/start-02sLteYG.mjs +0 -4
- package/.output/server/_ssr/storageProfile-FVkjPoGb.mjs +0 -9
- package/.output/server/_tanstack-start-manifest_v-Bpx52WOU.mjs +0 -20
- package/.output/server/node_modules/tslib/modules/index.js +0 -70
- package/.output/server/node_modules/tslib/modules/package.json +0 -3
- package/.output/server/node_modules/tslib/package.json +0 -47
- package/.output/server/node_modules/tslib/tslib.js +0 -484
- package/.output/server/package.json +0 -9
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DatabasePluginInputError,
|
|
3
|
+
type Bundle,
|
|
4
|
+
type ChannelDeleteInput,
|
|
5
|
+
type ChannelInsertInput,
|
|
6
|
+
type DatabaseBundleQueryOptions,
|
|
7
|
+
deleteRelease as deleteReleaseMutation,
|
|
8
|
+
preflightReleasePolicy,
|
|
9
|
+
promoteRelease as promoteReleaseMutation,
|
|
10
|
+
type ReleasePolicyPatch,
|
|
11
|
+
updateReleasePolicy,
|
|
12
|
+
} from "@hot-updater/plugin-core";
|
|
13
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
parseBundleEventAnalyticsInput,
|
|
17
|
+
parseBundleEventSummaryInput,
|
|
18
|
+
parseInstallationHistoryInput,
|
|
19
|
+
parseSearchInstallationsInput,
|
|
20
|
+
} from "./analytics-input";
|
|
21
|
+
import { DEFAULT_PAGE_LIMIT } from "./constants";
|
|
22
|
+
import { listReleases } from "./server/listReleases";
|
|
23
|
+
import { getReleaseActivity30d } from "./server/releaseActivity";
|
|
24
|
+
import { addReleaseReachability } from "./server/releaseReachability";
|
|
25
|
+
|
|
26
|
+
type GetBundlesInput = {
|
|
27
|
+
platform?: "ios" | "android";
|
|
28
|
+
page?: number;
|
|
29
|
+
limit?: string;
|
|
30
|
+
after?: string;
|
|
31
|
+
before?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type GetBundleInput = {
|
|
35
|
+
bundleId: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type GetBundleChildrenInput = {
|
|
39
|
+
baseBundleId: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type GetBundleChildCountsInput = {
|
|
43
|
+
bundleIds: string[];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type DeleteBundleInput = {
|
|
47
|
+
bundleId: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type DeleteBundlesInput = {
|
|
51
|
+
bundleIds: string[];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type GetReleasesInput = {
|
|
55
|
+
afterReleaseId?: string;
|
|
56
|
+
beforeReleaseId?: string;
|
|
57
|
+
bundleId?: string;
|
|
58
|
+
channelId?: string;
|
|
59
|
+
enabled?: boolean;
|
|
60
|
+
platform?: "ios" | "android";
|
|
61
|
+
limit?: number;
|
|
62
|
+
page?: number;
|
|
63
|
+
targetAppVersion?: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type ReleaseMutationInput = {
|
|
67
|
+
expectedRevision?: number;
|
|
68
|
+
patch: ReleasePolicyPatch;
|
|
69
|
+
releaseId: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type DeleteReleaseInput = {
|
|
73
|
+
expectedRevision?: number;
|
|
74
|
+
releaseId: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const getReleases = createServerFn({ method: "GET" })
|
|
78
|
+
.inputValidator((input: GetReleasesInput | undefined) => input)
|
|
79
|
+
.handler(async ({ data }) => {
|
|
80
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
81
|
+
const { config, hotUpdater } = await prepareConfig();
|
|
82
|
+
const result = await listReleases(config.database.models.releases, {
|
|
83
|
+
...(data?.afterReleaseId === undefined
|
|
84
|
+
? {}
|
|
85
|
+
: { afterReleaseId: data.afterReleaseId }),
|
|
86
|
+
...(data?.beforeReleaseId === undefined
|
|
87
|
+
? {}
|
|
88
|
+
: { beforeReleaseId: data.beforeReleaseId }),
|
|
89
|
+
...(data?.bundleId === undefined ? {} : { bundleId: data.bundleId }),
|
|
90
|
+
...(data?.channelId === undefined ? {} : { channelId: data.channelId }),
|
|
91
|
+
...(data?.enabled === undefined ? {} : { enabled: data.enabled }),
|
|
92
|
+
...(data?.page === undefined ? {} : { page: data.page }),
|
|
93
|
+
...(data?.platform === undefined ? {} : { platform: data.platform }),
|
|
94
|
+
...(data?.targetAppVersion === undefined
|
|
95
|
+
? {}
|
|
96
|
+
: { targetAppVersion: data.targetAppVersion }),
|
|
97
|
+
limit: data?.limit ?? DEFAULT_PAGE_LIMIT,
|
|
98
|
+
});
|
|
99
|
+
const [releases, activityByBundleId] = await Promise.all([
|
|
100
|
+
addReleaseReachability(
|
|
101
|
+
config.database.models.releaseCatalogs,
|
|
102
|
+
result.data,
|
|
103
|
+
),
|
|
104
|
+
getReleaseActivity30d(hotUpdater, result.data),
|
|
105
|
+
]);
|
|
106
|
+
return {
|
|
107
|
+
...result,
|
|
108
|
+
data: releases.map((release) => ({
|
|
109
|
+
...release,
|
|
110
|
+
activity30d:
|
|
111
|
+
release.bundle_id === null
|
|
112
|
+
? null
|
|
113
|
+
: (activityByBundleId.get(release.bundle_id) ?? null),
|
|
114
|
+
})),
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const getRelease = createServerFn({ method: "GET" })
|
|
119
|
+
.inputValidator((input: { releaseId: string }) => input)
|
|
120
|
+
.handler(async ({ data }) => {
|
|
121
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
122
|
+
const { config } = await prepareConfig();
|
|
123
|
+
return config.database.models.releases.findById(data.releaseId);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const updateRelease = createServerFn({ method: "POST" })
|
|
127
|
+
.inputValidator((input: ReleaseMutationInput) => input)
|
|
128
|
+
.handler(async ({ data }) => {
|
|
129
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
130
|
+
const { config } = await prepareConfig();
|
|
131
|
+
return updateReleasePolicy({ database: config.database, ...data });
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
export const preflightRelease = createServerFn({ method: "POST" })
|
|
135
|
+
.inputValidator((input: ReleaseMutationInput) => input)
|
|
136
|
+
.handler(async ({ data }) => {
|
|
137
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
138
|
+
const { config } = await prepareConfig();
|
|
139
|
+
return preflightReleasePolicy({ database: config.database, ...data });
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
export const deleteRelease = createServerFn({ method: "POST" })
|
|
143
|
+
.inputValidator((input: DeleteReleaseInput) => input)
|
|
144
|
+
.handler(async ({ data }) => {
|
|
145
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
146
|
+
const { config } = await prepareConfig();
|
|
147
|
+
return deleteReleaseMutation({ database: config.database, ...data });
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
export const promoteRelease = createServerFn({ method: "POST" })
|
|
151
|
+
.inputValidator(
|
|
152
|
+
(input: {
|
|
153
|
+
action: "copy" | "move";
|
|
154
|
+
expectedRevision?: number;
|
|
155
|
+
releaseId: string;
|
|
156
|
+
targetChannel: string;
|
|
157
|
+
}) => input,
|
|
158
|
+
)
|
|
159
|
+
.handler(async ({ data }) => {
|
|
160
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
161
|
+
const { config } = await prepareConfig();
|
|
162
|
+
return promoteReleaseMutation({ database: config.database, ...data });
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
export const getReleaseCatalogDiagnostics = createServerFn({ method: "GET" })
|
|
166
|
+
.inputValidator((input: { scopeKey: string }) => input)
|
|
167
|
+
.handler(async ({ data }) => {
|
|
168
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
169
|
+
const { config } = await prepareConfig();
|
|
170
|
+
return config.database.models.releaseCatalogs.findByScopeKey(data.scopeKey);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// GET /api/config
|
|
174
|
+
export const getConfig = createServerFn().handler(async () => {
|
|
175
|
+
try {
|
|
176
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
177
|
+
const { config } = await prepareConfig();
|
|
178
|
+
return { console: config.console };
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error("Error during config retrieval:", error);
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// GET /api/channels
|
|
186
|
+
export const getChannels = createServerFn().handler(async () => {
|
|
187
|
+
try {
|
|
188
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
189
|
+
const { databaseClient } = await prepareConfig();
|
|
190
|
+
const channels = await databaseClient.getChannels();
|
|
191
|
+
return channels ?? [];
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error("Error during channel retrieval:", error);
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// POST /api/channels
|
|
199
|
+
export const createChannel = createServerFn({ method: "POST" })
|
|
200
|
+
.inputValidator((input: ChannelInsertInput) => input)
|
|
201
|
+
.handler(async ({ data }) => {
|
|
202
|
+
try {
|
|
203
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
204
|
+
const { databaseClient } = await prepareConfig();
|
|
205
|
+
return { data: await databaseClient.insertChannel(data) };
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.error("Error during channel creation:", error);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// DELETE /api/channels/:id
|
|
213
|
+
export const deleteChannel = createServerFn({ method: "POST" })
|
|
214
|
+
.inputValidator((input: ChannelDeleteInput) => input)
|
|
215
|
+
.handler(async ({ data }) => {
|
|
216
|
+
try {
|
|
217
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
218
|
+
const { databaseClient } = await prepareConfig();
|
|
219
|
+
return { data: await databaseClient.deleteChannel(data) };
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error("Error during channel deletion:", error);
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// GET /api/config-loaded
|
|
227
|
+
export const getConfigLoaded = createServerFn().handler(async () => {
|
|
228
|
+
try {
|
|
229
|
+
const [{ getRequest }, { requireConsoleAccess }] = await Promise.all([
|
|
230
|
+
import("@tanstack/react-start/server"),
|
|
231
|
+
import("./server/auth.server"),
|
|
232
|
+
]);
|
|
233
|
+
await requireConsoleAccess(getRequest());
|
|
234
|
+
const { isConfigLoaded } = await import("./server/config.server");
|
|
235
|
+
const configLoaded = isConfigLoaded();
|
|
236
|
+
return { configLoaded };
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error("Error during config loaded retrieval:", error);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// GET /api/bundles
|
|
244
|
+
export const getBundles = createServerFn({ method: "GET" })
|
|
245
|
+
.inputValidator((input: GetBundlesInput | undefined) => input)
|
|
246
|
+
.handler(async ({ data }) => {
|
|
247
|
+
try {
|
|
248
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
249
|
+
const query = {
|
|
250
|
+
platform: data?.platform ?? undefined,
|
|
251
|
+
page:
|
|
252
|
+
typeof data?.page === "number" &&
|
|
253
|
+
Number.isInteger(data.page) &&
|
|
254
|
+
data.page > 1
|
|
255
|
+
? data.page
|
|
256
|
+
: undefined,
|
|
257
|
+
limit: data?.limit ? Number(data.limit) : DEFAULT_PAGE_LIMIT,
|
|
258
|
+
after: data?.after ?? undefined,
|
|
259
|
+
before: data?.before ?? undefined,
|
|
260
|
+
};
|
|
261
|
+
if (
|
|
262
|
+
(query.after !== undefined && query.before !== undefined) ||
|
|
263
|
+
(query.page !== undefined &&
|
|
264
|
+
(query.after !== undefined || query.before !== undefined))
|
|
265
|
+
) {
|
|
266
|
+
throw new DatabasePluginInputError("invalid-pagination");
|
|
267
|
+
}
|
|
268
|
+
const pagination =
|
|
269
|
+
query.page !== undefined
|
|
270
|
+
? { page: query.page }
|
|
271
|
+
: query.after !== undefined
|
|
272
|
+
? { cursor: { after: query.after } }
|
|
273
|
+
: query.before !== undefined
|
|
274
|
+
? { cursor: { before: query.before } }
|
|
275
|
+
: {};
|
|
276
|
+
|
|
277
|
+
const { databaseClient } = await prepareConfig();
|
|
278
|
+
const bundleQueryOptions: DatabaseBundleQueryOptions = {
|
|
279
|
+
where: {
|
|
280
|
+
platform: query.platform,
|
|
281
|
+
},
|
|
282
|
+
limit: query.limit,
|
|
283
|
+
...pagination,
|
|
284
|
+
};
|
|
285
|
+
const bundles = await databaseClient.getBundles(bundleQueryOptions);
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
bundles ?? {
|
|
289
|
+
data: [],
|
|
290
|
+
pagination: {
|
|
291
|
+
total: 0,
|
|
292
|
+
hasNextPage: false,
|
|
293
|
+
hasPreviousPage: false,
|
|
294
|
+
currentPage: 1,
|
|
295
|
+
totalPages: 0,
|
|
296
|
+
},
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.error("Error during bundle retrieval:", error);
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// GET /api/bundles/:bundleId
|
|
306
|
+
export const getBundle = createServerFn({ method: "GET" })
|
|
307
|
+
.inputValidator((input: GetBundleInput) => input)
|
|
308
|
+
.handler(async ({ data }) => {
|
|
309
|
+
try {
|
|
310
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
311
|
+
const { databaseClient } = await prepareConfig();
|
|
312
|
+
const bundle = await databaseClient.getBundleById(data.bundleId);
|
|
313
|
+
return bundle ?? null;
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error("Error during bundle retrieval:", error);
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
export const getBundleEventSummary = createServerFn({ method: "GET" })
|
|
321
|
+
.inputValidator(parseBundleEventSummaryInput)
|
|
322
|
+
.handler(async ({ data }) => {
|
|
323
|
+
try {
|
|
324
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
325
|
+
const { getBundleEventSummary: getBundleEventSummaryWithRuntime } =
|
|
326
|
+
await import("./server/runtime.server");
|
|
327
|
+
const { hotUpdater } = await prepareConfig();
|
|
328
|
+
|
|
329
|
+
return await getBundleEventSummaryWithRuntime(hotUpdater, data);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error("Error during bundle event summary retrieval:", error);
|
|
332
|
+
throw error;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
export const getBundleEventAnalytics = createServerFn({ method: "GET" })
|
|
337
|
+
.inputValidator(parseBundleEventAnalyticsInput)
|
|
338
|
+
.handler(async ({ data }) => {
|
|
339
|
+
try {
|
|
340
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
341
|
+
const { getBundleEventAnalytics: getBundleEventAnalyticsWithRuntime } =
|
|
342
|
+
await import("./server/runtime.server");
|
|
343
|
+
const { hotUpdater } = await prepareConfig();
|
|
344
|
+
|
|
345
|
+
return await getBundleEventAnalyticsWithRuntime(hotUpdater, data);
|
|
346
|
+
} catch (error) {
|
|
347
|
+
console.error("Error during bundle event analytics retrieval:", error);
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
export const searchInstallations = createServerFn({ method: "GET" })
|
|
353
|
+
.inputValidator(parseSearchInstallationsInput)
|
|
354
|
+
.handler(async ({ data }) => {
|
|
355
|
+
try {
|
|
356
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
357
|
+
const { searchInstallations: searchInstallationsWithRuntime } =
|
|
358
|
+
await import("./server/runtime.server");
|
|
359
|
+
const { hotUpdater } = await prepareConfig();
|
|
360
|
+
|
|
361
|
+
return await searchInstallationsWithRuntime(hotUpdater, data);
|
|
362
|
+
} catch (error) {
|
|
363
|
+
console.error("Error during installation search:", error);
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
export const getInstallationHistory = createServerFn({ method: "GET" })
|
|
369
|
+
.inputValidator(parseInstallationHistoryInput)
|
|
370
|
+
.handler(async ({ data }) => {
|
|
371
|
+
try {
|
|
372
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
373
|
+
const { getInstallationHistory: getInstallationHistoryWithRuntime } =
|
|
374
|
+
await import("./server/runtime.server");
|
|
375
|
+
const { hotUpdater } = await prepareConfig();
|
|
376
|
+
|
|
377
|
+
return await getInstallationHistoryWithRuntime(hotUpdater, data);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error("Error during installation history retrieval:", error);
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
export const getBundleChildren = createServerFn({ method: "GET" })
|
|
385
|
+
.inputValidator((input: GetBundleChildrenInput) => input)
|
|
386
|
+
.handler(async ({ data }) => {
|
|
387
|
+
try {
|
|
388
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
389
|
+
const { getBundleChildren: getBundleChildrenWithConfig } =
|
|
390
|
+
await import("./server/getBundleChildren");
|
|
391
|
+
const { databaseClient } = await prepareConfig();
|
|
392
|
+
|
|
393
|
+
return await getBundleChildrenWithConfig(data, {
|
|
394
|
+
databaseClient,
|
|
395
|
+
});
|
|
396
|
+
} catch (error) {
|
|
397
|
+
console.error("Error during bundle children retrieval:", error);
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
export const getBundleChildCounts = createServerFn({ method: "GET" })
|
|
403
|
+
.inputValidator((input: GetBundleChildCountsInput) => input)
|
|
404
|
+
.handler(async ({ data }) => {
|
|
405
|
+
try {
|
|
406
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
407
|
+
const { getBundleChildCounts: getBundleChildCountsWithConfig } =
|
|
408
|
+
await import("./server/getBundleChildren");
|
|
409
|
+
const { databaseClient } = await prepareConfig();
|
|
410
|
+
|
|
411
|
+
return await getBundleChildCountsWithConfig(data.bundleIds, {
|
|
412
|
+
databaseClient,
|
|
413
|
+
});
|
|
414
|
+
} catch (error) {
|
|
415
|
+
console.error("Error during bundle child count retrieval:", error);
|
|
416
|
+
throw error;
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// POST /api/bundles
|
|
421
|
+
export const createBundle = createServerFn({ method: "POST" })
|
|
422
|
+
.inputValidator((input: Bundle) => input)
|
|
423
|
+
.handler(async ({ data }) => {
|
|
424
|
+
try {
|
|
425
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
426
|
+
const { databaseClient } = await prepareConfig();
|
|
427
|
+
await databaseClient.insertBundle(data);
|
|
428
|
+
return { success: true, bundleId: data.id };
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.error("Error during bundle creation:", error);
|
|
431
|
+
throw error;
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// DELETE /api/bundles/:bundleId
|
|
436
|
+
export const deleteBundle = createServerFn({ method: "POST" })
|
|
437
|
+
.inputValidator((input: DeleteBundleInput) => input)
|
|
438
|
+
.handler(async ({ data }) => {
|
|
439
|
+
try {
|
|
440
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
441
|
+
const { deleteBundle: deleteBundleWithStorage } =
|
|
442
|
+
await import("./server/deleteBundle");
|
|
443
|
+
const { databaseClient, storagePlugin } = await prepareConfig();
|
|
444
|
+
|
|
445
|
+
await deleteBundleWithStorage(data, {
|
|
446
|
+
databaseClient,
|
|
447
|
+
storagePlugin,
|
|
448
|
+
waitForStorageCleanup: false,
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
return { success: true };
|
|
452
|
+
} catch (error) {
|
|
453
|
+
console.error("Error during bundle deletion:", error);
|
|
454
|
+
throw error;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
export const deleteBundles = createServerFn({ method: "POST" })
|
|
459
|
+
.inputValidator((input: DeleteBundlesInput) => input)
|
|
460
|
+
.handler(async ({ data }) => {
|
|
461
|
+
try {
|
|
462
|
+
const { prepareConfig } = await import("./server/config.server");
|
|
463
|
+
const { deleteBundles: deleteBundlesWithStorage } =
|
|
464
|
+
await import("./server/deleteBundle");
|
|
465
|
+
const { databaseClient, storagePlugin } = await prepareConfig();
|
|
466
|
+
|
|
467
|
+
const result = await deleteBundlesWithStorage(data, {
|
|
468
|
+
databaseClient,
|
|
469
|
+
storagePlugin,
|
|
470
|
+
waitForStorageCleanup: false,
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
return { success: true, ...result };
|
|
474
|
+
} catch (error) {
|
|
475
|
+
console.error("Error during bundle deletion:", error);
|
|
476
|
+
throw error;
|
|
477
|
+
}
|
|
478
|
+
});
|