dify/sdks/nodejs-client/src/client/validation.ts
yyh 4d48791f3c
Some checks are pending
autofix.ci / autofix (push) Waiting to run
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/amd64, build-api-amd64) (push) Waiting to run
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/arm64, build-api-arm64) (push) Waiting to run
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/amd64, build-web-amd64) (push) Waiting to run
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/arm64, build-web-arm64) (push) Waiting to run
Build and Push API & Web / create-manifest (api, DIFY_API_IMAGE_NAME, merge-api-images) (push) Blocked by required conditions
Build and Push API & Web / create-manifest (web, DIFY_WEB_IMAGE_NAME, merge-web-images) (push) Blocked by required conditions
Main CI Pipeline / Check Changed Files (push) Waiting to run
Main CI Pipeline / API Tests (push) Blocked by required conditions
Main CI Pipeline / Web Tests (push) Blocked by required conditions
Main CI Pipeline / Style Check (push) Waiting to run
Main CI Pipeline / VDB Tests (push) Blocked by required conditions
Main CI Pipeline / DB Migration Test (push) Blocked by required conditions
refactor: nodejs sdk (#30036)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-12-23 23:24:38 +08:00

137 lines
4.4 KiB
TypeScript

import { ValidationError } from "../errors/dify-error";
const MAX_STRING_LENGTH = 10000;
const MAX_LIST_LENGTH = 1000;
const MAX_DICT_LENGTH = 100;
export function ensureNonEmptyString(
value: unknown,
name: string
): asserts value is string {
if (typeof value !== "string" || value.trim().length === 0) {
throw new ValidationError(`${name} must be a non-empty string`);
}
if (value.length > MAX_STRING_LENGTH) {
throw new ValidationError(
`${name} exceeds maximum length of ${MAX_STRING_LENGTH} characters`
);
}
}
/**
* Validates optional string fields that must be non-empty when provided.
* Use this for fields like `name` that are optional but should not be empty strings.
*
* For filter parameters that accept empty strings (e.g., `keyword: ""`),
* use `validateParams` which allows empty strings for optional params.
*/
export function ensureOptionalString(value: unknown, name: string): void {
if (value === undefined || value === null) {
return;
}
if (typeof value !== "string" || value.trim().length === 0) {
throw new ValidationError(`${name} must be a non-empty string when set`);
}
if (value.length > MAX_STRING_LENGTH) {
throw new ValidationError(
`${name} exceeds maximum length of ${MAX_STRING_LENGTH} characters`
);
}
}
export function ensureOptionalInt(value: unknown, name: string): void {
if (value === undefined || value === null) {
return;
}
if (!Number.isInteger(value)) {
throw new ValidationError(`${name} must be an integer when set`);
}
}
export function ensureOptionalBoolean(value: unknown, name: string): void {
if (value === undefined || value === null) {
return;
}
if (typeof value !== "boolean") {
throw new ValidationError(`${name} must be a boolean when set`);
}
}
export function ensureStringArray(value: unknown, name: string): void {
if (!Array.isArray(value) || value.length === 0) {
throw new ValidationError(`${name} must be a non-empty string array`);
}
if (value.length > MAX_LIST_LENGTH) {
throw new ValidationError(
`${name} exceeds maximum size of ${MAX_LIST_LENGTH} items`
);
}
value.forEach((item) => {
if (typeof item !== "string" || item.trim().length === 0) {
throw new ValidationError(`${name} must contain non-empty strings`);
}
});
}
export function ensureOptionalStringArray(value: unknown, name: string): void {
if (value === undefined || value === null) {
return;
}
ensureStringArray(value, name);
}
export function ensureRating(value: unknown): void {
if (value === undefined || value === null) {
return;
}
if (value !== "like" && value !== "dislike") {
throw new ValidationError("rating must be either 'like' or 'dislike'");
}
}
export function validateParams(params: Record<string, unknown>): void {
Object.entries(params).forEach(([key, value]) => {
if (value === undefined || value === null) {
return;
}
// Only check max length for strings; empty strings are allowed for optional params
// Required fields are validated at method level via ensureNonEmptyString
if (typeof value === "string") {
if (value.length > MAX_STRING_LENGTH) {
throw new ValidationError(
`Parameter '${key}' exceeds maximum length of ${MAX_STRING_LENGTH} characters`
);
}
} else if (Array.isArray(value)) {
if (value.length > MAX_LIST_LENGTH) {
throw new ValidationError(
`Parameter '${key}' exceeds maximum size of ${MAX_LIST_LENGTH} items`
);
}
} else if (typeof value === "object") {
if (Object.keys(value as Record<string, unknown>).length > MAX_DICT_LENGTH) {
throw new ValidationError(
`Parameter '${key}' exceeds maximum size of ${MAX_DICT_LENGTH} items`
);
}
}
if (key === "user" && typeof value !== "string") {
throw new ValidationError(`Parameter '${key}' must be a string`);
}
if (
(key === "page" || key === "limit" || key === "page_size") &&
!Number.isInteger(value)
) {
throw new ValidationError(`Parameter '${key}' must be an integer`);
}
if (key === "files" && !Array.isArray(value) && typeof value !== "object") {
throw new ValidationError(`Parameter '${key}' must be a list or dict`);
}
if (key === "rating" && value !== "like" && value !== "dislike") {
throw new ValidationError(`Parameter '${key}' must be 'like' or 'dislike'`);
}
});
}