openxiangda 1.0.89 → 1.0.90

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.
@@ -3508,6 +3508,384 @@ import {
3508
3508
  useState as useState4
3509
3509
  } from "react";
3510
3510
 
3511
+ // packages/sdk/src/runtime/host/browserHost.ts
3512
+ var NAMESPACE_ROOT_CLASS2 = "sy-app-workspace";
3513
+ var defaultModuleLoader = (url2) => import(
3514
+ /* @vite-ignore */
3515
+ url2
3516
+ );
3517
+ var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
3518
+ var getDefaultServicePrefix = () => typeof window !== "undefined" ? trimTrailingSlash(window.__OPENXIANGDA_SERVICE_PREFIX__ || "/service") : "/service";
3519
+ var joinServicePath = (servicePrefix, path) => {
3520
+ if (/^https?:\/\//i.test(path)) return path;
3521
+ const normalizedPrefix = trimTrailingSlash(servicePrefix || "/service");
3522
+ if (path.startsWith(normalizedPrefix)) return path;
3523
+ return `${normalizedPrefix}${path.startsWith("/") ? path : `/${path}`}`;
3524
+ };
3525
+ var appendQuery = (url2, query) => {
3526
+ if (!query) return url2;
3527
+ return `${url2}${url2.includes("?") ? "&" : "?"}${query}`;
3528
+ };
3529
+ var normalizeMethod2 = (method4) => {
3530
+ const value = String(method4 || "get").toUpperCase();
3531
+ return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(value) ? value : "GET";
3532
+ };
3533
+ var normalizeCssIsolation2 = (value) => {
3534
+ if (value === "namespace" || value === "shadow" || value === "none") {
3535
+ return value;
3536
+ }
3537
+ return "none";
3538
+ };
3539
+ var normalizeEnvelopeCode2 = (value, fallback) => {
3540
+ if (value === void 0 || value === null || value === "") return fallback;
3541
+ const normalized = Number(value);
3542
+ return Number.isFinite(normalized) ? normalized : String(value);
3543
+ };
3544
+ var isSuccessCode4 = (value) => {
3545
+ if (value === void 0 || value === null || value === "") return true;
3546
+ const normalized = Number(value);
3547
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
3548
+ };
3549
+ var parseJsonResponse = async (response) => {
3550
+ const payload = await response.json().catch(() => null);
3551
+ if (!response.ok) {
3552
+ const message7 = payload && typeof payload === "object" ? payload.message || payload.error || response.statusText : response.statusText;
3553
+ throw new Error(message7 || "\u8BF7\u6C42\u5931\u8D25");
3554
+ }
3555
+ if (payload && typeof payload === "object" && "code" in payload) {
3556
+ const code = normalizeEnvelopeCode2(payload.code, response.status);
3557
+ return {
3558
+ code,
3559
+ success: payload.success !== false && isSuccessCode4(code),
3560
+ message: payload.message,
3561
+ result: payload.result ?? payload.data ?? null,
3562
+ data: payload.data,
3563
+ raw: payload
3564
+ };
3565
+ }
3566
+ return {
3567
+ code: response.status,
3568
+ success: response.ok,
3569
+ message: response.statusText,
3570
+ result: payload,
3571
+ data: payload,
3572
+ raw: payload
3573
+ };
3574
+ };
3575
+ var createBrowserPageBridge = (options = {}) => {
3576
+ const servicePrefix = options.servicePrefix || getDefaultServicePrefix();
3577
+ const fetchImpl = createBoundFetch(options.fetchImpl);
3578
+ const request = async (payload) => {
3579
+ if (!payload?.path) {
3580
+ throw new Error("transport.request \u9700\u8981 path");
3581
+ }
3582
+ const url2 = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
3583
+ const headers = new Headers(payload.headers);
3584
+ let body;
3585
+ if (payload.body !== void 0) {
3586
+ if (payload.body instanceof FormData) {
3587
+ body = payload.body;
3588
+ } else {
3589
+ headers.set("Content-Type", headers.get("Content-Type") || "application/json");
3590
+ body = JSON.stringify(payload.body);
3591
+ }
3592
+ }
3593
+ const response = await fetchImpl(url2, {
3594
+ method: normalizeMethod2(payload.method),
3595
+ headers,
3596
+ body,
3597
+ credentials: "include"
3598
+ });
3599
+ return parseJsonResponse(response);
3600
+ };
3601
+ const download = async (payload) => {
3602
+ if (!payload?.path) {
3603
+ throw new Error("transport.download \u9700\u8981 path");
3604
+ }
3605
+ const url2 = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
3606
+ const headers = new Headers(payload.headers);
3607
+ let body;
3608
+ if (payload.body !== void 0) {
3609
+ if (payload.body instanceof FormData) {
3610
+ body = payload.body;
3611
+ } else {
3612
+ headers.set("Content-Type", headers.get("Content-Type") || "application/json");
3613
+ body = JSON.stringify(payload.body);
3614
+ }
3615
+ }
3616
+ const response = await fetchImpl(url2, {
3617
+ method: normalizeMethod2(payload.method),
3618
+ headers,
3619
+ body,
3620
+ credentials: "include"
3621
+ });
3622
+ if (!response.ok) {
3623
+ throw new Error(response.statusText || "\u4E0B\u8F7D\u5931\u8D25");
3624
+ }
3625
+ return {
3626
+ blob: await response.blob(),
3627
+ contentType: response.headers.get("content-type") || void 0,
3628
+ fileName: response.headers.get("content-disposition") || void 0,
3629
+ headers: Object.fromEntries(response.headers.entries())
3630
+ };
3631
+ };
3632
+ return {
3633
+ invoke: async (method4, payload) => {
3634
+ if (method4 === "transport.request") return await request(payload);
3635
+ if (method4 === "transport.download") return await download(payload);
3636
+ throw new Error(`\u4E0D\u652F\u6301\u7684 bridge \u65B9\u6CD5: ${method4}`);
3637
+ }
3638
+ };
3639
+ };
3640
+ var createBrowserPageContext = (bootstrap, options = {}) => {
3641
+ const route = {
3642
+ pathname: options.route?.pathname || (typeof window !== "undefined" ? window.location.pathname : ""),
3643
+ fullPath: options.route?.fullPath || (typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}${window.location.hash}` : ""),
3644
+ params: options.route?.params || {},
3645
+ query: options.route?.query || {},
3646
+ hash: options.route?.hash || (typeof window !== "undefined" ? window.location.hash : "")
3647
+ };
3648
+ return {
3649
+ protocolVersion: bootstrap.asset?.protocolVersion || "1.0",
3650
+ app: bootstrap.app,
3651
+ page: {
3652
+ ...bootstrap.page,
3653
+ version: bootstrap.asset?.version || bootstrap.page.version,
3654
+ buildId: bootstrap.asset?.buildId || bootstrap.page.buildId
3655
+ },
3656
+ user: bootstrap.user,
3657
+ route,
3658
+ env: bootstrap.env || {},
3659
+ permissions: {
3660
+ canView: bootstrap.permissions?.canView !== false,
3661
+ hasFullAccess: bootstrap.permissions?.hasFullAccess === true,
3662
+ ...bootstrap.permissions || {}
3663
+ },
3664
+ capabilities: Array.from(
3665
+ /* @__PURE__ */ new Set([
3666
+ "navigation",
3667
+ "ui.message",
3668
+ "ui.modal",
3669
+ "transport.request",
3670
+ "transport.download",
3671
+ ...bootstrap.sdk?.supportedBridgeMethods || []
3672
+ ])
3673
+ ),
3674
+ ui: {
3675
+ message: {
3676
+ success: (text) => options.message?.success?.(text),
3677
+ error: (text) => options.message?.error?.(text),
3678
+ warning: (text) => options.message?.warning?.(text),
3679
+ info: (text) => options.message?.info?.(text),
3680
+ loading: (text) => options.message?.loading?.(text) || (() => void 0)
3681
+ },
3682
+ modal: {
3683
+ confirm: (input) => options.modal?.confirm?.(input) || Promise.resolve(false)
3684
+ }
3685
+ },
3686
+ navigation: {
3687
+ pushPage: (pageKey, query) => options.navigation?.pushPage?.(pageKey, query),
3688
+ replacePage: (pageKey, query) => options.navigation?.replacePage?.(pageKey, query),
3689
+ pushRoute: (routeValue, query) => options.navigation?.pushRoute?.(routeValue, query),
3690
+ replaceRoute: (routeValue, query) => options.navigation?.replaceRoute?.(routeValue, query),
3691
+ updateQuery: (query) => options.navigation?.updateQuery?.(query),
3692
+ setHash: (hash) => options.navigation?.setHash?.(hash),
3693
+ back: () => options.navigation?.back?.()
3694
+ },
3695
+ bridge: createBrowserPageBridge(options),
3696
+ sdk: {
3697
+ ...bootstrap.sdk,
3698
+ supportedBridgeMethods: ["transport.request", "transport.download"]
3699
+ }
3700
+ };
3701
+ };
3702
+ var resolveRuntimeAssets = async (bootstrap, fetchImpl = fetch) => {
3703
+ const boundFetch = createBoundFetch(fetchImpl);
3704
+ const fallback = {
3705
+ entryUrl: bootstrap.runtimeAssets?.entryUrl || bootstrap.asset?.entryUrl || "",
3706
+ cssUrls: bootstrap.runtimeAssets?.cssUrls || bootstrap.asset?.cssAssets || [],
3707
+ jsUrls: bootstrap.runtimeAssets?.jsUrls || bootstrap.asset?.jsAssets || [],
3708
+ cssIsolation: normalizeCssIsolation2(
3709
+ bootstrap.runtimeAssets?.cssIsolation || bootstrap.page.capabilities?.cssIsolation
3710
+ )
3711
+ };
3712
+ if (bootstrap.runtimeAssets?.entryUrl || !bootstrap.asset?.manifestUrl) {
3713
+ return fallback;
3714
+ }
3715
+ try {
3716
+ const response = await boundFetch(bootstrap.asset.manifestUrl, {
3717
+ credentials: "omit"
3718
+ });
3719
+ if (!response.ok) return fallback;
3720
+ const manifest = await response.json();
3721
+ const base = bootstrap.asset.manifestUrl;
3722
+ const resolveUrl = (value) => new URL(value, base).toString();
3723
+ return {
3724
+ entryUrl: manifest?.entry?.url ? resolveUrl(manifest.entry.url) : fallback.entryUrl,
3725
+ cssUrls: Array.isArray(manifest?.assets?.css) ? manifest.assets.css.map(resolveUrl) : fallback.cssUrls,
3726
+ jsUrls: Array.isArray(manifest?.assets?.js) ? manifest.assets.js.map(resolveUrl) : fallback.jsUrls,
3727
+ cssIsolation: normalizeCssIsolation2(
3728
+ manifest?.style?.isolation || fallback.cssIsolation
3729
+ )
3730
+ };
3731
+ } catch {
3732
+ return fallback;
3733
+ }
3734
+ };
3735
+ var fetchBrowserRuntimeBootstrap = async ({
3736
+ appType,
3737
+ bootstrapPath,
3738
+ fetchImpl = fetch,
3739
+ pageKey,
3740
+ servicePrefix
3741
+ }) => {
3742
+ if (!appType) {
3743
+ throw new Error("appType \u7F3A\u5931");
3744
+ }
3745
+ if (!pageKey) {
3746
+ throw new Error("pageKey \u7F3A\u5931");
3747
+ }
3748
+ const path = bootstrapPath || `/openxiangda-api/v1/apps/${encodeURIComponent(
3749
+ appType
3750
+ )}/pages/${encodeURIComponent(pageKey)}/bootstrap`;
3751
+ const boundFetch = createBoundFetch(fetchImpl);
3752
+ const response = await boundFetch(
3753
+ joinServicePath(servicePrefix || getDefaultServicePrefix(), path),
3754
+ {
3755
+ method: "GET",
3756
+ credentials: "include"
3757
+ }
3758
+ );
3759
+ const payload = await response.json().catch(() => null);
3760
+ if (!response.ok) {
3761
+ throw new Error(payload?.message || response.statusText || "\u83B7\u53D6\u9875\u9762\u8FD0\u884C\u65F6\u5931\u8D25");
3762
+ }
3763
+ if (payload && typeof payload === "object" && ("code" in payload || "success" in payload)) {
3764
+ if (payload.success === false || payload.code && Number(payload.code) !== 200) {
3765
+ throw new Error(payload.message || "\u83B7\u53D6\u9875\u9762\u8FD0\u884C\u65F6\u5931\u8D25");
3766
+ }
3767
+ return payload.data || {};
3768
+ }
3769
+ return payload || {};
3770
+ };
3771
+ var resolveBrowserRuntimeRoute = async ({
3772
+ appType,
3773
+ fetchImpl = fetch,
3774
+ path,
3775
+ resolvePath,
3776
+ search,
3777
+ servicePrefix
3778
+ }) => {
3779
+ if (!appType) {
3780
+ throw new Error("appType \u7F3A\u5931");
3781
+ }
3782
+ const currentPath = path || (typeof window !== "undefined" ? window.location.pathname : "/");
3783
+ const currentSearch = search !== void 0 ? search : typeof window !== "undefined" ? window.location.search : "";
3784
+ const endpoint = resolvePath || `/openxiangda-api/v1/apps/${encodeURIComponent(
3785
+ appType
3786
+ )}/runtime/routes/resolve`;
3787
+ const boundFetch = createBoundFetch(fetchImpl);
3788
+ const response = await boundFetch(
3789
+ joinServicePath(servicePrefix || getDefaultServicePrefix(), endpoint),
3790
+ {
3791
+ method: "POST",
3792
+ credentials: "include",
3793
+ headers: {
3794
+ "Content-Type": "application/json"
3795
+ },
3796
+ body: JSON.stringify({
3797
+ path: currentPath,
3798
+ search: currentSearch
3799
+ })
3800
+ }
3801
+ );
3802
+ const parsed = await parseJsonResponse(response);
3803
+ if (!parsed.success || !parsed.result) {
3804
+ throw new Error(parsed.message || "\u89E3\u6790\u8FD0\u884C\u65F6\u8DEF\u7531\u5931\u8D25");
3805
+ }
3806
+ return parsed.result;
3807
+ };
3808
+ var loadRuntimeScriptModules = async (jsUrls = [], moduleLoader = defaultModuleLoader) => {
3809
+ const urls = Array.from(
3810
+ new Set(jsUrls.map((url2) => String(url2 || "").trim()).filter(Boolean))
3811
+ );
3812
+ for (const url2 of urls) {
3813
+ await moduleLoader(url2);
3814
+ }
3815
+ };
3816
+ var loadCustomPageModule = async (entryUrl, moduleLoader = defaultModuleLoader, jsUrls = []) => {
3817
+ if (!entryUrl) {
3818
+ throw new Error("\u4EE3\u7801\u9875\u9762\u7F3A\u5C11 entryUrl");
3819
+ }
3820
+ await loadRuntimeScriptModules(
3821
+ jsUrls.filter((url2) => url2 && url2 !== entryUrl),
3822
+ moduleLoader
3823
+ );
3824
+ const loaded = await moduleLoader(entryUrl);
3825
+ return loaded?.default && (loaded.default.mount || loaded.default.unmount) ? { ...loaded.default, ...loaded } : loaded || {};
3826
+ };
3827
+ var mountCustomPageRuntime = async ({
3828
+ assets,
3829
+ container,
3830
+ context,
3831
+ module
3832
+ }) => {
3833
+ const cssIsolation = normalizeCssIsolation2(assets?.cssIsolation);
3834
+ const mountedLinks = [];
3835
+ container.innerHTML = "";
3836
+ container.classList.toggle(NAMESPACE_ROOT_CLASS2, cssIsolation === "namespace");
3837
+ (assets?.cssUrls || []).forEach((href) => {
3838
+ const link = document.createElement("link");
3839
+ link.rel = "stylesheet";
3840
+ link.href = href;
3841
+ link.setAttribute("data-openxiangda-runtime-style", href);
3842
+ document.head.appendChild(link);
3843
+ mountedLinks.push(link);
3844
+ });
3845
+ await module.mount?.(container, context);
3846
+ return async () => {
3847
+ await module.unmount?.(container, context);
3848
+ mountedLinks.forEach((link) => link.remove());
3849
+ container.classList.remove(NAMESPACE_ROOT_CLASS2);
3850
+ container.innerHTML = "";
3851
+ };
3852
+ };
3853
+ var mountBrowserPageRuntime = async (options) => {
3854
+ const bootstrap = await fetchBrowserRuntimeBootstrap({
3855
+ appType: options.appType,
3856
+ pageKey: options.pageKey,
3857
+ bootstrapPath: options.bootstrapPath,
3858
+ fetchImpl: options.fetchImpl,
3859
+ servicePrefix: options.servicePrefix
3860
+ });
3861
+ if (bootstrap.permissions?.canView === false) {
3862
+ throw new Error(String(bootstrap.permissions.message || "\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u8BE5\u9875\u9762"));
3863
+ }
3864
+ const assets = await resolveRuntimeAssets(bootstrap, options.fetchImpl || fetch);
3865
+ if (!assets.entryUrl) {
3866
+ throw new Error("\u4EE3\u7801\u9875\u9762\u7F3A\u5C11 entryUrl");
3867
+ }
3868
+ const context = createBrowserPageContext(bootstrap, options);
3869
+ const module = await loadCustomPageModule(
3870
+ assets.entryUrl,
3871
+ options.moduleLoader,
3872
+ assets.jsUrls
3873
+ );
3874
+ const cleanup2 = await mountCustomPageRuntime({
3875
+ assets,
3876
+ container: options.container,
3877
+ context,
3878
+ module
3879
+ });
3880
+ return {
3881
+ bootstrap,
3882
+ assets,
3883
+ context,
3884
+ module,
3885
+ cleanup: cleanup2
3886
+ };
3887
+ };
3888
+
3511
3889
  // packages/sdk/src/runtime/react/auth.tsx
3512
3890
  import {
3513
3891
  useCallback as useCallback3,
@@ -4132,6 +4510,96 @@ var useOpenXiangda = () => {
4132
4510
  return context;
4133
4511
  };
4134
4512
  var useRuntimeBootstrap = () => useOpenXiangda();
4513
+ var OpenXiangdaPageProvider = ({
4514
+ children,
4515
+ page,
4516
+ route,
4517
+ env,
4518
+ message: message7,
4519
+ modal,
4520
+ navigation
4521
+ }) => {
4522
+ const runtime = useOpenXiangda();
4523
+ const context = useMemo5(() => {
4524
+ const bootstrap = runtime.data;
4525
+ const app = toRuntimeRecord(bootstrap?.app);
4526
+ const user = toRuntimeRecord(bootstrap?.user);
4527
+ const permissions = bootstrap?.permissions;
4528
+ const tenantId = toStringValue(getRecordValue3(app, "tenantId")) || toStringValue(getRecordValue3(user, "tenantId")) || toStringValue(getRecordValue3(app, "tenantCode")) || "";
4529
+ const appType = runtime.appType || bootstrap?.appType || toStringValue(getRecordValue3(app, "appType"));
4530
+ const routeInfo = buildBrowserRouteInfo(route);
4531
+ return createBrowserPageContext(
4532
+ {
4533
+ app: {
4534
+ ...app,
4535
+ appType,
4536
+ tenantId
4537
+ },
4538
+ page: {
4539
+ id: routeInfo.pathname || "react-spa",
4540
+ code: routeInfo.pathname || "react-spa",
4541
+ name: "OpenXiangda React SPA",
4542
+ type: "react-spa",
4543
+ rendererType: "react-spa",
4544
+ routeKey: routeInfo.pathname || "react-spa",
4545
+ status: "ACTIVE",
4546
+ props: {},
4547
+ route: {},
4548
+ dataSources: [],
4549
+ capabilities: {},
4550
+ buildId: toStringValue(
4551
+ getRecordValue3(bootstrap?.runtime, "activeBuildId")
4552
+ ),
4553
+ ...page
4554
+ },
4555
+ user: {
4556
+ ...user,
4557
+ id: toStringValue(getRecordValue3(user, "id")) || (user.isGuest ? "guest" : "current"),
4558
+ username: toStringValue(getRecordValue3(user, "username")) || toStringValue(getRecordValue3(user, "name")) || (user.isGuest ? "guest" : "current"),
4559
+ tenantId,
4560
+ isGuest: user.isGuest === true || user.userType === "guest" || Boolean(getRecordValue3(user, "publicAccess")),
4561
+ userType: user.userType === "guest" || user.isGuest === true ? "guest" : "normal"
4562
+ },
4563
+ env: {
4564
+ appType,
4565
+ servicePrefix: runtime.servicePrefix,
4566
+ runtimeMode: bootstrap?.runtime?.mode || "react-spa",
4567
+ ...env || {}
4568
+ },
4569
+ permissions: {
4570
+ canView: runtime.error?.type !== "forbidden",
4571
+ hasFullAccess: permissions?.hasFullAccess === true,
4572
+ ...permissions || {}
4573
+ },
4574
+ sdk: {
4575
+ packageName: "openxiangda",
4576
+ supportedBridgeMethods: ["transport.request", "transport.download"]
4577
+ }
4578
+ },
4579
+ {
4580
+ servicePrefix: runtime.servicePrefix,
4581
+ fetchImpl: runtime.fetchImpl,
4582
+ route: routeInfo,
4583
+ message: message7,
4584
+ modal,
4585
+ navigation
4586
+ }
4587
+ );
4588
+ }, [
4589
+ env,
4590
+ message7,
4591
+ modal,
4592
+ navigation,
4593
+ page,
4594
+ route,
4595
+ runtime.appType,
4596
+ runtime.data,
4597
+ runtime.error?.type,
4598
+ runtime.fetchImpl,
4599
+ runtime.servicePrefix
4600
+ ]);
4601
+ return /* @__PURE__ */ jsx4(PageProvider, { context, children });
4602
+ };
4135
4603
  var useAppMenus = () => {
4136
4604
  const runtime = useOpenXiangda();
4137
4605
  return {
@@ -4509,7 +4977,40 @@ var getRecordValue3 = (value, key) => {
4509
4977
  if (!value || typeof value !== "object") return void 0;
4510
4978
  return value[key];
4511
4979
  };
4512
- var isSuccessCode4 = (code) => {
4980
+ var toRuntimeRecord = (value) => {
4981
+ return value && typeof value === "object" ? { ...value } : {};
4982
+ };
4983
+ var toStringValue = (value) => {
4984
+ if (value === void 0 || value === null) return "";
4985
+ return String(value);
4986
+ };
4987
+ var parseBrowserQuery = () => {
4988
+ if (typeof window === "undefined") return {};
4989
+ const query = {};
4990
+ const params = new URLSearchParams(window.location.search);
4991
+ params.forEach((value, key) => {
4992
+ const currentValue = query[key];
4993
+ if (currentValue === void 0) {
4994
+ query[key] = value;
4995
+ return;
4996
+ }
4997
+ query[key] = Array.isArray(currentValue) ? [...currentValue, value] : [currentValue, value];
4998
+ });
4999
+ return query;
5000
+ };
5001
+ var buildBrowserRouteInfo = (route) => {
5002
+ const pathname = route?.pathname || (typeof window !== "undefined" ? window.location.pathname : "");
5003
+ const search = typeof window !== "undefined" ? window.location.search : "";
5004
+ const hash = route?.hash || (typeof window !== "undefined" ? window.location.hash : "");
5005
+ return {
5006
+ pathname,
5007
+ fullPath: route?.fullPath || (typeof window !== "undefined" ? `${pathname}${search}${hash}` : pathname),
5008
+ params: route?.params || {},
5009
+ query: route?.query || parseBrowserQuery(),
5010
+ hash
5011
+ };
5012
+ };
5013
+ var isSuccessCode5 = (code) => {
4513
5014
  if (code === void 0 || code === null || code === "") return true;
4514
5015
  const normalized = Number(code);
4515
5016
  return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
@@ -4517,7 +5018,7 @@ var isSuccessCode4 = (code) => {
4517
5018
  var isRuntimeEnvelopeFailure = (response, payload) => {
4518
5019
  const code = getRecordValue3(payload, "code");
4519
5020
  const success = getRecordValue3(payload, "success");
4520
- return !response.ok || success === false || !isSuccessCode4(code);
5021
+ return !response.ok || success === false || !isSuccessCode5(code);
4521
5022
  };
4522
5023
  var isServerErrorCode = (code) => {
4523
5024
  const normalized = Number(code);
@@ -4627,384 +5128,6 @@ var readTicketFromLocation = () => {
4627
5128
  };
4628
5129
  var readPathFromLocation = () => typeof window === "undefined" ? void 0 : window.location.pathname;
4629
5130
 
4630
- // packages/sdk/src/runtime/host/browserHost.ts
4631
- var NAMESPACE_ROOT_CLASS2 = "sy-app-workspace";
4632
- var defaultModuleLoader = (url2) => import(
4633
- /* @vite-ignore */
4634
- url2
4635
- );
4636
- var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
4637
- var getDefaultServicePrefix = () => typeof window !== "undefined" ? trimTrailingSlash(window.__OPENXIANGDA_SERVICE_PREFIX__ || "/service") : "/service";
4638
- var joinServicePath = (servicePrefix, path) => {
4639
- if (/^https?:\/\//i.test(path)) return path;
4640
- const normalizedPrefix = trimTrailingSlash(servicePrefix || "/service");
4641
- if (path.startsWith(normalizedPrefix)) return path;
4642
- return `${normalizedPrefix}${path.startsWith("/") ? path : `/${path}`}`;
4643
- };
4644
- var appendQuery = (url2, query) => {
4645
- if (!query) return url2;
4646
- return `${url2}${url2.includes("?") ? "&" : "?"}${query}`;
4647
- };
4648
- var normalizeMethod2 = (method4) => {
4649
- const value = String(method4 || "get").toUpperCase();
4650
- return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(value) ? value : "GET";
4651
- };
4652
- var normalizeCssIsolation2 = (value) => {
4653
- if (value === "namespace" || value === "shadow" || value === "none") {
4654
- return value;
4655
- }
4656
- return "none";
4657
- };
4658
- var normalizeEnvelopeCode2 = (value, fallback) => {
4659
- if (value === void 0 || value === null || value === "") return fallback;
4660
- const normalized = Number(value);
4661
- return Number.isFinite(normalized) ? normalized : String(value);
4662
- };
4663
- var isSuccessCode5 = (value) => {
4664
- if (value === void 0 || value === null || value === "") return true;
4665
- const normalized = Number(value);
4666
- return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
4667
- };
4668
- var parseJsonResponse = async (response) => {
4669
- const payload = await response.json().catch(() => null);
4670
- if (!response.ok) {
4671
- const message7 = payload && typeof payload === "object" ? payload.message || payload.error || response.statusText : response.statusText;
4672
- throw new Error(message7 || "\u8BF7\u6C42\u5931\u8D25");
4673
- }
4674
- if (payload && typeof payload === "object" && "code" in payload) {
4675
- const code = normalizeEnvelopeCode2(payload.code, response.status);
4676
- return {
4677
- code,
4678
- success: payload.success !== false && isSuccessCode5(code),
4679
- message: payload.message,
4680
- result: payload.result ?? payload.data ?? null,
4681
- data: payload.data,
4682
- raw: payload
4683
- };
4684
- }
4685
- return {
4686
- code: response.status,
4687
- success: response.ok,
4688
- message: response.statusText,
4689
- result: payload,
4690
- data: payload,
4691
- raw: payload
4692
- };
4693
- };
4694
- var createBrowserPageBridge = (options = {}) => {
4695
- const servicePrefix = options.servicePrefix || getDefaultServicePrefix();
4696
- const fetchImpl = createBoundFetch(options.fetchImpl);
4697
- const request = async (payload) => {
4698
- if (!payload?.path) {
4699
- throw new Error("transport.request \u9700\u8981 path");
4700
- }
4701
- const url2 = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
4702
- const headers = new Headers(payload.headers);
4703
- let body;
4704
- if (payload.body !== void 0) {
4705
- if (payload.body instanceof FormData) {
4706
- body = payload.body;
4707
- } else {
4708
- headers.set("Content-Type", headers.get("Content-Type") || "application/json");
4709
- body = JSON.stringify(payload.body);
4710
- }
4711
- }
4712
- const response = await fetchImpl(url2, {
4713
- method: normalizeMethod2(payload.method),
4714
- headers,
4715
- body,
4716
- credentials: "include"
4717
- });
4718
- return parseJsonResponse(response);
4719
- };
4720
- const download = async (payload) => {
4721
- if (!payload?.path) {
4722
- throw new Error("transport.download \u9700\u8981 path");
4723
- }
4724
- const url2 = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
4725
- const headers = new Headers(payload.headers);
4726
- let body;
4727
- if (payload.body !== void 0) {
4728
- if (payload.body instanceof FormData) {
4729
- body = payload.body;
4730
- } else {
4731
- headers.set("Content-Type", headers.get("Content-Type") || "application/json");
4732
- body = JSON.stringify(payload.body);
4733
- }
4734
- }
4735
- const response = await fetchImpl(url2, {
4736
- method: normalizeMethod2(payload.method),
4737
- headers,
4738
- body,
4739
- credentials: "include"
4740
- });
4741
- if (!response.ok) {
4742
- throw new Error(response.statusText || "\u4E0B\u8F7D\u5931\u8D25");
4743
- }
4744
- return {
4745
- blob: await response.blob(),
4746
- contentType: response.headers.get("content-type") || void 0,
4747
- fileName: response.headers.get("content-disposition") || void 0,
4748
- headers: Object.fromEntries(response.headers.entries())
4749
- };
4750
- };
4751
- return {
4752
- invoke: async (method4, payload) => {
4753
- if (method4 === "transport.request") return await request(payload);
4754
- if (method4 === "transport.download") return await download(payload);
4755
- throw new Error(`\u4E0D\u652F\u6301\u7684 bridge \u65B9\u6CD5: ${method4}`);
4756
- }
4757
- };
4758
- };
4759
- var createBrowserPageContext = (bootstrap, options = {}) => {
4760
- const route = {
4761
- pathname: options.route?.pathname || (typeof window !== "undefined" ? window.location.pathname : ""),
4762
- fullPath: options.route?.fullPath || (typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}${window.location.hash}` : ""),
4763
- params: options.route?.params || {},
4764
- query: options.route?.query || {},
4765
- hash: options.route?.hash || (typeof window !== "undefined" ? window.location.hash : "")
4766
- };
4767
- return {
4768
- protocolVersion: bootstrap.asset?.protocolVersion || "1.0",
4769
- app: bootstrap.app,
4770
- page: {
4771
- ...bootstrap.page,
4772
- version: bootstrap.asset?.version || bootstrap.page.version,
4773
- buildId: bootstrap.asset?.buildId || bootstrap.page.buildId
4774
- },
4775
- user: bootstrap.user,
4776
- route,
4777
- env: bootstrap.env || {},
4778
- permissions: {
4779
- canView: bootstrap.permissions?.canView !== false,
4780
- hasFullAccess: bootstrap.permissions?.hasFullAccess === true,
4781
- ...bootstrap.permissions || {}
4782
- },
4783
- capabilities: Array.from(
4784
- /* @__PURE__ */ new Set([
4785
- "navigation",
4786
- "ui.message",
4787
- "ui.modal",
4788
- "transport.request",
4789
- "transport.download",
4790
- ...bootstrap.sdk?.supportedBridgeMethods || []
4791
- ])
4792
- ),
4793
- ui: {
4794
- message: {
4795
- success: (text) => options.message?.success?.(text),
4796
- error: (text) => options.message?.error?.(text),
4797
- warning: (text) => options.message?.warning?.(text),
4798
- info: (text) => options.message?.info?.(text),
4799
- loading: (text) => options.message?.loading?.(text) || (() => void 0)
4800
- },
4801
- modal: {
4802
- confirm: (input) => options.modal?.confirm?.(input) || Promise.resolve(false)
4803
- }
4804
- },
4805
- navigation: {
4806
- pushPage: (pageKey, query) => options.navigation?.pushPage?.(pageKey, query),
4807
- replacePage: (pageKey, query) => options.navigation?.replacePage?.(pageKey, query),
4808
- pushRoute: (routeValue, query) => options.navigation?.pushRoute?.(routeValue, query),
4809
- replaceRoute: (routeValue, query) => options.navigation?.replaceRoute?.(routeValue, query),
4810
- updateQuery: (query) => options.navigation?.updateQuery?.(query),
4811
- setHash: (hash) => options.navigation?.setHash?.(hash),
4812
- back: () => options.navigation?.back?.()
4813
- },
4814
- bridge: createBrowserPageBridge(options),
4815
- sdk: {
4816
- ...bootstrap.sdk,
4817
- supportedBridgeMethods: ["transport.request", "transport.download"]
4818
- }
4819
- };
4820
- };
4821
- var resolveRuntimeAssets = async (bootstrap, fetchImpl = fetch) => {
4822
- const boundFetch = createBoundFetch(fetchImpl);
4823
- const fallback = {
4824
- entryUrl: bootstrap.runtimeAssets?.entryUrl || bootstrap.asset?.entryUrl || "",
4825
- cssUrls: bootstrap.runtimeAssets?.cssUrls || bootstrap.asset?.cssAssets || [],
4826
- jsUrls: bootstrap.runtimeAssets?.jsUrls || bootstrap.asset?.jsAssets || [],
4827
- cssIsolation: normalizeCssIsolation2(
4828
- bootstrap.runtimeAssets?.cssIsolation || bootstrap.page.capabilities?.cssIsolation
4829
- )
4830
- };
4831
- if (bootstrap.runtimeAssets?.entryUrl || !bootstrap.asset?.manifestUrl) {
4832
- return fallback;
4833
- }
4834
- try {
4835
- const response = await boundFetch(bootstrap.asset.manifestUrl, {
4836
- credentials: "omit"
4837
- });
4838
- if (!response.ok) return fallback;
4839
- const manifest = await response.json();
4840
- const base = bootstrap.asset.manifestUrl;
4841
- const resolveUrl = (value) => new URL(value, base).toString();
4842
- return {
4843
- entryUrl: manifest?.entry?.url ? resolveUrl(manifest.entry.url) : fallback.entryUrl,
4844
- cssUrls: Array.isArray(manifest?.assets?.css) ? manifest.assets.css.map(resolveUrl) : fallback.cssUrls,
4845
- jsUrls: Array.isArray(manifest?.assets?.js) ? manifest.assets.js.map(resolveUrl) : fallback.jsUrls,
4846
- cssIsolation: normalizeCssIsolation2(
4847
- manifest?.style?.isolation || fallback.cssIsolation
4848
- )
4849
- };
4850
- } catch {
4851
- return fallback;
4852
- }
4853
- };
4854
- var fetchBrowserRuntimeBootstrap = async ({
4855
- appType,
4856
- bootstrapPath,
4857
- fetchImpl = fetch,
4858
- pageKey,
4859
- servicePrefix
4860
- }) => {
4861
- if (!appType) {
4862
- throw new Error("appType \u7F3A\u5931");
4863
- }
4864
- if (!pageKey) {
4865
- throw new Error("pageKey \u7F3A\u5931");
4866
- }
4867
- const path = bootstrapPath || `/openxiangda-api/v1/apps/${encodeURIComponent(
4868
- appType
4869
- )}/pages/${encodeURIComponent(pageKey)}/bootstrap`;
4870
- const boundFetch = createBoundFetch(fetchImpl);
4871
- const response = await boundFetch(
4872
- joinServicePath(servicePrefix || getDefaultServicePrefix(), path),
4873
- {
4874
- method: "GET",
4875
- credentials: "include"
4876
- }
4877
- );
4878
- const payload = await response.json().catch(() => null);
4879
- if (!response.ok) {
4880
- throw new Error(payload?.message || response.statusText || "\u83B7\u53D6\u9875\u9762\u8FD0\u884C\u65F6\u5931\u8D25");
4881
- }
4882
- if (payload && typeof payload === "object" && ("code" in payload || "success" in payload)) {
4883
- if (payload.success === false || payload.code && Number(payload.code) !== 200) {
4884
- throw new Error(payload.message || "\u83B7\u53D6\u9875\u9762\u8FD0\u884C\u65F6\u5931\u8D25");
4885
- }
4886
- return payload.data || {};
4887
- }
4888
- return payload || {};
4889
- };
4890
- var resolveBrowserRuntimeRoute = async ({
4891
- appType,
4892
- fetchImpl = fetch,
4893
- path,
4894
- resolvePath,
4895
- search,
4896
- servicePrefix
4897
- }) => {
4898
- if (!appType) {
4899
- throw new Error("appType \u7F3A\u5931");
4900
- }
4901
- const currentPath = path || (typeof window !== "undefined" ? window.location.pathname : "/");
4902
- const currentSearch = search !== void 0 ? search : typeof window !== "undefined" ? window.location.search : "";
4903
- const endpoint = resolvePath || `/openxiangda-api/v1/apps/${encodeURIComponent(
4904
- appType
4905
- )}/runtime/routes/resolve`;
4906
- const boundFetch = createBoundFetch(fetchImpl);
4907
- const response = await boundFetch(
4908
- joinServicePath(servicePrefix || getDefaultServicePrefix(), endpoint),
4909
- {
4910
- method: "POST",
4911
- credentials: "include",
4912
- headers: {
4913
- "Content-Type": "application/json"
4914
- },
4915
- body: JSON.stringify({
4916
- path: currentPath,
4917
- search: currentSearch
4918
- })
4919
- }
4920
- );
4921
- const parsed = await parseJsonResponse(response);
4922
- if (!parsed.success || !parsed.result) {
4923
- throw new Error(parsed.message || "\u89E3\u6790\u8FD0\u884C\u65F6\u8DEF\u7531\u5931\u8D25");
4924
- }
4925
- return parsed.result;
4926
- };
4927
- var loadRuntimeScriptModules = async (jsUrls = [], moduleLoader = defaultModuleLoader) => {
4928
- const urls = Array.from(
4929
- new Set(jsUrls.map((url2) => String(url2 || "").trim()).filter(Boolean))
4930
- );
4931
- for (const url2 of urls) {
4932
- await moduleLoader(url2);
4933
- }
4934
- };
4935
- var loadCustomPageModule = async (entryUrl, moduleLoader = defaultModuleLoader, jsUrls = []) => {
4936
- if (!entryUrl) {
4937
- throw new Error("\u4EE3\u7801\u9875\u9762\u7F3A\u5C11 entryUrl");
4938
- }
4939
- await loadRuntimeScriptModules(
4940
- jsUrls.filter((url2) => url2 && url2 !== entryUrl),
4941
- moduleLoader
4942
- );
4943
- const loaded = await moduleLoader(entryUrl);
4944
- return loaded?.default && (loaded.default.mount || loaded.default.unmount) ? { ...loaded.default, ...loaded } : loaded || {};
4945
- };
4946
- var mountCustomPageRuntime = async ({
4947
- assets,
4948
- container,
4949
- context,
4950
- module
4951
- }) => {
4952
- const cssIsolation = normalizeCssIsolation2(assets?.cssIsolation);
4953
- const mountedLinks = [];
4954
- container.innerHTML = "";
4955
- container.classList.toggle(NAMESPACE_ROOT_CLASS2, cssIsolation === "namespace");
4956
- (assets?.cssUrls || []).forEach((href) => {
4957
- const link = document.createElement("link");
4958
- link.rel = "stylesheet";
4959
- link.href = href;
4960
- link.setAttribute("data-openxiangda-runtime-style", href);
4961
- document.head.appendChild(link);
4962
- mountedLinks.push(link);
4963
- });
4964
- await module.mount?.(container, context);
4965
- return async () => {
4966
- await module.unmount?.(container, context);
4967
- mountedLinks.forEach((link) => link.remove());
4968
- container.classList.remove(NAMESPACE_ROOT_CLASS2);
4969
- container.innerHTML = "";
4970
- };
4971
- };
4972
- var mountBrowserPageRuntime = async (options) => {
4973
- const bootstrap = await fetchBrowserRuntimeBootstrap({
4974
- appType: options.appType,
4975
- pageKey: options.pageKey,
4976
- bootstrapPath: options.bootstrapPath,
4977
- fetchImpl: options.fetchImpl,
4978
- servicePrefix: options.servicePrefix
4979
- });
4980
- if (bootstrap.permissions?.canView === false) {
4981
- throw new Error(String(bootstrap.permissions.message || "\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u8BE5\u9875\u9762"));
4982
- }
4983
- const assets = await resolveRuntimeAssets(bootstrap, options.fetchImpl || fetch);
4984
- if (!assets.entryUrl) {
4985
- throw new Error("\u4EE3\u7801\u9875\u9762\u7F3A\u5C11 entryUrl");
4986
- }
4987
- const context = createBrowserPageContext(bootstrap, options);
4988
- const module = await loadCustomPageModule(
4989
- assets.entryUrl,
4990
- options.moduleLoader,
4991
- assets.jsUrls
4992
- );
4993
- const cleanup2 = await mountCustomPageRuntime({
4994
- assets,
4995
- container: options.container,
4996
- context,
4997
- module
4998
- });
4999
- return {
5000
- bootstrap,
5001
- assets,
5002
- context,
5003
- module,
5004
- cleanup: cleanup2
5005
- };
5006
- };
5007
-
5008
5131
  // packages/sdk/src/runtime/host/builtinRouteRenderer.tsx
5009
5132
  import { useCallback as useCallback39, useEffect as useEffect101, useMemo as useMemo67, useState as useState93 } from "react";
5010
5133
  import { Alert as Alert4, Button as Button17, Card as Card3, Empty as Empty9, Spin as Spin6, Typography as Typography3 } from "antd";
@@ -50864,6 +50987,7 @@ export {
50864
50987
  AuthClientError,
50865
50988
  BuiltinRouteRenderer,
50866
50989
  LoginPage,
50990
+ OpenXiangdaPageProvider,
50867
50991
  OpenXiangdaProvider,
50868
50992
  PageProvider,
50869
50993
  PermissionBoundary,