openxiangda 1.0.88 → 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,
@@ -846,18 +847,39 @@ var normalizeDynamicOrder = (value) => {
846
847
  }
847
848
  return `${value.id}:${value.isAsc === "n" ? "-" : "+"}`;
848
849
  };
850
+ var hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
851
+ var normalizeEnvelopeCode = (value) => {
852
+ if (value === void 0 || value === null || value === "") {
853
+ return 200;
854
+ }
855
+ const normalized = Number(value);
856
+ return Number.isFinite(normalized) ? normalized : String(value);
857
+ };
858
+ var isSuccessCode = (value) => {
859
+ if (value === void 0 || value === null || value === "") {
860
+ return true;
861
+ }
862
+ const normalized = Number(value);
863
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
864
+ };
865
+ var getEnvelopeCode = (rawResponse) => {
866
+ if (isRecord(rawResponse) && hasOwn(rawResponse, "code")) {
867
+ return rawResponse.code;
868
+ }
869
+ const nestedData = rawResponse?.data;
870
+ if (isRecord(nestedData) && hasOwn(nestedData, "code")) {
871
+ return nestedData.code;
872
+ }
873
+ return void 0;
874
+ };
849
875
  var normalizeJsonResponse = (rawResponse) => {
850
- const topLevelCode = Number(rawResponse?.code);
851
- const nestedCode = Number(
852
- rawResponse?.data?.code
853
- );
854
- const code = Number.isFinite(topLevelCode) ? topLevelCode : Number.isFinite(nestedCode) ? nestedCode : 200;
876
+ const code = normalizeEnvelopeCode(getEnvelopeCode(rawResponse));
855
877
  const topLevelResult = isRecord(rawResponse) && "result" in rawResponse ? rawResponse.result : void 0;
856
878
  const nestedResult = isRecord(rawResponse?.data) && "result" in (rawResponse.data || {}) ? rawResponse.data?.result : void 0;
857
879
  const topLevelData = isRecord(rawResponse) && "data" in rawResponse ? rawResponse.data : void 0;
858
880
  const result = topLevelResult !== void 0 ? topLevelResult : nestedResult !== void 0 ? nestedResult : topLevelData !== void 0 ? topLevelData : isRecord(rawResponse) ? rawResponse : null;
859
881
  const nestedSuccess = typeof rawResponse?.data?.success === "boolean" ? rawResponse.data?.success : void 0;
860
- const success = typeof rawResponse?.success === "boolean" ? Boolean(rawResponse.success) : typeof nestedSuccess === "boolean" ? Boolean(nestedSuccess) : code >= 200 && code < 300;
882
+ const success = rawResponse?.success === false || nestedSuccess === false ? false : isSuccessCode(code);
861
883
  return {
862
884
  code,
863
885
  success,
@@ -902,6 +924,9 @@ var normalizeBinaryResponse = (rawResponse) => {
902
924
  };
903
925
  };
904
926
  var toSdkError = (input, payload) => {
927
+ if (input instanceof Error && input.response) {
928
+ return input;
929
+ }
905
930
  const normalizedResponse = isRecord(input) ? normalizeJsonResponse(input) : void 0;
906
931
  const nextError = input instanceof Error ? input : new Error(
907
932
  normalizedResponse?.message || `\u8BF7\u6C42\u5931\u8D25: ${String(payload.method).toUpperCase()} ${payload.path}`
@@ -2523,6 +2548,187 @@ var createBoundFetch = (fetchImpl) => {
2523
2548
  return ((input, init) => baseFetch.call(globalThis, input, init));
2524
2549
  };
2525
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
+
2526
2732
  // packages/sdk/src/runtime/react/auth.tsx
2527
2733
  var import_react7 = require("react");
2528
2734
  var import_antd2 = require("antd");
@@ -2560,7 +2766,8 @@ var createAuthClient = ({
2560
2766
  });
2561
2767
  const payload = await readPayload(response);
2562
2768
  const code = getRecordValue(payload, "code");
2563
- if (!response.ok || typeof code === "number" && code >= 400) {
2769
+ const success = getRecordValue(payload, "success");
2770
+ if (!response.ok || success === false || !isSuccessCode3(code)) {
2564
2771
  throw new AuthClientError(
2565
2772
  String(getRecordValue(payload, "message") || `Auth request failed: ${response.status}`),
2566
2773
  { status: response.status, code, payload }
@@ -2613,6 +2820,11 @@ var getRecordValue = (value, key) => {
2613
2820
  if (!value || typeof value !== "object") return void 0;
2614
2821
  return value[key];
2615
2822
  };
2823
+ var isSuccessCode3 = (code) => {
2824
+ if (code === void 0 || code === null || code === "") return true;
2825
+ const normalized = Number(code);
2826
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
2827
+ };
2616
2828
  var resolveLoginUrl = (appType, {
2617
2829
  callbackUrl = getCurrentHref2(),
2618
2830
  callbackParamName = "callback",
@@ -3193,7 +3405,7 @@ var OpenXiangdaProvider = ({
3193
3405
  }
3194
3406
  );
3195
3407
  const payload = await readJsonPayload(response);
3196
- if (!response.ok || payload?.code >= 400) {
3408
+ if (isRuntimeEnvelopeFailure(response, payload)) {
3197
3409
  throw createRuntimeHttpError(
3198
3410
  response,
3199
3411
  payload,
@@ -3237,6 +3449,96 @@ var useOpenXiangda = () => {
3237
3449
  return context;
3238
3450
  };
3239
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
+ };
3240
3542
  var useAppMenus = () => {
3241
3543
  const runtime = useOpenXiangda();
3242
3544
  return {
@@ -3328,7 +3630,7 @@ var useCanAccessRoute = (input) => {
3328
3630
  payload
3329
3631
  };
3330
3632
  if (!disposed) {
3331
- const shouldTreatAsError = !response.ok || typeof code === "number" && code >= 500;
3633
+ const shouldTreatAsError = !response.ok || isServerErrorCode(code);
3332
3634
  setState({
3333
3635
  data,
3334
3636
  loading: false,
@@ -3460,7 +3762,7 @@ var useRuntimeAuth = () => {
3460
3762
  }
3461
3763
  );
3462
3764
  const payload = await readJsonPayload(response);
3463
- if (!response.ok || payload?.code >= 400) {
3765
+ if (isRuntimeEnvelopeFailure(response, payload)) {
3464
3766
  throw createRuntimeHttpError(
3465
3767
  response,
3466
3768
  payload,
@@ -3550,6 +3852,15 @@ var classifyRuntimeError = (status, code) => {
3550
3852
  const normalizedCode = typeof code === "string" ? Number(code) : code;
3551
3853
  if (status === 401 || normalizedCode === 401) return "unauthenticated";
3552
3854
  if (status === 403 || normalizedCode === 403) return "forbidden";
3855
+ if (typeof code === "string") {
3856
+ const normalizedText = code.toUpperCase();
3857
+ if (normalizedText.includes("DENIED") || normalizedText.includes("FORBIDDEN")) {
3858
+ return "forbidden";
3859
+ }
3860
+ if (normalizedText.includes("UNAUTH") || normalizedText.includes("LOGIN")) {
3861
+ return "unauthenticated";
3862
+ }
3863
+ }
3553
3864
  if (!status && !normalizedCode) return "network";
3554
3865
  return "unknown";
3555
3866
  };
@@ -3605,6 +3916,53 @@ var getRecordValue2 = (value, key) => {
3605
3916
  if (!value || typeof value !== "object") return void 0;
3606
3917
  return value[key];
3607
3918
  };
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) => {
3953
+ if (code === void 0 || code === null || code === "") return true;
3954
+ const normalized = Number(code);
3955
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
3956
+ };
3957
+ var isRuntimeEnvelopeFailure = (response, payload) => {
3958
+ const code = getRecordValue2(payload, "code");
3959
+ const success = getRecordValue2(payload, "success");
3960
+ return !response.ok || success === false || !isSuccessCode4(code);
3961
+ };
3962
+ var isServerErrorCode = (code) => {
3963
+ const normalized = Number(code);
3964
+ return Number.isFinite(normalized) && normalized >= 500;
3965
+ };
3608
3966
  var getRecordString = (value, key) => {
3609
3967
  const result = getRecordValue2(value, key);
3610
3968
  return typeof result === "string" ? result : void 0;
@@ -3668,7 +4026,8 @@ var createPublicAccessClient = ({
3668
4026
  );
3669
4027
  const payload = await readPayload2(response);
3670
4028
  const code = getRecordValue3(payload, "code");
3671
- if (!response.ok || typeof code === "number" && code >= 400) {
4029
+ const success = getRecordValue3(payload, "success");
4030
+ if (!response.ok || success === false || !isSuccessCode5(code)) {
3672
4031
  throw new PublicAccessClientError(
3673
4032
  String(
3674
4033
  getRecordValue3(payload, "message") || `Public access session failed: ${response.status}`
@@ -3706,6 +4065,11 @@ var getRecordValue3 = (value, key) => {
3706
4065
  if (!value || typeof value !== "object") return void 0;
3707
4066
  return value[key];
3708
4067
  };
4068
+ var isSuccessCode5 = (code) => {
4069
+ if (code === void 0 || code === null || code === "") return true;
4070
+ const normalized = Number(code);
4071
+ return Number.isFinite(normalized) ? normalized === 0 || normalized >= 200 && normalized < 300 : false;
4072
+ };
3709
4073
  var getCurrentPathname = () => typeof window === "undefined" ? void 0 : window.location.pathname;
3710
4074
  var getCurrentDomain = () => typeof window === "undefined" ? void 0 : window.location.host;
3711
4075
  var getCurrentUserAgent = () => typeof navigator === "undefined" ? void 0 : navigator.userAgent;