counterfact 1.5.0 → 1.6.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.
@@ -5,6 +5,7 @@ import { READ_ONLY_COMMENTS } from "./read-only-comments.js";
5
5
  import { ResponsesTypeCoder } from "./responses-type-coder.js";
6
6
  import { SchemaTypeCoder } from "./schema-type-coder.js";
7
7
  import { TypeCoder } from "./type-coder.js";
8
+ import { ParameterExportTypeCoder } from "./parameter-export-type-coder.js";
8
9
  export class OperationTypeCoder extends TypeCoder {
9
10
  constructor(requirement, requestMethod, securitySchemes = []) {
10
11
  super(requirement);
@@ -14,9 +15,23 @@ export class OperationTypeCoder extends TypeCoder {
14
15
  this.requestMethod = requestMethod;
15
16
  this.securitySchemes = securitySchemes;
16
17
  }
18
+ getOperationBaseName() {
19
+ const operationId = this.requirement.get("operationId")?.data;
20
+ return operationId || `HTTP_${this.requestMethod.toUpperCase()}`;
21
+ }
17
22
  names() {
18
23
  return super.names(`HTTP_${this.requestMethod.toUpperCase()}`);
19
24
  }
25
+ exportParameterType(script, parameterKind, inlineType, baseName, modulePath) {
26
+ if (inlineType === "never") {
27
+ return "never";
28
+ }
29
+ const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
30
+ const typeName = `${baseName}_${capitalize(parameterKind)}`;
31
+ const coder = new ParameterExportTypeCoder(this.requirement, typeName, inlineType, parameterKind);
32
+ coder._modulePath = modulePath;
33
+ return script.export(coder, true);
34
+ }
20
35
  responseTypes(script) {
21
36
  return this.requirement
22
37
  .get("responses")
@@ -87,6 +102,12 @@ export class OperationTypeCoder extends TypeCoder {
87
102
  this.requirement.specification?.rootRequirement?.get("produces")?.data).write(script);
88
103
  const proxyType = "(url: string) => COUNTERFACT_RESPONSE";
89
104
  const delayType = "(milliseconds: number, maxMilliseconds?: number) => Promise<void>";
90
- return `($: OmitValueWhenNever<{ query: ${queryType}, path: ${pathType}, headers: ${headersType}, body: ${bodyType}, context: ${contextTypeImportName}, response: ${responseType}, x: ${xType}, proxy: ${proxyType}, user: ${this.userType()}, delay: ${delayType} }>) => MaybePromise<${this.responseTypes(script)} | { status: 415, contentType: "text/plain", body: string } | COUNTERFACT_RESPONSE | { ALL_REMAINING_HEADERS_ARE_OPTIONAL: COUNTERFACT_RESPONSE }>`;
105
+ // Get the base name for this operation and export parameter types
106
+ const baseName = this.getOperationBaseName();
107
+ const modulePath = this.modulePath();
108
+ const queryTypeName = this.exportParameterType(script, "query", queryType, baseName, modulePath);
109
+ const pathTypeName = this.exportParameterType(script, "path", pathType, baseName, modulePath);
110
+ const headersTypeName = this.exportParameterType(script, "headers", headersType, baseName, modulePath);
111
+ return `($: OmitValueWhenNever<{ query: ${queryTypeName}, path: ${pathTypeName}, headers: ${headersTypeName}, body: ${bodyType}, context: ${contextTypeImportName}, response: ${responseType}, x: ${xType}, proxy: ${proxyType}, user: ${this.userType()}, delay: ${delayType} }>) => MaybePromise<${this.responseTypes(script)} | { status: 415, contentType: "text/plain", body: string } | COUNTERFACT_RESPONSE | { ALL_REMAINING_HEADERS_ARE_OPTIONAL: COUNTERFACT_RESPONSE }>`;
91
112
  }
92
113
  }
@@ -0,0 +1,24 @@
1
+ import { TypeCoder } from "./type-coder.js";
2
+ // Helper class for exporting parameter types
3
+ export class ParameterExportTypeCoder extends TypeCoder {
4
+ constructor(requirement, typeName, typeCode, parameterKind) {
5
+ super(requirement);
6
+ this._typeName = typeName;
7
+ this._typeCode = typeCode;
8
+ this._parameterKind = parameterKind;
9
+ }
10
+ get id() {
11
+ // Make the id unique by including the parameter kind
12
+ return `${super.id}:${this._parameterKind}`;
13
+ }
14
+ *names() {
15
+ yield this._typeName;
16
+ }
17
+ writeCode() {
18
+ return this._typeCode;
19
+ }
20
+ modulePath() {
21
+ // Use the same module path as the parent operation
22
+ return this._modulePath;
23
+ }
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "counterfact",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Generate a TypeScript-based mock server from an OpenAPI spec in seconds — with stateful routes, hot reload, and REPL support.",
5
5
  "type": "module",
6
6
  "main": "./dist/app.js",
@@ -78,10 +78,10 @@
78
78
  },
79
79
  "devDependencies": {
80
80
  "@changesets/cli": "2.29.8",
81
- "@stryker-mutator/core": "9.4.0",
82
- "@stryker-mutator/jest-runner": "9.4.0",
83
- "@stryker-mutator/typescript-checker": "9.4.0",
84
- "@swc/core": "1.15.8",
81
+ "@stryker-mutator/core": "9.5.1",
82
+ "@stryker-mutator/jest-runner": "9.5.1",
83
+ "@stryker-mutator/typescript-checker": "9.5.1",
84
+ "@swc/core": "1.15.11",
85
85
  "@swc/jest": "0.2.39",
86
86
  "@testing-library/dom": "10.4.1",
87
87
  "@types/debug": "^4.1.12",
@@ -95,26 +95,26 @@
95
95
  "@typescript-eslint/eslint-plugin": "^8.53.0",
96
96
  "@typescript-eslint/parser": "^8.53.0",
97
97
  "copyfiles": "2.4.1",
98
- "eslint": "9.39.2",
98
+ "eslint": "9.39.3",
99
99
  "eslint-formatter-github-annotations": "0.1.0",
100
100
  "eslint-import-resolver-typescript": "4.4.4",
101
101
  "eslint-plugin-etc": "2.0.3",
102
102
  "eslint-plugin-file-progress": "3.0.2",
103
103
  "eslint-plugin-import": "2.32.0",
104
- "eslint-plugin-jest": "29.12.1",
104
+ "eslint-plugin-jest": "29.15.0",
105
105
  "eslint-plugin-jest-dom": "5.5.0",
106
- "eslint-plugin-n": "^17.23.2",
106
+ "eslint-plugin-n": "^17.24.0",
107
107
  "eslint-plugin-no-explicit-type-exports": "0.12.1",
108
108
  "eslint-plugin-prettier": "5.5.5",
109
109
  "eslint-plugin-promise": "^7.2.1",
110
- "eslint-plugin-regexp": "^2.10.0",
111
- "eslint-plugin-security": "^3.0.1",
112
- "eslint-plugin-unused-imports": "4.3.0",
110
+ "eslint-plugin-regexp": "^3.0.0",
111
+ "eslint-plugin-security": "^4.0.0",
112
+ "eslint-plugin-unused-imports": "4.4.1",
113
113
  "husky": "9.1.7",
114
114
  "jest": "30.2.0",
115
115
  "jest-retries": "1.0.1",
116
116
  "node-mocks-http": "1.17.2",
117
- "rimraf": "6.1.2",
117
+ "rimraf": "6.1.3",
118
118
  "stryker-cli": "1.1.0",
119
119
  "supertest": "7.2.2",
120
120
  "tsd": "0.33.0",
@@ -125,7 +125,7 @@
125
125
  "@hapi/accept": "6.0.3",
126
126
  "@types/json-schema": "7.0.15",
127
127
  "chokidar": "5.0.0",
128
- "commander": "14.0.2",
128
+ "commander": "14.0.3",
129
129
  "debug": "4.4.3",
130
130
  "fetch": "1.1.0",
131
131
  "fs-extra": "11.3.3",
@@ -143,7 +143,7 @@
143
143
  "open": "11.0.0",
144
144
  "patch-package": "8.0.1",
145
145
  "precinct": "12.2.0",
146
- "prettier": "3.8.0",
146
+ "prettier": "3.8.1",
147
147
  "typescript": "5.9.3"
148
148
  },
149
149
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",