@hot-updater/console 1.0.0-rc.20 → 1.0.0-rc.21
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 → ConsoleFeatureUnavailable-D0LPL1Gy.js} +1 -1
- package/.output/public/assets/{HashValueDisplay-D880zntR.js → HashValueDisplay-BmuB4FW-.js} +1 -1
- package/.output/public/assets/InsightsInfo--v4SC07c.js +1 -0
- package/.output/public/assets/InsightsPageHeader-dU83CAQY.js +1 -0
- package/.output/public/assets/{NotFoundPage-Dys8C0cW.js → NotFoundPage-B5mhGG2a.js} +1 -1
- package/.output/public/assets/api-D-vOVlQ4.js +1 -0
- package/.output/public/assets/api-keys-Csh8ARKU.js +1 -0
- package/.output/public/assets/api-keys-OMPUoA_A.js +1 -0
- package/.output/public/assets/arrow-left-Bwq9X1eS.js +1 -0
- package/.output/public/assets/arrow-up-right-BkOVn4if.js +1 -0
- package/.output/public/assets/{card-DzCPSRsh.js → card-C_7d6O9a.js} +1 -1
- package/.output/public/assets/console-features-api-C1jRZTGw.js +1 -0
- package/.output/public/assets/dialog-DE8wFN_P.js +1 -0
- package/.output/public/assets/{dist-Clb6cQ9l.js → dist-C7ENGzpS.js} +1 -1
- package/.output/public/assets/empty-CVd5NlQD.js +1 -0
- package/.output/public/assets/{field-Bou7shoO.js → field-C06q1iC9.js} +1 -1
- package/.output/public/assets/index-BeWlQtO6.js +11 -0
- package/.output/public/assets/{input-group-DVtWFUUF.js → input-group-Bi61biIA.js} +1 -1
- package/.output/public/assets/insights-BjnAtC0f.js +2 -0
- package/.output/public/assets/insights-D86m11yH.js +42 -0
- package/.output/public/assets/insights-DpYstMoY.js +1 -0
- package/.output/public/assets/{insights-recovery-rpc-wvdyM4LD.js → insights-recovery-rpc-BIm5_ALc.js} +1 -1
- package/.output/public/assets/{insights-usage-rpc-qUkNtrWr.js → insights-usage-rpc-VHj8vyBt.js} +1 -1
- package/.output/public/assets/insights_.distribution-ADcrX48c.js +2 -0
- package/.output/public/assets/insights_.distribution-CuuJUN6Y.js +1 -0
- package/.output/public/assets/{insights_.distribution-CItZw3-8.js → insights_.distribution-DJRjuXsO.js} +1 -1
- package/.output/public/assets/installations-BSBBzqWs.js +2 -0
- package/.output/public/assets/installations-DqIE6WcO.js +1 -0
- package/.output/public/assets/installations-UsELbDvw.js +1 -0
- package/.output/public/assets/{loader-circle-Ca7C9YY1.js → loader-circle-CnCBxzHp.js} +1 -1
- package/.output/public/assets/mutation-Csp7xUNh.js +1 -0
- package/.output/public/assets/preload-helper-B-cOmpLH.js +1 -0
- package/.output/public/assets/{refresh-cw-CVGqvy8Z.js → refresh-cw-FF1NtzlQ.js} +1 -1
- package/.output/public/assets/{routes-veKtDW39.js → routes-CoN9XHP_.js} +2 -2
- package/.output/public/assets/routes-DT1jB0Zi.js +1 -0
- package/.output/public/assets/sidebar-D8mJRF15.js +3 -0
- package/.output/public/assets/styles-Bwt7v6U5.css +2 -0
- package/.output/public/assets/table-WBgfvgXg.js +1 -0
- package/.output/public/assets/{useCompositeListItem-CF7vsfcA.js → useCompositeListItem-CloBmDwn.js} +1 -1
- package/.output/public/assets/useMutation-DO8cvsTx.js +1 -0
- package/.output/public/assets/{useOpenInteractionType-AnAMWYIY.js → useOpenInteractionType-ReGr9GzJ.js} +1 -1
- package/.output/public/assets/valueToPercent-BvPAi4bP.js +1 -0
- package/.output/server/{__23tanstack-start-server-fn-resolver-CUQLz7hs.mjs → __23tanstack-start-server-fn-resolver-DMRD4e4f.mjs} +34 -42
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +3756 -4022
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +138 -95
- package/.output/server/_libs/tanstack__history.mjs +68 -41
- package/.output/server/_libs/tanstack__query-core.mjs +1618 -309
- package/.output/server/_libs/tanstack__react-query.mjs +255 -20
- package/.output/server/_ssr/{ConsoleFeatureUnavailable-DoxET2AT.mjs → ConsoleFeatureUnavailable-Du7jNPNS.mjs} +7 -7
- package/.output/server/_ssr/{HashValueDisplay-BplboHEb.mjs → HashValueDisplay-GQvFkXoi.mjs} +2 -2
- package/.output/server/_ssr/{InsightsInfo-o2YPd5Qc.mjs → InsightsInfo-Do7QSaFR.mjs} +2 -2
- package/.output/server/_ssr/{InsightsPageHeader-NExCJL1I.mjs → InsightsPageHeader-DSUWUWRc.mjs} +6 -6
- package/.output/server/_ssr/{NotFoundPage-Cd-A8ock.mjs → NotFoundPage-DsF4Vrhg.mjs} +2 -2
- package/.output/server/_ssr/{api-B1Ro0uys.mjs → api-BEiVs0H7.mjs} +9 -8
- package/.output/server/_ssr/{api-keys-Dvvy1sem.mjs → api-keys-BrvBWGRf.mjs} +2 -2
- package/.output/server/_ssr/{api-keys-CT3HG7KT.mjs → api-keys-K5v32nf7.mjs} +8 -8
- package/.output/server/_ssr/{api-keys-rpc-b1qTTFfG.mjs → api-keys-rpc-B96bBllm.mjs} +5 -5
- package/.output/server/_ssr/{api-rpc-Cbns2MGx.mjs → api-rpc-DcUe280B.mjs} +13 -55
- package/.output/server/_ssr/{auth-rpc-DChS7m9y.mjs → auth-rpc-C68W56DP.mjs} +6 -6
- package/.output/server/_ssr/{api-C0G9MTMI.mjs → auth.server-DM1J6NwR.mjs} +2815 -1308
- package/.output/server/_ssr/{bundleActivity-D17Pb_h5.mjs → bundleActivity-CpuY9CTP.mjs} +1 -1
- package/.output/server/_ssr/{card-DMbcvlPz.mjs → card-CPAEKx0w.mjs} +1 -1
- package/.output/server/_ssr/config-nsIcsHh8.mjs +15 -0
- package/.output/server/_ssr/config.server-DDCZk3Sq.mjs +36 -0
- package/.output/server/_ssr/{console-access-KpPv5lin.mjs → console-access-Da-2Qd7q.mjs} +3 -3
- package/.output/server/_ssr/{console-features-CsbyHYfK.mjs → console-features-Dzu2iUGD.mjs} +6 -6
- package/.output/server/_ssr/{console-features-api-B-KVuo4p.mjs → console-features-api-xAsSgFa_.mjs} +6 -6
- package/.output/server/_ssr/{console-features-rpc-Djyo5740.mjs → console-features-rpc-qARGpB24.mjs} +5 -5
- package/.output/server/_ssr/{createMiddleware-B_I3Ll4M.mjs → createMiddleware-BdBf_ezN.mjs} +41 -56
- package/.output/server/_ssr/{createServerRpc-DuNm5mmo.mjs → createServerRpc-B_y2lrwA.mjs} +2 -2
- package/.output/server/_ssr/databaseJsonValue-Bhxciy7Z.mjs +68 -0
- package/.output/server/_ssr/databaseRows-DwMAjaF8.mjs +74 -0
- package/.output/server/_ssr/{dialog-cOmLTUV2.mjs → dialog-q__BJ7mQ.mjs} +1 -1
- package/.output/server/_ssr/{dist-B-r4u3Lg.mjs → dist-Cxo9ghYv.mjs} +114 -3
- package/.output/server/_ssr/{downloadBundle-CexOFoZ4.mjs → downloadBundle-BW9I-pMQ.mjs} +6 -5
- package/.output/server/_ssr/{empty-BHoY_5jt.mjs → empty-DcBTAooP.mjs} +2 -2
- package/.output/server/_ssr/{empty-plugin-adapters-B5QvGpEl.mjs → empty-plugin-adapters-CYdinE-i.mjs} +1 -1
- package/.output/server/_ssr/{field-mjhcNEXD.mjs → field-QCDBVpXA.mjs} +2 -2
- package/.output/server/_ssr/{getBundleChildren-DbDXe9wB.mjs → getBundleChildren-DIAGCF4a.mjs} +2 -2
- package/.output/server/_ssr/{input-group-96H30HWC.mjs → input-group-hCk2nUoU.mjs} +1 -1
- package/.output/server/_ssr/{insights-DgFv1NsO.mjs → insights-BfBO0RFr.mjs} +18 -18
- package/.output/server/_ssr/{insights-D359GJFL.mjs → insights-DsAU3-TB.mjs} +5 -5
- package/.output/server/_ssr/{insights-D25VDVaz.mjs → insights-RIfg447W.mjs} +2 -2
- package/.output/server/_ssr/{insights-api-ChAKrbhG.mjs → insights-api-CDn-QQHU.mjs} +5 -5
- package/.output/server/_ssr/{insights-failures-WQ-ttjOx.mjs → insights-failures-BBGMhuUr.mjs} +2 -2
- package/.output/server/_ssr/{insights-failures-rpc-BFsqlltN.mjs → insights-failures-rpc-rA2dctK2.mjs} +8 -8
- package/.output/server/_ssr/{insights-recovery-DkL6bxMW.mjs → insights-recovery-Dpk6Mfb9.mjs} +1 -1
- package/.output/server/_ssr/{insights-recovery-rpc-2P5m8F62.mjs → insights-recovery-rpc-BCaF-xSd.mjs} +11 -11
- package/.output/server/_ssr/{insights-recovery-rpc-Tj8vNC19.mjs → insights-recovery-rpc-CcgYyUHk.mjs} +5 -5
- package/.output/server/_ssr/{insights-rpc-DrkVmV9o.mjs → insights-rpc-keycmwzw.mjs} +5 -5
- package/.output/server/_ssr/{insights-search-BsalnNw-.mjs → insights-search-BRg5VsNe.mjs} +1 -1
- package/.output/server/_ssr/{insights-usage-1nVTQrLy.mjs → insights-usage-cbw9n2Fq.mjs} +1 -1
- package/.output/server/_ssr/{insights-usage-rpc-Ct_4xHhZ.mjs → insights-usage-rpc-BKgV1QDf.mjs} +8 -8
- package/.output/server/_ssr/{insights-usage-rpc-DaYIRtFK.mjs → insights-usage-rpc-D-JYachy.mjs} +5 -5
- package/.output/server/_ssr/{insightsRecovery-CpGucWN1.mjs → insightsRecovery-B7oMc8d8.mjs} +2 -2
- package/.output/server/_ssr/{insightsUsage-JYpKZAF7.mjs → insightsUsage-Oa7kk5ek.mjs} +3 -3
- package/.output/server/_ssr/{insights_.distribution-jQZEF07J.mjs → insights_.distribution-BIqOqRW0.mjs} +13 -13
- package/.output/server/_ssr/{insights_.distribution-Bcu6uYs_.mjs → insights_.distribution-CuUrDa7P.mjs} +2 -2
- package/.output/server/_ssr/{insights_.distribution-D3Csuyjw.mjs → insights_.distribution-RT_6x_ud.mjs} +5 -5
- package/.output/server/_ssr/{installations-Cxikllmx.mjs → installations-BO5CjX2z.mjs} +11 -11
- package/.output/server/_ssr/{installations-BI5kelHv.mjs → installations-BjaHiIfh.mjs} +2 -2
- package/.output/server/_ssr/{installations-B8Vh54lH.mjs → installations-Dt5luA-N.mjs} +4 -4
- package/.output/server/_ssr/{listReleases-DqU9t1l3.mjs → listReleases-BitHzOYB.mjs} +1 -1
- package/.output/server/_ssr/{router-CRkm-wHD.mjs → router-DfVAixxe.mjs} +42 -39
- package/.output/server/_ssr/{routes-CNAi0Mmv.mjs → routes-C6LstNp8.mjs} +14 -14
- package/.output/server/_ssr/{routes-B3IJo_jL.mjs → routes-Q3Uhmwwz.mjs} +11 -11
- package/.output/server/_ssr/{runtime.server-NucbYjc7.mjs → runtime.server-fL0o6I2b.mjs} +500 -413
- package/.output/server/_ssr/schema-BKY9SqaY.mjs +25 -0
- package/.output/server/_ssr/{select-BkPAJFL7.mjs → select-CUlInmjk.mjs} +1 -1
- package/.output/server/_ssr/server-C43wq9ft.mjs +8330 -0
- package/.output/server/_ssr/{sidebar-Cw1VuC7d.mjs → sidebar-DKbx2ach.mjs} +3 -3
- package/.output/server/_ssr/ssr.mjs +1 -1
- package/.output/server/_ssr/start-BXUOv_n8.mjs +4 -0
- package/.output/server/_ssr/{table-q0P9wz7x.mjs → table-NGWV8B-S.mjs} +1 -1
- package/.output/server/_ssr/{updateFailures-DMU9f0pK.mjs → updateFailures-Jwe2Baab.mjs} +3 -3
- package/.output/server/_ssr/{uuidv7-BzSO-fr-.mjs → uuidv7-C8bwiZr8.mjs} +2 -2
- package/.output/server/_tanstack-start-manifest_v-WQ5qGn8n.mjs +124 -0
- package/.output/server/index.mjs +218 -218
- package/LICENSE +13 -14
- package/README.md +16 -12
- package/lib/index.d.mts +18 -8
- package/lib/vite-internal.mjs +15 -8
- package/lib/vite.d.mts +2 -0
- package/package.json +14 -14
- package/src/components/AppSidebar.tsx +9 -0
- package/src/components/ConsoleFeatureUnavailable.tsx +1 -3
- package/src/components/features/bundles/BundleMetadata.tsx +1 -1
- package/src/components/features/bundles/RolloutCohortsDialog.tsx +1 -1
- package/src/components/features/releases/ReleaseEditorSheet.tsx +6 -6
- package/src/index.ts +27 -15
- package/src/lib/api-rpc.ts +1 -54
- package/src/lib/api.ts +8 -89
- package/src/lib/console-features.ts +5 -5
- package/src/lib/scroll-restoration.ts +1 -1
- package/src/lib/server/config.server.ts +15 -52
- package/src/lib/server/console-runtime.server.ts +84 -6
- package/src/lib/server/downloadBundle.ts +10 -6
- package/src/lib/server/releaseReachability.ts +4 -4
- package/src/lib/server/runtime.server.ts +34 -46
- package/src/routeTree.gen.ts +31 -31
- package/src/routes/api/bundles/$bundleId/download.ts +2 -2
- package/src/vite-internal.ts +17 -8
- package/src/vite.ts +2 -0
- package/.output/public/assets/InsightsInfo-By_sPjTE.js +0 -1
- package/.output/public/assets/InsightsPageHeader-9_kx_LL7.js +0 -1
- package/.output/public/assets/api-CtarlV0l.js +0 -1
- package/.output/public/assets/api-keys-DFF_QqtN.js +0 -1
- package/.output/public/assets/api-keys-evfsQ4sN.js +0 -1
- package/.output/public/assets/arrow-left-BP9D-ta_.js +0 -1
- package/.output/public/assets/arrow-up-right-CDP9Tevw.js +0 -1
- package/.output/public/assets/console-features-api-yv7rm3DX.js +0 -1
- package/.output/public/assets/dialog-BDvCy_QO.js +0 -1
- package/.output/public/assets/empty-C5x9mn_s.js +0 -1
- package/.output/public/assets/index-0eg3l8aC.js +0 -10
- package/.output/public/assets/insights-2MbdiSNv.js +0 -1
- package/.output/public/assets/insights-C6tmCZHk.js +0 -2
- package/.output/public/assets/insights-CadS_aIA.js +0 -42
- package/.output/public/assets/insights_.distribution-BhBs6PNA.js +0 -1
- package/.output/public/assets/insights_.distribution-CJUH_wAS.js +0 -2
- package/.output/public/assets/installations-CH2H7JQt.js +0 -2
- package/.output/public/assets/installations-DMeMuwsW.js +0 -1
- package/.output/public/assets/installations-DnvxI9Dt.js +0 -1
- package/.output/public/assets/mutation-x9L28_CD.js +0 -1
- package/.output/public/assets/preload-helper-BN-UkjOE.js +0 -1
- package/.output/public/assets/routes-BhK8DuZA.js +0 -1
- package/.output/public/assets/sidebar-B45aMqRm.js +0 -3
- package/.output/public/assets/styles-Dn0pK1EX.css +0 -2
- package/.output/public/assets/table-CwLnN6KX.js +0 -1
- package/.output/public/assets/useMutation-CN1ygYEr.js +0 -1
- package/.output/public/assets/valueToPercent-C-t8FT0y.js +0 -1
- package/.output/server/_ssr/auth.server-Ccqz2iVv.mjs +0 -37
- package/.output/server/_ssr/config-DMEJdhoW.mjs +0 -13
- package/.output/server/_ssr/config.server-DyypN6cQ.mjs +0 -60
- package/.output/server/_ssr/databaseRows-CXxf_VIB.mjs +0 -132
- package/.output/server/_ssr/deleteBundle-Dcc21Lbd.mjs +0 -56
- package/.output/server/_ssr/server-DKJYsaCP.mjs +0 -7442
- package/.output/server/_ssr/start-DpViQGnt.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-Bb0gKDbb.mjs +0 -124
- package/src/lib/server/deleteBundle.ts +0 -136
|
@@ -1,82 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertStorageOperations,
|
|
3
|
-
type HotUpdaterCoreApi,
|
|
4
|
-
type StoragePluginWith,
|
|
5
|
-
} from "@hot-updater/plugin-core";
|
|
6
|
-
import { createDatabaseCoreApi } from "@hot-updater/server/db";
|
|
1
|
+
import type { HotUpdaterCoreApi } from "@hot-updater/plugin-core";
|
|
7
2
|
import { getRequest } from "@tanstack/react-start/server";
|
|
8
3
|
|
|
9
|
-
import type { HotUpdaterConsoleConfig } from "../../index";
|
|
10
4
|
import { requireConsoleAccess } from "./auth.server";
|
|
11
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
resolveConsoleConfig,
|
|
7
|
+
type ResolvedConsoleConfig,
|
|
8
|
+
} from "./console-runtime.server";
|
|
12
9
|
import type { ConsoleRuntime } from "./runtime.server";
|
|
13
10
|
|
|
14
|
-
type ResolvedConsoleConfig = HotUpdaterConsoleConfig & {
|
|
15
|
-
readonly console: NonNullable<HotUpdaterConsoleConfig["console"]>;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
11
|
let configPromise: Promise<ResolvedConsoleConfig> | null = null;
|
|
19
12
|
let core: HotUpdaterCoreApi | null = null;
|
|
20
13
|
let runtime: ConsoleRuntime | null = null;
|
|
21
|
-
let storagePluginPromise: Promise<
|
|
22
|
-
StoragePluginWith<"get" | "put" | "exists" | "delete">
|
|
23
|
-
> | null = null;
|
|
24
14
|
|
|
25
15
|
const loadCachedConfig = async (request: Request) => {
|
|
26
16
|
if (!configPromise) {
|
|
27
|
-
configPromise = resolveConsoleConfig(request)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}))
|
|
32
|
-
.catch((error) => {
|
|
33
|
-
configPromise = null;
|
|
34
|
-
throw error;
|
|
35
|
-
});
|
|
17
|
+
configPromise = resolveConsoleConfig(request).catch((error) => {
|
|
18
|
+
configPromise = null;
|
|
19
|
+
throw error;
|
|
20
|
+
});
|
|
36
21
|
}
|
|
37
22
|
|
|
38
23
|
return configPromise;
|
|
39
24
|
};
|
|
40
25
|
|
|
41
|
-
const loadCachedStoragePlugin = async (config: ResolvedConsoleConfig) => {
|
|
42
|
-
if (!storagePluginPromise) {
|
|
43
|
-
storagePluginPromise = Promise.resolve(config.storage)
|
|
44
|
-
.then((storagePlugin) => {
|
|
45
|
-
assertStorageOperations(storagePlugin, [
|
|
46
|
-
"get",
|
|
47
|
-
"put",
|
|
48
|
-
"exists",
|
|
49
|
-
"delete",
|
|
50
|
-
]);
|
|
51
|
-
return storagePlugin;
|
|
52
|
-
})
|
|
53
|
-
.catch((error) => {
|
|
54
|
-
storagePluginPromise = null;
|
|
55
|
-
throw error;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return storagePluginPromise;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
26
|
export const prepareConfig = async (request: Request = getRequest()) => {
|
|
63
27
|
try {
|
|
64
28
|
await requireConsoleAccess(request);
|
|
65
29
|
const config = await loadCachedConfig(request);
|
|
66
30
|
|
|
67
|
-
// Bundles, releases, catalogs, and channels: core
|
|
68
|
-
//
|
|
69
|
-
core ??=
|
|
31
|
+
// Bundles, releases, catalogs, and channels: core assembled as the
|
|
32
|
+
// server's, on the server's own path, or a self-hosted server's admin API.
|
|
33
|
+
core ??= config.core;
|
|
70
34
|
|
|
71
|
-
// The console's features: those of the plugins
|
|
35
|
+
// The console's features: those of the plugins its config lists.
|
|
72
36
|
if (!runtime) {
|
|
73
37
|
const { createConsoleRuntime } = await import("./runtime.server");
|
|
74
38
|
runtime = createConsoleRuntime(config);
|
|
75
39
|
}
|
|
76
40
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return { config, core, runtime, storagePlugin };
|
|
41
|
+
// Each bundle file is read and deleted with its protocol's storage.
|
|
42
|
+
return { config, core, runtime, storage: config.storage };
|
|
80
43
|
} catch (error) {
|
|
81
44
|
if (
|
|
82
45
|
!(
|
|
@@ -1,9 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AnyHotUpdaterPlugin,
|
|
3
|
+
type ConfiguredDatabase,
|
|
4
|
+
createMemoryAdapter,
|
|
5
|
+
type EngineDatabase,
|
|
6
|
+
type HotUpdaterCoreApi,
|
|
7
|
+
isRemoteDatabase,
|
|
8
|
+
type StorageAdapter,
|
|
9
|
+
} from "@hot-updater/plugin-core";
|
|
10
|
+
import { createHotUpdater } from "@hot-updater/server";
|
|
11
|
+
|
|
1
12
|
import type {
|
|
2
13
|
ConsoleAuthAdapter,
|
|
3
|
-
HotUpdaterConsoleConfig,
|
|
4
14
|
HotUpdaterConsoleConfigSource,
|
|
5
15
|
} from "../../index";
|
|
6
16
|
|
|
17
|
+
/** What the console runs on, assembled from its config as the server is. */
|
|
18
|
+
export interface ResolvedConsoleConfig {
|
|
19
|
+
readonly gitUrl?: string;
|
|
20
|
+
/** The server's database, or its admin API. */
|
|
21
|
+
readonly database: ConfiguredDatabase;
|
|
22
|
+
/**
|
|
23
|
+
* Core's API, assembled over the database as the server assembles it, so
|
|
24
|
+
* the console's writes take the server's path, or a self-hosted server's
|
|
25
|
+
* admin API.
|
|
26
|
+
*/
|
|
27
|
+
readonly core: HotUpdaterCoreApi;
|
|
28
|
+
/** The server's storage; each bundle file is read with its protocol's. */
|
|
29
|
+
readonly storage: readonly StorageAdapter[];
|
|
30
|
+
/** The plugins the server runs, as the config lists them. */
|
|
31
|
+
readonly plugins: readonly AnyHotUpdaterPlugin[];
|
|
32
|
+
/**
|
|
33
|
+
* The plugins' APIs by id, which serve their features; absent over a
|
|
34
|
+
* self-hosted server's admin API, whose plugins run on the server.
|
|
35
|
+
*/
|
|
36
|
+
readonly api?: Readonly<Record<string, unknown>>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Core and the plugins over `database`, assembled by `createHotUpdater` as
|
|
41
|
+
* the server assembles them, with public client routes unless a plugin
|
|
42
|
+
* provides clientAuth: the console mounts no handlers. cli-tools'
|
|
43
|
+
* `assembleServer` does the same for the CLI; the console keeps its own
|
|
44
|
+
* copy, since a hosted console never loads cli-tools.
|
|
45
|
+
*/
|
|
46
|
+
const assemble = (
|
|
47
|
+
database: EngineDatabase,
|
|
48
|
+
storage: StorageAdapter,
|
|
49
|
+
plugins: readonly AnyHotUpdaterPlugin[],
|
|
50
|
+
) =>
|
|
51
|
+
createHotUpdater({
|
|
52
|
+
database,
|
|
53
|
+
storage: [storage],
|
|
54
|
+
plugins,
|
|
55
|
+
...(plugins.some((plugin) => plugin.provides?.clientAuth)
|
|
56
|
+
? {}
|
|
57
|
+
: { clientAccess: "public" }),
|
|
58
|
+
} as Parameters<typeof createHotUpdater>[0]);
|
|
59
|
+
|
|
7
60
|
export const getConsoleAuthAdapter = async (): Promise<ConsoleAuthAdapter> => {
|
|
8
61
|
const module = await import("virtual:hot-updater-console/auth");
|
|
9
62
|
return module.default;
|
|
@@ -11,17 +64,42 @@ export const getConsoleAuthAdapter = async (): Promise<ConsoleAuthAdapter> => {
|
|
|
11
64
|
|
|
12
65
|
export const resolveConsoleConfig = async (
|
|
13
66
|
request: Request,
|
|
14
|
-
): Promise<
|
|
67
|
+
): Promise<ResolvedConsoleConfig> => {
|
|
15
68
|
const { default: source } =
|
|
16
69
|
(await import("virtual:hot-updater-console/config")) as {
|
|
17
70
|
readonly default: HotUpdaterConsoleConfigSource;
|
|
18
71
|
};
|
|
19
72
|
|
|
20
73
|
const config = typeof source === "function" ? await source(request) : source;
|
|
74
|
+
const { database, storage, plugins = [] } = config;
|
|
75
|
+
const gitUrl =
|
|
76
|
+
config.console?.gitUrl === undefined
|
|
77
|
+
? {}
|
|
78
|
+
: { gitUrl: config.console.gitUrl };
|
|
79
|
+
// A self-hosted server runs the plugins itself: core is its admin API.
|
|
80
|
+
// The plugins are still checked as the server checks them, on a database
|
|
81
|
+
// nothing reads, so one the server would refuse is refused here too.
|
|
82
|
+
if (isRemoteDatabase(database)) {
|
|
83
|
+
const checked = assemble(
|
|
84
|
+
{ name: "memory", adapter: createMemoryAdapter() },
|
|
85
|
+
storage,
|
|
86
|
+
plugins,
|
|
87
|
+
);
|
|
88
|
+
return {
|
|
89
|
+
...gitUrl,
|
|
90
|
+
database,
|
|
91
|
+
core: database.core,
|
|
92
|
+
storage: [storage],
|
|
93
|
+
plugins: checked.plugins,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const server = assemble(database, storage, plugins);
|
|
21
97
|
return {
|
|
22
|
-
|
|
23
|
-
database
|
|
24
|
-
|
|
25
|
-
|
|
98
|
+
...gitUrl,
|
|
99
|
+
database,
|
|
100
|
+
core: server.core,
|
|
101
|
+
storage: server.storage,
|
|
102
|
+
plugins: server.plugins,
|
|
103
|
+
api: server.api,
|
|
26
104
|
};
|
|
27
105
|
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
HotUpdaterCoreApi,
|
|
3
|
-
|
|
3
|
+
StorageAdapter,
|
|
4
4
|
} from "@hot-updater/plugin-core";
|
|
5
5
|
|
|
6
6
|
interface DownloadBundleDependencies {
|
|
7
7
|
readonly core: Pick<HotUpdaterCoreApi, "getBundle">;
|
|
8
|
-
|
|
8
|
+
/** The server's storage; the manifest is read with its protocol's. */
|
|
9
|
+
readonly storage: readonly StorageAdapter[];
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export const downloadBundle = async (
|
|
12
13
|
bundleId: string,
|
|
13
|
-
{ core,
|
|
14
|
+
{ core, storage }: DownloadBundleDependencies,
|
|
14
15
|
): Promise<Response> => {
|
|
15
16
|
const detail = await core.getBundle(bundleId);
|
|
16
17
|
if (!detail) return new Response("Bundle not found", { status: 404 });
|
|
@@ -18,8 +19,11 @@ export const downloadBundle = async (
|
|
|
18
19
|
const storageUri = detail.bundle.manifest_storage_uri;
|
|
19
20
|
|
|
20
21
|
const protocol = new URL(storageUri).protocol.replace(":", "");
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
const storageAdapter = storage.find(
|
|
23
|
+
(adapter) => adapter.protocol === protocol,
|
|
24
|
+
);
|
|
25
|
+
if (storageAdapter?.get !== undefined) {
|
|
26
|
+
const { response } = await storageAdapter.get({ storageUri });
|
|
23
27
|
if (!response)
|
|
24
28
|
return new Response("Storage object not found", { status: 404 });
|
|
25
29
|
|
|
@@ -34,7 +38,7 @@ export const downloadBundle = async (
|
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
if (protocol !== "http" && protocol !== "https") {
|
|
37
|
-
return new Response(`No storage
|
|
41
|
+
return new Response(`No storage adapter for protocol: ${protocol}`, {
|
|
38
42
|
status: 503,
|
|
39
43
|
});
|
|
40
44
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isReleaseEligibleForCohort,
|
|
3
|
-
NUMERIC_COHORT_SIZE,
|
|
4
|
-
} from "@hot-updater/core";
|
|
5
1
|
import type {
|
|
6
2
|
CompiledReleaseCatalog,
|
|
7
3
|
HotUpdaterCoreApi,
|
|
8
4
|
ReleaseRow,
|
|
9
5
|
} from "@hot-updater/plugin-core";
|
|
6
|
+
import {
|
|
7
|
+
isReleaseEligibleForCohort,
|
|
8
|
+
NUMERIC_COHORT_SIZE,
|
|
9
|
+
} from "@hot-updater/protocol";
|
|
10
10
|
|
|
11
11
|
export type ReleaseReachabilityRow = ReleaseRow & {
|
|
12
12
|
readonly currentlyUnreachable: boolean;
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
type ConfiguredDatabase,
|
|
3
3
|
isRemoteDatabase,
|
|
4
4
|
} from "@hot-updater/plugin-core";
|
|
5
|
-
import { createDatabasePluginApis } from "@hot-updater/server/db";
|
|
6
5
|
|
|
7
6
|
import {
|
|
8
7
|
type ConsoleFeature,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
import {
|
|
15
14
|
type ConsoleFeatureApis,
|
|
16
15
|
consoleFeatureApis,
|
|
17
|
-
type FetchAdmin,
|
|
18
16
|
} from "./console-feature-apis";
|
|
19
17
|
|
|
20
18
|
export type { ConsoleFeatureApis } from "./console-feature-apis";
|
|
@@ -22,7 +20,7 @@ export type { ConsoleFeatureApis } from "./console-feature-apis";
|
|
|
22
20
|
export interface ConsoleRuntime {
|
|
23
21
|
/** Whether the console reaches a self-hosted server through its admin API. */
|
|
24
22
|
readonly remote: boolean;
|
|
25
|
-
/** The features on here,
|
|
23
|
+
/** The features on here, from the plugins the console's config lists. */
|
|
26
24
|
features(): Promise<ConsoleFeatures>;
|
|
27
25
|
/** What serves the features the console can serve here; {@link requireFeature} hands it out. */
|
|
28
26
|
readonly apis: Partial<ConsoleFeatureApis>;
|
|
@@ -31,32 +29,16 @@ export interface ConsoleRuntime {
|
|
|
31
29
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
32
30
|
typeof value === "object" && value !== null;
|
|
33
31
|
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// A server from before `/version` listed its plugins reports none, so the
|
|
45
|
-
// console serves none of their features until the server is upgraded.
|
|
46
|
-
return Array.isArray(plugins)
|
|
47
|
-
? plugins.filter((id): id is string => typeof id === "string")
|
|
48
|
-
: [];
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/** Runs `load` once and keeps its result; a failure is not kept, so the next call retries. */
|
|
52
|
-
const once = <T>(load: () => Promise<T>): (() => Promise<T>) => {
|
|
53
|
-
let pending: Promise<T> | undefined;
|
|
54
|
-
return () =>
|
|
55
|
-
(pending ??= load().catch((error: unknown) => {
|
|
56
|
-
pending = undefined;
|
|
57
|
-
throw error;
|
|
58
|
-
}));
|
|
59
|
-
};
|
|
32
|
+
/**
|
|
33
|
+
* Whether one of Hot Updater's own factories made `plugin`: the brand they
|
|
34
|
+
* set under a registered symbol, read here with a copy of the key so the
|
|
35
|
+
* console imports no package's internals. Assembly refuses any other plugin
|
|
36
|
+
* that takes one of their ids, so features key on it.
|
|
37
|
+
*/
|
|
38
|
+
const isOfficialPlugin = (plugin: unknown): boolean =>
|
|
39
|
+
isRecord(plugin) &&
|
|
40
|
+
Reflect.get(plugin, Symbol.for("@hot-updater/server/official-plugin")) ===
|
|
41
|
+
true;
|
|
60
42
|
|
|
61
43
|
const featureIds = Object.keys(consoleFeatureApis) as ConsoleFeature[];
|
|
62
44
|
|
|
@@ -76,41 +58,47 @@ const featureApis = (
|
|
|
76
58
|
);
|
|
77
59
|
|
|
78
60
|
/**
|
|
79
|
-
* The console's features and what serves them, for
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
61
|
+
* The console's features and what serves them, for the plugins its config
|
|
62
|
+
* lists, the plugins the server runs:
|
|
63
|
+
* - a self-hosted server (`standaloneRepository`) runs them itself; the
|
|
64
|
+
* console serves what that server's admin API serves of their features,
|
|
65
|
+
* and nothing that needs the database;
|
|
66
|
+
* - otherwise the console runs them over the database, as the server does,
|
|
67
|
+
* and serves their features through `api`, their APIs.
|
|
85
68
|
*/
|
|
86
69
|
export const createConsoleRuntime = (config: {
|
|
87
70
|
readonly database: ConfiguredDatabase;
|
|
88
|
-
readonly plugins
|
|
71
|
+
readonly plugins: readonly unknown[];
|
|
72
|
+
readonly api?: Readonly<Record<string, unknown>>;
|
|
89
73
|
}): ConsoleRuntime => {
|
|
90
74
|
const { database } = config;
|
|
75
|
+
// A feature's plugin is Hot Updater's own, which alone may take its id:
|
|
76
|
+
// the server's assembly refuses any other, and features key on the
|
|
77
|
+
// factory's mark, so another plugin under that id turns on nothing.
|
|
78
|
+
const official = new Set(
|
|
79
|
+
config.plugins
|
|
80
|
+
.filter(isOfficialPlugin)
|
|
81
|
+
.map((plugin) => (plugin as { id: string }).id),
|
|
82
|
+
);
|
|
91
83
|
if (isRemoteDatabase(database)) {
|
|
92
84
|
const { fetchAdmin } = database;
|
|
85
|
+
const features = resolveConsoleFeatures([...official], { remote: true });
|
|
93
86
|
return {
|
|
94
87
|
remote: true,
|
|
95
|
-
features:
|
|
96
|
-
resolveConsoleFeatures(await readServerPlugins(fetchAdmin), {
|
|
97
|
-
remote: true,
|
|
98
|
-
}),
|
|
99
|
-
),
|
|
88
|
+
features: async () => features,
|
|
100
89
|
apis: featureApis((feature) =>
|
|
101
90
|
consoleFeatureApis[feature].remote?.(fetchAdmin),
|
|
102
91
|
),
|
|
103
92
|
};
|
|
104
93
|
}
|
|
105
|
-
const api =
|
|
106
|
-
const features = resolveConsoleFeatures(
|
|
94
|
+
const api = config.api ?? {};
|
|
95
|
+
const features = resolveConsoleFeatures([...official], { remote: false });
|
|
107
96
|
return {
|
|
108
97
|
remote: false,
|
|
109
98
|
features: async () => features,
|
|
110
|
-
// A feature reads the plugin with its plugin's id, taken to be Hot
|
|
111
|
-
// Updater's own, as a self-hosted server's /version list is.
|
|
112
99
|
apis: featureApis((feature) => {
|
|
113
|
-
const
|
|
100
|
+
const { plugin } = consoleFeatures[feature];
|
|
101
|
+
const pluginApi = official.has(plugin) ? api[plugin] : undefined;
|
|
114
102
|
return pluginApi === undefined
|
|
115
103
|
? undefined
|
|
116
104
|
: consoleFeatureApis[feature].local(pluginApi as never);
|
package/src/routeTree.gen.ts
CHANGED
|
@@ -9,22 +9,17 @@
|
|
|
9
9
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
10
|
|
|
11
11
|
import { Route as rootRouteImport } from './routes/__root'
|
|
12
|
-
import { Route as InstallationsRouteImport } from './routes/installations'
|
|
13
|
-
import { Route as InsightsRouteImport } from './routes/insights'
|
|
14
|
-
import { Route as ApiKeysRouteImport } from './routes/api-keys'
|
|
15
12
|
import { Route as IndexRouteImport } from './routes/index'
|
|
13
|
+
import { Route as ApiKeysRouteImport } from './routes/api-keys'
|
|
14
|
+
import { Route as InsightsRouteImport } from './routes/insights'
|
|
15
|
+
import { Route as InstallationsRouteImport } from './routes/installations'
|
|
16
16
|
import { Route as InsightsDistributionRouteImport } from './routes/insights_.distribution'
|
|
17
17
|
import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
|
|
18
18
|
import { Route as ApiBundlesBundleIdDownloadRouteImport } from './routes/api/bundles/$bundleId/download'
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
id: '/
|
|
22
|
-
path: '/
|
|
23
|
-
getParentRoute: () => rootRouteImport,
|
|
24
|
-
} as any)
|
|
25
|
-
const InsightsRoute = InsightsRouteImport.update({
|
|
26
|
-
id: '/insights',
|
|
27
|
-
path: '/insights',
|
|
20
|
+
const IndexRoute = IndexRouteImport.update({
|
|
21
|
+
id: '/',
|
|
22
|
+
path: '/',
|
|
28
23
|
getParentRoute: () => rootRouteImport,
|
|
29
24
|
} as any)
|
|
30
25
|
const ApiKeysRoute = ApiKeysRouteImport.update({
|
|
@@ -32,9 +27,14 @@ const ApiKeysRoute = ApiKeysRouteImport.update({
|
|
|
32
27
|
path: '/api-keys',
|
|
33
28
|
getParentRoute: () => rootRouteImport,
|
|
34
29
|
} as any)
|
|
35
|
-
const
|
|
36
|
-
id: '/',
|
|
37
|
-
path: '/',
|
|
30
|
+
const InsightsRoute = InsightsRouteImport.update({
|
|
31
|
+
id: '/insights',
|
|
32
|
+
path: '/insights',
|
|
33
|
+
getParentRoute: () => rootRouteImport,
|
|
34
|
+
} as any)
|
|
35
|
+
const InstallationsRoute = InstallationsRouteImport.update({
|
|
36
|
+
id: '/installations',
|
|
37
|
+
path: '/installations',
|
|
38
38
|
getParentRoute: () => rootRouteImport,
|
|
39
39
|
} as any)
|
|
40
40
|
const InsightsDistributionRoute = InsightsDistributionRouteImport.update({
|
|
@@ -124,18 +124,11 @@ export interface RootRouteChildren {
|
|
|
124
124
|
|
|
125
125
|
declare module '@tanstack/react-router' {
|
|
126
126
|
interface FileRoutesByPath {
|
|
127
|
-
'/
|
|
128
|
-
id: '/
|
|
129
|
-
path: '/
|
|
130
|
-
fullPath: '/
|
|
131
|
-
preLoaderRoute: typeof
|
|
132
|
-
parentRoute: typeof rootRouteImport
|
|
133
|
-
}
|
|
134
|
-
'/insights': {
|
|
135
|
-
id: '/insights'
|
|
136
|
-
path: '/insights'
|
|
137
|
-
fullPath: '/insights'
|
|
138
|
-
preLoaderRoute: typeof InsightsRouteImport
|
|
127
|
+
'/': {
|
|
128
|
+
id: '/'
|
|
129
|
+
path: '/'
|
|
130
|
+
fullPath: '/'
|
|
131
|
+
preLoaderRoute: typeof IndexRouteImport
|
|
139
132
|
parentRoute: typeof rootRouteImport
|
|
140
133
|
}
|
|
141
134
|
'/api-keys': {
|
|
@@ -145,11 +138,18 @@ declare module '@tanstack/react-router' {
|
|
|
145
138
|
preLoaderRoute: typeof ApiKeysRouteImport
|
|
146
139
|
parentRoute: typeof rootRouteImport
|
|
147
140
|
}
|
|
148
|
-
'/': {
|
|
149
|
-
id: '/'
|
|
150
|
-
path: '/'
|
|
151
|
-
fullPath: '/'
|
|
152
|
-
preLoaderRoute: typeof
|
|
141
|
+
'/insights': {
|
|
142
|
+
id: '/insights'
|
|
143
|
+
path: '/insights'
|
|
144
|
+
fullPath: '/insights'
|
|
145
|
+
preLoaderRoute: typeof InsightsRouteImport
|
|
146
|
+
parentRoute: typeof rootRouteImport
|
|
147
|
+
}
|
|
148
|
+
'/installations': {
|
|
149
|
+
id: '/installations'
|
|
150
|
+
path: '/installations'
|
|
151
|
+
fullPath: '/installations'
|
|
152
|
+
preLoaderRoute: typeof InstallationsRouteImport
|
|
153
153
|
parentRoute: typeof rootRouteImport
|
|
154
154
|
}
|
|
155
155
|
'/insights_/distribution': {
|
|
@@ -6,8 +6,8 @@ export const Route = createFileRoute("/api/bundles/$bundleId/download")({
|
|
|
6
6
|
GET: async ({ params, request }) => {
|
|
7
7
|
const { prepareConfig } = await import("@/lib/server/config.server");
|
|
8
8
|
const { downloadBundle } = await import("@/lib/server/downloadBundle");
|
|
9
|
-
const { core,
|
|
10
|
-
return downloadBundle(params.bundleId, { core,
|
|
9
|
+
const { core, storage } = await prepareConfig(request);
|
|
10
|
+
return downloadBundle(params.bundleId, { core, storage });
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
},
|
package/src/vite-internal.ts
CHANGED
|
@@ -70,7 +70,7 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
|
|
|
70
70
|
);
|
|
71
71
|
configFile = resolveFromRoot(
|
|
72
72
|
root,
|
|
73
|
-
mode.options.config ?? "
|
|
73
|
+
mode.options.config ?? "console.config.ts",
|
|
74
74
|
);
|
|
75
75
|
|
|
76
76
|
writeFileIfChanged(
|
|
@@ -128,18 +128,27 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
|
|
|
128
128
|
|
|
129
129
|
if (id === resolvedVirtualConfigModuleId) {
|
|
130
130
|
if (mode.type === "local") {
|
|
131
|
+
// hot-updater.config.ts's database, storage, and plugins, as the
|
|
132
|
+
// CLI loads them.
|
|
131
133
|
return [
|
|
132
|
-
'import { loadConfig
|
|
134
|
+
'import { loadConfig } from "@hot-updater/cli-tools";',
|
|
133
135
|
"export default async () => {",
|
|
134
|
-
" const
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
136
|
+
" const config = await loadConfig(null);",
|
|
137
|
+
" if (config.database === undefined) {",
|
|
138
|
+
" throw new Error(",
|
|
139
|
+
' "Set database in hot-updater.config.ts: the database your server runs on, such as d1Database(...), or standaloneRepository({ baseUrl }) to reach a self-hosted server through its admin API.",',
|
|
140
|
+
" );",
|
|
141
|
+
" }",
|
|
142
|
+
" if (config.storage === undefined) {",
|
|
143
|
+
" throw new Error(",
|
|
144
|
+
' "Set storage in hot-updater.config.ts: where your server stores bundles, which the console reads, such as r2Storage(...).",',
|
|
145
|
+
" );",
|
|
146
|
+
" }",
|
|
138
147
|
" return {",
|
|
139
|
-
" console: { gitUrl: config.console.gitUrl },",
|
|
140
148
|
" database: config.database,",
|
|
141
149
|
" storage: config.storage,",
|
|
142
|
-
"
|
|
150
|
+
" plugins: config.plugins,",
|
|
151
|
+
" console: { gitUrl: config.console.gitUrl },",
|
|
143
152
|
" };",
|
|
144
153
|
"};",
|
|
145
154
|
].join("\n");
|
package/src/vite.ts
CHANGED
|
@@ -3,7 +3,9 @@ import type { PluginOption } from "vite";
|
|
|
3
3
|
import { createHostedConsolePlugins } from "./vite-internal";
|
|
4
4
|
|
|
5
5
|
export interface HotUpdaterConsolePluginOptions {
|
|
6
|
+
/** The console's auth module, `console.auth.ts` by default. */
|
|
6
7
|
readonly auth?: string;
|
|
8
|
+
/** The module whose default export is `defineConsoleConfig(...)`, `console.config.ts` by default. */
|
|
7
9
|
readonly config?: string;
|
|
8
10
|
}
|
|
9
11
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Gr as e,Hr as t,Pn as n,Q as r,Z as i,dr as a,et as o}from"./sidebar-B45aMqRm.js";import{y as s}from"./preload-helper-BN-UkjOE.js";var c=e(t(),1),l=a();function u({label:e,children:t}){let a=(0,c.useId)(),[u,d]=(0,c.useState)(!1);return(0,l.jsxs)(i,{open:u,onOpenChange:d,triggerId:a,children:[(0,l.jsx)(o,{id:a,"aria-describedby":u?`${a}-description`:void 0,closeOnClick:!1,onClick:()=>d(e=>!e),render:(0,l.jsx)(n,{"aria-label":e,className:`size-11 sm:size-7`,size:`icon`,variant:`ghost`}),children:(0,l.jsx)(s,{})}),(0,l.jsx)(r,{id:`${a}-description`,role:`tooltip`,className:`max-w-64`,side:`bottom`,children:t})]})}export{u as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as e,At as t,B as n,F as r,Fn as i,Gn as a,Gr as o,Gt as s,H as c,Hn as l,Hr as u,I as d,In as f,It as p,Jn as m,L as h,Ln as g,Lt as _,M as v,Mt as y,N as b,Nt as x,O as S,Ot as C,Pt as w,Rn as T,U as E,Un as D,V as O,Vn as k,Vt as A,Wn as j,Xt as M,_n as N,at as P,cn as F,dr as I,en as L,er as R,j as z,jt as B,k as ee,kt as V,ot as H,p as U,qn as W,sn as G,vn as K,yn as te,zn as q}from"./sidebar-B45aMqRm.js";import{i as J,l as Y,s as ne}from"./console-features-api-yv7rm3DX.js";import{b as re,y as ie}from"./preload-helper-BN-UkjOE.js";import{c as ae,d as oe,u as se}from"./field-Bou7shoO.js";import{a as ce,i as le,n as ue,r as de}from"./useCompositeListItem-CF7vsfcA.js";import{s as fe}from"./card-DzCPSRsh.js";var X=I();function pe({error:e,fallbackTitle:t}){return ne(e)?(0,X.jsxs)(ae,{children:[(0,X.jsx)(ie,{"aria-hidden":`true`}),(0,X.jsx)(oe,{children:`Insights not installed`}),(0,X.jsx)(se,{children:e.message})]}):(0,X.jsxs)(ae,{variant:`destructive`,children:[(0,X.jsx)(fe,{"aria-hidden":`true`}),(0,X.jsx)(oe,{children:t}),(0,X.jsx)(se,{children:`Refresh to try again. If this keeps happening, check your Insights provider connection.`})]})}var Z=o(u()),me=Z.createContext(void 0);function he(){let e=Z.useContext(me);if(e===void 0)throw Error(a(64));return e}var ge=function(e){return e.activationDirection=`data-activation-direction`,e.orientation=`data-orientation`,e}({}),_e={tabActivationDirection:e=>({[ge.activationDirection]:e})},ve=Z.forwardRef(function(e,t){let{className:n,defaultValue:r=0,onValueChange:i,orientation:a=`horizontal`,render:o,value:c,style:l,...u}=e,d=e.defaultValue!==void 0,f=Z.useRef([]),[p,h]=Z.useState(()=>new Map),[_,v]=le({controlled:c,default:r,name:`Tabs`,state:`value`}),y=c!==void 0,[b,x]=Z.useState(()=>new Map),S=Z.useCallback(e=>{if(e===void 0)return null;for(let[t,n]of b.entries())if(n!=null&&e===(n.value??n.index))return t;return null},[b]),[C,w]=Z.useState(()=>({previousValue:_,tabActivationDirection:`none`})),{previousValue:T,tabActivationDirection:E}=C,D=E,O=!1;T!==_&&(D=ye(T,_,a,b),O=T!=null&&_!=null&&S(_)==null);let k=O?T:_,A=T!==k||E!==D;W(()=>{A&&w({previousValue:k,tabActivationDirection:D})},[k,A,D]);let j=m((e,t)=>{t.activationDirection=ye(_,e,a,b),i?.(e,t),!t.isCanceled&&v(e)}),N=m((e,t)=>{i?.(e,s(t,void 0,void 0,{activationDirection:`none`}))}),P=m((e,t)=>{h(n=>{if(n.get(e)===t)return n;let r=new Map(n);return r.set(e,t),r})}),F=m((e,t)=>{h(n=>{if(!n.has(e)||n.get(e)!==t)return n;let r=new Map(n);return r.delete(e),r})}),I=Z.useCallback(e=>p.get(e),[p]),R=Z.useCallback(e=>{for(let t of b.values())if(e===t?.value)return t?.id},[b]),z=Z.useMemo(()=>({getTabElementBySelectedValue:S,getTabIdByPanelValue:R,getTabPanelIdByValue:I,onValueChange:j,orientation:a,registerMountedTabPanel:P,setTabMap:x,unregisterMountedTabPanel:F,tabActivationDirection:D,value:_}),[S,R,I,j,a,P,x,F,D,_]),B=Z.useMemo(()=>{for(let e of b.values())if(e!=null&&e.value===_)return e},[b,_]),ee=Z.useMemo(()=>{for(let e of b.values())if(e!=null&&!e.disabled)return e.value},[b]),V=Z.useRef(!d),H=Z.useRef(d),U=Z.useRef(!1);W(()=>{if(y)return;function e(e,t){v(e),w(t=>t.previousValue===e&&t.tabActivationDirection===`none`?t:{previousValue:e,tabActivationDirection:`none`}),N(e,t),V.current=!1}if(b.size===0){if(!U.current||_===null)return;e(null,G);return}U.current=!0;let t=B?.disabled,n=B==null&&_!==null;if(!t&&_===r&&(H.current=!1),H.current&&t&&_===r)return;let i=V.current;if(t||n){let n=ee??null;if(_===n){V.current=!1;return}let r=G;i?r=L:t&&(r=M),e(n,r);return}i&&B!=null&&(N(_,L),V.current=!1)},[r,ee,y,N,B,v,b,_]);let K=g(`div`,e,{state:{orientation:a,tabActivationDirection:D},ref:t,props:u,stateAttributesMapping:_e});return(0,X.jsx)(me.Provider,{value:z,children:(0,X.jsx)(de,{elementsRef:f,children:K})})});function ye(e,t,n,r){if(e==null||t==null)return`none`;let i=null,a=null;for(let[n,o]of r.entries()){if(o==null)continue;let r=o.value??o.index;if(e===r&&(i=n),t===r&&(a=n),i!=null&&a!=null)break}if(i==null||a==null)return i!==a&&(typeof e==`number`||typeof e==`string`)&&typeof e==typeof t?n===`horizontal`?t>e?`right`:`left`:t>e?`down`:`up`:`none`;let o=i.getBoundingClientRect(),s=a.getBoundingClientRect();if(n===`horizontal`){if(s.left<o.left)return`left`;if(s.left>o.left)return`right`}else{if(s.top<o.top)return`up`;if(s.top>o.top)return`down`}return`none`}var be=`data-composite-item-active`;function xe(e={}){let{highlightItemOnHover:t,highlightedIndex:n,onHighlightedIndexChange:r}=j(),{ref:i,index:a}=ue(e),o=n===a,s=Z.useRef(null),c=k(i,s);return{compositeProps:Z.useMemo(()=>({tabIndex:o?0:-1,onFocus(){r(a)},onMouseMove(){let e=s.current;if(!t||!e)return;let n=e.hasAttribute(`disabled`)||e.ariaDisabled===`true`;!o&&!n&&e.focus()}}),[o,r,a,t]),compositeRef:c,index:a}}var Se=Z.createContext(void 0);function Ce(){let e=Z.useContext(Se);if(e===void 0)throw Error(a(65));return e}var we=Z.forwardRef(function(e,t){let{className:n,disabled:r=!1,render:i,value:a,id:o,nativeButton:c=!0,style:u,...d}=e,{value:f,getTabPanelIdByValue:p,orientation:m}=he(),{activateOnFocus:h,highlightedTabIndex:_,onTabActivation:v,registerTabResizeObserverElement:y,setHighlightedTabIndex:b,tabsListElement:x}=Ce(),S=H(o),{compositeProps:C,compositeRef:w,index:T}=xe({metadata:Z.useMemo(()=>({disabled:r,id:S,value:a}),[r,S,a])}),E=a===f,D=Z.useRef(!1),O=Z.useRef(null);Z.useEffect(()=>{let e=O.current;if(e)return y(e)},[y]),W(()=>{if(D.current){D.current=!1;return}if(!(E&&T>-1&&_!==T))return;let e=x;if(e!=null){let t=N(A(e));if(t&&K(e,t))return}r||b(T)},[E,T,_,b,r,x]);let{getButtonProps:k,buttonRef:j}=l({disabled:r,native:c,focusableWhenDisabled:!0}),M=p(a),P=Z.useRef(!1),I=Z.useRef(!1);function L(e){E||r||v(a,s(F,e.nativeEvent,void 0,{activationDirection:`none`}))}function R(e){E||(T>-1&&!r&&b(T),!r&&h&&(!P.current||P.current&&I.current)&&v(a,s(F,e.nativeEvent,void 0,{activationDirection:`none`})))}function z(e){if(E||r)return;P.current=!0;function t(){P.current=!1,I.current=!1}(!e.button||e.button===0)&&(I.current=!0,A(e.currentTarget).addEventListener(`pointerup`,t,{once:!0}))}return g(`button`,e,{state:{disabled:r,active:E,orientation:m},ref:[t,j,w,O],props:[C,{role:`tab`,"aria-controls":M,"aria-selected":E,id:S,onClick:L,onFocus:R,onPointerDown:z,[be]:E?``:void 0,onKeyDownCapture(){D.current=!0}},d,k]})});function Te(e){return e==null||e.hasAttribute(`disabled`)||e.getAttribute(`aria-disabled`)===`true`}var Ee=[];function De(i){let{itemSizes:a,cols:o=1,loopFocus:s=!0,onLoop:l,dense:u=!1,orientation:f=`both`,direction:h,highlightedIndex:g,onHighlightedIndexChange:T,rootRef:D,enableHomeAndEndKeys:A=!1,stopEventPropagation:j=!1,disabledIndices:M,modifierKeys:N=Ee}=i,[P,F]=Z.useState(0),I=o>1,L=Z.useRef(null),R=k(L,D),H=Z.useRef([]),U=Z.useRef(!1),W=g??P,G=m((e,t=!1)=>{if((T??F)(e),t){let t=H.current[e];E(L.current,t,h,f)}}),K=m(e=>{if(e.size===0||U.current)return;U.current=!0;let t=Array.from(e.keys()),n=t.find(e=>e?.hasAttribute(`data-composite-item-active`))??null,r=n?t.indexOf(n):-1;r!==-1&&G(r),E(L.current,n,h,f)}),q=m((e,t,n)=>l?l?.(e,t,n,H):n),J=Z.useMemo(()=>({"aria-orientation":f===`both`?void 0:f,ref:R,onFocus(e){let t=L.current,n=te(e.nativeEvent);!t||n==null||!c(n)||n.setSelectionRange(0,n.value.length??0)},onKeyDown(i){let m=A?b:ee;if(!m.has(i.key)||Oe(i,N)||!L.current)return;let g=h===`rtl`,T=g?e:z,E={horizontal:T,vertical:S,both:T}[f],D=g?z:e,k={horizontal:D,vertical:v,both:D}[f],P=te(i.nativeEvent);if(P!=null&&c(P)&&!Te(P)){let e=P.selectionStart,t=P.selectionEnd,n=P.value??``;if(e==null||i.shiftKey||e!==t||i.key!==k&&e<n.length||i.key!==E&&e>0)return}let F=W,R=w(H,M),U=x(H,M);if(I){let e=a||Array.from({length:H.current.length},()=>({width:1,height:1})),n=C(e,o,u),r=n.findIndex(e=>e!=null&&!_(H.current,e,M)),c=n.reduce((e,t,n)=>t!=null&&!_(H.current,t,M)?n:e,-1);F=n[y(n.map(e=>e==null?null:H.current[e]),{event:i,orientation:f,loopFocus:s,onLoop:q,cols:o,disabledIndices:B([...M||H.current.map((e,t)=>_(H.current,t)?t:void 0),void 0],n),minIndex:r,maxIndex:c,prevIndex:t(W>U?R:W,e,n,o,i.key===`ArrowDown`?`bl`:i.key===`ArrowRight`?`tr`:`tl`),rtl:g})]}let K={horizontal:[T],vertical:[S],both:[T,S]}[f],J={horizontal:[D],vertical:[v],both:[D,v]}[f],Y=I?m:{horizontal:A?d:r,vertical:A?O:n,both:m}[f];A&&(i.key===`Home`?F=R:i.key===`End`&&(F=U)),F===W&&(K.includes(i.key)||J.includes(i.key))&&(s&&F===U&&K.includes(i.key)?(F=R,l&&(F=l(i,W,F,H))):s&&F===R&&J.includes(i.key)?(F=U,l&&(F=l(i,W,F,H))):F=V(H.current,{startingIndex:F,decrement:J.includes(i.key),disabledIndices:M})),F!==W&&!p(H.current,F)&&(j&&i.stopPropagation(),Y.has(i.key)&&i.preventDefault(),G(F,!0),queueMicrotask(()=>{H.current[F]?.focus()}))}}),[o,u,h,M,H,A,W,I,a,s,l,q,R,N,G,f,j]);return Z.useMemo(()=>({props:J,highlightedIndex:W,onHighlightedIndexChange:G,elementsRef:H,disabledIndices:M,onMapChange:K,relayKeyboardEvent:J.onKeyDown}),[J,W,G,H,M,K])}function Oe(e,t){for(let n of h.values())if(!t.includes(n)&&e.getModifierState(n))return!0;return!1}function ke(e){let{render:t,className:n,style:r,refs:i=T,props:a=T,state:o=q,stateAttributesMapping:s,highlightedIndex:c,onHighlightedIndexChange:l,orientation:u,dense:d,itemSizes:f,loopFocus:p,onLoop:m,cols:h,enableHomeAndEndKeys:_,onMapChange:v,stopEventPropagation:y=!0,rootRef:b,disabledIndices:x,modifierKeys:S,highlightItemOnHover:C=!1,tag:w=`div`,...E}=e,{props:O,highlightedIndex:k,onHighlightedIndexChange:A,elementsRef:j,onMapChange:M,relayKeyboardEvent:N}=De({itemSizes:f,cols:h,loopFocus:p,onLoop:m,dense:d,orientation:u,highlightedIndex:c,onHighlightedIndexChange:l,rootRef:b,stopEventPropagation:y,enableHomeAndEndKeys:_,direction:P(),disabledIndices:x,modifierKeys:S}),F=g(w,e,{state:o,ref:i,props:[O,...a,E],stateAttributesMapping:s}),I=Z.useMemo(()=>({highlightedIndex:k,onHighlightedIndexChange:A,highlightItemOnHover:C,relayKeyboardEvent:N}),[k,A,C,N]);return(0,X.jsx)(D.Provider,{value:I,children:(0,X.jsx)(de,{elementsRef:j,onMapChange:e=>{v?.(e),M(e)},children:F})})}var Ae=Z.forwardRef(function(e,t){let{activateOnFocus:n=!1,className:r,loopFocus:i=!0,render:a,style:o,...s}=e,{onValueChange:c,orientation:l,value:u,setTabMap:d,tabActivationDirection:f}=he(),[p,h]=Z.useState(0),[g,_]=Z.useState(null),v=Z.useRef(new Set),y=Z.useRef(new Set),b=Z.useRef(null);Z.useEffect(()=>{if(typeof ResizeObserver>`u`)return;let e=new ResizeObserver(()=>{v.current.forEach(e=>{e()})});return b.current=e,g&&e.observe(g),y.current.forEach(t=>{e.observe(t)}),()=>{e.disconnect(),b.current=null}},[g]);let x=m(e=>(v.current.add(e),()=>{v.current.delete(e)})),S=m(e=>(y.current.add(e),b.current?.observe(e),()=>{y.current.delete(e),b.current?.unobserve(e)})),C=m((e,t)=>{e!==u&&c(e,t)}),w={orientation:l,tabActivationDirection:f},E={"aria-orientation":l===`vertical`?`vertical`:void 0,role:`tablist`},D=Z.useMemo(()=>({activateOnFocus:n,highlightedTabIndex:p,registerIndicatorUpdateListener:x,registerTabResizeObserverElement:S,onTabActivation:C,setHighlightedTabIndex:h,tabsListElement:g}),[n,p,x,S,C,h,g]);return(0,X.jsx)(Se.Provider,{value:D,children:(0,X.jsx)(ke,{render:a,className:r,style:o,state:w,refs:[t,_],props:[E,s],stateAttributesMapping:_e,highlightedIndex:p,enableHomeAndEndKeys:!0,loopFocus:i,orientation:l,onHighlightedIndexChange:h,onMapChange:d,disabledIndices:T})})});function je({className:e,orientation:t=`horizontal`,...n}){return(0,X.jsx)(ve,{orientation:t,"data-slot":`tabs`,"data-orientation":t,className:R(`group/tabs flex gap-2 data-horizontal:flex-col`,e),...n})}var Me=f(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function Ne({className:e,variant:t=`default`,...n}){return(0,X.jsx)(Ae,{"data-slot":`tabs-list`,"data-variant":t,className:R(Me({variant:t}),e),...n})}function Pe({className:e,...t}){return(0,X.jsx)(we,{"data-slot":`tabs-trigger`,className:R(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-xs font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:py-[calc(--spacing(1.25))] hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent`,`data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100`,e),...t})}var Q={"24h":{label:`DAU`,period:`24 hours`,interval:`hour`},"7d":{label:`WAU`,period:`7 days`,interval:`6 hours`},"30d":{label:`MAU`,period:`30 days`,interval:`day`},"12m":{label:`YAU`,period:`12 months`,interval:`week`}};function $({label:e,onPeriodChange:t,period:n,periods:r}){return(0,X.jsx)(je,{value:n,onValueChange:e=>{let n=r.find(t=>t.value===e);n&&t(n.value)},children:(0,X.jsx)(Ne,{"aria-label":e,className:`min-h-11 sm:min-h-9`,children:r.map(({value:e,name:t})=>(0,X.jsx)(Pe,{value:e,"aria-label":t,className:`min-w-12 px-3`,children:e},e))})})}var Fe=[`24h`,`7d`,`30d`].map(e=>({value:e,name:Q[e].period})),Ie=Object.keys(Q).map(e=>({value:e,name:Q[e].period}));function Le({window:e,onWindowChange:t}){return(0,X.jsx)($,{label:`Reporting period`,onPeriodChange:t,period:e,periods:Fe})}function Re({window:e,onWindowChange:t,twelveMonths:n=!0}){return(0,X.jsx)($,{label:`Reporting period`,onPeriodChange:t,period:e,periods:Ie.filter(({value:e})=>n||e!==`12m`)})}function ze({view:e,overviewSearch:t}){let n=J(`insightsAnalytics`);return(0,X.jsxs)(`header`,{className:`sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-3 border-b bg-background px-3 py-3 sm:bg-card/70 sm:px-4 sm:backdrop-blur-sm`,children:[(0,X.jsx)(U,{className:`-ml-1 size-11 lg:size-7`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,X.jsx)(re,{"aria-hidden":`true`,className:`size-3.5 text-muted-foreground`}),(0,X.jsx)(`h1`,{className:`text-sm font-medium`,children:`Insights`})]}),(0,X.jsxs)(`nav`,{"aria-label":`Insights views`,className:`ml-auto flex gap-2`,children:[n?(0,X.jsx)(Y,{"aria-current":e===`overview`?`page`:void 0,className:R(i({className:`h-11 px-3 lg:h-8 lg:px-2.5`,size:`lg`,variant:e===`overview`?`secondary`:`ghost`})),search:t,to:`/insights`,children:`Overview`}):null,(0,X.jsxs)(Y,{"aria-current":e===`events`?`page`:void 0,className:R(i({className:`h-11 px-3 lg:h-8 lg:px-2.5`,size:`lg`,variant:e===`events`?`secondary`:`ghost`})),to:`/installations`,children:[(0,X.jsx)(ce,{"aria-hidden":`true`,"data-icon":`inline-start`}),`All events`]})]})]})}export{Q as a,Re as i,Le as n,pe as o,$ as r,ze as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ar as e,cr as t,jr as n,nr as r,rr as i,ur as a}from"./sidebar-B45aMqRm.js";import{t as o}from"./useMutation-CN1ygYEr.js";var s=e(`arrow-right`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]),c=e(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),l=i({method:`GET`}).middleware([r]).handler(n(`206547cb1526f961070a989818ca7b9e34f6b2b0e4ab851698c3807fe9fb5e0c`)),u=i({method:`GET`}).middleware([r]).handler(n(`a6f23116eeaf76166d405e28a95213123025613c6603030894e519015bf48032`)),d=i({method:`POST`}).middleware([r]).handler(n(`7ea0186f19f9f2bc2ca4b26e3c59636891cf046957f84287b6783f8d88bd8cb7`)),f=i({method:`POST`}).middleware([r]).handler(n(`b46c95dba95a6a3e8fa5c9d100e3622fa5ae7af4f38e10fb1ed2fa48289a3a8f`)),p=i({method:`POST`}).middleware([r]).handler(n(`d5b58722ce514e3b63a377f736b4823c2011782495442ae4870ed547e392c70b`)),m=i({method:`POST`}).middleware([r]).handler(n(`956539a300d79a7efa191c1cc2d529d62fc4bfd940442548fdbc1404e0d53078`)),h=i({method:`GET`}).middleware([r]).handler(n(`e8c24b7247936f045a145ffd5c177fd0e3df3b52769d67dfbd8d1de491d66396`)),g=i().middleware([r]).handler(n(`51a34c05479a893c7d320bd4cd1604427289d667698c48b9f30a01aabf8a5e68`)),_=i().middleware([r]).handler(n(`79ada05964de8f2123bfcd62b10097d59bf8fd689ef5c7161031e5871d8396c5`)),v=i({method:`POST`}).middleware([r]).handler(n(`2b9b8d1f49f79a511589617d8d4bfc6094a3acf5264f33651b9569ba66d3f321`)),y=i({method:`POST`}).middleware([r]).handler(n(`52756dde414919a906bfe83d1ab6d29910c63bcafdb47653d6f1df562d958920`));i().middleware([r]).handler(n(`f8bdca3d0579adb812d6404f55d9261a89cdb025e920b1fcad82883646a5fe9e`)),i({method:`GET`}).middleware([r]).handler(n(`00ccacb4a0212c83ec29f4d11719046ad91ea8291cfc557d514dbf00d3bd7f5f`));var b=i({method:`GET`}).middleware([r]).handler(n(`1bd85c2a50e24785cb6abb023a247a9f048f37ddfa85cbb1c57e579563bad013`)),x=i({method:`GET`}).middleware([r]).handler(n(`4370f1bf70b91f1168d85379d3008449a1bedb915e9878ca4ef89d5f3a80fa7f`)),S=i({method:`GET`}).middleware([r]).handler(n(`4ca367070b00f58179a572f0bb8196a4ccdd3881e9b1dbfe33deee0cb6e1f549`));i({method:`POST`}).middleware([r]).handler(n(`3a27ff5679228b86a346b3fe42142e7a5bf0264f73173c0dbe5f07fb37c43cf7`)),i({method:`POST`}).middleware([r]).handler(n(`61de3b69779c5ce2a5f5d3c27e2cfaca8fba8f14c8803559b9cd733c456494fa`));var C=[`bundles`],w=[`releases`],T={config:[`config`],channels:[`channels`],configLoaded:[`config-loaded`],bundles:{all:C,list:e=>[...C,e??{}]},releases:{all:w,list:e=>[...w,e??{}]},release:e=>[`release`,e],releaseCatalog:e=>[`release-catalog`,e],bundleChildren:{all:[`bundle-children`],list:e=>[`bundle-children`,e],counts:e=>[`bundle-children`,`counts`,...e]},bundle:e=>[`bundle`,e]};function E(){return t({queryKey:T.config,queryFn:()=>g(),staleTime:1/0})}function D(){return t({queryKey:T.channels,queryFn:()=>_(),staleTime:1/0})}function O(e){return t({queryKey:T.releases.list(e),queryFn:()=>l({data:e}),placeholderData:e=>e})}function k(e){return t({enabled:e.length>0,queryFn:()=>u({data:{releaseId:e}}),queryKey:T.release(e)})}function A(e){return t({enabled:e.length>0,queryFn:()=>h({data:{scopeKey:e}}),queryKey:T.releaseCatalog(e)})}function j(e){return t({queryKey:T.bundle(e),queryFn:()=>b({data:{bundleId:e}}),staleTime:1/0,enabled:!!e})}function M(e){return t({queryKey:T.bundleChildren.list(e),queryFn:()=>x({data:{baseBundleId:e}}),staleTime:1/0,enabled:!!e})}function N(e){let n=[...e].sort((e,t)=>e.localeCompare(t));return t({queryKey:T.bundleChildren.counts(n),queryFn:()=>S({data:{bundleIds:n}}),staleTime:1/0,enabled:n.length>0})}function P(){let e=a();return o({mutationFn:e=>v({data:e}).then(e=>e.data),onSuccess:async()=>{await e.invalidateQueries({queryKey:T.channels})}})}function F(){let e=a();return o({mutationFn:e=>y({data:e}).then(e=>e.data),onSettled:async()=>{await e.invalidateQueries({queryKey:T.channels})}})}function I(){let e=a();return o({mutationFn:e=>d({data:e}),onSuccess:async(t,n)=>{await Promise.all([e.invalidateQueries({queryKey:T.releases.all}),e.invalidateQueries({queryKey:T.release(n.releaseId)}),e.invalidateQueries({queryKey:[`release-catalog`]}),e.invalidateQueries({queryKey:T.channels})])}})}function L(){return o({mutationFn:e=>f({data:e})})}function R(){let e=a();return o({mutationFn:e=>p({data:e}),onSuccess:async(t,n)=>{e.removeQueries({queryKey:T.release(n.releaseId)}),await Promise.all([e.invalidateQueries({queryKey:T.releases.all}),e.invalidateQueries({queryKey:[`release-catalog`]}),e.invalidateQueries({queryKey:T.channels})])}})}function z(){let e=a();return o({mutationFn:e=>m({data:e}),onSuccess:async()=>{await Promise.all([e.invalidateQueries({queryKey:T.releases.all}),e.invalidateQueries({queryKey:[`release`]}),e.invalidateQueries({queryKey:[`release-catalog`]}),e.invalidateQueries({queryKey:T.channels})])}})}export{E as a,R as c,A as d,k as f,s as g,c as h,D as i,L as l,I as m,M as n,P as o,O as p,j as r,F as s,N as t,z as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{$n as e,Gr as t,Hr as n,Pn as r,Y as i,ar as a,cr as o,dr as s,jr as c,nr as l,p as u,rr as d,ur as f}from"./sidebar-B45aMqRm.js";import{t as p}from"./useMutation-CN1ygYEr.js";import{a as m,c as ee,d as te,f as ne,i as h,l as g,n as _,r as v,s as y,t as b,u as x}from"./field-Bou7shoO.js";import{n as S,t as re}from"./loader-circle-Ca7C9YY1.js";import{_ as ie,a as ae,c as C,d as w,f as T,g as E,h as D,i as O,l as k,m as A,n as j,o as M,p as N,r as P,t as F,u as I,v as L}from"./dialog-BDvCy_QO.js";import{t as R}from"./refresh-cw-CVGqvy8Z.js";import{a as z,n as B,o as V,s as oe,t as H}from"./card-DzCPSRsh.js";import{n as U}from"./dist-Clb6cQ9l.js";import{a as W,i as G,n as K,o as q,r as J,t as se}from"./table-CwLnN6KX.js";var ce=a(`clipboard`,[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`,key:`116196`}]]),Y=a(`shield-off`,[[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M5 5a1 1 0 0 0-1 1v7c0 5 3.5 7.5 7.67 8.94a1 1 0 0 0 .67.01c2.35-.82 4.48-1.97 5.9-3.71`,key:`1jlk70`}],[`path`,{d:`M9.309 3.652A12.252 12.252 0 0 0 11.24 2.28a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1v7a9.784 9.784 0 0 1-.08 1.264`,key:`18rp1v`}]]),X=t(n(),1),Z=d({method:`GET`}).middleware([l]).handler(c(`2c7f3cdb9bd3cab2c026a48abdc84c362db0362924a08679052a325640aec56b`)),le=d({method:`POST`}).middleware([l]).handler(c(`68a2d94ee016be64936401f5eba60ab08a47ff373e1cf9de48e4413336e6034b`)),ue=d({method:`POST`}).middleware([l]).handler(c(`a1cb80b19ca72a64fb631ca28ebb9b6941db245983de082d5dd3203ec2eef795`)),Q={list:[`api-keys`,`list`]},de=()=>o({queryKey:Q.list,queryFn:()=>Z()}),fe=()=>{let e=f();return p({mutationFn:e=>le({data:{name:e}}),onSuccess:async()=>{await e.invalidateQueries({queryKey:Q.list})}})},pe=()=>{let e=f();return p({mutationFn:e=>ue({data:{id:e}}),onSuccess:async()=>{await e.invalidateQueries({queryKey:Q.list})}})},$=s(),me=e=>new Date(e).toISOString().slice(0,10);function he(){let[e,t]=(0,X.useState)(!1),[n,a]=(0,X.useState)(``),[o,s]=(0,X.useState)(null),c=fe(),l=n.trim(),u=l.length>64?`Name must be 64 characters or fewer.`:null,d=()=>{a(``),s(null),c.reset()},f=e=>{t(e),e||d()};return(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(r,{onClick:()=>t(!0),children:[(0,$.jsx)(L,{"data-icon":`inline-start`}),`Create API key`]}),(0,$.jsx)(F,{open:e,onOpenChange:f,children:(0,$.jsxs)(j,{showCloseButton:o===null,children:[(0,$.jsxs)(ae,{children:[(0,$.jsx)(M,{children:o===null?`Create API key`:`Save your API key`}),(0,$.jsx)(P,{children:o===null?`Name the app or environment that will use this key.`:`This key is shown once. Store it securely before closing.`})]}),o===null?(0,$.jsxs)(`form`,{onSubmit:async e=>{if(e.preventDefault(),!(l.length===0||u!==null))try{s((await c.mutateAsync(l)).apiKey),U.success(`API key created`)}catch(e){U.error(e instanceof Error?e.message:`Unable to create API key`)}},children:[(0,$.jsx)(h,{children:(0,$.jsxs)(b,{"data-invalid":u!==null||void 0,children:[(0,$.jsx)(m,{htmlFor:`api-key-name`,children:`Name`}),(0,$.jsx)(i,{id:`api-key-name`,autoComplete:`off`,maxLength:65,onChange:e=>a(e.target.value),placeholder:`Production app`,value:n}),(0,$.jsx)(_,{children:`Use a name you can identify before revoking the key.`}),(0,$.jsx)(v,{children:u})]})}),(0,$.jsx)(O,{className:`mt-4`,children:(0,$.jsxs)(r,{disabled:c.isPending||l.length===0||u!==null,type:`submit`,children:[c.isPending?(0,$.jsx)(re,{"data-icon":`inline-start`,className:`animate-spin`}):(0,$.jsx)(S,{"data-icon":`inline-start`}),`Create API key`]})})]}):(0,$.jsxs)(h,{children:[(0,$.jsxs)(b,{children:[(0,$.jsx)(m,{htmlFor:`created-api-key`,children:`API key`}),(0,$.jsxs)(`div`,{className:`flex gap-2`,children:[(0,$.jsx)(i,{id:`created-api-key`,className:`font-mono`,readOnly:!0,value:o}),(0,$.jsxs)(r,{onClick:async()=>{if(o!==null)try{await navigator.clipboard.writeText(o),U.success(`API key copied`)}catch{U.error(`Unable to copy API key`)}},type:`button`,variant:`outline`,children:[(0,$.jsx)(ce,{"data-icon":`inline-start`}),`Copy`]})]})]}),(0,$.jsx)(O,{children:(0,$.jsxs)(r,{onClick:()=>f(!1),children:[(0,$.jsx)(ne,{"data-icon":`inline-start`}),`Done`]})})]})]})})]})}function ge({record:e}){let[t,n]=(0,X.useState)(!1),i=pe(),a=async t=>{t.preventDefault();try{await i.mutateAsync(e.id),n(!1),U.success(`API key revoked`)}catch(e){U.error(e instanceof Error?e.message:`Unable to revoke API key`)}};return(0,$.jsxs)(C,{open:t,onOpenChange:e=>{i.isPending||n(e)},children:[(0,$.jsxs)(ie,{render:(0,$.jsx)(r,{size:`sm`,variant:`ghost`}),children:[(0,$.jsx)(Y,{"data-icon":`inline-start`}),`Revoke`]}),(0,$.jsxs)(w,{children:[(0,$.jsxs)(A,{children:[(0,$.jsx)(D,{children:(0,$.jsx)(Y,{})}),(0,$.jsxs)(E,{children:[`Revoke `,e.name,`?`]}),(0,$.jsxs)(T,{children:[`Apps using `,e.prefix,`… will immediately lose OTA update and insights access. This action cannot be undone.`]})]}),(0,$.jsxs)(N,{children:[(0,$.jsx)(I,{disabled:i.isPending,children:`Cancel`}),(0,$.jsx)(k,{disabled:i.isPending,onClick:e=>void a(e),variant:`destructive`,children:`Revoke API key`})]})]})]})}function _e(){let t=de();return(0,$.jsxs)(H,{className:`overflow-hidden shadow-sm`,children:[(0,$.jsxs)(z,{className:`flex-row items-center justify-between space-y-0 border-b px-4 py-3`,children:[(0,$.jsx)(V,{className:`text-sm`,children:(0,$.jsx)(`h2`,{children:`API keys`})}),(0,$.jsx)(he,{})]}),(0,$.jsx)(B,{className:`p-0`,children:t.isError?(0,$.jsx)(`div`,{className:`p-4`,children:(0,$.jsxs)(ee,{variant:`destructive`,children:[(0,$.jsx)(oe,{}),(0,$.jsx)(te,{children:`API keys couldn't be loaded`}),(0,$.jsx)(x,{children:`Check your connection and try again.`}),(0,$.jsx)(g,{children:(0,$.jsxs)(r,{onClick:()=>void t.refetch(),size:`xs`,variant:`outline`,children:[(0,$.jsx)(R,{"data-icon":`inline-start`}),`Retry`]})})]})}):(0,$.jsxs)(se,{"aria-label":`API keys`,className:`table-fixed`,children:[(0,$.jsx)(W,{children:(0,$.jsxs)(q,{children:[(0,$.jsx)(G,{children:`Key`}),(0,$.jsx)(G,{className:`w-32`,children:`Created`}),(0,$.jsx)(G,{className:`w-24 text-right`,children:(0,$.jsx)(`span`,{className:`sr-only`,children:`Actions`})})]})}),(0,$.jsx)(K,{children:t.isLoading?Array.from({length:3},(t,n)=>(0,$.jsxs)(q,{children:[(0,$.jsxs)(J,{className:`space-y-2 py-3`,children:[n===0?(0,$.jsx)(`span`,{className:`sr-only`,children:`Loading API keys`}):null,(0,$.jsx)(e,{className:`h-3.5 w-32`}),(0,$.jsx)(e,{className:`h-3 w-20`})]}),(0,$.jsx)(J,{children:(0,$.jsx)(e,{className:`h-3.5 w-20`})}),(0,$.jsx)(J,{children:(0,$.jsx)(e,{className:`ml-auto h-6 w-16`})})]},n)):t.data?.length===0?(0,$.jsx)(q,{children:(0,$.jsx)(J,{colSpan:3,className:`h-40 text-center text-muted-foreground`,children:(0,$.jsxs)(`div`,{className:`mx-auto flex max-w-xs flex-col items-center gap-2`,children:[(0,$.jsx)(S,{className:`size-5`}),(0,$.jsx)(`p`,{className:`font-medium text-foreground`,children:`No API keys`}),(0,$.jsx)(`p`,{children:`Create an API key to connect an app.`})]})})}):t.data?.map(e=>(0,$.jsxs)(q,{className:e.revoked_at_ms===null?void 0:`text-muted-foreground`,children:[(0,$.jsx)(J,{className:`whitespace-normal py-3`,children:(0,$.jsxs)(`div`,{className:`min-w-0 space-y-1`,children:[(0,$.jsx)(`p`,{className:`break-words font-medium text-foreground`,children:e.name}),(0,$.jsxs)(`p`,{className:`font-mono text-xs text-muted-foreground`,children:[e.prefix,`…`]})]})}),(0,$.jsx)(J,{className:`text-xs text-muted-foreground`,children:(0,$.jsx)(`time`,{dateTime:new Date(e.created_at_ms).toISOString(),children:me(e.created_at_ms)})}),(0,$.jsx)(J,{className:`text-right`,children:e.revoked_at_ms===null?(0,$.jsx)(ge,{record:e}):(0,$.jsx)(y,{variant:`outline`,children:`Revoked`})})]},e.id))})]})})]})}function ve(){return(0,$.jsxs)(`div`,{className:`flex h-svh min-h-0 flex-col`,children:[(0,$.jsxs)(`header`,{className:`sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-x-3 gap-y-1 border-b bg-background px-3 py-3 sm:min-h-12 sm:flex-nowrap sm:bg-card/70 sm:px-4 sm:backdrop-blur-sm`,children:[(0,$.jsx)(u,{className:`-ml-1`}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,$.jsx)(S,{"aria-hidden":`true`,className:`size-3.5 text-muted-foreground`}),(0,$.jsx)(`h1`,{className:`text-sm font-medium`,children:`API keys`})]}),(0,$.jsx)(`p`,{className:`basis-full pl-9 text-xs text-muted-foreground sm:basis-auto sm:pl-0`,children:`API keys can download OTA updates and submit insights only.`})]}),(0,$.jsx)(`div`,{className:`min-h-0 min-w-0 flex-1 overflow-y-auto bg-muted/5 p-3 sm:p-6`,children:(0,$.jsx)(`div`,{className:`mx-auto w-full max-w-5xl`,children:(0,$.jsx)(_e,{})})})]})}export{ve as component};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./ConsoleFeatureUnavailable-B9VYGA3N.js";var t=e;export{t as notFoundComponent};
|