Files
LangBot/web/src/app/home/components/dynamic-form/DynamicFormItemConfig.ts
Junyan Qin bca710dbd4 feat(platform): show deployment outbound IPs on adapter config forms
Cloud/NAT deployments couldn't complete WeCom-family / Official Account /
QQ Official setup because the trusted-IP (IP whitelist) value — the
server's egress IPs — was nowhere visible in LangBot.

- config.yaml: new system.outbound_ips list (env: SYSTEM__OUTBOUND_IPS,
  comma-separated), exposed via GET /api/v1/system/info
- dynamic form: generic __system.*-named display-only fields resolved
  from systemContext (same namespace as show_if), one read-only row per
  value with a copy button, excluded from form state and emitted values;
  hidden entirely when the deployment provides no IPs
- manifests: trusted-IP display field for wecom, wecomcs, wecombot,
  officialaccount, qqofficial

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:41:17 +08:00

66 lines
1.9 KiB
TypeScript

import {
IDynamicFormItemSchema,
DynamicFormItemType,
IDynamicFormItemOption,
IShowIfCondition,
SYSTEM_FIELD_PREFIX,
} from '@/app/infra/entities/form/dynamic';
import { I18nObject } from '@/app/infra/entities/common';
export class DynamicFormItemConfig implements IDynamicFormItemSchema {
id: string;
name: string;
default: string | number | boolean | Array<unknown>;
label: I18nObject;
required: boolean;
type: DynamicFormItemType;
description?: I18nObject;
options?: IDynamicFormItemOption[];
show_if?: IShowIfCondition;
login_platform?: string;
constructor(params: IDynamicFormItemSchema) {
this.id = params.id;
this.name = params.name;
this.default = params.default;
this.label = params.label;
this.required = params.required;
this.type = params.type;
this.description = params.description;
this.options = params.options;
this.show_if = params.show_if;
this.login_platform = params.login_platform;
}
}
export function isDynamicFormItemType(
value: string,
): value is DynamicFormItemType {
return Object.values(DynamicFormItemType).includes(
value as DynamicFormItemType,
);
}
export function parseDynamicFormItemType(value: string): DynamicFormItemType {
return isDynamicFormItemType(value) ? value : DynamicFormItemType.UNKNOWN;
}
export function getDefaultValues(
itemConfigList: IDynamicFormItemSchema[],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> {
return itemConfigList.reduce(
(acc, item) => {
// `__system.*` fields are display-only (resolved from systemContext);
// their placeholder defaults must not leak into the config values.
if (item.name.startsWith(SYSTEM_FIELD_PREFIX)) {
return acc;
}
acc[item.name] = item.default;
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{} as Record<string, any>,
);
}