@chatbi-v/mocks 1.0.1 → 2.0.0

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/adapter.js CHANGED
@@ -36,73 +36,81 @@ export class MockAdapter {
36
36
  * @returns Promise 返回模拟的响应数据
37
37
  */
38
38
  async request(config, endpointConfig) {
39
- return new Promise((resolve) => {
39
+ // 优先使用接口定义的 delay,否则使用全局默认 delay
40
+ const delay = endpointConfig?.delay ?? this.delay;
41
+ return new Promise((resolve, reject) => {
40
42
  setTimeout(() => {
41
- if (!endpointConfig || !endpointConfig.responseSchema) {
42
- logger.warn(`未找到响应架构配置: ${config.url}`);
43
- resolve({});
44
- return;
45
- }
46
- let schema = endpointConfig.responseSchema;
47
- let mockData;
48
- // 支持函数式 schema,允许根据请求参数动态生成 schema
49
- if (typeof schema === 'function') {
50
- schema = schema(config);
51
- }
52
- // 构造有效配置对象,合并 endpointConfig 顶层属性
53
- const effectiveConfig = {
54
- type: endpointConfig.type,
55
- pageEvent: endpointConfig.pageEvent,
56
- responseSchema: schema,
57
- ...(typeof schema === 'object' ? schema : {}),
58
- };
59
- // 1. 字符串 Schema:直接作为结果返回(极少情况)
60
- if (typeof schema === 'string') {
61
- mockData = schema;
62
- }
63
- // 2. 遗留的高级 Schema (通过 _type 字段识别)
64
- else if (this.isLegacySchema(schema)) {
65
- const strategy = MockAdapter.strategies[schema._type];
66
- if (strategy) {
67
- const chunks = strategy.generate(schema);
68
- // 将流式块合并为单个字符串,并清理 SSE 格式标记
69
- mockData = chunks
70
- .join('')
71
- .replace(/event: data\ndata: /g, '')
72
- .replace(/\n\n/g, '');
73
- try {
74
- mockData = JSON.parse(mockData);
43
+ try {
44
+ if (!endpointConfig || !endpointConfig.responseSchema) {
45
+ logger.warn(`未找到响应架构配置: ${config.url}`);
46
+ resolve({});
47
+ return;
48
+ }
49
+ let schema = endpointConfig.responseSchema;
50
+ let mockData;
51
+ // 支持函数式 schema,允许根据请求参数动态生成 schema
52
+ if (typeof schema === 'function') {
53
+ schema = schema(config);
54
+ }
55
+ // 构造有效配置对象,合并 endpointConfig 顶层属性
56
+ const effectiveConfig = {
57
+ type: endpointConfig.type,
58
+ status: endpointConfig.status || 200,
59
+ pageEvent: endpointConfig.pageEvent,
60
+ responseSchema: schema,
61
+ ...(typeof schema === 'object' ? schema : {}),
62
+ };
63
+ // 0. 处理非 200 状态码
64
+ if (effectiveConfig.status !== 200) {
65
+ const error = new Error(`Request failed with status code ${effectiveConfig.status}`);
66
+ error.response = {
67
+ status: effectiveConfig.status,
68
+ data: Mock.mock(schema),
69
+ headers: {},
70
+ };
71
+ reject(error);
72
+ return;
73
+ }
74
+ // 1. 字符串 Schema:直接作为结果返回(极少情况)
75
+ if (typeof schema === 'string') {
76
+ mockData = schema;
77
+ }
78
+ // 2. 遗留的高级 Schema (通过 _type 字段识别)
79
+ else if (this.isLegacySchema(schema)) {
80
+ const strategy = MockAdapter.strategies[schema._type];
81
+ if (strategy) {
82
+ const chunks = strategy.generate(schema);
83
+ // 将流式块合并为单个字符串,并清理 SSE 格式标记
84
+ mockData = chunks
85
+ .join('')
86
+ .replace(/event: data\ndata: /g, '')
87
+ .replace(/\n\n/g, '');
88
+ try {
89
+ mockData = JSON.parse(mockData);
90
+ }
91
+ catch (e) {
92
+ // 忽略解析错误,保持原始数据格式
93
+ }
75
94
  }
76
- catch (e) {
77
- // 忽略解析错误,保持原始数据格式
95
+ else {
96
+ logger.warn(`未找到对应的策略类型: ${schema._type}`);
97
+ mockData = {};
78
98
  }
79
99
  }
100
+ // 3. 通用策略模式
80
101
  else {
81
- logger.warn(`未找到对应的策略类型: ${schema._type}`);
82
- mockData = {};
83
- }
84
- }
85
- // 3. 新版 Schema (通过 type: 'json' | 'sse' | 'sse-page' 识别)
86
- else if (this.isNewConfig(effectiveConfig)) {
87
- const type = effectiveConfig.type || 'json';
88
- const strategy = StrategyFactory.getStrategy(type);
89
- // 对于 request() 调用,我们只处理 'json' 类型
90
- if (type === 'json') {
102
+ const type = effectiveConfig.type || 'json';
103
+ const strategy = StrategyFactory.getStrategy(type);
91
104
  mockData = strategy.process(effectiveConfig, config.params || config.data);
92
105
  }
93
- else {
94
- logger.warn(`在同步请求中调用了流式接口: ${config.url}`);
95
- mockData = {};
96
- }
106
+ logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
107
+ logger.info(`Response:`, mockData);
108
+ resolve(mockData);
97
109
  }
98
- // 4. 默认 MockJS 回退:直接使用 Mock.mock 生成
99
- else {
100
- mockData = Mock.mock(schema);
110
+ catch (error) {
111
+ reject(error);
101
112
  }
102
- logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
103
- logger.info(`Response:`, mockData);
104
- resolve(mockData);
105
- }, this.delay);
113
+ }, delay);
106
114
  });
107
115
  }
108
116
  /**
@@ -114,6 +122,8 @@ export class MockAdapter {
114
122
  async stream(config, callbacks, endpointConfig) {
115
123
  const { onMessage, onFinish, onError } = callbacks;
116
124
  const signal = config.signal;
125
+ // 优先使用接口定义的 delay,否则使用全局默认 delay
126
+ const delay = endpointConfig?.delay ?? this.delay;
117
127
  return new Promise((resolve) => {
118
128
  // 如果请求已被取消,直接结束
119
129
  if (signal && signal.aborted) {
@@ -227,7 +237,7 @@ export class MockAdapter {
227
237
  onError(error);
228
238
  resolve();
229
239
  }
230
- }, this.delay);
240
+ }, delay);
231
241
  });
232
242
  }
233
243
  /**
package/dist/index.cjs CHANGED
@@ -527,14 +527,20 @@ function processTemplate(data, context) {
527
527
  }
528
528
  return data;
529
529
  }
530
- function flatEvents(eventsSchema, query = {}) {
530
+ function flatEvents(eventsSchema, requestData = {}) {
531
+ const context = {
532
+ $query: requestData,
533
+ // Backward compatibility
534
+ $body: requestData,
535
+ $param: requestData?.param || requestData
536
+ };
531
537
  import_mockjs.default.Random.extend({
532
- $query: function() {
533
- return query;
534
- }
538
+ $query: () => context.$query,
539
+ $body: () => context.$body,
540
+ $param: () => context.$param
535
541
  });
536
542
  const compiled = import_mockjs.default.mock(eventsSchema);
537
- return Object.values(compiled).flat().map((event) => processTemplate(event, { $query: query })).sort((a, b) => {
543
+ return Object.values(compiled).flat().map((event) => processTemplate(event, context)).sort((a, b) => {
538
544
  const delayA = typeof a.delay === "number" ? a.delay : parseInt(String(a.delay || 0));
539
545
  const delayB = typeof b.delay === "number" ? b.delay : parseInt(String(b.delay || 0));
540
546
  return delayA - delayB;
@@ -642,9 +648,19 @@ var SsePageStrategy = class {
642
648
  if (!ssePageConfig.responseSchema) return [];
643
649
  const events = flatEvents(ssePageConfig.responseSchema, requestParams);
644
650
  if (ssePageConfig.pageEvent) {
645
- import_mockjs2.default.Random.extend({ $query: () => requestParams });
651
+ const context = {
652
+ $query: requestParams,
653
+ // Backward compatibility
654
+ $body: requestParams,
655
+ $param: requestParams?.param || requestParams
656
+ };
657
+ import_mockjs2.default.Random.extend({
658
+ $query: () => context.$query,
659
+ $body: () => context.$body,
660
+ $param: () => context.$param
661
+ });
646
662
  let pageEvent = import_mockjs2.default.mock(ssePageConfig.pageEvent);
647
- pageEvent = processTemplate(pageEvent, { $query: requestParams });
663
+ pageEvent = processTemplate(pageEvent, context);
648
664
  let maxDelay = 0;
649
665
  if (events.length > 0) {
650
666
  const lastEvent = events[events.length - 1];
@@ -710,58 +726,64 @@ var MockAdapter = class _MockAdapter {
710
726
  * @returns Promise 返回模拟的响应数据
711
727
  */
712
728
  async request(config, endpointConfig) {
713
- return new Promise((resolve) => {
729
+ const delay = endpointConfig?.delay ?? this.delay;
730
+ return new Promise((resolve, reject) => {
714
731
  setTimeout(() => {
715
- if (!endpointConfig || !endpointConfig.responseSchema) {
716
- logger.warn(`\u672A\u627E\u5230\u54CD\u5E94\u67B6\u6784\u914D\u7F6E: ${config.url}`);
717
- resolve({});
718
- return;
719
- }
720
- let schema = endpointConfig.responseSchema;
721
- let mockData2;
722
- if (typeof schema === "function") {
723
- schema = schema(config);
724
- }
725
- const effectiveConfig = {
726
- type: endpointConfig.type,
727
- pageEvent: endpointConfig.pageEvent,
728
- responseSchema: schema,
729
- ...typeof schema === "object" ? schema : {}
730
- };
731
- if (typeof schema === "string") {
732
- mockData2 = schema;
733
- } else if (this.isLegacySchema(schema)) {
734
- const strategy = _MockAdapter.strategies[schema._type];
735
- if (strategy) {
736
- const chunks = strategy.generate(schema);
737
- mockData2 = chunks.join("").replace(/event: data\ndata: /g, "").replace(/\n\n/g, "");
738
- try {
739
- mockData2 = JSON.parse(mockData2);
740
- } catch (e) {
741
- }
742
- } else {
743
- logger.warn(`\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7B56\u7565\u7C7B\u578B: ${schema._type}`);
744
- mockData2 = {};
732
+ try {
733
+ if (!endpointConfig || !endpointConfig.responseSchema) {
734
+ logger.warn(`\u672A\u627E\u5230\u54CD\u5E94\u67B6\u6784\u914D\u7F6E: ${config.url}`);
735
+ resolve({});
736
+ return;
745
737
  }
746
- } else if (this.isNewConfig(effectiveConfig)) {
747
- const type = effectiveConfig.type || "json";
748
- const strategy = StrategyFactory.getStrategy(type);
749
- if (type === "json") {
750
- mockData2 = strategy.process(
751
- effectiveConfig,
752
- config.params || config.data
753
- );
738
+ let schema = endpointConfig.responseSchema;
739
+ let mockData2;
740
+ if (typeof schema === "function") {
741
+ schema = schema(config);
742
+ }
743
+ const effectiveConfig = {
744
+ type: endpointConfig.type,
745
+ status: endpointConfig.status || 200,
746
+ pageEvent: endpointConfig.pageEvent,
747
+ responseSchema: schema,
748
+ ...typeof schema === "object" ? schema : {}
749
+ };
750
+ if (effectiveConfig.status !== 200) {
751
+ const error = new Error(`Request failed with status code ${effectiveConfig.status}`);
752
+ error.response = {
753
+ status: effectiveConfig.status,
754
+ data: import_mockjs3.default.mock(schema),
755
+ headers: {}
756
+ };
757
+ reject(error);
758
+ return;
759
+ }
760
+ if (typeof schema === "string") {
761
+ mockData2 = schema;
762
+ } else if (this.isLegacySchema(schema)) {
763
+ const strategy = _MockAdapter.strategies[schema._type];
764
+ if (strategy) {
765
+ const chunks = strategy.generate(schema);
766
+ mockData2 = chunks.join("").replace(/event: data\ndata: /g, "").replace(/\n\n/g, "");
767
+ try {
768
+ mockData2 = JSON.parse(mockData2);
769
+ } catch (e) {
770
+ }
771
+ } else {
772
+ logger.warn(`\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7B56\u7565\u7C7B\u578B: ${schema._type}`);
773
+ mockData2 = {};
774
+ }
754
775
  } else {
755
- logger.warn(`\u5728\u540C\u6B65\u8BF7\u6C42\u4E2D\u8C03\u7528\u4E86\u6D41\u5F0F\u63A5\u53E3: ${config.url}`);
756
- mockData2 = {};
776
+ const type = effectiveConfig.type || "json";
777
+ const strategy = StrategyFactory.getStrategy(type);
778
+ mockData2 = strategy.process(effectiveConfig, config.params || config.data);
757
779
  }
758
- } else {
759
- mockData2 = import_mockjs3.default.mock(schema);
780
+ logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
781
+ logger.info(`Response:`, mockData2);
782
+ resolve(mockData2);
783
+ } catch (error) {
784
+ reject(error);
760
785
  }
761
- logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
762
- logger.info(`Response:`, mockData2);
763
- resolve(mockData2);
764
- }, this.delay);
786
+ }, delay);
765
787
  });
766
788
  }
767
789
  /**
@@ -773,6 +795,7 @@ var MockAdapter = class _MockAdapter {
773
795
  async stream(config, callbacks, endpointConfig) {
774
796
  const { onMessage, onFinish, onError } = callbacks;
775
797
  const signal = config.signal;
798
+ const delay = endpointConfig?.delay ?? this.delay;
776
799
  return new Promise((resolve) => {
777
800
  if (signal && signal.aborted) {
778
801
  if (onFinish) onFinish();
@@ -822,9 +845,9 @@ var MockAdapter = class _MockAdapter {
822
845
  );
823
846
  break;
824
847
  }
825
- const delay = typeof event.delay === "number" ? event.delay : parseInt(String(event.delay || 0));
848
+ const delay2 = typeof event.delay === "number" ? event.delay : parseInt(String(event.delay || 0));
826
849
  const elapsed = import_core2.dateUtils.now() - startTime;
827
- const remaining = Math.max(0, delay - elapsed);
850
+ const remaining = Math.max(0, delay2 - elapsed);
828
851
  if (remaining > 0) {
829
852
  await sleep(remaining);
830
853
  }
@@ -880,7 +903,7 @@ data: ${JSON.stringify(event.data)}
880
903
  if (onError) onError(error);
881
904
  resolve();
882
905
  }
883
- }, this.delay);
906
+ }, delay);
884
907
  });
885
908
  }
886
909
  /**
@@ -932,13 +955,14 @@ function installFetchMock(schema) {
932
955
  console.log(`[Mock] Intercepted ${method} ${url}`, rule);
933
956
  await sleep(rule.delay || 0);
934
957
  const type = rule.type || "json";
958
+ const status = rule.status || 200;
935
959
  const strategy = StrategyFactory.getStrategy(type);
936
960
  const urlObj = new URL(url, window.location.origin);
937
961
  const query = Object.fromEntries(urlObj.searchParams);
938
962
  const result = strategy.process(rule, query);
939
963
  if (type === "json") {
940
964
  return new Response(JSON.stringify(result), {
941
- status: 200,
965
+ status,
942
966
  headers: { "Content-Type": "application/json" }
943
967
  });
944
968
  }
@@ -946,7 +970,7 @@ function installFetchMock(schema) {
946
970
  const events = result;
947
971
  const stream = eventsToStream(events);
948
972
  return new Response(stream, {
949
- status: 200,
973
+ status,
950
974
  headers: { "Content-Type": "text/event-stream" }
951
975
  });
952
976
  }
package/dist/index.mjs CHANGED
@@ -497,14 +497,20 @@ function processTemplate(data, context) {
497
497
  }
498
498
  return data;
499
499
  }
500
- function flatEvents(eventsSchema, query = {}) {
500
+ function flatEvents(eventsSchema, requestData = {}) {
501
+ const context = {
502
+ $query: requestData,
503
+ // Backward compatibility
504
+ $body: requestData,
505
+ $param: requestData?.param || requestData
506
+ };
501
507
  Mock.Random.extend({
502
- $query: function() {
503
- return query;
504
- }
508
+ $query: () => context.$query,
509
+ $body: () => context.$body,
510
+ $param: () => context.$param
505
511
  });
506
512
  const compiled = Mock.mock(eventsSchema);
507
- return Object.values(compiled).flat().map((event) => processTemplate(event, { $query: query })).sort((a, b) => {
513
+ return Object.values(compiled).flat().map((event) => processTemplate(event, context)).sort((a, b) => {
508
514
  const delayA = typeof a.delay === "number" ? a.delay : parseInt(String(a.delay || 0));
509
515
  const delayB = typeof b.delay === "number" ? b.delay : parseInt(String(b.delay || 0));
510
516
  return delayA - delayB;
@@ -612,9 +618,19 @@ var SsePageStrategy = class {
612
618
  if (!ssePageConfig.responseSchema) return [];
613
619
  const events = flatEvents(ssePageConfig.responseSchema, requestParams);
614
620
  if (ssePageConfig.pageEvent) {
615
- Mock2.Random.extend({ $query: () => requestParams });
621
+ const context = {
622
+ $query: requestParams,
623
+ // Backward compatibility
624
+ $body: requestParams,
625
+ $param: requestParams?.param || requestParams
626
+ };
627
+ Mock2.Random.extend({
628
+ $query: () => context.$query,
629
+ $body: () => context.$body,
630
+ $param: () => context.$param
631
+ });
616
632
  let pageEvent = Mock2.mock(ssePageConfig.pageEvent);
617
- pageEvent = processTemplate(pageEvent, { $query: requestParams });
633
+ pageEvent = processTemplate(pageEvent, context);
618
634
  let maxDelay = 0;
619
635
  if (events.length > 0) {
620
636
  const lastEvent = events[events.length - 1];
@@ -680,58 +696,64 @@ var MockAdapter = class _MockAdapter {
680
696
  * @returns Promise 返回模拟的响应数据
681
697
  */
682
698
  async request(config, endpointConfig) {
683
- return new Promise((resolve) => {
699
+ const delay = endpointConfig?.delay ?? this.delay;
700
+ return new Promise((resolve, reject) => {
684
701
  setTimeout(() => {
685
- if (!endpointConfig || !endpointConfig.responseSchema) {
686
- logger.warn(`\u672A\u627E\u5230\u54CD\u5E94\u67B6\u6784\u914D\u7F6E: ${config.url}`);
687
- resolve({});
688
- return;
689
- }
690
- let schema = endpointConfig.responseSchema;
691
- let mockData2;
692
- if (typeof schema === "function") {
693
- schema = schema(config);
694
- }
695
- const effectiveConfig = {
696
- type: endpointConfig.type,
697
- pageEvent: endpointConfig.pageEvent,
698
- responseSchema: schema,
699
- ...typeof schema === "object" ? schema : {}
700
- };
701
- if (typeof schema === "string") {
702
- mockData2 = schema;
703
- } else if (this.isLegacySchema(schema)) {
704
- const strategy = _MockAdapter.strategies[schema._type];
705
- if (strategy) {
706
- const chunks = strategy.generate(schema);
707
- mockData2 = chunks.join("").replace(/event: data\ndata: /g, "").replace(/\n\n/g, "");
708
- try {
709
- mockData2 = JSON.parse(mockData2);
710
- } catch (e) {
711
- }
712
- } else {
713
- logger.warn(`\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7B56\u7565\u7C7B\u578B: ${schema._type}`);
714
- mockData2 = {};
702
+ try {
703
+ if (!endpointConfig || !endpointConfig.responseSchema) {
704
+ logger.warn(`\u672A\u627E\u5230\u54CD\u5E94\u67B6\u6784\u914D\u7F6E: ${config.url}`);
705
+ resolve({});
706
+ return;
715
707
  }
716
- } else if (this.isNewConfig(effectiveConfig)) {
717
- const type = effectiveConfig.type || "json";
718
- const strategy = StrategyFactory.getStrategy(type);
719
- if (type === "json") {
720
- mockData2 = strategy.process(
721
- effectiveConfig,
722
- config.params || config.data
723
- );
708
+ let schema = endpointConfig.responseSchema;
709
+ let mockData2;
710
+ if (typeof schema === "function") {
711
+ schema = schema(config);
712
+ }
713
+ const effectiveConfig = {
714
+ type: endpointConfig.type,
715
+ status: endpointConfig.status || 200,
716
+ pageEvent: endpointConfig.pageEvent,
717
+ responseSchema: schema,
718
+ ...typeof schema === "object" ? schema : {}
719
+ };
720
+ if (effectiveConfig.status !== 200) {
721
+ const error = new Error(`Request failed with status code ${effectiveConfig.status}`);
722
+ error.response = {
723
+ status: effectiveConfig.status,
724
+ data: Mock3.mock(schema),
725
+ headers: {}
726
+ };
727
+ reject(error);
728
+ return;
729
+ }
730
+ if (typeof schema === "string") {
731
+ mockData2 = schema;
732
+ } else if (this.isLegacySchema(schema)) {
733
+ const strategy = _MockAdapter.strategies[schema._type];
734
+ if (strategy) {
735
+ const chunks = strategy.generate(schema);
736
+ mockData2 = chunks.join("").replace(/event: data\ndata: /g, "").replace(/\n\n/g, "");
737
+ try {
738
+ mockData2 = JSON.parse(mockData2);
739
+ } catch (e) {
740
+ }
741
+ } else {
742
+ logger.warn(`\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7B56\u7565\u7C7B\u578B: ${schema._type}`);
743
+ mockData2 = {};
744
+ }
724
745
  } else {
725
- logger.warn(`\u5728\u540C\u6B65\u8BF7\u6C42\u4E2D\u8C03\u7528\u4E86\u6D41\u5F0F\u63A5\u53E3: ${config.url}`);
726
- mockData2 = {};
746
+ const type = effectiveConfig.type || "json";
747
+ const strategy = StrategyFactory.getStrategy(type);
748
+ mockData2 = strategy.process(effectiveConfig, config.params || config.data);
727
749
  }
728
- } else {
729
- mockData2 = Mock3.mock(schema);
750
+ logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
751
+ logger.info(`Response:`, mockData2);
752
+ resolve(mockData2);
753
+ } catch (error) {
754
+ reject(error);
730
755
  }
731
- logger.info(`Request: ${config.method} ${config.url}`, config.data || config.params);
732
- logger.info(`Response:`, mockData2);
733
- resolve(mockData2);
734
- }, this.delay);
756
+ }, delay);
735
757
  });
736
758
  }
737
759
  /**
@@ -743,6 +765,7 @@ var MockAdapter = class _MockAdapter {
743
765
  async stream(config, callbacks, endpointConfig) {
744
766
  const { onMessage, onFinish, onError } = callbacks;
745
767
  const signal = config.signal;
768
+ const delay = endpointConfig?.delay ?? this.delay;
746
769
  return new Promise((resolve) => {
747
770
  if (signal && signal.aborted) {
748
771
  if (onFinish) onFinish();
@@ -792,9 +815,9 @@ var MockAdapter = class _MockAdapter {
792
815
  );
793
816
  break;
794
817
  }
795
- const delay = typeof event.delay === "number" ? event.delay : parseInt(String(event.delay || 0));
818
+ const delay2 = typeof event.delay === "number" ? event.delay : parseInt(String(event.delay || 0));
796
819
  const elapsed = dateUtils2.now() - startTime;
797
- const remaining = Math.max(0, delay - elapsed);
820
+ const remaining = Math.max(0, delay2 - elapsed);
798
821
  if (remaining > 0) {
799
822
  await sleep(remaining);
800
823
  }
@@ -850,7 +873,7 @@ data: ${JSON.stringify(event.data)}
850
873
  if (onError) onError(error);
851
874
  resolve();
852
875
  }
853
- }, this.delay);
876
+ }, delay);
854
877
  });
855
878
  }
856
879
  /**
@@ -902,13 +925,14 @@ function installFetchMock(schema) {
902
925
  console.log(`[Mock] Intercepted ${method} ${url}`, rule);
903
926
  await sleep(rule.delay || 0);
904
927
  const type = rule.type || "json";
928
+ const status = rule.status || 200;
905
929
  const strategy = StrategyFactory.getStrategy(type);
906
930
  const urlObj = new URL(url, window.location.origin);
907
931
  const query = Object.fromEntries(urlObj.searchParams);
908
932
  const result = strategy.process(rule, query);
909
933
  if (type === "json") {
910
934
  return new Response(JSON.stringify(result), {
911
- status: 200,
935
+ status,
912
936
  headers: { "Content-Type": "application/json" }
913
937
  });
914
938
  }
@@ -916,7 +940,7 @@ function installFetchMock(schema) {
916
940
  const events = result;
917
941
  const stream = eventsToStream(events);
918
942
  return new Response(stream, {
919
- status: 200,
943
+ status,
920
944
  headers: { "Content-Type": "text/event-stream" }
921
945
  });
922
946
  }
@@ -30,6 +30,7 @@ export function installFetchMock(schema) {
30
30
  await sleep(rule.delay || 0);
31
31
  // Determine type (default 'json' if not present)
32
32
  const type = rule.type || 'json';
33
+ const status = rule.status || 200;
33
34
  const strategy = StrategyFactory.getStrategy(type);
34
35
  // Parse query params for strategies that need them
35
36
  const urlObj = new URL(url, window.location.origin);
@@ -38,7 +39,7 @@ export function installFetchMock(schema) {
38
39
  /* 1. JSON Response */
39
40
  if (type === 'json') {
40
41
  return new Response(JSON.stringify(result), {
41
- status: 200,
42
+ status,
42
43
  headers: { 'Content-Type': 'application/json' },
43
44
  });
44
45
  }
@@ -47,7 +48,7 @@ export function installFetchMock(schema) {
47
48
  const events = result; // Strategy returns MockEvent[]
48
49
  const stream = eventsToStream(events);
49
50
  return new Response(stream, {
50
- status: 200,
51
+ status,
51
52
  headers: { 'Content-Type': 'text/event-stream' }
52
53
  });
53
54
  }
@@ -83,11 +83,20 @@ export class SsePageStrategy {
83
83
  const events = flatEvents(ssePageConfig.responseSchema, requestParams);
84
84
  // 2. Generate page event if exists
85
85
  if (ssePageConfig.pageEvent) {
86
- Mock.Random.extend({ $query: () => requestParams });
86
+ const context = {
87
+ $query: requestParams, // Backward compatibility
88
+ $body: requestParams,
89
+ $param: requestParams?.param || requestParams
90
+ };
91
+ Mock.Random.extend({
92
+ $query: () => context.$query,
93
+ $body: () => context.$body,
94
+ $param: () => context.$param
95
+ });
87
96
  // First let Mock.js process standard templates (like @integer)
88
97
  let pageEvent = Mock.mock(ssePageConfig.pageEvent);
89
98
  // Then process custom {{}} templates
90
- pageEvent = processTemplate(pageEvent, { $query: requestParams });
99
+ pageEvent = processTemplate(pageEvent, context);
91
100
  // Calculate max delay from existing events to ensure page event is last
92
101
  let maxDelay = 0;
93
102
  if (events.length > 0) {
package/dist/types.d.ts CHANGED
@@ -21,6 +21,8 @@ export interface BaseMockConfig {
21
21
  method?: MockMethod;
22
22
  /** Global delay for the request */
23
23
  delay?: number;
24
+ /** Optional: HTTP status code (default: 200) */
25
+ status?: number;
24
26
  /** Mock type (default: 'json') */
25
27
  type?: MockType;
26
28
  }
package/dist/utils.d.ts CHANGED
@@ -2,18 +2,17 @@ import { MockEvent } from './types';
2
2
  export declare const sleep: (ms: number) => Promise<unknown>;
3
3
  /**
4
4
  * Process string templates like "{{$query.pageNo * 10}}" in object values.
5
- * Uses simple evaluation with limited context.
5
+ * Supports $query (for backward compatibility), $body, and $param.
6
6
  */
7
7
  export declare function processTemplate(data: any, context: Record<string, any>): any;
8
8
  /**
9
9
  * Flatten eventsSchema into a sorted array of events.
10
- * It also extends Mock.Random with $query to access URL parameters.
11
10
  *
12
11
  * Supports Mock.js array generation rules in keys, e.g.:
13
12
  * { 'data|8-12': [{ event: 'data', ... }] }
14
13
  * -> generates 8 to 12 data events.
15
14
  */
16
- export declare function flatEvents(eventsSchema: Record<string, MockEvent[]>, query?: Record<string, string>): MockEvent[];
15
+ export declare function flatEvents(eventsSchema: Record<string, MockEvent[]>, requestData?: any): MockEvent[];
17
16
  /**
18
17
  * Convert an array of events into a ReadableStream (for SSE).
19
18
  */
package/dist/utils.js CHANGED
@@ -3,7 +3,7 @@ import Mock from 'mockjs';
3
3
  export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
4
4
  /**
5
5
  * Process string templates like "{{$query.pageNo * 10}}" in object values.
6
- * Uses simple evaluation with limited context.
6
+ * Supports $query (for backward compatibility), $body, and $param.
7
7
  */
8
8
  export function processTemplate(data, context) {
9
9
  if (typeof data === 'string') {
@@ -38,26 +38,30 @@ export function processTemplate(data, context) {
38
38
  }
39
39
  /**
40
40
  * Flatten eventsSchema into a sorted array of events.
41
- * It also extends Mock.Random with $query to access URL parameters.
42
41
  *
43
42
  * Supports Mock.js array generation rules in keys, e.g.:
44
43
  * { 'data|8-12': [{ event: 'data', ... }] }
45
44
  * -> generates 8 to 12 data events.
46
45
  */
47
- export function flatEvents(eventsSchema, query = {}) {
48
- // Extend Mock.Random to support $query
46
+ export function flatEvents(eventsSchema, requestData = {}) {
47
+ // Construct context for template processing
48
+ const context = {
49
+ $query: requestData, // Backward compatibility
50
+ $body: requestData,
51
+ $param: requestData?.param || requestData
52
+ };
53
+ // Extend Mock.Random to support templates
49
54
  Mock.Random.extend({
50
- $query: function () {
51
- return query;
52
- }
55
+ $query: () => context.$query,
56
+ $body: () => context.$body,
57
+ $param: () => context.$param
53
58
  });
54
59
  // Generate data using Mock.mock
55
- // This handles keys like 'data|8-12' to generate arrays
56
60
  const compiled = Mock.mock(eventsSchema);
57
61
  // Flatten and sort by delay
58
62
  return Object.values(compiled)
59
63
  .flat()
60
- .map(event => processTemplate(event, { $query: query })) // Apply template replacement
64
+ .map(event => processTemplate(event, context))
61
65
  .sort((a, b) => {
62
66
  const delayA = typeof a.delay === 'number' ? a.delay : parseInt(String(a.delay || 0));
63
67
  const delayB = typeof b.delay === 'number' ? b.delay : parseInt(String(b.delay || 0));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatbi-v/mocks",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.cjs",
5
5
  "files": [
6
6
  "dist"
@@ -19,10 +19,10 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "mockjs": "^1.1.0",
22
- "@chatbi-v/core": "1.0.2"
22
+ "@chatbi-v/core": "2.0.0"
23
23
  },
24
24
  "peerDependencies": {
25
- "@chatbi-v/cli": "1.0.2"
25
+ "@chatbi-v/cli": "1.0.9"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/mockjs": "^1.0.10",