@blocklet/did-space-react 0.5.66 → 0.5.68

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.
@@ -3,6 +3,7 @@ import { SpaceGateway, SpaceStatus } from '../../types';
3
3
  export type Action = React.ReactNode | ((props: {
4
4
  spaceGateway: SpaceGateway;
5
5
  spaceStatus: SpaceStatus;
6
+ errorCode: number;
6
7
  selected: boolean;
7
8
  compat: boolean;
8
9
  refresh: () => void;
@@ -7,10 +7,12 @@ import DidAddress from '@arcblock/ux/lib/DID';
7
7
  import { styled } from '@arcblock/ux/lib/Theme';
8
8
  import { useState, useRef, useEffect } from 'react';
9
9
  import { AxiosError } from 'axios';
10
+ import { useCreation } from 'ahooks';
11
+ import { SPACE_CONNECT_ERROR_CODE } from '../../libs/constants.js';
10
12
  import useMobile from '../../hooks/use-mobile.js';
11
13
  import useSpaceInfo from '../../hooks/use-space-info.js';
12
14
  import useLocale from '../../hooks/use-locale.js';
13
- import { getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceGatewayUrlFromEndpoint, classNames, getSpaceNftDisplayUrlFromEndpoint } from '../../libs/util.js';
15
+ import { getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceGatewayUrlFromEndpoint, isCorsBlockedError, classNames, getSpaceNftDisplayUrlFromEndpoint } from '../../libs/util.js';
14
16
  import { SpaceStatus } from '../../types/index.js';
15
17
  import '../../icons/index.js';
16
18
  import { PreviewSpaceNft } from '../preview-space-nft/index.js';
@@ -21,61 +23,83 @@ import SvgSpaceConnectError from '../../icons/space-connect-error.svg.js';
21
23
  function Status({
22
24
  spaceUrl,
23
25
  status,
24
- isError,
26
+ errorCode,
25
27
  refresh,
26
28
  sx,
27
29
  ...rest
28
30
  }) {
29
- const { t } = useLocale();
31
+ const { t, locale } = useLocale();
30
32
  const iconStyle = { marginRight: "4px" };
31
- let icon = null;
32
- let text = null;
33
- if (status === SpaceStatus.CONNECTED) {
34
- icon = /* @__PURE__ */ jsx(SvgSpaceConnected, { style: iconStyle });
35
- text = /* @__PURE__ */ jsx("span", { style: { color: "#047857" }, children: t("storage.spaces.connected.tag") });
36
- }
37
- if (status === SpaceStatus.DISCONNECTED) {
38
- icon = /* @__PURE__ */ jsx(SvgSpaceDisconnect, { style: iconStyle });
39
- text = /* @__PURE__ */ jsx("span", { style: { color: "#626a77" }, children: t("storage.spaces.disconnected.tag") });
40
- }
41
- if (status === SpaceStatus.EXPIRED) {
42
- icon = /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle });
43
- text = /* @__PURE__ */ jsx(Tooltip, { title: t("storage.spaces.error.expired"), placement: "top", children: /* @__PURE__ */ jsxs(
44
- Link,
45
- {
46
- href: withQuery(joinURL(spaceUrl, "overview"), { guide: 1 }),
47
- target: "_blank",
48
- underline: "hover",
49
- color: "error",
50
- sx: { display: "flex", alignItems: "center", color: "error.main" },
51
- children: [
52
- /* @__PURE__ */ jsx("span", { children: t("storage.spaces.error.tag") }),
53
- /* @__PURE__ */ jsx(OpenInNewIcon, { sx: { fontSize: "14px", marginLeft: "4px" } })
54
- ]
33
+ const spaceGuideUrl = withQuery(joinURL(spaceUrl, "overview"), { guide: 1 });
34
+ const statusConfig = useCreation(
35
+ () => ({
36
+ // 加载中
37
+ [SpaceStatus.LOADING]: {
38
+ icon: null,
39
+ text: null
40
+ },
41
+ // 已连接
42
+ [SpaceStatus.CONNECTED]: {
43
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnected, { style: iconStyle }),
44
+ text: /* @__PURE__ */ jsx("span", { style: { color: "#047857" }, children: t("storage.spaces.connected.tag") })
45
+ },
46
+ // 未连接(未授权)
47
+ [SpaceStatus.DISCONNECTED]: {
48
+ icon: /* @__PURE__ */ jsx(SvgSpaceDisconnect, { style: iconStyle }),
49
+ text: /* @__PURE__ */ jsx("span", { style: { color: "#626a77" }, children: t("storage.spaces.disconnected.tag") })
55
50
  }
56
- ) });
57
- }
58
- if (status === SpaceStatus.CORS_BLOCKED) {
59
- icon = /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle });
60
- text = /* @__PURE__ */ jsx(Tooltip, { title: t("storage.spaces.error.corsBlocked"), placement: "top", children: /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", color: "error.main" }, children: /* @__PURE__ */ jsx("span", { children: t("storage.spaces.error.tag") }) }) });
61
- }
62
- if (status === SpaceStatus.UNKNOWN) {
63
- icon = /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle });
64
- text = /* @__PURE__ */ jsx(Box, { sx: { color: "error.main" }, children: t("storage.spaces.error.networkError") });
65
- }
51
+ }),
52
+ [locale]
53
+ );
54
+ const errorStatusConfig = useCreation(
55
+ () => ({
56
+ // 未知的网络错误(如超时)
57
+ [SPACE_CONNECT_ERROR_CODE.NETWORK_ERROR]: {
58
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
59
+ text: /* @__PURE__ */ jsx(Box, { sx: { color: "error.main" }, children: t("storage.spaces.error.networkError") })
60
+ },
61
+ // 订阅过期
62
+ [SPACE_CONNECT_ERROR_CODE.EXPIRED]: {
63
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
64
+ text: /* @__PURE__ */ jsx(ErrorLink, { title: t("storage.spaces.error.expired"), url: spaceGuideUrl })
65
+ },
66
+ // 订阅逾期
67
+ [SPACE_CONNECT_ERROR_CODE.PAST_DUE]: {
68
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
69
+ text: /* @__PURE__ */ jsx(ErrorLink, { title: t("storage.spaces.error.pastDue"), url: spaceGuideUrl })
70
+ },
71
+ // 订阅状态异常
72
+ [SPACE_CONNECT_ERROR_CODE.INVALID]: {
73
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
74
+ text: /* @__PURE__ */ jsx(ErrorLink, { title: t("storage.spaces.error.invalid"), url: spaceGuideUrl })
75
+ },
76
+ // 用量不足
77
+ [SPACE_CONNECT_ERROR_CODE.UNIT_LIMIT]: {
78
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
79
+ text: /* @__PURE__ */ jsx(ErrorLink, { title: t("storage.spaces.error.unitLimit"), url: spaceGuideUrl })
80
+ },
81
+ // CORS 拦截
82
+ [SPACE_CONNECT_ERROR_CODE.CORS_BLOCKED]: {
83
+ icon: /* @__PURE__ */ jsx(SvgSpaceConnectError, { style: iconStyle }),
84
+ text: /* @__PURE__ */ jsx(Tooltip, { title: t("storage.spaces.error.corsBlocked"), placement: "top", children: /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", color: "error.main" }, children: /* @__PURE__ */ jsx("span", { children: t("storage.spaces.error.tag") }) }) })
85
+ }
86
+ }),
87
+ [locale]
88
+ );
89
+ const { icon, text } = status === SpaceStatus.UNAVAILABLE ? errorStatusConfig[errorCode] : statusConfig[status];
66
90
  useEffect(() => {
67
91
  const handleVisibilityChange = () => {
68
92
  if (!document.hidden) {
69
93
  refresh();
70
94
  }
71
95
  };
72
- if (isError) {
96
+ if (status !== SpaceStatus.CONNECTED) {
73
97
  document.addEventListener("visibilitychange", handleVisibilityChange);
74
98
  } else {
75
99
  document.removeEventListener("visibilitychange", handleVisibilityChange);
76
100
  }
77
101
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
78
- }, [isError, refresh]);
102
+ }, [status, refresh]);
79
103
  return /* @__PURE__ */ jsxs(
80
104
  Box,
81
105
  {
@@ -90,6 +114,23 @@ function Status({
90
114
  }
91
115
  );
92
116
  }
117
+ function ErrorLink({ title, url }) {
118
+ const { t } = useLocale();
119
+ return /* @__PURE__ */ jsx(Tooltip, { title, placement: "top", children: /* @__PURE__ */ jsxs(
120
+ Link,
121
+ {
122
+ href: url,
123
+ target: "_blank",
124
+ underline: "hover",
125
+ color: "error",
126
+ sx: { display: "flex", alignItems: "center", color: "error.main" },
127
+ children: [
128
+ /* @__PURE__ */ jsx("span", { children: t("storage.spaces.error.tag") }),
129
+ /* @__PURE__ */ jsx(OpenInNewIcon, { sx: { fontSize: "14px", marginLeft: "4px" } })
130
+ ]
131
+ }
132
+ ) });
133
+ }
93
134
  function SpaceCard({ endpoint, selected = false, compat, action, className, deps, ...rest }) {
94
135
  const isMobile = useMobile();
95
136
  const { t } = useLocale();
@@ -111,33 +152,30 @@ function SpaceCard({ endpoint, selected = false, compat, action, className, deps
111
152
  deps: [refreshSpaceInfo].concat(deps ?? [])
112
153
  });
113
154
  let spaceName = "";
114
- const hasPermission = spaceInfo?.hasPermission ?? false;
115
155
  const isAvailable = spaceInfo?.isAvailable ?? false;
116
- let isError = false;
117
156
  const spaceStatus = useRef(SpaceStatus.LOADING);
157
+ let errorCode = 0;
118
158
  if (loading) {
119
159
  spaceStatus.current = SpaceStatus.LOADING;
120
160
  spaceName = /* @__PURE__ */ jsx(Skeleton, { variant: "text", sx: { width: "180px", fontSize: "1rem" } });
121
161
  } else if (spaceInfo) {
122
162
  spaceName = spaceInfo.spaceName;
123
163
  if (!isAvailable) {
124
- spaceStatus.current = SpaceStatus.EXPIRED;
125
- isError = true;
126
- } else if (hasPermission) {
127
- spaceStatus.current = SpaceStatus.CONNECTED;
164
+ spaceStatus.current = SpaceStatus.UNAVAILABLE;
165
+ errorCode = spaceInfo.errorCode;
166
+ if (errorCode === SPACE_CONNECT_ERROR_CODE.UNAUTHORIZED) {
167
+ spaceStatus.current = SpaceStatus.DISCONNECTED;
168
+ }
128
169
  } else {
129
- spaceStatus.current = SpaceStatus.DISCONNECTED;
170
+ spaceStatus.current = SpaceStatus.CONNECTED;
130
171
  }
131
172
  } else if (error instanceof AxiosError) {
132
173
  spaceName = t("common.unknown");
133
- isError = true;
134
- if (!error.response && // 无响应
135
- error.message === "Network Error" && // 网络错误
136
- error.code !== "ECONNABORTED" && // 非超时引起
137
- new URL(error.config.url).origin !== window.location.origin) {
138
- spaceStatus.current = SpaceStatus.CORS_BLOCKED;
174
+ spaceStatus.current = SpaceStatus.UNAVAILABLE;
175
+ if (isCorsBlockedError(error)) {
176
+ errorCode = SPACE_CONNECT_ERROR_CODE.CORS_BLOCKED;
139
177
  } else {
140
- spaceStatus.current = SpaceStatus.UNKNOWN;
178
+ errorCode = SPACE_CONNECT_ERROR_CODE.NETWORK_ERROR;
141
179
  }
142
180
  }
143
181
  const renderAction = () => {
@@ -152,6 +190,7 @@ function SpaceCard({ endpoint, selected = false, compat, action, className, deps
152
190
  endpoint
153
191
  },
154
192
  spaceStatus: spaceStatus.current,
193
+ errorCode,
155
194
  selected,
156
195
  compat: isCompact,
157
196
  refresh
@@ -164,7 +203,7 @@ function SpaceCard({ endpoint, selected = false, compat, action, className, deps
164
203
  {
165
204
  className: classNames(className, {
166
205
  selected,
167
- error: isError
206
+ error: errorCode > 0
168
207
  }),
169
208
  ...rest,
170
209
  children: [
@@ -178,8 +217,8 @@ function SpaceCard({ endpoint, selected = false, compat, action, className, deps
178
217
  {
179
218
  spaceUrl,
180
219
  status: spaceStatus.current,
220
+ errorCode,
181
221
  refresh,
182
- isError,
183
222
  sx: { mr: 1 }
184
223
  }
185
224
  )
@@ -208,8 +247,8 @@ function SpaceCard({ endpoint, selected = false, compat, action, className, deps
208
247
  {
209
248
  spaceUrl,
210
249
  status: spaceStatus.current,
250
+ errorCode,
211
251
  refresh,
212
- isError,
213
252
  flexShrink: 0
214
253
  }
215
254
  ),
@@ -3,6 +3,8 @@ export default function useSpaceInfo({ endpoint, deps }: {
3
3
  deps?: any[];
4
4
  }): import("ahooks/lib/useRequest/src/types").Result<{
5
5
  spaceName: string;
6
- hasPermission: boolean;
6
+ subscriptionId: any;
7
7
  isAvailable: boolean;
8
+ errorMessage: string;
9
+ errorCode: number;
8
10
  } | undefined, []>;
@@ -9,13 +9,18 @@ function useSpaceInfo({ endpoint, deps = [] }) {
9
9
  return void 0;
10
10
  }
11
11
  const { headers } = await api.head(endpoint, {
12
- timeout: 1e3 * 30
12
+ timeout: 1e3 * 30,
13
+ params: {
14
+ withExtras: true
15
+ }
13
16
  });
14
17
  const spaceName = headers["x-space-name"];
15
18
  return {
16
19
  spaceName: spaceName ? decodeURIComponent(spaceName) : "",
17
- hasPermission: headers["x-listable"] === "true" && headers["x-readable"] === "true" && headers["x-writeable"] === "true",
18
- isAvailable: headers["x-space-is-available"] === "true"
20
+ subscriptionId: headers["x-subscription-id"],
21
+ isAvailable: headers["x-space-is-available"] === "true",
22
+ errorMessage: decodeURIComponent(headers["x-error-message"]),
23
+ errorCode: parseInt(headers["x-error-code"], 10)
19
24
  };
20
25
  },
21
26
  {
@@ -7,6 +7,7 @@ export * from './components/preview-space-nft';
7
7
  export * from './components/base-connect-to';
8
8
  export * from './components/auth-connect-to';
9
9
  export * from './components/session-connect-to';
10
+ export * from './libs/constants';
10
11
  export * from './libs/util';
11
12
  export * from './libs/gateway';
12
13
  export * from './locales';
package/dist/es/index.js CHANGED
@@ -7,8 +7,9 @@ export { PreviewSpaceNft } from './components/preview-space-nft/index.js';
7
7
  export { BaseConnectTo } from './components/base-connect-to/index.js';
8
8
  export { AuthConnectTo } from './components/auth-connect-to/index.js';
9
9
  export { SessionConnectTo } from './components/session-connect-to/index.js';
10
- export { classNames, decryptSpaceGateway, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromGatewayUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint } from './libs/util.js';
11
- export { getSpaceGatewayUrl, isValidSpaceGatewayUrl } from './libs/gateway.js';
10
+ export { AUTHORIZE, SPACE_CONNECT_ERROR_CODE, copyGatewayPageUrl } from './libs/constants.js';
11
+ export { classNames, decryptSpaceGateway, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromSpaceUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint, isCorsBlockedError, t } from './libs/util.js';
12
+ export { getSpaceGatewayUrl, verifySpaceUrl } from './libs/gateway.js';
12
13
  export { translations } from './locales/index.js';
13
14
  export { SpaceStatus } from './types/index.js';
14
15
  import './icons/index.js';
@@ -1,3 +1,19 @@
1
+ export declare const SPACE_CONNECT_ERROR_CODE: {
2
+ /** 网络错误 */
3
+ NETWORK_ERROR: number;
4
+ /** 未授权 */
5
+ UNAUTHORIZED: number;
6
+ /** 订阅过期 */
7
+ EXPIRED: number;
8
+ /** 订阅逾期 */
9
+ PAST_DUE: number;
10
+ /** 订阅状态异常 */
11
+ INVALID: number;
12
+ /** 用量不足 */
13
+ UNIT_LIMIT: number;
14
+ /** 跨域限制 */
15
+ CORS_BLOCKED: number;
16
+ };
1
17
  export declare const AUTHORIZE: {
2
18
  DEFAULT_SCOPE: string;
3
19
  };
@@ -1,6 +1,22 @@
1
+ const SPACE_CONNECT_ERROR_CODE = {
2
+ /** 网络错误 */
3
+ NETWORK_ERROR: 1001,
4
+ /** 未授权 */
5
+ UNAUTHORIZED: 1002,
6
+ /** 订阅过期 */
7
+ EXPIRED: 1003,
8
+ /** 订阅逾期 */
9
+ PAST_DUE: 1004,
10
+ /** 订阅状态异常 */
11
+ INVALID: 1005,
12
+ /** 用量不足 */
13
+ UNIT_LIMIT: 1006,
14
+ /** 跨域限制 */
15
+ CORS_BLOCKED: 1007
16
+ };
1
17
  const AUTHORIZE = {
2
18
  DEFAULT_SCOPE: "list:object read:object write:object"
3
19
  };
4
20
  const copyGatewayPageUrl = "https://www.arcblock.io/content/docs/did-spaces/how-to-obtain-space-gateway-url";
5
21
 
6
- export { AUTHORIZE, copyGatewayPageUrl };
22
+ export { AUTHORIZE, SPACE_CONNECT_ERROR_CODE, copyGatewayPageUrl };
@@ -2,4 +2,8 @@ export declare function getSpaceGatewayUrl(anyUrl: string, options?: {
2
2
  timeout: number;
3
3
  withSearchParams: boolean;
4
4
  }): Promise<string>;
5
- export declare function isValidSpaceGatewayUrl(spaceGatewayUrl: string): Promise<boolean>;
5
+ export declare function verifySpaceUrl({ spaceGatewayUrl, spaceDid, locale, }: {
6
+ spaceGatewayUrl: string;
7
+ spaceDid?: string;
8
+ locale?: string;
9
+ }): Promise<void>;
@@ -2,8 +2,9 @@ import { joinURL, withQuery } from 'ufo';
2
2
  import isUrl from 'is-url';
3
3
  import isString from 'lodash/isString';
4
4
  import isObject from 'lodash/isObject';
5
+ import { isValid } from '@arcblock/did';
5
6
  import api from './api.js';
6
- import { extraDIDSpacesCoreUrl } from './util.js';
7
+ import { t, extraDIDSpacesCoreUrl } from './util.js';
7
8
 
8
9
  async function getSpaceGatewayUrl(anyUrl, options = { timeout: 3e4, withSearchParams: true }) {
9
10
  if (!isString(anyUrl)) {
@@ -24,21 +25,25 @@ async function getSpaceGatewayUrl(anyUrl, options = { timeout: 3e4, withSearchPa
24
25
  const spaceGatewayUrl = options.withSearchParams && u.searchParams.get("spaceDid") ? withQuery(didSpacesCoreUrl, { spaceDid: u.searchParams.get("spaceDid") }) : didSpacesCoreUrl;
25
26
  return spaceGatewayUrl;
26
27
  }
27
- async function isValidSpaceGatewayUrl(spaceGatewayUrl) {
28
- try {
29
- if (!isUrl(spaceGatewayUrl)) {
30
- return false;
31
- }
32
- const didSpacesCoreUrl = extraDIDSpacesCoreUrl(spaceGatewayUrl);
33
- const didConnectTokenUrl = joinURL(didSpacesCoreUrl, "space/api/did/one-click-authorization/token");
34
- const { status, data } = await api.get(didConnectTokenUrl, {
35
- timeout: 5e3
36
- });
37
- return status === 200 && isObject(data);
38
- } catch (error) {
39
- console.error(error);
40
- return false;
28
+ async function verifySpaceUrl({
29
+ spaceGatewayUrl,
30
+ spaceDid,
31
+ locale
32
+ }) {
33
+ if (!isUrl(spaceGatewayUrl)) {
34
+ throw new Error(t("common.invalidUrl", locale, { url: spaceGatewayUrl }));
35
+ }
36
+ if (!spaceDid || !isValid(spaceDid)) {
37
+ throw new Error(t("storage.spaces.gateway.add.invalidUrl", locale));
38
+ }
39
+ const didSpacesCoreUrl = extraDIDSpacesCoreUrl(spaceGatewayUrl);
40
+ const didConnectTokenUrl = joinURL(didSpacesCoreUrl, "space/api/did/one-click-authorization/token");
41
+ const { status, data } = await api.get(didConnectTokenUrl, {
42
+ timeout: 5e3
43
+ });
44
+ if (!(status === 200 && isObject(data))) {
45
+ throw new Error(t("storage.spaces.gateway.add.invalidUrl", locale));
41
46
  }
42
47
  }
43
48
 
44
- export { getSpaceGatewayUrl, isValidSpaceGatewayUrl };
49
+ export { getSpaceGatewayUrl, verifySpaceUrl };
@@ -1,3 +1,4 @@
1
+ import { type AxiosError } from 'axios';
1
2
  type ClassStr = string | undefined | null;
2
3
  /** classObj -> className
3
4
  * examples:
@@ -16,6 +17,9 @@ export declare function getSpaceNftDisplayUrlFromEndpoint(endpoint: string): str
16
17
  export declare function getSpaceDidFromEndpoint(endpoint: string): string | undefined;
17
18
  export declare function getSpaceGatewayUrlFromEndpoint(endpoint: string): string;
18
19
  export declare function extraDIDSpacesCoreUrl(url: string): string;
19
- export declare function getSpaceDidFromGatewayUrl(url: string): string | undefined;
20
+ export declare function getSpaceDidFromSpaceUrl(url: string): string | undefined;
20
21
  export declare function decryptSpaceGateway(response: Record<string, string>, decrypt: Function): any;
22
+ export declare function isCorsBlockedError(error: AxiosError): boolean;
23
+ export declare function t(key: string, locale?: string, data?: Record<string, any>): string;
24
+ export declare function t(key: string, data?: Record<string, any>): string;
21
25
  export {};
@@ -1,5 +1,7 @@
1
1
  import { joinURL } from 'ufo';
2
2
  import isEmpty from 'lodash/isEmpty';
3
+ import { translate } from '@arcblock/ux/lib/Locale/util';
4
+ import { translations } from '../locales/index.js';
3
5
 
4
6
  function classNames(...classes) {
5
7
  const result = [];
@@ -52,7 +54,7 @@ function extraDIDSpacesCoreUrl(url) {
52
54
  return didSpacesCoreUrl;
53
55
  }
54
56
  const spaceDidRegex = /\/space\/([^/]+)/;
55
- function getSpaceDidFromGatewayUrl(url) {
57
+ function getSpaceDidFromSpaceUrl(url) {
56
58
  return new URL(url).pathname.match(spaceDidRegex)?.[1];
57
59
  }
58
60
  function decryptSpaceGateway(response, decrypt) {
@@ -68,5 +70,16 @@ function decryptSpaceGateway(response, decrypt) {
68
70
  ...space
69
71
  };
70
72
  }
73
+ function isCorsBlockedError(error) {
74
+ return !error.response && // 无响应
75
+ error.message === "Network Error" && // 是网络错误
76
+ error.code !== "ECONNABORTED" && // 非超时引起
77
+ new URL(error.config.url).origin !== window.location.origin;
78
+ }
79
+ function t(key, localeOrData, data = {}) {
80
+ const locale = typeof localeOrData === "string" ? localeOrData : "en";
81
+ const finalData = typeof localeOrData === "object" ? localeOrData : data;
82
+ return translate(translations, key, locale, "en", finalData);
83
+ }
71
84
 
72
- export { classNames, decryptSpaceGateway, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromGatewayUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint };
85
+ export { classNames, decryptSpaceGateway, extraDIDSpacesCoreUrl, getDIDSpaceDidFromEndpoint, getDIDSpaceUrlFromEndpoint, getSpaceDidFromEndpoint, getSpaceDidFromSpaceUrl, getSpaceGatewayUrlFromEndpoint, getSpaceNftDisplayUrlFromEndpoint, isCorsBlockedError, t };
@@ -7,7 +7,8 @@ const en = flatten({
7
7
  delete: "Delete",
8
8
  error: "Error",
9
9
  open: "Open",
10
- unknown: "Unknown"
10
+ unknown: "Unknown",
11
+ invalidUrl: "Invalid url: {url}"
11
12
  },
12
13
  storage: {
13
14
  spaces: {
@@ -32,8 +33,11 @@ const en = flatten({
32
33
  },
33
34
  error: {
34
35
  tag: "Need Attention",
35
- expired: "This DID spaces has expired, you can re-subscribe by opening this link",
36
- corsBlocked: "Connection requests may be blocked by CORS. Please check security settings in the DID Space dashboard.",
36
+ expired: "DID Spaces has expired, click this link to re-subscribe",
37
+ pastDue: "DID Spaces has unpaid bills, click this link to complete payment",
38
+ invalid: "DID Spaces subscription anomaly, click this link to check",
39
+ unitLimit: "DID Spaces free quota has been used up, click this link to pay for the upgrade",
40
+ corsBlocked: "Connection requests may be blocked by CORS. Please contact your DID Space administrator to check the settings",
37
41
  networkError: "Network error"
38
42
  },
39
43
  gateway: {
@@ -7,7 +7,8 @@ const zh = flatten({
7
7
  delete: "\u5220\u9664",
8
8
  error: "\u9519\u8BEF",
9
9
  open: "\u6253\u5F00",
10
- unknown: "\u672A\u77E5"
10
+ unknown: "\u672A\u77E5",
11
+ invalidUrl: "\u65E0\u6548\u7684 url: {url}"
11
12
  },
12
13
  storage: {
13
14
  spaces: {
@@ -32,8 +33,11 @@ const zh = flatten({
32
33
  },
33
34
  error: {
34
35
  tag: "\u9700\u8981\u5173\u6CE8",
35
- expired: "\u6B64 DID Spaces \u5DF2\u8FC7\u671F\uFF0C\u60A8\u53EF\u4EE5\u6253\u5F00\u6B64\u94FE\u63A5\u91CD\u65B0\u8BA2\u9605",
36
- corsBlocked: "\u8FDE\u63A5\u8BF7\u6C42\u53EF\u80FD\u88AB CORS \u963B\u6B62\u3002\u8BF7\u68C0\u67E5 DID Space \u63A7\u5236\u9762\u677F\u4E2D\u7684\u5B89\u5168\u8BBE\u7F6E\u3002",
36
+ expired: "DID Spaces \u5DF2\u8FC7\u671F\uFF0C\u70B9\u51FB\u6B64\u94FE\u63A5\u91CD\u65B0\u8BA2\u9605",
37
+ pastDue: "DID Spaces \u6709\u672A\u652F\u4ED8\u8D26\u5355\uFF0C\u70B9\u51FB\u6B64\u94FE\u63A5\u5B8C\u6210\u652F\u4ED8",
38
+ invalid: "DID Spaces \u8BA2\u9605\u5F02\u5E38\uFF0C\u70B9\u51FB\u6B64\u94FE\u63A5\u68C0\u67E5",
39
+ unitLimit: "DID Spaces \u514D\u8D39\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u70B9\u51FB\u6B64\u94FE\u63A5\u4ED8\u8D39\u5347\u7EA7",
40
+ corsBlocked: "\u8FDE\u63A5\u8BF7\u6C42\u53EF\u80FD\u88AB CORS \u9650\u5236\uFF0C\u8BF7\u8054\u7CFB DID Space \u7BA1\u7406\u5458\u68C0\u67E5\u76F8\u5173\u8BBE\u7F6E",
37
41
  networkError: "\u7F51\u7EDC\u9519\u8BEF"
38
42
  },
39
43
  gateway: {
@@ -20,9 +20,8 @@ export declare enum SpaceStatus {
20
20
  LOADING = "loading",
21
21
  CONNECTED = "connected",
22
22
  DISCONNECTED = "disconnected",
23
- EXPIRED = "expired",
24
- CORS_BLOCKED = "corsBlocked",
25
- UNKNOWN = "unknown"
23
+ /** 不可用,跟订阅状态相关,比如过期、逾期、用量不足等 */
24
+ UNAVAILABLE = "unavailable"
26
25
  }
27
26
  export interface SpaceGateway {
28
27
  did: string;
@@ -2,9 +2,7 @@ var SpaceStatus = /* @__PURE__ */ ((SpaceStatus2) => {
2
2
  SpaceStatus2["LOADING"] = "loading";
3
3
  SpaceStatus2["CONNECTED"] = "connected";
4
4
  SpaceStatus2["DISCONNECTED"] = "disconnected";
5
- SpaceStatus2["EXPIRED"] = "expired";
6
- SpaceStatus2["CORS_BLOCKED"] = "corsBlocked";
7
- SpaceStatus2["UNKNOWN"] = "unknown";
5
+ SpaceStatus2["UNAVAILABLE"] = "unavailable";
8
6
  return SpaceStatus2;
9
7
  })(SpaceStatus || {});
10
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/did-space-react",
3
- "version": "0.5.66",
3
+ "version": "0.5.68",
4
4
  "description": "Reusable react components for did space",
5
5
  "keywords": [
6
6
  "react",
@@ -84,11 +84,11 @@
84
84
  }
85
85
  },
86
86
  "dependencies": {
87
- "@arcblock/did": "^1.18.139",
88
- "@arcblock/did-connect": "^2.10.64",
89
- "@arcblock/ux": "^2.10.64",
90
- "@blocklet/js-sdk": "1.16.32",
91
- "@blocklet/sdk": "1.16.32",
87
+ "@arcblock/did": "^1.18.144",
88
+ "@arcblock/did-connect": "^2.10.65",
89
+ "@arcblock/ux": "^2.10.65",
90
+ "@blocklet/js-sdk": "^1.16.33",
91
+ "@blocklet/sdk": "^1.16.33",
92
92
  "@mui/icons-material": "^5.16.7",
93
93
  "@mui/lab": "^5.0.0-alpha.173",
94
94
  "@mui/material": "^5.16.7",
@@ -127,7 +127,7 @@
127
127
  "@types/react": "^18.3.12",
128
128
  "@types/react-dom": "^18.3.1",
129
129
  "@vitejs/plugin-legacy": "^5.4.3",
130
- "@vitest/coverage-v8": "^2.1.4",
130
+ "@vitest/coverage-v8": "^2.1.5",
131
131
  "babel-plugin-inline-react-svg": "^2.0.2",
132
132
  "copyfiles": "^2.4.1",
133
133
  "eslint": "^8.57.1",
@@ -137,13 +137,13 @@
137
137
  "react-dom": "^18.3.1",
138
138
  "rollup-plugin-node-builtins": "^2.1.2",
139
139
  "storybook": "^7.6.20",
140
- "type-fest": "^4.26.1",
140
+ "type-fest": "^4.27.0",
141
141
  "typescript": "~5.5.4",
142
142
  "unbuild": "^2.0.0",
143
143
  "vite": "^5.4.11",
144
144
  "vite-plugin-babel": "^1.2.0",
145
145
  "vite-plugin-node-polyfills": "^0.22.0",
146
- "vitest": "^2.1.4"
146
+ "vitest": "^2.1.5"
147
147
  },
148
- "gitHead": "4d2971ce890ba083ef8a6240615a8f416b3e2b2b"
148
+ "gitHead": "154e33932d965d3a6088058eb353bf7be2fe771c"
149
149
  }