@pisell/pisellos 2.2.47 → 2.2.49

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 (43) hide show
  1. package/dist/model/strategy/adapter/index.d.ts +0 -2
  2. package/dist/model/strategy/adapter/index.js +1 -2
  3. package/dist/model/strategy/adapter/walletPass/evaluator.js +1 -4
  4. package/dist/model/strategy/index.d.ts +93 -2
  5. package/dist/model/strategy/index.js +549 -6
  6. package/dist/modules/BaseModule.d.ts +0 -4
  7. package/dist/modules/BaseModule.js +0 -5
  8. package/dist/modules/Payment/index.js +4 -0
  9. package/dist/modules/Payment/types.d.ts +2 -0
  10. package/dist/modules/Product/index.d.ts +1 -1
  11. package/dist/modules/Rules/index.d.ts +0 -1
  12. package/dist/modules/Rules/index.js +16 -28
  13. package/dist/solution/BookingTicket/index.d.ts +1 -1
  14. package/lib/model/strategy/adapter/index.d.ts +0 -2
  15. package/lib/model/strategy/adapter/index.js +0 -5
  16. package/lib/model/strategy/adapter/walletPass/evaluator.js +1 -2
  17. package/lib/model/strategy/index.d.ts +93 -2
  18. package/lib/model/strategy/index.js +381 -6
  19. package/lib/modules/BaseModule.d.ts +0 -4
  20. package/lib/modules/BaseModule.js +0 -3
  21. package/lib/modules/Payment/index.js +4 -1
  22. package/lib/modules/Payment/types.d.ts +2 -0
  23. package/lib/modules/Product/index.d.ts +1 -1
  24. package/lib/modules/Rules/index.d.ts +0 -1
  25. package/lib/modules/Rules/index.js +17 -23
  26. package/lib/solution/BookingTicket/index.d.ts +1 -1
  27. package/package.json +1 -1
  28. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +0 -212
  29. package/dist/model/strategy/adapter/promotion/evaluator.js +0 -1180
  30. package/dist/model/strategy/adapter/promotion/index.d.ts +0 -206
  31. package/dist/model/strategy/adapter/promotion/index.js +0 -447
  32. package/dist/model/strategy/adapter/promotion/type.d.ts +0 -447
  33. package/dist/model/strategy/adapter/promotion/type.js +0 -209
  34. package/dist/model/strategy/engine.d.ts +0 -106
  35. package/dist/model/strategy/engine.js +0 -611
  36. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +0 -212
  37. package/lib/model/strategy/adapter/promotion/evaluator.js +0 -824
  38. package/lib/model/strategy/adapter/promotion/index.d.ts +0 -206
  39. package/lib/model/strategy/adapter/promotion/index.js +0 -386
  40. package/lib/model/strategy/adapter/promotion/type.d.ts +0 -447
  41. package/lib/model/strategy/adapter/promotion/type.js +0 -51
  42. package/lib/model/strategy/engine.d.ts +0 -106
  43. package/lib/model/strategy/engine.js +0 -450
@@ -1,450 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // src/model/strategy/engine.ts
20
- var engine_exports = {};
21
- __export(engine_exports, {
22
- StrategyEngine: () => StrategyEngine,
23
- createStrategyEngine: () => createStrategyEngine,
24
- evaluate: () => evaluate
25
- });
26
- module.exports = __toCommonJS(engine_exports);
27
- var import_type = require("./type");
28
- var StrategyEngine = class {
29
- constructor(options = {}) {
30
- this.options = {
31
- debug: options.debug ?? false,
32
- enableTrace: options.enableTrace ?? false,
33
- operatorHandlers: options.operatorHandlers ?? {},
34
- errorHandler: options.errorHandler ?? ((error) => console.error(error))
35
- };
36
- this.operatorHandlers = new Map(
37
- Object.entries(this.options.operatorHandlers)
38
- );
39
- this.initializeBuiltInOperators();
40
- }
41
- /**
42
- * 评估策略
43
- */
44
- evaluate(config, context) {
45
- var _a;
46
- const startTime = Date.now();
47
- const trace = {
48
- steps: [],
49
- duration: 0,
50
- errors: []
51
- };
52
- try {
53
- this.validateConfig(config);
54
- if (this.options.enableTrace) {
55
- trace.steps.push({
56
- step: "validate_config",
57
- status: "success",
58
- duration: Date.now() - startTime
59
- });
60
- }
61
- const evaluateStart = Date.now();
62
- const evaluationResult = this.evaluateConditionGroup(
63
- config.conditions,
64
- context
65
- );
66
- if (this.options.enableTrace) {
67
- trace.steps.push({
68
- step: "evaluate_conditions",
69
- status: "success",
70
- duration: Date.now() - evaluateStart,
71
- details: {
72
- satisfied: evaluationResult.satisfied,
73
- collectedActionIds: evaluationResult.actionIds
74
- }
75
- });
76
- }
77
- const actionStart = Date.now();
78
- const matchedActions = this.getActionsByIds(
79
- evaluationResult.actionIds,
80
- config.actions
81
- );
82
- if (this.options.enableTrace) {
83
- trace.steps.push({
84
- step: "get_actions",
85
- status: "success",
86
- duration: Date.now() - actionStart,
87
- details: { matchedCount: matchedActions.length }
88
- });
89
- }
90
- const sortStart = Date.now();
91
- const sortedActions = this.sortActionsByPriority(matchedActions);
92
- if (this.options.enableTrace) {
93
- trace.steps.push({
94
- step: "sort_actions",
95
- status: "success",
96
- duration: Date.now() - sortStart
97
- });
98
- }
99
- const applicable = evaluationResult.satisfied;
100
- const result = {
101
- success: true,
102
- applicable,
103
- code: applicable ? import_type.SUCCESS_CODES.SUCCESS : import_type.NOT_APPLICABLE_CODES.CONDITION_NOT_MET,
104
- message: applicable ? "Strategy is applicable" : "Conditions not met",
105
- matched: {
106
- conditions: applicable,
107
- actionIds: evaluationResult.actionIds,
108
- details: {}
109
- },
110
- matchedActions: sortedActions,
111
- outputs: {},
112
- config
113
- };
114
- trace.duration = Date.now() - startTime;
115
- if (this.options.enableTrace) {
116
- result.trace = trace;
117
- }
118
- return result;
119
- } catch (error) {
120
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
121
- if (this.options.enableTrace) {
122
- (_a = trace.errors) == null ? void 0 : _a.push({
123
- step: "evaluation",
124
- error: errorMessage,
125
- timestamp: Date.now()
126
- });
127
- trace.duration = Date.now() - startTime;
128
- }
129
- this.options.errorHandler(error, context);
130
- return {
131
- success: false,
132
- applicable: false,
133
- code: import_type.ERROR_CODES.EVALUATION_ERROR,
134
- message: errorMessage,
135
- matched: {
136
- conditions: false,
137
- actionIds: [],
138
- details: {}
139
- },
140
- matchedActions: [],
141
- outputs: {},
142
- trace: this.options.enableTrace ? trace : void 0,
143
- config
144
- };
145
- }
146
- }
147
- /**
148
- * 递归评估条件组
149
- *
150
- * @param group 条件组
151
- * @param context 运行时上下文
152
- * @returns 评估结果对象,包含条件是否满足和收集到的 actionIds
153
- */
154
- evaluateConditionGroup(group, context) {
155
- const collectedActionIds = [];
156
- const isCurrentLayerSatisfied = this.evaluateGroupLogic(group, context);
157
- if (isCurrentLayerSatisfied) {
158
- collectedActionIds.push(...group.actionIds);
159
- for (const rule of group.rules) {
160
- if (this.isConditionGroup(rule)) {
161
- const nestedResult = this.evaluateConditionGroup(rule, context);
162
- collectedActionIds.push(...nestedResult.actionIds);
163
- }
164
- }
165
- }
166
- return {
167
- satisfied: isCurrentLayerSatisfied,
168
- actionIds: collectedActionIds
169
- };
170
- }
171
- /**
172
- * 评估条件组的逻辑运算
173
- */
174
- evaluateGroupLogic(group, context) {
175
- const { operator, rules } = group;
176
- switch (operator) {
177
- case "and":
178
- return rules.every((rule) => this.evaluateRule(rule, context));
179
- case "or":
180
- return rules.some((rule) => this.evaluateRule(rule, context));
181
- case "not":
182
- if (rules.length === 0)
183
- return false;
184
- return !this.evaluateRule(rules[0], context);
185
- default:
186
- throw new Error(`Unknown operator: ${operator}`);
187
- }
188
- }
189
- /**
190
- * 评估单个规则
191
- */
192
- evaluateRule(rule, context) {
193
- if (this.isConditionGroup(rule)) {
194
- return this.evaluateGroupLogic(rule, context);
195
- }
196
- const conditionRule = rule;
197
- if (conditionRule.type === "code" && conditionRule.code) {
198
- return this.evaluateCodeCondition(conditionRule.code, context);
199
- }
200
- return this.evaluateOperatorCondition(conditionRule, context);
201
- }
202
- /**
203
- * 评估代码模式条件
204
- */
205
- evaluateCodeCondition(code, context) {
206
- try {
207
- const { entities, attributes, metadata } = context;
208
- const evalFunc = new Function(
209
- "entities",
210
- "attributes",
211
- "metadata",
212
- `return (${code})`
213
- );
214
- const result = evalFunc(entities, attributes, metadata);
215
- return Boolean(result);
216
- } catch (error) {
217
- if (this.options.debug) {
218
- console.error("Code evaluation error:", error);
219
- }
220
- return false;
221
- }
222
- }
223
- /**
224
- * 评估运算符模式条件
225
- */
226
- evaluateOperatorCondition(rule, context) {
227
- const { field, operator, value } = rule;
228
- if (!field || !operator) {
229
- return false;
230
- }
231
- const fieldValue = this.getFieldValue(field, context);
232
- const handler = this.operatorHandlers.get(operator);
233
- if (handler) {
234
- return handler(fieldValue, value, rule);
235
- }
236
- return this.evaluateBuiltInOperator(fieldValue, operator, value);
237
- }
238
- /**
239
- * 获取字段值
240
- */
241
- getFieldValue(field, context) {
242
- const path = field.split(".");
243
- let value = context.attributes;
244
- for (const key of path) {
245
- if (value && typeof value === "object" && key in value) {
246
- value = value[key];
247
- } else {
248
- return void 0;
249
- }
250
- }
251
- return value;
252
- }
253
- /**
254
- * 评估内置运算符
255
- */
256
- evaluateBuiltInOperator(fieldValue, operator, compareValue) {
257
- switch (operator) {
258
- case "=":
259
- case "==":
260
- return fieldValue == compareValue;
261
- case "!=":
262
- return fieldValue != compareValue;
263
- case ">":
264
- return fieldValue > compareValue;
265
- case ">=":
266
- return fieldValue >= compareValue;
267
- case "<":
268
- return fieldValue < compareValue;
269
- case "<=":
270
- return fieldValue <= compareValue;
271
- case "in":
272
- return Array.isArray(compareValue) && compareValue.includes(fieldValue);
273
- case "not_in":
274
- return Array.isArray(compareValue) && !compareValue.includes(fieldValue);
275
- case "contains":
276
- if (Array.isArray(fieldValue)) {
277
- return fieldValue.includes(compareValue);
278
- }
279
- if (typeof fieldValue === "string") {
280
- return fieldValue.includes(compareValue);
281
- }
282
- return false;
283
- case "not_contains":
284
- if (Array.isArray(fieldValue)) {
285
- return !fieldValue.includes(compareValue);
286
- }
287
- if (typeof fieldValue === "string") {
288
- return !fieldValue.includes(compareValue);
289
- }
290
- return true;
291
- case "starts_with":
292
- return typeof fieldValue === "string" && fieldValue.startsWith(compareValue);
293
- case "ends_with":
294
- return typeof fieldValue === "string" && fieldValue.endsWith(compareValue);
295
- case "regex":
296
- return typeof fieldValue === "string" && new RegExp(compareValue).test(fieldValue);
297
- case "between":
298
- if (!Array.isArray(compareValue) || compareValue.length !== 2)
299
- return false;
300
- return fieldValue >= compareValue[0] && fieldValue <= compareValue[1];
301
- case "is_null":
302
- return fieldValue === null || fieldValue === void 0;
303
- case "is_not_null":
304
- return fieldValue !== null && fieldValue !== void 0;
305
- case "is_empty":
306
- if (Array.isArray(fieldValue))
307
- return fieldValue.length === 0;
308
- if (typeof fieldValue === "string")
309
- return fieldValue.length === 0;
310
- if (typeof fieldValue === "object")
311
- return Object.keys(fieldValue).length === 0;
312
- return !fieldValue;
313
- case "is_not_empty":
314
- if (Array.isArray(fieldValue))
315
- return fieldValue.length > 0;
316
- if (typeof fieldValue === "string")
317
- return fieldValue.length > 0;
318
- if (typeof fieldValue === "object")
319
- return Object.keys(fieldValue).length > 0;
320
- return Boolean(fieldValue);
321
- case "product_match":
322
- return this.evaluateProductMatch(fieldValue, compareValue);
323
- case "object_in":
324
- return this.evaluateProductMatch(fieldValue, compareValue);
325
- default:
326
- throw new Error(`Unsupported operator: ${operator}`);
327
- }
328
- }
329
- /**
330
- * 根据 actionIds 获取 ActionEffect 对象
331
- */
332
- getActionsByIds(actionIds, actions) {
333
- const matchedActions = [];
334
- const actionMap = new Map(actions.map((action) => [action.id, action]));
335
- for (const id of actionIds) {
336
- const action = actionMap.get(id);
337
- if (action) {
338
- matchedActions.push(action);
339
- } else {
340
- if (this.options.debug) {
341
- console.warn(`Action with id "${id}" not found in actions array`);
342
- }
343
- }
344
- }
345
- return matchedActions;
346
- }
347
- /**
348
- * 按 priority 排序(降序)
349
- */
350
- sortActionsByPriority(actions) {
351
- return [...actions].sort((a, b) => {
352
- const priorityA = a.priority ?? 0;
353
- const priorityB = b.priority ?? 0;
354
- return priorityB - priorityA;
355
- });
356
- }
357
- /**
358
- * 判断是否为条件组
359
- */
360
- isConditionGroup(rule) {
361
- return "operator" in rule && "rules" in rule && Array.isArray(rule.rules);
362
- }
363
- /**
364
- * 验证配置
365
- */
366
- validateConfig(config) {
367
- if (!config) {
368
- throw new Error("Strategy config is required");
369
- }
370
- if (!config.metadata || !config.metadata.id) {
371
- throw new Error("Strategy metadata.id is required");
372
- }
373
- if (!config.conditions) {
374
- throw new Error("Strategy conditions is required");
375
- }
376
- if (!Array.isArray(config.actions)) {
377
- throw new Error("Strategy actions must be an array");
378
- }
379
- }
380
- /**
381
- * 初始化内置运算符处理器
382
- */
383
- initializeBuiltInOperators() {
384
- }
385
- /**
386
- * 评估商品匹配运算符
387
- *
388
- * 匹配规则:
389
- * - 首先匹配 product_id
390
- * - 如果配置的 product_variant_id = 0,只需要 product_id 匹配(表示任意变体)
391
- * - 如果配置的 product_variant_id != 0,还需要 product_variant_id 精确匹配
392
- *
393
- * @param fieldValue 实际商品 { product_id: number, product_variant_id: number }
394
- * @param configValue 配置的商品列表 Array<{ product_id: number, product_variant_id: number }>
395
- * @returns 是否匹配
396
- */
397
- evaluateProductMatch(fieldValue, configValue) {
398
- if (!Array.isArray(configValue)) {
399
- return false;
400
- }
401
- if (!fieldValue || typeof fieldValue !== "object" || typeof fieldValue.product_id !== "number") {
402
- return false;
403
- }
404
- const actualProductId = fieldValue.product_id;
405
- const actualVariantId = fieldValue.product_variant_id ?? 0;
406
- return configValue.some((item) => {
407
- if (!item || typeof item.product_id !== "number") {
408
- return false;
409
- }
410
- const configProductId = item.product_id;
411
- const configVariantId = item.product_variant_id ?? 0;
412
- if (configProductId !== actualProductId) {
413
- return false;
414
- }
415
- if (configVariantId === 0) {
416
- return true;
417
- }
418
- return configVariantId === actualVariantId;
419
- });
420
- }
421
- /**
422
- * 注册自定义运算符
423
- */
424
- registerOperator(operator, handler) {
425
- this.operatorHandlers.set(operator, handler);
426
- }
427
- /**
428
- * 获取调试信息
429
- */
430
- getDebugInfo() {
431
- return {
432
- debug: this.options.debug,
433
- enableTrace: this.options.enableTrace,
434
- registeredOperators: Array.from(this.operatorHandlers.keys())
435
- };
436
- }
437
- };
438
- function createStrategyEngine(options) {
439
- return new StrategyEngine(options);
440
- }
441
- function evaluate(config, context) {
442
- const engine = new StrategyEngine();
443
- return engine.evaluate(config, context);
444
- }
445
- // Annotate the CommonJS export names for ESM import in node:
446
- 0 && (module.exports = {
447
- StrategyEngine,
448
- createStrategyEngine,
449
- evaluate
450
- });