feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# @coze-arch/idl2ts-helper
@coze-arch/idl2ts-helper
## Overview
This package is part of the Coze Studio monorepo and provides utilities functionality. It serves as a core component in the Coze ecosystem.
## Getting Started
### Installation
Add this package to your `package.json`:
```json
{
"dependencies": {
"@coze-arch/idl2ts-helper": "workspace:*"
}
}
```
Then run:
```bash
rush update
```
### Usage
```typescript
import { /* exported functions/components */ } from '@coze-arch/idl2ts-helper';
// Example usage
// TODO: Add specific usage examples
```
## Features
- Core functionality for Coze Studio
- TypeScript support
- Modern ES modules
## API Reference
### Exports
- `*`
- `*`
- `*`
- `*`
- `*`
For detailed API documentation, please refer to the TypeScript definitions.
## Development
This package is built with:
- TypeScript
- Modern JavaScript
- Vitest for testing
- ESLint for code quality
## Contributing
This package is part of the Coze Studio monorepo. Please follow the monorepo contribution guidelines.
## License
Apache-2.0

View File

@@ -0,0 +1,12 @@
{
"operationSettings": [
{
"operationName": "test:cov",
"outputFolderNames": ["coverage"]
},
{
"operationName": "ts-check",
"outputFolderNames": ["dist"]
}
]
}

View File

@@ -0,0 +1,16 @@
const { defineConfig } = require('@coze-arch/eslint-config');
module.exports = defineConfig({
packageRoot: __dirname,
preset: 'node',
rules: {
'@typescript-eslint/naming-convention': 'off',
'unicorn/filename-case': 'off',
'@coze-arch/no-batch-import-or-export': 'off',
'max-statements-per-line': 'off',
'max-lines': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/consistent-type-assertions': 'off',
'@coze-arch/max-line-per-function': 'off',
},
});

View File

@@ -0,0 +1,35 @@
{
"name": "@coze-arch/idl2ts-helper",
"version": "0.1.6",
"description": "@coze-arch/idl2ts-helper",
"license": "Apache-2.0",
"author": "fanwenjie.fe@bytedance.com",
"main": "./src/index.ts",
"scripts": {
"build": "exit 0",
"lint": "eslint ./ --cache",
"test": "vitest --run --passWithNoTests",
"test:cov": "npm run test -- --coverage"
},
"dependencies": {
"@babel/parser": "^7.12.14",
"@babel/template": "^7.6.0",
"@babel/types": "^7.20.7",
"@coze-arch/idl-parser": "workspace:*",
"fs-extra": "^9.1.0",
"prettier": "~3.3.3"
},
"devDependencies": {
"@coze-arch/eslint-config": "workspace:*",
"@coze-arch/ts-config": "workspace:*",
"@coze-arch/vitest-config": "workspace:*",
"@types/fs-extra": "^9.0.5",
"@types/jssha": "^2.0.0",
"@types/lodash": "^4.14.137",
"@types/node": "^18",
"@types/yaml": "^1.2.0",
"@vitest/coverage-v8": "~3.0.5",
"tsx": "^4.19.2",
"vitest": "~3.0.5"
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const ReservedKeyWord = [
'class',
'const',
'var',
'arguments',
'import',
'export',
'from',
'extends',
'interface',
'enum',
'package',
'do',
'eval',
'object',
];

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type t from '@babel/types';
import {
type IParseResultItem,
type ServiceDefinition,
type FunctionDefinition,
type UnifyStatement,
} from './types';
interface BaseCtx {
[key: string]: any;
}
export interface IMeta {
reqType: string;
resType: string;
url: string;
method: string;
reqMapping: IHttpRpcMapping;
resMapping?: IHttpRpcMapping; // res mapping
name: string;
service: string;
schemaRoot: string;
serializer?: string;
}
type Fields = string[];
export interface IHttpRpcMapping {
path?: Fields; // path参数
query?: Fields; // query参数
body?: Fields; // body 参数
header?: Fields; // header 参数
status_code?: Fields; // http状态码
cookie?: Fields; // cookie
entire_body?: Fields;
raw_body?: Fields;
}
export interface BaseContent {
ast: IParseResultItem[];
}
interface BabelDist {
type: 'babel';
content: t.File;
}
interface TextDist {
type: 'text';
content: string;
}
interface JsonDist {
type: 'json';
content: { [key: string]: any };
}
type Dist = JsonDist | BabelDist | TextDist;
export type IGentsRes = Map<string, Dist>;
export interface IParseEntryCtx<T = any> extends BaseCtx {
ast: IParseResultItem[];
files: IGentsRes;
instance: T;
entries: string[];
}
export interface IGenTemplateCtx extends BaseCtx {
ast: IParseResultItem;
service: ServiceDefinition;
method: FunctionDefinition;
meta: IMeta;
template: string;
}
export interface ProcessIdlCtx extends BaseCtx {
ast: IParseResultItem;
output: IGentsRes;
dts: t.File;
mock: t.File;
node?: UnifyStatement;
mockStatements: t.Statement[];
meta: IMeta[];
}

View File

@@ -0,0 +1,407 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import path from 'path';
import prettier, { type Options } from 'prettier';
import fs from 'fs-extra';
import { SyntaxType } from '@coze-arch/idl-parser';
import { type Program, type File, type Node } from '@babel/types';
import * as t from '@babel/types';
import template from '@babel/template';
import { type ParserPlugin, parse } from '@babel/parser';
import * as h from './types';
import { ReservedKeyWord } from './constant';
export const plugins: ParserPlugin[] = [
'typescript',
'decorators-legacy',
'classProperties',
'doExpressions',
];
export const createFile = (source: string) => {
const program: Program = template.program(source, {
plugins,
})();
const file: File = {
type: 'File',
loc: program.loc,
start: program.start,
end: program.end,
program,
comments: [],
tokens: null,
leadingComments: [],
trailingComments: [],
innerComments: [],
};
return file;
};
export function createIdWithTypeAnnotation(exp: string) {
const dec = template.ast(`let ${exp}`, { plugins }) as t.VariableDeclaration;
return dec.declarations[0].id as t.Identifier;
}
export const parseFile = (fileName: string) =>
parse(fs.readFileSync(fileName, 'utf8'), {
sourceType: 'module',
plugins,
});
export function formatCode(code: string, root = '.') {
const defaultConfig: Options = {
tabWidth: 2,
printWidth: 120,
singleQuote: true,
};
const file = path.resolve(process.cwd(), root, './for-prettier-bug'); // 这里一定要加多一级目录
const config = prettier.resolveConfig(file, { editorconfig: true });
return prettier.format(code, {
...(config || defaultConfig),
parser: 'typescript',
});
}
export function disableLint<T extends Node>(node: T, isTs = true) {
return t.addComment<T>(
node,
'leading',
isTs ? ' tslint:disable ' : ' eslint-disable ',
);
}
export async function safeWriteFile(fileName: string, content: string) {
await fs.ensureDirSync(path.dirname(fileName));
await fs.writeFile(fileName, content, 'utf8');
}
export function addComment<T extends t.Node = t.Node>(
node: T,
comments: h.Comment[],
position?: t.CommentTypeShorthand,
): T {
const [content, multi] = convertVComments(comments);
if (content) {
return t.addComment(
node,
position || multi ? 'leading' : 'trailing',
content,
!multi,
);
} else {
return node;
}
}
export function convertVComments(comments: h.Comment[]): [string, boolean] {
if (!comments) {
return ['', false];
}
let res = [] as string[];
for (const comment of comments) {
const { value } = comment;
if (Array.isArray(value)) {
res = [...res, ...value];
} else {
res = [...res, value];
}
}
if (res.length > 1) {
return [
`*\n * ${res.map(i => i.replace(/\*\//g, '/')).join('\n * ')}\n`,
true,
];
}
if (res.length > 0) {
return [`* ${res[0]?.replace(/\*\//g, '/')} `, true];
}
return ['', false];
}
export function getRelativePath(from: string, to: string) {
let relative = path.relative(path.parse(from).dir, to);
relative = !relative.startsWith('.') ? `./${relative}` : relative;
return removeFileExt(relative);
}
export function removeFileExt(fileName: string) {
const [_, ...target] = fileName.split('.').reverse();
const res = target.reverse().join('.');
return res.startsWith('./') || res.startsWith('/') ? res : `./${res}`;
}
export function parseIdFiledType(fieldType: h.Identifier) {
const { value } = fieldType;
const namespaceArr = value.split('.');
const [refName, ...namespace] = namespaceArr.reverse();
const namespaceName = namespace.reverse().join('.');
return {
refName,
namespace: namespaceName,
};
}
export function parseId(id: string) {
const res = id.split('.');
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const name = res.pop()!;
const namespace = uniformNs(res.join('_'));
return namespace ? `${namespace}.${name}` : name;
}
export function uniformNs(ns: string) {
if (ReservedKeyWord.includes(ns)) {
// 命中保留字,处理为下划线开头
return `_${ns}`;
}
return ns.replace(/\./g, '_');
}
export function getValuesFromEnum(params: h.EnumDefinition) {
const { members } = params;
let currentVal = 0;
const enumArr = [] as number[];
for (const member of members) {
const { initializer } = member;
if (initializer) {
if (h.isIntegerLiteral(initializer.value)) {
currentVal = Number(initializer.value.value);
} else if (h.isHexLiteral(initializer.value)) {
// 16进制
currentVal = Number(initializer.value.value);
}
enumArr.push(currentVal);
} else {
enumArr.push(currentVal);
}
currentVal = currentVal + 1;
}
return enumArr;
}
export function parseFiledName(filed: h.FieldDefinition) {
const { name, extensionConfig } = filed;
if (extensionConfig?.key === '.') {
return name.value;
}
return extensionConfig?.key || name.value;
}
export function getAnnotation(
annotations: h.Annotations | undefined,
name: string,
) {
if (!annotations) {
return undefined;
}
for (const ele of annotations.annotations) {
if (ele.name.value === name) {
return ele.value && ele.value.value;
}
}
return undefined;
}
// export function parseAnnotations(anno: h.Annotations) {
// const result = {} as { [key: string]: string };
// anno.annotations.forEach((i) => {
// const { name, value } = i;
// result[name.value] = value ? value.value : "";
// });
// return result;
// }
export function getNamespaceByPath(idlPath: string) {
return (idlPath.split('/').pop() as string).replace(/\.(thrift|proto)$/, '');
}
export function genAst<T = unknown>(code: string): T {
return template.ast(code, {
plugins,
preserveComments: true,
startLine: 2,
}) as any;
}
export function getStatementById(
id: h.Identifier,
current: h.IParseResultItem,
) {
const { namespace, refName } = parseIdFiledType(id);
let statement: h.UnifyStatement | undefined;
if (namespace) {
const ast = getAstFromNamespace(namespace, current);
statement = h.findDefinition(ast, refName);
} else {
statement = h.findDefinition(current.statements, id.value);
}
if (!statement) {
throw new Error(`can not find Struct: ${id.value} `);
}
return statement;
}
export function getAstFromNamespace(
namespace: string,
current: h.IParseResultItem,
) {
const item = getParseResultFromNamespace(namespace, current);
return item.statements;
}
export function getParseResultFromNamespace(
namespace: string,
current: h.IParseResultItem,
) {
let item = null as h.IParseResultItem | null;
for (const file in current.deps) {
// eslint-disable-next-line no-prototype-builtins
if (current.deps.hasOwnProperty(file)) {
const element = current.deps[file];
const ns = getNamespaceByPath(file);
if (ns === namespace) {
item = element;
break;
}
}
}
if (!item) {
throw new Error(`can not find ast by namespace : ${namespace}`);
}
return item;
}
export function ignoreField(f: h.FieldDefinition) {
if (['KContext', 'Base', 'BaseResp'].includes(f.name.value)) {
return false;
}
if (h.isIdentifier(f.fieldType)) {
return !['base.Base', 'base.BaseResp'].includes(f.fieldType.value);
}
return true;
}
export function isFullBody(f: h.FieldDefinition) {
return (
(f.extensionConfig?.position === 'body' && f.extensionConfig.key === '.') ||
getAnnotation(f.annotations, 'api.full_body') !== undefined
);
}
export function hasDynamicJsonAnnotation(annotations?: h.Annotations) {
if (!annotations) {
return false;
}
return annotations.annotations.find(i =>
[
'kgw.json',
'kgw.json.req',
'kgw.json.resp',
'api.request.converter',
'api.response.converter',
].some(k => k === i.name.value),
);
}
/**
* 从 api.(request|response).converter 中解析出前端与网关之间的真实类型,
* 能搞出这两个注解来,这个协议着实恶心😭
* @param annotations
* @returns
*/
export function getTypeFromDynamicJsonAnnotation(
annotations?: h.Annotations,
): undefined | 'string' | 'Object' | 'unknown' {
if (!annotations) {
return undefined;
}
const requestVal = annotations.annotations.find(
i => i.name.value === 'api.request.converter',
)?.value?.value;
const responseVal = annotations.annotations.find(
i => i.name.value === 'api.response.converter',
)?.value?.value;
const typeValue = [
[undefined, 'string', 'Object'],
['Object', 'unknown', 'string'],
['Object', 'Object', 'unknown'],
] as const;
const index = (value: undefined | 'encode' | 'decode' | string) =>
value === 'encode' ? 2 : value === 'decode' ? 1 : 0;
return typeValue[index(responseVal)][index(requestVal)];
}
export function getFieldsAlias(i: h.FieldDefinition) {
return parseFiledName(i);
}
export function withExportDeclaration(
node: t.Declaration,
comments?: h.Comment[],
) {
const declaration = t.exportNamedDeclaration(node);
if (!comments) {
return declaration;
}
return addComment(declaration, comments, 'leading');
}
export function getSchemaRootByPath(absFile: string, idlRoot: string) {
const pathName = path
.relative(idlRoot, removeFileExt(absFile))
.replace(/\//g, '_');
return `api://schemas/${pathName}`;
}
export function getOutputName(params: {
source: string;
idlRoot: string;
outputDir: string;
}) {
const relativeName = path.relative(params.idlRoot, params.source);
return path.resolve(params.outputDir, relativeName);
}
export function transformFieldId(fieldName: string) {
return fieldName.includes('-')
? t.stringLiteral(fieldName)
: t.identifier(fieldName);
}
export function getBaseTypeConverts(i64Type: string) {
let newType = 'number';
if (i64Type === 'string') {
newType = 'string';
}
return {
[SyntaxType.ByteKeyword]: 'number',
[SyntaxType.I8Keyword]: 'number',
[SyntaxType.I16Keyword]: 'number',
[SyntaxType.I32Keyword]: 'number',
[SyntaxType.I64Keyword]: newType,
[SyntaxType.DoubleKeyword]: 'number',
[SyntaxType.BinaryKeyword]: 'object',
[SyntaxType.StringKeyword]: 'string',
[SyntaxType.BoolKeyword]: 'boolean',
};
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './parser';
export * from './types';
export * from './ctx';
export * from './utils';
export * from './helper';

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as path from 'path';
import { parse, type UnifyDocument } from '@coze-arch/idl-parser';
import { isPbFile, lookupFile } from './utils';
import type * as t from './types';
import { getNamespaceByPath, uniformNs } from './helper';
export function parseDSL(
idlFullPaths: string[],
parsedRes: t.IParseResultItem[] = [],
idlRoot: string = process.cwd(),
): t.IParseResultItem[] {
const results = parsedRes;
const entries =
typeof idlFullPaths === 'string' ? [idlFullPaths] : idlFullPaths;
const isPb = isPbFile(idlFullPaths[0]);
function addResult(res: t.IParseResultItem) {
if (!results.find(i => i.idlPath === res.idlPath)) {
results.push(res);
}
}
function _parse(idlFullPath: string, isEntry = false) {
const target = results.find(i => i.idlPath === idlFullPath);
if (target) {
if (isEntry) {
target.isEntry = true;
}
return target;
}
const ast: UnifyDocument = parse(idlFullPath, {
cache: false,
ignoreGoTagDash: false,
root: idlRoot,
namespaceRefer: true,
searchPaths: [path.dirname(idlFullPath)],
});
const res = {
...ast,
deps: {},
includeMap: {},
idlPath: idlFullPath,
isEntry,
} as t.IParseResultItem;
addResult(res);
if (ast.includes && ast.includes.length > 0) {
ast.includes.forEach(i => {
if (/google\/(protobuf|api)/.test(i)) {
return;
}
const filePath = isPb
? lookupFile(i, [path.dirname(idlFullPath), idlRoot])
: path.resolve(path.dirname(idlFullPath), i);
const subResults = _parse(filePath);
if (subResults) {
res.deps[filePath] = subResults;
res.includeMap[i] = filePath;
if (!isPb) {
res.includeRefer[i] = getNamespaceByPath(i);
}
res.includeRefer[i] = uniformNs(res.includeRefer[i]);
addResult(subResults);
}
});
}
return res;
}
entries.forEach(i => {
_parse(i, true);
});
return results;
}

View File

@@ -0,0 +1,232 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
type UnifyStatement,
SyntaxType,
type StructDefinition,
type FieldType,
type Identifier,
type BaseType,
type MapType,
type TypedefDefinition,
type EnumDefinition,
type ServiceDefinition,
type FunctionType,
type ConstDefinition,
type SyntaxNode,
type SetType,
type ListType,
type IntegerLiteral,
type HexLiteral,
type IntConstant,
type StringLiteral,
type DoubleConstant,
type BooleanLiteral,
type ConstMap,
type ConstList,
type ConstValue,
type Annotations,
type UnifyDocument,
} from '@coze-arch/idl-parser';
export * from '@coze-arch/idl-parser';
export interface Deps {
[path: string]: IParseResultItem;
}
export type IParseResultItem = UnifyDocument & {
idlPath: string;
includeMap: Record<string, string>;
deps: Deps;
isEntry: boolean;
};
export interface I64Type extends BaseType {
type: SyntaxType.I64Keyword;
annotations?: Annotations;
}
export interface I32Type extends BaseType {
type: SyntaxType.I32Keyword;
annotations?: Annotations;
}
export interface I16Type extends BaseType {
type: SyntaxType.I16Keyword;
annotations?: Annotations;
}
export interface I8Type extends BaseType {
type: SyntaxType.I8Keyword;
annotations?: Annotations;
}
export interface StringType extends BaseType {
type: SyntaxType.StringKeyword;
annotations?: Annotations;
}
export type RefType =
| ConstDefinition
| StructDefinition
| EnumDefinition
| TypedefDefinition
| ServiceDefinition;
export function isServiceDefinition(
statement: UnifyStatement,
): statement is ServiceDefinition {
return statement.type === SyntaxType.ServiceDefinition;
}
export function isStructDefinition(
statement: UnifyStatement,
): statement is StructDefinition {
return statement.type === SyntaxType.StructDefinition;
}
export function isTypedefDefinition(
statement: UnifyStatement,
): statement is TypedefDefinition {
return statement.type === SyntaxType.TypedefDefinition;
}
export function isEnumDefinition(
statement: UnifyStatement,
): statement is EnumDefinition {
return statement.type === SyntaxType.EnumDefinition;
}
export function isConstDefinition(
statement: UnifyStatement,
): statement is ConstDefinition {
return statement.type === SyntaxType.ConstDefinition;
}
export function isIdentifier(
statement: FieldType | FunctionType | ConstValue,
): statement is Identifier {
return statement.type === SyntaxType.Identifier;
}
export function findDefinition(
statements: UnifyStatement[],
structName: string,
): UnifyStatement | undefined {
for (const statement in statements) {
// eslint-disable-next-line no-prototype-builtins
if (statements.hasOwnProperty(statement)) {
const element = statements[statement];
if (element.name.value === structName) {
return element;
}
}
}
return undefined;
}
/**
* isBasetype
*/
export function isBaseType(
fieldType: FieldType | FunctionType,
): fieldType is BaseType {
const BaseType = [
SyntaxType.StringKeyword,
SyntaxType.DoubleKeyword,
SyntaxType.BoolKeyword,
SyntaxType.I8Keyword,
SyntaxType.I16Keyword,
SyntaxType.I32Keyword,
SyntaxType.I64Keyword,
SyntaxType.BinaryKeyword,
SyntaxType.ByteKeyword,
];
return BaseType.indexOf(fieldType.type) > -1;
}
export function isI64Type(
fieldType: FieldType | FunctionType,
): fieldType is I64Type {
return fieldType.type === SyntaxType.I64Keyword;
}
// export function isI64Type(fieldType: FieldType | FunctionType): fieldType is BaseType {
// }
/**
* isReftype
*/
export function isReftype(statement: UnifyStatement): statement is RefType {
const BaseType = [
SyntaxType.ConstDefinition,
SyntaxType.StructDefinition,
SyntaxType.EnumDefinition,
// SyntaxType.UnionDefinition,
SyntaxType.TypedefDefinition,
SyntaxType.ServiceDefinition,
];
return BaseType.indexOf(statement.type) > -1;
}
export function isMapType(
fieldType: FieldType | FunctionType,
): fieldType is MapType {
return fieldType.type === SyntaxType.MapType;
}
export function isSetType(
fieldType: FieldType | FunctionType,
): fieldType is SetType {
return fieldType.type === SyntaxType.SetType;
}
export function isListType(
fieldType: FieldType | FunctionType,
): fieldType is ListType {
return fieldType.type === SyntaxType.ListType;
}
export function isIntegerLiteral(
fieldType: SyntaxNode,
): fieldType is IntegerLiteral {
return fieldType.type === SyntaxType.IntegerLiteral;
}
export function isHexLiteral(fieldType: SyntaxNode): fieldType is HexLiteral {
return fieldType.type === SyntaxType.HexLiteral;
}
export function isStringLiteral(
fieldType: SyntaxNode,
): fieldType is StringLiteral {
return fieldType.type === SyntaxType.StringLiteral;
}
export function isAnnotations(fieldType: any): fieldType is Annotations {
return fieldType.type === SyntaxType.Annotations;
}
export function isIntConstant(fieldType: SyntaxNode): fieldType is IntConstant {
return fieldType.type === SyntaxType.IntConstant;
}
export function isDoubleConstant(
fieldType: SyntaxNode,
): fieldType is DoubleConstant {
return fieldType.type === SyntaxType.DoubleConstant;
}
export function isBooleanLiteral(
fieldType: SyntaxNode,
): fieldType is BooleanLiteral {
return fieldType.type === SyntaxType.BooleanLiteral;
}
export function isConstMap(fieldType: SyntaxNode): fieldType is ConstMap {
return fieldType.type === SyntaxType.ConstMap;
}
export function isConstList(fieldType: SyntaxNode): fieldType is ConstList {
return fieldType.type === SyntaxType.ConstList;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import path from 'path';
import fs from 'fs';
export function isPbFile(p: string) {
return p.endsWith('.proto');
}
export function lookupFile(include: string, search: string[]) {
let results = include;
search.forEach(s => {
const target = path.resolve(s, include);
if (fs.existsSync(target)) {
results = target;
}
});
return results;
}

View File

@@ -0,0 +1,28 @@
{
"extends": "@coze-arch/ts-config/tsconfig.node.json",
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"module": "CommonJS",
"target": "ES2020",
"moduleResolution": "node",
"tsBuildInfoFile": "dist/tsconfig.build.tsbuildinfo"
},
"include": ["src"],
"exclude": ["node_modules", "dist"],
"references": [
{
"path": "../../../config/eslint-config/tsconfig.build.json"
},
{
"path": "../../../config/ts-config/tsconfig.build.json"
},
{
"path": "../../../config/vitest-config/tsconfig.build.json"
},
{
"path": "../idl-parser/tsconfig.build.json"
}
]
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"exclude": ["**/*"],
"compilerOptions": {
"composite": true
},
"references": [
{
"path": "./tsconfig.build.json"
},
{
"path": "./tsconfig.misc.json"
}
]
}

View File

@@ -0,0 +1,18 @@
{
"extends": "@coze-arch/ts-config/tsconfig.node.json",
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"rootDir": "./",
"outDir": "./dist",
"module": "CommonJS",
"target": "ES2020",
"moduleResolution": "node"
},
"include": ["__tests__", "vitest.config.ts"],
"exclude": ["./dist"],
"references": [
{
"path": "./tsconfig.build.json"
}
]
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'node',
});