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,259 @@
# @coze-studio/bot-env-adapter
> Environment configuration adapter for bot applications with multi-region support
## Project Overview
The `@coze-studio/bot-env-adapter` package provides a centralized environment configuration management system for bot applications. It consolidates environment variables, feature flags, and business configurations into a type-safe, region-aware adapter that supports different deployment environments (CN, SG, VA) and build types (local, online, offline, test).
This package was originally extracted from `apps/bot/env` to provide reusable environment configuration management across the bot ecosystem.
## Features
- **Multi-Region Support**: Configures environments for China (CN), Singapore (SG), and Virginia (VA) regions
- **Environment-Aware Configuration**: Automatically selects appropriate configurations based on build type and region
- **Type Safety**: Auto-generated TypeScript definitions ensure type safety across the application
- **Feature Flags**: Centralized feature flag management for different environments and regions
- **Business Configuration**: Environment-specific business settings and API configurations
- **Build-Time Validation**: Validates required environment variables at build time
## Get Started
### Installation
Install the package in your workspace:
```bash
# Add to your package.json dependencies
"@coze-studio/bot-env-adapter": "workspace:*"
# Run rush update to install
rush update
```
### Basic Usage
```typescript
import { GLOBAL_ENVS } from '@coze-studio/bot-env-adapter';
// Access environment variables
console.log(GLOBAL_ENVS.REGION); // 'cn' | 'sg' | 'va'
console.log(GLOBAL_ENVS.BUILD_TYPE); // 'local' | 'online' | 'offline' | 'test'
console.log(GLOBAL_ENVS.BOT_BRAND_NAME); // Region-specific brand name
// Access feature flags
if (GLOBAL_ENVS.FEATURE_ENABLE_SSO) {
// Enable SSO functionality
}
// Access business configurations
const appId = GLOBAL_ENVS.APP_ID;
const cdnUrl = GLOBAL_ENVS.CDN;
```
### Runtime Environment
```typescript
import { runtimeEnv } from '@coze-studio/bot-env-adapter/runtime';
// Access runtime environment information
console.log(runtimeEnv.isPPE); // Production environment check
```
### Type Definitions
```typescript
import type { TConfigEnv } from '@coze-studio/bot-env-adapter/typings';
// Use predefined types for configuration
const myConfig: TConfigEnv<string> = {
cn: {
boe: 'boe-value',
inhouse: 'inhouse-value',
release: 'release-value',
},
sg: {
inhouse: 'sg-inhouse-value',
release: 'sg-release-value',
},
va: {
release: 'va-release-value',
},
};
```
## API Reference
### Core Exports
#### `GLOBAL_ENVS`
The main export containing all environment variables, feature flags, and configurations.
```typescript
import { GLOBAL_ENVS } from '@coze-studio/bot-env-adapter';
// Base environment variables
GLOBAL_ENVS.BUILD_TYPE // Build environment type
GLOBAL_ENVS.REGION // Deployment region
GLOBAL_ENVS.NODE_ENV // Node environment
GLOBAL_ENVS.CDN // CDN URL for current environment
// Feature flags
GLOBAL_ENVS.FEATURE_ENABLE_SSO // SSO feature toggle
GLOBAL_ENVS.FEATURE_ENABLE_APP_GUIDE // App guide feature
GLOBAL_ENVS.FEATURE_GOOGLE_LOGIN // Google login support
// Business configurations
GLOBAL_ENVS.APP_ID // Application ID
GLOBAL_ENVS.BOT_BRAND_NAME // Brand name for current region
GLOBAL_ENVS.GOOGLE_CLIENT_ID // Google OAuth client ID
```
#### `extractEnvValue<T>(config: TConfigEnv<T>): T`
Utility function to extract environment-specific values based on current region and build type.
```typescript
import { extractEnvValue } from '@coze-studio/bot-env-adapter';
const apiUrl = extractEnvValue<string>({
cn: {
boe: 'https://api-boe.example.cn',
inhouse: 'https://api-inhouse.example.cn',
release: 'https://api.example.cn',
},
sg: {
inhouse: 'https://api-inhouse.example.com',
release: 'https://api.example.com',
},
va: {
release: 'https://api-va.example.com',
},
});
```
### Configuration Structure
#### Base Configuration (`base.ts`)
Contains fundamental environment variables and regional judgments:
- Build type and version information
- Regional flags (IS_OVERSEA, IS_CN_REGION, etc.)
- CDN configurations
- Development mode flags
#### Feature Flags (`features.ts`)
Boolean flags controlling feature availability:
- Authentication features (SSO, Google login, etc.)
- Regional feature differences
- Version-specific feature toggles
#### Business Configurations (`configs.ts`)
Environment-specific business settings:
- API keys and application IDs
- External service configurations
- Legal document URLs
- Platform-specific settings
### Type Definitions
The package automatically generates TypeScript definitions in `src/typings.d.ts` based on the environment configuration. These types are available for import:
```typescript
// Auto-generated types based on actual configuration
declare const BUILD_TYPE: 'local' | 'online' | 'offline' | 'test';
declare const REGION: 'cn' | 'sg' | 'va';
declare const FEATURE_ENABLE_SSO: boolean;
// ... and many more
```
## Development
### Project Structure
```
src/
├── index.ts # Main entry point, exports GLOBAL_ENVS
├── base.ts # Base environment variables and regional flags
├── features.ts # Feature flag configurations
├── configs.ts # Business-specific configurations
├── typings.d.ts # Auto-generated type definitions
├── runtime/
│ └── index.ts # Runtime environment utilities
├── utils/
│ ├── config-helper.ts # Configuration extraction utilities
│ └── current-branch.ts # Git branch detection
└── configs/
└── volcano.ts # Volcano platform configurations
```
### Configuration Guidelines
When adding new environment configurations, follow these conventions:
1. **Use `extractEnvValue` for environment-specific values**:
```typescript
const MY_CONFIG = extractEnvValue<string>({
cn: {
boe: 'boe-value',
inhouse: 'inhouse-value',
release: 'release-value',
},
sg: {
inhouse: 'sg-inhouse-value',
release: 'sg-release-value',
},
va: {
release: 'va-release-value',
},
});
```
2. **Ensure all environments are covered** to prevent configuration gaps
3. **Update the `envs` object** in `src/index.ts` to include new configurations
4. **Run the build script** to regenerate type definitions
### Build Process
The package includes an automated TypeScript definition generator:
```bash
npm run build
```
This command:
1. Analyzes the `envs` object in `src/index.ts`
2. Generates type definitions in `src/typings.d.ts`
3. Compiles TypeScript files
### Environment Variables
Set these environment variables to control the adapter behavior:
- `BUILD_TYPE`: Build environment ('local' | 'online' | 'offline' | 'test')
- `REGION`: Deployment region ('cn' | 'sg' | 'va')
- `CUSTOM_VERSION`: Version type ('inhouse' | 'release')
- `NODE_ENV`: Node environment ('development' | 'production' | 'test')
- `VERBOSE`: Set to 'true' to log all environment values
### Testing
```bash
npm run test # Run tests
npm run test:cov # Run tests with coverage
npm run lint # Run linting
```
## Dependencies
### Runtime Dependencies
This package has no runtime dependencies, making it lightweight and suitable for both client and server environments.
### Development Dependencies
- **@coze-arch/eslint-config**: Workspace ESLint configuration
- **@coze-arch/ts-config**: Workspace TypeScript configuration
- **@coze-arch/vitest-config**: Workspace Vitest configuration
- **ts-morph**: TypeScript AST manipulation for type generation
- **sucrase**: Fast TypeScript compiler for build scripts
## License
Apache-2.0

View File

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

View File

@@ -0,0 +1,7 @@
const { defineConfig } = require('@coze-arch/eslint-config');
module.exports = defineConfig({
packageRoot: __dirname,
preset: 'node',
rules: {},
});

View File

@@ -0,0 +1,45 @@
{
"name": "@coze-studio/bot-env-adapter",
"version": "0.0.1",
"description": "data info adapter for bot-env",
"license": "Apache-2.0",
"author": "chenjiawei.inizio@bytedance.com",
"maintainers": [],
"exports": {
".": "./src/index.ts",
"./build": "./scripts/build.ts",
"./typings": "./src/typings.d.ts",
"./runtime": "./src/runtime/index.ts"
},
"main": "src/index.ts",
"typesVersions": {
"*": {
"build": [
"./scripts/build.ts"
],
"typings": [
"./src/typings.ts"
],
"runtime": [
"./src/runtime/index.ts"
]
}
},
"scripts": {
"build": "node -r sucrase/register scripts/index.ts && tsc -b tsconfig.build.json",
"lint": "eslint ./ --cache",
"test": "vitest --run --passWithNoTests",
"test:cov": "npm run test -- --coverage"
},
"devDependencies": {
"@coze-arch/eslint-config": "workspace:*",
"@coze-arch/ts-config": "workspace:*",
"@coze-arch/vitest-config": "workspace:*",
"@types/node": "^18",
"@vitest/coverage-v8": "~3.0.5",
"sucrase": "^3.32.0",
"ts-morph": "^20.0.0",
"vitest": "~3.0.5"
}
}

View File

@@ -0,0 +1,139 @@
/*
* 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 {
Project,
SyntaxKind,
PropertyAssignment,
ShorthandPropertyAssignment,
SpreadAssignment,
VariableDeclarationKind,
TypeFormatFlags,
type VariableDeclarationStructure,
type OptionalKind,
} from 'ts-morph';
interface TUpdateDTSParams {
inputFileName: string;
envVarName: string;
outputFileName: string;
}
const updateDTS = ({
inputFileName,
envVarName,
outputFileName,
}: TUpdateDTSParams) => {
// 初始化一个 ts-morph 项目
const project = new Project({
compilerOptions: {
incremental: true,
allowJs: false,
skipLibCheck: true,
strictNullChecks: true,
noEmitOnError: true,
},
});
// 添加想要解析的文件
const file = project.addSourceFileAtPath(inputFileName);
// 获取你想要解析的变量
const envs = file.getVariableDeclarationOrThrow(envVarName);
// 获取 envs 变量的初始值
const initializer = envs.getInitializerIfKindOrThrow(
SyntaxKind.ObjectLiteralExpression,
);
// 获取 envs 对象的属性
const properties = initializer.getProperties();
const baseDir = path.resolve(__dirname, '../');
// 创建一个新的文件,用来保存生成的类型定义
const typeDefs = project.createSourceFile(
outputFileName,
`/* eslint-disable */
/* prettier-ignore */
// 基于${path.relative(baseDir, inputFileName)}自动生成,请勿手动修改`,
{
overwrite: true,
},
);
const declarations: OptionalKind<VariableDeclarationStructure>[] = [];
const addDeclaration = (name: string, type: string) => {
declarations.push({
name,
type,
});
};
// 遍历每一个属性
properties.forEach(property => {
if (
property instanceof PropertyAssignment ||
property instanceof ShorthandPropertyAssignment
) {
addDeclaration(property.getName(), property.getType().getText());
} else if (property instanceof SpreadAssignment) {
const expression = property.getExpression();
const type = expression.getType();
if (type.isObject()) {
// 如果类型是一个对象类型,获取其属性
const spreadProperties = type.getProperties();
// 遍历属性
for (const spreadProperty of spreadProperties) {
const declaration = spreadProperty.getDeclarations()?.[0];
if (declaration) {
addDeclaration(
spreadProperty.getName(),
declaration
.getType()
.getText(
undefined,
TypeFormatFlags.UseSingleQuotesForStringLiteralType,
),
);
}
}
}
}
});
// 保存文件
typeDefs.addVariableStatements(
declarations
.sort((a, b) => (a.name > b.name ? 1 : -1))
.map(d => ({
declarationKind: VariableDeclarationKind.Const,
hasDeclareKeyword: true,
declarations: [d],
})),
);
typeDefs.saveSync();
};
export const build = () => {
const start = Date.now();
const root = path.resolve(__dirname, '../src');
updateDTS({
inputFileName: path.resolve(root, 'index.ts'),
envVarName: 'envs',
outputFileName: path.resolve(root, 'typings.d.ts'),
});
console.info(`DTS generated in ${Date.now() - start} ms`);
};

View File

@@ -0,0 +1,19 @@
/*
* 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 { build } from './build';
build();

View File

@@ -0,0 +1,107 @@
/*
* 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 { getCurrentBranch } from './utils/current-branch';
const processEnvs = {
BUILD_TYPE: (process.env.BUILD_TYPE || 'local') as
| 'online'
| 'offline'
| 'test'
| 'local',
CUSTOM_VERSION: (process.env.CUSTOM_VERSION || 'inhouse') as
| 'release'
| 'inhouse',
BUILD_BRANCH: (process.env.BUILD_BRANCH || getCurrentBranch()) as string,
REGION: (process.env.REGION || 'cn') as 'cn' | 'sg' | 'va',
NODE_ENV: process.env.NODE_ENV as 'production' | 'development' | 'test',
CDN_PATH_PREFIX: (process.env.CDN_PATH_PREFIX ?? '/') as string,
// vmok 生产者使用,用来将生产者的 sourcemap 文件上传至对应的消费者版本下面
CONSUMER_BUILD_VERSION: (process.env.CONSUMER_BUILD_VERSION ?? '') as string,
};
const IS_OVERSEA = Boolean(process.env.REGION) && process.env.REGION !== 'cn';
const IS_CN_REGION = process.env.REGION === 'cn';
const IS_VA_REGION = process.env.REGION === 'va';
const IS_RELEASE_VERSION = processEnvs.CUSTOM_VERSION === 'release'; // 为 ture 表示对外版本
const IS_OVERSEA_RELEASE = IS_OVERSEA && IS_RELEASE_VERSION;
const IS_PROD =
processEnvs.BUILD_TYPE === 'online' ||
process.env.CUSTOM_BUILD_TYPE === 'online'; // 是否是线上
const IS_BOE = processEnvs.BUILD_TYPE === 'offline';
const IS_DEV_MODE = processEnvs.NODE_ENV === 'development'; // 本地开发
const IS_BOT_OP = false; // 是否是 bot 运营平台,默认都是 false从运营平台构建会设置成 true
const IS_OPEN_SOURCE = (process.env.IS_OPEN_SOURCE ?? 'false') === 'true';
const judgements = {
IS_OVERSEA,
IS_CN_REGION,
IS_VA_REGION,
IS_BOE,
IS_RELEASE_VERSION,
IS_OVERSEA_RELEASE,
IS_DEV_MODE,
IS_PROD,
IS_BOT_OP,
IS_OPEN_SOURCE,
};
const getInnerCDN = () =>
process.env[`CDN_INNER_${processEnvs.REGION.toUpperCase()}`];
const getOuterCDN = () =>
process.env[`CDN_OUTER_${processEnvs.REGION.toUpperCase()}`];
const getCDN = () => {
if (IS_DEV_MODE) {
if (IS_RELEASE_VERSION) {
return '';
} else {
return '';
}
}
if (IS_RELEASE_VERSION && processEnvs.BUILD_TYPE === 'online') {
// 海外正式版使用独立业务线
return getOuterCDN();
} else {
return getInnerCDN();
}
};
/** 对应CDN资源上传平台上的CDN地址 */
const getUploadCDN = () => {
const uploadCDNPrefixes = {
UPLOAD_CDN_CN: '',
UPLOAD_CDN_SG: '',
UPLOAD_CDN_VA: '',
};
const currentKey = `UPLOAD_CDN_${processEnvs.REGION.toUpperCase() as string}`;
return {
UPLOAD_CDN: uploadCDNPrefixes[currentKey as keyof typeof uploadCDNPrefixes],
...(IS_DEV_MODE ? uploadCDNPrefixes : {}),
};
};
export const base = {
...processEnvs,
...judgements,
CDN: getCDN(),
// release 环境下外部静态域名
OUTER_CDN: getOuterCDN(),
...getUploadCDN(),
};

View File

@@ -0,0 +1,673 @@
/*
* 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.
*/
/* eslint-disable max-lines -- 待拆分 */
import { extractEnvValue } from './utils/config-helper';
import { volcanoConfigs } from './configs/volcano';
const domainMap = {
DOMAIN_RELEASE_CN: 'www.coze.cn',
DOMAIN_RELEASE_OVERSEA: 'www.coze.com',
};
const APP_ID = extractEnvValue<number>({
cn: {
boe: 0,
inhouse: 0,
release: 0,
},
sg: {
inhouse: 0,
release: 0,
},
va: {
release: 0,
},
});
const APP_KEY = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const FLOW_BRAND_NAME = extractEnvValue<string>({
cn: {
boe: '豆包',
inhouse: '豆包',
release: '豆包',
},
sg: {
inhouse: 'Cici',
release: 'Cici',
},
va: {
release: 'Cici',
},
});
const BOT_BRAND_NAME = extractEnvValue<string>({
cn: {
boe: '扣子',
inhouse: '扣子',
release: '扣子',
},
sg: {
inhouse: 'Coze',
release: 'Coze',
},
va: {
release: 'Coze',
},
});
const appMeta = {
APP_ID,
APP_KEY,
FLOW_BRAND_NAME,
BOT_BRAND_NAME,
} as const;
const SEC_SDK_ASSERT_URL = extractEnvValue<string | null>({
cn: {
boe: null,
inhouse: null,
release: null,
},
sg: {
// 非 release 环境使用默认内网公用 SCM tos 无上传权限,也无脱敏需要,直接使用风控提供的 tos 地址
inhouse: '',
// release 上传至独立 SCM CDN
release: '',
},
va: {
release: '',
},
});
const FLOW_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '489823',
release: '489823',
},
va: {
release: '489823',
},
});
const FEISHU_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const LARK_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const REDDIT_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const JUEJIN_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const OBRIC_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const MYAI_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const DISCORD_PUBLISH_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const BYTE_UPLOADER_REGION = extractEnvValue<
| 'cn-north-1'
| 'us-east-1'
| 'ap-singapore-1'
| 'us-east-red'
| 'boe'
| 'boei18n'
| 'US-TTP'
| 'gcp'
>({
cn: {
// TODO 确认下这里
boe: 'boe',
inhouse: 'cn-north-1',
release: 'cn-north-1',
},
sg: {
inhouse: 'ap-singapore-1',
release: 'ap-singapore-1',
},
va: {
release: 'us-east-1',
},
});
const IMAGE_FALLBACK_HOST = extractEnvValue<string>({
cn: {
// TODO 确认下这里
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const GOOGLE_CLIENT_ID = extractEnvValue<null | string>({
cn: {
boe: null,
inhouse: null,
release: null,
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const GOOGLE_PLATFORM_ID = extractEnvValue<null | number>({
cn: {
boe: null,
inhouse: null,
release: null,
},
sg: {
inhouse: 0,
release: 0,
},
va: {
release: 0,
},
});
// 曾经计划 facebook 登录 然后需求变动后没有了
const FACEBOOK_APP_ID = extractEnvValue<null | string>({
cn: {
boe: null,
inhouse: null,
release: null,
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const AWEME_PLATFORM_ID = extractEnvValue<number>({
cn: {
boe: 0,
inhouse: 0,
release: 0,
},
sg: {
inhouse: 0,
release: 0,
},
va: {
release: 0,
},
});
const AWEME_PLATFORM_APP_KEY = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const AWEME_ORIGIN = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const SAMI_APP_KEY = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const SAMI_WS_ORIGIN = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const COZE_API_TTS_BASE_URL = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const SAMI_CHAT_WS_URL = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const COZE_FEISHU_APP = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
export const COZE_LARK_APP = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const legalEnvs = {
TERMS_OF_SERVICE:
'https://www.coze.com/docs/guides/terms_of_service?_lang=en',
PRIVATE_POLICY: 'https://www.coze.com/docs/guides/policy?_lang=en',
CN_TERMS_OF_SERVICE: 'https://www.coze.cn/docs/guides/terms-of-service',
CN_PRIVATE_POLICY: 'https://www.coze.cn/docs/guides/privacy',
VOLC_TERMS_OF_SERVICE: 'https://www.volcengine.com/docs/6256/64903',
VOLC_PRIVATE_POLICY: 'https://www.volcengine.com/docs/6256/64902',
};
const MONACO_EDITOR_PUBLIC_PATH = '/';
const FEEL_GOOD_HOST = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: 'survey.coze.com',
release: 'survey.coze.com',
},
va: {
release: 'survey.coze.com',
},
});
const feelGoodEnvs = {
FEEL_GOOD_PID: '',
FEEL_GOOD_HOST,
} as const;
const CARD_BUILDER_ENV_STR = extractEnvValue<string>({
cn: {
boe: 'boe',
inhouse: 'cn-inhouse',
release: 'cn-release',
},
sg: {
inhouse: 'sg-inhouse',
release: 'sg-release',
},
va: {
release: 'va-release',
},
});
const OPEN_WEB_SDK_BOT_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const OPEN_DOCS_APP_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const CUSTOM_PLAT_APPLY_PUBLIC_PLAT_FORM_LINK = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const OPEN_DOCS_LIB_ID = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const PLUGIN_IDE_EDITION = extractEnvValue<string>({
cn: {
boe: 'cn-internal-boe',
inhouse: 'cn-internal-prod',
release: 'cn-public-prod',
},
sg: {
inhouse: 'sg-internal-prod',
release: 'sg-public-prod',
},
va: {
release: 'va-public-prod',
},
});
const EMBEDDED_PAGE_URL = extractEnvValue<string>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: '',
release: '',
},
va: {
release: '',
},
});
const SOCIAL_SCENE_FRONTIER_SERVICE_KEY = extractEnvValue<number>({
cn: {
boe: 0,
inhouse: 0,
release: 0,
},
sg: {
inhouse: 0,
release: 0,
},
va: {
release: 0,
},
});
const FORNAX_DOMAIN = extractEnvValue<string | null>({
cn: {
boe: '',
inhouse: null,
release: '',
},
sg: {
inhouse: null,
release: null,
},
va: {
release: null,
},
});
const COZE_DOMAIN = extractEnvValue<string | null>({
cn: {
boe: '',
inhouse: '',
release: 'www.coze.cn',
},
sg: {
inhouse: '',
release: 'www.coze.com',
},
va: {
release: 'www.coze.com',
},
});
export const configs = {
...appMeta,
...feelGoodEnvs,
...legalEnvs,
...domainMap,
...volcanoConfigs,
FLOW_PUBLISH_ID,
FEISHU_PUBLISH_ID,
LARK_PUBLISH_ID,
REDDIT_PUBLISH_ID,
JUEJIN_PUBLISH_ID,
OBRIC_PUBLISH_ID,
MYAI_PUBLISH_ID,
DISCORD_PUBLISH_ID,
SEC_SDK_ASSERT_URL,
BYTE_UPLOADER_REGION,
IMAGE_FALLBACK_HOST,
GOOGLE_CLIENT_ID,
GOOGLE_PLATFORM_ID,
FACEBOOK_APP_ID,
AWEME_ORIGIN,
AWEME_PLATFORM_APP_KEY,
AWEME_PLATFORM_ID,
SAMI_APP_KEY,
SAMI_WS_ORIGIN,
SAMI_CHAT_WS_URL,
CARD_BUILDER_ENV_STR,
MONACO_EDITOR_PUBLIC_PATH,
OPEN_WEB_SDK_BOT_ID,
OPEN_DOCS_APP_ID,
OPEN_DOCS_LIB_ID,
COZE_FEISHU_APP,
COZE_LARK_APP,
PLUGIN_IDE_EDITION,
EMBEDDED_PAGE_URL,
SOCIAL_SCENE_FRONTIER_SERVICE_KEY,
CUSTOM_PLAT_APPLY_PUBLIC_PLAT_FORM_LINK,
COZE_API_TTS_BASE_URL,
FORNAX_DOMAIN,
COZE_DOMAIN,
};

View File

@@ -0,0 +1,68 @@
/*
* 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 { extractEnvValue } from '../utils/config-helper';
const VOLCANO_PLATFORM_ID = extractEnvValue<number | null>({
cn: {
boe: 0,
inhouse: 0,
release: 0,
},
sg: {
inhouse: null,
release: null,
},
va: {
release: null,
},
});
const VOLCANO_PLATFORM_APP_KEY = extractEnvValue<string | null>({
cn: {
boe: '0',
inhouse: '0',
release: '0',
},
sg: {
inhouse: null,
release: null,
},
va: {
release: null,
},
});
const VOLCANO_IDENTITY_DOMAIN = extractEnvValue<string | null>({
cn: {
boe: '',
inhouse: '',
release: '',
},
sg: {
inhouse: null,
release: null,
},
va: {
release: null,
},
});
export const volcanoConfigs = {
VOLCANO_PLATFORM_ID,
VOLCANO_PLATFORM_APP_KEY,
VOLCANO_IDENTITY_DOMAIN,
};

View File

@@ -0,0 +1,74 @@
/*
* 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 { base } from './base';
const { IS_RELEASE_VERSION, IS_OVERSEA, IS_BOE } = base;
export const features = {
// 与志强&产品沟通后下掉boe环境的sso
FEATURE_ENABLE_SSO: !IS_RELEASE_VERSION && !IS_BOE,
FEATURE_ENABLE_APP_GUIDE: !IS_RELEASE_VERSION || IS_OVERSEA,
FEATURE_ENABLE_FEEDBACK_MAILTO: IS_RELEASE_VERSION,
FEATURE_ENABLE_MSG_DEBUG: !IS_RELEASE_VERSION,
FEATURE_ENABLE_TABLE_VARIABLE: IS_OVERSEA || !IS_RELEASE_VERSION,
FEATURE_ENABLE_TABLE_MEMORY: true,
// FEATURE_ENABLE_RUYI_CARD: false,
FEATURE_ENABLE_VARIABLE: false,
/**
* 是否开启新的注销流程目前只有cn开启
*/
FEATURE_ENABLE_NEW_DELETE_ACCOUNT: !IS_OVERSEA,
FEATURE_AWEME_LOGIN: !IS_OVERSEA,
FEATURE_GOOGLE_LOGIN: IS_OVERSEA,
/**
* @description 只在boe环境和inhouse-cn环境支持 workflow code 节点编辑 python 代码
*/
FEATURE_ENABLE_CODE_PYTHON: !IS_OVERSEA && !IS_RELEASE_VERSION,
/**
* 暂时隐藏banner后续可能用于运营位置
*/
FEATURE_ENABLE_BANNER: false,
/**
* Database tooltip示例区分图海外和国内
*/
FEATURE_ENABLE_DATABASE_TABLE: !IS_OVERSEA,
/**
* bot市场中国区入口
*/
FEATURE_ENABLE_BOT_STORE: true,
/**
* workflow llm 计费只在海外或者 in-house 显示
*/
FEATURE_ENABLE_WORKFLOW_LLM_PAYMENT: IS_OVERSEA || !IS_RELEASE_VERSION,
/**
* 豆包 cici 特殊需求只在inhouse上线
*/
FEATURE_ENABLE_QUERY_ENTRY: !IS_RELEASE_VERSION,
/**
* coze接入审核增加用于发布机审弹窗提前、版本历史Publish类审核结果展示。目前仅CN生效。
*/
FEATURE_ENABLE_TCS: !IS_OVERSEA,
/**
* Tea 上报数据增加 UG 线索回传参数,仅 cn release 需要
*
*/
FEATURE_ENABLE_TEA_UG: IS_RELEASE_VERSION && !IS_OVERSEA,
};

View File

@@ -0,0 +1,47 @@
/*
* 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 { features } from './features';
import { configs } from './configs';
import { base } from './base';
const envs = {
...base,
...configs,
...features,
};
const COMMON_NULLABLE_VARS = ['CUSTOM_ENV_NAME', 'OUTER_CDN'];
const NULLABLE_VARS =
envs.BUILD_TYPE === 'local'
? ['CDN', ...COMMON_NULLABLE_VARS]
: [...COMMON_NULLABLE_VARS];
if (process.env.VERBOSE === 'true') {
console.info(JSON.stringify(envs, null, 2));
}
const emptyVars = Object.entries({
...base,
...features,
}).filter(
([key, value]) => value === undefined && !NULLABLE_VARS.includes(key),
);
if (emptyVars.length) {
throw Error(`以下环境变量值为空:${emptyVars.join('、')}`);
}
export { envs as GLOBAL_ENVS };

View File

@@ -0,0 +1,23 @@
/*
* 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.
*/
class Env {
get isPPE() {
return IS_PROD;
}
}
export const runtimeEnv = new Env();

View File

@@ -0,0 +1,111 @@
/*
* 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.
*/
/* eslint-disable */
/* prettier-ignore */
// 基于src/index.ts自动生成请勿手动修改
declare const APP_ID: number;
declare const APP_KEY: string;
declare const AWEME_ORIGIN: string;
declare const AWEME_PLATFORM_APP_KEY: string;
declare const AWEME_PLATFORM_ID: number;
declare const BOT_BRAND_NAME: string;
declare const BUILD_BRANCH: string;
declare const BUILD_TYPE: 'local' | 'online' | 'offline' | 'test';
declare const BYTE_UPLOADER_REGION: 'cn-north-1' | 'us-east-1' | 'ap-singapore-1' | 'us-east-red' | 'boe' | 'boei18n' | 'US-TTP' | 'gcp';
declare const CARD_BUILDER_ENV_STR: string;
declare const CDN: string | undefined;
declare const CDN_PATH_PREFIX: string;
declare const CN_PRIVATE_POLICY: string;
declare const CN_TERMS_OF_SERVICE: string;
declare const CONSUMER_BUILD_VERSION: string;
declare const COZE_API_TTS_BASE_URL: string;
declare const COZE_DOMAIN: string | null;
declare const COZE_FEISHU_APP: string;
declare const COZE_LARK_APP: string;
declare const CUSTOM_PLAT_APPLY_PUBLIC_PLAT_FORM_LINK: string;
declare const CUSTOM_VERSION: 'inhouse' | 'release';
declare const DISCORD_PUBLISH_ID: string;
declare const DOMAIN_RELEASE_CN: string;
declare const DOMAIN_RELEASE_OVERSEA: string;
declare const EMBEDDED_PAGE_URL: string;
declare const FACEBOOK_APP_ID: string | null;
declare const FEATURE_AWEME_LOGIN: boolean;
declare const FEATURE_ENABLE_APP_GUIDE: boolean;
declare const FEATURE_ENABLE_BANNER: boolean;
declare const FEATURE_ENABLE_BOT_STORE: boolean;
declare const FEATURE_ENABLE_CODE_PYTHON: boolean;
declare const FEATURE_ENABLE_DATABASE_TABLE: boolean;
declare const FEATURE_ENABLE_FEEDBACK_MAILTO: boolean;
declare const FEATURE_ENABLE_MSG_DEBUG: boolean;
declare const FEATURE_ENABLE_NEW_DELETE_ACCOUNT: boolean;
declare const FEATURE_ENABLE_QUERY_ENTRY: boolean;
declare const FEATURE_ENABLE_SSO: boolean;
declare const FEATURE_ENABLE_TABLE_MEMORY: boolean;
declare const FEATURE_ENABLE_TABLE_VARIABLE: boolean;
declare const FEATURE_ENABLE_TCS: boolean;
declare const FEATURE_ENABLE_TEA_UG: boolean;
declare const FEATURE_ENABLE_VARIABLE: boolean;
declare const FEATURE_ENABLE_WORKFLOW_LLM_PAYMENT: boolean;
declare const FEATURE_GOOGLE_LOGIN: boolean;
declare const FEEL_GOOD_HOST: string;
declare const FEEL_GOOD_PID: '';
declare const FEISHU_PUBLISH_ID: string;
declare const FLOW_BRAND_NAME: string;
declare const FLOW_PUBLISH_ID: string;
declare const FORNAX_DOMAIN: string | null;
declare const GOOGLE_CLIENT_ID: string | null;
declare const GOOGLE_PLATFORM_ID: number | null;
declare const IMAGE_FALLBACK_HOST: string;
declare const IS_BOE: boolean;
declare const IS_BOT_OP: boolean;
declare const IS_CN_REGION: boolean;
declare const IS_DEV_MODE: boolean;
declare const IS_OPEN_SOURCE: boolean;
declare const IS_OVERSEA: boolean;
declare const IS_OVERSEA_RELEASE: boolean;
declare const IS_PROD: boolean;
declare const IS_RELEASE_VERSION: boolean;
declare const IS_VA_REGION: boolean;
declare const JUEJIN_PUBLISH_ID: string;
declare const LARK_PUBLISH_ID: string;
declare const MONACO_EDITOR_PUBLIC_PATH: string;
declare const MYAI_PUBLISH_ID: string;
declare const NODE_ENV: 'test' | 'production' | 'development';
declare const OBRIC_PUBLISH_ID: string;
declare const OPEN_DOCS_APP_ID: string;
declare const OPEN_DOCS_LIB_ID: string;
declare const OPEN_WEB_SDK_BOT_ID: string;
declare const OUTER_CDN: string | undefined;
declare const PLUGIN_IDE_EDITION: string;
declare const PRIVATE_POLICY: string;
declare const REDDIT_PUBLISH_ID: string;
declare const REGION: 'cn' | 'sg' | 'va';
declare const SAMI_APP_KEY: string;
declare const SAMI_CHAT_WS_URL: string;
declare const SAMI_WS_ORIGIN: string;
declare const SEC_SDK_ASSERT_URL: string | null;
declare const SOCIAL_SCENE_FRONTIER_SERVICE_KEY: number;
declare const TERMS_OF_SERVICE: string;
declare const UPLOAD_CDN: string;
declare const UPLOAD_CDN_CN: string;
declare const UPLOAD_CDN_SG: string;
declare const UPLOAD_CDN_VA: string;
declare const VOLCANO_IDENTITY_DOMAIN: string | null;
declare const VOLCANO_PLATFORM_APP_KEY: string | null;
declare const VOLCANO_PLATFORM_ID: number | null;
declare const VOLC_PRIVATE_POLICY: string;
declare const VOLC_TERMS_OF_SERVICE: string;

View File

@@ -0,0 +1,77 @@
/*
* 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.
*/
/* eslint-disable */
/* tslint:disable */
// @ts-nocheck
import { base } from '../base';
const { REGION, IS_RELEASE_VERSION, IS_BOE } = base;
type TValue = string | number | boolean | null;
export interface TConfigEnv<TVal extends TValue = TValue> {
cn: {
boe: TVal;
inhouse: TVal;
release: TVal;
};
sg: {
inhouse: TVal;
release: TVal;
};
va: {
release: TVal;
};
}
export const extractEnvValue = <TConfigValue extends TValue = TValue>(
config: TConfigEnv<TConfigValue>,
): TConfigValue => {
let key: string;
switch (REGION) {
case 'cn': {
key = IS_BOE ? 'boe' : IS_RELEASE_VERSION ? 'release' : 'inhouse';
break;
}
case 'sg': {
key = IS_RELEASE_VERSION ? 'release' : 'inhouse';
break;
}
case 'va': {
key = 'release';
break;
}
}
return config[REGION][key] as TConfigValue;
};
/**
* template
const NAME = extractEnvValue<string>({
cn: {
boe: ,
inhouse: ,
},
sg: {
inhouse: ,
release: ,
},
va: {
release: ,
},
});
*/

View File

@@ -0,0 +1,42 @@
/*
* 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 { execSync } from 'child_process';
/**
* 获取当前 git 分支名称
* @returns 当前分支名称,如果不在 git 仓库中或发生错误则返回 undefined
*/
export function getCurrentBranch(): string | undefined {
try {
// 使用 git rev-parse 获取当前分支名
// --abbrev-ref 参数返回分支名而不是 commit hash
// HEAD 表示当前位置
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
encoding: 'utf-8',
}).trim();
// 如果在 detached HEAD 状态,返回 undefined
if (branch === 'HEAD') {
return undefined;
}
return branch;
} catch (error) {
// 如果执行出错(比如不在 git 仓库中),返回 undefined
return '';
}
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@coze-arch/ts-config/tsconfig.web.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "dist/tsconfig.build.tsbuildinfo"
},
"include": ["src"],
"references": [
{
"path": "../../../config/eslint-config/tsconfig.build.json"
},
{
"path": "../../../config/ts-config/tsconfig.build.json"
},
{
"path": "../../../config/vitest-config/tsconfig.build.json"
}
]
}

View File

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

View File

@@ -0,0 +1,16 @@
{
"extends": "@coze-arch/ts-config/tsconfig.node.json",
"$schema": "https://json.schemastore.org/tsconfig",
"include": ["__tests__", "scripts", "vitest.config.mts"],
"exclude": ["./dist"],
"references": [
{
"path": "./tsconfig.build.json"
}
],
"compilerOptions": {
"rootDir": "./",
"outDir": "./dist",
"types": ["vitest/globals"]
}
}

View File

@@ -0,0 +1,6 @@
import { defineConfig } from '@coze-arch/vitest-config';
export default defineConfig({
dirname: __dirname,
preset: 'node',
});