@scenarist/core 0.0.1 → 0.1.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 (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +755 -28
  3. package/dist/adapters/in-memory-registry.d.ts +18 -0
  4. package/dist/adapters/in-memory-registry.d.ts.map +1 -0
  5. package/dist/adapters/in-memory-registry.js +25 -0
  6. package/dist/adapters/in-memory-sequence-tracker.d.ts +28 -0
  7. package/dist/adapters/in-memory-sequence-tracker.d.ts.map +1 -0
  8. package/dist/adapters/in-memory-sequence-tracker.js +82 -0
  9. package/dist/adapters/in-memory-state-manager.d.ts +24 -0
  10. package/dist/adapters/in-memory-state-manager.d.ts.map +1 -0
  11. package/dist/adapters/in-memory-state-manager.js +81 -0
  12. package/dist/adapters/in-memory-store.d.ts +18 -0
  13. package/dist/adapters/in-memory-store.d.ts.map +1 -0
  14. package/dist/adapters/in-memory-store.js +25 -0
  15. package/dist/adapters/index.d.ts +5 -0
  16. package/dist/adapters/index.d.ts.map +1 -0
  17. package/dist/adapters/index.js +4 -0
  18. package/dist/constants/headers.d.ts +10 -0
  19. package/dist/constants/headers.d.ts.map +1 -0
  20. package/dist/constants/headers.js +9 -0
  21. package/dist/constants/index.d.ts +2 -0
  22. package/dist/constants/index.d.ts.map +1 -0
  23. package/dist/constants/index.js +1 -0
  24. package/dist/contracts/framework-adapter.d.ts +118 -0
  25. package/dist/contracts/framework-adapter.d.ts.map +1 -0
  26. package/dist/contracts/framework-adapter.js +1 -0
  27. package/dist/contracts/index.d.ts +2 -0
  28. package/dist/contracts/index.d.ts.map +1 -0
  29. package/dist/contracts/index.js +1 -0
  30. package/dist/domain/config-builder.d.ts +9 -0
  31. package/dist/domain/config-builder.d.ts.map +1 -0
  32. package/dist/domain/config-builder.js +20 -0
  33. package/dist/domain/index.d.ts +5 -0
  34. package/dist/domain/index.d.ts.map +1 -0
  35. package/dist/domain/index.js +4 -0
  36. package/dist/domain/path-extraction.d.ts +17 -0
  37. package/dist/domain/path-extraction.d.ts.map +1 -0
  38. package/dist/domain/path-extraction.js +60 -0
  39. package/dist/domain/regex-matching.d.ts +20 -0
  40. package/dist/domain/regex-matching.d.ts.map +1 -0
  41. package/dist/domain/regex-matching.js +27 -0
  42. package/dist/domain/response-selector.d.ts +22 -0
  43. package/dist/domain/response-selector.d.ts.map +1 -0
  44. package/dist/domain/response-selector.js +337 -0
  45. package/dist/domain/scenario-manager.d.ts +20 -0
  46. package/dist/domain/scenario-manager.d.ts.map +1 -0
  47. package/dist/domain/scenario-manager.js +90 -0
  48. package/dist/domain/template-replacement.d.ts +11 -0
  49. package/dist/domain/template-replacement.d.ts.map +1 -0
  50. package/dist/domain/template-replacement.js +94 -0
  51. package/dist/index.d.ts +8 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +8 -0
  54. package/dist/ports/driven/request-context.d.ts +43 -0
  55. package/dist/ports/driven/request-context.d.ts.map +1 -0
  56. package/dist/ports/driven/request-context.js +1 -0
  57. package/dist/ports/driven/response-selector.d.ts +34 -0
  58. package/dist/ports/driven/response-selector.d.ts.map +1 -0
  59. package/dist/ports/driven/response-selector.js +9 -0
  60. package/dist/ports/driven/scenario-registry.d.ts +46 -0
  61. package/dist/ports/driven/scenario-registry.d.ts.map +1 -0
  62. package/dist/ports/driven/scenario-registry.js +1 -0
  63. package/dist/ports/driven/scenario-store.d.ts +33 -0
  64. package/dist/ports/driven/scenario-store.d.ts.map +1 -0
  65. package/dist/ports/driven/scenario-store.js +1 -0
  66. package/dist/ports/driven/sequence-tracker.d.ts +49 -0
  67. package/dist/ports/driven/sequence-tracker.d.ts.map +1 -0
  68. package/dist/ports/driven/sequence-tracker.js +1 -0
  69. package/dist/ports/driven/state-manager.d.ts +56 -0
  70. package/dist/ports/driven/state-manager.d.ts.map +1 -0
  71. package/dist/ports/driven/state-manager.js +1 -0
  72. package/dist/ports/driving/scenario-manager.d.ts +99 -0
  73. package/dist/ports/driving/scenario-manager.d.ts.map +1 -0
  74. package/dist/ports/driving/scenario-manager.js +1 -0
  75. package/dist/ports/index.d.ts +8 -0
  76. package/dist/ports/index.d.ts.map +1 -0
  77. package/dist/ports/index.js +1 -0
  78. package/dist/schemas/index.d.ts +18 -0
  79. package/dist/schemas/index.d.ts.map +1 -0
  80. package/dist/schemas/index.js +17 -0
  81. package/dist/schemas/match-criteria.d.ts +27 -0
  82. package/dist/schemas/match-criteria.d.ts.map +1 -0
  83. package/dist/schemas/match-criteria.js +71 -0
  84. package/dist/schemas/scenario-definition.d.ts +276 -0
  85. package/dist/schemas/scenario-definition.d.ts.map +1 -0
  86. package/dist/schemas/scenario-definition.js +78 -0
  87. package/dist/schemas/scenario-requests.d.ts +33 -0
  88. package/dist/schemas/scenario-requests.d.ts.map +1 -0
  89. package/dist/schemas/scenario-requests.js +29 -0
  90. package/dist/schemas/scenarios-object.d.ts +91 -0
  91. package/dist/schemas/scenarios-object.d.ts.map +1 -0
  92. package/dist/schemas/scenarios-object.js +17 -0
  93. package/dist/types/config.d.ts +70 -0
  94. package/dist/types/config.d.ts.map +1 -0
  95. package/dist/types/config.js +1 -0
  96. package/dist/types/index.d.ts +4 -0
  97. package/dist/types/index.d.ts.map +1 -0
  98. package/dist/types/index.js +1 -0
  99. package/dist/types/scenario.d.ts +141 -0
  100. package/dist/types/scenario.d.ts.map +1 -0
  101. package/dist/types/scenario.js +1 -0
  102. package/package.json +67 -7
@@ -0,0 +1,276 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Zod schemas for scenario definitions.
4
+ * These schemas validate the structure of scenario data at trust boundaries.
5
+ *
6
+ * **IMPORTANT**: TypeScript types are inferred from these schemas to maintain
7
+ * a single source of truth. The schemas in this file are the canonical definition.
8
+ */
9
+ export declare const HttpMethodSchema: z.ZodEnum<{
10
+ GET: "GET";
11
+ POST: "POST";
12
+ PUT: "PUT";
13
+ DELETE: "DELETE";
14
+ PATCH: "PATCH";
15
+ OPTIONS: "OPTIONS";
16
+ HEAD: "HEAD";
17
+ }>;
18
+ export type HttpMethod = z.infer<typeof HttpMethodSchema>;
19
+ export declare const ScenaristResponseSchema: z.ZodObject<{
20
+ status: z.ZodNumber;
21
+ body: z.ZodOptional<z.ZodUnknown>;
22
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
23
+ delay: z.ZodOptional<z.ZodNumber>;
24
+ }, z.core.$strip>;
25
+ export type ScenaristResponse = z.infer<typeof ScenaristResponseSchema>;
26
+ /**
27
+ * Match value supports 6 matching strategies:
28
+ * - Plain string: exact match (backward compatible)
29
+ * - equals: explicit exact match
30
+ * - contains: substring match
31
+ * - startsWith: prefix match
32
+ * - endsWith: suffix match
33
+ * - regex: pattern match (serialized form)
34
+ * - Native RegExp: pattern match (native JavaScript RegExp object)
35
+ *
36
+ * Exactly ONE strategy must be defined when using object form.
37
+ */
38
+ export declare const MatchValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
39
+ equals: z.ZodOptional<z.ZodString>;
40
+ contains: z.ZodOptional<z.ZodString>;
41
+ startsWith: z.ZodOptional<z.ZodString>;
42
+ endsWith: z.ZodOptional<z.ZodString>;
43
+ regex: z.ZodOptional<z.ZodObject<{
44
+ source: z.ZodString;
45
+ flags: z.ZodOptional<z.ZodString>;
46
+ }, z.core.$strip>>;
47
+ }, z.core.$strip>]>;
48
+ export type MatchValue = z.infer<typeof MatchValueSchema>;
49
+ export declare const ScenaristMatchSchema: z.ZodObject<{
50
+ url: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
51
+ equals: z.ZodOptional<z.ZodString>;
52
+ contains: z.ZodOptional<z.ZodString>;
53
+ startsWith: z.ZodOptional<z.ZodString>;
54
+ endsWith: z.ZodOptional<z.ZodString>;
55
+ regex: z.ZodOptional<z.ZodObject<{
56
+ source: z.ZodString;
57
+ flags: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>>;
59
+ }, z.core.$strip>]>>;
60
+ body: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
61
+ equals: z.ZodOptional<z.ZodString>;
62
+ contains: z.ZodOptional<z.ZodString>;
63
+ startsWith: z.ZodOptional<z.ZodString>;
64
+ endsWith: z.ZodOptional<z.ZodString>;
65
+ regex: z.ZodOptional<z.ZodObject<{
66
+ source: z.ZodString;
67
+ flags: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>>;
69
+ }, z.core.$strip>]>>>;
70
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
71
+ equals: z.ZodOptional<z.ZodString>;
72
+ contains: z.ZodOptional<z.ZodString>;
73
+ startsWith: z.ZodOptional<z.ZodString>;
74
+ endsWith: z.ZodOptional<z.ZodString>;
75
+ regex: z.ZodOptional<z.ZodObject<{
76
+ source: z.ZodString;
77
+ flags: z.ZodOptional<z.ZodString>;
78
+ }, z.core.$strip>>;
79
+ }, z.core.$strip>]>>>;
80
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
81
+ equals: z.ZodOptional<z.ZodString>;
82
+ contains: z.ZodOptional<z.ZodString>;
83
+ startsWith: z.ZodOptional<z.ZodString>;
84
+ endsWith: z.ZodOptional<z.ZodString>;
85
+ regex: z.ZodOptional<z.ZodObject<{
86
+ source: z.ZodString;
87
+ flags: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strip>>;
89
+ }, z.core.$strip>]>>>;
90
+ }, z.core.$strip>;
91
+ export type ScenaristMatch = z.infer<typeof ScenaristMatchSchema>;
92
+ export declare const RepeatModeSchema: z.ZodEnum<{
93
+ last: "last";
94
+ cycle: "cycle";
95
+ none: "none";
96
+ }>;
97
+ export type RepeatMode = z.infer<typeof RepeatModeSchema>;
98
+ export declare const ScenaristSequenceSchema: z.ZodObject<{
99
+ responses: z.ZodArray<z.ZodObject<{
100
+ status: z.ZodNumber;
101
+ body: z.ZodOptional<z.ZodUnknown>;
102
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
103
+ delay: z.ZodOptional<z.ZodNumber>;
104
+ }, z.core.$strip>>;
105
+ repeat: z.ZodOptional<z.ZodEnum<{
106
+ last: "last";
107
+ cycle: "cycle";
108
+ none: "none";
109
+ }>>;
110
+ }, z.core.$strip>;
111
+ export type ScenaristSequence = z.infer<typeof ScenaristSequenceSchema>;
112
+ export declare const ScenaristCaptureConfigSchema: z.ZodRecord<z.ZodString, z.ZodString>;
113
+ export type ScenaristCaptureConfig = z.infer<typeof ScenaristCaptureConfigSchema>;
114
+ /**
115
+ * URL pattern supports three forms:
116
+ * - String: exact match, path params (/users/:id), or glob (/api/*)
117
+ * - Native RegExp: pattern match (e.g., /\/users\/\d+/)
118
+ */
119
+ export declare const ScenaristUrlPatternSchema: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>]>;
120
+ export type ScenaristUrlPattern = z.infer<typeof ScenaristUrlPatternSchema>;
121
+ export declare const ScenaristMockSchema: z.ZodObject<{
122
+ method: z.ZodEnum<{
123
+ GET: "GET";
124
+ POST: "POST";
125
+ PUT: "PUT";
126
+ DELETE: "DELETE";
127
+ PATCH: "PATCH";
128
+ OPTIONS: "OPTIONS";
129
+ HEAD: "HEAD";
130
+ }>;
131
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>]>;
132
+ match: z.ZodOptional<z.ZodObject<{
133
+ url: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
134
+ equals: z.ZodOptional<z.ZodString>;
135
+ contains: z.ZodOptional<z.ZodString>;
136
+ startsWith: z.ZodOptional<z.ZodString>;
137
+ endsWith: z.ZodOptional<z.ZodString>;
138
+ regex: z.ZodOptional<z.ZodObject<{
139
+ source: z.ZodString;
140
+ flags: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strip>>;
142
+ }, z.core.$strip>]>>;
143
+ body: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
144
+ equals: z.ZodOptional<z.ZodString>;
145
+ contains: z.ZodOptional<z.ZodString>;
146
+ startsWith: z.ZodOptional<z.ZodString>;
147
+ endsWith: z.ZodOptional<z.ZodString>;
148
+ regex: z.ZodOptional<z.ZodObject<{
149
+ source: z.ZodString;
150
+ flags: z.ZodOptional<z.ZodString>;
151
+ }, z.core.$strip>>;
152
+ }, z.core.$strip>]>>>;
153
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
154
+ equals: z.ZodOptional<z.ZodString>;
155
+ contains: z.ZodOptional<z.ZodString>;
156
+ startsWith: z.ZodOptional<z.ZodString>;
157
+ endsWith: z.ZodOptional<z.ZodString>;
158
+ regex: z.ZodOptional<z.ZodObject<{
159
+ source: z.ZodString;
160
+ flags: z.ZodOptional<z.ZodString>;
161
+ }, z.core.$strip>>;
162
+ }, z.core.$strip>]>>>;
163
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
164
+ equals: z.ZodOptional<z.ZodString>;
165
+ contains: z.ZodOptional<z.ZodString>;
166
+ startsWith: z.ZodOptional<z.ZodString>;
167
+ endsWith: z.ZodOptional<z.ZodString>;
168
+ regex: z.ZodOptional<z.ZodObject<{
169
+ source: z.ZodString;
170
+ flags: z.ZodOptional<z.ZodString>;
171
+ }, z.core.$strip>>;
172
+ }, z.core.$strip>]>>>;
173
+ }, z.core.$strip>>;
174
+ response: z.ZodOptional<z.ZodObject<{
175
+ status: z.ZodNumber;
176
+ body: z.ZodOptional<z.ZodUnknown>;
177
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
178
+ delay: z.ZodOptional<z.ZodNumber>;
179
+ }, z.core.$strip>>;
180
+ sequence: z.ZodOptional<z.ZodObject<{
181
+ responses: z.ZodArray<z.ZodObject<{
182
+ status: z.ZodNumber;
183
+ body: z.ZodOptional<z.ZodUnknown>;
184
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
185
+ delay: z.ZodOptional<z.ZodNumber>;
186
+ }, z.core.$strip>>;
187
+ repeat: z.ZodOptional<z.ZodEnum<{
188
+ last: "last";
189
+ cycle: "cycle";
190
+ none: "none";
191
+ }>>;
192
+ }, z.core.$strip>>;
193
+ captureState: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
194
+ }, z.core.$strip>;
195
+ export type ScenaristMock = z.infer<typeof ScenaristMockSchema>;
196
+ export declare const ScenaristScenarioSchema: z.ZodObject<{
197
+ id: z.ZodString;
198
+ name: z.ZodString;
199
+ description: z.ZodString;
200
+ mocks: z.ZodArray<z.ZodObject<{
201
+ method: z.ZodEnum<{
202
+ GET: "GET";
203
+ POST: "POST";
204
+ PUT: "PUT";
205
+ DELETE: "DELETE";
206
+ PATCH: "PATCH";
207
+ OPTIONS: "OPTIONS";
208
+ HEAD: "HEAD";
209
+ }>;
210
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>]>;
211
+ match: z.ZodOptional<z.ZodObject<{
212
+ url: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
213
+ equals: z.ZodOptional<z.ZodString>;
214
+ contains: z.ZodOptional<z.ZodString>;
215
+ startsWith: z.ZodOptional<z.ZodString>;
216
+ endsWith: z.ZodOptional<z.ZodString>;
217
+ regex: z.ZodOptional<z.ZodObject<{
218
+ source: z.ZodString;
219
+ flags: z.ZodOptional<z.ZodString>;
220
+ }, z.core.$strip>>;
221
+ }, z.core.$strip>]>>;
222
+ body: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
223
+ equals: z.ZodOptional<z.ZodString>;
224
+ contains: z.ZodOptional<z.ZodString>;
225
+ startsWith: z.ZodOptional<z.ZodString>;
226
+ endsWith: z.ZodOptional<z.ZodString>;
227
+ regex: z.ZodOptional<z.ZodObject<{
228
+ source: z.ZodString;
229
+ flags: z.ZodOptional<z.ZodString>;
230
+ }, z.core.$strip>>;
231
+ }, z.core.$strip>]>>>;
232
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
233
+ equals: z.ZodOptional<z.ZodString>;
234
+ contains: z.ZodOptional<z.ZodString>;
235
+ startsWith: z.ZodOptional<z.ZodString>;
236
+ endsWith: z.ZodOptional<z.ZodString>;
237
+ regex: z.ZodOptional<z.ZodObject<{
238
+ source: z.ZodString;
239
+ flags: z.ZodOptional<z.ZodString>;
240
+ }, z.core.$strip>>;
241
+ }, z.core.$strip>]>>>;
242
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
243
+ equals: z.ZodOptional<z.ZodString>;
244
+ contains: z.ZodOptional<z.ZodString>;
245
+ startsWith: z.ZodOptional<z.ZodString>;
246
+ endsWith: z.ZodOptional<z.ZodString>;
247
+ regex: z.ZodOptional<z.ZodObject<{
248
+ source: z.ZodString;
249
+ flags: z.ZodOptional<z.ZodString>;
250
+ }, z.core.$strip>>;
251
+ }, z.core.$strip>]>>>;
252
+ }, z.core.$strip>>;
253
+ response: z.ZodOptional<z.ZodObject<{
254
+ status: z.ZodNumber;
255
+ body: z.ZodOptional<z.ZodUnknown>;
256
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
257
+ delay: z.ZodOptional<z.ZodNumber>;
258
+ }, z.core.$strip>>;
259
+ sequence: z.ZodOptional<z.ZodObject<{
260
+ responses: z.ZodArray<z.ZodObject<{
261
+ status: z.ZodNumber;
262
+ body: z.ZodOptional<z.ZodUnknown>;
263
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
264
+ delay: z.ZodOptional<z.ZodNumber>;
265
+ }, z.core.$strip>>;
266
+ repeat: z.ZodOptional<z.ZodEnum<{
267
+ last: "last";
268
+ cycle: "cycle";
269
+ none: "none";
270
+ }>>;
271
+ }, z.core.$strip>>;
272
+ captureState: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
273
+ }, z.core.$strip>>;
274
+ }, z.core.$strip>;
275
+ export type ScenaristScenario = z.infer<typeof ScenaristScenarioSchema>;
276
+ //# sourceMappingURL=scenario-definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario-definition.d.ts","sourceRoot":"","sources":["../../src/schemas/scenario-definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;EAAuE,CAAC;AACrG,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,uBAAuB;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;mBAiB3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,gBAAgB;;;;EAAoC,CAAC;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBAGlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,4BAA4B,uCAAmC,CAAC;AAC7E,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,iEAGpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ import { SerializedRegexSchema } from './match-criteria.js';
3
+ /**
4
+ * Zod schemas for scenario definitions.
5
+ * These schemas validate the structure of scenario data at trust boundaries.
6
+ *
7
+ * **IMPORTANT**: TypeScript types are inferred from these schemas to maintain
8
+ * a single source of truth. The schemas in this file are the canonical definition.
9
+ */
10
+ export const HttpMethodSchema = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']);
11
+ export const ScenaristResponseSchema = z.object({
12
+ status: z.number().int().min(100).max(599),
13
+ body: z.unknown().optional(),
14
+ headers: z.record(z.string(), z.string()).optional(),
15
+ delay: z.number().nonnegative().optional(),
16
+ });
17
+ /**
18
+ * Match value supports 6 matching strategies:
19
+ * - Plain string: exact match (backward compatible)
20
+ * - equals: explicit exact match
21
+ * - contains: substring match
22
+ * - startsWith: prefix match
23
+ * - endsWith: suffix match
24
+ * - regex: pattern match (serialized form)
25
+ * - Native RegExp: pattern match (native JavaScript RegExp object)
26
+ *
27
+ * Exactly ONE strategy must be defined when using object form.
28
+ */
29
+ export const MatchValueSchema = z.union([
30
+ z.string(),
31
+ z.instanceof(RegExp),
32
+ z.object({
33
+ equals: z.string().optional(),
34
+ contains: z.string().optional(),
35
+ startsWith: z.string().optional(),
36
+ endsWith: z.string().optional(),
37
+ regex: SerializedRegexSchema.optional(),
38
+ }).refine((obj) => {
39
+ const strategies = [obj.equals, obj.contains, obj.startsWith, obj.endsWith, obj.regex];
40
+ const defined = strategies.filter(s => s !== undefined);
41
+ return defined.length === 1;
42
+ }, { message: 'Exactly one matching strategy must be defined (equals, contains, startsWith, endsWith, or regex)' }),
43
+ ]);
44
+ export const ScenaristMatchSchema = z.object({
45
+ url: MatchValueSchema.optional(),
46
+ body: z.record(z.string(), MatchValueSchema).optional(),
47
+ headers: z.record(z.string(), MatchValueSchema).optional(),
48
+ query: z.record(z.string(), MatchValueSchema).optional(),
49
+ });
50
+ export const RepeatModeSchema = z.enum(['last', 'cycle', 'none']);
51
+ export const ScenaristSequenceSchema = z.object({
52
+ responses: z.array(ScenaristResponseSchema).min(1),
53
+ repeat: RepeatModeSchema.optional(),
54
+ });
55
+ export const ScenaristCaptureConfigSchema = z.record(z.string(), z.string());
56
+ /**
57
+ * URL pattern supports three forms:
58
+ * - String: exact match, path params (/users/:id), or glob (/api/*)
59
+ * - Native RegExp: pattern match (e.g., /\/users\/\d+/)
60
+ */
61
+ export const ScenaristUrlPatternSchema = z.union([
62
+ z.string().min(1),
63
+ z.instanceof(RegExp),
64
+ ]);
65
+ export const ScenaristMockSchema = z.object({
66
+ method: HttpMethodSchema,
67
+ url: ScenaristUrlPatternSchema,
68
+ match: ScenaristMatchSchema.optional(),
69
+ response: ScenaristResponseSchema.optional(),
70
+ sequence: ScenaristSequenceSchema.optional(),
71
+ captureState: ScenaristCaptureConfigSchema.optional(),
72
+ });
73
+ export const ScenaristScenarioSchema = z.object({
74
+ id: z.string().min(1),
75
+ name: z.string().min(1),
76
+ description: z.string(),
77
+ mocks: z.array(ScenaristMockSchema),
78
+ });
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Schema for scenario switch request body.
4
+ *
5
+ * This schema defines the domain rules for what constitutes a valid
6
+ * scenario switch request. All framework adapters MUST use this schema
7
+ * to validate scenario switch requests at the trust boundary (HTTP request → domain).
8
+ *
9
+ * **Architectural Note:**
10
+ * - This is DOMAIN KNOWLEDGE (what makes a valid request)
11
+ * - Adapters apply this validation at TRUST BOUNDARIES
12
+ * - Single source of truth for scenario request validation
13
+ * - Never duplicate this schema in adapters
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // In adapter endpoint handler:
18
+ * import { ScenarioRequestSchema } from '@scenarist/core';
19
+ *
20
+ * const { scenario } = ScenarioRequestSchema.parse(req.body);
21
+ * ```
22
+ */
23
+ export declare const ScenarioRequestSchema: z.ZodObject<{
24
+ scenario: z.ZodString;
25
+ }, z.core.$strip>;
26
+ /**
27
+ * Type derived from ScenarioRequestSchema.
28
+ * Represents a validated scenario switch request.
29
+ *
30
+ * **Usage:** Use this type for function parameters after validation has occurred.
31
+ */
32
+ export type ScenarioRequest = z.infer<typeof ScenarioRequestSchema>;
33
+ //# sourceMappingURL=scenario-requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenario-requests.d.ts","sourceRoot":"","sources":["../../src/schemas/scenario-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,qBAAqB;;iBAMhC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Schema for scenario switch request body.
4
+ *
5
+ * This schema defines the domain rules for what constitutes a valid
6
+ * scenario switch request. All framework adapters MUST use this schema
7
+ * to validate scenario switch requests at the trust boundary (HTTP request → domain).
8
+ *
9
+ * **Architectural Note:**
10
+ * - This is DOMAIN KNOWLEDGE (what makes a valid request)
11
+ * - Adapters apply this validation at TRUST BOUNDARIES
12
+ * - Single source of truth for scenario request validation
13
+ * - Never duplicate this schema in adapters
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // In adapter endpoint handler:
18
+ * import { ScenarioRequestSchema } from '@scenarist/core';
19
+ *
20
+ * const { scenario } = ScenarioRequestSchema.parse(req.body);
21
+ * ```
22
+ */
23
+ export const ScenarioRequestSchema = z.object({
24
+ /**
25
+ * Scenario ID to switch to.
26
+ * Must be a non-empty string matching a registered scenario ID.
27
+ */
28
+ scenario: z.string().min(1, 'Scenario ID must not be empty'),
29
+ });
@@ -0,0 +1,91 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Validates that a scenarios object has a 'default' key.
4
+ *
5
+ * This enforces the convention that all scenario collections must
6
+ * include a 'default' scenario to serve as the baseline.
7
+ *
8
+ * **Trust Boundary:** Applied in buildConfig when user provides scenarios.
9
+ *
10
+ * Each value must be a valid ScenarioDefinition with proper structure.
11
+ */
12
+ export declare const ScenariosObjectSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
13
+ id: z.ZodString;
14
+ name: z.ZodString;
15
+ description: z.ZodString;
16
+ mocks: z.ZodArray<z.ZodObject<{
17
+ method: z.ZodEnum<{
18
+ GET: "GET";
19
+ POST: "POST";
20
+ PUT: "PUT";
21
+ DELETE: "DELETE";
22
+ PATCH: "PATCH";
23
+ OPTIONS: "OPTIONS";
24
+ HEAD: "HEAD";
25
+ }>;
26
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>]>;
27
+ match: z.ZodOptional<z.ZodObject<{
28
+ url: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
29
+ equals: z.ZodOptional<z.ZodString>;
30
+ contains: z.ZodOptional<z.ZodString>;
31
+ startsWith: z.ZodOptional<z.ZodString>;
32
+ endsWith: z.ZodOptional<z.ZodString>;
33
+ regex: z.ZodOptional<z.ZodObject<{
34
+ source: z.ZodString;
35
+ flags: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>>;
37
+ }, z.core.$strip>]>>;
38
+ body: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
39
+ equals: z.ZodOptional<z.ZodString>;
40
+ contains: z.ZodOptional<z.ZodString>;
41
+ startsWith: z.ZodOptional<z.ZodString>;
42
+ endsWith: z.ZodOptional<z.ZodString>;
43
+ regex: z.ZodOptional<z.ZodObject<{
44
+ source: z.ZodString;
45
+ flags: z.ZodOptional<z.ZodString>;
46
+ }, z.core.$strip>>;
47
+ }, z.core.$strip>]>>>;
48
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
49
+ equals: z.ZodOptional<z.ZodString>;
50
+ contains: z.ZodOptional<z.ZodString>;
51
+ startsWith: z.ZodOptional<z.ZodString>;
52
+ endsWith: z.ZodOptional<z.ZodString>;
53
+ regex: z.ZodOptional<z.ZodObject<{
54
+ source: z.ZodString;
55
+ flags: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>;
57
+ }, z.core.$strip>]>>>;
58
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
59
+ equals: z.ZodOptional<z.ZodString>;
60
+ contains: z.ZodOptional<z.ZodString>;
61
+ startsWith: z.ZodOptional<z.ZodString>;
62
+ endsWith: z.ZodOptional<z.ZodString>;
63
+ regex: z.ZodOptional<z.ZodObject<{
64
+ source: z.ZodString;
65
+ flags: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ }, z.core.$strip>]>>>;
68
+ }, z.core.$strip>>;
69
+ response: z.ZodOptional<z.ZodObject<{
70
+ status: z.ZodNumber;
71
+ body: z.ZodOptional<z.ZodUnknown>;
72
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
73
+ delay: z.ZodOptional<z.ZodNumber>;
74
+ }, z.core.$strip>>;
75
+ sequence: z.ZodOptional<z.ZodObject<{
76
+ responses: z.ZodArray<z.ZodObject<{
77
+ status: z.ZodNumber;
78
+ body: z.ZodOptional<z.ZodUnknown>;
79
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
80
+ delay: z.ZodOptional<z.ZodNumber>;
81
+ }, z.core.$strip>>;
82
+ repeat: z.ZodOptional<z.ZodEnum<{
83
+ last: "last";
84
+ cycle: "cycle";
85
+ none: "none";
86
+ }>>;
87
+ }, z.core.$strip>>;
88
+ captureState: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
+ }, z.core.$strip>>;
90
+ }, z.core.$strip>>;
91
+ //# sourceMappingURL=scenarios-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios-object.d.ts","sourceRoot":"","sources":["../../src/schemas/scenarios-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAI9B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import { ScenaristScenarioSchema } from './scenario-definition.js';
3
+ /**
4
+ * Validates that a scenarios object has a 'default' key.
5
+ *
6
+ * This enforces the convention that all scenario collections must
7
+ * include a 'default' scenario to serve as the baseline.
8
+ *
9
+ * **Trust Boundary:** Applied in buildConfig when user provides scenarios.
10
+ *
11
+ * Each value must be a valid ScenarioDefinition with proper structure.
12
+ */
13
+ export const ScenariosObjectSchema = z
14
+ .record(z.string(), ScenaristScenarioSchema)
15
+ .refine((scenarios) => 'default' in scenarios, {
16
+ message: "Scenarios object must have a 'default' key",
17
+ });
@@ -0,0 +1,70 @@
1
+ import type { ScenaristScenarios } from './scenario.js';
2
+ /**
3
+ * Configuration for the scenario management system.
4
+ * All properties are readonly for immutability.
5
+ */
6
+ export type ScenaristConfig = {
7
+ /**
8
+ * Whether mocking is enabled.
9
+ * For dynamic enabling (e.g., based on environment), evaluate before creating config:
10
+ * `enabled: process.env.NODE_ENV !== 'production'`
11
+ */
12
+ readonly enabled: boolean;
13
+ /**
14
+ * Whether to enforce strict mode for unmocked requests.
15
+ *
16
+ * - `true`: Unmocked requests return error responses (501 Not Implemented)
17
+ * - `false`: Unmocked requests passthrough to real APIs
18
+ *
19
+ * Default: false
20
+ *
21
+ * Strict mode is useful in tests to ensure all external API calls are explicitly mocked,
22
+ * preventing accidental calls to real services.
23
+ */
24
+ readonly strictMode: boolean;
25
+ /**
26
+ * HTTP endpoint paths for scenario control.
27
+ */
28
+ readonly endpoints: {
29
+ /** Endpoint to set/switch scenarios (default: '/__scenario__') */
30
+ readonly setScenario: string;
31
+ /** Endpoint to get current scenario (default: '/__scenario__') */
32
+ readonly getScenario: string;
33
+ };
34
+ /**
35
+ * The default test ID to use when no x-scenarist-test-id header is present.
36
+ */
37
+ readonly defaultTestId: string;
38
+ };
39
+ /**
40
+ * Partial config for user input - missing values will use defaults.
41
+ * All properties must be serializable (no functions).
42
+ */
43
+ export type ScenaristConfigInput<T extends ScenaristScenarios = ScenaristScenarios> = {
44
+ readonly enabled: boolean;
45
+ readonly strictMode?: boolean;
46
+ readonly endpoints?: Partial<ScenaristConfig['endpoints']>;
47
+ /**
48
+ * All scenarios defined as a named object.
49
+ * Keys become scenario IDs that enable type-safe autocomplete.
50
+ *
51
+ * **REQUIRED:** Must include a 'default' key to serve as the baseline scenario.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const scenarios = {
56
+ * default: { id: 'default', ... }, // Required!
57
+ * cartWithState: { id: 'cartWithState', ... },
58
+ * premiumUser: { id: 'premiumUser', ... },
59
+ * } as const satisfies ScenaristScenarios;
60
+ *
61
+ * createScenarist({
62
+ * enabled: true,
63
+ * scenarios,
64
+ * });
65
+ * ```
66
+ */
67
+ readonly scenarios: T;
68
+ readonly defaultTestId?: string;
69
+ };
70
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE;QAClB,kEAAkE;QAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,kEAAkE;QAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;IAC3D;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACtB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export type { HttpMethod, ScenaristResponse, ScenaristMock, ScenaristMatch, RepeatMode, ScenaristSequence, ScenaristCaptureConfig, ScenaristScenario, } from '../schemas/scenario-definition.js';
2
+ export type { HttpRequestContext, ScenaristMockWithParams, ActiveScenario, ScenaristResult, ScenaristScenarios, ScenarioIds, } from './scenario.js';
3
+ export type { ScenaristConfig, ScenaristConfigInput, } from './config.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,mCAAmC,CAAC;AAG3C,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,eAAe,EACf,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ export {};