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.
@@ -32,6 +32,7 @@ var react_exports = {};
32
32
  __export(react_exports, {
33
33
  AuthClientError: () => AuthClientError,
34
34
  LoginPage: () => LoginPage,
35
+ OpenXiangdaPageProvider: () => OpenXiangdaPageProvider,
35
36
  OpenXiangdaProvider: () => OpenXiangdaProvider,
36
37
  PageProvider: () => PageProvider,
37
38
  PermissionBoundary: () => PermissionBoundary,
@@ -2547,6 +2548,187 @@ var createBoundFetch = (fetchImpl) => {
2547
2548
  return ((input, init) => baseFetch.call(globalThis, input, init));
2548
2549
  };
2549
2550
 
2551
+ // packages/sdk/src/runtime/host/browserHost.ts
2552
+ var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
2553
+ var getDefaultServicePrefix = () => typeof window !== "undefined" ? trimTrailingSlash(window.__OPENXIANGDA_SERVICE_PREFIX__ || "/service") : "/service";
2554
+ var joinServicePath = (servicePrefix, path) => {
2555
+ if (/^https?:\/\//i.test(path)) return path;
2556
+ const normalizedPrefix = trimTrailingSlash(servicePrefix || "/service");
2557
+ if (path.startsWith(normalizedPrefix)) return path;
2558
+ return `${normalizedPrefix}${path.startsWith("/") ? path : `/${path}`}`;
2559
+ };
2560
+ var appendQuery = (url, query) => {
2561
+ if (!query) return url;
2562
+ return `${url}${url.includes("?") ? "&" : "?"}${query}`;
2563
+ };
2564
+ var normalizeMethod2 = (method) => {
2565
+ const value = String(method || "get").toUpperCase();
2566
+ return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(value) ? value : "GET";
2567
+ };
2568
+ var normalizeEnvelopeCode2 = (value, fallback) => {
2569
+ if (value === void 0 || value === null || value === "") return fallback;
2570
+ const normalized = Number(value);
2571
+ return Number.isFinite(normalized) ? normalized : String(value);
2572
+ };
2573
+ var isSuccessCode2 = (value) => {
2574
+ if (value === void 0 || value === null || value === "") return true;
2575
+ const normalized = Number(value);
2576
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
2577
+ };
2578
+ var parseJsonResponse = async (response) => {
2579
+ const payload = await response.json().catch(() => null);
2580
+ if (!response.ok) {
2581
+ const message2 = payload && typeof payload === "object" ? payload.message || payload.error || response.statusText : response.statusText;
2582
+ throw new Error(message2 || "\u8BF7\u6C42\u5931\u8D25");
2583
+ }
2584
+ if (payload && typeof payload === "object" && "code" in payload) {
2585
+ const code = normalizeEnvelopeCode2(payload.code, response.status);
2586
+ return {
2587
+ code,
2588
+ success: payload.success !== false && isSuccessCode2(code),
2589
+ message: payload.message,
2590
+ result: payload.result ?? payload.data ?? null,
2591
+ data: payload.data,
2592
+ raw: payload
2593
+ };
2594
+ }
2595
+ return {
2596
+ code: response.status,
2597
+ success: response.ok,
2598
+ message: response.statusText,
2599
+ result: payload,
2600
+ data: payload,
2601
+ raw: payload
2602
+ };
2603
+ };
2604
+ var createBrowserPageBridge = (options = {}) => {
2605
+ const servicePrefix = options.servicePrefix || getDefaultServicePrefix();
2606
+ const fetchImpl = createBoundFetch(options.fetchImpl);
2607
+ const request = async (payload) => {
2608
+ if (!payload?.path) {
2609
+ throw new Error("transport.request \u9700\u8981 path");
2610
+ }
2611
+ const url = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
2612
+ const headers = new Headers(payload.headers);
2613
+ let body;
2614
+ if (payload.body !== void 0) {
2615
+ if (payload.body instanceof FormData) {
2616
+ body = payload.body;
2617
+ } else {
2618
+ headers.set("Content-Type", headers.get("Content-Type") || "application/json");
2619
+ body = JSON.stringify(payload.body);
2620
+ }
2621
+ }
2622
+ const response = await fetchImpl(url, {
2623
+ method: normalizeMethod2(payload.method),
2624
+ headers,
2625
+ body,
2626
+ credentials: "include"
2627
+ });
2628
+ return parseJsonResponse(response);
2629
+ };
2630
+ const download = async (payload) => {
2631
+ if (!payload?.path) {
2632
+ throw new Error("transport.download \u9700\u8981 path");
2633
+ }
2634
+ const url = appendQuery(joinServicePath(servicePrefix, payload.path), payload.query);
2635
+ const headers = new Headers(payload.headers);
2636
+ let body;
2637
+ if (payload.body !== void 0) {
2638
+ if (payload.body instanceof FormData) {
2639
+ body = payload.body;
2640
+ } else {
2641
+ headers.set("Content-Type", headers.get("Content-Type") || "application/json");
2642
+ body = JSON.stringify(payload.body);
2643
+ }
2644
+ }
2645
+ const response = await fetchImpl(url, {
2646
+ method: normalizeMethod2(payload.method),
2647
+ headers,
2648
+ body,
2649
+ credentials: "include"
2650
+ });
2651
+ if (!response.ok) {
2652
+ throw new Error(response.statusText || "\u4E0B\u8F7D\u5931\u8D25");
2653
+ }
2654
+ return {
2655
+ blob: await response.blob(),
2656
+ contentType: response.headers.get("content-type") || void 0,
2657
+ fileName: response.headers.get("content-disposition") || void 0,
2658
+ headers: Object.fromEntries(response.headers.entries())
2659
+ };
2660
+ };
2661
+ return {
2662
+ invoke: async (method, payload) => {
2663
+ if (method === "transport.request") return await request(payload);
2664
+ if (method === "transport.download") return await download(payload);
2665
+ throw new Error(`\u4E0D\u652F\u6301\u7684 bridge \u65B9\u6CD5: ${method}`);
2666
+ }
2667
+ };
2668
+ };
2669
+ var createBrowserPageContext = (bootstrap, options = {}) => {
2670
+ const route = {
2671
+ pathname: options.route?.pathname || (typeof window !== "undefined" ? window.location.pathname : ""),
2672
+ fullPath: options.route?.fullPath || (typeof window !== "undefined" ? `${window.location.pathname}${window.location.search}${window.location.hash}` : ""),
2673
+ params: options.route?.params || {},
2674
+ query: options.route?.query || {},
2675
+ hash: options.route?.hash || (typeof window !== "undefined" ? window.location.hash : "")
2676
+ };
2677
+ return {
2678
+ protocolVersion: bootstrap.asset?.protocolVersion || "1.0",
2679
+ app: bootstrap.app,
2680
+ page: {
2681
+ ...bootstrap.page,
2682
+ version: bootstrap.asset?.version || bootstrap.page.version,
2683
+ buildId: bootstrap.asset?.buildId || bootstrap.page.buildId
2684
+ },
2685
+ user: bootstrap.user,
2686
+ route,
2687
+ env: bootstrap.env || {},
2688
+ permissions: {
2689
+ canView: bootstrap.permissions?.canView !== false,
2690
+ hasFullAccess: bootstrap.permissions?.hasFullAccess === true,
2691
+ ...bootstrap.permissions || {}
2692
+ },
2693
+ capabilities: Array.from(
2694
+ /* @__PURE__ */ new Set([
2695
+ "navigation",
2696
+ "ui.message",
2697
+ "ui.modal",
2698
+ "transport.request",
2699
+ "transport.download",
2700
+ ...bootstrap.sdk?.supportedBridgeMethods || []
2701
+ ])
2702
+ ),
2703
+ ui: {
2704
+ message: {
2705
+ success: (text) => options.message?.success?.(text),
2706
+ error: (text) => options.message?.error?.(text),
2707
+ warning: (text) => options.message?.warning?.(text),
2708
+ info: (text) => options.message?.info?.(text),
2709
+ loading: (text) => options.message?.loading?.(text) || (() => void 0)
2710
+ },
2711
+ modal: {
2712
+ confirm: (input) => options.modal?.confirm?.(input) || Promise.resolve(false)
2713
+ }
2714
+ },
2715
+ navigation: {
2716
+ pushPage: (pageKey, query) => options.navigation?.pushPage?.(pageKey, query),
2717
+ replacePage: (pageKey, query) => options.navigation?.replacePage?.(pageKey, query),
2718
+ pushRoute: (routeValue, query) => options.navigation?.pushRoute?.(routeValue, query),
2719
+ replaceRoute: (routeValue, query) => options.navigation?.replaceRoute?.(routeValue, query),
2720
+ updateQuery: (query) => options.navigation?.updateQuery?.(query),
2721
+ setHash: (hash) => options.navigation?.setHash?.(hash),
2722
+ back: () => options.navigation?.back?.()
2723
+ },
2724
+ bridge: createBrowserPageBridge(options),
2725
+ sdk: {
2726
+ ...bootstrap.sdk,
2727
+ supportedBridgeMethods: ["transport.request", "transport.download"]
2728
+ }
2729
+ };
2730
+ };
2731
+
2550
2732
  // packages/sdk/src/runtime/react/auth.tsx
2551
2733
  var import_react7 = require("react");
2552
2734
  var import_antd2 = require("antd");
@@ -2585,7 +2767,7 @@ var createAuthClient = ({
2585
2767
  const payload = await readPayload(response);
2586
2768
  const code = getRecordValue(payload, "code");
2587
2769
  const success = getRecordValue(payload, "success");
2588
- if (!response.ok || success === false || !isSuccessCode2(code)) {
2770
+ if (!response.ok || success === false || !isSuccessCode3(code)) {
2589
2771
  throw new AuthClientError(
2590
2772
  String(getRecordValue(payload, "message") || `Auth request failed: ${response.status}`),
2591
2773
  { status: response.status, code, payload }
@@ -2638,7 +2820,7 @@ var getRecordValue = (value, key) => {
2638
2820
  if (!value || typeof value !== "object") return void 0;
2639
2821
  return value[key];
2640
2822
  };
2641
- var isSuccessCode2 = (code) => {
2823
+ var isSuccessCode3 = (code) => {
2642
2824
  if (code === void 0 || code === null || code === "") return true;
2643
2825
  const normalized = Number(code);
2644
2826
  return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
@@ -3267,6 +3449,96 @@ var useOpenXiangda = () => {
3267
3449
  return context;
3268
3450
  };
3269
3451
  var useRuntimeBootstrap = () => useOpenXiangda();
3452
+ var OpenXiangdaPageProvider = ({
3453
+ children,
3454
+ page,
3455
+ route,
3456
+ env,
3457
+ message: message2,
3458
+ modal,
3459
+ navigation
3460
+ }) => {
3461
+ const runtime = useOpenXiangda();
3462
+ const context = (0, import_react8.useMemo)(() => {
3463
+ const bootstrap = runtime.data;
3464
+ const app = toRuntimeRecord(bootstrap?.app);
3465
+ const user = toRuntimeRecord(bootstrap?.user);
3466
+ const permissions = bootstrap?.permissions;
3467
+ const tenantId = toStringValue(getRecordValue2(app, "tenantId")) || toStringValue(getRecordValue2(user, "tenantId")) || toStringValue(getRecordValue2(app, "tenantCode")) || "";
3468
+ const appType = runtime.appType || bootstrap?.appType || toStringValue(getRecordValue2(app, "appType"));
3469
+ const routeInfo = buildBrowserRouteInfo(route);
3470
+ return createBrowserPageContext(
3471
+ {
3472
+ app: {
3473
+ ...app,
3474
+ appType,
3475
+ tenantId
3476
+ },
3477
+ page: {
3478
+ id: routeInfo.pathname || "react-spa",
3479
+ code: routeInfo.pathname || "react-spa",
3480
+ name: "OpenXiangda React SPA",
3481
+ type: "react-spa",
3482
+ rendererType: "react-spa",
3483
+ routeKey: routeInfo.pathname || "react-spa",
3484
+ status: "ACTIVE",
3485
+ props: {},
3486
+ route: {},
3487
+ dataSources: [],
3488
+ capabilities: {},
3489
+ buildId: toStringValue(
3490
+ getRecordValue2(bootstrap?.runtime, "activeBuildId")
3491
+ ),
3492
+ ...page
3493
+ },
3494
+ user: {
3495
+ ...user,
3496
+ id: toStringValue(getRecordValue2(user, "id")) || (user.isGuest ? "guest" : "current"),
3497
+ username: toStringValue(getRecordValue2(user, "username")) || toStringValue(getRecordValue2(user, "name")) || (user.isGuest ? "guest" : "current"),
3498
+ tenantId,
3499
+ isGuest: user.isGuest === true || user.userType === "guest" || Boolean(getRecordValue2(user, "publicAccess")),
3500
+ userType: user.userType === "guest" || user.isGuest === true ? "guest" : "normal"
3501
+ },
3502
+ env: {
3503
+ appType,
3504
+ servicePrefix: runtime.servicePrefix,
3505
+ runtimeMode: bootstrap?.runtime?.mode || "react-spa",
3506
+ ...env || {}
3507
+ },
3508
+ permissions: {
3509
+ canView: runtime.error?.type !== "forbidden",
3510
+ hasFullAccess: permissions?.hasFullAccess === true,
3511
+ ...permissions || {}
3512
+ },
3513
+ sdk: {
3514
+ packageName: "openxiangda",
3515
+ supportedBridgeMethods: ["transport.request", "transport.download"]
3516
+ }
3517
+ },
3518
+ {
3519
+ servicePrefix: runtime.servicePrefix,
3520
+ fetchImpl: runtime.fetchImpl,
3521
+ route: routeInfo,
3522
+ message: message2,
3523
+ modal,
3524
+ navigation
3525
+ }
3526
+ );
3527
+ }, [
3528
+ env,
3529
+ message2,
3530
+ modal,
3531
+ navigation,
3532
+ page,
3533
+ route,
3534
+ runtime.appType,
3535
+ runtime.data,
3536
+ runtime.error?.type,
3537
+ runtime.fetchImpl,
3538
+ runtime.servicePrefix
3539
+ ]);
3540
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageProvider, { context, children });
3541
+ };
3270
3542
  var useAppMenus = () => {
3271
3543
  const runtime = useOpenXiangda();
3272
3544
  return {
@@ -3644,7 +3916,40 @@ var getRecordValue2 = (value, key) => {
3644
3916
  if (!value || typeof value !== "object") return void 0;
3645
3917
  return value[key];
3646
3918
  };
3647
- var isSuccessCode3 = (code) => {
3919
+ var toRuntimeRecord = (value) => {
3920
+ return value && typeof value === "object" ? { ...value } : {};
3921
+ };
3922
+ var toStringValue = (value) => {
3923
+ if (value === void 0 || value === null) return "";
3924
+ return String(value);
3925
+ };
3926
+ var parseBrowserQuery = () => {
3927
+ if (typeof window === "undefined") return {};
3928
+ const query = {};
3929
+ const params = new URLSearchParams(window.location.search);
3930
+ params.forEach((value, key) => {
3931
+ const currentValue = query[key];
3932
+ if (currentValue === void 0) {
3933
+ query[key] = value;
3934
+ return;
3935
+ }
3936
+ query[key] = Array.isArray(currentValue) ? [...currentValue, value] : [currentValue, value];
3937
+ });
3938
+ return query;
3939
+ };
3940
+ var buildBrowserRouteInfo = (route) => {
3941
+ const pathname = route?.pathname || (typeof window !== "undefined" ? window.location.pathname : "");
3942
+ const search = typeof window !== "undefined" ? window.location.search : "";
3943
+ const hash = route?.hash || (typeof window !== "undefined" ? window.location.hash : "");
3944
+ return {
3945
+ pathname,
3946
+ fullPath: route?.fullPath || (typeof window !== "undefined" ? `${pathname}${search}${hash}` : pathname),
3947
+ params: route?.params || {},
3948
+ query: route?.query || parseBrowserQuery(),
3949
+ hash
3950
+ };
3951
+ };
3952
+ var isSuccessCode4 = (code) => {
3648
3953
  if (code === void 0 || code === null || code === "") return true;
3649
3954
  const normalized = Number(code);
3650
3955
  return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
@@ -3652,7 +3957,7 @@ var isSuccessCode3 = (code) => {
3652
3957
  var isRuntimeEnvelopeFailure = (response, payload) => {
3653
3958
  const code = getRecordValue2(payload, "code");
3654
3959
  const success = getRecordValue2(payload, "success");
3655
- return !response.ok || success === false || !isSuccessCode3(code);
3960
+ return !response.ok || success === false || !isSuccessCode4(code);
3656
3961
  };
3657
3962
  var isServerErrorCode = (code) => {
3658
3963
  const normalized = Number(code);
@@ -3722,7 +4027,7 @@ var createPublicAccessClient = ({
3722
4027
  const payload = await readPayload2(response);
3723
4028
  const code = getRecordValue3(payload, "code");
3724
4029
  const success = getRecordValue3(payload, "success");
3725
- if (!response.ok || success === false || !isSuccessCode4(code)) {
4030
+ if (!response.ok || success === false || !isSuccessCode5(code)) {
3726
4031
  throw new PublicAccessClientError(
3727
4032
  String(
3728
4033
  getRecordValue3(payload, "message") || `Public access session failed: ${response.status}`
@@ -3760,7 +4065,7 @@ var getRecordValue3 = (value, key) => {
3760
4065
  if (!value || typeof value !== "object") return void 0;
3761
4066
  return value[key];
3762
4067
  };
3763
- var isSuccessCode4 = (code) => {
4068
+ var isSuccessCode5 = (code) => {
3764
4069
  if (code === void 0 || code === null || code === "") return true;
3765
4070
  const normalized = Number(code);
3766
4071
  return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;