semanticdb-core 1.1.0 → 1.1.1

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/index.d.ts CHANGED
@@ -9,5 +9,6 @@ export { getDrilldownDimensions } from './schema/schema.utils/getDrilldownDimens
9
9
  export * from './logicform/logicform';
10
10
  export * from './logicform/logicform.utils';
11
11
  export * from './logicform/types/query';
12
+ export * from './logicform/nameForPredNode';
12
13
  export * from './custom-function/utils';
13
14
  export * from './result/index';
package/dist/index.js CHANGED
@@ -27,5 +27,6 @@ Object.defineProperty(exports, "getDrilldownDimensions", { enumerable: true, get
27
27
  __exportStar(require("./logicform/logicform"), exports);
28
28
  __exportStar(require("./logicform/logicform.utils"), exports);
29
29
  __exportStar(require("./logicform/types/query"), exports);
30
+ __exportStar(require("./logicform/nameForPredNode"), exports);
30
31
  __exportStar(require("./custom-function/utils"), exports);
31
32
  __exportStar(require("./result/index"), exports);
@@ -0,0 +1,20 @@
1
+ import { SchemaType } from '../schema/schema';
2
+ import { PredItemType } from './logicform';
3
+ import { QueryType } from './types/query';
4
+ export interface ctx {
5
+ schemas: Record<string, SchemaType>;
6
+ customFunctions: Record<string, any>;
7
+ locale?: string;
8
+ }
9
+ /**
10
+ * 给Query起名
11
+ */
12
+ export declare const nameForQuery: (query: QueryType, schema: SchemaType, schemas: Record<string, SchemaType>) => string;
13
+ /**
14
+ * 给pred node起名, normalize阶段用到
15
+ * @param predNode - PredItemType
16
+ * @param s - schema object
17
+ * @param ctx - 上下文对象
18
+ * @returns 名称字符串
19
+ */
20
+ export declare const nameForPredNode: (predNode: PredItemType, s: SchemaType, ctx: ctx) => string | null;
@@ -0,0 +1,907 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.nameForPredNode = exports.nameForQuery = void 0;
7
+ const moment_1 = __importDefault(require("moment"));
8
+ const schema_utils_1 = require("../schema/schema.utils");
9
+ const utils_1 = require("../custom-function/utils");
10
+ const date_1 = require("../common/date");
11
+ // ============== 辅助函数 ==============
12
+ const getPropertyName = (property) => {
13
+ var _a;
14
+ if ((_a = property === null || property === void 0 ? void 0 : property.ui) === null || _a === void 0 ? void 0 : _a.title) {
15
+ return property.ui.title;
16
+ }
17
+ return property.name;
18
+ };
19
+ const twToChinese = (tw) => {
20
+ const map = {
21
+ year: '年',
22
+ quarter: '季度',
23
+ month: '月',
24
+ week: '周',
25
+ day: '日',
26
+ hour: '点',
27
+ minute: '分',
28
+ second: '秒',
29
+ };
30
+ return map[tw];
31
+ };
32
+ /**
33
+ * 中文转其他语言的简化实现
34
+ */
35
+ const zhCNToOthers = (cnText, locale = 'zh-CN') => {
36
+ if (locale.toLowerCase() === 'zh-cn') {
37
+ return cnText;
38
+ }
39
+ if (locale.startsWith('en')) {
40
+ const map = {
41
+ '同比': 'YoY%',
42
+ '环比': 'MoM%',
43
+ '周环比': 'WoW%',
44
+ '季度环比': 'QoQ%',
45
+ '同比差值': 'YoY Diff',
46
+ '环比差值': 'MoM Diff',
47
+ '同期': 'YoY',
48
+ '环期': 'MoM',
49
+ '周环期': 'WoW',
50
+ '占比': '%',
51
+ '数量': '#',
52
+ '累计': 'Cumulative ',
53
+ '年': 'Year',
54
+ '季度': 'Quarter',
55
+ '月': 'Month',
56
+ '周': 'Week',
57
+ '星期': 'Weekday',
58
+ '日': 'Day',
59
+ '小时': 'Hour',
60
+ '分钟': 'Minute',
61
+ '秒': 'Second',
62
+ '均': ' Avg',
63
+ '每小时': 'Hourly ',
64
+ '每小时段': 'By Hour ',
65
+ '分星期': 'By Weekday ',
66
+ '日均': 'Daily Avg ',
67
+ '月均': 'Monthly Avg ',
68
+ '周均': 'Weekly Avg ',
69
+ '上期': 'Previous Period ',
70
+ '按农历': ' (Lunar)',
71
+ '按星期': ' (By Weekday)',
72
+ '段': ' Range',
73
+ };
74
+ return map[cnText] || cnText;
75
+ }
76
+ return cnText;
77
+ };
78
+ /**
79
+ * 将相对日期转为中文问句
80
+ */
81
+ const relativeDateToQuestion = (value) => {
82
+ let toAdd = '';
83
+ const tws = (0, date_1.getSupportedTimeWindows)().reverse();
84
+ for (const tw of tws) {
85
+ if (tw in value) {
86
+ const chinese = twToChinese(tw);
87
+ if (chinese) {
88
+ if (typeof value[tw] === 'object') {
89
+ if (value[tw].$gte && value[tw].$lte) {
90
+ toAdd += `${value[tw].$gte}-${value[tw].$lte}${chinese}`;
91
+ }
92
+ else if (value[tw].$in) {
93
+ toAdd += `${value[tw].$in.join(',')}${chinese}`;
94
+ }
95
+ }
96
+ else {
97
+ toAdd += `${value[tw]}${chinese}`;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ if (value.$offset) {
103
+ if (value.$offset.year === 0) {
104
+ toAdd += '今年';
105
+ }
106
+ else if (value.$offset.year === -1) {
107
+ toAdd += '去年';
108
+ }
109
+ else if (value.$offset.year) {
110
+ toAdd += `${-value.$offset.year}年前`;
111
+ }
112
+ if (value.$offset.quarter === 0) {
113
+ toAdd += '本季度';
114
+ }
115
+ else if (value.$offset.quarter === -1) {
116
+ toAdd += '上季度';
117
+ }
118
+ else if (value.$offset.quarter) {
119
+ toAdd += `${-value.$offset.quarter}季度前`;
120
+ }
121
+ if (value.$offset.month === 0) {
122
+ toAdd += '本月';
123
+ }
124
+ else if (value.$offset.month === -1) {
125
+ toAdd += '上月';
126
+ }
127
+ else if (value.$offset.month) {
128
+ toAdd += `${-value.$offset.month}个月前`;
129
+ }
130
+ if (value.$offset.week === -1) {
131
+ toAdd += `上周`;
132
+ }
133
+ else if (value.$offset.week) {
134
+ toAdd += `${-value.$offset.week}周前`;
135
+ }
136
+ else if (value.$offset.week === 0) {
137
+ toAdd += '本周';
138
+ }
139
+ if (value.weekday) {
140
+ const weekdayMap = {
141
+ 1: '周一',
142
+ 2: '周二',
143
+ 3: '周三',
144
+ 4: '周四',
145
+ 5: '周五',
146
+ 6: '周六',
147
+ 7: '周日',
148
+ };
149
+ toAdd += weekdayMap[value.weekday] || '';
150
+ }
151
+ if (value.$offset.day === 0) {
152
+ toAdd += '今天';
153
+ }
154
+ else if (value.$offset.day === -1) {
155
+ toAdd += '昨天';
156
+ }
157
+ else if (value.$offset.day) {
158
+ toAdd += `${-value.$offset.day}天前`;
159
+ }
160
+ }
161
+ return toAdd;
162
+ };
163
+ // moment的帮助函数
164
+ const momentGetOneIndexedMonthByLevel = (date, level) => {
165
+ if (level === 'month') {
166
+ return date.get(level) + 1;
167
+ }
168
+ if (level === 'day') {
169
+ return date.get('date');
170
+ }
171
+ return date.get(level);
172
+ };
173
+ /**
174
+ * 将标准日期格式转为问句
175
+ */
176
+ const normalizedDateFormToQuestion = (date) => {
177
+ const start = (0, moment_1.default)(date.$gte);
178
+ const end = (0, moment_1.default)(date.$lte);
179
+ const formatter = 'YYYYMMDDHHmmss';
180
+ const levels = ['year', 'quarter', 'month', 'date'];
181
+ const processLevel = (levelIndex, baseRelativeForm = {}) => {
182
+ const level = levels[levelIndex];
183
+ if (!level)
184
+ return null;
185
+ if (start.get(level) === end.get(level)) {
186
+ if (start.format(formatter) === (0, moment_1.default)(start).startOf(level).format(formatter) &&
187
+ end.format(formatter) === (0, moment_1.default)(end).endOf(level).format(formatter)) {
188
+ const levelKey = level === 'date' ? 'day' : level;
189
+ const relativeDateForm = Object.assign(Object.assign({}, baseRelativeForm), { [levelKey]: momentGetOneIndexedMonthByLevel(start, level) });
190
+ if (relativeDateForm.month) {
191
+ delete relativeDateForm.quarter;
192
+ }
193
+ if (relativeDateForm.day) {
194
+ delete relativeDateForm.week;
195
+ }
196
+ return relativeDateToQuestion(relativeDateForm);
197
+ }
198
+ if (levelIndex >= levels.length) {
199
+ return null;
200
+ }
201
+ const newBaseRelativeForm = Object.assign(Object.assign({}, baseRelativeForm), { [level]: momentGetOneIndexedMonthByLevel(start, level) });
202
+ const innerQuestion = processLevel(levelIndex + 1, newBaseRelativeForm);
203
+ if (innerQuestion)
204
+ return innerQuestion;
205
+ // XTD
206
+ if (!innerQuestion) {
207
+ if (start.isSame((0, moment_1.default)(start).startOf(level)) && end.isSame((0, moment_1.default)().endOf('day'))) {
208
+ switch (level) {
209
+ case 'year':
210
+ return 'YTD';
211
+ case 'quarter':
212
+ return 'QTD';
213
+ case 'month':
214
+ return 'MTD';
215
+ }
216
+ }
217
+ }
218
+ return null;
219
+ }
220
+ return null;
221
+ };
222
+ const ret = processLevel(0, {});
223
+ if (ret)
224
+ return ret;
225
+ let startString = start.format('YYYY-MM-DD HH:mm:ss');
226
+ let endString = end.format('YYYY-MM-DD HH:mm:ss');
227
+ if (startString.endsWith(' 00:00:00') && endString.endsWith(' 23:59:59')) {
228
+ startString = startString.substring(0, 10);
229
+ endString = endString.substring(0, 10);
230
+ }
231
+ return `${startString}~${endString}`;
232
+ };
233
+ /**
234
+ * 将相对日期格式标准化
235
+ */
236
+ const normaliseRelativeDateForm = (value, config = {}) => {
237
+ if (config.startOfWeek === 'sunday') {
238
+ moment_1.default.locale('en');
239
+ }
240
+ let startDate = (0, moment_1.default)();
241
+ let endDate = (0, moment_1.default)();
242
+ const tws = (0, date_1.getSupportedTimeWindows)();
243
+ let granuality;
244
+ const others = {};
245
+ if (value.$calendar) {
246
+ others.$calendar = value.$calendar;
247
+ }
248
+ // 处理 $in 连续值
249
+ for (const [k, v] of Object.entries(value)) {
250
+ if (typeof v === 'object' && v && v.$in) {
251
+ let isContinuous = false;
252
+ const sorted = [...v.$in].sort((a, b) => a - b);
253
+ if (sorted[sorted.length - 1] - sorted[0] === sorted.length - 1) {
254
+ isContinuous = true;
255
+ }
256
+ if (isContinuous) {
257
+ value[k] = {
258
+ $gte: sorted[0],
259
+ $lte: sorted[sorted.length - 1],
260
+ };
261
+ }
262
+ }
263
+ }
264
+ let hasHitComplexDate = false;
265
+ if ('hour' in value && 'minute' in value && !('second' in value)) {
266
+ value.second = 0;
267
+ }
268
+ if (!('year' in value) && !('$offset' in value)) {
269
+ hasHitComplexDate = true;
270
+ if ('hour' in value && 'minute' in value && 'second' in value) {
271
+ others.$time = (0, moment_1.default)()
272
+ .hour(value.hour)
273
+ .minute(value.minute)
274
+ .second(value.second)
275
+ .format('HH:mm:ss');
276
+ }
277
+ }
278
+ if (('year' in value || ('$offset' in value && 'year' in value.$offset)) &&
279
+ 'day' in value &&
280
+ Object.keys(value).length === 2) {
281
+ hasHitComplexDate = true;
282
+ }
283
+ for (let index = tws.length - 1; index >= 0; index--) {
284
+ const tw = tws[index];
285
+ const valueInGran = value[tw];
286
+ if (tw in value) {
287
+ let twToSet = tw;
288
+ if (twToSet === 'day') {
289
+ twToSet = 'date';
290
+ }
291
+ else if (twToSet === 'weekday') {
292
+ twToSet = 'day';
293
+ }
294
+ if (!hasHitComplexDate && typeof valueInGran === 'number') {
295
+ granuality = tw;
296
+ if (twToSet === 'month') {
297
+ startDate.set(twToSet, valueInGran - 1);
298
+ endDate.set(twToSet, valueInGran - 1);
299
+ }
300
+ else if (twToSet === 'week') {
301
+ if (!value.month && !('$offset' in value && 'month' in value.$offset)) {
302
+ const twoDigitValue = `${valueInGran}`.padStart(2, '0');
303
+ startDate = (0, moment_1.default)(`${startDate.year()}${twoDigitValue}`, 'ggggww').startOf('week');
304
+ endDate = (0, moment_1.default)(startDate).endOf('week');
305
+ }
306
+ else {
307
+ startDate.startOf('month').startOf('week');
308
+ endDate.startOf('month').endOf('week');
309
+ }
310
+ }
311
+ else {
312
+ if ('period' in value && 'hour' in value && value.period === 'pm' && value.hour < 12) {
313
+ startDate.set(twToSet, valueInGran + 12);
314
+ endDate.set(twToSet, valueInGran + 12);
315
+ }
316
+ else {
317
+ startDate.set(twToSet, valueInGran);
318
+ endDate.set(twToSet, valueInGran);
319
+ }
320
+ }
321
+ }
322
+ else if (!hasHitComplexDate &&
323
+ valueInGran.$gte &&
324
+ valueInGran.$lte &&
325
+ Object.keys(valueInGran).length === 2) {
326
+ granuality = tw;
327
+ if (twToSet === 'month') {
328
+ startDate.set(twToSet, valueInGran.$gte - 1);
329
+ endDate.set(twToSet, valueInGran.$lte - 1);
330
+ }
331
+ else {
332
+ startDate.set(twToSet, valueInGran.$gte);
333
+ endDate.set(twToSet, valueInGran.$lte);
334
+ }
335
+ hasHitComplexDate = true;
336
+ }
337
+ else {
338
+ others[`$${tw}`] = valueInGran;
339
+ hasHitComplexDate = true;
340
+ if (tw === 'year') {
341
+ granuality = 'year';
342
+ if (typeof valueInGran === 'object' && valueInGran.$in) {
343
+ const startYear = Math.min(...valueInGran.$in);
344
+ const endYear = Math.max(...valueInGran.$in);
345
+ startDate.set('year', startYear);
346
+ endDate.set('year', endYear);
347
+ }
348
+ else if (typeof valueInGran === 'number') {
349
+ startDate.set('year', valueInGran);
350
+ endDate.set('year', valueInGran);
351
+ }
352
+ }
353
+ }
354
+ }
355
+ if ('$offset' in value && tw in value.$offset) {
356
+ if (!granuality || tws.indexOf(tw) < tws.indexOf(granuality)) {
357
+ granuality = tw;
358
+ }
359
+ startDate.add(value.$offset[tw], tw);
360
+ endDate.add(value.$offset[tw], tw);
361
+ }
362
+ }
363
+ const getMomentGran = (gran) => {
364
+ let momentGran = gran;
365
+ if (gran === 'weekday')
366
+ momentGran = 'day';
367
+ return momentGran || 'day';
368
+ };
369
+ const momentGran = getMomentGran(granuality);
370
+ const normed = Object.assign({ $gte: startDate.startOf(momentGran).toDate(), $lte: endDate.endOf(momentGran).toDate(), $options: Object.assign({}, value) }, others);
371
+ if (!granuality) {
372
+ delete normed.$gte;
373
+ delete normed.$lte;
374
+ }
375
+ if (normed.$options) {
376
+ delete normed.$options.$calendar;
377
+ }
378
+ moment_1.default.locale('zh-cn');
379
+ return normed;
380
+ };
381
+ // ============== nameForValue ==============
382
+ const nameForValue = (property, value, prefix) => {
383
+ let toAdd = '';
384
+ let propertyNameUsed = false;
385
+ if (property.primal_type === 'boolean') {
386
+ let negativePrefix = '';
387
+ if (value === true) {
388
+ negativePrefix = '';
389
+ }
390
+ else if (value === false) {
391
+ negativePrefix = '非';
392
+ }
393
+ else if (typeof value === 'object' && '$ne' in value) {
394
+ if (value.$ne)
395
+ negativePrefix = '非';
396
+ }
397
+ let booleanPredName = property.name;
398
+ if (booleanPredName.startsWith('是否')) {
399
+ booleanPredName = booleanPredName.slice(2);
400
+ }
401
+ else if (booleanPredName.startsWith('是不是')) {
402
+ booleanPredName = booleanPredName.slice(3);
403
+ }
404
+ toAdd = `${negativePrefix}${booleanPredName}`;
405
+ propertyNameUsed = true;
406
+ }
407
+ else if (property.primal_type === 'date') {
408
+ if ((0, date_1.isRelativeDateForm)(value) || typeof value === 'string') {
409
+ let postfix = '';
410
+ if (prefix === '大于等于') {
411
+ postfix = '以后';
412
+ }
413
+ else if (prefix === '小于等于') {
414
+ postfix = '以前';
415
+ }
416
+ if ((0, date_1.isRelativeDateForm)(value)) {
417
+ toAdd = relativeDateToQuestion(value);
418
+ }
419
+ else {
420
+ toAdd = value;
421
+ if ((0, moment_1.default)(toAdd).format('MMDDmmss') === '01010000') {
422
+ toAdd = (0, moment_1.default)(toAdd).format('YYYY年');
423
+ }
424
+ else if ((0, moment_1.default)(toAdd).format('HHmmss') === '000000') {
425
+ toAdd = (0, moment_1.default)(toAdd).format('YYYY年MM月DD日');
426
+ }
427
+ }
428
+ toAdd = `${toAdd}${postfix}`;
429
+ }
430
+ else if (typeof value === 'object' && value.$options && typeof value.$options === 'string') {
431
+ toAdd = value.$options;
432
+ }
433
+ else {
434
+ let low = value.$gte || value.$gt;
435
+ let high = value.$lte || value.$lt;
436
+ if (low && high) {
437
+ if ((0, date_1.isRelativeDateForm)(low)) {
438
+ if (value.$gte) {
439
+ low = normaliseRelativeDateForm(low).$gte;
440
+ }
441
+ else {
442
+ low = normaliseRelativeDateForm(low).$lte;
443
+ }
444
+ }
445
+ if ((0, date_1.isRelativeDateForm)(high)) {
446
+ if (value.$lte) {
447
+ high = normaliseRelativeDateForm(high).$lte;
448
+ }
449
+ else {
450
+ high = normaliseRelativeDateForm(high).$gte;
451
+ }
452
+ }
453
+ }
454
+ toAdd = normalizedDateFormToQuestion({
455
+ $gte: low,
456
+ $lte: high,
457
+ });
458
+ // $month, $year, etc...
459
+ const tws = (0, date_1.getSupportedTimeWindows)().reverse();
460
+ for (const tw of tws) {
461
+ if (`$${tw}` in value || tw in value) {
462
+ const data = value[`$${tw}`] || value[tw];
463
+ if (typeof data === 'object') {
464
+ if (data.$in) {
465
+ toAdd += `,${data.$in.join(',')}${twToChinese(tw)}`;
466
+ }
467
+ if (data.$gte && data.$lte) {
468
+ toAdd += `,${data.$gte}~${data.$lte}${twToChinese(tw)}`;
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+ }
475
+ else if (property.primal_type === 'object' && typeof value === 'boolean') {
476
+ if (value) {
477
+ toAdd = property.name;
478
+ }
479
+ else {
480
+ toAdd = `无${property.name}`;
481
+ }
482
+ propertyNameUsed = true;
483
+ }
484
+ else if (typeof value === 'object' && '$exists' in value) {
485
+ if (value.$exists) {
486
+ toAdd = `有${property.name}`;
487
+ }
488
+ else {
489
+ toAdd = `无${property.name}`;
490
+ }
491
+ propertyNameUsed = true;
492
+ }
493
+ else if (property.primal_type === 'object' && typeof value === 'object' && value.name) {
494
+ toAdd = value.name;
495
+ }
496
+ else if (typeof value !== 'object') {
497
+ toAdd += `${value}`;
498
+ }
499
+ else {
500
+ console.error(`[nameForQuery]未考虑到的情况: ${JSON.stringify(value)} `);
501
+ }
502
+ return { toAdd, propertyNameUsed };
503
+ };
504
+ // ============== nameForQuery ==============
505
+ /**
506
+ * 给Query起名
507
+ */
508
+ const nameForQuery = (query, schema, schemas) => {
509
+ const names = [];
510
+ for (const [pred, value] of Object.entries(query)) {
511
+ const property = (0, schema_utils_1.findPropertyByName)(schema._id, pred, schemas);
512
+ if (!property)
513
+ continue;
514
+ // skip agg_key
515
+ if (schema.agg_key && schema.agg_key.key === property.name)
516
+ continue;
517
+ const shouldNotAddPropertyName = property.primal_type === 'date' ||
518
+ property.is_categorical ||
519
+ property.is_name ||
520
+ property.primal_type === 'object';
521
+ let toAdd = '';
522
+ let propertyNameUsed = false;
523
+ if (typeof value === 'object' && value !== null) {
524
+ if ('schema' in value && 'query' in value) {
525
+ toAdd += (0, exports.nameForQuery)(value.query, schemas[value.schema], schemas);
526
+ }
527
+ else if (property.primal_type === 'date' &&
528
+ ((0, date_1.isStandardDateForm)(value) || (0, date_1.isRelativeDateForm)(value))) {
529
+ const res = nameForValue(property, value);
530
+ toAdd = res.toAdd;
531
+ propertyNameUsed = res.propertyNameUsed;
532
+ }
533
+ else {
534
+ Object.entries(value).forEach(([k, v]) => {
535
+ let shouldRunNameForValue = true;
536
+ if ('$gte' === k) {
537
+ toAdd += '大于等于';
538
+ }
539
+ else if ('$gt' === k) {
540
+ toAdd += '大于';
541
+ }
542
+ else if ('$ne' === k) {
543
+ toAdd += '不等于';
544
+ }
545
+ else if ('$eq' === k) {
546
+ toAdd += '为';
547
+ }
548
+ else if ('$lte' === k) {
549
+ toAdd += '小于等于';
550
+ }
551
+ else if ('$lt' === k) {
552
+ toAdd += '小于';
553
+ }
554
+ else if ('$exists' === k) {
555
+ toAdd += `${v ? (property.primal_type === 'object' ? '' : '有') : '无'}${property.name}`;
556
+ propertyNameUsed = true;
557
+ shouldRunNameForValue = false;
558
+ }
559
+ else if ('$regex' === k) {
560
+ propertyNameUsed = true;
561
+ shouldRunNameForValue = false;
562
+ }
563
+ else if ('$in' === k) {
564
+ toAdd = v
565
+ .map((vv) => {
566
+ return (0, exports.nameForQuery)({
567
+ [pred]: vv,
568
+ }, schema, schemas);
569
+ })
570
+ .join('或');
571
+ propertyNameUsed = true;
572
+ shouldRunNameForValue = false;
573
+ }
574
+ else if ('$nin' === k) {
575
+ toAdd =
576
+ '非' +
577
+ v
578
+ .map((vv) => {
579
+ return (0, exports.nameForQuery)({
580
+ [pred]: vv,
581
+ }, schema, schemas);
582
+ })
583
+ .join('且');
584
+ propertyNameUsed = true;
585
+ shouldRunNameForValue = false;
586
+ }
587
+ if (shouldRunNameForValue) {
588
+ const res = nameForValue(property, v, toAdd);
589
+ if (property.primal_type === 'date') {
590
+ toAdd = '';
591
+ }
592
+ toAdd += res.toAdd;
593
+ propertyNameUsed = res.propertyNameUsed;
594
+ }
595
+ });
596
+ }
597
+ }
598
+ else {
599
+ if (!shouldNotAddPropertyName) {
600
+ toAdd = '为';
601
+ }
602
+ const res = nameForValue(property, value, toAdd);
603
+ toAdd = toAdd + res.toAdd;
604
+ propertyNameUsed = res.propertyNameUsed;
605
+ }
606
+ if (!shouldNotAddPropertyName && !propertyNameUsed) {
607
+ toAdd = `${property.name}${toAdd}`;
608
+ }
609
+ names.push(toAdd);
610
+ }
611
+ let name = '';
612
+ for (let i = 0; i < names.length; i++) {
613
+ const element = names[i];
614
+ if (i > 0) {
615
+ const prev = names[i - 1];
616
+ if (prev.match('\\d$') && element.match('^\\d')) {
617
+ name += `,${element}`;
618
+ continue;
619
+ }
620
+ if (prev.match('[a-zA-Z]$') && element.match('^[a-zA-Z]')) {
621
+ name += ` ${element}`;
622
+ continue;
623
+ }
624
+ }
625
+ name += element;
626
+ }
627
+ return name;
628
+ };
629
+ exports.nameForQuery = nameForQuery;
630
+ // ============== nameForPredNode ==============
631
+ /**
632
+ * 给pred node起名, normalize阶段用到
633
+ * @param predNode - PredItemType
634
+ * @param s - schema object
635
+ * @param ctx - 上下文对象
636
+ * @returns 名称字符串
637
+ */
638
+ const nameForPredNode = (predNode, s, ctx) => {
639
+ var _a, _b, _c, _d;
640
+ const { schemas, customFunctions, locale = 'zh-CN' } = ctx;
641
+ if (typeof predNode !== 'object')
642
+ return null;
643
+ const schema = predNode.schema ? schemas[predNode.schema] : s;
644
+ let name = '';
645
+ // query
646
+ if (predNode.query) {
647
+ name += (0, exports.nameForQuery)(predNode.query, schema, schemas);
648
+ }
649
+ // operator
650
+ let useAggKey = false;
651
+ if (predNode.query && schema.agg_key && schema.agg_key.key in predNode.query) {
652
+ let keyName;
653
+ if (typeof predNode.query[schema.agg_key.key] === 'object' &&
654
+ predNode.query[schema.agg_key.key].query) {
655
+ keyName = Object.values(predNode.query[schema.agg_key.key].query)[0];
656
+ }
657
+ else {
658
+ keyName = predNode.query[schema.agg_key.key];
659
+ }
660
+ useAggKey = true;
661
+ let onlyValue = keyName;
662
+ while (typeof onlyValue === 'object') {
663
+ onlyValue = Object.values(onlyValue)[0];
664
+ }
665
+ name += onlyValue;
666
+ }
667
+ let defaultNameCalled = false;
668
+ if (predNode.operator) {
669
+ const func = (0, utils_1.findOneCustomFunction)(predNode.schema || schema._id, predNode.operator, customFunctions);
670
+ if (!func) {
671
+ throw new Error(`未注册的函数:${predNode.operator}`);
672
+ }
673
+ let basePredName = null;
674
+ let baseProperty = null;
675
+ if (typeof predNode.pred === 'object') {
676
+ basePredName = (0, exports.nameForPredNode)(predNode.pred, schema, ctx);
677
+ }
678
+ else if (predNode.pred) {
679
+ baseProperty = (0, schema_utils_1.findPropertyByName)(schema._id, predNode.pred, schemas);
680
+ if (baseProperty) {
681
+ basePredName = getPropertyName(baseProperty);
682
+ }
683
+ else {
684
+ basePredName = predNode.pred;
685
+ }
686
+ }
687
+ if (predNode.by) {
688
+ const addNameForByItem = (byItem) => {
689
+ if ([
690
+ '$year',
691
+ '$quarter',
692
+ '$month',
693
+ '$week',
694
+ '$weekday',
695
+ '$day',
696
+ '$hour',
697
+ '$minute',
698
+ '$second',
699
+ ].includes(byItem)) {
700
+ const dateLevelString = byItem.substring(1);
701
+ switch (dateLevelString) {
702
+ case 'year':
703
+ name += zhCNToOthers('年', locale);
704
+ break;
705
+ case 'quarter':
706
+ name += zhCNToOthers('季度', locale);
707
+ break;
708
+ case 'month':
709
+ name += zhCNToOthers('月', locale);
710
+ break;
711
+ case 'week':
712
+ name += zhCNToOthers('周', locale);
713
+ break;
714
+ case 'weekday':
715
+ name += zhCNToOthers('星期', locale);
716
+ break;
717
+ case 'day':
718
+ name += zhCNToOthers('日', locale);
719
+ break;
720
+ case 'hour':
721
+ name += zhCNToOthers('小时', locale);
722
+ break;
723
+ case 'minute':
724
+ name += zhCNToOthers('分钟', locale);
725
+ break;
726
+ case 'second':
727
+ name += zhCNToOthers('秒', locale);
728
+ break;
729
+ default:
730
+ throw new Error(`[nameForPred]不支持的日期级别:${dateLevelString}`);
731
+ }
732
+ }
733
+ else {
734
+ name += byItem;
735
+ }
736
+ };
737
+ if (typeof predNode.by === 'string') {
738
+ addNameForByItem(predNode.by);
739
+ }
740
+ else if (Array.isArray(predNode.by)) {
741
+ predNode.by.forEach((byItem) => addNameForByItem(byItem));
742
+ }
743
+ name += zhCNToOthers('均', locale);
744
+ }
745
+ if (func && func.defaultName) {
746
+ if (func.name === '$sql') {
747
+ name += func.defaultName(Object.assign(Object.assign({}, predNode), { schema }), locale, Object.assign(Object.assign({}, ctx), { nameForPredNode: exports.nameForPredNode }));
748
+ }
749
+ else if (func.name === '$count_recent' || func.name === '$count_repeat' || func.name === '$sql') {
750
+ name = func.defaultName(Object.assign(Object.assign({}, predNode), { name: basePredName, schema }), locale, Object.assign(Object.assign({}, ctx), { nameForPredNode: exports.nameForPredNode }));
751
+ }
752
+ else if (!(useAggKey && predNode.pred === ((_a = schema.agg_key) === null || _a === void 0 ? void 0 : _a.value))) {
753
+ name += func.defaultName(Object.assign(Object.assign(Object.assign({}, predNode), (baseProperty || {})), { name: basePredName, schema }), locale, Object.assign(Object.assign({}, ctx), { nameForPredNode: exports.nameForPredNode }));
754
+ }
755
+ defaultNameCalled = true;
756
+ }
757
+ else {
758
+ switch (predNode.operator) {
759
+ case '$hour':
760
+ name += `${zhCNToOthers('每小时', locale)}${basePredName}`;
761
+ break;
762
+ case '$toHour':
763
+ name += `${zhCNToOthers('每小时段', locale)}${basePredName}`;
764
+ break;
765
+ case '$weekday':
766
+ name += `${zhCNToOthers('分星期', locale)}${basePredName}`;
767
+ break;
768
+ case '$day':
769
+ name += `${zhCNToOthers('日', locale)}${basePredName}`;
770
+ break;
771
+ case '$year':
772
+ name += `${zhCNToOthers('年', locale)}${basePredName}`;
773
+ break;
774
+ case '$week':
775
+ name += `${zhCNToOthers('周', locale)}${basePredName}`;
776
+ break;
777
+ case '$month':
778
+ name += `${zhCNToOthers('月', locale)}${basePredName}`;
779
+ break;
780
+ case '$quarter':
781
+ name += `${zhCNToOthers('季度', locale)}${basePredName}`;
782
+ break;
783
+ case '$yoy':
784
+ case '$mom':
785
+ case '$wow':
786
+ case '$qoq':
787
+ case '$yoyd':
788
+ case '$momd':
789
+ case '$sply':
790
+ case '$splm':
791
+ case '$splw': {
792
+ const map = {
793
+ $yoy: '同比',
794
+ $mom: '环比',
795
+ $wow: '周环比',
796
+ $qoq: '季度环比',
797
+ $yoyd: '同比差值',
798
+ $momd: '环比差值',
799
+ $sply: '同期',
800
+ $splm: '环期',
801
+ $splw: '周环期',
802
+ };
803
+ if (map[predNode.operator] === '环期') {
804
+ name += `${zhCNToOthers('上期', locale)}${basePredName}`;
805
+ }
806
+ else if (map[predNode.operator] === '同期') {
807
+ name += `${zhCNToOthers(map[predNode.operator], locale)}${basePredName}`;
808
+ }
809
+ else {
810
+ name += `${basePredName}${zhCNToOthers(map[predNode.operator], locale)}`;
811
+ }
812
+ if (predNode.params) {
813
+ if ((_b = predNode.params[0]) === null || _b === void 0 ? void 0 : _b.time) {
814
+ const timestampProp = (0, schema_utils_1.findTimestampLikeProperty)(schema);
815
+ if (timestampProp) {
816
+ name += (0, exports.nameForQuery)({
817
+ [timestampProp.name]: predNode.params[0].time,
818
+ }, schema, schemas);
819
+ }
820
+ }
821
+ if (((_c = predNode.params[0]) === null || _c === void 0 ? void 0 : _c.by) === 'lunar') {
822
+ name += zhCNToOthers('按农历', locale);
823
+ }
824
+ else if (((_d = predNode.params[0]) === null || _d === void 0 ? void 0 : _d.by) === 'weekday') {
825
+ name += zhCNToOthers('按星期', locale);
826
+ }
827
+ }
828
+ break;
829
+ }
830
+ case '$percentage':
831
+ if (predNode.pred) {
832
+ if (typeof predNode.pred === 'object') {
833
+ name += (0, exports.nameForPredNode)(predNode.pred, schema, ctx);
834
+ }
835
+ else {
836
+ name += predNode.pred;
837
+ }
838
+ }
839
+ name += zhCNToOthers('占比', locale);
840
+ break;
841
+ case '$uniq':
842
+ if (predNode.pred) {
843
+ if (typeof predNode.pred === 'object') {
844
+ name += (0, exports.nameForPredNode)(predNode.pred, schema, ctx);
845
+ }
846
+ else {
847
+ name += predNode.pred;
848
+ }
849
+ }
850
+ name += zhCNToOthers('数量', locale);
851
+ break;
852
+ case '$dailyavg':
853
+ if (locale.startsWith('en')) {
854
+ name += `${basePredName} daily avg`;
855
+ }
856
+ else {
857
+ name += `${zhCNToOthers('日均', locale)}${basePredName}`;
858
+ }
859
+ break;
860
+ case '$monthlyavg':
861
+ if (locale.startsWith('en')) {
862
+ name += `${basePredName} monthly avg`;
863
+ }
864
+ else {
865
+ name += `${zhCNToOthers('月均', locale)}${basePredName}`;
866
+ }
867
+ break;
868
+ case '$weeklyavg':
869
+ if (locale.startsWith('en')) {
870
+ name += `${basePredName} weekly avg`;
871
+ }
872
+ else {
873
+ name += `${zhCNToOthers('周均', locale)}${basePredName}`;
874
+ }
875
+ break;
876
+ case '$piecewise':
877
+ name += `${basePredName}${zhCNToOthers('段', locale)}`;
878
+ break;
879
+ default:
880
+ name += predNode.operator;
881
+ break;
882
+ }
883
+ }
884
+ }
885
+ else if (predNode.pred) {
886
+ if (predNode.pred === '*') {
887
+ return null;
888
+ }
889
+ name += predNode.pred;
890
+ }
891
+ // level
892
+ if (!defaultNameCalled && predNode.level) {
893
+ name += `(${predNode.level})`;
894
+ }
895
+ // accumulate
896
+ if (predNode.accumulate) {
897
+ if (locale.startsWith('en')) {
898
+ // do nothing
899
+ }
900
+ else {
901
+ name = `${zhCNToOthers('累计', locale)}${name}`;
902
+ }
903
+ }
904
+ // feat: name 不能有下划线
905
+ return name.replace(/_/g, '');
906
+ };
907
+ exports.nameForPredNode = nameForPredNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "semanticdb-core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [