@next-core/easyops-runtime 0.15.26 → 0.15.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/auth.js CHANGED
@@ -74,22 +74,71 @@ function addPathToBlackList(path) {
74
74
 
75
75
  /**
76
76
  * 判断一个内部 URL 路径是否被屏蔽。
77
+ *
78
+ * @param pathnameWithQuery - 路径(可包含查询字符串)
79
+ * @returns 是否被屏蔽
80
+ */
81
+ function isBlockedPath(pathnameWithQuery) {
82
+ return [...pathBlackListSet].some(pattern => {
83
+ // 分离 pattern 的路径和查询字符串
84
+ const [patternPath, patternQuery] = pattern.split("?");
85
+
86
+ // 分离待检查路径的路径和查询字符串
87
+ const [pathname, pathQuery] = pathnameWithQuery.split("?");
88
+
89
+ // 首先匹配路径部分
90
+ const pathMatched = (0, _runtime.matchPath)(pathname, {
91
+ path: patternPath
92
+ });
93
+ if (!pathMatched) {
94
+ return false;
95
+ }
96
+
97
+ // 如果 pattern 不包含查询字符串,只要路径匹配就返回 true
98
+ if (!patternQuery) {
99
+ return true;
100
+ }
101
+
102
+ // 如果 pattern 包含查询字符串,但待检查路径没有,返回 false
103
+ if (!pathQuery) {
104
+ return false;
105
+ }
106
+
107
+ // 精确匹配查询字符串(所有 pattern 中的参数必须存在且值相同)
108
+ const patternParams = new URLSearchParams(patternQuery);
109
+ const pathParams = new URLSearchParams(pathQuery);
110
+ for (const [key, value] of patternParams.entries()) {
111
+ if (pathParams.get(key) !== value) {
112
+ return false;
113
+ }
114
+ }
115
+ return true;
116
+ });
117
+ }
118
+
119
+ /**
120
+ * 根据特性开关决定是否拼接查询字符串
121
+ * @param pathname - 路径名
122
+ * @param search - 查询字符串(可选)
123
+ * @returns 拼接后的路径
77
124
  */
78
- function isBlockedPath(pathname) {
79
- return [...pathBlackListSet].some(path => (0, _runtime.matchPath)(pathname, {
80
- path
81
- }));
125
+ function getPathnameWithQuery(pathname, search) {
126
+ const flags = (0, _runtime.getRuntime)().getFeatureFlags();
127
+ const blackListPreserveQueryFlag = flags === null || flags === void 0 ? void 0 : flags["blacklist-preserve-query-string"];
128
+ return blackListPreserveQueryFlag && search ? pathname + search : pathname;
82
129
  }
83
130
 
84
131
  /**
85
132
  * 判断一个内部 URL 是否被屏蔽。
86
133
  */
87
134
  function isBlockedUrl(url) {
88
- const pathname = (typeof url === "string" ? (0, _history.createLocation)(url) : url).pathname;
135
+ const location = typeof url === "string" ? (0, _history.createLocation)(url) : url;
136
+ const pathname = location.pathname;
89
137
  if (typeof pathname !== "string") {
90
138
  return false;
91
139
  }
92
- return isBlockedPath(pathname);
140
+ const pathnameWithQuery = getPathnameWithQuery(pathname, location.search);
141
+ return isBlockedPath(pathnameWithQuery);
93
142
  }
94
143
 
95
144
  /**
@@ -103,6 +152,8 @@ function isBlockedHref(href) {
103
152
  return false;
104
153
  }
105
154
  // 转换为内部路径
106
- return isBlockedPath(url.pathname.substring(basePath.length - 1));
155
+ const internalPath = url.pathname.substring(basePath.length - 1);
156
+ const pathnameWithQuery = getPathnameWithQuery(internalPath, url.search);
157
+ return isBlockedPath(pathnameWithQuery);
107
158
  }
108
159
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","names":["_runtime","require","_history","_checkPermissions","auth","pathBlackListSet","Set","authenticate","newAuth","_newAuth$license","Object","assign","org","username","userInstanceId","loginFrom","accessRule","isAdmin","csrfToken","license","accessToken","userShowValue","blackList","getAuth","logout","key","keys","undefined","resetPermissionPreChecks","isLoggedIn","addPathToBlackList","path","add","isBlockedPath","pathname","some","matchPath","isBlockedUrl","url","createLocation","isBlockedHref","href","basePath","getBasePath","URL","location","origin","startsWith","substring","length"],"sources":["../../src/auth.ts"],"sourcesContent":["import { getBasePath, matchPath } from \"@next-core/runtime\";\nimport type { AuthApi_CheckLoginResponseBody } from \"@next-api-sdk/api-gateway-sdk\";\nimport { createLocation, type LocationDescriptor } from \"history\";\nimport { resetPermissionPreChecks } from \"./checkPermissions.js\";\n\nconst auth: AuthInfo = {};\nlet pathBlackListSet = new Set<string>();\n\n/** @internal */\nexport type AuthInfo = Omit<AuthApi_CheckLoginResponseBody, \"loggedIn\">;\n\n/** @internal */\nexport function authenticate(newAuth: AuthInfo): void {\n Object.assign(auth, {\n org: newAuth.org,\n username: newAuth.username,\n userInstanceId: newAuth.userInstanceId,\n loginFrom: newAuth.loginFrom,\n accessRule: newAuth.accessRule,\n isAdmin: newAuth.isAdmin,\n csrfToken: newAuth.csrfToken,\n license: newAuth.license,\n accessToken: newAuth.accessToken,\n userShowValue: newAuth.userShowValue,\n });\n\n pathBlackListSet = new Set(newAuth.license?.blackList);\n}\n\n/**\n * 获取当前登录认证信息。\n *\n * @returns 当前登录认证信息。\n */\nexport function getAuth(): AuthInfo {\n return {\n ...auth,\n };\n}\n\n/** @internal */\nexport function logout(): void {\n for (const key of Object.keys(auth) as (keyof AuthInfo)[]) {\n auth[key] = undefined;\n }\n resetPermissionPreChecks();\n}\n\n/**\n * 查看当前是否已登录。\n *\n * @returns 当前是否已登录。\n */\nexport function isLoggedIn(): boolean {\n return auth.username !== undefined;\n}\n\n/**\n * 增加路径黑名单\n */\nexport function addPathToBlackList(path: string): void {\n pathBlackListSet.add(path);\n}\n\n/**\n * 判断一个内部 URL 路径是否被屏蔽。\n */\nexport function isBlockedPath(pathname: string): boolean {\n return [...pathBlackListSet].some((path) => matchPath(pathname, { path }));\n}\n\n/**\n * 判断一个内部 URL 是否被屏蔽。\n */\nexport function isBlockedUrl(url: string | LocationDescriptor): boolean {\n const pathname = (typeof url === \"string\" ? createLocation(url) : url)\n .pathname;\n if (typeof pathname !== \"string\") {\n return false;\n }\n return isBlockedPath(pathname);\n}\n\n/**\n * 判断一个 href 是否被屏蔽。\n */\nexport function isBlockedHref(href: string): boolean {\n const basePath = getBasePath();\n const url = new URL(href, `${location.origin}${basePath}`);\n // 忽略外链地址\n if (url.origin !== location.origin || !url.pathname.startsWith(basePath)) {\n return false;\n }\n // 转换为内部路径\n return isBlockedPath(url.pathname.substring(basePath.length - 1));\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"auth.js","names":["_runtime","require","_history","_checkPermissions","auth","pathBlackListSet","Set","authenticate","newAuth","_newAuth$license","Object","assign","org","username","userInstanceId","loginFrom","accessRule","isAdmin","csrfToken","license","accessToken","userShowValue","blackList","getAuth","logout","key","keys","undefined","resetPermissionPreChecks","isLoggedIn","addPathToBlackList","path","add","isBlockedPath","pathnameWithQuery","some","pattern","patternPath","patternQuery","split","pathname","pathQuery","pathMatched","matchPath","patternParams","URLSearchParams","pathParams","value","entries","get","getPathnameWithQuery","search","flags","getRuntime","getFeatureFlags","blackListPreserveQueryFlag","isBlockedUrl","url","location","createLocation","isBlockedHref","href","basePath","getBasePath","URL","origin","startsWith","internalPath","substring","length"],"sources":["../../src/auth.ts"],"sourcesContent":["import { getBasePath, getRuntime, matchPath } from \"@next-core/runtime\";\nimport type { AuthApi_CheckLoginResponseBody } from \"@next-api-sdk/api-gateway-sdk\";\nimport { createLocation, type LocationDescriptor } from \"history\";\nimport { resetPermissionPreChecks } from \"./checkPermissions.js\";\n\nconst auth: AuthInfo = {};\nlet pathBlackListSet = new Set<string>();\n\n/** @internal */\nexport type AuthInfo = Omit<AuthApi_CheckLoginResponseBody, \"loggedIn\">;\n\n/** @internal */\nexport function authenticate(newAuth: AuthInfo): void {\n Object.assign(auth, {\n org: newAuth.org,\n username: newAuth.username,\n userInstanceId: newAuth.userInstanceId,\n loginFrom: newAuth.loginFrom,\n accessRule: newAuth.accessRule,\n isAdmin: newAuth.isAdmin,\n csrfToken: newAuth.csrfToken,\n license: newAuth.license,\n accessToken: newAuth.accessToken,\n userShowValue: newAuth.userShowValue,\n });\n\n pathBlackListSet = new Set(newAuth.license?.blackList);\n}\n\n/**\n * 获取当前登录认证信息。\n *\n * @returns 当前登录认证信息。\n */\nexport function getAuth(): AuthInfo {\n return {\n ...auth,\n };\n}\n\n/** @internal */\nexport function logout(): void {\n for (const key of Object.keys(auth) as (keyof AuthInfo)[]) {\n auth[key] = undefined;\n }\n resetPermissionPreChecks();\n}\n\n/**\n * 查看当前是否已登录。\n *\n * @returns 当前是否已登录。\n */\nexport function isLoggedIn(): boolean {\n return auth.username !== undefined;\n}\n\n/**\n * 增加路径黑名单\n */\nexport function addPathToBlackList(path: string): void {\n pathBlackListSet.add(path);\n}\n\n/**\n * 判断一个内部 URL 路径是否被屏蔽。\n *\n * @param pathnameWithQuery - 路径(可包含查询字符串)\n * @returns 是否被屏蔽\n */\nexport function isBlockedPath(pathnameWithQuery: string): boolean {\n return [...pathBlackListSet].some((pattern) => {\n // 分离 pattern 的路径和查询字符串\n const [patternPath, patternQuery] = pattern.split(\"?\");\n\n // 分离待检查路径的路径和查询字符串\n const [pathname, pathQuery] = pathnameWithQuery.split(\"?\");\n\n // 首先匹配路径部分\n const pathMatched = matchPath(pathname, { path: patternPath });\n if (!pathMatched) {\n return false;\n }\n\n // 如果 pattern 不包含查询字符串,只要路径匹配就返回 true\n if (!patternQuery) {\n return true;\n }\n\n // 如果 pattern 包含查询字符串,但待检查路径没有,返回 false\n if (!pathQuery) {\n return false;\n }\n\n // 精确匹配查询字符串(所有 pattern 中的参数必须存在且值相同)\n const patternParams = new URLSearchParams(patternQuery);\n const pathParams = new URLSearchParams(pathQuery);\n\n for (const [key, value] of patternParams.entries()) {\n if (pathParams.get(key) !== value) {\n return false;\n }\n }\n\n return true;\n });\n}\n\n/**\n * 根据特性开关决定是否拼接查询字符串\n * @param pathname - 路径名\n * @param search - 查询字符串(可选)\n * @returns 拼接后的路径\n */\nfunction getPathnameWithQuery(pathname: string, search?: string): string {\n const flags = getRuntime().getFeatureFlags();\n const blackListPreserveQueryFlag = flags?.[\"blacklist-preserve-query-string\"];\n return blackListPreserveQueryFlag && search ? pathname + search : pathname;\n}\n\n/**\n * 判断一个内部 URL 是否被屏蔽。\n */\nexport function isBlockedUrl(url: string | LocationDescriptor): boolean {\n const location = typeof url === \"string\" ? createLocation(url) : url;\n const pathname = location.pathname;\n if (typeof pathname !== \"string\") {\n return false;\n }\n const pathnameWithQuery = getPathnameWithQuery(pathname, location.search);\n return isBlockedPath(pathnameWithQuery);\n}\n\n/**\n * 判断一个 href 是否被屏蔽。\n */\nexport function isBlockedHref(href: string): boolean {\n const basePath = getBasePath();\n const url = new URL(href, `${location.origin}${basePath}`);\n // 忽略外链地址\n if (url.origin !== location.origin || !url.pathname.startsWith(basePath)) {\n return false;\n }\n // 转换为内部路径\n const internalPath = url.pathname.substring(basePath.length - 1);\n const pathnameWithQuery = getPathnameWithQuery(internalPath, url.search);\n return isBlockedPath(pathnameWithQuery);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -10,6 +10,7 @@ var _jsYaml = _interopRequireDefault(require("js-yaml"));
10
10
  var _nextBuilderSdk = require("@next-api-sdk/next-builder-sdk");
11
11
  var _general = require("@next-core/utils/general");
12
12
  var _CollectContracts = require("./CollectContracts.js");
13
+ var _runtime = require("@next-core/runtime");
13
14
  const remoteContractCache = new Map();
14
15
 
15
16
  // Legacy Custom API: `${namespace}@${name}`
@@ -202,6 +203,10 @@ async function fetchFlowApiDefinitionFromRemote(namespace, name, version) {
202
203
  });
203
204
  contractData = contractList[0];
204
205
  } catch (e) {
206
+ if ((0, _runtime.isUnauthenticatedError)(e)) {
207
+ // If unauthenticated, throw the error to be handled by upper level
208
+ throw e;
209
+ }
205
210
  error = e;
206
211
  }
207
212
  if (!contractData) {
@@ -1 +1 @@
1
- {"version":3,"file":"FlowApi.js","names":["_jsYaml","_interopRequireDefault","require","_nextBuilderSdk","_general","_CollectContracts","remoteContractCache","Map","isFlowApiProvider","provider","includes","getArgsOfFlowApi","originalArgs","method","stream","Error","apiDefinition","fetchFlowApiDefinition","FlowApiNotFoundError","apiProfile","getApiProfileFromApiDefinition","getApiArgsFromApiProfile","api","uri","apiMethod","ext_fields","responseWrapper","isFileType","request","isDownload","filename","fixedArgs","Array","isArray","slice","shift","url","args","getTransformedUriAndRestArgs","originalUri","name","namespace","serviceName","version","prefix","startsWith","transformedUri","restArgs","replace","restParams","params","_","key","hasOwnProperty","value","isSimpleRequest","toLowerCase","_uri$match","_request$fields","noParams","type","match","length","fields","push","bodyField","find","item","source","body","queryField","query","options","_contract$response","contract","yaml","safeLoad","schema","JSON_SCHEMA","json","endpoint","response","wrapper","namespaceName","nameWithVersion","split","getContract","namespaceId","promise","get","fetchFlowApiDefinitionFromRemote","set","contractData","fullContractName","error","list","contractList","ContractCenterApi_batchSearchContract","e","console","constructor","message","captureStackTrace"],"sources":["../../../src/flowApi/FlowApi.ts"],"sourcesContent":["import yaml from \"js-yaml\";\nimport {\n ContractCenterApi_batchSearchContract,\n type ContractCenterApi_BatchSearchContractResponseBody_list_item,\n} from \"@next-api-sdk/next-builder-sdk\";\nimport type {\n ContractResponse,\n ExtField,\n ContractRequest,\n UseProviderContractConf,\n} from \"@next-core/types\";\nimport { hasOwnProperty } from \"@next-core/utils/general\";\nimport { getContract } from \"./CollectContracts.js\";\n\nexport type MinimalContractRequest = Pick<ContractRequest, \"type\"> & {\n fields?: MinimalContractField[];\n};\nexport type MinimalContractField =\n | {\n type: string;\n fields?: MinimalContractField[];\n }\n | {\n ref: string;\n };\nexport type MinimalContractResponse = Pick<\n ContractResponse,\n \"type\" | \"wrapper\"\n>;\n\nconst remoteContractCache = new Map<\n string,\n Promise<CustomApiDefinition | null>\n>();\n\n// Legacy Custom API: `${namespace}@${name}`\n// Flow API: `${namespace}@${name}:${version}`\nexport function isFlowApiProvider(provider: string): boolean {\n return provider.includes(\"@\");\n}\n\nexport async function getArgsOfFlowApi(\n provider: string,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): Promise<unknown[]> {\n if (!provider.includes(\":\")) {\n throw new Error(\n `You're using legacy Custom API \"${provider}\" which is dropped in v3, please use Flow API instead`\n );\n }\n\n const apiDefinition = await fetchFlowApiDefinition(provider);\n\n if (!apiDefinition) {\n throw new FlowApiNotFoundError(`Flow API not found: \"${provider}\"`);\n }\n\n const apiProfile = getApiProfileFromApiDefinition(provider, apiDefinition);\n\n return getApiArgsFromApiProfile(apiProfile, originalArgs, method, stream);\n}\n\nfunction getApiArgsFromApiProfile(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): unknown[] {\n const {\n uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n isFileType,\n request,\n } = api;\n // `saveAs` requires the first argument to be the filename.\n const isDownload = method === \"saveAs\";\n let filename: string | undefined;\n let fixedArgs = originalArgs;\n if (isDownload) {\n if (Array.isArray(originalArgs)) {\n fixedArgs = originalArgs.slice();\n filename = fixedArgs.shift() as string;\n } else {\n filename = originalArgs.filename;\n }\n }\n\n const { url, args } = getTransformedUriAndRestArgs(api, fixedArgs);\n\n return [\n ...(isDownload ? [filename] : []),\n {\n url,\n originalUri: uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n request,\n isFileType,\n stream,\n },\n ...args,\n ];\n}\n\nfunction getTransformedUriAndRestArgs(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf\n): { url: string; args: unknown[] } {\n const {\n uri,\n name,\n namespace,\n serviceName,\n version,\n method = \"GET\",\n request,\n ext_fields,\n } = api;\n\n const prefix = version\n ? serviceName === \"logic.api.gateway\" ||\n serviceName?.startsWith(\"logic.api.gateway.\")\n ? \"\"\n : serviceName\n ? `api/gateway/${serviceName}`\n : `api/gateway/${namespace}.${name}@${version}`\n : `api/gateway/api_service.${namespace}.${name}`;\n\n let transformedUri: string;\n let restArgs: unknown[] = [];\n if (Array.isArray(originalArgs)) {\n restArgs = originalArgs.slice();\n transformedUri = uri.replace(/:([^/]+)/g, () => restArgs.shift() as string);\n } else {\n const restParams = { ...originalArgs.params };\n transformedUri = uri.replace(/:([^/]+)/g, (_, key) => {\n if (hasOwnProperty(restParams, key)) {\n const value = restParams[key] as string;\n delete restParams[key];\n return value;\n }\n throw new Error(`Missing required param: \"${key}\"`);\n });\n\n const isSimpleRequest = [\"get\", \"delete\", \"head\"].includes(\n method.toLowerCase()\n );\n if (isSimpleRequest) {\n const noParams =\n request?.type === \"object\" &&\n (uri.match(/:([^/]+)/g)?.length ?? 0) === (request.fields?.length ?? 0);\n if (!noParams) {\n restArgs.push(restParams);\n }\n } else {\n const bodyField = ext_fields?.find((item) => item.source === \"body\");\n if (bodyField) {\n let body: Record<string, unknown> | undefined;\n if (bodyField.name && hasOwnProperty(restParams, bodyField.name)) {\n body = restParams[bodyField.name] as Record<string, unknown>;\n delete restParams[bodyField.name];\n }\n restArgs.push(body);\n }\n\n const queryField = ext_fields?.find((item) => item.source === \"query\");\n if (queryField) {\n let query: Record<string, unknown> | undefined;\n if (queryField.name && hasOwnProperty(restParams, queryField.name)) {\n query = restParams[queryField.name] as Record<string, unknown>;\n delete restParams[queryField.name];\n }\n\n restArgs.push(query);\n }\n\n if (!bodyField && !queryField) {\n restArgs.push(restParams);\n }\n }\n\n if (originalArgs.options) {\n restArgs.push(originalArgs.options);\n }\n }\n return {\n url: prefix ? prefix + transformedUri : transformedUri.replace(/^\\//, \"\"),\n args: restArgs,\n };\n}\n\nfunction getApiProfileFromApiDefinition(\n provider: string,\n api: CustomApiDefinition\n): CustomApiProfile {\n const contract: CustomApiDefinition[\"contract\"] =\n typeof api.contract === \"string\"\n ? (yaml.safeLoad(api.contract, {\n schema: yaml.JSON_SCHEMA,\n json: true,\n }) as CustomApiDefinition[\"contract\"])\n : api.contract;\n const { uri, method = \"GET\", ext_fields } = contract?.endpoint ?? {};\n const responseWrapper = contract?.response\n ? contract.response.wrapper !== false\n : false;\n if (!uri) {\n throw new Error(\n `Missing endpoint.uri in contract of provider \"${provider}\"`\n );\n }\n return {\n uri,\n method: method.toLowerCase() === \"list\" ? \"get\" : method,\n ext_fields,\n name: api.name,\n namespace: api.namespace,\n serviceName: api.serviceName,\n version: api.version,\n isFileType: contract?.response?.type === \"file\",\n responseWrapper,\n request: contract?.request,\n };\n}\n\nasync function fetchFlowApiDefinition(\n provider: string\n): Promise<CustomApiDefinition | null> {\n const [namespaceName, nameWithVersion] = provider.split(\"@\");\n const [name, version] = nameWithVersion.split(\":\");\n\n // Do not cache the result of `getContract`, which will lead to no contract\n // will be found when render twice immediately.\n const contract = getContract(`${namespaceName}.${name}`);\n if (contract) {\n return {\n name: contract.name,\n namespace: contract.namespaceId,\n serviceName: contract.serviceName,\n version: contract.version,\n contract: {\n endpoint: contract.endpoint,\n response: contract.response,\n request: contract.request,\n },\n };\n }\n let promise = remoteContractCache.get(provider);\n if (!promise) {\n promise = fetchFlowApiDefinitionFromRemote(namespaceName, name, version);\n remoteContractCache.set(provider, promise);\n }\n return promise;\n}\n\nasync function fetchFlowApiDefinitionFromRemote(\n namespace: string,\n name: string,\n version: string\n): Promise<CustomApiDefinition | null> {\n let contractData:\n | ContractCenterApi_BatchSearchContractResponseBody_list_item\n | undefined;\n const fullContractName = `${namespace}@${name}`;\n let error: unknown;\n\n try {\n const { list: contractList } = await ContractCenterApi_batchSearchContract({\n contract: [\n {\n fullContractName,\n version,\n },\n ],\n });\n contractData = contractList![0];\n } catch (e) {\n error = e;\n }\n\n if (!contractData) {\n // eslint-disable-next-line no-console\n console.error(\n `Failed to fetch Flow API definition for \"${fullContractName}:${version}\"`,\n error ?? \"Contract not found\"\n );\n return null;\n }\n\n return {\n name: contractData.name,\n namespace: contractData.namespaceId,\n serviceName: contractData.serviceName,\n version: contractData.version,\n contract: {\n endpoint: contractData.endpoint,\n response: contractData.response,\n request: contractData.request,\n },\n } as CustomApiDefinition;\n}\n\nexport interface CustomApiDefinition {\n name: string;\n namespace: string;\n version?: string;\n serviceName?: string;\n contract?: {\n endpoint: {\n ext_fields?: ExtField[];\n uri: string;\n method:\n | \"POST\"\n | \"post\"\n | \"PUT\"\n | \"put\"\n | \"GET\"\n | \"get\"\n | \"DELETE\"\n | \"delete\"\n | \"LIST\"\n | \"list\"\n | \"PATCH\"\n | \"patch\"\n | \"HEAD\"\n | \"head\";\n };\n request?: MinimalContractRequest;\n response?: MinimalContractResponse;\n };\n}\n\nexport interface CustomApiProfile {\n uri: string;\n method: string;\n name: string;\n namespace: string;\n serviceName?: string;\n responseWrapper: boolean;\n version?: string;\n isFileType?: boolean;\n ext_fields?: ExtField[];\n request?: MinimalContractRequest;\n}\n\nclass FlowApiNotFoundError extends Error {\n constructor(message: string) {\n // Pass remaining arguments (including vendor specific ones) to parent constructor\n super(message);\n\n this.name = \"FlowApiNotFoundError\";\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n // istanbul ignore else\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FlowApiNotFoundError);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FlowApi.js","names":["_jsYaml","_interopRequireDefault","require","_nextBuilderSdk","_general","_CollectContracts","_runtime","remoteContractCache","Map","isFlowApiProvider","provider","includes","getArgsOfFlowApi","originalArgs","method","stream","Error","apiDefinition","fetchFlowApiDefinition","FlowApiNotFoundError","apiProfile","getApiProfileFromApiDefinition","getApiArgsFromApiProfile","api","uri","apiMethod","ext_fields","responseWrapper","isFileType","request","isDownload","filename","fixedArgs","Array","isArray","slice","shift","url","args","getTransformedUriAndRestArgs","originalUri","name","namespace","serviceName","version","prefix","startsWith","transformedUri","restArgs","replace","restParams","params","_","key","hasOwnProperty","value","isSimpleRequest","toLowerCase","_uri$match","_request$fields","noParams","type","match","length","fields","push","bodyField","find","item","source","body","queryField","query","options","_contract$response","contract","yaml","safeLoad","schema","JSON_SCHEMA","json","endpoint","response","wrapper","namespaceName","nameWithVersion","split","getContract","namespaceId","promise","get","fetchFlowApiDefinitionFromRemote","set","contractData","fullContractName","error","list","contractList","ContractCenterApi_batchSearchContract","e","isUnauthenticatedError","console","constructor","message","captureStackTrace"],"sources":["../../../src/flowApi/FlowApi.ts"],"sourcesContent":["import yaml from \"js-yaml\";\nimport {\n ContractCenterApi_batchSearchContract,\n type ContractCenterApi_BatchSearchContractResponseBody_list_item,\n} from \"@next-api-sdk/next-builder-sdk\";\nimport type {\n ContractResponse,\n ExtField,\n ContractRequest,\n UseProviderContractConf,\n} from \"@next-core/types\";\nimport { hasOwnProperty } from \"@next-core/utils/general\";\nimport { getContract } from \"./CollectContracts.js\";\nimport { isUnauthenticatedError } from \"@next-core/runtime\";\n\nexport type MinimalContractRequest = Pick<ContractRequest, \"type\"> & {\n fields?: MinimalContractField[];\n};\nexport type MinimalContractField =\n | {\n type: string;\n fields?: MinimalContractField[];\n }\n | {\n ref: string;\n };\nexport type MinimalContractResponse = Pick<\n ContractResponse,\n \"type\" | \"wrapper\"\n>;\n\nconst remoteContractCache = new Map<\n string,\n Promise<CustomApiDefinition | null>\n>();\n\n// Legacy Custom API: `${namespace}@${name}`\n// Flow API: `${namespace}@${name}:${version}`\nexport function isFlowApiProvider(provider: string): boolean {\n return provider.includes(\"@\");\n}\n\nexport async function getArgsOfFlowApi(\n provider: string,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): Promise<unknown[]> {\n if (!provider.includes(\":\")) {\n throw new Error(\n `You're using legacy Custom API \"${provider}\" which is dropped in v3, please use Flow API instead`\n );\n }\n\n const apiDefinition = await fetchFlowApiDefinition(provider);\n\n if (!apiDefinition) {\n throw new FlowApiNotFoundError(`Flow API not found: \"${provider}\"`);\n }\n\n const apiProfile = getApiProfileFromApiDefinition(provider, apiDefinition);\n\n return getApiArgsFromApiProfile(apiProfile, originalArgs, method, stream);\n}\n\nfunction getApiArgsFromApiProfile(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): unknown[] {\n const {\n uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n isFileType,\n request,\n } = api;\n // `saveAs` requires the first argument to be the filename.\n const isDownload = method === \"saveAs\";\n let filename: string | undefined;\n let fixedArgs = originalArgs;\n if (isDownload) {\n if (Array.isArray(originalArgs)) {\n fixedArgs = originalArgs.slice();\n filename = fixedArgs.shift() as string;\n } else {\n filename = originalArgs.filename;\n }\n }\n\n const { url, args } = getTransformedUriAndRestArgs(api, fixedArgs);\n\n return [\n ...(isDownload ? [filename] : []),\n {\n url,\n originalUri: uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n request,\n isFileType,\n stream,\n },\n ...args,\n ];\n}\n\nfunction getTransformedUriAndRestArgs(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf\n): { url: string; args: unknown[] } {\n const {\n uri,\n name,\n namespace,\n serviceName,\n version,\n method = \"GET\",\n request,\n ext_fields,\n } = api;\n\n const prefix = version\n ? serviceName === \"logic.api.gateway\" ||\n serviceName?.startsWith(\"logic.api.gateway.\")\n ? \"\"\n : serviceName\n ? `api/gateway/${serviceName}`\n : `api/gateway/${namespace}.${name}@${version}`\n : `api/gateway/api_service.${namespace}.${name}`;\n\n let transformedUri: string;\n let restArgs: unknown[] = [];\n if (Array.isArray(originalArgs)) {\n restArgs = originalArgs.slice();\n transformedUri = uri.replace(/:([^/]+)/g, () => restArgs.shift() as string);\n } else {\n const restParams = { ...originalArgs.params };\n transformedUri = uri.replace(/:([^/]+)/g, (_, key) => {\n if (hasOwnProperty(restParams, key)) {\n const value = restParams[key] as string;\n delete restParams[key];\n return value;\n }\n throw new Error(`Missing required param: \"${key}\"`);\n });\n\n const isSimpleRequest = [\"get\", \"delete\", \"head\"].includes(\n method.toLowerCase()\n );\n if (isSimpleRequest) {\n const noParams =\n request?.type === \"object\" &&\n (uri.match(/:([^/]+)/g)?.length ?? 0) === (request.fields?.length ?? 0);\n if (!noParams) {\n restArgs.push(restParams);\n }\n } else {\n const bodyField = ext_fields?.find((item) => item.source === \"body\");\n if (bodyField) {\n let body: Record<string, unknown> | undefined;\n if (bodyField.name && hasOwnProperty(restParams, bodyField.name)) {\n body = restParams[bodyField.name] as Record<string, unknown>;\n delete restParams[bodyField.name];\n }\n restArgs.push(body);\n }\n\n const queryField = ext_fields?.find((item) => item.source === \"query\");\n if (queryField) {\n let query: Record<string, unknown> | undefined;\n if (queryField.name && hasOwnProperty(restParams, queryField.name)) {\n query = restParams[queryField.name] as Record<string, unknown>;\n delete restParams[queryField.name];\n }\n\n restArgs.push(query);\n }\n\n if (!bodyField && !queryField) {\n restArgs.push(restParams);\n }\n }\n\n if (originalArgs.options) {\n restArgs.push(originalArgs.options);\n }\n }\n return {\n url: prefix ? prefix + transformedUri : transformedUri.replace(/^\\//, \"\"),\n args: restArgs,\n };\n}\n\nfunction getApiProfileFromApiDefinition(\n provider: string,\n api: CustomApiDefinition\n): CustomApiProfile {\n const contract: CustomApiDefinition[\"contract\"] =\n typeof api.contract === \"string\"\n ? (yaml.safeLoad(api.contract, {\n schema: yaml.JSON_SCHEMA,\n json: true,\n }) as CustomApiDefinition[\"contract\"])\n : api.contract;\n const { uri, method = \"GET\", ext_fields } = contract?.endpoint ?? {};\n const responseWrapper = contract?.response\n ? contract.response.wrapper !== false\n : false;\n if (!uri) {\n throw new Error(\n `Missing endpoint.uri in contract of provider \"${provider}\"`\n );\n }\n return {\n uri,\n method: method.toLowerCase() === \"list\" ? \"get\" : method,\n ext_fields,\n name: api.name,\n namespace: api.namespace,\n serviceName: api.serviceName,\n version: api.version,\n isFileType: contract?.response?.type === \"file\",\n responseWrapper,\n request: contract?.request,\n };\n}\n\nasync function fetchFlowApiDefinition(\n provider: string\n): Promise<CustomApiDefinition | null> {\n const [namespaceName, nameWithVersion] = provider.split(\"@\");\n const [name, version] = nameWithVersion.split(\":\");\n\n // Do not cache the result of `getContract`, which will lead to no contract\n // will be found when render twice immediately.\n const contract = getContract(`${namespaceName}.${name}`);\n if (contract) {\n return {\n name: contract.name,\n namespace: contract.namespaceId,\n serviceName: contract.serviceName,\n version: contract.version,\n contract: {\n endpoint: contract.endpoint,\n response: contract.response,\n request: contract.request,\n },\n };\n }\n let promise = remoteContractCache.get(provider);\n if (!promise) {\n promise = fetchFlowApiDefinitionFromRemote(namespaceName, name, version);\n remoteContractCache.set(provider, promise);\n }\n return promise;\n}\n\nasync function fetchFlowApiDefinitionFromRemote(\n namespace: string,\n name: string,\n version: string\n): Promise<CustomApiDefinition | null> {\n let contractData:\n | ContractCenterApi_BatchSearchContractResponseBody_list_item\n | undefined;\n const fullContractName = `${namespace}@${name}`;\n let error: unknown;\n\n try {\n const { list: contractList } = await ContractCenterApi_batchSearchContract({\n contract: [\n {\n fullContractName,\n version,\n },\n ],\n });\n contractData = contractList![0];\n } catch (e) {\n if (isUnauthenticatedError(e)) {\n // If unauthenticated, throw the error to be handled by upper level\n throw e;\n }\n error = e;\n }\n\n if (!contractData) {\n // eslint-disable-next-line no-console\n console.error(\n `Failed to fetch Flow API definition for \"${fullContractName}:${version}\"`,\n error ?? \"Contract not found\"\n );\n return null;\n }\n\n return {\n name: contractData.name,\n namespace: contractData.namespaceId,\n serviceName: contractData.serviceName,\n version: contractData.version,\n contract: {\n endpoint: contractData.endpoint,\n response: contractData.response,\n request: contractData.request,\n },\n } as CustomApiDefinition;\n}\n\nexport interface CustomApiDefinition {\n name: string;\n namespace: string;\n version?: string;\n serviceName?: string;\n contract?: {\n endpoint: {\n ext_fields?: ExtField[];\n uri: string;\n method:\n | \"POST\"\n | \"post\"\n | \"PUT\"\n | \"put\"\n | \"GET\"\n | \"get\"\n | \"DELETE\"\n | \"delete\"\n | \"LIST\"\n | \"list\"\n | \"PATCH\"\n | \"patch\"\n | \"HEAD\"\n | \"head\";\n };\n request?: MinimalContractRequest;\n response?: MinimalContractResponse;\n };\n}\n\nexport interface CustomApiProfile {\n uri: string;\n method: string;\n name: string;\n namespace: string;\n serviceName?: string;\n responseWrapper: boolean;\n version?: string;\n isFileType?: boolean;\n ext_fields?: ExtField[];\n request?: MinimalContractRequest;\n}\n\nclass FlowApiNotFoundError extends Error {\n constructor(message: string) {\n // Pass remaining arguments (including vendor specific ones) to parent constructor\n super(message);\n\n this.name = \"FlowApiNotFoundError\";\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n // istanbul ignore else\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FlowApiNotFoundError);\n }\n }\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AAUA,IAAAE,QAAA,GAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AACA,IAAAI,QAAA,GAAAJ,OAAA;AAkBA,MAAMK,mBAAmB,GAAG,IAAIC,GAAG,CAGjC,CAAC;;AAEH;AACA;AACO,SAASC,iBAAiBA,CAACC,QAAgB,EAAW;EAC3D,OAAOA,QAAQ,CAACC,QAAQ,CAAC,GAAG,CAAC;AAC/B;AAEO,eAAeC,gBAAgBA,CACpCF,QAAgB,EAChBG,YAAiD,EACjDC,MAAe,EACfC,MAAgB,EACI;EACpB,IAAI,CAACL,QAAQ,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC3B,MAAM,IAAIK,KAAK,CACb,mCAAmCN,QAAQ,uDAC7C,CAAC;EACH;EAEA,MAAMO,aAAa,GAAG,MAAMC,sBAAsB,CAACR,QAAQ,CAAC;EAE5D,IAAI,CAACO,aAAa,EAAE;IAClB,MAAM,IAAIE,oBAAoB,CAAC,wBAAwBT,QAAQ,GAAG,CAAC;EACrE;EAEA,MAAMU,UAAU,GAAGC,8BAA8B,CAACX,QAAQ,EAAEO,aAAa,CAAC;EAE1E,OAAOK,wBAAwB,CAACF,UAAU,EAAEP,YAAY,EAAEC,MAAM,EAAEC,MAAM,CAAC;AAC3E;AAEA,SAASO,wBAAwBA,CAC/BC,GAAqB,EACrBV,YAAiD,EACjDC,MAAe,EACfC,MAAgB,EACL;EACX,MAAM;IACJS,GAAG;IACHV,MAAM,EAAEW,SAAS;IACjBC,UAAU;IACVC,eAAe;IACfC,UAAU;IACVC;EACF,CAAC,GAAGN,GAAG;EACP;EACA,MAAMO,UAAU,GAAGhB,MAAM,KAAK,QAAQ;EACtC,IAAIiB,QAA4B;EAChC,IAAIC,SAAS,GAAGnB,YAAY;EAC5B,IAAIiB,UAAU,EAAE;IACd,IAAIG,KAAK,CAACC,OAAO,CAACrB,YAAY,CAAC,EAAE;MAC/BmB,SAAS,GAAGnB,YAAY,CAACsB,KAAK,CAAC,CAAC;MAChCJ,QAAQ,GAAGC,SAAS,CAACI,KAAK,CAAC,CAAW;IACxC,CAAC,MAAM;MACLL,QAAQ,GAAGlB,YAAY,CAACkB,QAAQ;IAClC;EACF;EAEA,MAAM;IAAEM,GAAG;IAAEC;EAAK,CAAC,GAAGC,4BAA4B,CAAChB,GAAG,EAAES,SAAS,CAAC;EAElE,OAAO,CACL,IAAIF,UAAU,GAAG,CAACC,QAAQ,CAAC,GAAG,EAAE,CAAC,EACjC;IACEM,GAAG;IACHG,WAAW,EAAEhB,GAAG;IAChBV,MAAM,EAAEW,SAAS;IACjBC,UAAU;IACVC,eAAe;IACfE,OAAO;IACPD,UAAU;IACVb;EACF,CAAC,EACD,GAAGuB,IAAI,CACR;AACH;AAEA,SAASC,4BAA4BA,CACnChB,GAAqB,EACrBV,YAAiD,EACf;EAClC,MAAM;IACJW,GAAG;IACHiB,IAAI;IACJC,SAAS;IACTC,WAAW;IACXC,OAAO;IACP9B,MAAM,GAAG,KAAK;IACde,OAAO;IACPH;EACF,CAAC,GAAGH,GAAG;EAEP,MAAMsB,MAAM,GAAGD,OAAO,GAClBD,WAAW,KAAK,mBAAmB,IACnCA,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEG,UAAU,CAAC,oBAAoB,CAAC,GAC3C,EAAE,GACFH,WAAW,GACT,eAAeA,WAAW,EAAE,GAC5B,eAAeD,SAAS,IAAID,IAAI,IAAIG,OAAO,EAAE,GACjD,2BAA2BF,SAAS,IAAID,IAAI,EAAE;EAElD,IAAIM,cAAsB;EAC1B,IAAIC,QAAmB,GAAG,EAAE;EAC5B,IAAIf,KAAK,CAACC,OAAO,CAACrB,YAAY,CAAC,EAAE;IAC/BmC,QAAQ,GAAGnC,YAAY,CAACsB,KAAK,CAAC,CAAC;IAC/BY,cAAc,GAAGvB,GAAG,CAACyB,OAAO,CAAC,WAAW,EAAE,MAAMD,QAAQ,CAACZ,KAAK,CAAC,CAAW,CAAC;EAC7E,CAAC,MAAM;IACL,MAAMc,UAAU,GAAG;MAAE,GAAGrC,YAAY,CAACsC;IAAO,CAAC;IAC7CJ,cAAc,GAAGvB,GAAG,CAACyB,OAAO,CAAC,WAAW,EAAE,CAACG,CAAC,EAAEC,GAAG,KAAK;MACpD,IAAI,IAAAC,uBAAc,EAACJ,UAAU,EAAEG,GAAG,CAAC,EAAE;QACnC,MAAME,KAAK,GAAGL,UAAU,CAACG,GAAG,CAAW;QACvC,OAAOH,UAAU,CAACG,GAAG,CAAC;QACtB,OAAOE,KAAK;MACd;MACA,MAAM,IAAIvC,KAAK,CAAC,4BAA4BqC,GAAG,GAAG,CAAC;IACrD,CAAC,CAAC;IAEF,MAAMG,eAAe,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC7C,QAAQ,CACxDG,MAAM,CAAC2C,WAAW,CAAC,CACrB,CAAC;IACD,IAAID,eAAe,EAAE;MAAA,IAAAE,UAAA,EAAAC,eAAA;MACnB,MAAMC,QAAQ,GACZ,CAAA/B,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEgC,IAAI,MAAK,QAAQ,IAC1B,CAAC,EAAAH,UAAA,GAAAlC,GAAG,CAACsC,KAAK,CAAC,WAAW,CAAC,cAAAJ,UAAA,uBAAtBA,UAAA,CAAwBK,MAAM,KAAI,CAAC,OAAO,EAAAJ,eAAA,GAAA9B,OAAO,CAACmC,MAAM,cAAAL,eAAA,uBAAdA,eAAA,CAAgBI,MAAM,KAAI,CAAC,CAAC;MACzE,IAAI,CAACH,QAAQ,EAAE;QACbZ,QAAQ,CAACiB,IAAI,CAACf,UAAU,CAAC;MAC3B;IACF,CAAC,MAAM;MACL,MAAMgB,SAAS,GAAGxC,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAEyC,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACC,MAAM,KAAK,MAAM,CAAC;MACpE,IAAIH,SAAS,EAAE;QACb,IAAII,IAAyC;QAC7C,IAAIJ,SAAS,CAACzB,IAAI,IAAI,IAAAa,uBAAc,EAACJ,UAAU,EAAEgB,SAAS,CAACzB,IAAI,CAAC,EAAE;UAChE6B,IAAI,GAAGpB,UAAU,CAACgB,SAAS,CAACzB,IAAI,CAA4B;UAC5D,OAAOS,UAAU,CAACgB,SAAS,CAACzB,IAAI,CAAC;QACnC;QACAO,QAAQ,CAACiB,IAAI,CAACK,IAAI,CAAC;MACrB;MAEA,MAAMC,UAAU,GAAG7C,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAEyC,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACC,MAAM,KAAK,OAAO,CAAC;MACtE,IAAIE,UAAU,EAAE;QACd,IAAIC,KAA0C;QAC9C,IAAID,UAAU,CAAC9B,IAAI,IAAI,IAAAa,uBAAc,EAACJ,UAAU,EAAEqB,UAAU,CAAC9B,IAAI,CAAC,EAAE;UAClE+B,KAAK,GAAGtB,UAAU,CAACqB,UAAU,CAAC9B,IAAI,CAA4B;UAC9D,OAAOS,UAAU,CAACqB,UAAU,CAAC9B,IAAI,CAAC;QACpC;QAEAO,QAAQ,CAACiB,IAAI,CAACO,KAAK,CAAC;MACtB;MAEA,IAAI,CAACN,SAAS,IAAI,CAACK,UAAU,EAAE;QAC7BvB,QAAQ,CAACiB,IAAI,CAACf,UAAU,CAAC;MAC3B;IACF;IAEA,IAAIrC,YAAY,CAAC4D,OAAO,EAAE;MACxBzB,QAAQ,CAACiB,IAAI,CAACpD,YAAY,CAAC4D,OAAO,CAAC;IACrC;EACF;EACA,OAAO;IACLpC,GAAG,EAAEQ,MAAM,GAAGA,MAAM,GAAGE,cAAc,GAAGA,cAAc,CAACE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IACzEX,IAAI,EAAEU;EACR,CAAC;AACH;AAEA,SAAS3B,8BAA8BA,CACrCX,QAAgB,EAChBa,GAAwB,EACN;EAAA,IAAAmD,kBAAA;EAClB,MAAMC,QAAyC,GAC7C,OAAOpD,GAAG,CAACoD,QAAQ,KAAK,QAAQ,GAC3BC,eAAI,CAACC,QAAQ,CAACtD,GAAG,CAACoD,QAAQ,EAAE;IAC3BG,MAAM,EAAEF,eAAI,CAACG,WAAW;IACxBC,IAAI,EAAE;EACR,CAAC,CAAC,GACFzD,GAAG,CAACoD,QAAQ;EAClB,MAAM;IAAEnD,GAAG;IAAEV,MAAM,GAAG,KAAK;IAAEY;EAAW,CAAC,GAAG,CAAAiD,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAEM,QAAQ,KAAI,CAAC,CAAC;EACpE,MAAMtD,eAAe,GAAGgD,QAAQ,aAARA,QAAQ,eAARA,QAAQ,CAAEO,QAAQ,GACtCP,QAAQ,CAACO,QAAQ,CAACC,OAAO,KAAK,KAAK,GACnC,KAAK;EACT,IAAI,CAAC3D,GAAG,EAAE;IACR,MAAM,IAAIR,KAAK,CACb,iDAAiDN,QAAQ,GAC3D,CAAC;EACH;EACA,OAAO;IACLc,GAAG;IACHV,MAAM,EAAEA,MAAM,CAAC2C,WAAW,CAAC,CAAC,KAAK,MAAM,GAAG,KAAK,GAAG3C,MAAM;IACxDY,UAAU;IACVe,IAAI,EAAElB,GAAG,CAACkB,IAAI;IACdC,SAAS,EAAEnB,GAAG,CAACmB,SAAS;IACxBC,WAAW,EAAEpB,GAAG,CAACoB,WAAW;IAC5BC,OAAO,EAAErB,GAAG,CAACqB,OAAO;IACpBhB,UAAU,EAAE,CAAA+C,QAAQ,aAARA,QAAQ,gBAAAD,kBAAA,GAARC,QAAQ,CAAEO,QAAQ,cAAAR,kBAAA,uBAAlBA,kBAAA,CAAoBb,IAAI,MAAK,MAAM;IAC/ClC,eAAe;IACfE,OAAO,EAAE8C,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAE9C;EACrB,CAAC;AACH;AAEA,eAAeX,sBAAsBA,CACnCR,QAAgB,EACqB;EACrC,MAAM,CAAC0E,aAAa,EAAEC,eAAe,CAAC,GAAG3E,QAAQ,CAAC4E,KAAK,CAAC,GAAG,CAAC;EAC5D,MAAM,CAAC7C,IAAI,EAAEG,OAAO,CAAC,GAAGyC,eAAe,CAACC,KAAK,CAAC,GAAG,CAAC;;EAElD;EACA;EACA,MAAMX,QAAQ,GAAG,IAAAY,6BAAW,EAAC,GAAGH,aAAa,IAAI3C,IAAI,EAAE,CAAC;EACxD,IAAIkC,QAAQ,EAAE;IACZ,OAAO;MACLlC,IAAI,EAAEkC,QAAQ,CAAClC,IAAI;MACnBC,SAAS,EAAEiC,QAAQ,CAACa,WAAW;MAC/B7C,WAAW,EAAEgC,QAAQ,CAAChC,WAAW;MACjCC,OAAO,EAAE+B,QAAQ,CAAC/B,OAAO;MACzB+B,QAAQ,EAAE;QACRM,QAAQ,EAAEN,QAAQ,CAACM,QAAQ;QAC3BC,QAAQ,EAAEP,QAAQ,CAACO,QAAQ;QAC3BrD,OAAO,EAAE8C,QAAQ,CAAC9C;MACpB;IACF,CAAC;EACH;EACA,IAAI4D,OAAO,GAAGlF,mBAAmB,CAACmF,GAAG,CAAChF,QAAQ,CAAC;EAC/C,IAAI,CAAC+E,OAAO,EAAE;IACZA,OAAO,GAAGE,gCAAgC,CAACP,aAAa,EAAE3C,IAAI,EAAEG,OAAO,CAAC;IACxErC,mBAAmB,CAACqF,GAAG,CAAClF,QAAQ,EAAE+E,OAAO,CAAC;EAC5C;EACA,OAAOA,OAAO;AAChB;AAEA,eAAeE,gCAAgCA,CAC7CjD,SAAiB,EACjBD,IAAY,EACZG,OAAe,EACsB;EACrC,IAAIiD,YAES;EACb,MAAMC,gBAAgB,GAAG,GAAGpD,SAAS,IAAID,IAAI,EAAE;EAC/C,IAAIsD,KAAc;EAElB,IAAI;IACF,MAAM;MAAEC,IAAI,EAAEC;IAAa,CAAC,GAAG,MAAM,IAAAC,qDAAqC,EAAC;MACzEvB,QAAQ,EAAE,CACR;QACEmB,gBAAgB;QAChBlD;MACF,CAAC;IAEL,CAAC,CAAC;IACFiD,YAAY,GAAGI,YAAY,CAAE,CAAC,CAAC;EACjC,CAAC,CAAC,OAAOE,CAAC,EAAE;IACV,IAAI,IAAAC,+BAAsB,EAACD,CAAC,CAAC,EAAE;MAC7B;MACA,MAAMA,CAAC;IACT;IACAJ,KAAK,GAAGI,CAAC;EACX;EAEA,IAAI,CAACN,YAAY,EAAE;IACjB;IACAQ,OAAO,CAACN,KAAK,CACX,4CAA4CD,gBAAgB,IAAIlD,OAAO,GAAG,EAC1EmD,KAAK,IAAI,oBACX,CAAC;IACD,OAAO,IAAI;EACb;EAEA,OAAO;IACLtD,IAAI,EAAEoD,YAAY,CAACpD,IAAI;IACvBC,SAAS,EAAEmD,YAAY,CAACL,WAAW;IACnC7C,WAAW,EAAEkD,YAAY,CAAClD,WAAW;IACrCC,OAAO,EAAEiD,YAAY,CAACjD,OAAO;IAC7B+B,QAAQ,EAAE;MACRM,QAAQ,EAAEY,YAAY,CAACZ,QAAQ;MAC/BC,QAAQ,EAAEW,YAAY,CAACX,QAAQ;MAC/BrD,OAAO,EAAEgE,YAAY,CAAChE;IACxB;EACF,CAAC;AACH;AA6CA,MAAMV,oBAAoB,SAASH,KAAK,CAAC;EACvCsF,WAAWA,CAACC,OAAe,EAAE;IAC3B;IACA,KAAK,CAACA,OAAO,CAAC;IAEd,IAAI,CAAC9D,IAAI,GAAG,sBAAsB;;IAElC;IACA;IACA,IAAIzB,KAAK,CAACwF,iBAAiB,EAAE;MAC3BxF,KAAK,CAACwF,iBAAiB,CAAC,IAAI,EAAErF,oBAAoB,CAAC;IACrD;EACF;AACF","ignoreList":[]}
package/dist/esm/auth.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getBasePath, matchPath } from "@next-core/runtime";
1
+ import { getBasePath, getRuntime, matchPath } from "@next-core/runtime";
2
2
  import { createLocation } from "history";
3
3
  import { resetPermissionPreChecks } from "./checkPermissions.js";
4
4
  const auth = {};
@@ -61,22 +61,71 @@ export function addPathToBlackList(path) {
61
61
 
62
62
  /**
63
63
  * 判断一个内部 URL 路径是否被屏蔽。
64
+ *
65
+ * @param pathnameWithQuery - 路径(可包含查询字符串)
66
+ * @returns 是否被屏蔽
67
+ */
68
+ export function isBlockedPath(pathnameWithQuery) {
69
+ return [...pathBlackListSet].some(pattern => {
70
+ // 分离 pattern 的路径和查询字符串
71
+ const [patternPath, patternQuery] = pattern.split("?");
72
+
73
+ // 分离待检查路径的路径和查询字符串
74
+ const [pathname, pathQuery] = pathnameWithQuery.split("?");
75
+
76
+ // 首先匹配路径部分
77
+ const pathMatched = matchPath(pathname, {
78
+ path: patternPath
79
+ });
80
+ if (!pathMatched) {
81
+ return false;
82
+ }
83
+
84
+ // 如果 pattern 不包含查询字符串,只要路径匹配就返回 true
85
+ if (!patternQuery) {
86
+ return true;
87
+ }
88
+
89
+ // 如果 pattern 包含查询字符串,但待检查路径没有,返回 false
90
+ if (!pathQuery) {
91
+ return false;
92
+ }
93
+
94
+ // 精确匹配查询字符串(所有 pattern 中的参数必须存在且值相同)
95
+ const patternParams = new URLSearchParams(patternQuery);
96
+ const pathParams = new URLSearchParams(pathQuery);
97
+ for (const [key, value] of patternParams.entries()) {
98
+ if (pathParams.get(key) !== value) {
99
+ return false;
100
+ }
101
+ }
102
+ return true;
103
+ });
104
+ }
105
+
106
+ /**
107
+ * 根据特性开关决定是否拼接查询字符串
108
+ * @param pathname - 路径名
109
+ * @param search - 查询字符串(可选)
110
+ * @returns 拼接后的路径
64
111
  */
65
- export function isBlockedPath(pathname) {
66
- return [...pathBlackListSet].some(path => matchPath(pathname, {
67
- path
68
- }));
112
+ function getPathnameWithQuery(pathname, search) {
113
+ const flags = getRuntime().getFeatureFlags();
114
+ const blackListPreserveQueryFlag = flags === null || flags === void 0 ? void 0 : flags["blacklist-preserve-query-string"];
115
+ return blackListPreserveQueryFlag && search ? pathname + search : pathname;
69
116
  }
70
117
 
71
118
  /**
72
119
  * 判断一个内部 URL 是否被屏蔽。
73
120
  */
74
121
  export function isBlockedUrl(url) {
75
- const pathname = (typeof url === "string" ? createLocation(url) : url).pathname;
122
+ const location = typeof url === "string" ? createLocation(url) : url;
123
+ const pathname = location.pathname;
76
124
  if (typeof pathname !== "string") {
77
125
  return false;
78
126
  }
79
- return isBlockedPath(pathname);
127
+ const pathnameWithQuery = getPathnameWithQuery(pathname, location.search);
128
+ return isBlockedPath(pathnameWithQuery);
80
129
  }
81
130
 
82
131
  /**
@@ -90,6 +139,8 @@ export function isBlockedHref(href) {
90
139
  return false;
91
140
  }
92
141
  // 转换为内部路径
93
- return isBlockedPath(url.pathname.substring(basePath.length - 1));
142
+ const internalPath = url.pathname.substring(basePath.length - 1);
143
+ const pathnameWithQuery = getPathnameWithQuery(internalPath, url.search);
144
+ return isBlockedPath(pathnameWithQuery);
94
145
  }
95
146
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","names":["getBasePath","matchPath","createLocation","resetPermissionPreChecks","auth","pathBlackListSet","Set","authenticate","newAuth","_newAuth$license","Object","assign","org","username","userInstanceId","loginFrom","accessRule","isAdmin","csrfToken","license","accessToken","userShowValue","blackList","getAuth","logout","key","keys","undefined","isLoggedIn","addPathToBlackList","path","add","isBlockedPath","pathname","some","isBlockedUrl","url","isBlockedHref","href","basePath","URL","location","origin","startsWith","substring","length"],"sources":["../../src/auth.ts"],"sourcesContent":["import { getBasePath, matchPath } from \"@next-core/runtime\";\nimport type { AuthApi_CheckLoginResponseBody } from \"@next-api-sdk/api-gateway-sdk\";\nimport { createLocation, type LocationDescriptor } from \"history\";\nimport { resetPermissionPreChecks } from \"./checkPermissions.js\";\n\nconst auth: AuthInfo = {};\nlet pathBlackListSet = new Set<string>();\n\n/** @internal */\nexport type AuthInfo = Omit<AuthApi_CheckLoginResponseBody, \"loggedIn\">;\n\n/** @internal */\nexport function authenticate(newAuth: AuthInfo): void {\n Object.assign(auth, {\n org: newAuth.org,\n username: newAuth.username,\n userInstanceId: newAuth.userInstanceId,\n loginFrom: newAuth.loginFrom,\n accessRule: newAuth.accessRule,\n isAdmin: newAuth.isAdmin,\n csrfToken: newAuth.csrfToken,\n license: newAuth.license,\n accessToken: newAuth.accessToken,\n userShowValue: newAuth.userShowValue,\n });\n\n pathBlackListSet = new Set(newAuth.license?.blackList);\n}\n\n/**\n * 获取当前登录认证信息。\n *\n * @returns 当前登录认证信息。\n */\nexport function getAuth(): AuthInfo {\n return {\n ...auth,\n };\n}\n\n/** @internal */\nexport function logout(): void {\n for (const key of Object.keys(auth) as (keyof AuthInfo)[]) {\n auth[key] = undefined;\n }\n resetPermissionPreChecks();\n}\n\n/**\n * 查看当前是否已登录。\n *\n * @returns 当前是否已登录。\n */\nexport function isLoggedIn(): boolean {\n return auth.username !== undefined;\n}\n\n/**\n * 增加路径黑名单\n */\nexport function addPathToBlackList(path: string): void {\n pathBlackListSet.add(path);\n}\n\n/**\n * 判断一个内部 URL 路径是否被屏蔽。\n */\nexport function isBlockedPath(pathname: string): boolean {\n return [...pathBlackListSet].some((path) => matchPath(pathname, { path }));\n}\n\n/**\n * 判断一个内部 URL 是否被屏蔽。\n */\nexport function isBlockedUrl(url: string | LocationDescriptor): boolean {\n const pathname = (typeof url === \"string\" ? createLocation(url) : url)\n .pathname;\n if (typeof pathname !== \"string\") {\n return false;\n }\n return isBlockedPath(pathname);\n}\n\n/**\n * 判断一个 href 是否被屏蔽。\n */\nexport function isBlockedHref(href: string): boolean {\n const basePath = getBasePath();\n const url = new URL(href, `${location.origin}${basePath}`);\n // 忽略外链地址\n if (url.origin !== location.origin || !url.pathname.startsWith(basePath)) {\n return false;\n }\n // 转换为内部路径\n return isBlockedPath(url.pathname.substring(basePath.length - 1));\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"auth.js","names":["getBasePath","getRuntime","matchPath","createLocation","resetPermissionPreChecks","auth","pathBlackListSet","Set","authenticate","newAuth","_newAuth$license","Object","assign","org","username","userInstanceId","loginFrom","accessRule","isAdmin","csrfToken","license","accessToken","userShowValue","blackList","getAuth","logout","key","keys","undefined","isLoggedIn","addPathToBlackList","path","add","isBlockedPath","pathnameWithQuery","some","pattern","patternPath","patternQuery","split","pathname","pathQuery","pathMatched","patternParams","URLSearchParams","pathParams","value","entries","get","getPathnameWithQuery","search","flags","getFeatureFlags","blackListPreserveQueryFlag","isBlockedUrl","url","location","isBlockedHref","href","basePath","URL","origin","startsWith","internalPath","substring","length"],"sources":["../../src/auth.ts"],"sourcesContent":["import { getBasePath, getRuntime, matchPath } from \"@next-core/runtime\";\nimport type { AuthApi_CheckLoginResponseBody } from \"@next-api-sdk/api-gateway-sdk\";\nimport { createLocation, type LocationDescriptor } from \"history\";\nimport { resetPermissionPreChecks } from \"./checkPermissions.js\";\n\nconst auth: AuthInfo = {};\nlet pathBlackListSet = new Set<string>();\n\n/** @internal */\nexport type AuthInfo = Omit<AuthApi_CheckLoginResponseBody, \"loggedIn\">;\n\n/** @internal */\nexport function authenticate(newAuth: AuthInfo): void {\n Object.assign(auth, {\n org: newAuth.org,\n username: newAuth.username,\n userInstanceId: newAuth.userInstanceId,\n loginFrom: newAuth.loginFrom,\n accessRule: newAuth.accessRule,\n isAdmin: newAuth.isAdmin,\n csrfToken: newAuth.csrfToken,\n license: newAuth.license,\n accessToken: newAuth.accessToken,\n userShowValue: newAuth.userShowValue,\n });\n\n pathBlackListSet = new Set(newAuth.license?.blackList);\n}\n\n/**\n * 获取当前登录认证信息。\n *\n * @returns 当前登录认证信息。\n */\nexport function getAuth(): AuthInfo {\n return {\n ...auth,\n };\n}\n\n/** @internal */\nexport function logout(): void {\n for (const key of Object.keys(auth) as (keyof AuthInfo)[]) {\n auth[key] = undefined;\n }\n resetPermissionPreChecks();\n}\n\n/**\n * 查看当前是否已登录。\n *\n * @returns 当前是否已登录。\n */\nexport function isLoggedIn(): boolean {\n return auth.username !== undefined;\n}\n\n/**\n * 增加路径黑名单\n */\nexport function addPathToBlackList(path: string): void {\n pathBlackListSet.add(path);\n}\n\n/**\n * 判断一个内部 URL 路径是否被屏蔽。\n *\n * @param pathnameWithQuery - 路径(可包含查询字符串)\n * @returns 是否被屏蔽\n */\nexport function isBlockedPath(pathnameWithQuery: string): boolean {\n return [...pathBlackListSet].some((pattern) => {\n // 分离 pattern 的路径和查询字符串\n const [patternPath, patternQuery] = pattern.split(\"?\");\n\n // 分离待检查路径的路径和查询字符串\n const [pathname, pathQuery] = pathnameWithQuery.split(\"?\");\n\n // 首先匹配路径部分\n const pathMatched = matchPath(pathname, { path: patternPath });\n if (!pathMatched) {\n return false;\n }\n\n // 如果 pattern 不包含查询字符串,只要路径匹配就返回 true\n if (!patternQuery) {\n return true;\n }\n\n // 如果 pattern 包含查询字符串,但待检查路径没有,返回 false\n if (!pathQuery) {\n return false;\n }\n\n // 精确匹配查询字符串(所有 pattern 中的参数必须存在且值相同)\n const patternParams = new URLSearchParams(patternQuery);\n const pathParams = new URLSearchParams(pathQuery);\n\n for (const [key, value] of patternParams.entries()) {\n if (pathParams.get(key) !== value) {\n return false;\n }\n }\n\n return true;\n });\n}\n\n/**\n * 根据特性开关决定是否拼接查询字符串\n * @param pathname - 路径名\n * @param search - 查询字符串(可选)\n * @returns 拼接后的路径\n */\nfunction getPathnameWithQuery(pathname: string, search?: string): string {\n const flags = getRuntime().getFeatureFlags();\n const blackListPreserveQueryFlag = flags?.[\"blacklist-preserve-query-string\"];\n return blackListPreserveQueryFlag && search ? pathname + search : pathname;\n}\n\n/**\n * 判断一个内部 URL 是否被屏蔽。\n */\nexport function isBlockedUrl(url: string | LocationDescriptor): boolean {\n const location = typeof url === \"string\" ? createLocation(url) : url;\n const pathname = location.pathname;\n if (typeof pathname !== \"string\") {\n return false;\n }\n const pathnameWithQuery = getPathnameWithQuery(pathname, location.search);\n return isBlockedPath(pathnameWithQuery);\n}\n\n/**\n * 判断一个 href 是否被屏蔽。\n */\nexport function isBlockedHref(href: string): boolean {\n const basePath = getBasePath();\n const url = new URL(href, `${location.origin}${basePath}`);\n // 忽略外链地址\n if (url.origin !== location.origin || !url.pathname.startsWith(basePath)) {\n return false;\n }\n // 转换为内部路径\n const internalPath = url.pathname.substring(basePath.length - 1);\n const pathnameWithQuery = getPathnameWithQuery(internalPath, url.search);\n return isBlockedPath(pathnameWithQuery);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -2,6 +2,7 @@ import yaml from "js-yaml";
2
2
  import { ContractCenterApi_batchSearchContract } from "@next-api-sdk/next-builder-sdk";
3
3
  import { hasOwnProperty } from "@next-core/utils/general";
4
4
  import { getContract } from "./CollectContracts.js";
5
+ import { isUnauthenticatedError } from "@next-core/runtime";
5
6
  const remoteContractCache = new Map();
6
7
 
7
8
  // Legacy Custom API: `${namespace}@${name}`
@@ -194,6 +195,10 @@ async function fetchFlowApiDefinitionFromRemote(namespace, name, version) {
194
195
  });
195
196
  contractData = contractList[0];
196
197
  } catch (e) {
198
+ if (isUnauthenticatedError(e)) {
199
+ // If unauthenticated, throw the error to be handled by upper level
200
+ throw e;
201
+ }
197
202
  error = e;
198
203
  }
199
204
  if (!contractData) {
@@ -1 +1 @@
1
- {"version":3,"file":"FlowApi.js","names":["yaml","ContractCenterApi_batchSearchContract","hasOwnProperty","getContract","remoteContractCache","Map","isFlowApiProvider","provider","includes","getArgsOfFlowApi","originalArgs","method","stream","Error","apiDefinition","fetchFlowApiDefinition","FlowApiNotFoundError","apiProfile","getApiProfileFromApiDefinition","getApiArgsFromApiProfile","api","uri","apiMethod","ext_fields","responseWrapper","isFileType","request","isDownload","filename","fixedArgs","Array","isArray","slice","shift","url","args","getTransformedUriAndRestArgs","originalUri","name","namespace","serviceName","version","prefix","startsWith","transformedUri","restArgs","replace","restParams","params","_","key","value","isSimpleRequest","toLowerCase","_uri$match$length","_uri$match","_request$fields$lengt","_request$fields","noParams","type","match","length","fields","push","bodyField","find","item","source","body","queryField","query","options","_contract$endpoint","_contract$response","contract","safeLoad","schema","JSON_SCHEMA","json","endpoint","response","wrapper","namespaceName","nameWithVersion","split","namespaceId","promise","get","fetchFlowApiDefinitionFromRemote","set","contractData","fullContractName","error","list","contractList","e","console","constructor","message","captureStackTrace"],"sources":["../../../src/flowApi/FlowApi.ts"],"sourcesContent":["import yaml from \"js-yaml\";\nimport {\n ContractCenterApi_batchSearchContract,\n type ContractCenterApi_BatchSearchContractResponseBody_list_item,\n} from \"@next-api-sdk/next-builder-sdk\";\nimport type {\n ContractResponse,\n ExtField,\n ContractRequest,\n UseProviderContractConf,\n} from \"@next-core/types\";\nimport { hasOwnProperty } from \"@next-core/utils/general\";\nimport { getContract } from \"./CollectContracts.js\";\n\nexport type MinimalContractRequest = Pick<ContractRequest, \"type\"> & {\n fields?: MinimalContractField[];\n};\nexport type MinimalContractField =\n | {\n type: string;\n fields?: MinimalContractField[];\n }\n | {\n ref: string;\n };\nexport type MinimalContractResponse = Pick<\n ContractResponse,\n \"type\" | \"wrapper\"\n>;\n\nconst remoteContractCache = new Map<\n string,\n Promise<CustomApiDefinition | null>\n>();\n\n// Legacy Custom API: `${namespace}@${name}`\n// Flow API: `${namespace}@${name}:${version}`\nexport function isFlowApiProvider(provider: string): boolean {\n return provider.includes(\"@\");\n}\n\nexport async function getArgsOfFlowApi(\n provider: string,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): Promise<unknown[]> {\n if (!provider.includes(\":\")) {\n throw new Error(\n `You're using legacy Custom API \"${provider}\" which is dropped in v3, please use Flow API instead`\n );\n }\n\n const apiDefinition = await fetchFlowApiDefinition(provider);\n\n if (!apiDefinition) {\n throw new FlowApiNotFoundError(`Flow API not found: \"${provider}\"`);\n }\n\n const apiProfile = getApiProfileFromApiDefinition(provider, apiDefinition);\n\n return getApiArgsFromApiProfile(apiProfile, originalArgs, method, stream);\n}\n\nfunction getApiArgsFromApiProfile(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): unknown[] {\n const {\n uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n isFileType,\n request,\n } = api;\n // `saveAs` requires the first argument to be the filename.\n const isDownload = method === \"saveAs\";\n let filename: string | undefined;\n let fixedArgs = originalArgs;\n if (isDownload) {\n if (Array.isArray(originalArgs)) {\n fixedArgs = originalArgs.slice();\n filename = fixedArgs.shift() as string;\n } else {\n filename = originalArgs.filename;\n }\n }\n\n const { url, args } = getTransformedUriAndRestArgs(api, fixedArgs);\n\n return [\n ...(isDownload ? [filename] : []),\n {\n url,\n originalUri: uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n request,\n isFileType,\n stream,\n },\n ...args,\n ];\n}\n\nfunction getTransformedUriAndRestArgs(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf\n): { url: string; args: unknown[] } {\n const {\n uri,\n name,\n namespace,\n serviceName,\n version,\n method = \"GET\",\n request,\n ext_fields,\n } = api;\n\n const prefix = version\n ? serviceName === \"logic.api.gateway\" ||\n serviceName?.startsWith(\"logic.api.gateway.\")\n ? \"\"\n : serviceName\n ? `api/gateway/${serviceName}`\n : `api/gateway/${namespace}.${name}@${version}`\n : `api/gateway/api_service.${namespace}.${name}`;\n\n let transformedUri: string;\n let restArgs: unknown[] = [];\n if (Array.isArray(originalArgs)) {\n restArgs = originalArgs.slice();\n transformedUri = uri.replace(/:([^/]+)/g, () => restArgs.shift() as string);\n } else {\n const restParams = { ...originalArgs.params };\n transformedUri = uri.replace(/:([^/]+)/g, (_, key) => {\n if (hasOwnProperty(restParams, key)) {\n const value = restParams[key] as string;\n delete restParams[key];\n return value;\n }\n throw new Error(`Missing required param: \"${key}\"`);\n });\n\n const isSimpleRequest = [\"get\", \"delete\", \"head\"].includes(\n method.toLowerCase()\n );\n if (isSimpleRequest) {\n const noParams =\n request?.type === \"object\" &&\n (uri.match(/:([^/]+)/g)?.length ?? 0) === (request.fields?.length ?? 0);\n if (!noParams) {\n restArgs.push(restParams);\n }\n } else {\n const bodyField = ext_fields?.find((item) => item.source === \"body\");\n if (bodyField) {\n let body: Record<string, unknown> | undefined;\n if (bodyField.name && hasOwnProperty(restParams, bodyField.name)) {\n body = restParams[bodyField.name] as Record<string, unknown>;\n delete restParams[bodyField.name];\n }\n restArgs.push(body);\n }\n\n const queryField = ext_fields?.find((item) => item.source === \"query\");\n if (queryField) {\n let query: Record<string, unknown> | undefined;\n if (queryField.name && hasOwnProperty(restParams, queryField.name)) {\n query = restParams[queryField.name] as Record<string, unknown>;\n delete restParams[queryField.name];\n }\n\n restArgs.push(query);\n }\n\n if (!bodyField && !queryField) {\n restArgs.push(restParams);\n }\n }\n\n if (originalArgs.options) {\n restArgs.push(originalArgs.options);\n }\n }\n return {\n url: prefix ? prefix + transformedUri : transformedUri.replace(/^\\//, \"\"),\n args: restArgs,\n };\n}\n\nfunction getApiProfileFromApiDefinition(\n provider: string,\n api: CustomApiDefinition\n): CustomApiProfile {\n const contract: CustomApiDefinition[\"contract\"] =\n typeof api.contract === \"string\"\n ? (yaml.safeLoad(api.contract, {\n schema: yaml.JSON_SCHEMA,\n json: true,\n }) as CustomApiDefinition[\"contract\"])\n : api.contract;\n const { uri, method = \"GET\", ext_fields } = contract?.endpoint ?? {};\n const responseWrapper = contract?.response\n ? contract.response.wrapper !== false\n : false;\n if (!uri) {\n throw new Error(\n `Missing endpoint.uri in contract of provider \"${provider}\"`\n );\n }\n return {\n uri,\n method: method.toLowerCase() === \"list\" ? \"get\" : method,\n ext_fields,\n name: api.name,\n namespace: api.namespace,\n serviceName: api.serviceName,\n version: api.version,\n isFileType: contract?.response?.type === \"file\",\n responseWrapper,\n request: contract?.request,\n };\n}\n\nasync function fetchFlowApiDefinition(\n provider: string\n): Promise<CustomApiDefinition | null> {\n const [namespaceName, nameWithVersion] = provider.split(\"@\");\n const [name, version] = nameWithVersion.split(\":\");\n\n // Do not cache the result of `getContract`, which will lead to no contract\n // will be found when render twice immediately.\n const contract = getContract(`${namespaceName}.${name}`);\n if (contract) {\n return {\n name: contract.name,\n namespace: contract.namespaceId,\n serviceName: contract.serviceName,\n version: contract.version,\n contract: {\n endpoint: contract.endpoint,\n response: contract.response,\n request: contract.request,\n },\n };\n }\n let promise = remoteContractCache.get(provider);\n if (!promise) {\n promise = fetchFlowApiDefinitionFromRemote(namespaceName, name, version);\n remoteContractCache.set(provider, promise);\n }\n return promise;\n}\n\nasync function fetchFlowApiDefinitionFromRemote(\n namespace: string,\n name: string,\n version: string\n): Promise<CustomApiDefinition | null> {\n let contractData:\n | ContractCenterApi_BatchSearchContractResponseBody_list_item\n | undefined;\n const fullContractName = `${namespace}@${name}`;\n let error: unknown;\n\n try {\n const { list: contractList } = await ContractCenterApi_batchSearchContract({\n contract: [\n {\n fullContractName,\n version,\n },\n ],\n });\n contractData = contractList![0];\n } catch (e) {\n error = e;\n }\n\n if (!contractData) {\n // eslint-disable-next-line no-console\n console.error(\n `Failed to fetch Flow API definition for \"${fullContractName}:${version}\"`,\n error ?? \"Contract not found\"\n );\n return null;\n }\n\n return {\n name: contractData.name,\n namespace: contractData.namespaceId,\n serviceName: contractData.serviceName,\n version: contractData.version,\n contract: {\n endpoint: contractData.endpoint,\n response: contractData.response,\n request: contractData.request,\n },\n } as CustomApiDefinition;\n}\n\nexport interface CustomApiDefinition {\n name: string;\n namespace: string;\n version?: string;\n serviceName?: string;\n contract?: {\n endpoint: {\n ext_fields?: ExtField[];\n uri: string;\n method:\n | \"POST\"\n | \"post\"\n | \"PUT\"\n | \"put\"\n | \"GET\"\n | \"get\"\n | \"DELETE\"\n | \"delete\"\n | \"LIST\"\n | \"list\"\n | \"PATCH\"\n | \"patch\"\n | \"HEAD\"\n | \"head\";\n };\n request?: MinimalContractRequest;\n response?: MinimalContractResponse;\n };\n}\n\nexport interface CustomApiProfile {\n uri: string;\n method: string;\n name: string;\n namespace: string;\n serviceName?: string;\n responseWrapper: boolean;\n version?: string;\n isFileType?: boolean;\n ext_fields?: ExtField[];\n request?: MinimalContractRequest;\n}\n\nclass FlowApiNotFoundError extends Error {\n constructor(message: string) {\n // Pass remaining arguments (including vendor specific ones) to parent constructor\n super(message);\n\n this.name = \"FlowApiNotFoundError\";\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n // istanbul ignore else\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FlowApiNotFoundError);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FlowApi.js","names":["yaml","ContractCenterApi_batchSearchContract","hasOwnProperty","getContract","isUnauthenticatedError","remoteContractCache","Map","isFlowApiProvider","provider","includes","getArgsOfFlowApi","originalArgs","method","stream","Error","apiDefinition","fetchFlowApiDefinition","FlowApiNotFoundError","apiProfile","getApiProfileFromApiDefinition","getApiArgsFromApiProfile","api","uri","apiMethod","ext_fields","responseWrapper","isFileType","request","isDownload","filename","fixedArgs","Array","isArray","slice","shift","url","args","getTransformedUriAndRestArgs","originalUri","name","namespace","serviceName","version","prefix","startsWith","transformedUri","restArgs","replace","restParams","params","_","key","value","isSimpleRequest","toLowerCase","_uri$match$length","_uri$match","_request$fields$lengt","_request$fields","noParams","type","match","length","fields","push","bodyField","find","item","source","body","queryField","query","options","_contract$endpoint","_contract$response","contract","safeLoad","schema","JSON_SCHEMA","json","endpoint","response","wrapper","namespaceName","nameWithVersion","split","namespaceId","promise","get","fetchFlowApiDefinitionFromRemote","set","contractData","fullContractName","error","list","contractList","e","console","constructor","message","captureStackTrace"],"sources":["../../../src/flowApi/FlowApi.ts"],"sourcesContent":["import yaml from \"js-yaml\";\nimport {\n ContractCenterApi_batchSearchContract,\n type ContractCenterApi_BatchSearchContractResponseBody_list_item,\n} from \"@next-api-sdk/next-builder-sdk\";\nimport type {\n ContractResponse,\n ExtField,\n ContractRequest,\n UseProviderContractConf,\n} from \"@next-core/types\";\nimport { hasOwnProperty } from \"@next-core/utils/general\";\nimport { getContract } from \"./CollectContracts.js\";\nimport { isUnauthenticatedError } from \"@next-core/runtime\";\n\nexport type MinimalContractRequest = Pick<ContractRequest, \"type\"> & {\n fields?: MinimalContractField[];\n};\nexport type MinimalContractField =\n | {\n type: string;\n fields?: MinimalContractField[];\n }\n | {\n ref: string;\n };\nexport type MinimalContractResponse = Pick<\n ContractResponse,\n \"type\" | \"wrapper\"\n>;\n\nconst remoteContractCache = new Map<\n string,\n Promise<CustomApiDefinition | null>\n>();\n\n// Legacy Custom API: `${namespace}@${name}`\n// Flow API: `${namespace}@${name}:${version}`\nexport function isFlowApiProvider(provider: string): boolean {\n return provider.includes(\"@\");\n}\n\nexport async function getArgsOfFlowApi(\n provider: string,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): Promise<unknown[]> {\n if (!provider.includes(\":\")) {\n throw new Error(\n `You're using legacy Custom API \"${provider}\" which is dropped in v3, please use Flow API instead`\n );\n }\n\n const apiDefinition = await fetchFlowApiDefinition(provider);\n\n if (!apiDefinition) {\n throw new FlowApiNotFoundError(`Flow API not found: \"${provider}\"`);\n }\n\n const apiProfile = getApiProfileFromApiDefinition(provider, apiDefinition);\n\n return getApiArgsFromApiProfile(apiProfile, originalArgs, method, stream);\n}\n\nfunction getApiArgsFromApiProfile(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf,\n method?: string,\n stream?: boolean\n): unknown[] {\n const {\n uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n isFileType,\n request,\n } = api;\n // `saveAs` requires the first argument to be the filename.\n const isDownload = method === \"saveAs\";\n let filename: string | undefined;\n let fixedArgs = originalArgs;\n if (isDownload) {\n if (Array.isArray(originalArgs)) {\n fixedArgs = originalArgs.slice();\n filename = fixedArgs.shift() as string;\n } else {\n filename = originalArgs.filename;\n }\n }\n\n const { url, args } = getTransformedUriAndRestArgs(api, fixedArgs);\n\n return [\n ...(isDownload ? [filename] : []),\n {\n url,\n originalUri: uri,\n method: apiMethod,\n ext_fields,\n responseWrapper,\n request,\n isFileType,\n stream,\n },\n ...args,\n ];\n}\n\nfunction getTransformedUriAndRestArgs(\n api: CustomApiProfile,\n originalArgs: unknown[] | UseProviderContractConf\n): { url: string; args: unknown[] } {\n const {\n uri,\n name,\n namespace,\n serviceName,\n version,\n method = \"GET\",\n request,\n ext_fields,\n } = api;\n\n const prefix = version\n ? serviceName === \"logic.api.gateway\" ||\n serviceName?.startsWith(\"logic.api.gateway.\")\n ? \"\"\n : serviceName\n ? `api/gateway/${serviceName}`\n : `api/gateway/${namespace}.${name}@${version}`\n : `api/gateway/api_service.${namespace}.${name}`;\n\n let transformedUri: string;\n let restArgs: unknown[] = [];\n if (Array.isArray(originalArgs)) {\n restArgs = originalArgs.slice();\n transformedUri = uri.replace(/:([^/]+)/g, () => restArgs.shift() as string);\n } else {\n const restParams = { ...originalArgs.params };\n transformedUri = uri.replace(/:([^/]+)/g, (_, key) => {\n if (hasOwnProperty(restParams, key)) {\n const value = restParams[key] as string;\n delete restParams[key];\n return value;\n }\n throw new Error(`Missing required param: \"${key}\"`);\n });\n\n const isSimpleRequest = [\"get\", \"delete\", \"head\"].includes(\n method.toLowerCase()\n );\n if (isSimpleRequest) {\n const noParams =\n request?.type === \"object\" &&\n (uri.match(/:([^/]+)/g)?.length ?? 0) === (request.fields?.length ?? 0);\n if (!noParams) {\n restArgs.push(restParams);\n }\n } else {\n const bodyField = ext_fields?.find((item) => item.source === \"body\");\n if (bodyField) {\n let body: Record<string, unknown> | undefined;\n if (bodyField.name && hasOwnProperty(restParams, bodyField.name)) {\n body = restParams[bodyField.name] as Record<string, unknown>;\n delete restParams[bodyField.name];\n }\n restArgs.push(body);\n }\n\n const queryField = ext_fields?.find((item) => item.source === \"query\");\n if (queryField) {\n let query: Record<string, unknown> | undefined;\n if (queryField.name && hasOwnProperty(restParams, queryField.name)) {\n query = restParams[queryField.name] as Record<string, unknown>;\n delete restParams[queryField.name];\n }\n\n restArgs.push(query);\n }\n\n if (!bodyField && !queryField) {\n restArgs.push(restParams);\n }\n }\n\n if (originalArgs.options) {\n restArgs.push(originalArgs.options);\n }\n }\n return {\n url: prefix ? prefix + transformedUri : transformedUri.replace(/^\\//, \"\"),\n args: restArgs,\n };\n}\n\nfunction getApiProfileFromApiDefinition(\n provider: string,\n api: CustomApiDefinition\n): CustomApiProfile {\n const contract: CustomApiDefinition[\"contract\"] =\n typeof api.contract === \"string\"\n ? (yaml.safeLoad(api.contract, {\n schema: yaml.JSON_SCHEMA,\n json: true,\n }) as CustomApiDefinition[\"contract\"])\n : api.contract;\n const { uri, method = \"GET\", ext_fields } = contract?.endpoint ?? {};\n const responseWrapper = contract?.response\n ? contract.response.wrapper !== false\n : false;\n if (!uri) {\n throw new Error(\n `Missing endpoint.uri in contract of provider \"${provider}\"`\n );\n }\n return {\n uri,\n method: method.toLowerCase() === \"list\" ? \"get\" : method,\n ext_fields,\n name: api.name,\n namespace: api.namespace,\n serviceName: api.serviceName,\n version: api.version,\n isFileType: contract?.response?.type === \"file\",\n responseWrapper,\n request: contract?.request,\n };\n}\n\nasync function fetchFlowApiDefinition(\n provider: string\n): Promise<CustomApiDefinition | null> {\n const [namespaceName, nameWithVersion] = provider.split(\"@\");\n const [name, version] = nameWithVersion.split(\":\");\n\n // Do not cache the result of `getContract`, which will lead to no contract\n // will be found when render twice immediately.\n const contract = getContract(`${namespaceName}.${name}`);\n if (contract) {\n return {\n name: contract.name,\n namespace: contract.namespaceId,\n serviceName: contract.serviceName,\n version: contract.version,\n contract: {\n endpoint: contract.endpoint,\n response: contract.response,\n request: contract.request,\n },\n };\n }\n let promise = remoteContractCache.get(provider);\n if (!promise) {\n promise = fetchFlowApiDefinitionFromRemote(namespaceName, name, version);\n remoteContractCache.set(provider, promise);\n }\n return promise;\n}\n\nasync function fetchFlowApiDefinitionFromRemote(\n namespace: string,\n name: string,\n version: string\n): Promise<CustomApiDefinition | null> {\n let contractData:\n | ContractCenterApi_BatchSearchContractResponseBody_list_item\n | undefined;\n const fullContractName = `${namespace}@${name}`;\n let error: unknown;\n\n try {\n const { list: contractList } = await ContractCenterApi_batchSearchContract({\n contract: [\n {\n fullContractName,\n version,\n },\n ],\n });\n contractData = contractList![0];\n } catch (e) {\n if (isUnauthenticatedError(e)) {\n // If unauthenticated, throw the error to be handled by upper level\n throw e;\n }\n error = e;\n }\n\n if (!contractData) {\n // eslint-disable-next-line no-console\n console.error(\n `Failed to fetch Flow API definition for \"${fullContractName}:${version}\"`,\n error ?? \"Contract not found\"\n );\n return null;\n }\n\n return {\n name: contractData.name,\n namespace: contractData.namespaceId,\n serviceName: contractData.serviceName,\n version: contractData.version,\n contract: {\n endpoint: contractData.endpoint,\n response: contractData.response,\n request: contractData.request,\n },\n } as CustomApiDefinition;\n}\n\nexport interface CustomApiDefinition {\n name: string;\n namespace: string;\n version?: string;\n serviceName?: string;\n contract?: {\n endpoint: {\n ext_fields?: ExtField[];\n uri: string;\n method:\n | \"POST\"\n | \"post\"\n | \"PUT\"\n | \"put\"\n | \"GET\"\n | \"get\"\n | \"DELETE\"\n | \"delete\"\n | \"LIST\"\n | \"list\"\n | \"PATCH\"\n | \"patch\"\n | \"HEAD\"\n | \"head\";\n };\n request?: MinimalContractRequest;\n response?: MinimalContractResponse;\n };\n}\n\nexport interface CustomApiProfile {\n uri: string;\n method: string;\n name: string;\n namespace: string;\n serviceName?: string;\n responseWrapper: boolean;\n version?: string;\n isFileType?: boolean;\n ext_fields?: ExtField[];\n request?: MinimalContractRequest;\n}\n\nclass FlowApiNotFoundError extends Error {\n constructor(message: string) {\n // Pass remaining arguments (including vendor specific ones) to parent constructor\n super(message);\n\n this.name = \"FlowApiNotFoundError\";\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n // istanbul ignore else\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FlowApiNotFoundError);\n }\n }\n}\n"],"mappings":"AAAA,OAAOA,IAAI,MAAM,SAAS;AAC1B,SACEC,qCAAqC,QAEhC,gCAAgC;AAOvC,SAASC,cAAc,QAAQ,0BAA0B;AACzD,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,sBAAsB,QAAQ,oBAAoB;AAkB3D,MAAMC,mBAAmB,GAAG,IAAIC,GAAG,CAGjC,CAAC;;AAEH;AACA;AACA,OAAO,SAASC,iBAAiBA,CAACC,QAAgB,EAAW;EAC3D,OAAOA,QAAQ,CAACC,QAAQ,CAAC,GAAG,CAAC;AAC/B;AAEA,OAAO,eAAeC,gBAAgBA,CACpCF,QAAgB,EAChBG,YAAiD,EACjDC,MAAe,EACfC,MAAgB,EACI;EACpB,IAAI,CAACL,QAAQ,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAC3B,MAAM,IAAIK,KAAK,CACb,mCAAmCN,QAAQ,uDAC7C,CAAC;EACH;EAEA,MAAMO,aAAa,GAAG,MAAMC,sBAAsB,CAACR,QAAQ,CAAC;EAE5D,IAAI,CAACO,aAAa,EAAE;IAClB,MAAM,IAAIE,oBAAoB,CAAC,wBAAwBT,QAAQ,GAAG,CAAC;EACrE;EAEA,MAAMU,UAAU,GAAGC,8BAA8B,CAACX,QAAQ,EAAEO,aAAa,CAAC;EAE1E,OAAOK,wBAAwB,CAACF,UAAU,EAAEP,YAAY,EAAEC,MAAM,EAAEC,MAAM,CAAC;AAC3E;AAEA,SAASO,wBAAwBA,CAC/BC,GAAqB,EACrBV,YAAiD,EACjDC,MAAe,EACfC,MAAgB,EACL;EACX,MAAM;IACJS,GAAG;IACHV,MAAM,EAAEW,SAAS;IACjBC,UAAU;IACVC,eAAe;IACfC,UAAU;IACVC;EACF,CAAC,GAAGN,GAAG;EACP;EACA,MAAMO,UAAU,GAAGhB,MAAM,KAAK,QAAQ;EACtC,IAAIiB,QAA4B;EAChC,IAAIC,SAAS,GAAGnB,YAAY;EAC5B,IAAIiB,UAAU,EAAE;IACd,IAAIG,KAAK,CAACC,OAAO,CAACrB,YAAY,CAAC,EAAE;MAC/BmB,SAAS,GAAGnB,YAAY,CAACsB,KAAK,CAAC,CAAC;MAChCJ,QAAQ,GAAGC,SAAS,CAACI,KAAK,CAAC,CAAW;IACxC,CAAC,MAAM;MACLL,QAAQ,GAAGlB,YAAY,CAACkB,QAAQ;IAClC;EACF;EAEA,MAAM;IAAEM,GAAG;IAAEC;EAAK,CAAC,GAAGC,4BAA4B,CAAChB,GAAG,EAAES,SAAS,CAAC;EAElE,OAAO,CACL,IAAIF,UAAU,GAAG,CAACC,QAAQ,CAAC,GAAG,EAAE,CAAC,EACjC;IACEM,GAAG;IACHG,WAAW,EAAEhB,GAAG;IAChBV,MAAM,EAAEW,SAAS;IACjBC,UAAU;IACVC,eAAe;IACfE,OAAO;IACPD,UAAU;IACVb;EACF,CAAC,EACD,GAAGuB,IAAI,CACR;AACH;AAEA,SAASC,4BAA4BA,CACnChB,GAAqB,EACrBV,YAAiD,EACf;EAClC,MAAM;IACJW,GAAG;IACHiB,IAAI;IACJC,SAAS;IACTC,WAAW;IACXC,OAAO;IACP9B,MAAM,GAAG,KAAK;IACde,OAAO;IACPH;EACF,CAAC,GAAGH,GAAG;EAEP,MAAMsB,MAAM,GAAGD,OAAO,GAClBD,WAAW,KAAK,mBAAmB,IACnCA,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEG,UAAU,CAAC,oBAAoB,CAAC,GAC3C,EAAE,GACFH,WAAW,GACT,eAAeA,WAAW,EAAE,GAC5B,eAAeD,SAAS,IAAID,IAAI,IAAIG,OAAO,EAAE,GACjD,2BAA2BF,SAAS,IAAID,IAAI,EAAE;EAElD,IAAIM,cAAsB;EAC1B,IAAIC,QAAmB,GAAG,EAAE;EAC5B,IAAIf,KAAK,CAACC,OAAO,CAACrB,YAAY,CAAC,EAAE;IAC/BmC,QAAQ,GAAGnC,YAAY,CAACsB,KAAK,CAAC,CAAC;IAC/BY,cAAc,GAAGvB,GAAG,CAACyB,OAAO,CAAC,WAAW,EAAE,MAAMD,QAAQ,CAACZ,KAAK,CAAC,CAAW,CAAC;EAC7E,CAAC,MAAM;IACL,MAAMc,UAAU,GAAG;MAAE,GAAGrC,YAAY,CAACsC;IAAO,CAAC;IAC7CJ,cAAc,GAAGvB,GAAG,CAACyB,OAAO,CAAC,WAAW,EAAE,CAACG,CAAC,EAAEC,GAAG,KAAK;MACpD,IAAIjD,cAAc,CAAC8C,UAAU,EAAEG,GAAG,CAAC,EAAE;QACnC,MAAMC,KAAK,GAAGJ,UAAU,CAACG,GAAG,CAAW;QACvC,OAAOH,UAAU,CAACG,GAAG,CAAC;QACtB,OAAOC,KAAK;MACd;MACA,MAAM,IAAItC,KAAK,CAAC,4BAA4BqC,GAAG,GAAG,CAAC;IACrD,CAAC,CAAC;IAEF,MAAME,eAAe,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC5C,QAAQ,CACxDG,MAAM,CAAC0C,WAAW,CAAC,CACrB,CAAC;IACD,IAAID,eAAe,EAAE;MAAA,IAAAE,iBAAA,EAAAC,UAAA,EAAAC,qBAAA,EAAAC,eAAA;MACnB,MAAMC,QAAQ,GACZ,CAAAhC,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEiC,IAAI,MAAK,QAAQ,IAC1B,EAAAL,iBAAA,IAAAC,UAAA,GAAClC,GAAG,CAACuC,KAAK,CAAC,WAAW,CAAC,cAAAL,UAAA,uBAAtBA,UAAA,CAAwBM,MAAM,cAAAP,iBAAA,cAAAA,iBAAA,GAAI,CAAC,QAAAE,qBAAA,IAAAC,eAAA,GAAO/B,OAAO,CAACoC,MAAM,cAAAL,eAAA,uBAAdA,eAAA,CAAgBI,MAAM,cAAAL,qBAAA,cAAAA,qBAAA,GAAI,CAAC,CAAC;MACzE,IAAI,CAACE,QAAQ,EAAE;QACbb,QAAQ,CAACkB,IAAI,CAAChB,UAAU,CAAC;MAC3B;IACF,CAAC,MAAM;MACL,MAAMiB,SAAS,GAAGzC,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAE0C,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACC,MAAM,KAAK,MAAM,CAAC;MACpE,IAAIH,SAAS,EAAE;QACb,IAAII,IAAyC;QAC7C,IAAIJ,SAAS,CAAC1B,IAAI,IAAIrC,cAAc,CAAC8C,UAAU,EAAEiB,SAAS,CAAC1B,IAAI,CAAC,EAAE;UAChE8B,IAAI,GAAGrB,UAAU,CAACiB,SAAS,CAAC1B,IAAI,CAA4B;UAC5D,OAAOS,UAAU,CAACiB,SAAS,CAAC1B,IAAI,CAAC;QACnC;QACAO,QAAQ,CAACkB,IAAI,CAACK,IAAI,CAAC;MACrB;MAEA,MAAMC,UAAU,GAAG9C,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAE0C,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACC,MAAM,KAAK,OAAO,CAAC;MACtE,IAAIE,UAAU,EAAE;QACd,IAAIC,KAA0C;QAC9C,IAAID,UAAU,CAAC/B,IAAI,IAAIrC,cAAc,CAAC8C,UAAU,EAAEsB,UAAU,CAAC/B,IAAI,CAAC,EAAE;UAClEgC,KAAK,GAAGvB,UAAU,CAACsB,UAAU,CAAC/B,IAAI,CAA4B;UAC9D,OAAOS,UAAU,CAACsB,UAAU,CAAC/B,IAAI,CAAC;QACpC;QAEAO,QAAQ,CAACkB,IAAI,CAACO,KAAK,CAAC;MACtB;MAEA,IAAI,CAACN,SAAS,IAAI,CAACK,UAAU,EAAE;QAC7BxB,QAAQ,CAACkB,IAAI,CAAChB,UAAU,CAAC;MAC3B;IACF;IAEA,IAAIrC,YAAY,CAAC6D,OAAO,EAAE;MACxB1B,QAAQ,CAACkB,IAAI,CAACrD,YAAY,CAAC6D,OAAO,CAAC;IACrC;EACF;EACA,OAAO;IACLrC,GAAG,EAAEQ,MAAM,GAAGA,MAAM,GAAGE,cAAc,GAAGA,cAAc,CAACE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IACzEX,IAAI,EAAEU;EACR,CAAC;AACH;AAEA,SAAS3B,8BAA8BA,CACrCX,QAAgB,EAChBa,GAAwB,EACN;EAAA,IAAAoD,kBAAA,EAAAC,kBAAA;EAClB,MAAMC,QAAyC,GAC7C,OAAOtD,GAAG,CAACsD,QAAQ,KAAK,QAAQ,GAC3B3E,IAAI,CAAC4E,QAAQ,CAACvD,GAAG,CAACsD,QAAQ,EAAE;IAC3BE,MAAM,EAAE7E,IAAI,CAAC8E,WAAW;IACxBC,IAAI,EAAE;EACR,CAAC,CAAC,GACF1D,GAAG,CAACsD,QAAQ;EAClB,MAAM;IAAErD,GAAG;IAAEV,MAAM,GAAG,KAAK;IAAEY;EAAW,CAAC,IAAAiD,kBAAA,GAAGE,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAEK,QAAQ,cAAAP,kBAAA,cAAAA,kBAAA,GAAI,CAAC,CAAC;EACpE,MAAMhD,eAAe,GAAGkD,QAAQ,aAARA,QAAQ,eAARA,QAAQ,CAAEM,QAAQ,GACtCN,QAAQ,CAACM,QAAQ,CAACC,OAAO,KAAK,KAAK,GACnC,KAAK;EACT,IAAI,CAAC5D,GAAG,EAAE;IACR,MAAM,IAAIR,KAAK,CACb,iDAAiDN,QAAQ,GAC3D,CAAC;EACH;EACA,OAAO;IACLc,GAAG;IACHV,MAAM,EAAEA,MAAM,CAAC0C,WAAW,CAAC,CAAC,KAAK,MAAM,GAAG,KAAK,GAAG1C,MAAM;IACxDY,UAAU;IACVe,IAAI,EAAElB,GAAG,CAACkB,IAAI;IACdC,SAAS,EAAEnB,GAAG,CAACmB,SAAS;IACxBC,WAAW,EAAEpB,GAAG,CAACoB,WAAW;IAC5BC,OAAO,EAAErB,GAAG,CAACqB,OAAO;IACpBhB,UAAU,EAAE,CAAAiD,QAAQ,aAARA,QAAQ,gBAAAD,kBAAA,GAARC,QAAQ,CAAEM,QAAQ,cAAAP,kBAAA,uBAAlBA,kBAAA,CAAoBd,IAAI,MAAK,MAAM;IAC/CnC,eAAe;IACfE,OAAO,EAAEgD,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAEhD;EACrB,CAAC;AACH;AAEA,eAAeX,sBAAsBA,CACnCR,QAAgB,EACqB;EACrC,MAAM,CAAC2E,aAAa,EAAEC,eAAe,CAAC,GAAG5E,QAAQ,CAAC6E,KAAK,CAAC,GAAG,CAAC;EAC5D,MAAM,CAAC9C,IAAI,EAAEG,OAAO,CAAC,GAAG0C,eAAe,CAACC,KAAK,CAAC,GAAG,CAAC;;EAElD;EACA;EACA,MAAMV,QAAQ,GAAGxE,WAAW,CAAC,GAAGgF,aAAa,IAAI5C,IAAI,EAAE,CAAC;EACxD,IAAIoC,QAAQ,EAAE;IACZ,OAAO;MACLpC,IAAI,EAAEoC,QAAQ,CAACpC,IAAI;MACnBC,SAAS,EAAEmC,QAAQ,CAACW,WAAW;MAC/B7C,WAAW,EAAEkC,QAAQ,CAAClC,WAAW;MACjCC,OAAO,EAAEiC,QAAQ,CAACjC,OAAO;MACzBiC,QAAQ,EAAE;QACRK,QAAQ,EAAEL,QAAQ,CAACK,QAAQ;QAC3BC,QAAQ,EAAEN,QAAQ,CAACM,QAAQ;QAC3BtD,OAAO,EAAEgD,QAAQ,CAAChD;MACpB;IACF,CAAC;EACH;EACA,IAAI4D,OAAO,GAAGlF,mBAAmB,CAACmF,GAAG,CAAChF,QAAQ,CAAC;EAC/C,IAAI,CAAC+E,OAAO,EAAE;IACZA,OAAO,GAAGE,gCAAgC,CAACN,aAAa,EAAE5C,IAAI,EAAEG,OAAO,CAAC;IACxErC,mBAAmB,CAACqF,GAAG,CAAClF,QAAQ,EAAE+E,OAAO,CAAC;EAC5C;EACA,OAAOA,OAAO;AAChB;AAEA,eAAeE,gCAAgCA,CAC7CjD,SAAiB,EACjBD,IAAY,EACZG,OAAe,EACsB;EACrC,IAAIiD,YAES;EACb,MAAMC,gBAAgB,GAAG,GAAGpD,SAAS,IAAID,IAAI,EAAE;EAC/C,IAAIsD,KAAc;EAElB,IAAI;IACF,MAAM;MAAEC,IAAI,EAAEC;IAAa,CAAC,GAAG,MAAM9F,qCAAqC,CAAC;MACzE0E,QAAQ,EAAE,CACR;QACEiB,gBAAgB;QAChBlD;MACF,CAAC;IAEL,CAAC,CAAC;IACFiD,YAAY,GAAGI,YAAY,CAAE,CAAC,CAAC;EACjC,CAAC,CAAC,OAAOC,CAAC,EAAE;IACV,IAAI5F,sBAAsB,CAAC4F,CAAC,CAAC,EAAE;MAC7B;MACA,MAAMA,CAAC;IACT;IACAH,KAAK,GAAGG,CAAC;EACX;EAEA,IAAI,CAACL,YAAY,EAAE;IACjB;IACAM,OAAO,CAACJ,KAAK,CACX,4CAA4CD,gBAAgB,IAAIlD,OAAO,GAAG,EAC1EmD,KAAK,aAALA,KAAK,cAALA,KAAK,GAAI,oBACX,CAAC;IACD,OAAO,IAAI;EACb;EAEA,OAAO;IACLtD,IAAI,EAAEoD,YAAY,CAACpD,IAAI;IACvBC,SAAS,EAAEmD,YAAY,CAACL,WAAW;IACnC7C,WAAW,EAAEkD,YAAY,CAAClD,WAAW;IACrCC,OAAO,EAAEiD,YAAY,CAACjD,OAAO;IAC7BiC,QAAQ,EAAE;MACRK,QAAQ,EAAEW,YAAY,CAACX,QAAQ;MAC/BC,QAAQ,EAAEU,YAAY,CAACV,QAAQ;MAC/BtD,OAAO,EAAEgE,YAAY,CAAChE;IACxB;EACF,CAAC;AACH;AA6CA,MAAMV,oBAAoB,SAASH,KAAK,CAAC;EACvCoF,WAAWA,CAACC,OAAe,EAAE;IAC3B;IACA,KAAK,CAACA,OAAO,CAAC;IAEd,IAAI,CAAC5D,IAAI,GAAG,sBAAsB;;IAElC;IACA;IACA,IAAIzB,KAAK,CAACsF,iBAAiB,EAAE;MAC3BtF,KAAK,CAACsF,iBAAiB,CAAC,IAAI,EAAEnF,oBAAoB,CAAC;IACrD;EACF;AACF","ignoreList":[]}
@@ -24,8 +24,11 @@ export declare function isLoggedIn(): boolean;
24
24
  export declare function addPathToBlackList(path: string): void;
25
25
  /**
26
26
  * 判断一个内部 URL 路径是否被屏蔽。
27
+ *
28
+ * @param pathnameWithQuery - 路径(可包含查询字符串)
29
+ * @returns 是否被屏蔽
27
30
  */
28
- export declare function isBlockedPath(pathname: string): boolean;
31
+ export declare function isBlockedPath(pathnameWithQuery: string): boolean;
29
32
  /**
30
33
  * 判断一个内部 URL 是否被屏蔽。
31
34
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next-core/easyops-runtime",
3
- "version": "0.15.26",
3
+ "version": "0.15.28",
4
4
  "homepage": "https://github.com/easyops-cn/next-core/tree/v3/packages/easyops-runtime",
5
5
  "license": "GPL-3.0",
6
6
  "repository": {
@@ -49,7 +49,7 @@
49
49
  "@next-core/cook": "^2.5.12",
50
50
  "@next-core/http": "^1.2.14",
51
51
  "@next-core/pipes": "^2.0.36",
52
- "@next-core/runtime": "^1.72.2",
52
+ "@next-core/runtime": "^1.72.3",
53
53
  "@next-core/types": "^1.19.0",
54
54
  "@next-core/utils": "^1.8.9",
55
55
  "js-yaml": "^3.14.1",
@@ -61,5 +61,5 @@
61
61
  "jest-websocket-mock": "^2.5.0",
62
62
  "whatwg-fetch": "^3.6.20"
63
63
  },
64
- "gitHead": "8b56a7ae267ef34303a936bd380cec6568206854"
64
+ "gitHead": "9943d00dfa9228c45a10362013cfc10103f771a3"
65
65
  }