@shaxpir/duiduidui-models 1.5.13 → 1.5.15

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.
@@ -72,4 +72,52 @@ export declare const Condition: {
72
72
  intermediate: () => DifficultyCondition;
73
73
  advanced: () => DifficultyCondition;
74
74
  expert: () => DifficultyCondition;
75
+ /**
76
+ * Check if starred condition is required (in 'all' section)
77
+ */
78
+ requiresStarred: (filters?: ConditionFilters) => boolean;
79
+ /**
80
+ * Check if starred condition is optional (in 'any' section)
81
+ */
82
+ allowsStarred: (filters?: ConditionFilters) => boolean;
83
+ /**
84
+ * Check if starred condition is excluded (in 'none' section)
85
+ */
86
+ excludesStarred: (filters?: ConditionFilters) => boolean;
87
+ /**
88
+ * Check if starred condition exists anywhere in filters
89
+ */
90
+ hasStarred: (filters?: ConditionFilters) => boolean;
91
+ /**
92
+ * Check if a specific tag is required (in 'all' section)
93
+ */
94
+ requiresTag: (filters: ConditionFilters | undefined, tag: string) => boolean;
95
+ /**
96
+ * Check if a specific tag is optional (in 'any' section)
97
+ */
98
+ allowsTag: (filters: ConditionFilters | undefined, tag: string) => boolean;
99
+ /**
100
+ * Check if a specific tag is excluded (in 'none' section)
101
+ */
102
+ excludesTag: (filters: ConditionFilters | undefined, tag: string) => boolean;
103
+ /**
104
+ * Check if a specific grade is required (in 'all' section)
105
+ */
106
+ requiresGrade: (filters: ConditionFilters | undefined, grade: "A" | "B" | "C" | "D" | "F") => boolean;
107
+ /**
108
+ * Check if any condition of a specific type exists in filters
109
+ */
110
+ hasConditionType: (filters: ConditionFilters | undefined, type: string) => boolean;
111
+ /**
112
+ * Validate filters for logical inconsistencies
113
+ * Returns an array of error messages, empty if valid
114
+ */
115
+ validate: (filters?: ConditionFilters) => string[];
116
+ hasStarredInAll: (filters?: ConditionFilters) => boolean;
117
+ hasStarredInAny: (filters?: ConditionFilters) => boolean;
118
+ hasStarredInNone: (filters?: ConditionFilters) => boolean;
119
+ hasTagInAll: (filters: ConditionFilters | undefined, tag: string) => boolean;
120
+ hasTagInAny: (filters: ConditionFilters | undefined, tag: string) => boolean;
121
+ hasTagInNone: (filters: ConditionFilters | undefined, tag: string) => boolean;
122
+ hasGradeInAll: (filters: ConditionFilters | undefined, grade: "A" | "B" | "C" | "D" | "F") => boolean;
75
123
  };
@@ -37,5 +37,106 @@ exports.Condition = {
37
37
  elementary: () => ({ type: 'difficulty', min: 100, max: 500 }), // Easy
38
38
  intermediate: () => ({ type: 'difficulty', min: 500, max: 1500 }), // Medium
39
39
  advanced: () => ({ type: 'difficulty', min: 1500, max: 3000 }), // Hard
40
- expert: () => ({ type: 'difficulty', min: 3000 }) // Very hard
40
+ expert: () => ({ type: 'difficulty', min: 3000 }), // Very hard
41
+ // Helper methods to check if conditions are present in filters
42
+ /**
43
+ * Check if starred condition is required (in 'all' section)
44
+ */
45
+ requiresStarred: (filters) => {
46
+ return !!(filters?.all?.some(c => c.type === 'starred' && c.value === true));
47
+ },
48
+ /**
49
+ * Check if starred condition is optional (in 'any' section)
50
+ */
51
+ allowsStarred: (filters) => {
52
+ return !!(filters?.any?.some(c => c.type === 'starred' && c.value === true));
53
+ },
54
+ /**
55
+ * Check if starred condition is excluded (in 'none' section)
56
+ */
57
+ excludesStarred: (filters) => {
58
+ return !!(filters?.none?.some(c => c.type === 'starred' && c.value === true));
59
+ },
60
+ /**
61
+ * Check if starred condition exists anywhere in filters
62
+ */
63
+ hasStarred: (filters) => {
64
+ return exports.Condition.requiresStarred(filters) ||
65
+ exports.Condition.allowsStarred(filters) ||
66
+ exports.Condition.excludesStarred(filters);
67
+ },
68
+ /**
69
+ * Check if a specific tag is required (in 'all' section)
70
+ */
71
+ requiresTag: (filters, tag) => {
72
+ return !!(filters?.all?.some(c => c.type === 'tag' && c.tag === tag));
73
+ },
74
+ /**
75
+ * Check if a specific tag is optional (in 'any' section)
76
+ */
77
+ allowsTag: (filters, tag) => {
78
+ return !!(filters?.any?.some(c => c.type === 'tag' && c.tag === tag));
79
+ },
80
+ /**
81
+ * Check if a specific tag is excluded (in 'none' section)
82
+ */
83
+ excludesTag: (filters, tag) => {
84
+ return !!(filters?.none?.some(c => c.type === 'tag' && c.tag === tag));
85
+ },
86
+ /**
87
+ * Check if a specific grade is required (in 'all' section)
88
+ */
89
+ requiresGrade: (filters, grade) => {
90
+ return !!(filters?.all?.some(c => c.type === 'grade' && c.grade === grade));
91
+ },
92
+ /**
93
+ * Check if any condition of a specific type exists in filters
94
+ */
95
+ hasConditionType: (filters, type) => {
96
+ return !!(filters?.all?.some(c => c.type === type) ||
97
+ filters?.any?.some(c => c.type === type) ||
98
+ filters?.none?.some(c => c.type === type));
99
+ },
100
+ /**
101
+ * Validate filters for logical inconsistencies
102
+ * Returns an array of error messages, empty if valid
103
+ */
104
+ validate: (filters) => {
105
+ if (!filters)
106
+ return [];
107
+ const errors = [];
108
+ // Check for contradictory starred conditions
109
+ if (exports.Condition.requiresStarred(filters) && exports.Condition.excludesStarred(filters)) {
110
+ errors.push('Cannot require starred items and exclude starred items at the same time');
111
+ }
112
+ // Check for contradictory tags
113
+ const allTags = filters.all?.filter(c => c.type === 'tag').map(c => c.tag) || [];
114
+ const noneTags = filters.none?.filter(c => c.type === 'tag').map(c => c.tag) || [];
115
+ allTags.forEach(tag => {
116
+ if (noneTags.includes(tag)) {
117
+ errors.push(`Tag "${tag}" cannot be both required and excluded`);
118
+ }
119
+ });
120
+ // Check for contradictory grades
121
+ const allGrades = filters.all?.filter(c => c.type === 'grade').map(c => c.grade) || [];
122
+ const noneGrades = filters.none?.filter(c => c.type === 'grade').map(c => c.grade) || [];
123
+ allGrades.forEach(grade => {
124
+ if (noneGrades.includes(grade)) {
125
+ errors.push(`Grade "${grade}" cannot be both required and excluded`);
126
+ }
127
+ });
128
+ // Check for multiple required grades (can only have one grade at a time)
129
+ if (allGrades.length > 1) {
130
+ errors.push(`Cannot require multiple grades: ${allGrades.join(', ')} - an item can only have one grade`);
131
+ }
132
+ return errors;
133
+ },
134
+ // Backward compatibility aliases (deprecated - use requiresStarred/allowsStarred/excludesStarred instead)
135
+ hasStarredInAll: (filters) => exports.Condition.requiresStarred(filters),
136
+ hasStarredInAny: (filters) => exports.Condition.allowsStarred(filters),
137
+ hasStarredInNone: (filters) => exports.Condition.excludesStarred(filters),
138
+ hasTagInAll: (filters, tag) => exports.Condition.requiresTag(filters, tag),
139
+ hasTagInAny: (filters, tag) => exports.Condition.allowsTag(filters, tag),
140
+ hasTagInNone: (filters, tag) => exports.Condition.excludesTag(filters, tag),
141
+ hasGradeInAll: (filters, grade) => exports.Condition.requiresGrade(filters, grade)
41
142
  };
@@ -32,10 +32,10 @@ export interface AnnotatedPhrase extends Phrase {
32
32
  phrase_id?: number;
33
33
  content_id?: ContentId;
34
34
  starred_at: CompactDateTime | null;
35
- alpha: number;
36
- beta: number;
37
- theta: number;
38
- uncertainty: number;
35
+ alpha: number | null;
36
+ beta: number | null;
37
+ theta: number | null;
38
+ uncertainty: number | null;
39
39
  reviews: ReviewLike[];
40
40
  user_tags: string[];
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaxpir/duiduidui-models",
3
- "version": "1.5.13",
3
+ "version": "1.5.15",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shaxpir/duiduidui-models"