@zze/mock-server 0.2.5 → 0.5.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.
Files changed (38) hide show
  1. package/README.md +117 -28
  2. package/dist/__tests__/mock-server.test.js +52 -0
  3. package/dist/admin/__tests__/admin-router.test.js +0 -151
  4. package/dist/admin/admin-router.d.ts.map +1 -1
  5. package/dist/admin/admin-router.js +0 -205
  6. package/dist/admin/types.d.ts +0 -84
  7. package/dist/admin/types.d.ts.map +1 -1
  8. package/dist/admin/types.js +1 -5
  9. package/dist/config/config-writer.d.ts +1 -35
  10. package/dist/config/config-writer.d.ts.map +1 -1
  11. package/dist/config/config-writer.js +0 -103
  12. package/dist/mock-server.d.ts +14 -3
  13. package/dist/mock-server.d.ts.map +1 -1
  14. package/dist/mock-server.js +57 -60
  15. package/dist/resolver/__tests__/response-resolver.test.js +134 -0
  16. package/dist/resolver/response-resolver.d.ts +18 -2
  17. package/dist/resolver/response-resolver.d.ts.map +1 -1
  18. package/dist/resolver/response-resolver.js +62 -5
  19. package/dist/resolver/types.d.ts +8 -0
  20. package/dist/resolver/types.d.ts.map +1 -1
  21. package/dist/resolver/types.js +7 -0
  22. package/dist/schemas/__tests__/endpoint.schema.test.js +48 -0
  23. package/dist/schemas/endpoint.schema.d.ts +31 -8
  24. package/dist/schemas/endpoint.schema.d.ts.map +1 -1
  25. package/dist/schemas/scenario.schema.d.ts +28 -4
  26. package/dist/schemas/scenario.schema.d.ts.map +1 -1
  27. package/dist/schemas/scenario.schema.js +23 -3
  28. package/dist/server/__tests__/mock-server-app.test.js +37 -0
  29. package/dist/server/mock-server-app.d.ts.map +1 -1
  30. package/dist/server/mock-server-app.js +5 -1
  31. package/dist/server/types.d.ts +8 -0
  32. package/dist/server/types.d.ts.map +1 -1
  33. package/dist/server/types.js +1 -0
  34. package/dist/ui/assets/{index-rj7m-XdG.css → index-C5BZSa2z.css} +1 -1
  35. package/dist/ui/assets/index-DY4CS66u.js +9 -0
  36. package/dist/ui/index.html +2 -2
  37. package/package.json +6 -4
  38. package/dist/ui/assets/index-SADMOgPE.js +0 -10
@@ -24,90 +24,6 @@ export declare const ActivateFlowRequestSchema: z.ZodObject<{
24
24
  flowId: string | null;
25
25
  }>;
26
26
  export type ActivateFlowRequest = z.infer<typeof ActivateFlowRequestSchema>;
27
- /**
28
- * Request body for creating/updating an endpoint
29
- */
30
- export declare const EndpointRequestSchema: z.ZodEffects<z.ZodObject<{
31
- id: z.ZodString;
32
- path: z.ZodString;
33
- method: z.ZodEnum<["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"]>;
34
- scenarios: z.ZodArray<z.ZodObject<{
35
- id: z.ZodString;
36
- name: z.ZodString;
37
- status: z.ZodNumber;
38
- headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
39
- body: z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodUnknown, "many">, z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodAny>]>;
40
- delay: z.ZodOptional<z.ZodNumber>;
41
- }, "strip", z.ZodTypeAny, {
42
- status: number;
43
- id: string;
44
- name: string;
45
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
46
- headers?: Record<string, string> | undefined;
47
- delay?: number | undefined;
48
- }, {
49
- status: number;
50
- id: string;
51
- name: string;
52
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
53
- headers?: Record<string, string> | undefined;
54
- delay?: number | undefined;
55
- }>, "many">;
56
- defaultScenarioId: z.ZodString;
57
- }, "strip", z.ZodTypeAny, {
58
- path: string;
59
- id: string;
60
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
61
- scenarios: {
62
- status: number;
63
- id: string;
64
- name: string;
65
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
66
- headers?: Record<string, string> | undefined;
67
- delay?: number | undefined;
68
- }[];
69
- defaultScenarioId: string;
70
- }, {
71
- path: string;
72
- id: string;
73
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
74
- scenarios: {
75
- status: number;
76
- id: string;
77
- name: string;
78
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
79
- headers?: Record<string, string> | undefined;
80
- delay?: number | undefined;
81
- }[];
82
- defaultScenarioId: string;
83
- }>, {
84
- path: string;
85
- id: string;
86
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
87
- scenarios: {
88
- status: number;
89
- id: string;
90
- name: string;
91
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
92
- headers?: Record<string, string> | undefined;
93
- delay?: number | undefined;
94
- }[];
95
- defaultScenarioId: string;
96
- }, {
97
- path: string;
98
- id: string;
99
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
100
- scenarios: {
101
- status: number;
102
- id: string;
103
- name: string;
104
- body: string | number | boolean | unknown[] | Record<string, unknown> | ((args_0: any, ...args: unknown[]) => any) | null;
105
- headers?: Record<string, string> | undefined;
106
- delay?: number | undefined;
107
- }[];
108
- defaultScenarioId: string;
109
- }>;
110
- export type EndpointRequest = z.infer<typeof EndpointRequestSchema>;
111
27
  /**
112
28
  * Request body for creating/updating a flow
113
29
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;EAGxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;EAEpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAuB,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAAmB,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;EAGrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,KAAK,CAAC;YACf,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC,CAAC;QACH,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;EAGxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;EAEpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAAmB,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;EAGrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,KAAK,CAAC;YACf,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC,CAAC;QACH,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DuplicateFlowRequestSchema = exports.FlowRequestSchema = exports.EndpointRequestSchema = exports.ActivateFlowRequestSchema = exports.ActivateScenarioRequestSchema = void 0;
3
+ exports.DuplicateFlowRequestSchema = exports.FlowRequestSchema = exports.ActivateFlowRequestSchema = exports.ActivateScenarioRequestSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const index_js_1 = require("../schemas/index.js");
6
6
  /**
@@ -16,10 +16,6 @@ exports.ActivateScenarioRequestSchema = zod_1.z.object({
16
16
  exports.ActivateFlowRequestSchema = zod_1.z.object({
17
17
  flowId: zod_1.z.string().min(1).nullable(),
18
18
  });
19
- /**
20
- * Request body for creating/updating an endpoint
21
- */
22
- exports.EndpointRequestSchema = index_js_1.EndpointConfigSchema;
23
19
  /**
24
20
  * Request body for creating/updating a flow
25
21
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Config file writer - handles persisting endpoint and flow configs to disk
3
3
  */
4
- import type { EndpointConfig, FlowConfig } from '../schemas/index.js';
4
+ import type { FlowConfig } from '../schemas/index.js';
5
5
  /**
6
6
  * Result of a write operation
7
7
  */
@@ -26,38 +26,18 @@ export declare class ConfigWriter {
26
26
  private endpointsDir;
27
27
  private flowsDir;
28
28
  constructor(options: ConfigWriterOptions);
29
- /**
30
- * Get the file path for an endpoint config
31
- */
32
- getEndpointFilePath(endpointId: string): string;
33
29
  /**
34
30
  * Get the file path for a flow config
35
31
  */
36
32
  getFlowFilePath(flowId: string): string;
37
- /**
38
- * Check if an endpoint file exists
39
- */
40
- endpointExists(endpointId: string): Promise<boolean>;
41
33
  /**
42
34
  * Check if a flow file exists
43
35
  */
44
36
  flowExists(flowId: string): Promise<boolean>;
45
- /**
46
- * Find an existing endpoint file by ID (could be .json, .js, or .ts)
47
- */
48
- findEndpointFile(endpointId: string): Promise<string | null>;
49
37
  /**
50
38
  * Find an existing flow file by ID (could be .json, .js, or .ts)
51
39
  */
52
40
  findFlowFile(flowId: string): Promise<string | null>;
53
- /**
54
- * Validate an endpoint config
55
- */
56
- validateEndpoint(data: unknown): {
57
- success: boolean;
58
- data?: EndpointConfig;
59
- error?: string;
60
- };
61
41
  /**
62
42
  * Validate a flow config
63
43
  */
@@ -66,28 +46,14 @@ export declare class ConfigWriter {
66
46
  data?: FlowConfig;
67
47
  error?: string;
68
48
  };
69
- /**
70
- * Write an endpoint config to disk
71
- * Creates a new file or overwrites existing .json file
72
- */
73
- writeEndpoint(endpoint: EndpointConfig): Promise<WriteResult>;
74
49
  /**
75
50
  * Write a flow config to disk
76
51
  */
77
52
  writeFlow(flow: FlowConfig): Promise<WriteResult>;
78
- /**
79
- * Delete an endpoint file
80
- */
81
- deleteEndpoint(endpointId: string): Promise<WriteResult>;
82
53
  /**
83
54
  * Delete a flow file
84
55
  */
85
56
  deleteFlow(flowId: string): Promise<WriteResult>;
86
- /**
87
- * Clean endpoint data for JSON serialization
88
- * Converts function bodies to null (they can't be serialized)
89
- */
90
- private cleanEndpointForJson;
91
57
  }
92
58
  /**
93
59
  * Create a ConfigWriter instance
@@ -1 +1 @@
1
- {"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/config/config-writer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,mBAAmB;IAKxC;;OAEG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAI/C;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIvC;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU1D;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlD;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAclE;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc1D;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,cAAc,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAS5F;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IASpF;;;OAGG;IACG,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAuBnE;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBvD;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAkB9D;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAkBtD;;;OAGG;IACH,OAAO,CAAC,oBAAoB;CAU7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAE7E"}
1
+ {"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/config/config-writer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,mBAAmB;IAKxC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIvC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc1D;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IASpF;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBvD;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAkBvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAE7E"}
@@ -49,31 +49,12 @@ class ConfigWriter {
49
49
  this.endpointsDir = options.endpointsDir;
50
50
  this.flowsDir = options.flowsDir;
51
51
  }
52
- /**
53
- * Get the file path for an endpoint config
54
- */
55
- getEndpointFilePath(endpointId) {
56
- return path.join(this.endpointsDir, `${endpointId}.json`);
57
- }
58
52
  /**
59
53
  * Get the file path for a flow config
60
54
  */
61
55
  getFlowFilePath(flowId) {
62
56
  return path.join(this.flowsDir, `${flowId}.json`);
63
57
  }
64
- /**
65
- * Check if an endpoint file exists
66
- */
67
- async endpointExists(endpointId) {
68
- const filePath = this.getEndpointFilePath(endpointId);
69
- try {
70
- await fs.access(filePath);
71
- return true;
72
- }
73
- catch {
74
- return false;
75
- }
76
- }
77
58
  /**
78
59
  * Check if a flow file exists
79
60
  */
@@ -87,23 +68,6 @@ class ConfigWriter {
87
68
  return false;
88
69
  }
89
70
  }
90
- /**
91
- * Find an existing endpoint file by ID (could be .json, .js, or .ts)
92
- */
93
- async findEndpointFile(endpointId) {
94
- const extensions = ['.json', '.js', '.ts', '.mjs', '.mts'];
95
- for (const ext of extensions) {
96
- const filePath = path.join(this.endpointsDir, `${endpointId}${ext}`);
97
- try {
98
- await fs.access(filePath);
99
- return filePath;
100
- }
101
- catch {
102
- // Continue checking
103
- }
104
- }
105
- return null;
106
- }
107
71
  /**
108
72
  * Find an existing flow file by ID (could be .json, .js, or .ts)
109
73
  */
@@ -121,17 +85,6 @@ class ConfigWriter {
121
85
  }
122
86
  return null;
123
87
  }
124
- /**
125
- * Validate an endpoint config
126
- */
127
- validateEndpoint(data) {
128
- const result = index_js_1.EndpointConfigSchema.safeParse(data);
129
- if (result.success) {
130
- return { success: true, data: result.data };
131
- }
132
- const errors = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
133
- return { success: false, error: errors };
134
- }
135
88
  /**
136
89
  * Validate a flow config
137
90
  */
@@ -143,29 +96,6 @@ class ConfigWriter {
143
96
  const errors = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
144
97
  return { success: false, error: errors };
145
98
  }
146
- /**
147
- * Write an endpoint config to disk
148
- * Creates a new file or overwrites existing .json file
149
- */
150
- async writeEndpoint(endpoint) {
151
- const filePath = this.getEndpointFilePath(endpoint.id);
152
- try {
153
- // Ensure directory exists
154
- await fs.mkdir(this.endpointsDir, { recursive: true });
155
- // Prepare clean endpoint data (remove function bodies for JSON)
156
- const cleanEndpoint = this.cleanEndpointForJson(endpoint);
157
- // Write formatted JSON
158
- const content = JSON.stringify(cleanEndpoint, null, 2) + '\n';
159
- await fs.writeFile(filePath, content, 'utf-8');
160
- return { success: true, filePath };
161
- }
162
- catch (error) {
163
- return {
164
- success: false,
165
- error: error instanceof Error ? error.message : 'Unknown error',
166
- };
167
- }
168
- }
169
99
  /**
170
100
  * Write a flow config to disk
171
101
  */
@@ -186,25 +116,6 @@ class ConfigWriter {
186
116
  };
187
117
  }
188
118
  }
189
- /**
190
- * Delete an endpoint file
191
- */
192
- async deleteEndpoint(endpointId) {
193
- const existingFile = await this.findEndpointFile(endpointId);
194
- if (!existingFile) {
195
- return { success: false, error: `Endpoint "${endpointId}" not found` };
196
- }
197
- try {
198
- await fs.unlink(existingFile);
199
- return { success: true, filePath: existingFile };
200
- }
201
- catch (error) {
202
- return {
203
- success: false,
204
- error: error instanceof Error ? error.message : 'Unknown error',
205
- };
206
- }
207
- }
208
119
  /**
209
120
  * Delete a flow file
210
121
  */
@@ -224,20 +135,6 @@ class ConfigWriter {
224
135
  };
225
136
  }
226
137
  }
227
- /**
228
- * Clean endpoint data for JSON serialization
229
- * Converts function bodies to null (they can't be serialized)
230
- */
231
- cleanEndpointForJson(endpoint) {
232
- return {
233
- ...endpoint,
234
- scenarios: endpoint.scenarios.map((scenario) => ({
235
- ...scenario,
236
- // If body is a function, convert to a placeholder or keep as-is for objects
237
- body: typeof scenario.body === 'function' ? { _note: 'Function body - edit in .ts file' } : scenario.body,
238
- })),
239
- };
240
- }
241
138
  }
242
139
  exports.ConfigWriter = ConfigWriter;
243
140
  /**
@@ -38,6 +38,15 @@ export interface MockServerOptions {
38
38
  * Options for the file watcher (only used when hotReload is true).
39
39
  */
40
40
  watcherOptions?: WatcherOptions;
41
+ /**
42
+ * Global delay applied to every response when the matched scenario has no explicit `delay`.
43
+ * A number is a fixed millisecond value; a tuple [min, max] produces a random value in that range.
44
+ * Scenario-level `delay` always takes precedence.
45
+ * @example
46
+ * globalDelay: 200 // every response waits 200 ms (unless scenario overrides)
47
+ * globalDelay: [100, 500] // each response waits a random 100-500 ms
48
+ */
49
+ globalDelay?: number | [number, number];
41
50
  }
42
51
  /**
43
52
  * Current state of the mock server
@@ -111,10 +120,11 @@ export declare class MockServer {
111
120
  * 2. Creates and starts the Express server
112
121
  * 3. Optionally starts the file watcher for hot reload
113
122
  *
114
- * @returns Promise that resolves when the server is ready
115
- * @throws Error if configuration loading fails or server fails to start
123
+ * @returns Promise that resolves when the server is ready (when no callback is provided)
124
+ * @throws Error if configuration loading fails or server fails to start (when no callback is provided)
116
125
  */
117
126
  start(): Promise<void>;
127
+ start(callback: (err?: Error) => void): void;
118
128
  /**
119
129
  * Stop the mock server
120
130
  *
@@ -122,9 +132,10 @@ export declare class MockServer {
122
132
  * 1. Stops the file watcher (if running)
123
133
  * 2. Stops the Express server
124
134
  *
125
- * @returns Promise that resolves when the server has stopped
135
+ * @returns Promise that resolves when the server has stopped (when no callback is provided)
126
136
  */
127
137
  stop(): Promise<void>;
138
+ stop(callback: (err?: Error) => void): void;
128
139
  /**
129
140
  * Restart the mock server
130
141
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../src/mock-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../src/mock-server.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,7 @@ class MockServer {
57
57
  apiPrefix: options.apiPrefix ?? '/api',
58
58
  hotReload: options.hotReload ?? true,
59
59
  watcherOptions: options.watcherOptions,
60
+ globalDelay: options.globalDelay,
60
61
  };
61
62
  // Create config loader
62
63
  this.configLoader = new config_loader_js_1.ConfigLoader(this.options.configPath);
@@ -66,70 +67,66 @@ class MockServer {
66
67
  flowsDir: path_1.default.join(this.options.configPath, 'flows'),
67
68
  });
68
69
  }
69
- /**
70
- * Start the mock server
71
- *
72
- * This method:
73
- * 1. Loads configuration from the config directory
74
- * 2. Creates and starts the Express server
75
- * 3. Optionally starts the file watcher for hot reload
76
- *
77
- * @returns Promise that resolves when the server is ready
78
- * @throws Error if configuration loading fails or server fails to start
79
- */
80
- async start() {
81
- if (this.serverApp?.isRunning()) {
82
- throw new Error('Server is already running');
83
- }
84
- // Load configuration
85
- const result = await this.configLoader.load();
86
- if (!result.success || !result.config) {
87
- const errorMessages = result.errors.map((e) => `${e.filePath}: ${e.error}`).join('\n');
88
- throw new Error(`Failed to load configuration:\n${errorMessages}`);
89
- }
90
- // Store loaded config
91
- this.loadedEndpoints = result.config.endpoints;
92
- this.loadedFlows = result.config.flows;
93
- // Create server app
94
- const serverOptions = {
95
- port: this.options.port,
96
- apiPrefix: this.options.apiPrefix,
97
- hotReload: this.options.hotReload,
70
+ start(callback) {
71
+ const run = async () => {
72
+ if (this.serverApp?.isRunning()) {
73
+ throw new Error('Server is already running');
74
+ }
75
+ // Load configuration
76
+ const result = await this.configLoader.load();
77
+ if (!result.success || !result.config) {
78
+ const errorMessages = result.errors.map((e) => `${e.filePath}: ${e.error}`).join('\n');
79
+ throw new Error(`Failed to load configuration:\n${errorMessages}`);
80
+ }
81
+ // Store loaded config
82
+ this.loadedEndpoints = result.config.endpoints;
83
+ this.loadedFlows = result.config.flows;
84
+ // Create server app
85
+ const serverOptions = {
86
+ port: this.options.port,
87
+ apiPrefix: this.options.apiPrefix,
88
+ hotReload: this.options.hotReload,
89
+ configPath: this.options.configPath,
90
+ globalDelay: this.options.globalDelay,
91
+ };
92
+ this.serverApp = new mock_server_app_js_1.MockServerApp(serverOptions);
93
+ // Set config writer for endpoint/flow management via admin API
94
+ this.serverApp.setConfigWriter(this.configWriter, () => this.reload());
95
+ this.serverApp.registerConfig(this.loadedEndpoints, this.loadedFlows);
96
+ // Start the server
97
+ await this.serverApp.start();
98
+ // Start file watcher if hot reload is enabled
99
+ if (this.options.hotReload) {
100
+ await this.startWatcher();
101
+ }
98
102
  };
99
- this.serverApp = new mock_server_app_js_1.MockServerApp(serverOptions);
100
- // Set config writer for endpoint/flow management via admin API
101
- this.serverApp.setConfigWriter(this.configWriter, () => this.reload());
102
- this.serverApp.registerConfig(this.loadedEndpoints, this.loadedFlows);
103
- // Start the server
104
- await this.serverApp.start();
105
- // Start file watcher if hot reload is enabled
106
- if (this.options.hotReload) {
107
- await this.startWatcher();
103
+ if (callback) {
104
+ run().then(() => callback()).catch((err) => callback(err));
105
+ return;
108
106
  }
107
+ return run();
109
108
  }
110
- /**
111
- * Stop the mock server
112
- *
113
- * This method:
114
- * 1. Stops the file watcher (if running)
115
- * 2. Stops the Express server
116
- *
117
- * @returns Promise that resolves when the server has stopped
118
- */
119
- async stop() {
120
- // Stop watcher first
121
- if (this.watcher) {
122
- await this.watcher.stop();
123
- this.watcher = null;
124
- }
125
- // Stop server
126
- if (this.serverApp) {
127
- await this.serverApp.stop();
128
- this.serverApp = null;
109
+ stop(callback) {
110
+ const run = async () => {
111
+ // Stop watcher first
112
+ if (this.watcher) {
113
+ await this.watcher.stop();
114
+ this.watcher = null;
115
+ }
116
+ // Stop server
117
+ if (this.serverApp) {
118
+ await this.serverApp.stop();
119
+ this.serverApp = null;
120
+ }
121
+ // Clear loaded config
122
+ this.loadedEndpoints = [];
123
+ this.loadedFlows = [];
124
+ };
125
+ if (callback) {
126
+ run().then(() => callback()).catch((err) => callback(err));
127
+ return;
129
128
  }
130
- // Clear loaded config
131
- this.loadedEndpoints = [];
132
- this.loadedFlows = [];
129
+ return run();
133
130
  }
134
131
  /**
135
132
  * Restart the mock server