@malloydata/malloy-filter 0.0.237-dev250222025222 → 0.0.237-dev250222205057
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.
- package/dist/a_simple_parser.js +12 -9
- package/dist/a_simple_parser.js.map +1 -1
- package/dist/base_parser.d.ts +0 -2
- package/dist/base_parser.js.map +1 -1
- package/dist/boolean_parser.d.ts +2 -2
- package/dist/boolean_parser.js +3 -1
- package/dist/boolean_parser.js.map +1 -1
- package/dist/boolean_serializer.d.ts +4 -4
- package/dist/boolean_serializer.js +12 -4
- package/dist/boolean_serializer.js.map +1 -1
- package/dist/clause_types.d.ts +40 -47
- package/dist/date_parser.d.ts +13 -11
- package/dist/date_parser.js +192 -131
- package/dist/date_parser.js.map +1 -1
- package/dist/date_serializer.d.ts +6 -5
- package/dist/date_serializer.js +65 -77
- package/dist/date_serializer.js.map +1 -1
- package/dist/date_types.d.ts +75 -0
- package/dist/{filter_types.js → date_types.js} +1 -1
- package/dist/date_types.js.map +1 -0
- package/dist/generate_samples.js +162 -87
- package/dist/generate_samples.js.map +1 -1
- package/dist/number_parser.d.ts +2 -5
- package/dist/number_parser.js +10 -51
- package/dist/number_parser.js.map +1 -1
- package/dist/number_serializer.d.ts +4 -4
- package/dist/number_serializer.js +17 -14
- package/dist/number_serializer.js.map +1 -1
- package/dist/string_parser.d.ts +2 -2
- package/dist/string_parser.js +21 -21
- package/dist/string_parser.js.map +1 -1
- package/dist/string_serializer.d.ts +6 -5
- package/dist/string_serializer.js +38 -24
- package/dist/string_serializer.js.map +1 -1
- package/package.json +1 -2
- package/src/DEVELOPING.md +2 -5
- package/src/a_simple_parser.ts +12 -9
- package/src/base_parser.ts +0 -3
- package/src/boolean_parser.ts +10 -5
- package/src/boolean_serializer.ts +14 -7
- package/src/clause_types.ts +65 -108
- package/src/date_parser.ts +229 -192
- package/src/date_serializer.ts +59 -87
- package/src/date_types.ts +159 -0
- package/src/generate_samples.ts +178 -109
- package/src/number_parser.ts +14 -63
- package/src/number_serializer.ts +19 -20
- package/src/string_parser.ts +40 -27
- package/src/string_serializer.ts +58 -32
- package/tsconfig.json +1 -6
- package/dist/a_simple_serializer.d.ts +0 -1
- package/dist/a_simple_serializer.js +0 -31
- package/dist/a_simple_serializer.js.map +0 -1
- package/dist/base_serializer.d.ts +0 -6
- package/dist/base_serializer.js +0 -11
- package/dist/base_serializer.js.map +0 -1
- package/dist/filter_parser.d.ts +0 -12
- package/dist/filter_parser.js +0 -66
- package/dist/filter_parser.js.map +0 -1
- package/dist/filter_serializer.d.ts +0 -13
- package/dist/filter_serializer.js +0 -43
- package/dist/filter_serializer.js.map +0 -1
- package/dist/filter_types.d.ts +0 -10
- package/dist/filter_types.js.map +0 -1
- package/src/a_simple_serializer.ts +0 -40
- package/src/base_serializer.ts +0 -9
- package/src/filter_parser.ts +0 -68
- package/src/filter_serializer.ts +0 -49
- package/src/filter_types.ts +0 -12
package/src/date_serializer.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DateRange,
|
|
3
2
|
DateMoment,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Clause,
|
|
9
|
-
} from './clause_types';
|
|
10
|
-
import {BaseSerializer} from './base_serializer';
|
|
3
|
+
DateBetweenClause,
|
|
4
|
+
DateForClause,
|
|
5
|
+
DateClause,
|
|
6
|
+
} from './date_types';
|
|
11
7
|
|
|
12
|
-
export class DateSerializer
|
|
13
|
-
constructor(clauses:
|
|
14
|
-
|
|
8
|
+
export class DateSerializer {
|
|
9
|
+
constructor(private clauses: DateClause[]) {
|
|
10
|
+
this.clauses = clauses;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
public serialize(): string {
|
|
@@ -19,95 +15,71 @@ export class DateSerializer extends BaseSerializer {
|
|
|
19
15
|
return result.trim().replace(/,$/, '');
|
|
20
16
|
}
|
|
21
17
|
|
|
22
|
-
private static dateMomentToString(
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const custom: DateMomentInterval = clause as DateMomentInterval;
|
|
37
|
-
let value = custom.operator + ' ' + custom.unit;
|
|
38
|
-
if (custom.prefix) {
|
|
39
|
-
value = custom.prefix + ' ' + value;
|
|
40
|
-
}
|
|
41
|
-
return value;
|
|
42
|
-
} else if (operator === 'LASTN' || operator === 'NEXTN') {
|
|
43
|
-
const custom: DateMomentNumberInterval =
|
|
44
|
-
clause as DateMomentNumberInterval;
|
|
45
|
-
operator = operator.substring(0, 4); // Strip "N"
|
|
46
|
-
let value = operator + ' ' + custom.value + ' ' + custom.unit;
|
|
47
|
-
if (custom.prefix) {
|
|
48
|
-
value = custom.prefix + ' ' + value;
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
} else if (operator === 'AGO' || operator === 'FROMNOW') {
|
|
52
|
-
const custom: DateMomentNumberInterval =
|
|
53
|
-
clause as DateMomentNumberInterval;
|
|
54
|
-
if (operator === 'FROMNOW') operator = 'FROM NOW';
|
|
55
|
-
let value = custom.value + ' ' + custom.unit + ' ' + operator;
|
|
56
|
-
if (custom.prefix) {
|
|
57
|
-
value = custom.prefix + ' ' + value;
|
|
58
|
-
}
|
|
59
|
-
return value;
|
|
60
|
-
} else if (operator === 'TIMEBLOCK') {
|
|
61
|
-
const custom: DateMomentNumberUnit = clause as DateMomentNumberUnit;
|
|
62
|
-
let value = custom.value + ' ' + custom.unit;
|
|
63
|
-
if (custom.prefix) {
|
|
64
|
-
value = custom.prefix + ' ' + value;
|
|
65
|
-
}
|
|
66
|
-
return value;
|
|
67
|
-
} else if (operator === 'DATE' || operator === 'DATETIME') {
|
|
68
|
-
const custom: DateMomentNumber = clause as DateMomentNumber;
|
|
69
|
-
let value = custom.date;
|
|
70
|
-
if (custom.time) {
|
|
71
|
-
value = value + ' ' + custom.time;
|
|
72
|
-
}
|
|
73
|
-
if (custom.prefix) {
|
|
74
|
-
value = custom.prefix + ' ' + value;
|
|
75
|
-
}
|
|
76
|
-
return value;
|
|
18
|
+
private static dateMomentToString(moment: DateMoment): string {
|
|
19
|
+
if (moment.type === 'ABSOLUTE') {
|
|
20
|
+
return moment.date;
|
|
21
|
+
} else if (moment.type === 'INTERVAL') {
|
|
22
|
+
return moment.kind + ' ' + moment.unit;
|
|
23
|
+
} else if (moment.type === 'NAMED') {
|
|
24
|
+
return moment.name;
|
|
25
|
+
} else if (moment.type === 'OFFSET_FROM_NOW') {
|
|
26
|
+
const direction = moment.direction === 'FROMNOW' ? 'FROM NOW' : 'AGO';
|
|
27
|
+
return moment.amount + ' ' + moment.unit + ' ' + direction;
|
|
28
|
+
} else if (moment.type === 'SPAN_FROM_NOW') {
|
|
29
|
+
return moment.direction + ' ' + moment.amount + ' ' + moment.unit;
|
|
30
|
+
} else {
|
|
31
|
+
throw new Error('moment type not recognized ' + JSON.stringify(moment));
|
|
77
32
|
}
|
|
78
|
-
return '';
|
|
79
33
|
}
|
|
80
34
|
|
|
81
|
-
private static
|
|
82
|
-
operator: 'TO' | 'FOR',
|
|
83
|
-
clause: DateRange
|
|
84
|
-
): string {
|
|
35
|
+
private static goDateBetweenClause(clause: DateBetweenClause): string {
|
|
85
36
|
return (
|
|
86
|
-
DateSerializer.dateMomentToString(clause.
|
|
87
|
-
' ' +
|
|
88
|
-
clause.
|
|
37
|
+
DateSerializer.dateMomentToString(clause.from) +
|
|
38
|
+
' TO ' +
|
|
39
|
+
DateSerializer.dateMomentToString(clause.to)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private static goDateForClause(clause: DateForClause): string {
|
|
44
|
+
return (
|
|
45
|
+
DateSerializer.dateMomentToString(clause.from) +
|
|
46
|
+
' FOR ' +
|
|
47
|
+
clause.duration.amount +
|
|
89
48
|
' ' +
|
|
90
|
-
|
|
49
|
+
clause.duration.unit
|
|
91
50
|
);
|
|
92
51
|
}
|
|
93
52
|
|
|
94
|
-
private static clauseToString(
|
|
95
|
-
if (operator
|
|
96
|
-
|
|
97
|
-
|
|
53
|
+
private static clauseToString(clause: DateClause): string {
|
|
54
|
+
if (!('operator' in clause)) {
|
|
55
|
+
throw new Error('Invalid date clause ' + JSON.stringify(clause));
|
|
56
|
+
}
|
|
57
|
+
if (clause.operator === 'TO_RANGE') {
|
|
58
|
+
return DateSerializer.goDateBetweenClause(clause);
|
|
59
|
+
} else if (clause.operator === 'FOR_RANGE') {
|
|
60
|
+
return DateSerializer.goDateForClause(clause);
|
|
61
|
+
} else if (clause.operator === 'BEFORE') {
|
|
62
|
+
return 'BEFORE ' + DateSerializer.dateMomentToString(clause.moment);
|
|
63
|
+
} else if (clause.operator === 'AFTER') {
|
|
64
|
+
return 'AFTER ' + DateSerializer.dateMomentToString(clause.moment);
|
|
65
|
+
} else if (clause.operator === 'ON') {
|
|
66
|
+
return DateSerializer.dateMomentToString(clause.moment);
|
|
67
|
+
} else if (clause.operator === 'NULL') {
|
|
68
|
+
return 'NULL';
|
|
69
|
+
} else if (clause.operator === 'NOTNULL') {
|
|
70
|
+
return '-NULL';
|
|
71
|
+
} else if (clause.operator === 'DURATION') {
|
|
72
|
+
return clause.duration.amount + ' ' + clause.duration.unit;
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error('Clause type not recognized ' + JSON.stringify(clause));
|
|
98
75
|
}
|
|
99
|
-
return DateSerializer.dateMomentToString(operator, clause);
|
|
100
76
|
}
|
|
101
77
|
|
|
102
|
-
private static clausesToString(clauses:
|
|
78
|
+
private static clausesToString(clauses: DateClause[]): string {
|
|
103
79
|
let result = '';
|
|
104
80
|
for (const clause of clauses) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
result += ', ';
|
|
108
|
-
} else {
|
|
109
|
-
throw new Error('Invalid date clause ' + JSON.stringify(clause));
|
|
110
|
-
}
|
|
81
|
+
result += DateSerializer.clauseToString(clause);
|
|
82
|
+
result += ', ';
|
|
111
83
|
}
|
|
112
84
|
return result;
|
|
113
85
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {FilterError} from './clause_types';
|
|
2
|
+
|
|
3
|
+
export type DateTimeUnit =
|
|
4
|
+
| 'YEAR'
|
|
5
|
+
| 'QUARTER'
|
|
6
|
+
| 'MONTH'
|
|
7
|
+
| 'WEEK'
|
|
8
|
+
| 'DAY'
|
|
9
|
+
| 'HOUR'
|
|
10
|
+
| 'MINUTE'
|
|
11
|
+
| 'SECOND';
|
|
12
|
+
|
|
13
|
+
export type DateWeekday =
|
|
14
|
+
| 'MONDAY'
|
|
15
|
+
| 'TUESDAY'
|
|
16
|
+
| 'WEDNESDAY'
|
|
17
|
+
| 'THURSDAY'
|
|
18
|
+
| 'FRIDAY'
|
|
19
|
+
| 'SATURDAY'
|
|
20
|
+
| 'SUNDAY';
|
|
21
|
+
|
|
22
|
+
// 7 weeks, 32 hours
|
|
23
|
+
export interface Duration {
|
|
24
|
+
amount: number;
|
|
25
|
+
unit: DateTimeUnit;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type DateMomentName = 'NOW' | 'TODAY' | 'YESTERDAY' | 'TOMORROW';
|
|
29
|
+
|
|
30
|
+
// now, today, yesterday, tomorrow
|
|
31
|
+
export interface NamedMoment {
|
|
32
|
+
type: 'NAMED';
|
|
33
|
+
name: DateMomentName;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type DateMomentIntervalOperator = 'LAST' | 'THIS' | 'NEXT';
|
|
37
|
+
|
|
38
|
+
// LAST|UNITOFTIME, LAST|DAYOFWEEK
|
|
39
|
+
// THIS|UNITOFTIME
|
|
40
|
+
// NEXT|UNITOFTIME, NEXT|DAYOFWEEK
|
|
41
|
+
// last month, next tuesday, this month
|
|
42
|
+
export interface IntervalMoment {
|
|
43
|
+
type: 'INTERVAL';
|
|
44
|
+
kind: DateMomentIntervalOperator;
|
|
45
|
+
unit: DateTimeUnit | DateWeekday;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type DateMomentOffsetFromNowDirection = 'AGO' | 'FROMNOW';
|
|
49
|
+
|
|
50
|
+
// NUMBER|UNITOFTIME|AGO
|
|
51
|
+
// NUMBER|UNITOFTIME|FROM|NOW
|
|
52
|
+
// 3 hours ago, 6 weeks from now
|
|
53
|
+
export interface OffsetMoment {
|
|
54
|
+
type: 'OFFSET_FROM_NOW';
|
|
55
|
+
direction: DateMomentOffsetFromNowDirection;
|
|
56
|
+
unit: DateTimeUnit;
|
|
57
|
+
amount: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type DateMomentSpanFromNowDirection = 'LAST' | 'NEXT';
|
|
61
|
+
|
|
62
|
+
// LAST|NUMBER|UNITOFTIME
|
|
63
|
+
// NEXT|NUMBER|UNITOFTIME
|
|
64
|
+
// last 3 hours, next 2025 seconds, last 6 weeks
|
|
65
|
+
export interface SpanMoment {
|
|
66
|
+
type: 'SPAN_FROM_NOW';
|
|
67
|
+
direction: DateMomentSpanFromNowDirection;
|
|
68
|
+
unit: DateTimeUnit;
|
|
69
|
+
amount: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 2005, 2005-01, 2005-01-01, 2005-01-01 00:00, 2005-01-01 00:00:01
|
|
73
|
+
export interface AbsoluteMoment {
|
|
74
|
+
type: 'ABSOLUTE';
|
|
75
|
+
date: string;
|
|
76
|
+
unit: DateTimeUnit;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 2025-01
|
|
80
|
+
// {
|
|
81
|
+
// operator: 'ON';
|
|
82
|
+
// moment: { date: '2025-01';
|
|
83
|
+
// unit: 'MONTH' }
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
// after 2025-01
|
|
87
|
+
// {
|
|
88
|
+
// operator: 'AFTER';
|
|
89
|
+
// moment: { date: '2025-01';
|
|
90
|
+
// unit: 'MONTH' }
|
|
91
|
+
// }
|
|
92
|
+
|
|
93
|
+
export type DateMoment =
|
|
94
|
+
| AbsoluteMoment // 2005-01
|
|
95
|
+
| NamedMoment // "today"
|
|
96
|
+
| IntervalMoment // "this month"
|
|
97
|
+
| SpanMoment // "last 3 weeks, next 3 weeks
|
|
98
|
+
| OffsetMoment; // "3 days ago"
|
|
99
|
+
|
|
100
|
+
// after 2005-01, after 3 hours ago
|
|
101
|
+
export interface DateAfterClause {
|
|
102
|
+
operator: 'AFTER';
|
|
103
|
+
moment: DateMoment;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// before 2005-01, before 3 hours ago
|
|
107
|
+
export interface DateBeforeClause {
|
|
108
|
+
operator: 'BEFORE';
|
|
109
|
+
moment: DateMoment;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// next week, last 3 weeks, 3 days ago
|
|
113
|
+
export interface DateOnClause {
|
|
114
|
+
operator: 'ON';
|
|
115
|
+
moment: DateMoment;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 2015 to next month
|
|
119
|
+
export interface DateBetweenClause {
|
|
120
|
+
operator: 'TO_RANGE';
|
|
121
|
+
from: DateMoment;
|
|
122
|
+
to: DateMoment;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2025-01-01 12:00:00 for 3 days
|
|
126
|
+
export interface DateForClause {
|
|
127
|
+
operator: 'FOR_RANGE';
|
|
128
|
+
from: DateMoment;
|
|
129
|
+
duration: Duration;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface DateNullClause {
|
|
133
|
+
operator: 'NULL';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface DateNotNullClause {
|
|
137
|
+
operator: 'NOTNULL';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 3 days
|
|
141
|
+
export interface DateDurationClause {
|
|
142
|
+
operator: 'DURATION';
|
|
143
|
+
duration: Duration;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export type DateClause =
|
|
147
|
+
| DateAfterClause
|
|
148
|
+
| DateBeforeClause
|
|
149
|
+
| DateOnClause
|
|
150
|
+
| DateBetweenClause
|
|
151
|
+
| DateForClause
|
|
152
|
+
| DateNullClause
|
|
153
|
+
| DateNotNullClause
|
|
154
|
+
| DateDurationClause;
|
|
155
|
+
|
|
156
|
+
export interface DateParserResponse {
|
|
157
|
+
clauses: DateClause[];
|
|
158
|
+
errors: FilterError[];
|
|
159
|
+
}
|