@pisell/pisellos 2.2.62 → 2.2.63

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 (53) 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/Product/index.d.ts +1 -1
  9. package/dist/modules/Rules/index.d.ts +0 -1
  10. package/dist/modules/Rules/index.js +16 -28
  11. package/dist/solution/BookingByStep/index.d.ts +1 -1
  12. package/dist/solution/BookingTicket/index.d.ts +1 -1
  13. package/dist/solution/Checkout/index.js +1 -1
  14. package/dist/solution/ShopDiscount/index.js +1 -0
  15. package/lib/model/strategy/adapter/index.d.ts +0 -2
  16. package/lib/model/strategy/adapter/index.js +0 -6
  17. package/lib/model/strategy/adapter/walletPass/evaluator.js +1 -2
  18. package/lib/model/strategy/index.d.ts +93 -2
  19. package/lib/model/strategy/index.js +381 -6
  20. package/lib/modules/BaseModule.d.ts +0 -4
  21. package/lib/modules/BaseModule.js +0 -3
  22. package/lib/modules/Product/index.d.ts +1 -1
  23. package/lib/modules/Rules/index.d.ts +0 -1
  24. package/lib/modules/Rules/index.js +17 -23
  25. package/lib/solution/BookingByStep/index.d.ts +1 -1
  26. package/lib/solution/BookingTicket/index.d.ts +1 -1
  27. package/lib/solution/Checkout/index.js +1 -1
  28. package/lib/solution/ShopDiscount/index.js +2 -0
  29. package/package.json +1 -1
  30. package/dist/model/strategy/adapter/promotion/adapter.d.ts +0 -66
  31. package/dist/model/strategy/adapter/promotion/adapter.js +0 -271
  32. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +0 -213
  33. package/dist/model/strategy/adapter/promotion/evaluator.js +0 -1206
  34. package/dist/model/strategy/adapter/promotion/examples.d.ts +0 -138
  35. package/dist/model/strategy/adapter/promotion/examples.js +0 -166
  36. package/dist/model/strategy/adapter/promotion/index.d.ts +0 -4
  37. package/dist/model/strategy/adapter/promotion/index.js +0 -0
  38. package/dist/model/strategy/adapter/promotion/type.d.ts +0 -447
  39. package/dist/model/strategy/adapter/promotion/type.js +0 -209
  40. package/dist/model/strategy/engine.d.ts +0 -106
  41. package/dist/model/strategy/engine.js +0 -611
  42. package/lib/model/strategy/adapter/promotion/adapter.d.ts +0 -66
  43. package/lib/model/strategy/adapter/promotion/adapter.js +0 -217
  44. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +0 -213
  45. package/lib/model/strategy/adapter/promotion/evaluator.js +0 -844
  46. package/lib/model/strategy/adapter/promotion/examples.d.ts +0 -138
  47. package/lib/model/strategy/adapter/promotion/examples.js +0 -192
  48. package/lib/model/strategy/adapter/promotion/index.d.ts +0 -4
  49. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  50. package/lib/model/strategy/adapter/promotion/type.d.ts +0 -447
  51. package/lib/model/strategy/adapter/promotion/type.js +0 -51
  52. package/lib/model/strategy/engine.d.ts +0 -106
  53. 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
- });