akanjs 3.0.0-beta.26 → 3.0.0-beta.28
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/base/baseEnv.ts +19 -5
- package/client/csrTypes.ts +2 -0
- package/client/device.ts +28 -12
- package/client/index.ts +1 -0
- package/client/native/accessibility.ts +1 -0
- package/client/native/app-state.ts +1 -0
- package/client/native/app.ts +1 -0
- package/client/native/appearance.ts +1 -0
- package/client/native/auth-session.ts +1 -0
- package/client/native/autostart.ts +1 -0
- package/client/native/badge.ts +1 -0
- package/client/native/biometric.ts +1 -0
- package/client/native/browser.ts +1 -0
- package/client/native/camera.ts +1 -0
- package/client/native/clipboard.ts +1 -0
- package/client/native/contacts.ts +1 -0
- package/client/native/device.ts +1 -0
- package/client/native/dialog.ts +1 -0
- package/client/native/dock.ts +1 -0
- package/client/native/file-picker.ts +1 -0
- package/client/native/filesystem.ts +1 -0
- package/client/native/geolocation.ts +1 -0
- package/client/native/global-shortcut.ts +1 -0
- package/client/native/haptics.ts +1 -0
- package/client/native/http.ts +1 -0
- package/client/native/iap.ts +1 -0
- package/client/native/keep-awake.ts +1 -0
- package/client/native/keyboard.ts +1 -0
- package/client/native/local-notifications.ts +1 -0
- package/client/native/menu.ts +1 -0
- package/client/native/network.ts +1 -0
- package/client/native/opener.ts +1 -0
- package/client/native/preferences.ts +1 -0
- package/client/native/push.ts +1 -0
- package/client/native/screen-orientation.ts +1 -0
- package/client/native/screen.ts +1 -0
- package/client/native/secure-storage.ts +1 -0
- package/client/native/share.ts +1 -0
- package/client/native/single-instance.ts +1 -0
- package/client/native/splash-screen.ts +1 -0
- package/client/native/sqlite.ts +1 -0
- package/client/native/toast.ts +1 -0
- package/client/native/tray.ts +1 -0
- package/client/native/updates.ts +1 -0
- package/client/native/volume.ts +1 -0
- package/client/native/window-state.ts +1 -0
- package/client/native/window.ts +1 -0
- package/client/native.ts +31 -1
- package/client/resolveServerUrl.ts +11 -0
- package/client/router.ts +8 -0
- package/common/Logger.ts +26 -2
- package/common/RouteLayering.ts +52 -0
- package/common/index.ts +1 -0
- package/index.ts +115 -6
- package/native/desktop.ts +5 -0
- package/package.json +11 -1
- package/server/akanApp.ts +23 -3
- package/server/akanAppHeaders.ts +4 -1
- package/server/akanServer.ts +27 -7
- package/server/index.ts +1 -0
- package/server/lifecycle/orphanGroup.ts +21 -0
- package/server/nativeFile.ts +107 -0
- package/server/ops/opsRoute.ts +3 -2
- package/server/routeTreeBuilder.ts +14 -39
- package/server/routing/apiRouter.ts +26 -3
- package/server/routing/hostAllowlist.ts +24 -0
- package/server/selfExec.ts +25 -0
- package/server/types.tsx +3 -1
- package/server/webRouter.ts +7 -4
- package/service/ipcTypes.ts +4 -0
- package/signal/CrossSiteGuard.ts +7 -0
- package/test/signalTestRuntime.ts +8 -2
- package/types/base/baseEnv.d.ts +1 -0
- package/types/client/csrTypes.d.ts +2 -0
- package/types/client/index.d.ts +1 -0
- package/types/client/native/accessibility.d.ts +1 -0
- package/types/client/native/app-state.d.ts +1 -0
- package/types/client/native/app.d.ts +1 -0
- package/types/client/native/appearance.d.ts +1 -0
- package/types/client/native/auth-session.d.ts +1 -0
- package/types/client/native/autostart.d.ts +1 -0
- package/types/client/native/badge.d.ts +1 -0
- package/types/client/native/biometric.d.ts +1 -0
- package/types/client/native/browser.d.ts +1 -0
- package/types/client/native/camera.d.ts +1 -0
- package/types/client/native/clipboard.d.ts +1 -0
- package/types/client/native/contacts.d.ts +1 -0
- package/types/client/native/device.d.ts +1 -0
- package/types/client/native/dialog.d.ts +1 -0
- package/types/client/native/dock.d.ts +1 -0
- package/types/client/native/file-picker.d.ts +1 -0
- package/types/client/native/filesystem.d.ts +1 -0
- package/types/client/native/geolocation.d.ts +1 -0
- package/types/client/native/global-shortcut.d.ts +1 -0
- package/types/client/native/haptics.d.ts +1 -0
- package/types/client/native/http.d.ts +1 -0
- package/types/client/native/iap.d.ts +1 -0
- package/types/client/native/keep-awake.d.ts +1 -0
- package/types/client/native/keyboard.d.ts +1 -0
- package/types/client/native/local-notifications.d.ts +1 -0
- package/types/client/native/menu.d.ts +1 -0
- package/types/client/native/network.d.ts +1 -0
- package/types/client/native/opener.d.ts +1 -0
- package/types/client/native/preferences.d.ts +1 -0
- package/types/client/native/push.d.ts +1 -0
- package/types/client/native/screen-orientation.d.ts +1 -0
- package/types/client/native/screen.d.ts +1 -0
- package/types/client/native/secure-storage.d.ts +1 -0
- package/types/client/native/share.d.ts +1 -0
- package/types/client/native/single-instance.d.ts +1 -0
- package/types/client/native/splash-screen.d.ts +1 -0
- package/types/client/native/sqlite.d.ts +1 -0
- package/types/client/native/toast.d.ts +1 -0
- package/types/client/native/tray.d.ts +1 -0
- package/types/client/native/updates.d.ts +1 -0
- package/types/client/native/volume.d.ts +1 -0
- package/types/client/native/window-state.d.ts +1 -0
- package/types/client/native/window.d.ts +1 -0
- package/types/client/native.d.ts +14 -2
- package/types/client/resolveServerUrl.d.ts +1 -0
- package/types/client/router.d.ts +3 -0
- package/types/common/RouteLayering.d.ts +28 -0
- package/types/common/index.d.ts +1 -0
- package/types/index.d.ts +112 -6
- package/types/native/desktop.d.ts +3 -0
- package/types/server/akanAppHeaders.d.ts +2 -0
- package/types/server/index.d.ts +1 -0
- package/types/server/lifecycle/orphanGroup.d.ts +7 -0
- package/types/server/nativeFile.d.ts +10 -0
- package/types/server/routing/apiRouter.d.ts +3 -1
- package/types/server/routing/hostAllowlist.d.ts +8 -0
- package/types/server/selfExec.d.ts +8 -0
- package/types/server/types.d.ts +3 -1
- package/types/service/ipcTypes.d.ts +16 -0
- package/types/signal/CrossSiteGuard.d.ts +1 -0
- package/types/ui/recipe/buttonRecipe.d.ts +2 -2
- package/types/vendor/@akanjs/native/packages/cli/src/api.d.ts +57 -4
- package/types/vendor/@akanjs/native/packages/cli/src/config.d.ts +48 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.d.ts +8 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/prepare.d.ts +8 -2
- package/types/vendor/@akanjs/native/packages/cli/src/lib/project.d.ts +10 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/publish.d.ts +24 -0
- package/types/vendor/@akanjs/native/packages/cli/src/lib/updates.d.ts +24 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.d.ts +4 -1
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/macos.d.ts +5 -0
- package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.d.ts +38 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/dispatcher.d.ts +8 -1
- package/types/vendor/@akanjs/native/packages/desktop/src/grants.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/main.d.ts +11 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/paths.d.ts +13 -2
- package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +27 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/relaunch.d.ts +21 -0
- package/types/vendor/@akanjs/native/packages/desktop/src/server.d.ts +79 -0
- package/types/vendor/@akanjs/native/plugins/app/src/index.d.ts +5 -0
- package/types/vendor/@akanjs/native/plugins/file-picker/src/index.d.ts +20 -1
- package/types/vendor/@akanjs/native/plugins/push/src/index.d.ts +9 -0
- package/types/vendor/@akanjs/native/plugins/updates/src/desktop.d.ts +28 -0
- package/types/vendor/@akanjs/native/plugins/volume/src/common.d.ts +10 -0
- package/types/vendor/@akanjs/native/plugins/volume/src/desktop.d.ts +18 -0
- package/types/vendor/@akanjs/native/plugins/volume/src/index.d.ts +28 -0
- package/types/vendor/@akanjs/native/plugins/volume/src.d.ts +1 -0
- package/types/webkit/csrFrameDump.d.ts +42 -0
- package/types/webkit/nativeNavigation.d.ts +1 -0
- package/types/webkit/nativePurchase.d.ts +6 -2
- package/types/webkit/nativeUpdates.d.ts +8 -0
- package/ui/Agent/Attach.tsx +6 -2
- package/ui/CsrImage.tsx +3 -2
- package/ui/System/CSR.tsx +4 -0
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeActivity.kt +5 -1
- package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeBridge.kt +19 -0
- package/vendor/@akanjs/native/native/desktop/Cargo.toml +1 -1
- package/vendor/@akanjs/native/native/desktop/src/lib.rs +161 -25
- package/vendor/@akanjs/native/native/desktop/src/volume.rs +184 -0
- package/vendor/@akanjs/native/native/desktop/src/win/mod.rs +3 -1
- package/vendor/@akanjs/native/native/desktop/src/win/volume.rs +71 -0
- package/vendor/@akanjs/native/native/ios/Sources/AkanNativeShell.swift +12 -2
- package/vendor/@akanjs/native/packages/cli/src/api.ts +142 -12
- package/vendor/@akanjs/native/packages/cli/src/commands/build.ts +5 -3
- package/vendor/@akanjs/native/packages/cli/src/commands/update.ts +10 -71
- package/vendor/@akanjs/native/packages/cli/src/config.ts +41 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/configkeys.ts +9 -2
- package/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.ts +58 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/hmr.ts +2 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/prepare.ts +10 -2
- package/vendor/@akanjs/native/packages/cli/src/lib/project.ts +38 -2
- package/vendor/@akanjs/native/packages/cli/src/lib/publish.ts +104 -0
- package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +85 -5
- package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +1 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.ts +6 -4
- package/vendor/@akanjs/native/packages/cli/src/platforms/desktop.ts +16 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/macos.ts +44 -1
- package/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.ts +436 -0
- package/vendor/@akanjs/native/packages/cli/src/platforms/windows.ts +2 -0
- package/vendor/@akanjs/native/packages/core/src/runtime.ts +26 -5
- package/vendor/@akanjs/native/packages/desktop/src/dispatcher.ts +20 -0
- package/vendor/@akanjs/native/packages/desktop/src/grants.ts +47 -0
- package/vendor/@akanjs/native/packages/desktop/src/host.ts +102 -14
- package/vendor/@akanjs/native/packages/desktop/src/main.ts +59 -11
- package/vendor/@akanjs/native/packages/desktop/src/paths.ts +38 -4
- package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +28 -0
- package/vendor/@akanjs/native/packages/desktop/src/relaunch.ts +159 -0
- package/vendor/@akanjs/native/packages/desktop/src/server.ts +493 -0
- package/vendor/@akanjs/native/plugins/app/android/AppPlugin.kt +14 -0
- package/vendor/@akanjs/native/plugins/app/native-plugin.json +2 -2
- package/vendor/@akanjs/native/plugins/app/src/desktop.ts +5 -0
- package/vendor/@akanjs/native/plugins/app/src/index.ts +6 -1
- package/vendor/@akanjs/native/plugins/app/src/web.ts +3 -0
- package/vendor/@akanjs/native/plugins/file-picker/src/desktop.ts +39 -2
- package/vendor/@akanjs/native/plugins/file-picker/src/index.ts +36 -1
- package/vendor/@akanjs/native/plugins/push/android/PushPlugin.kt +9 -1
- package/vendor/@akanjs/native/plugins/push/ios/PushPlugin.swift +4 -0
- package/vendor/@akanjs/native/plugins/push/src/index.ts +10 -0
- package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +464 -452
- package/vendor/@akanjs/native/plugins/volume/android/VolumePlugin.kt +107 -0
- package/vendor/@akanjs/native/plugins/volume/native-plugin.json +14 -0
- package/vendor/@akanjs/native/plugins/volume/src/common.ts +28 -0
- package/vendor/@akanjs/native/plugins/volume/src/desktop.ts +185 -0
- package/vendor/@akanjs/native/plugins/volume/src/index.ts +32 -0
- package/webkit/CsrRouteTable.ts +15 -35
- package/webkit/RenderLayer.tsx +71 -6
- package/webkit/bootCsr.tsx +11 -8
- package/webkit/csrFrameDump.ts +67 -0
- package/webkit/nativeNavigation.ts +17 -0
- package/webkit/nativePurchase.ts +12 -2
- package/webkit/nativeUpdates.ts +55 -0
- package/webkit/useCsrValues.ts +27 -0
|
@@ -15,8 +15,9 @@ import {
|
|
|
15
15
|
getRouteExports,
|
|
16
16
|
Logger,
|
|
17
17
|
matchRoutePattern,
|
|
18
|
-
parseBasePaths,
|
|
19
18
|
parseRouteModuleKey,
|
|
19
|
+
type RouteLayer,
|
|
20
|
+
RouteLayering,
|
|
20
21
|
routeSegmentToTreePath,
|
|
21
22
|
} from "akanjs/common";
|
|
22
23
|
import { createElement } from "react";
|
|
@@ -54,15 +55,12 @@ export class RouteTreeBuilder {
|
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
readonly #context: PagesContext;
|
|
57
|
-
readonly #baseLayoutPaths: string[];
|
|
58
58
|
readonly #routeMap = new Map<string, Route>();
|
|
59
59
|
readonly #pagePatterns: { key: string; pattern: string }[] = [];
|
|
60
60
|
readonly #fallbackRoutes: LayoutFallbackRoute[] = [];
|
|
61
61
|
|
|
62
62
|
constructor(context: PagesContext) {
|
|
63
63
|
this.#context = context;
|
|
64
|
-
const basePaths = process.env.AKAN_PUBLIC_BASE_PATHS ? parseBasePaths(process.env.AKAN_PUBLIC_BASE_PATHS) : null;
|
|
65
|
-
this.#baseLayoutPaths = ["/", "/:lang", ...(basePaths?.map((bp) => `/:lang/${bp}`) ?? [])];
|
|
66
64
|
this.#routeMap.set("/", { path: "/", children: new Map() });
|
|
67
65
|
}
|
|
68
66
|
|
|
@@ -169,7 +167,7 @@ export class RouteTreeBuilder {
|
|
|
169
167
|
targetRouteMap.set(targetPath, {
|
|
170
168
|
...(targetRouteMap.get(targetPath) ?? { path: targetPath, children: new Map<string, Route>() }),
|
|
171
169
|
...(parsed.kind === "layout"
|
|
172
|
-
? { renderLayout: routeRender }
|
|
170
|
+
? { renderLayout: routeRender, isRootLayout: parsed.isInternalRootLayout }
|
|
173
171
|
: {
|
|
174
172
|
renderPage: routeRender,
|
|
175
173
|
pageIncludesOwnLayout: parsed.leaf === "_index",
|
|
@@ -178,48 +176,27 @@ export class RouteTreeBuilder {
|
|
|
178
176
|
} as Route);
|
|
179
177
|
}
|
|
180
178
|
|
|
181
|
-
#getPathRoutes(
|
|
182
|
-
route
|
|
183
|
-
parentRootLayouts: RouteRender[] = [],
|
|
184
|
-
parentLayouts: RouteRender[] = [],
|
|
185
|
-
parentPaths: string[] = [],
|
|
186
|
-
parentHead?: ResolveHead,
|
|
187
|
-
parentRootRenders: RouteRender[] = [],
|
|
188
|
-
): PathRoute[] {
|
|
189
|
-
const parentPath = parentPaths.filter((p) => p !== "/").join("");
|
|
190
|
-
const currentPathSegment = /^\/\(.*\)$/.test(route.path) ? "" : route.path;
|
|
191
|
-
const isRoot = this.#baseLayoutPaths.includes(parentPath + currentPathSegment) && parentRootLayouts.length < 2;
|
|
192
|
-
const routePath = parentPath + currentPathSegment;
|
|
193
|
-
const pathSegments = [...parentPaths, ...(currentPathSegment ? [currentPathSegment] : [])];
|
|
194
|
-
const currentRootLayout = isRoot && route.renderLayout ? route.renderLayout : null;
|
|
195
|
-
|
|
196
|
-
const currentOverrideRenders = route.renderOverrides ? [route.renderOverrides] : [];
|
|
197
|
-
const nodeRenders = [...currentOverrideRenders, ...(route.renderLayout ? [route.renderLayout] : [])];
|
|
198
|
-
const rootLayoutStack = [...parentRootLayouts, ...(currentRootLayout ? [currentRootLayout] : [])];
|
|
199
|
-
const renderRootLayouts = isRoot ? [...parentRootRenders, ...nodeRenders] : parentRootRenders;
|
|
200
|
-
const renderLayouts = isRoot ? parentLayouts : [...parentLayouts, ...nodeRenders];
|
|
179
|
+
#getPathRoutes(route: Route, parent: RouteLayer<RouteRender> | null = null, parentHead?: ResolveHead): PathRoute[] {
|
|
180
|
+
const layer = RouteLayering.of(route, parent);
|
|
201
181
|
if (route.renderLayout) {
|
|
202
182
|
this.#fallbackRoutes.push({
|
|
203
|
-
path:
|
|
204
|
-
pathSegments,
|
|
205
|
-
renderRootLayouts,
|
|
206
|
-
renderLayouts,
|
|
183
|
+
path: layer.path,
|
|
184
|
+
pathSegments: layer.pathSegments,
|
|
185
|
+
renderRootLayouts: layer.renderRootLayouts,
|
|
186
|
+
renderLayouts: layer.renderLayouts,
|
|
207
187
|
});
|
|
208
188
|
}
|
|
209
189
|
const routeHead = RouteTreeBuilder.#composeHeadResolvers(route.renderLayout?.resolveHead, parentHead);
|
|
210
|
-
const pageNodeRenders = route.pageIncludesOwnLayout === false ? currentOverrideRenders : nodeRenders;
|
|
211
|
-
const pageRenderRootLayouts = isRoot ? [...parentRootRenders, ...pageNodeRenders] : parentRootRenders;
|
|
212
|
-
const pageRenderLayouts = isRoot ? parentLayouts : [...parentLayouts, ...pageNodeRenders];
|
|
213
190
|
const pageHead = route.pageIncludesOwnLayout === false ? parentHead : routeHead;
|
|
214
191
|
return [
|
|
215
192
|
...(route.renderPage
|
|
216
193
|
? [
|
|
217
194
|
{
|
|
218
|
-
path:
|
|
219
|
-
pathSegments,
|
|
195
|
+
path: layer.path,
|
|
196
|
+
pathSegments: layer.pathSegments,
|
|
220
197
|
renderPage: route.renderPage,
|
|
221
|
-
renderRootLayouts: pageRenderRootLayouts,
|
|
222
|
-
renderLayouts: pageRenderLayouts,
|
|
198
|
+
renderRootLayouts: layer.pageRenderRootLayouts,
|
|
199
|
+
renderLayouts: layer.pageRenderLayouts,
|
|
223
200
|
resolveHead: RouteTreeBuilder.#composeHeadResolvers(route.renderPage.resolveHead, pageHead),
|
|
224
201
|
isSpecialRoute: route.isSpecialRoute,
|
|
225
202
|
pageState: route.pageState ?? defaultPageState,
|
|
@@ -227,9 +204,7 @@ export class RouteTreeBuilder {
|
|
|
227
204
|
]
|
|
228
205
|
: []),
|
|
229
206
|
...(route.children.size
|
|
230
|
-
? [...route.children.values()].flatMap((child) =>
|
|
231
|
-
this.#getPathRoutes(child, rootLayoutStack, renderLayouts, pathSegments, routeHead, renderRootLayouts),
|
|
232
|
-
)
|
|
207
|
+
? [...route.children.values()].flatMap((child) => this.#getPathRoutes(child, layer, routeHead))
|
|
233
208
|
: []),
|
|
234
209
|
];
|
|
235
210
|
}
|
|
@@ -8,6 +8,7 @@ import { copyBunRequestFields, type WebProxyRunner } from "../proxy";
|
|
|
8
8
|
import { SignalResolver } from "../resolver";
|
|
9
9
|
import type { HttpRoutes, SignalRouteOptions, WebsocketRoutes } from "../types";
|
|
10
10
|
import { AppWsData } from "./appWsData";
|
|
11
|
+
import type { HostAllowlist } from "./hostAllowlist";
|
|
11
12
|
|
|
12
13
|
export interface HmrStateSource {
|
|
13
14
|
readonly state: {
|
|
@@ -34,6 +35,7 @@ export interface ApiRouteInputs {
|
|
|
34
35
|
renderEnvRoutes: HttpRoutes;
|
|
35
36
|
upgradeAppWs: (req: Request, data: AppWsData) => boolean;
|
|
36
37
|
webProxyRunner?: WebProxyRunner | null;
|
|
38
|
+
hostAllowlist?: HostAllowlist | null;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
type RouteValue = NonNullHttpRoutes[keyof NonNullHttpRoutes];
|
|
@@ -62,6 +64,7 @@ export class ApiRouter {
|
|
|
62
64
|
renderEnvRoutes,
|
|
63
65
|
upgradeAppWs,
|
|
64
66
|
webProxyRunner,
|
|
67
|
+
hostAllowlist,
|
|
65
68
|
}: ApiRouteInputs): NonNullHttpRoutes {
|
|
66
69
|
const endpointEntries = Object.entries(routes ?? {}).map(
|
|
67
70
|
([p, handler]) =>
|
|
@@ -76,6 +79,12 @@ export class ApiRouter {
|
|
|
76
79
|
const endpointPaths = new Set([...endpointEntries.map(([path]) => path), ...builtinEntries.map(([path]) => path)]);
|
|
77
80
|
const routeTable = {
|
|
78
81
|
[`${prefix}${websocketPrefix}` as "/api/ws"]: (req) => {
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
CrossSiteGuard.assertOrigin(req, new URL(req.url), "websocket");
|
|
85
|
+
} catch {
|
|
86
|
+
return new Response("Forbidden", { status: 403 });
|
|
87
|
+
}
|
|
79
88
|
const upgraded = upgradeAppWs(req, AppWsData.fromRequest(req));
|
|
80
89
|
if (upgraded) return;
|
|
81
90
|
return new Response("Failed to upgrade to WebSocket", { status: 500 });
|
|
@@ -84,9 +93,10 @@ export class ApiRouter {
|
|
|
84
93
|
...Object.fromEntries(builtinEntries),
|
|
85
94
|
...(renderEnvRoutes ?? {}),
|
|
86
95
|
} as NonNullHttpRoutes;
|
|
87
|
-
|
|
96
|
+
const served = webProxyRunner
|
|
88
97
|
? ApiRouter.#wrapRoutesWithWebProxy(routeTable, webProxyRunner, prefix, endpointPaths)
|
|
89
98
|
: routeTable;
|
|
99
|
+
return hostAllowlist ? ApiRouter.#guardHosts(served, hostAllowlist) : served;
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
static buildWebsocketHandlers({
|
|
@@ -214,6 +224,15 @@ export class ApiRouter {
|
|
|
214
224
|
) as NonNullHttpRoutes;
|
|
215
225
|
}
|
|
216
226
|
|
|
227
|
+
static #guardHosts(routes: NonNullHttpRoutes, allowlist: HostAllowlist): NonNullHttpRoutes {
|
|
228
|
+
return Object.fromEntries(
|
|
229
|
+
Object.entries(routes).map(([path, route]) => [
|
|
230
|
+
path,
|
|
231
|
+
ApiRouter.#mapRoute(route, (handler) => (req) => (allowlist.allows(req) ? handler(req) : allowlist.refuse())),
|
|
232
|
+
]),
|
|
233
|
+
) as NonNullHttpRoutes;
|
|
234
|
+
}
|
|
235
|
+
|
|
217
236
|
static #isApiRoute(path: string, apiPrefix: string): boolean {
|
|
218
237
|
const normalized = apiPrefix.replace(/\/$/, "");
|
|
219
238
|
return path === normalized || path.startsWith(`${normalized}/`);
|
|
@@ -242,12 +261,16 @@ export class ApiRouter {
|
|
|
242
261
|
|
|
243
262
|
static #mapRoute(route: RouteValue, wrap: (handler: RouteHandler) => RouteHandler): RouteValue {
|
|
244
263
|
if (typeof route === "function") return wrap(route as RouteHandler) as RouteValue;
|
|
245
|
-
if (route instanceof Response) return wrap(() => route) as RouteValue;
|
|
264
|
+
if (route instanceof Response) return wrap(() => route.clone()) as RouteValue;
|
|
246
265
|
if (!route || typeof route !== "object") return route;
|
|
247
266
|
return Object.fromEntries(
|
|
248
267
|
Object.entries(route).map(([method, handler]) => [
|
|
249
268
|
method,
|
|
250
|
-
typeof handler === "function"
|
|
269
|
+
typeof handler === "function"
|
|
270
|
+
? wrap(handler as RouteHandler)
|
|
271
|
+
: handler instanceof Response
|
|
272
|
+
? wrap(() => handler.clone())
|
|
273
|
+
: handler,
|
|
251
274
|
]),
|
|
252
275
|
) as RouteValue;
|
|
253
276
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export class HostAllowlist {
|
|
4
|
+
readonly #hosts: Set<string>;
|
|
5
|
+
|
|
6
|
+
constructor(hosts: Iterable<string>) {
|
|
7
|
+
this.#hosts = new Set([...hosts].map((host) => host.trim().toLowerCase()).filter(Boolean));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** `AKAN_ALLOWED_HOSTS`: comma-separated `host:port` entries; unset or blank serves every Host. */
|
|
11
|
+
static fromEnv(env: Record<string, string | undefined> = process.env): HostAllowlist | null {
|
|
12
|
+
const allowlist = new HostAllowlist((env.AKAN_ALLOWED_HOSTS ?? "").split(","));
|
|
13
|
+
return allowlist.#hosts.size ? allowlist : null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
allows(req: Request): boolean {
|
|
17
|
+
const host = req.headers.get("host")?.trim().toLowerCase();
|
|
18
|
+
return !!host && this.#hosts.has(host);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
refuse(): Response {
|
|
22
|
+
return new Response("Forbidden", { status: 403 });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export class SelfExec {
|
|
4
|
+
static #beBun: string | undefined;
|
|
5
|
+
|
|
6
|
+
static adopt() {
|
|
7
|
+
const value = process.env.BUN_BE_BUN;
|
|
8
|
+
if (value === undefined) return;
|
|
9
|
+
SelfExec.#beBun = value;
|
|
10
|
+
delete process.env.BUN_BE_BUN;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** A desktop app's carried server: only its shell starts the app executable as Bun. */
|
|
14
|
+
static get carried(): boolean {
|
|
15
|
+
return SelfExec.#beBun !== undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static env(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
19
|
+
return SelfExec.#beBun === undefined ? env : { ...env, BUN_BE_BUN: SelfExec.#beBun };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static command(script: string, ...args: string[]): string[] {
|
|
23
|
+
return [process.execPath, ...process.execArgv, script, ...args];
|
|
24
|
+
}
|
|
25
|
+
}
|
package/server/types.tsx
CHANGED
|
@@ -125,7 +125,9 @@ export const getWebConfigFromEnv = (): AkanWebConfig => {
|
|
|
125
125
|
|
|
126
126
|
export interface MobileDeepLinkAssociation {
|
|
127
127
|
targetName: string;
|
|
128
|
-
|
|
128
|
+
/** Null when the target names no id for the platform; that platform then gets no association. */
|
|
129
|
+
iosAppId: string | null;
|
|
130
|
+
androidAppId: string | null;
|
|
129
131
|
domains: string[];
|
|
130
132
|
iosTeamId?: string;
|
|
131
133
|
androidSha256CertFingerprints?: string[];
|
package/server/webRouter.ts
CHANGED
|
@@ -1168,9 +1168,9 @@ export class WebRouter {
|
|
|
1168
1168
|
const associations = artifact.deepLinkAssociations ?? [];
|
|
1169
1169
|
if (pathname === APPLE_APP_SITE_ASSOCIATION_PATH) {
|
|
1170
1170
|
const details = associations
|
|
1171
|
-
.filter((association) => association.domains.length > 0 && association.iosTeamId)
|
|
1171
|
+
.filter((association) => association.domains.length > 0 && association.iosTeamId && association.iosAppId)
|
|
1172
1172
|
.map((association) => ({
|
|
1173
|
-
appIDs: [`${association.iosTeamId}.${association.
|
|
1173
|
+
appIDs: [`${association.iosTeamId}.${association.iosAppId}`],
|
|
1174
1174
|
components: [{ "/": "/*" }],
|
|
1175
1175
|
}));
|
|
1176
1176
|
if (details.length === 0) return null;
|
|
@@ -1180,14 +1180,17 @@ export class WebRouter {
|
|
|
1180
1180
|
const packageSuffixes = process.env.AKAN_PUBLIC_ENV === "main" ? [""] : ["", ".debug"];
|
|
1181
1181
|
const assetLinks = associations
|
|
1182
1182
|
.filter(
|
|
1183
|
-
(association) =>
|
|
1183
|
+
(association) =>
|
|
1184
|
+
association.domains.length > 0 &&
|
|
1185
|
+
!!association.androidAppId &&
|
|
1186
|
+
(association.androidSha256CertFingerprints?.length ?? 0) > 0,
|
|
1184
1187
|
)
|
|
1185
1188
|
.flatMap((association) =>
|
|
1186
1189
|
packageSuffixes.map((suffix) => ({
|
|
1187
1190
|
relation: ["delegate_permission/common.handle_all_urls"],
|
|
1188
1191
|
target: {
|
|
1189
1192
|
namespace: "android_app",
|
|
1190
|
-
package_name: `${association.
|
|
1193
|
+
package_name: `${association.androidAppId}${suffix}`,
|
|
1191
1194
|
sha256_cert_fingerprints: association.androidSha256CertFingerprints,
|
|
1192
1195
|
},
|
|
1193
1196
|
})),
|
package/service/ipcTypes.ts
CHANGED
|
@@ -143,6 +143,7 @@ export type AkanIpcMessage =
|
|
|
143
143
|
/** Actual websocket upstream the child bound; may differ from the preferred port when it was in use. */
|
|
144
144
|
wsUpstream?: Extract<AkanUpstream, { type: "tcp" }>;
|
|
145
145
|
healthPath?: string;
|
|
146
|
+
crossSite?: { allowedOrigins: string[]; enabled: boolean };
|
|
146
147
|
}
|
|
147
148
|
| { type: "backend-ready"; pid: number }
|
|
148
149
|
| { type: "pubsub.publish"; roomId: string; data: object | object[]; origin?: string }
|
|
@@ -163,6 +164,9 @@ export type AkanIpcMessage =
|
|
|
163
164
|
/** Hub → child: the lowest severity any subscriber wants; `null` tells the child to stop forwarding. */
|
|
164
165
|
| { type: "log.level"; minSev: number | null }
|
|
165
166
|
| { type: "shutdown"; signal?: string }
|
|
167
|
+
/** Desktop server → the shell that started it: the path behind a file picker grant (forServer). */
|
|
168
|
+
| { type: "file.resolve"; id: string; grant: string }
|
|
169
|
+
| { type: "file.resolved"; id: string; path?: string; mode?: "read" | "write" | "folder"; error?: string }
|
|
166
170
|
| { type: "error"; message: string; stack?: string; pid?: number };
|
|
167
171
|
|
|
168
172
|
export const sendAkanIpc = (message: AkanIpcMessage) => {
|
package/signal/CrossSiteGuard.ts
CHANGED
|
@@ -14,16 +14,23 @@ export class CrossSiteGuard {
|
|
|
14
14
|
* Android and Windows; both WebViews send exactly that as `Origin`. */
|
|
15
15
|
static readonly nativeOrigins = ["app://localhost", "https://app.localhost"] as const;
|
|
16
16
|
static #enabled = true;
|
|
17
|
+
static #allowedOrigins: string[] = [];
|
|
17
18
|
static #allowed = new Set<string>(CrossSiteGuard.nativeOrigins);
|
|
18
19
|
|
|
19
20
|
/** Applied at boot from the mounting app's `option.ts`; the native shells stay allowed unless disabled. */
|
|
20
21
|
static configure({ allowedOrigins = [], enabled = true }: CrossSiteOption) {
|
|
21
22
|
CrossSiteGuard.#enabled = enabled;
|
|
23
|
+
CrossSiteGuard.#allowedOrigins = [...allowedOrigins];
|
|
22
24
|
CrossSiteGuard.#allowed = new Set([...CrossSiteGuard.nativeOrigins, ...allowedOrigins]);
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
static option(): Required<CrossSiteOption> {
|
|
28
|
+
return { allowedOrigins: [...CrossSiteGuard.#allowedOrigins], enabled: CrossSiteGuard.#enabled };
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
static reset() {
|
|
26
32
|
CrossSiteGuard.#enabled = true;
|
|
33
|
+
CrossSiteGuard.#allowedOrigins = [];
|
|
27
34
|
CrossSiteGuard.#allowed = new Set(CrossSiteGuard.nativeOrigins);
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -20,7 +20,7 @@ export interface SignalTestContext<Fetch = FetchProxy> {
|
|
|
20
20
|
export type SignalTestOptions = Pick<TestServerOptions, "storage" | "workerId" | "port" | "serverMode">;
|
|
21
21
|
|
|
22
22
|
type SignalServerModule = {
|
|
23
|
-
env
|
|
23
|
+
env?: BackendEnv;
|
|
24
24
|
fetch: FetchProxy;
|
|
25
25
|
lib: AkanLib;
|
|
26
26
|
};
|
|
@@ -68,6 +68,11 @@ const importServerModule = async (type: "app" | "lib", name: string): Promise<Si
|
|
|
68
68
|
|
|
69
69
|
const importLibModule = async (name: string): Promise<SignalServerModule> => await import(`@libs/${name}/server`);
|
|
70
70
|
|
|
71
|
+
const importTestingEnv = async (type: "app" | "lib", name: string, targetModule: SignalServerModule) =>
|
|
72
|
+
type === "app"
|
|
73
|
+
? ((await import(`@apps/${name}/env/env.server.testing`)) as { env?: BackendEnv }).env
|
|
74
|
+
: targetModule.env;
|
|
75
|
+
|
|
71
76
|
export const setupSignalTestTarget = async <Fetch = FetchProxy>(
|
|
72
77
|
{
|
|
73
78
|
type = process.env.AKAN_TEST_TARGET_TYPE as "app" | "lib" | undefined,
|
|
@@ -96,10 +101,11 @@ export const setupSignalTestTarget = async <Fetch = FetchProxy>(
|
|
|
96
101
|
Promise.all((libNames ?? []).filter((libName) => libName !== name).map(importLibModule)),
|
|
97
102
|
importServerModule(type, name),
|
|
98
103
|
]);
|
|
104
|
+
const testingEnv = await importTestingEnv(type, name, targetModule);
|
|
99
105
|
const target: SignalTestTarget = {
|
|
100
106
|
type,
|
|
101
107
|
name,
|
|
102
|
-
env: { ...env, ...
|
|
108
|
+
env: { ...env, ...testingEnv },
|
|
103
109
|
fetch: targetModule.fetch,
|
|
104
110
|
libs: [...dependencyModules.map((mod) => mod.lib), targetModule.lib],
|
|
105
111
|
};
|
package/types/base/baseEnv.d.ts
CHANGED
|
@@ -171,6 +171,8 @@ export interface Route {
|
|
|
171
171
|
path: string;
|
|
172
172
|
renderPage?: RouteRender;
|
|
173
173
|
renderLayout?: RouteRender;
|
|
174
|
+
/** `renderLayout` is a generated `__root_layout`: a root boundary the page generator found. */
|
|
175
|
+
isRootLayout?: boolean;
|
|
174
176
|
/** Synthetic layout render from a `_overrides.tsx` at this node; wraps the subtree in a UI-override provider. */
|
|
175
177
|
renderOverrides?: RouteRender;
|
|
176
178
|
pageIncludesOwnLayout?: boolean;
|
package/types/client/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from "./device.d.ts";
|
|
|
8
8
|
export * from "./frameConfig.d.ts";
|
|
9
9
|
export * from "./locale.d.ts";
|
|
10
10
|
export * from "./makePageProto.d.ts";
|
|
11
|
+
export * from "./resolveServerUrl.d.ts";
|
|
11
12
|
export * from "./route.d.ts";
|
|
12
13
|
export * from "./router.d.ts";
|
|
13
14
|
export * from "./rscNavigation.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/accessibility/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/app-state/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/app/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/appearance/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/auth-session/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/autostart/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/badge/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/biometric/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/browser/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/camera/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/clipboard/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/contacts/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/device/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/dialog/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/dock/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/file-picker/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/filesystem/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/geolocation/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/global-shortcut/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/haptics/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/http/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/iap/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/keep-awake/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/keyboard/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/local-notifications/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/menu/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/network/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/opener/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/preferences/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/push/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/screen-orientation/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/screen/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/share/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/single-instance/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/splash-screen/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/sqlite/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/toast/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/tray/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/updates/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/volume/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/window-state/src/index.d.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../vendor/@akanjs/native/plugins/window/src/index.d.ts";
|
package/types/client/native.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { browser } from "../vendor/@akanjs/native/plugins/browser/src/index.d.ts";
|
|
2
2
|
import { opener } from "../vendor/@akanjs/native/plugins/opener/src/index.d.ts";
|
|
3
|
-
export {
|
|
3
|
+
export type { LiveValue, Plugin } from "../vendor/@akanjs/native/packages/core/src/index.d.ts";
|
|
4
|
+
export { AkanNativeError, createLiveValue, definePlugin, defineWebPlugin, fileBlob, isAkanNativeError, releaseFile, shallowEqual, } from "../vendor/@akanjs/native/packages/core/src/index.d.ts";
|
|
4
5
|
export { app } from "../vendor/@akanjs/native/plugins/app/src/index.d.ts";
|
|
5
6
|
export { appState } from "../vendor/@akanjs/native/plugins/app-state/src/index.d.ts";
|
|
7
|
+
export type { AuthSessionApi } from "../vendor/@akanjs/native/plugins/auth-session/src/index.d.ts";
|
|
8
|
+
export { authSession } from "../vendor/@akanjs/native/plugins/auth-session/src/index.d.ts";
|
|
6
9
|
export type { Photo } from "../vendor/@akanjs/native/plugins/camera/src/index.d.ts";
|
|
7
10
|
export type { Contact } from "../vendor/@akanjs/native/plugins/contacts/src/index.d.ts";
|
|
8
11
|
export type { DeviceInfo } from "../vendor/@akanjs/native/plugins/device/src/index.d.ts";
|
|
9
12
|
export { device } from "../vendor/@akanjs/native/plugins/device/src/index.d.ts";
|
|
10
13
|
export { dialog } from "../vendor/@akanjs/native/plugins/dialog/src/index.d.ts";
|
|
14
|
+
export type { DirectoryFile, PickDirectoryOptions, PickDirectoryResult, PickedFile, PickFilesOptions, SaveFileOptions, SaveFileResult, } from "../vendor/@akanjs/native/plugins/file-picker/src/index.d.ts";
|
|
15
|
+
export { filePicker } from "../vendor/@akanjs/native/plugins/file-picker/src/index.d.ts";
|
|
11
16
|
export type { Position } from "../vendor/@akanjs/native/plugins/geolocation/src/index.d.ts";
|
|
12
17
|
export { haptics } from "../vendor/@akanjs/native/plugins/haptics/src/index.d.ts";
|
|
13
18
|
export type { IapProduct, IapTransaction } from "../vendor/@akanjs/native/plugins/iap/src/index.d.ts";
|
|
@@ -16,6 +21,11 @@ export { preferences } from "../vendor/@akanjs/native/plugins/preferences/src/in
|
|
|
16
21
|
export type { PushAction, PushMessage, PushPermissionState, PushToken as NativePushToken, } from "../vendor/@akanjs/native/plugins/push/src/index.d.ts";
|
|
17
22
|
export { push } from "../vendor/@akanjs/native/plugins/push/src/index.d.ts";
|
|
18
23
|
export { secureStorage } from "../vendor/@akanjs/native/plugins/secure-storage/src/index.d.ts";
|
|
24
|
+
export type { UpdateCheck, UpdateProgress, UpdateState } from "../vendor/@akanjs/native/plugins/updates/src/index.d.ts";
|
|
25
|
+
export { markReady, updates, useUpdateState } from "../vendor/@akanjs/native/plugins/updates/src/index.d.ts";
|
|
26
|
+
export type { VolumeState } from "../vendor/@akanjs/native/plugins/volume/src/index.d.ts";
|
|
27
|
+
export { volume } from "../vendor/@akanjs/native/plugins/volume/src/index.d.ts";
|
|
28
|
+
export { useLiveValue, usePluginEvent } from "../vendor/@akanjs/native/packages/react/src/index.d.ts";
|
|
19
29
|
export { browser, opener };
|
|
20
30
|
export declare const loadCamera: () => Promise<typeof import("../vendor/@akanjs/native/plugins/camera/src/index.d.ts")>;
|
|
21
31
|
export declare const loadContacts: () => Promise<typeof import("../vendor/@akanjs/native/plugins/contacts/src/index.d.ts")>;
|
|
@@ -23,7 +33,9 @@ export declare const loadGeolocation: () => Promise<typeof import("../vendor/@ak
|
|
|
23
33
|
export declare const loadIap: () => Promise<typeof import("../vendor/@akanjs/native/plugins/iap/src/index.d.ts")>;
|
|
24
34
|
/** Inside an iOS or Android shell of the native runtime; a mobile target opened in a browser is not. */
|
|
25
35
|
export declare const isNativeApp: () => boolean;
|
|
36
|
+
/** Inside any shell of the native runtime, desktop included. */
|
|
37
|
+
export declare const isNativeShell: () => boolean;
|
|
26
38
|
export declare const nativePlatform: () => "ios" | "android" | null;
|
|
27
|
-
export declare const desktopPlatform: () => "
|
|
39
|
+
export declare const desktopPlatform: () => "macos" | "windows" | "linux" | null;
|
|
28
40
|
/** http(s) in the in-app browser, anything else (mailto:, tel:) in the app the system picks. */
|
|
29
41
|
export declare const openExternalUrl: (url: string) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const resolveServerUrl: (url: string) => string;
|
package/types/client/router.d.ts
CHANGED
|
@@ -76,6 +76,9 @@ declare class Router {
|
|
|
76
76
|
backOrFallback(fallbackHref?: string, routeOptions?: RouteOptions): never;
|
|
77
77
|
back(routeOptions?: RouteOptions): never;
|
|
78
78
|
refresh(): never;
|
|
79
|
+
/** Client-side redirects so far: a render that saw this change while it ran redirected instead of drawing. A method
|
|
80
|
+
* for the reason `navigation()` is one. */
|
|
81
|
+
redirectCount(): number;
|
|
79
82
|
redirect(href: string, options?: RedirectOptions): never;
|
|
80
83
|
notFound(): never;
|
|
81
84
|
setLang(lang: string): never;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface LayeredRoute<Render> {
|
|
2
|
+
/** The tree segment: `/`, `/:lang`, `/(group)`, `/foo`. */
|
|
3
|
+
path: string;
|
|
4
|
+
renderLayout?: Render;
|
|
5
|
+
/** A generated `__root_layout`: one of the root boundaries the page generator found. */
|
|
6
|
+
isRootLayout?: boolean;
|
|
7
|
+
renderOverrides?: Render;
|
|
8
|
+
/** `false` for a named page file, which sits beside its directory's layout rather than under it. */
|
|
9
|
+
pageIncludesOwnLayout?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface RouteLayer<Render> {
|
|
12
|
+
/** The URL pattern down to this node; a route group adds nothing to it. */
|
|
13
|
+
path: string;
|
|
14
|
+
pathSegments: string[];
|
|
15
|
+
isRoot: boolean;
|
|
16
|
+
/** The root layout above or at this node, overrides left out: once there is one, nothing below is a root. */
|
|
17
|
+
rootLayouts: Render[];
|
|
18
|
+
renderRootLayouts: Render[];
|
|
19
|
+
renderLayouts: Render[];
|
|
20
|
+
/** What a page file at this node renders inside: without this node's layout for a named page file. */
|
|
21
|
+
pageRenderRootLayouts: Render[];
|
|
22
|
+
pageRenderLayouts: Render[];
|
|
23
|
+
}
|
|
24
|
+
export declare class RouteLayering {
|
|
25
|
+
#private;
|
|
26
|
+
static of<Render>(route: LayeredRoute<Render>, parent: RouteLayer<Render> | null): RouteLayer<Render>;
|
|
27
|
+
}
|
|
28
|
+
export {};
|