mirror of
https://github.com/hexastack/hexabot
synced 2025-02-22 20:38:32 +00:00
Merge branch 'main' into refactor/category-dialog
This commit is contained in:
commit
7d93792f3a
11
api/package-lock.json
generated
11
api/package-lock.json
generated
@ -57,7 +57,8 @@
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"slug": "^8.2.2",
|
||||
"ts-migrate-mongoose": "^3.8.4",
|
||||
"uuid": "^9.0.1"
|
||||
"uuid": "^9.0.1",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@compodoc/compodoc": "^1.1.24",
|
||||
@ -20280,6 +20281,14 @@
|
||||
"resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz",
|
||||
"integrity": "sha512-C1x6lfvBICFTQIMgbt3JqMOno3VOtkWat/xEakLTOurskYIHPmzJrzd1e8BnmtdDVJlGuk5D+FxyCA8MPmkIyA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.24.1",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
|
||||
"integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,8 @@
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"slug": "^8.2.2",
|
||||
"ts-migrate-mongoose": "^3.8.4",
|
||||
"uuid": "^9.0.1"
|
||||
"uuid": "^9.0.1",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@compodoc/compodoc": "^1.1.24",
|
||||
@ -144,8 +145,8 @@
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@css-inline/css-inline-linux-arm64-musl": "^0.14.1",
|
||||
"@resvg/resvg-js-linux-arm64-musl": "^2.6.2",
|
||||
"@resvg/resvg-js-darwin-arm64": "^2.6.2"
|
||||
"@resvg/resvg-js-darwin-arm64": "^2.6.2",
|
||||
"@resvg/resvg-js-linux-arm64-musl": "^2.6.2"
|
||||
},
|
||||
"overrides": {
|
||||
"mjml": "5.0.0-alpha.4"
|
||||
|
@ -6,6 +6,8 @@
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
export enum FileType {
|
||||
image = 'image',
|
||||
video = 'video',
|
||||
@ -14,6 +16,8 @@ export enum FileType {
|
||||
unknown = 'unknown',
|
||||
}
|
||||
|
||||
export const fileTypeSchema = z.nativeEnum(FileType);
|
||||
|
||||
/**
|
||||
* The `AttachmentRef` type defines two possible ways to reference an attachment:
|
||||
* 1. By `id`: This is used when the attachment is uploaded and stored in the Hexabot system.
|
||||
@ -22,20 +26,24 @@ export enum FileType {
|
||||
* the content is generated or retrieved by a plugin that consumes a third-party API.
|
||||
* In this case, the `url` field contains the direct link to the external resource.
|
||||
*/
|
||||
export type AttachmentRef =
|
||||
| {
|
||||
id: string | null;
|
||||
}
|
||||
| {
|
||||
/** @deprecated To be used only for external URLs (plugins), for stored attachments use "id" instead */
|
||||
url: string;
|
||||
};
|
||||
|
||||
/** IMPORTANT: No need to use generic type here */
|
||||
export interface AttachmentPayload<T extends AttachmentRef = AttachmentRef> {
|
||||
type: FileType;
|
||||
payload: T;
|
||||
}
|
||||
export const attachmentRefSchema = z.union([
|
||||
z.object({
|
||||
id: z.string().nullable(),
|
||||
}),
|
||||
z.object({
|
||||
url: z.string(),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type AttachmentRef = z.infer<typeof attachmentRefSchema>;
|
||||
|
||||
export const attachmentPayloadSchema = z.object({
|
||||
type: fileTypeSchema,
|
||||
payload: attachmentRefSchema,
|
||||
});
|
||||
|
||||
export type AttachmentPayload = z.infer<typeof attachmentPayloadSchema>;
|
||||
|
||||
/** @deprecated */
|
||||
export type WithUrl<A> = A & { url?: string };
|
||||
|
@ -1,15 +1,19 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
export interface CaptureVar {
|
||||
// entity=`-1` to match text message
|
||||
// entity=`-2` for postback payload
|
||||
// entity is `String` for NLP entities
|
||||
entity: number | string;
|
||||
context_var: string;
|
||||
}
|
||||
import { z } from 'zod';
|
||||
|
||||
// entity=`-1` to match text message
|
||||
// entity=`-2` for postback payload
|
||||
// entity is `String` for NLP entities
|
||||
export const captureVarSchema = z.object({
|
||||
entity: z.union([z.number().min(-2).max(-1), z.string()]),
|
||||
context_var: z.string(),
|
||||
});
|
||||
|
||||
export type CaptureVar = z.infer<typeof captureVarSchema>;
|
||||
|
@ -1,29 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import { PayloadType } from './message';
|
||||
|
||||
export interface PayloadPattern {
|
||||
label: string;
|
||||
value: string;
|
||||
// @todo : rename 'attachment' to 'attachments'
|
||||
type?: PayloadType;
|
||||
}
|
||||
export const payloadPatternSchema = z.object({
|
||||
label: z.string(),
|
||||
value: z.string(),
|
||||
type: z.nativeEnum(PayloadType).optional(),
|
||||
});
|
||||
|
||||
export type NlpPattern =
|
||||
| {
|
||||
entity: string;
|
||||
match: 'entity';
|
||||
}
|
||||
| {
|
||||
entity: string;
|
||||
match: 'value';
|
||||
value: string;
|
||||
};
|
||||
export type PayloadPattern = z.infer<typeof payloadPatternSchema>;
|
||||
|
||||
export type Pattern = string | RegExp | PayloadPattern | NlpPattern[];
|
||||
export const nlpPatternSchema = z.discriminatedUnion('match', [
|
||||
z.object({
|
||||
entity: z.string(),
|
||||
match: z.literal('entity'),
|
||||
}),
|
||||
z.object({
|
||||
entity: z.string(),
|
||||
match: z.literal('value'),
|
||||
value: z.string(),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type NlpPattern = z.infer<typeof nlpPatternSchema>;
|
||||
|
||||
export const patternSchema = z.union([
|
||||
z.string(),
|
||||
z.instanceof(RegExp),
|
||||
payloadPatternSchema,
|
||||
z.array(nlpPatternSchema),
|
||||
]);
|
||||
|
||||
export type Pattern = z.infer<typeof patternSchema>;
|
||||
|
@ -1,12 +1,16 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
export type Position = {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
import { z } from 'zod';
|
||||
|
||||
export const positionSchema = z.object({
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
});
|
||||
|
||||
export type Position = z.infer<typeof positionSchema>;
|
||||
|
@ -6,21 +6,10 @@
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import { AttachmentPayload } from './attachment';
|
||||
import { PayloadType } from './message';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type Payload =
|
||||
| {
|
||||
type: PayloadType.location;
|
||||
coordinates: {
|
||||
lat: number;
|
||||
lon: number;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: PayloadType.attachments;
|
||||
attachment: AttachmentPayload;
|
||||
};
|
||||
import { attachmentPayloadSchema } from './attachment';
|
||||
import { PayloadType } from './message';
|
||||
|
||||
export enum QuickReplyType {
|
||||
text = 'text',
|
||||
@ -29,8 +18,28 @@ export enum QuickReplyType {
|
||||
user_email = 'user_email',
|
||||
}
|
||||
|
||||
export interface StdQuickReply {
|
||||
content_type: QuickReplyType;
|
||||
title: string;
|
||||
payload: string;
|
||||
}
|
||||
export const cordinatesSchema = z.object({
|
||||
lat: z.number(),
|
||||
lon: z.number(),
|
||||
});
|
||||
|
||||
export const payloadSchema = z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal(PayloadType.location),
|
||||
coordinates: cordinatesSchema,
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(PayloadType.attachments),
|
||||
attachment: attachmentPayloadSchema,
|
||||
}),
|
||||
]);
|
||||
|
||||
export const stdQuickReplySchema = z.object({
|
||||
content_type: z.nativeEnum(QuickReplyType),
|
||||
title: z.string(),
|
||||
payload: z.string(),
|
||||
});
|
||||
|
||||
export type Payload = z.infer<typeof payloadSchema>;
|
||||
|
||||
export type StdQuickReply = z.infer<typeof stdQuickReplySchema>;
|
||||
|
@ -1,11 +1,15 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
export interface SubscriberContext {
|
||||
vars?: { [key: string]: any };
|
||||
}
|
||||
import { z } from 'zod';
|
||||
|
||||
export const subscriberContextSchema = z.object({
|
||||
vars: z.record(z.any()).optional(),
|
||||
});
|
||||
|
||||
export type SubscriberContext = z.infer<typeof subscriberContextSchema>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Hexastack. All rights reserved.
|
||||
* Copyright © 2025 Hexastack. All rights reserved.
|
||||
*
|
||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||
@ -12,62 +12,15 @@ import {
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
} from 'class-validator';
|
||||
import Joi from 'joi';
|
||||
|
||||
import { Pattern } from '../schemas/types/pattern';
|
||||
import { Pattern, patternSchema } from '../schemas/types/pattern';
|
||||
|
||||
export function isPatternList(patterns: Pattern[]) {
|
||||
return (
|
||||
Array.isArray(patterns) &&
|
||||
patterns.every((pattern) => {
|
||||
if (typeof pattern === 'string') {
|
||||
// Check if valid regex
|
||||
if (pattern.endsWith('/') && pattern.startsWith('/')) {
|
||||
try {
|
||||
new RegExp(pattern.slice(1, -1), 'gi');
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Check if valid string (Equals/Like)
|
||||
return pattern !== '';
|
||||
} else if (Array.isArray(pattern)) {
|
||||
// Check if valid NLP pattern
|
||||
const nlpSchema = Joi.array()
|
||||
.items(
|
||||
Joi.object().keys({
|
||||
entity: Joi.string().required(),
|
||||
match: Joi.string().valid('entity', 'value').required(),
|
||||
value: Joi.string().required(),
|
||||
}),
|
||||
)
|
||||
.min(1);
|
||||
const nlpCheck = nlpSchema.validate(pattern);
|
||||
if (nlpCheck.error) {
|
||||
// console.log('Message validation failed! ', nlpCheck);
|
||||
}
|
||||
return !nlpCheck.error;
|
||||
} else if (typeof pattern === 'object') {
|
||||
// Invalid structure?
|
||||
const payloadSchema = Joi.object().keys({
|
||||
label: Joi.string().required(),
|
||||
value: Joi.any().required(),
|
||||
type: Joi.string(),
|
||||
});
|
||||
const payloadCheck = payloadSchema.validate(pattern);
|
||||
if (payloadCheck.error) {
|
||||
// console.log(
|
||||
// 'Message validation failed! ',
|
||||
// payloadCheck,
|
||||
// );
|
||||
}
|
||||
return !payloadCheck.error;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
);
|
||||
if (!Array.isArray(patterns)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return patterns.every((pattern) => patternSchema.safeParse(pattern).success);
|
||||
}
|
||||
|
||||
@ValidatorConstraint({ async: false })
|
||||
|
Loading…
Reference in New Issue
Block a user