@remnawave/backend-contract 2.1.74 → 2.1.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/build/backend/constants/response-rules/response-rules.contants.d.ts +26 -1
  2. package/build/backend/constants/response-rules/response-rules.contants.d.ts.map +1 -1
  3. package/build/backend/constants/response-rules/response-rules.contants.js +27 -2
  4. package/build/backend/models/response-rules/index.d.ts +0 -1
  5. package/build/backend/models/response-rules/index.d.ts.map +1 -1
  6. package/build/backend/models/response-rules/index.js +0 -1
  7. package/build/backend/models/response-rules/response-rule.schema.d.ts +6 -3
  8. package/build/backend/models/response-rules/response-rule.schema.d.ts.map +1 -1
  9. package/build/backend/models/response-rules/response-rule.schema.js +86 -11
  10. package/build/backend/models/response-rules/response-rules-config.schema.d.ts +10 -5
  11. package/build/backend/models/response-rules/response-rules-config.schema.d.ts.map +1 -1
  12. package/build/backend/models/response-rules/response-rules-config.schema.js +44 -2
  13. package/build/frontend/constants/response-rules/response-rules.contants.js +27 -2
  14. package/build/frontend/models/response-rules/index.js +0 -1
  15. package/build/frontend/models/response-rules/response-rule.schema.js +86 -11
  16. package/build/frontend/models/response-rules/response-rules-config.schema.js +44 -2
  17. package/package.json +1 -1
  18. package/build/backend/models/response-rules/response-rules-json-schema.d.ts +0 -7
  19. package/build/backend/models/response-rules/response-rules-json-schema.d.ts.map +0 -1
  20. package/build/backend/models/response-rules/response-rules-json-schema.js +0 -11
  21. package/build/frontend/models/response-rules/response-rules-json-schema.js +0 -11
@@ -20,9 +20,21 @@ export declare const RESPONSE_RULES_CONDITION_OPERATORS: {
20
20
  readonly REGEX: "REGEX";
21
21
  readonly NOT_REGEX: "NOT_REGEX";
22
22
  };
23
+ export declare const RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION: {
24
+ readonly EQUALS: "Equals operator checks if the header value exactly matches the specified string, case sensitive. Underlying implementation uses strict string comparison – ===.";
25
+ readonly NOT_EQUALS: "Not equals operator checks if the header value does not match the specified string, case sensitive. Underlying implementation uses strict string comparison – !==.";
26
+ readonly CONTAINS: "Contains operator checks if the header value contains the specified string, case sensitive. Underlying implementation uses string.includes().";
27
+ readonly NOT_CONTAINS: "Not contains operator checks if the header value does not contain the specified string, case sensitive. Underlying implementation uses string.includes().";
28
+ readonly STARTS_WITH: "Starts with operator checks if the header value starts with the specified string, case sensitive. Underlying implementation uses string.startsWith().";
29
+ readonly NOT_STARTS_WITH: "Not starts with operator checks if the header value does not start with the specified string, case sensitive. Underlying implementation uses string.startsWith().";
30
+ readonly ENDS_WITH: "Ends with operator checks if the header value ends with the specified string, case sensitive. Underlying implementation uses string.endsWith().";
31
+ readonly NOT_ENDS_WITH: "Not ends with operator checks if the header value does not end with the specified string, case sensitive. Underlying implementation uses string.endsWith().";
32
+ readonly REGEX: "Regex operator checks if the header value matches the specified regex. Underlying implementation uses regex.test().";
33
+ readonly NOT_REGEX: "Inverse regex operator checks if the header value does not match the specified regex. Underlying implementation uses regex.test().";
34
+ };
23
35
  export declare const RESPONSE_RULES_RESPONSE_TYPES: {
24
36
  readonly BLOCK: "BLOCK";
25
- readonly BASE64: "BASE64";
37
+ readonly XRAY_BASE64: "XRAY_BASE64";
26
38
  readonly STATUS_CODE_404: "STATUS_CODE_404";
27
39
  readonly STATUS_CODE_403: "STATUS_CODE_403";
28
40
  readonly STATUS_CODE_451: "STATUS_CODE_451";
@@ -34,4 +46,17 @@ export declare const RESPONSE_RULES_RESPONSE_TYPES: {
34
46
  readonly XRAY_JSON: "XRAY_JSON";
35
47
  readonly CLASH: "CLASH";
36
48
  };
49
+ export declare const RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION: {
50
+ readonly BLOCK: "Block response type blocks the request and returns a 403 status code.";
51
+ readonly XRAY_BASE64: "Previously used as fallback response type. It return subscription as base64 encoded string. Compatible with most client application with Xray core.";
52
+ readonly STATUS_CODE_404: "Status code 404 response type returns a 404 status code. This response type is used to return a 404 status code.";
53
+ readonly STATUS_CODE_451: "Status code 451 response type returns a 451 status code. This response type is used to return a 451 status code.";
54
+ readonly SOCKET_DROP: "Socket drop response type drops the socket connection. This response type is used to drop the socket connection.";
55
+ readonly CLASH: "Useful for client application that use Legacy Clash core. It return subscription as Clash YAML format.";
56
+ readonly STASH: "Format which is used by Stash client application.";
57
+ readonly SINGBOX: "Format which is used by Singbox client application.";
58
+ readonly SINGBOX_LEGACY: "Format which is used by Singbox client application (legacy version).";
59
+ readonly MIHOMO: "Return subscription as Mihomo Core YAML format.";
60
+ readonly XRAY_JSON: "Return subscription as Xray JSON format.";
61
+ };
37
62
  //# sourceMappingURL=response-rules.contants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response-rules.contants.d.ts","sourceRoot":"","sources":["../../../../constants/response-rules/response-rules.contants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,6BAA6B;;CAEhC,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX,eAAO,MAAM,6BAA6B;;CAEhC,CAAC;AAEX,eAAO,MAAM,kCAAkC;;;;;;;;;;;CAWrC,CAAC;AAEX,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;CAQhC,CAAC"}
1
+ {"version":3,"file":"response-rules.contants.d.ts","sourceRoot":"","sources":["../../../../constants/response-rules/response-rules.contants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,6BAA6B;;CAEhC,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX,eAAO,MAAM,6BAA6B;;CAEhC,CAAC;AAEX,eAAO,MAAM,kCAAkC;;;;;;;;;;;CAWrC,CAAC;AAEX,eAAO,MAAM,8CAA8C;;;;;;;;;;;CAqBjD,CAAC;AAEX,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;CAQhC,CAAC;AAEX,eAAO,MAAM,yCAAyC;;;;;;;;;;;;CAmB5C,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RESPONSE_RULES_RESPONSE_TYPES = exports.RESPONSE_RULES_CONDITION_OPERATORS = exports.RESPONSE_RULE_CONDITION_TYPES = exports.RESPONSE_RULES_OPERATORS = exports.RESPONSE_RULES_CONFIG_VERSION = void 0;
3
+ exports.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION = exports.RESPONSE_RULES_RESPONSE_TYPES = exports.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION = exports.RESPONSE_RULES_CONDITION_OPERATORS = exports.RESPONSE_RULE_CONDITION_TYPES = exports.RESPONSE_RULES_OPERATORS = exports.RESPONSE_RULES_CONFIG_VERSION = void 0;
4
4
  const subscription_template_1 = require("../subscription-template");
5
5
  exports.RESPONSE_RULES_CONFIG_VERSION = {
6
6
  1: '1',
@@ -24,12 +24,37 @@ exports.RESPONSE_RULES_CONDITION_OPERATORS = {
24
24
  REGEX: 'REGEX',
25
25
  NOT_REGEX: 'NOT_REGEX',
26
26
  };
27
+ exports.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION = {
28
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.EQUALS]: 'Equals operator checks if the header value exactly matches the specified string, case sensitive. Underlying implementation uses strict string comparison – ===.',
29
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_EQUALS]: 'Not equals operator checks if the header value does not match the specified string, case sensitive. Underlying implementation uses strict string comparison – !==.',
30
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS]: 'Contains operator checks if the header value contains the specified string, case sensitive. Underlying implementation uses string.includes().',
31
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_CONTAINS]: 'Not contains operator checks if the header value does not contain the specified string, case sensitive. Underlying implementation uses string.includes().',
32
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.STARTS_WITH]: 'Starts with operator checks if the header value starts with the specified string, case sensitive. Underlying implementation uses string.startsWith().',
33
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_STARTS_WITH]: 'Not starts with operator checks if the header value does not start with the specified string, case sensitive. Underlying implementation uses string.startsWith().',
34
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.ENDS_WITH]: 'Ends with operator checks if the header value ends with the specified string, case sensitive. Underlying implementation uses string.endsWith().',
35
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_ENDS_WITH]: 'Not ends with operator checks if the header value does not end with the specified string, case sensitive. Underlying implementation uses string.endsWith().',
36
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.REGEX]: 'Regex operator checks if the header value matches the specified regex. Underlying implementation uses regex.test().',
37
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_REGEX]: 'Inverse regex operator checks if the header value does not match the specified regex. Underlying implementation uses regex.test().',
38
+ };
27
39
  exports.RESPONSE_RULES_RESPONSE_TYPES = {
28
40
  ...subscription_template_1.SUBSCRIPTION_TEMPLATE_TYPE,
29
41
  BLOCK: 'BLOCK',
30
- BASE64: 'BASE64',
42
+ XRAY_BASE64: 'XRAY_BASE64',
31
43
  STATUS_CODE_404: 'STATUS_CODE_404',
32
44
  STATUS_CODE_403: 'STATUS_CODE_403',
33
45
  STATUS_CODE_451: 'STATUS_CODE_451',
34
46
  SOCKET_DROP: 'SOCKET_DROP',
35
47
  };
48
+ exports.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION = {
49
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.BLOCK]: 'Block response type blocks the request and returns a 403 status code.',
50
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.XRAY_BASE64]: 'Previously used as fallback response type. It return subscription as base64 encoded string. Compatible with most client application with Xray core.',
51
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STATUS_CODE_404]: 'Status code 404 response type returns a 404 status code. This response type is used to return a 404 status code.',
52
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STATUS_CODE_451]: 'Status code 451 response type returns a 451 status code. This response type is used to return a 451 status code.',
53
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SOCKET_DROP]: 'Socket drop response type drops the socket connection. This response type is used to drop the socket connection.',
54
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.CLASH]: 'Useful for client application that use Legacy Clash core. It return subscription as Clash YAML format.',
55
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STASH]: 'Format which is used by Stash client application.',
56
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SINGBOX]: 'Format which is used by Singbox client application.',
57
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SINGBOX_LEGACY]: 'Format which is used by Singbox client application (legacy version).',
58
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.MIHOMO]: 'Return subscription as Mihomo Core YAML format.',
59
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.XRAY_JSON]: 'Return subscription as Xray JSON format.',
60
+ };
@@ -1,4 +1,3 @@
1
1
  export * from './response-rule.schema';
2
2
  export * from './response-rules-config.schema';
3
- export * from './response-rules-json-schema';
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC"}
@@ -16,4 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./response-rule.schema"), exports);
18
18
  __exportStar(require("./response-rules-config.schema"), exports);
19
- __exportStar(require("./response-rules-json-schema"), exports);
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  export declare const ResponseRuleSchema: z.ZodObject<{
3
3
  name: z.ZodString;
4
4
  description: z.ZodOptional<z.ZodString>;
5
+ enabled: z.ZodBoolean;
5
6
  operator: z.ZodNativeEnum<{
6
7
  readonly AND: "AND";
7
8
  readonly OR: "OR";
@@ -32,7 +33,7 @@ export declare const ResponseRuleSchema: z.ZodObject<{
32
33
  }>, "many">;
33
34
  responseType: z.ZodNativeEnum<{
34
35
  readonly BLOCK: "BLOCK";
35
- readonly BASE64: "BASE64";
36
+ readonly XRAY_BASE64: "XRAY_BASE64";
36
37
  readonly STATUS_CODE_404: "STATUS_CODE_404";
37
38
  readonly STATUS_CODE_403: "STATUS_CODE_403";
38
39
  readonly STATUS_CODE_451: "STATUS_CODE_451";
@@ -46,23 +47,25 @@ export declare const ResponseRuleSchema: z.ZodObject<{
46
47
  }>;
47
48
  }, "strip", z.ZodTypeAny, {
48
49
  name: string;
50
+ enabled: boolean;
49
51
  operator: "AND" | "OR";
50
52
  conditions: {
51
53
  value: string;
52
54
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
53
55
  headerName: string;
54
56
  }[];
55
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
57
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
56
58
  description?: string | undefined;
57
59
  }, {
58
60
  name: string;
61
+ enabled: boolean;
59
62
  operator: "AND" | "OR";
60
63
  conditions: {
61
64
  value: string;
62
65
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
63
66
  headerName: string;
64
67
  }[];
65
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
68
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
66
69
  description?: string | undefined;
67
70
  }>;
68
71
  //# sourceMappingURL=response-rule.schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response-rule.schema.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/response-rule.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B7B,CAAC"}
1
+ {"version":3,"file":"response-rule.schema.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/response-rule.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkCxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6G1B,CAAC"}
@@ -3,27 +3,102 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResponseRuleSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const constants_1 = require("../../constants");
6
- exports.ResponseRuleSchema = zod_1.z.object({
7
- name: zod_1.z.string().min(1, 'Name is required').max(50, 'Name must be less than 50 characters'),
6
+ const RuleExampleJson = JSON.stringify({
7
+ name: 'Block Legacy Clients',
8
+ description: 'Block requests from legacy clients',
9
+ enabled: true,
10
+ operator: constants_1.RESPONSE_RULES_OPERATORS.OR,
11
+ conditions: [
12
+ {
13
+ headerName: 'user-agent',
14
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
15
+ value: 'Hiddify',
16
+ },
17
+ {
18
+ headerName: 'user-agent',
19
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
20
+ value: 'FoxRay',
21
+ },
22
+ ],
23
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
24
+ }, null, 2);
25
+ exports.ResponseRuleSchema = zod_1.z
26
+ .object({
27
+ name: zod_1.z
28
+ .string()
29
+ .min(1, 'Name is required')
30
+ .max(50, 'Name must be less than 50 characters')
31
+ .describe(JSON.stringify({
32
+ title: 'Name',
33
+ markdownDescription: 'Name of the response rule.',
34
+ })),
8
35
  description: zod_1.z
9
36
  .string()
10
37
  .min(1, 'Description is required')
11
38
  .max(250, 'Description must be less than 250 characters')
12
- .optional(),
13
- operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_OPERATORS).describe('Operator to use for the rule.'),
39
+ .optional()
40
+ .describe(JSON.stringify({
41
+ title: 'Description',
42
+ markdownDescription: 'Description of the response rule. Maximum length is 250 characters.',
43
+ })),
44
+ enabled: zod_1.z.boolean().describe(JSON.stringify({
45
+ markdownDescription: 'Whether the response rule is enabled. If disabled, the rule will not be applied.',
46
+ })),
47
+ operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_OPERATORS).describe(JSON.stringify({
48
+ title: 'Operator',
49
+ markdownDescription: 'Operator to use for combining conditions in the rule.',
50
+ })),
14
51
  conditions: zod_1.z.array(zod_1.z.object({
15
52
  headerName: zod_1.z
16
53
  .string()
17
54
  .regex(/^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/, 'Invalid header name. Only letters(a-z, A-Z), numbers(0-9), underscores(_) and hyphens(-) are allowed.')
18
- .describe('Name of the HTTP header to check, case insensitive, must comply with RFC 7230.'),
19
- operator: zod_1.z
20
- .nativeEnum(constants_1.RESPONSE_RULES_CONDITION_OPERATORS)
21
- .describe('Operator to use for the condition.'),
55
+ .describe(JSON.stringify({
56
+ title: 'Header Name',
57
+ markdownDescription: 'Name of the HTTP header to check, case insensitive, must comply with RFC 7230.',
58
+ })),
59
+ operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONDITION_OPERATORS).describe(JSON.stringify({
60
+ markdownDescription: `Comparison operator to compare the header value against.\n\n${Object.entries(constants_1.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION)
61
+ .map(([key, description]) => `- **${key}**: ${description}\n`)
62
+ .join('\n')}`,
63
+ })),
22
64
  value: zod_1.z
23
65
  .string()
24
66
  .min(1, 'Value is required')
25
67
  .max(255, 'Value must be less than 255 characters')
26
- .describe('Value to check against the header, case sensitive.'),
68
+ .describe(JSON.stringify({
69
+ markdownDescription: `Value to check against the header, case sensitive (excluding regex/not_regex operator). Maximum length is 255 characters.`,
70
+ })),
71
+ })),
72
+ responseType: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_RESPONSE_TYPES).describe(JSON.stringify({
73
+ markdownDescription: `Type of the response. Determines the type of **response** to be returned when the rule is matched.\n\n${Object.entries(constants_1.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION)
74
+ .map(([key, description]) => `- **${key}**: ${description}\n`)
75
+ .join('\n')}`,
27
76
  })),
28
- responseType: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_RESPONSE_TYPES).describe('Type of the response.'),
29
- });
77
+ })
78
+ .describe(JSON.stringify({
79
+ title: 'Response Rule',
80
+ markdownDescription: `\n\nFields:\n- **name**: Name of the response rule (required)\n- **description**: Description of the response rule (optional)\n- **enabled**: Whether the response rule is enabled. If disabled, the rule will not be applied.\n- **operator**: Operator to combine conditions (AND/OR)\n- **conditions**: Array of conditions to match against HTTP headers\n - **headerName**: Name of the HTTP header to check (case insensitive)\n - **operator**: Comparison operator (CONTAINS, EQUALS, etc)\n - **value**: Value to compare against (case sensitive, max 255 chars)\n- **responseType**: Type of response when rule matches (e.g. BLOCK)\n\nExample:\n\`\`\`json\n${RuleExampleJson}\n\`\`\``,
81
+ examples: [
82
+ {
83
+ name: 'This is example rule name',
84
+ description: 'This is example rule description (optional)',
85
+ enabled: true,
86
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
87
+ conditions: [
88
+ {
89
+ headerName: 'user-agent',
90
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
91
+ value: 'Example Rule Value, replace with your own value',
92
+ },
93
+ ],
94
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
95
+ },
96
+ {
97
+ name: 'Empty rule',
98
+ enabled: true,
99
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
100
+ conditions: [],
101
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
102
+ },
103
+ ],
104
+ }));
@@ -6,6 +6,7 @@ export declare const ResponseRulesConfigSchema: z.ZodObject<{
6
6
  rules: z.ZodArray<z.ZodObject<{
7
7
  name: z.ZodString;
8
8
  description: z.ZodOptional<z.ZodString>;
9
+ enabled: z.ZodBoolean;
9
10
  operator: z.ZodNativeEnum<{
10
11
  readonly AND: "AND";
11
12
  readonly OR: "OR";
@@ -36,7 +37,7 @@ export declare const ResponseRulesConfigSchema: z.ZodObject<{
36
37
  }>, "many">;
37
38
  responseType: z.ZodNativeEnum<{
38
39
  readonly BLOCK: "BLOCK";
39
- readonly BASE64: "BASE64";
40
+ readonly XRAY_BASE64: "XRAY_BASE64";
40
41
  readonly STATUS_CODE_404: "STATUS_CODE_404";
41
42
  readonly STATUS_CODE_403: "STATUS_CODE_403";
42
43
  readonly STATUS_CODE_451: "STATUS_CODE_451";
@@ -50,49 +51,53 @@ export declare const ResponseRulesConfigSchema: z.ZodObject<{
50
51
  }>;
51
52
  }, "strip", z.ZodTypeAny, {
52
53
  name: string;
54
+ enabled: boolean;
53
55
  operator: "AND" | "OR";
54
56
  conditions: {
55
57
  value: string;
56
58
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
57
59
  headerName: string;
58
60
  }[];
59
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
61
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
60
62
  description?: string | undefined;
61
63
  }, {
62
64
  name: string;
65
+ enabled: boolean;
63
66
  operator: "AND" | "OR";
64
67
  conditions: {
65
68
  value: string;
66
69
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
67
70
  headerName: string;
68
71
  }[];
69
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
72
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
70
73
  description?: string | undefined;
71
74
  }>, "many">;
72
75
  }, "strip", z.ZodTypeAny, {
73
76
  version: "1";
74
77
  rules: {
75
78
  name: string;
79
+ enabled: boolean;
76
80
  operator: "AND" | "OR";
77
81
  conditions: {
78
82
  value: string;
79
83
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
80
84
  headerName: string;
81
85
  }[];
82
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
86
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
83
87
  description?: string | undefined;
84
88
  }[];
85
89
  }, {
86
90
  version: "1";
87
91
  rules: {
88
92
  name: string;
93
+ enabled: boolean;
89
94
  operator: "AND" | "OR";
90
95
  conditions: {
91
96
  value: string;
92
97
  operator: "EQUALS" | "NOT_EQUALS" | "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "REGEX" | "NOT_REGEX";
93
98
  headerName: string;
94
99
  }[];
95
- responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
100
+ responseType: "STASH" | "SINGBOX" | "SINGBOX_LEGACY" | "MIHOMO" | "XRAY_JSON" | "CLASH" | "BLOCK" | "XRAY_BASE64" | "STATUS_CODE_404" | "STATUS_CODE_403" | "STATUS_CODE_451" | "SOCKET_DROP";
96
101
  description?: string | undefined;
97
102
  }[];
98
103
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"response-rules-config.schema.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/response-rules-config.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGpC,CAAC"}
1
+ {"version":3,"file":"response-rules-config.schema.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/response-rules-config.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkCxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCpC,CAAC"}
@@ -4,7 +4,49 @@ exports.ResponseRulesConfigSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const constants_1 = require("../../constants");
6
6
  const response_rule_schema_1 = require("./response-rule.schema");
7
+ const RuleExampleJson = JSON.stringify({
8
+ name: 'Block Legacy Clients',
9
+ description: 'Block requests from legacy clients',
10
+ operator: constants_1.RESPONSE_RULES_OPERATORS.OR,
11
+ enabled: true,
12
+ conditions: [
13
+ {
14
+ headerName: 'user-agent',
15
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
16
+ value: 'Hiddify',
17
+ },
18
+ {
19
+ headerName: 'user-agent',
20
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
21
+ value: 'FoxRay',
22
+ },
23
+ ],
24
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
25
+ }, null, 2);
7
26
  exports.ResponseRulesConfigSchema = zod_1.z.object({
8
- version: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONFIG_VERSION),
9
- rules: zod_1.z.array(response_rule_schema_1.ResponseRuleSchema),
27
+ version: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONFIG_VERSION).describe(JSON.stringify({
28
+ title: 'Response Rules Config Version',
29
+ markdownDescription: 'Version of the **response rules** config. Currently supported version is **1**.',
30
+ })),
31
+ rules: zod_1.z.array(response_rule_schema_1.ResponseRuleSchema).describe(JSON.stringify({
32
+ examples: [
33
+ [
34
+ {
35
+ name: 'This is example rule name',
36
+ description: 'This is example rule description (optional)',
37
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
38
+ enabled: true,
39
+ conditions: [
40
+ {
41
+ headerName: 'user-agent',
42
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
43
+ value: 'Example Rule Value, replace with your own value',
44
+ },
45
+ ],
46
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
47
+ },
48
+ ],
49
+ ],
50
+ markdownDescription: `Array of **response rules**.\n\nRules served from top to bottom – first matched rule is applied. Each rule is an object with the following properties:\n\n- **name**: Name of the response rule.\n- **description**: Description of the response rule.(Optional) \n- **enabled**: Whether the response rule is enabled. If disabled, the rule will not be applied.\n- **operator**: Operator to use for the rule.\n- **conditions**: Array of conditions to use for the rule.\n- **responseType**: Type of the response.\n\nExamples:\n\n1. Block legacy clients:\n\n\`\`\`json\n${RuleExampleJson}\n\`\`\`\n\nThis example shows how to block requests from legacy clients by checking if the User-Agent header contains "Hiddify" or "FoxRay".`,
51
+ })),
10
52
  });
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RESPONSE_RULES_RESPONSE_TYPES = exports.RESPONSE_RULES_CONDITION_OPERATORS = exports.RESPONSE_RULE_CONDITION_TYPES = exports.RESPONSE_RULES_OPERATORS = exports.RESPONSE_RULES_CONFIG_VERSION = void 0;
3
+ exports.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION = exports.RESPONSE_RULES_RESPONSE_TYPES = exports.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION = exports.RESPONSE_RULES_CONDITION_OPERATORS = exports.RESPONSE_RULE_CONDITION_TYPES = exports.RESPONSE_RULES_OPERATORS = exports.RESPONSE_RULES_CONFIG_VERSION = void 0;
4
4
  const subscription_template_1 = require("../subscription-template");
5
5
  exports.RESPONSE_RULES_CONFIG_VERSION = {
6
6
  1: '1',
@@ -24,4 +24,29 @@ exports.RESPONSE_RULES_CONDITION_OPERATORS = {
24
24
  REGEX: 'REGEX',
25
25
  NOT_REGEX: 'NOT_REGEX',
26
26
  };
27
- exports.RESPONSE_RULES_RESPONSE_TYPES = Object.assign(Object.assign({}, subscription_template_1.SUBSCRIPTION_TEMPLATE_TYPE), { BLOCK: 'BLOCK', BASE64: 'BASE64', STATUS_CODE_404: 'STATUS_CODE_404', STATUS_CODE_403: 'STATUS_CODE_403', STATUS_CODE_451: 'STATUS_CODE_451', SOCKET_DROP: 'SOCKET_DROP' });
27
+ exports.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION = {
28
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.EQUALS]: 'Equals operator checks if the header value exactly matches the specified string, case sensitive. Underlying implementation uses strict string comparison – ===.',
29
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_EQUALS]: 'Not equals operator checks if the header value does not match the specified string, case sensitive. Underlying implementation uses strict string comparison – !==.',
30
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS]: 'Contains operator checks if the header value contains the specified string, case sensitive. Underlying implementation uses string.includes().',
31
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_CONTAINS]: 'Not contains operator checks if the header value does not contain the specified string, case sensitive. Underlying implementation uses string.includes().',
32
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.STARTS_WITH]: 'Starts with operator checks if the header value starts with the specified string, case sensitive. Underlying implementation uses string.startsWith().',
33
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_STARTS_WITH]: 'Not starts with operator checks if the header value does not start with the specified string, case sensitive. Underlying implementation uses string.startsWith().',
34
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.ENDS_WITH]: 'Ends with operator checks if the header value ends with the specified string, case sensitive. Underlying implementation uses string.endsWith().',
35
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_ENDS_WITH]: 'Not ends with operator checks if the header value does not end with the specified string, case sensitive. Underlying implementation uses string.endsWith().',
36
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.REGEX]: 'Regex operator checks if the header value matches the specified regex. Underlying implementation uses regex.test().',
37
+ [exports.RESPONSE_RULES_CONDITION_OPERATORS.NOT_REGEX]: 'Inverse regex operator checks if the header value does not match the specified regex. Underlying implementation uses regex.test().',
38
+ };
39
+ exports.RESPONSE_RULES_RESPONSE_TYPES = Object.assign(Object.assign({}, subscription_template_1.SUBSCRIPTION_TEMPLATE_TYPE), { BLOCK: 'BLOCK', XRAY_BASE64: 'XRAY_BASE64', STATUS_CODE_404: 'STATUS_CODE_404', STATUS_CODE_403: 'STATUS_CODE_403', STATUS_CODE_451: 'STATUS_CODE_451', SOCKET_DROP: 'SOCKET_DROP' });
40
+ exports.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION = {
41
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.BLOCK]: 'Block response type blocks the request and returns a 403 status code.',
42
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.XRAY_BASE64]: 'Previously used as fallback response type. It return subscription as base64 encoded string. Compatible with most client application with Xray core.',
43
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STATUS_CODE_404]: 'Status code 404 response type returns a 404 status code. This response type is used to return a 404 status code.',
44
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STATUS_CODE_451]: 'Status code 451 response type returns a 451 status code. This response type is used to return a 451 status code.',
45
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SOCKET_DROP]: 'Socket drop response type drops the socket connection. This response type is used to drop the socket connection.',
46
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.CLASH]: 'Useful for client application that use Legacy Clash core. It return subscription as Clash YAML format.',
47
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.STASH]: 'Format which is used by Stash client application.',
48
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SINGBOX]: 'Format which is used by Singbox client application.',
49
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.SINGBOX_LEGACY]: 'Format which is used by Singbox client application (legacy version).',
50
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.MIHOMO]: 'Return subscription as Mihomo Core YAML format.',
51
+ [exports.RESPONSE_RULES_RESPONSE_TYPES.XRAY_JSON]: 'Return subscription as Xray JSON format.',
52
+ };
@@ -16,4 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./response-rule.schema"), exports);
18
18
  __exportStar(require("./response-rules-config.schema"), exports);
19
- __exportStar(require("./response-rules-json-schema"), exports);
@@ -3,27 +3,102 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResponseRuleSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const constants_1 = require("../../constants");
6
- exports.ResponseRuleSchema = zod_1.z.object({
7
- name: zod_1.z.string().min(1, 'Name is required').max(50, 'Name must be less than 50 characters'),
6
+ const RuleExampleJson = JSON.stringify({
7
+ name: 'Block Legacy Clients',
8
+ description: 'Block requests from legacy clients',
9
+ enabled: true,
10
+ operator: constants_1.RESPONSE_RULES_OPERATORS.OR,
11
+ conditions: [
12
+ {
13
+ headerName: 'user-agent',
14
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
15
+ value: 'Hiddify',
16
+ },
17
+ {
18
+ headerName: 'user-agent',
19
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
20
+ value: 'FoxRay',
21
+ },
22
+ ],
23
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
24
+ }, null, 2);
25
+ exports.ResponseRuleSchema = zod_1.z
26
+ .object({
27
+ name: zod_1.z
28
+ .string()
29
+ .min(1, 'Name is required')
30
+ .max(50, 'Name must be less than 50 characters')
31
+ .describe(JSON.stringify({
32
+ title: 'Name',
33
+ markdownDescription: 'Name of the response rule.',
34
+ })),
8
35
  description: zod_1.z
9
36
  .string()
10
37
  .min(1, 'Description is required')
11
38
  .max(250, 'Description must be less than 250 characters')
12
- .optional(),
13
- operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_OPERATORS).describe('Operator to use for the rule.'),
39
+ .optional()
40
+ .describe(JSON.stringify({
41
+ title: 'Description',
42
+ markdownDescription: 'Description of the response rule. Maximum length is 250 characters.',
43
+ })),
44
+ enabled: zod_1.z.boolean().describe(JSON.stringify({
45
+ markdownDescription: 'Whether the response rule is enabled. If disabled, the rule will not be applied.',
46
+ })),
47
+ operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_OPERATORS).describe(JSON.stringify({
48
+ title: 'Operator',
49
+ markdownDescription: 'Operator to use for combining conditions in the rule.',
50
+ })),
14
51
  conditions: zod_1.z.array(zod_1.z.object({
15
52
  headerName: zod_1.z
16
53
  .string()
17
54
  .regex(/^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/, 'Invalid header name. Only letters(a-z, A-Z), numbers(0-9), underscores(_) and hyphens(-) are allowed.')
18
- .describe('Name of the HTTP header to check, case insensitive, must comply with RFC 7230.'),
19
- operator: zod_1.z
20
- .nativeEnum(constants_1.RESPONSE_RULES_CONDITION_OPERATORS)
21
- .describe('Operator to use for the condition.'),
55
+ .describe(JSON.stringify({
56
+ title: 'Header Name',
57
+ markdownDescription: 'Name of the HTTP header to check, case insensitive, must comply with RFC 7230.',
58
+ })),
59
+ operator: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONDITION_OPERATORS).describe(JSON.stringify({
60
+ markdownDescription: `Comparison operator to compare the header value against.\n\n${Object.entries(constants_1.RESPONSE_RULES_CONDITION_OPERATORS_DESCRIPTION)
61
+ .map(([key, description]) => `- **${key}**: ${description}\n`)
62
+ .join('\n')}`,
63
+ })),
22
64
  value: zod_1.z
23
65
  .string()
24
66
  .min(1, 'Value is required')
25
67
  .max(255, 'Value must be less than 255 characters')
26
- .describe('Value to check against the header, case sensitive.'),
68
+ .describe(JSON.stringify({
69
+ markdownDescription: `Value to check against the header, case sensitive (excluding regex/not_regex operator). Maximum length is 255 characters.`,
70
+ })),
71
+ })),
72
+ responseType: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_RESPONSE_TYPES).describe(JSON.stringify({
73
+ markdownDescription: `Type of the response. Determines the type of **response** to be returned when the rule is matched.\n\n${Object.entries(constants_1.RESPONSE_RULES_RESPONSE_TYPES_DESCRIPTION)
74
+ .map(([key, description]) => `- **${key}**: ${description}\n`)
75
+ .join('\n')}`,
27
76
  })),
28
- responseType: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_RESPONSE_TYPES).describe('Type of the response.'),
29
- });
77
+ })
78
+ .describe(JSON.stringify({
79
+ title: 'Response Rule',
80
+ markdownDescription: `\n\nFields:\n- **name**: Name of the response rule (required)\n- **description**: Description of the response rule (optional)\n- **enabled**: Whether the response rule is enabled. If disabled, the rule will not be applied.\n- **operator**: Operator to combine conditions (AND/OR)\n- **conditions**: Array of conditions to match against HTTP headers\n - **headerName**: Name of the HTTP header to check (case insensitive)\n - **operator**: Comparison operator (CONTAINS, EQUALS, etc)\n - **value**: Value to compare against (case sensitive, max 255 chars)\n- **responseType**: Type of response when rule matches (e.g. BLOCK)\n\nExample:\n\`\`\`json\n${RuleExampleJson}\n\`\`\``,
81
+ examples: [
82
+ {
83
+ name: 'This is example rule name',
84
+ description: 'This is example rule description (optional)',
85
+ enabled: true,
86
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
87
+ conditions: [
88
+ {
89
+ headerName: 'user-agent',
90
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
91
+ value: 'Example Rule Value, replace with your own value',
92
+ },
93
+ ],
94
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
95
+ },
96
+ {
97
+ name: 'Empty rule',
98
+ enabled: true,
99
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
100
+ conditions: [],
101
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
102
+ },
103
+ ],
104
+ }));
@@ -4,7 +4,49 @@ exports.ResponseRulesConfigSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const constants_1 = require("../../constants");
6
6
  const response_rule_schema_1 = require("./response-rule.schema");
7
+ const RuleExampleJson = JSON.stringify({
8
+ name: 'Block Legacy Clients',
9
+ description: 'Block requests from legacy clients',
10
+ operator: constants_1.RESPONSE_RULES_OPERATORS.OR,
11
+ enabled: true,
12
+ conditions: [
13
+ {
14
+ headerName: 'user-agent',
15
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
16
+ value: 'Hiddify',
17
+ },
18
+ {
19
+ headerName: 'user-agent',
20
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
21
+ value: 'FoxRay',
22
+ },
23
+ ],
24
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
25
+ }, null, 2);
7
26
  exports.ResponseRulesConfigSchema = zod_1.z.object({
8
- version: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONFIG_VERSION),
9
- rules: zod_1.z.array(response_rule_schema_1.ResponseRuleSchema),
27
+ version: zod_1.z.nativeEnum(constants_1.RESPONSE_RULES_CONFIG_VERSION).describe(JSON.stringify({
28
+ title: 'Response Rules Config Version',
29
+ markdownDescription: 'Version of the **response rules** config. Currently supported version is **1**.',
30
+ })),
31
+ rules: zod_1.z.array(response_rule_schema_1.ResponseRuleSchema).describe(JSON.stringify({
32
+ examples: [
33
+ [
34
+ {
35
+ name: 'This is example rule name',
36
+ description: 'This is example rule description (optional)',
37
+ operator: constants_1.RESPONSE_RULES_OPERATORS.AND,
38
+ enabled: true,
39
+ conditions: [
40
+ {
41
+ headerName: 'user-agent',
42
+ operator: constants_1.RESPONSE_RULES_CONDITION_OPERATORS.CONTAINS,
43
+ value: 'Example Rule Value, replace with your own value',
44
+ },
45
+ ],
46
+ responseType: constants_1.RESPONSE_RULES_RESPONSE_TYPES.BLOCK,
47
+ },
48
+ ],
49
+ ],
50
+ markdownDescription: `Array of **response rules**.\n\nRules served from top to bottom – first matched rule is applied. Each rule is an object with the following properties:\n\n- **name**: Name of the response rule.\n- **description**: Description of the response rule.(Optional) \n- **enabled**: Whether the response rule is enabled. If disabled, the rule will not be applied.\n- **operator**: Operator to use for the rule.\n- **conditions**: Array of conditions to use for the rule.\n- **responseType**: Type of the response.\n\nExamples:\n\n1. Block legacy clients:\n\n\`\`\`json\n${RuleExampleJson}\n\`\`\`\n\nThis example shows how to block requests from legacy clients by checking if the User-Agent header contains "Hiddify" or "FoxRay".`,
51
+ })),
10
52
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnawave/backend-contract",
3
- "version": "2.1.74",
3
+ "version": "2.1.76",
4
4
  "public": true,
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "A contract library for Remnawave Backend. It can be used in backend and frontend.",
@@ -1,7 +0,0 @@
1
- export declare const ResponseRulesJsonSchema: import("zod-to-json-schema").JsonSchema7Type & {
2
- $schema?: string | undefined;
3
- definitions?: {
4
- [key: string]: import("zod-to-json-schema").JsonSchema7Type;
5
- } | undefined;
6
- };
7
- //# sourceMappingURL=response-rules-json-schema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"response-rules-json-schema.d.ts","sourceRoot":"","sources":["../../../../models/response-rules/response-rules-json-schema.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB;;;;;CAKlC,CAAC"}
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResponseRulesJsonSchema = void 0;
4
- const zod_to_json_schema_1 = require("zod-to-json-schema");
5
- const _1 = require(".");
6
- exports.ResponseRulesJsonSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(_1.ResponseRulesConfigSchema, {
7
- name: 'Response Rules Config Schema',
8
- $refStrategy: 'none',
9
- errorMessages: true,
10
- markdownDescription: true,
11
- });
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResponseRulesJsonSchema = void 0;
4
- const zod_to_json_schema_1 = require("zod-to-json-schema");
5
- const _1 = require(".");
6
- exports.ResponseRulesJsonSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(_1.ResponseRulesConfigSchema, {
7
- name: 'Response Rules Config Schema',
8
- $refStrategy: 'none',
9
- errorMessages: true,
10
- markdownDescription: true,
11
- });