后端迁移云触手请求与目录服务
This commit is contained in:
+13
-13
@@ -1,10 +1,10 @@
|
||||
// @ts-check
|
||||
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { cloudtentaclesRequest } from './http-client.js'
|
||||
import { resolveCloudtentaclesConfig } from './shared.js'
|
||||
|
||||
export async function getCloudtentaclesAsset(payload = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function getCloudtentaclesAsset(payload: JsonObject = {}) {
|
||||
const token = requireToken(payload.token, 'cloudtentacles 余额查询缺少 token', 'cloudtentacles_asset_missing_token')
|
||||
const config = resolveCloudtentaclesConfig(payload)
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function getCloudtentaclesAsset(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCloudtentaclesCategories(payload = {}) {
|
||||
export async function getCloudtentaclesCategories(payload: JsonObject = {}) {
|
||||
const token = requireToken(payload.token, 'cloudtentacles 分类查询缺少 token', 'cloudtentacles_categories_missing_token')
|
||||
const config = resolveCloudtentaclesConfig(payload)
|
||||
|
||||
@@ -47,7 +47,7 @@ export async function getCloudtentaclesCategories(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function listCloudtentaclesSku(payload = {}) {
|
||||
export async function listCloudtentaclesSku(payload: JsonObject = {}) {
|
||||
const token = requireToken(payload.token, 'cloudtentacles SKU 列表查询缺少 token', 'cloudtentacles_sku_list_missing_token')
|
||||
const config = resolveCloudtentaclesConfig(payload)
|
||||
|
||||
@@ -70,7 +70,7 @@ export async function listCloudtentaclesSku(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function buyCloudtentaclesSku(payload = {}) {
|
||||
export async function buyCloudtentaclesSku(payload: JsonObject = {}) {
|
||||
const token = requireToken(payload.token, 'cloudtentacles 购买 SKU 缺少 token', 'cloudtentacles_sku_buy_missing_token')
|
||||
const skuId = requireId(payload.id, 'cloudtentacles 购买 SKU 缺少商品 id', 'cloudtentacles_sku_buy_missing_id')
|
||||
const count = requireCount(payload.count)
|
||||
@@ -96,7 +96,7 @@ export async function buyCloudtentaclesSku(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function useCloudtentaclesSku(payload = {}) {
|
||||
export async function useCloudtentaclesSku(payload: JsonObject = {}) {
|
||||
const token = requireToken(payload.token, 'cloudtentacles 发货缺少 token', 'cloudtentacles_sku_use_missing_token')
|
||||
const skuId = requireId(payload.id, 'cloudtentacles 发货缺少商品 id', 'cloudtentacles_sku_use_missing_id')
|
||||
const virtualNumberId = requireId(
|
||||
@@ -140,7 +140,7 @@ export async function useCloudtentaclesSku(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapCategoryItem(item) {
|
||||
function mapCategoryItem(item: unknown) {
|
||||
const source = isPlainObject(item) ? item : {}
|
||||
|
||||
return {
|
||||
@@ -158,7 +158,7 @@ function mapCategoryItem(item) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapSkuItem(item) {
|
||||
function mapSkuItem(item: unknown) {
|
||||
const source = isPlainObject(item) ? item : {}
|
||||
|
||||
return {
|
||||
@@ -177,7 +177,7 @@ function mapSkuItem(item) {
|
||||
}
|
||||
}
|
||||
|
||||
function requireToken(value, message, errorCode) {
|
||||
function requireToken(value: unknown, message: string, errorCode: string) {
|
||||
const token = String(value || '').trim()
|
||||
if (!token) {
|
||||
throw createHttpError(message, {
|
||||
@@ -189,7 +189,7 @@ function requireToken(value, message, errorCode) {
|
||||
return token
|
||||
}
|
||||
|
||||
function requireId(value, message, errorCode) {
|
||||
function requireId(value: unknown, message: string, errorCode: string) {
|
||||
const id = Number(value)
|
||||
if (!Number.isInteger(id) || id <= 0) {
|
||||
throw createHttpError(message, {
|
||||
@@ -201,7 +201,7 @@ function requireId(value, message, errorCode) {
|
||||
return id
|
||||
}
|
||||
|
||||
function requireCount(value) {
|
||||
function requireCount(value: unknown) {
|
||||
const count = Number(value)
|
||||
if (!Number.isInteger(count) || count <= 0) {
|
||||
throw createHttpError('cloudtentacles 购买数量无效', {
|
||||
@@ -213,6 +213,6 @@ function requireCount(value) {
|
||||
return count
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||
}
|
||||
+32
-14
@@ -1,5 +1,3 @@
|
||||
// @ts-check
|
||||
|
||||
import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
|
||||
@@ -8,9 +6,21 @@ import { logInfo } from '../../../utils/logger.js'
|
||||
import { notifyCloudtentaclesAuthExpired } from '../../notification/domain-notifications.js'
|
||||
import { buildCloudtentaclesHeaders, buildCloudtentaclesUrl, resolveCloudtentaclesConfig } from './shared.js'
|
||||
|
||||
export async function cloudtentaclesRequest(pathname, options = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
type HeaderAdapter = {
|
||||
get(name: unknown): string | null
|
||||
}
|
||||
type NodeHttpResponse = {
|
||||
ok: boolean
|
||||
status: number
|
||||
headers: HeaderAdapter
|
||||
bodyText: string
|
||||
}
|
||||
|
||||
export async function cloudtentaclesRequest(pathname: unknown, options: JsonObject = {}) {
|
||||
const normalizedPathname = String(pathname || '').trim()
|
||||
const config = resolveCloudtentaclesConfig(options)
|
||||
const url = buildCloudtentaclesUrl(config.baseUrl, pathname, options.searchParams)
|
||||
const url = buildCloudtentaclesUrl(config.baseUrl, normalizedPathname, options.searchParams)
|
||||
const timeoutMs = Number(options.timeoutMs || config.timeoutMs || 5000)
|
||||
const controller = new AbortController()
|
||||
const timer = setTimeout(() => controller.abort(), timeoutMs)
|
||||
@@ -48,7 +58,7 @@ export async function cloudtentaclesRequest(pathname, options = {}) {
|
||||
|
||||
if (statusCode === 401 || isCloudtentaclesExpiredMessage(message)) {
|
||||
await notifyCloudtentaclesAuthExpired({
|
||||
pathname,
|
||||
pathname: normalizedPathname,
|
||||
errorCode,
|
||||
message,
|
||||
})
|
||||
@@ -62,7 +72,7 @@ export async function cloudtentaclesRequest(pathname, options = {}) {
|
||||
|
||||
logInfo('[cloudtentacles/http]', '请求完成', {
|
||||
method,
|
||||
pathname,
|
||||
pathname: normalizedPathname,
|
||||
status: response.status,
|
||||
})
|
||||
|
||||
@@ -86,12 +96,12 @@ export async function cloudtentaclesRequest(pathname, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function isCloudtentaclesExpiredMessage(message) {
|
||||
function isCloudtentaclesExpiredMessage(message: unknown) {
|
||||
const normalized = String(message || '').trim().toLowerCase()
|
||||
return normalized.includes('expired') || normalized.includes('过期') || normalized.includes('失效')
|
||||
}
|
||||
|
||||
function inferContentType(body) {
|
||||
function inferContentType(body: unknown) {
|
||||
if (body == null) {
|
||||
return ''
|
||||
}
|
||||
@@ -103,7 +113,7 @@ function inferContentType(body) {
|
||||
return 'application/json'
|
||||
}
|
||||
|
||||
function normalizeRequestBody(body, contentType) {
|
||||
function normalizeRequestBody(body: unknown, contentType: unknown) {
|
||||
if (body == null) {
|
||||
return undefined
|
||||
}
|
||||
@@ -119,7 +129,7 @@ function normalizeRequestBody(body, contentType) {
|
||||
return String(body)
|
||||
}
|
||||
|
||||
function tryParseJson(text) {
|
||||
function tryParseJson(text: string) {
|
||||
try {
|
||||
return JSON.parse(text)
|
||||
} catch {
|
||||
@@ -127,7 +137,15 @@ function tryParseJson(text) {
|
||||
}
|
||||
}
|
||||
|
||||
async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
async function requestViaNodeHttp(
|
||||
url: URL,
|
||||
{ method, headers, body, signal }: {
|
||||
method: string
|
||||
headers: JsonObject
|
||||
body?: string | URLSearchParams
|
||||
signal?: AbortSignal
|
||||
},
|
||||
): Promise<NodeHttpResponse> {
|
||||
const isHttps = url.protocol === 'https:'
|
||||
const transport = isHttps ? https : http
|
||||
|
||||
@@ -137,7 +155,7 @@ async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
headers,
|
||||
rejectUnauthorized: false,
|
||||
}, (response) => {
|
||||
const chunks = []
|
||||
const chunks: Buffer[] = []
|
||||
|
||||
response.on('data', (chunk) => {
|
||||
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
|
||||
@@ -178,7 +196,7 @@ async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
})
|
||||
}
|
||||
|
||||
function createHeaderAdapter(headers) {
|
||||
function createHeaderAdapter(headers: http.IncomingHttpHeaders): HeaderAdapter {
|
||||
const normalized = new Map()
|
||||
|
||||
for (const [key, value] of Object.entries(headers || {})) {
|
||||
@@ -193,7 +211,7 @@ function createHeaderAdapter(headers) {
|
||||
}
|
||||
|
||||
return {
|
||||
get(name) {
|
||||
get(name: unknown) {
|
||||
return normalized.get(String(name || '').toLowerCase()) || null
|
||||
},
|
||||
}
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
// @ts-check
|
||||
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { cloudtentaclesRequest } from './http-client.js'
|
||||
import { resolveCloudtentaclesConfig } from './shared.js'
|
||||
|
||||
export async function getCloudtentaclesKnapsack(payload = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function getCloudtentaclesKnapsack(payload: JsonObject = {}) {
|
||||
const token = String(payload.token || '').trim()
|
||||
if (!token) {
|
||||
throw createHttpError('cloudtentacles 背包查询缺少 token', {
|
||||
@@ -33,7 +33,7 @@ export async function getCloudtentaclesKnapsack(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapKnapsackItem(item) {
|
||||
function mapKnapsackItem(item: unknown) {
|
||||
const source = isPlainObject(item) ? item : {}
|
||||
|
||||
return {
|
||||
@@ -48,6 +48,6 @@ function mapKnapsackItem(item) {
|
||||
}
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||
}
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
// @ts-check
|
||||
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { logInfo } from '../../../utils/logger.js'
|
||||
import { encryptCloudtentaclesPayload, md5CloudtentaclesPassword } from './crypto-service.js'
|
||||
import { cloudtentaclesRequest } from './http-client.js'
|
||||
import { resolveCloudtentaclesConfig } from './shared.js'
|
||||
|
||||
export async function sendCloudtentaclesSmsCode(payload = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function sendCloudtentaclesSmsCode(payload: JsonObject = {}) {
|
||||
const username = String(payload.username || '').trim()
|
||||
const phone = String(payload.phone || '').trim()
|
||||
|
||||
@@ -56,7 +56,7 @@ export async function sendCloudtentaclesSmsCode(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function loginCloudtentaclesSession(payload = {}) {
|
||||
export async function loginCloudtentaclesSession(payload: JsonObject = {}) {
|
||||
const username = String(payload.username || '').trim()
|
||||
const password = String(payload.password || '').trim()
|
||||
const phone = String(payload.phone || '').trim()
|
||||
@@ -131,7 +131,7 @@ export async function loginCloudtentaclesSession(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function validateCloudtentaclesSession(payload = {}) {
|
||||
export async function validateCloudtentaclesSession(payload: JsonObject = {}) {
|
||||
const token = String(payload.token || '').trim()
|
||||
|
||||
if (!token) {
|
||||
@@ -181,7 +181,7 @@ export async function validateCloudtentaclesSession(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function maskPhone(phone) {
|
||||
function maskPhone(phone: unknown) {
|
||||
const normalized = String(phone || '').trim()
|
||||
if (normalized.length < 7) {
|
||||
return normalized
|
||||
@@ -190,6 +190,6 @@ function maskPhone(phone) {
|
||||
return `${normalized.slice(0, 3)}****${normalized.slice(-4)}`
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||
}
|
||||
Reference in New Issue
Block a user