chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -32,8 +32,8 @@ struct UserDeleteDataMap {
|
||||
We
|
||||
*/
|
||||
enum AvatarMetaType {
|
||||
UNKNOWN = 0, // 没有数据, 错误数据或者系统错误降级
|
||||
RANDOM = 1, // 在修改 or 创建时,用户未指定 name 或者选中推荐的文字时,程序随机选择的头像
|
||||
UNKNOWN = 0, // No data, incorrect data, or system error downgrade
|
||||
RANDOM = 1, // When modifying or creating, the user does not specify a name or select the recommended text, the program randomly selects the avatar
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ enum Gender {
|
||||
}
|
||||
|
||||
// const map<Gender, string> genderMap = {
|
||||
// Gender.Male: '男性',
|
||||
// Gender.Female: '女性',
|
||||
// Gender. Male: 'Male',
|
||||
// Gender. Female: 'Female',
|
||||
// }
|
||||
|
||||
union FuncRequest {
|
||||
|
||||
@@ -686,7 +686,7 @@ function convertFieldDefinition(
|
||||
if (!isProto3) {
|
||||
requiredness = optional ? 'optional' : 'required';
|
||||
} else if (rule === 'required') {
|
||||
// TODO: 处理 optional 的情况,需要修改 proto-parser
|
||||
// TODO: Handle optional cases, need to modify proto-parser
|
||||
requiredness = 'required';
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ function requiredWithoutCache(src, onError?) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { Module } = require('module');
|
||||
try {
|
||||
// disable 了 require 的缓存,这样可以改变了 mock 数据后,无需重启服务。
|
||||
// Disable the required cache so that you can change the mock data without restarting the service.
|
||||
const originCache = Module._cache;
|
||||
Module._cache = {};
|
||||
// eslint-disable-next-line security/detect-non-literal-require, @typescript-eslint/no-require-imports
|
||||
|
||||
@@ -186,7 +186,7 @@ export class FilterTypesPlugin {
|
||||
} else if (isIdentifier(fieldType)) {
|
||||
const statement = getStatementById(fieldType, current);
|
||||
if (isEnumDefinition(statement)) {
|
||||
// 强制转位 number
|
||||
// Forced indexing number
|
||||
// @ts-expect-error fixme late
|
||||
fieldType.type = SyntaxType.I32Keyword;
|
||||
let namespace = current.unifyNamespace;
|
||||
|
||||
@@ -55,15 +55,15 @@ export class MockPlugin implements IPlugin {
|
||||
if (context) {
|
||||
const { fieldDefinition } = context;
|
||||
const fieldName = fieldDefinition.name.value;
|
||||
// 各类 ID
|
||||
// various types of ID
|
||||
if (fieldName.toLocaleUpperCase().endsWith('ID')) {
|
||||
value = String(faker.number.int());
|
||||
}
|
||||
// email 处理
|
||||
// Email processing
|
||||
if (fieldName.includes('Email')) {
|
||||
value = `${faker.person.lastName()}@foo.com`;
|
||||
}
|
||||
// 直接映射值
|
||||
// direct mapping value
|
||||
value = StrMapper[fieldName] || value;
|
||||
}
|
||||
ctx.output = t.stringLiteral(value);
|
||||
@@ -76,20 +76,20 @@ export class MockPlugin implements IPlugin {
|
||||
const { fieldDefinition } = context;
|
||||
const fieldName = fieldDefinition.name.value;
|
||||
const formatName = fieldName.toLocaleUpperCase();
|
||||
// 各类 ID
|
||||
// various types of ID
|
||||
if (formatName.endsWith('ID')) {
|
||||
value = faker.number.int();
|
||||
}
|
||||
// 时间戳
|
||||
// timestamp
|
||||
if (formatName.endsWith('TIME') || formatName.includes('TIMESTAMP')) {
|
||||
value = dayjs(faker.date.anytime()).valueOf();
|
||||
}
|
||||
// 类型状态
|
||||
// type state
|
||||
if (formatName.endsWith('STATUS') || formatName.includes('TYPE')) {
|
||||
value = faker.number.int({ min: 0, max: 1 });
|
||||
}
|
||||
|
||||
// 直接映射值
|
||||
// direct mapping value
|
||||
const mapVal = NumMapper[fieldName];
|
||||
value = typeof mapVal !== 'undefined' ? mapVal : value;
|
||||
}
|
||||
|
||||
@@ -17,27 +17,27 @@
|
||||
import { type IPlugin } from '@coze-arch/idl2ts-generator';
|
||||
|
||||
export interface ApiConfig {
|
||||
// idl 入口
|
||||
// IDL entrance
|
||||
entries: Record<string, string>;
|
||||
// idl 根目录
|
||||
// IDL root directory
|
||||
idlRoot: string;
|
||||
// 服务别名
|
||||
// 自定义 api 方法
|
||||
// service alias
|
||||
// Custom API method
|
||||
commonCodePath: string;
|
||||
// api 产物目录
|
||||
// API Product Catalog
|
||||
output: string;
|
||||
// 仓库信息设置
|
||||
// Warehouse information settings
|
||||
repository?: {
|
||||
// 仓库地址
|
||||
// Warehouse address
|
||||
url: string;
|
||||
// clone 到本地的位置
|
||||
// Clone to local location
|
||||
dest: string;
|
||||
};
|
||||
// 插件
|
||||
// plugin
|
||||
plugins?: IPlugin[];
|
||||
// 聚合导出的文件名
|
||||
// aggregate exported filename
|
||||
aggregationExport?: string;
|
||||
// 格式化文件
|
||||
// Format file
|
||||
formatter: (name: string, content: string) => string;
|
||||
idlFetchConfig?: {
|
||||
source: string;
|
||||
@@ -48,6 +48,6 @@ export interface ApiConfig {
|
||||
}
|
||||
|
||||
export interface ApiTypeConfig extends ApiConfig {
|
||||
// 需要过滤的方法
|
||||
// Methods that require filtering
|
||||
filters: Record<string, string[]>;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export class ClientGenerator {
|
||||
|
||||
private processIdlAst(ast: IParseResultItem) {
|
||||
try {
|
||||
// 新的解析器貌似不是按原来位置排序的,这里要重新排序
|
||||
// The new parser doesn't seem to be sorted by the original position, so it needs to be reordered here.
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
ast.statements.sort((a, b) => a.loc!.start.line - b.loc!.start.line);
|
||||
} catch (error) {
|
||||
|
||||
@@ -139,14 +139,14 @@ export class AdapterPlugin implements IPlugin {
|
||||
getAnnotation(f.annotations, 'api.converter') === 'atoi_comp_empty'
|
||||
) {
|
||||
if (isInt(f.fieldType)) {
|
||||
// 类型转换为 string
|
||||
// Type conversion to string
|
||||
f.fieldType.type = SyntaxType.StringKeyword;
|
||||
}
|
||||
}
|
||||
// api.converter 对 int 以及 map 类型生效
|
||||
// Api.converter works for int and map types
|
||||
if (getAnnotation(f.annotations, 'api.converter') === 'itoa') {
|
||||
if (isInt(f.fieldType)) {
|
||||
// 类型转换为 string
|
||||
// Type conversion to string
|
||||
f.fieldType.type = SyntaxType.StringKeyword;
|
||||
}
|
||||
if (isMapType(f.fieldType)) {
|
||||
@@ -156,7 +156,7 @@ export class AdapterPlugin implements IPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
// item_converter 对 list 类型生效
|
||||
// item_converter for list types
|
||||
if (
|
||||
['atoi_comp_empty', 'itoa'].includes(
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
@@ -168,24 +168,24 @@ export class AdapterPlugin implements IPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
// 收集 decode encode 注解处理
|
||||
// Collection decoding encoding annotation processing
|
||||
if (getTypeFromDynamicJsonAnnotation(f.annotations)) {
|
||||
decodeEncodeFields.push(f.name.value);
|
||||
}
|
||||
// api.json 注解处理
|
||||
// api.json annotation processing
|
||||
const jsonAnnotation = getAnnotation(f.annotations, 'api.json');
|
||||
if (jsonAnnotation) {
|
||||
f.extensionConfig = f.extensionConfig || {};
|
||||
f.extensionConfig.key = jsonAnnotation;
|
||||
}
|
||||
// api.json_string 注解处理
|
||||
// API. json_string annotation handling
|
||||
const jsonStrAnnotation = getAnnotation(
|
||||
f.annotations,
|
||||
'api.json_string',
|
||||
);
|
||||
if (jsonStrAnnotation) {
|
||||
if (isInt(f.fieldType)) {
|
||||
// 类型转换为 string
|
||||
// Type conversion to string
|
||||
f.fieldType.type = SyntaxType.StringKeyword;
|
||||
f.extensionConfig = f.extensionConfig || {};
|
||||
f.extensionConfig.key = jsonStrAnnotation;
|
||||
|
||||
@@ -403,7 +403,7 @@ export class ClientPlugin implements IPlugin {
|
||||
});
|
||||
const enumAst = t.tsEnumDeclaration(t.identifier(name.value), enumArr);
|
||||
|
||||
// 从后向前删除枚举项,避免索引变化影响
|
||||
// Delete enumeration items from back to front to avoid the impact of index changes
|
||||
enumItemIndexArray
|
||||
.sort((a, b) => b - a)
|
||||
.forEach(index => {
|
||||
|
||||
@@ -21,7 +21,7 @@ import { type Contexts, HOOK } from '../context';
|
||||
|
||||
const MAGIC_COMMENT_KEY = '\n*@magic-comment';
|
||||
|
||||
// 忽略 struct 中的字段
|
||||
// Ignore fields in struct
|
||||
export class CommentFormatPlugin {
|
||||
apply(p: Program<Contexts>) {
|
||||
p.register(after('PARSE_ENTRY'), ctx => {
|
||||
|
||||
@@ -26,7 +26,7 @@ interface IPops {
|
||||
filter: Filter;
|
||||
}
|
||||
|
||||
// 忽略 struct 中的字段
|
||||
// Ignore fields in struct
|
||||
export class IgnoreStructFiledPlugin {
|
||||
private filter: Filter;
|
||||
constructor({ filter }: IPops) {
|
||||
|
||||
@@ -56,7 +56,7 @@ export class MetaPlugin implements IPlugin {
|
||||
ctx => {
|
||||
const node = ctx.node as ServiceDefinition;
|
||||
node.functions.forEach(fun => {
|
||||
// 过滤非泛化接口
|
||||
// Filtering non-generalized interfaces
|
||||
if (!fun.extensionConfig?.method) {
|
||||
return;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ export class MetaPlugin implements IPlugin {
|
||||
schemaRoot: getSchemaRootByPath(ast.idlPath, this.options.idlRoot),
|
||||
service,
|
||||
} as IMeta;
|
||||
// 不是 json 时,需要加上 serializer 标识
|
||||
// When not json, you need to add the serializer flag.
|
||||
if (extensionConfig?.serializer && extensionConfig?.serializer !== 'json') {
|
||||
res.serializer = extensionConfig?.serializer;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ export class MetaPlugin implements IPlugin {
|
||||
if (isStructDefinition(statement)) {
|
||||
const wholeBody = statement.fields.find(isFullBody);
|
||||
if (wholeBody) {
|
||||
// 处理 api.body="." 以及 api.full_body=''
|
||||
// Handle api.body = "." and api.full_body = "
|
||||
return `${id.value}['${getFieldsAlias(wholeBody)}']`;
|
||||
} else {
|
||||
return id.value;
|
||||
@@ -184,7 +184,7 @@ export class MetaPlugin implements IPlugin {
|
||||
}
|
||||
});
|
||||
}
|
||||
// 如果没有指定,根据method默认指定为query 或者 body
|
||||
// If not specified, it is specified as query or body by default according to method.
|
||||
if (!specificPositionFiled.has(alias)) {
|
||||
const filedMapping = mapping[defaultPosition];
|
||||
mapping[defaultPosition] = filedMapping
|
||||
|
||||
@@ -110,7 +110,7 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
nextOrder[name] = index;
|
||||
}
|
||||
});
|
||||
// 按照 mock 文件中的顺序优先排序
|
||||
// Prioritize in order in the mock file
|
||||
const getOrder = (name: string) =>
|
||||
typeof mockVarOrder[name] !== 'undefined'
|
||||
? mockVarOrder[name]
|
||||
@@ -210,7 +210,7 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
if (isStructDefinition(statement)) {
|
||||
const wholeBody = statement.fields.find(isFullBody);
|
||||
if (wholeBody) {
|
||||
// 处理 api.body="."
|
||||
// Processing api.body = "."
|
||||
const { annotations } = wholeBody;
|
||||
if (hasDynamicJsonAnnotation(annotations)) {
|
||||
return '{}';
|
||||
@@ -273,7 +273,7 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
if (!fieldNames.has(fieldName)) {
|
||||
return;
|
||||
}
|
||||
// 没有的,需要重新生成
|
||||
// No, it needs to be regenerated.
|
||||
newPros.push(
|
||||
t.objectProperty(
|
||||
fieldName.includes('-')
|
||||
@@ -351,11 +351,11 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
const { valueType } = fieldType;
|
||||
output = t.arrayExpression([this.processValue(valueType)]);
|
||||
} else if (isSetType(fieldType)) {
|
||||
// set 处理成array校验
|
||||
// Set to array validation
|
||||
const { valueType } = fieldType;
|
||||
output = t.arrayExpression([this.processValue(valueType)]);
|
||||
} else if (isIdentifier(fieldType)) {
|
||||
// 引用类型
|
||||
// reference type
|
||||
const { refName, namespace } = parseIdFiledType(fieldType);
|
||||
if (!namespace) {
|
||||
output = t.callExpression(t.identifier(refName), []);
|
||||
@@ -375,7 +375,7 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
throw new Error(`can not process fieldType : ${fieldType.type}`);
|
||||
}
|
||||
private processConst(constVal: ConstValue) {
|
||||
// 暂时统一处理成0
|
||||
// Temporarily unified processing to 0
|
||||
if (isStringLiteral(constVal)) {
|
||||
return t.stringLiteral(constVal.value);
|
||||
}
|
||||
@@ -410,11 +410,11 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
const comment = { type: 'CommentLine', value: commentValues } as any;
|
||||
const target = this.findTarget(name.value, ctx);
|
||||
if (target) {
|
||||
// 需要更新注释
|
||||
// Comments need to be updated
|
||||
// target.trailingComments = [comment];
|
||||
return;
|
||||
}
|
||||
// 枚举类型统一处理成常量
|
||||
// Enumeration types are uniformly processed into constants
|
||||
const builder = template(`var ${name.value}= () => %%value%% `);
|
||||
const node = builder({
|
||||
value: t.numericLiteral(values[0] || 0),
|
||||
@@ -437,7 +437,7 @@ export class MockTransformerPlugin implements IPlugin {
|
||||
// const variableDeclaration = t.addComment(
|
||||
// ,
|
||||
// 'leading',
|
||||
// '暂时对const默认处理为0,如有需要请自行重新赋值'
|
||||
// 'Temporarily, the default processing for const is 0, please reassign it yourself if necessary '
|
||||
// );
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import { type Options } from '../types';
|
||||
import { type Contexts, HOOK } from '../context';
|
||||
|
||||
/**
|
||||
* 提供统一 api 入口
|
||||
* Provide unified API entry
|
||||
*/
|
||||
export class PkgEntryPlugin implements IPlugin {
|
||||
private options: Options;
|
||||
@@ -52,7 +52,7 @@ export class PkgEntryPlugin implements IPlugin {
|
||||
);
|
||||
this.funcs.set(
|
||||
relativePath,
|
||||
// 只支持单 service
|
||||
// Only single service supported
|
||||
meta[0].service,
|
||||
);
|
||||
return ctx;
|
||||
|
||||
@@ -223,7 +223,7 @@ export class SchemaPlugin implements IPlugin {
|
||||
};
|
||||
return schema;
|
||||
} else if (isSetType(fieldType)) {
|
||||
// set 处理成array校验
|
||||
// Set to array validation
|
||||
const { valueType } = fieldType;
|
||||
const schema: ListType = {
|
||||
type: 'array',
|
||||
@@ -231,7 +231,7 @@ export class SchemaPlugin implements IPlugin {
|
||||
};
|
||||
return schema;
|
||||
} else if (isIdentifier(fieldType)) {
|
||||
// 引用类型
|
||||
// reference type
|
||||
const { refName, namespace } = parseIdFiledType(fieldType);
|
||||
if (!namespace) {
|
||||
const schema: RefType = { $ref: `#/definitions/${refName}` };
|
||||
@@ -249,7 +249,7 @@ export class SchemaPlugin implements IPlugin {
|
||||
throw new Error(`can not process fieldType : ${fieldType.type}`);
|
||||
}
|
||||
private processConst(constVal: ConstValue) {
|
||||
// 暂时统一处理成0
|
||||
// Temporarily unified processing to 0
|
||||
const schema = {} as ConstType;
|
||||
if (isStringLiteral(constVal)) {
|
||||
schema.const = constVal.value;
|
||||
|
||||
@@ -29,11 +29,11 @@ export interface Options {
|
||||
genMock: boolean;
|
||||
genClient: boolean;
|
||||
entryName?: string;
|
||||
// createAPI 所在文件路径
|
||||
// createAPI file path
|
||||
commonCodePath?: string;
|
||||
// decode encode 会丢失类型,这里提供一种方式,业务手动补充上对应的类型
|
||||
// Decoding encoding will lose the type, here provides a way to manually add the corresponding type
|
||||
patchTypesOutput?: string;
|
||||
// patchTypesOutput 的别名,patch type 需要使用额外的 pkg 组织时需要提供
|
||||
// PatchTypesOutput alias, patch type needs to be provided when using additional pkg organization
|
||||
patchTypesAliasOutput?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ export interface IMeta {
|
||||
type Fields = string[];
|
||||
|
||||
export interface IHttpRpcMapping {
|
||||
path?: Fields; // path参数
|
||||
query?: Fields; // query参数
|
||||
body?: Fields; // body 参数
|
||||
header?: Fields; // header 参数
|
||||
status_code?: Fields; // http状态码
|
||||
path?: Fields; // path parameter
|
||||
query?: Fields; // query parameters
|
||||
body?: Fields; // Body parameters
|
||||
header?: Fields; // header parameter
|
||||
status_code?: Fields; // HTTP status code
|
||||
cookie?: Fields; // cookie
|
||||
entire_body?: Fields;
|
||||
raw_body?: Fields;
|
||||
|
||||
@@ -68,7 +68,7 @@ export function formatCode(code: string, root = '.') {
|
||||
printWidth: 120,
|
||||
singleQuote: true,
|
||||
};
|
||||
const file = path.resolve(process.cwd(), root, './for-prettier-bug'); // 这里一定要加多一级目录
|
||||
const file = path.resolve(process.cwd(), root, './for-prettier-bug'); // Be sure to add an extra level catalog here.
|
||||
const config = prettier.resolveConfig(file, { editorconfig: true });
|
||||
return prettier.format(code, {
|
||||
...(config || defaultConfig),
|
||||
@@ -166,7 +166,7 @@ export function parseId(id: string) {
|
||||
|
||||
export function uniformNs(ns: string) {
|
||||
if (ReservedKeyWord.includes(ns)) {
|
||||
// 命中保留字,处理为下划线开头
|
||||
// Hit the reserved word, treated as an underscore
|
||||
return `_${ns}`;
|
||||
}
|
||||
return ns.replace(/\./g, '_');
|
||||
@@ -182,7 +182,7 @@ export function getValuesFromEnum(params: h.EnumDefinition) {
|
||||
if (h.isIntegerLiteral(initializer.value)) {
|
||||
currentVal = Number(initializer.value.value);
|
||||
} else if (h.isHexLiteral(initializer.value)) {
|
||||
// 16进制
|
||||
// hexadecimal
|
||||
currentVal = Number(initializer.value.value);
|
||||
}
|
||||
enumArr.push(currentVal);
|
||||
@@ -322,8 +322,8 @@ export function hasDynamicJsonAnnotation(annotations?: h.Annotations) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 api.(request|response).converter 中解析出前端与网关之间的真实类型,
|
||||
* 能搞出这两个注解来,这个协议着实恶心😭
|
||||
* Parse the real type between the front end and the gateway from api. (request | response).converter.
|
||||
* To be able to come up with these two annotations, this protocol is disgusting😭
|
||||
* @param annotations
|
||||
* @returns
|
||||
*/
|
||||
|
||||
@@ -42,7 +42,7 @@ export class Program<C extends Ctxs = any> {
|
||||
} = {};
|
||||
|
||||
/**
|
||||
* 加载插件
|
||||
* Load plugin
|
||||
* @param plugins
|
||||
*/
|
||||
loadPlugins(plugins: IPlugin[]) {
|
||||
@@ -51,10 +51,10 @@ export class Program<C extends Ctxs = any> {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 注册钩子
|
||||
* @param event 事件名称
|
||||
* @param handler 钩子
|
||||
* @param priority 优先级,数值越小,优先级越高
|
||||
* registration hook
|
||||
* @param event name
|
||||
* @param handler hook
|
||||
* @Param priority, the smaller the value, the higher the priority
|
||||
*/
|
||||
register<
|
||||
K extends keyof C,
|
||||
@@ -87,7 +87,7 @@ export class Program<C extends Ctxs = any> {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 触发事件
|
||||
* trigger event
|
||||
* @param event
|
||||
* @param args
|
||||
* @returns
|
||||
|
||||
@@ -20,20 +20,20 @@ import type { IMeta, CustomAPIMeta } from './types';
|
||||
export interface ApiLike<T, K, O = unknown, B extends boolean = false> {
|
||||
(req: T, option?: O extends object ? IOptions & O : IOptions): Promise<K>;
|
||||
meta: IMeta;
|
||||
/** fork 一份实例,该实例具有可中止请求的能力 */
|
||||
/** Fork an instance that has the ability to abort requests */
|
||||
withAbort: () => CancelAbleApi<T, K, O, B>;
|
||||
}
|
||||
|
||||
export interface CancelAbleApi<T, K, O = unknown, B extends boolean = false>
|
||||
extends ApiLike<T, K, O, B> {
|
||||
// 中止请求
|
||||
// abort request
|
||||
abort: () => void;
|
||||
// 是否是取消
|
||||
// Is it cancelled?
|
||||
isAborted: () => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义构建 api 方法
|
||||
* Custom build API method
|
||||
* @param meta
|
||||
* @param cancelable
|
||||
* @param useCustom
|
||||
@@ -56,7 +56,7 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
|
||||
|
||||
option = { ...(option || {}), ...customOption };
|
||||
|
||||
// 这里可以使用传进来的 req 作为默认映射,减少需要在 customAPI 中,需要手动绑定的情况
|
||||
// Here, you can use the incoming req as the default mapping to reduce the need for manual binding in the customAPI
|
||||
if (useCustom) {
|
||||
const mappingKeys: string[] = Object.keys(meta.reqMapping)
|
||||
.map(key => meta.reqMapping[key])
|
||||
@@ -98,12 +98,12 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
|
||||
|
||||
function abort() {
|
||||
/**
|
||||
* 这里加上 pending 状态的原因是,abortController.signal 的状态值只受控于 abortController.abort() 方法;
|
||||
* 不管请求是否完成或者异常,只要调用 abortController.abort(), abortController.signal.aborted 必定为 true,
|
||||
* 这样不好判断请求是否真 aborted;
|
||||
* The reason for adding the pending state here is that the state value of abortController.signal is only controlled by the abortController.abort () method;
|
||||
* No matter whether the request is completed or abnormal, as long as abortController.abort () is called, abortController.signal.aborted must be true.
|
||||
* This makes it difficult to determine whether the request is really aborted.
|
||||
*
|
||||
* 这里改为,只有在请求 pending 的情况下,可执行 abort(),
|
||||
* isAborted === true 时,请求异常必定是因为手动 abort 导致的
|
||||
* This is changed to abort () only if the request is pending.
|
||||
* When isAborted === true, the request exception must be caused by manual abort
|
||||
*/
|
||||
if (pending === true && cancelable && abortController) {
|
||||
abortController.abort();
|
||||
@@ -128,7 +128,7 @@ export function createAPI<T extends {}, K, O = unknown, B extends boolean = fals
|
||||
}
|
||||
|
||||
/**
|
||||
* 一些非泛化的接口,可以使用改方法构建,方便统一管理接口
|
||||
* Some non-generalized interfaces can be built using modified methods to facilitate unified management of interfaces
|
||||
* @param customAPIMeta
|
||||
* @param cancelable
|
||||
* @returns
|
||||
|
||||
@@ -30,11 +30,11 @@ export interface IMeta {
|
||||
type Fields = string[];
|
||||
|
||||
export interface IHttpRpcMapping {
|
||||
path?: Fields; // path参数
|
||||
query?: Fields; // query参数
|
||||
body?: Fields; // body 参数
|
||||
header?: Fields; // header 参数
|
||||
status_code?: Fields; // http状态码
|
||||
path?: Fields; // path parameter
|
||||
query?: Fields; // query parameters
|
||||
body?: Fields; // Body parameters
|
||||
header?: Fields; // header parameter
|
||||
status_code?: Fields; // HTTP status code
|
||||
cookie?: Fields; // cookie
|
||||
entire_body?: Fields;
|
||||
raw_body?: Fields;
|
||||
|
||||
@@ -27,22 +27,22 @@ export interface ServiceConfig {
|
||||
} & Omit<IdlConfig, 'clientFactory'>;
|
||||
}
|
||||
export interface IdlConfig {
|
||||
// client 工厂方法,要求返回一个 fetchClient 函数,使用 meta 总的信息,可实现灵活的 client 配置
|
||||
// The client factory method requires a fetchClient function to be returned, which uses the meta total information to achieve flexible client configuration
|
||||
clientFactory?: (
|
||||
meta: IMeta,
|
||||
) => (uri: string, init: RequestInit, opt: any) => any;
|
||||
// uri 前缀,如果 client 中设置了,这里可以不设置
|
||||
// URI prefix, if set in client, you can leave it unset here
|
||||
uriPrefix?: string;
|
||||
getParams?: (key: string) => string;
|
||||
// 服务级别的配置
|
||||
// Service level configuration
|
||||
services?: ServiceConfig;
|
||||
// 开发时,如果本地校验失败,这里可回调,通常是弹 toast
|
||||
// During development, if the local verification fails, it can be called back here, usually by playing toast.
|
||||
onVerifyReqError?: (message: string, ctx: any) => void;
|
||||
}
|
||||
|
||||
export interface IOptions {
|
||||
config?: IdlConfig;
|
||||
// 透传 request options 的选项
|
||||
// Passthrough request options
|
||||
requestOptions?: Record<string, any>;
|
||||
[key: string]: any;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ export interface PathPrams<T> {
|
||||
}
|
||||
|
||||
export function getConfig(service: string, method: string): IdlConfig {
|
||||
// 手动注册的配置优先级比全局变量高
|
||||
// Manually registered configuration takes precedence over global variables
|
||||
let config: IdlConfig | undefined = configCenter.getConfig(service);
|
||||
if (!config) {
|
||||
config = {};
|
||||
@@ -137,7 +137,7 @@ export function normalizeRequest(
|
||||
);
|
||||
const { uriPrefix = '', clientFactory } = config;
|
||||
if (!clientFactory) {
|
||||
// todo 这里考虑给个默认的 client,防止某些公共 package 在一些异常情况下使用
|
||||
// Todo here considers giving a default client to prevent some public packages from being used in some abnormal cases
|
||||
throw new Error('Lack of clientFactory config');
|
||||
}
|
||||
let uri = uriPrefix + apiUri;
|
||||
@@ -149,11 +149,11 @@ export function normalizeRequest(
|
||||
: 'application/json';
|
||||
if (option?.requestOptions?.headers) {
|
||||
headers = { ...headers, ...option.requestOptions.headers };
|
||||
// 合并了 header,可删除
|
||||
// Merged headers, can be deleted
|
||||
delete option.requestOptions.headers;
|
||||
}
|
||||
if (meta.reqMapping.query && meta.reqMapping.query.length > 0) {
|
||||
// 这里默认 skipNulls,网关后端需要忽略 null
|
||||
// The default here is skipNulls, and the gateway backend needs to ignore null.
|
||||
uri = `${uri}?${qs.stringify(getValue(req, meta.reqMapping.query), {
|
||||
skipNulls: true,
|
||||
arrayFormat: 'comma',
|
||||
@@ -168,7 +168,7 @@ export function normalizeRequest(
|
||||
|
||||
if (meta.reqMapping.entire_body && meta.reqMapping.entire_body.length > 0) {
|
||||
if (meta.reqMapping.entire_body.length === 1) {
|
||||
// 默认处理为 json ,如有其他场景需要支持,后需要再支持
|
||||
// The default processing is json. If there are other scenarios that need to be supported, they need to be supported later.
|
||||
requestOption.body = req[meta.reqMapping.entire_body[0]];
|
||||
} else {
|
||||
throw new Error('idl invalid entire_body should be only one filed');
|
||||
@@ -203,7 +203,7 @@ export function normalizeRequest(
|
||||
};
|
||||
}
|
||||
|
||||
// 旧版的 ferry 中,即使 idl 没有声明body,也需要加一个 空的 body
|
||||
// In the old version of ferry, even if idl does not declare body, you need to add an empty body.
|
||||
if (
|
||||
!requestOption.body &&
|
||||
['POST', 'PUT', 'PATCH'].includes(
|
||||
|
||||
Reference in New Issue
Block a user