@contractkit/plugin-csharp 0.1.3 → 0.1.4

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,9 +5,9 @@ $ tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly
5
5
  CLI tsup v8.5.1
6
6
  CLI Target: esnext
7
7
  ESM Build start
8
- ESM dist/index.js 87.30 KB
9
- ESM dist/index.js.map 188.87 KB
10
- ESM ⚡️ Build success in 180ms
8
+ ESM dist/index.js 88.63 KB
9
+ ESM dist/index.js.map 193.78 KB
10
+ ESM ⚡️ Build success in 154ms
11
11
  DTS Build start
12
- DTS ⚡️ Build success in 7420ms
12
+ DTS ⚡️ Build success in 6453ms
13
13
  DTS dist/index.d.ts 1.50 KB
@@ -3,34 +3,34 @@ $ vitest run --coverage
3
3
   RUN  v4.1.5 /home/runner/work/ContractKit/ContractKit/packages/plugin-csharp
4
4
  Coverage enabled with v8
5
5
 
6
- ✓ tests/codegen-client.test.ts (26 tests) 252ms
7
- ✓ tests/codegen-models.test.ts (65 tests) 282ms
8
- ✓ tests/index.test.ts (10 tests) 207ms
9
- ✓ tests/naming.test.ts (19 tests) 88ms
10
- ✓ tests/runtime.test.ts (14 tests) 51ms
11
- ✓ tests/scaffold.test.ts (5 tests) 14ms
12
- ✓ tests/hoist.test.ts (10 tests) 67ms
6
+ ✓ tests/naming.test.ts (23 tests) 110ms
7
+ ✓ tests/codegen-client.test.ts (40 tests) 305ms
8
+ ✓ tests/codegen-models.test.ts (65 tests) 306ms
9
+ ✓ tests/index.test.ts (10 tests) 199ms
10
+ ✓ tests/runtime.test.ts (14 tests) 65ms
11
+ ✓ tests/scaffold.test.ts (5 tests) 46ms
12
+ ✓ tests/hoist.test.ts (10 tests) 54ms
13
13
 
14
14
   Test Files  7 passed (7)
15
-  Tests  149 passed (149)
16
-  Start at  15:17:08
17
-  Duration  13.50s (transform 5.27s, setup 0ms, import 22.08s, tests 962ms, environment 10ms)
15
+  Tests  167 passed (167)
16
+  Start at  17:55:57
17
+  Duration  13.21s (transform 4.92s, setup 0ms, import 21.10s, tests 1.08s, environment 1ms)
18
18
 
19
19
   % Coverage report from v8
20
20
  -------------------|---------|----------|---------|---------|-------------------
21
21
  File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
22
22
  -------------------|---------|----------|---------|---------|-------------------
23
- All files | 88.04 | 77.07 | 89.59 | 90.82 |
24
- src | 88.08 | 77.15 | 89.79 | 90.86 |
25
- ...gen-client.ts | 94.61 | 87.12 | 94.91 | 97.59 | ...94-496,513-514
23
+ All files | 88.59 | 78.77 | 89.91 | 90.97 |
24
+ src | 88.65 | 78.52 | 90.14 | 91.02 |
25
+ ...gen-client.ts | 95.91 | 90.87 | 95.38 | 97.67 | ...28-530,547-548
26
26
  ...gen-models.ts | 91.29 | 75.25 | 96.61 | 93.02 | ...05,907,929-932
27
27
  codegen-sdk.ts | 100 | 100 | 100 | 100 |
28
28
  hoist.ts | 78.66 | 61.9 | 93.1 | 79.06 | ...13-322,350-362
29
29
  index.ts | 70.74 | 71.21 | 58.06 | 75.59 | ...25-329,350-369
30
- naming.ts | 86.2 | 72.72 | 100 | 100 | ...40,164-191,204
30
+ naming.ts | 88.05 | 72.72 | 100 | 100 | ...40,187-214,227
31
31
  ...converters.ts | 100 | 100 | 100 | 100 |
32
32
  runtime.ts | 100 | 100 | 100 | 100 |
33
33
  scaffold.ts | 100 | 100 | 100 | 100 |
34
- tests | 86.95 | 75.67 | 88 | 89.74 |
35
- helpers.ts | 86.95 | 75.67 | 88 | 89.74 | 99,138,146,175
34
+ tests | 86.95 | 83.78 | 88 | 89.74 |
35
+ helpers.ts | 86.95 | 83.78 | 88 | 89.74 | 99,138,146,175
36
36
  -------------------|---------|----------|---------|---------|-------------------
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @contractkit/plugin-csharp
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 6f8f55b: Fix two naming collisions that made the generated SDK fail to compile.
8
+
9
+ A path param named after one of the method's own arguments or locals was declared twice: `/notes/{body}` on an operation with a request body gave `PutNoteAsync(string body, Note body, ...)`, error CS0100. A path param now gets a trailing underscore when it lands on `body`, `query`, `customHeaders`, `pathParams`, `cancellationToken`, the `response` and `headers` locals, or the client's `http` field, so that method takes `string body_`. Keyword escaping is unchanged (`string @class`). The pattern variable an optional response header is read into is renamed the same way, so a header named like a parameter no longer redeclares it (CS0136).
10
+
11
+ An operation that declares both a request `headers:` block and response headers generated two records named `<Method>Headers` in one namespace, error CS0101. The request record keeps that name, since it is the one a caller constructs, and the response record becomes `<Method>ResponseHeaders`. Operations declaring only one of the two are unchanged.
12
+
3
13
  ## 0.1.3
4
14
 
5
15
  ### Patch Changes
package/README.md CHANGED
@@ -143,7 +143,8 @@ that hold it.
143
143
  A method returns the response body directly. Three things change that:
144
144
 
145
145
  - A status declaring **response headers** returns `<Method>Result(Data, Headers)`, or
146
- `<Method>Headers` when there is no body.
146
+ `<Method>Headers` when there is no body. When the operation also declares request `headers:`,
147
+ those keep `<Method>Headers` and the response side is `<Method>ResponseHeaders`.
147
148
  - An operation the client can observe at **several statuses** returns an abstract
148
149
  `<Method>Response` with a `Status<code>` leaf each.
149
150
  - A status declaring **several content types** returns one leaf per mime.
@@ -24,7 +24,7 @@ export declare function generateCSharpClient(root: OpRootNode, opts: CSharpClien
24
24
  * values that came from the caller are percent-encoded. `params` says where a value lives: spread
25
25
  * across the signature, or behind one `pathParams` argument when the route declares a model.
26
26
  */
27
- export declare function buildPathExpression(path: string, params?: ParamSource): string;
27
+ export declare function buildPathExpression(path: string, params?: ParamSource, bindings?: ReadonlyMap<string, string>): string;
28
28
  /**
29
29
  * The SDK method name, in the same priority order every ContractKit SDK uses: an explicit `sdk:`,
30
30
  * then the operation's `name:`, then a name inferred from the verb and path. C# spells it
@@ -1 +1 @@
1
- {"version":3,"file":"codegen-client.d.ts","sourceRoot":"","sources":["../src/codegen-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,SAAS,EACT,eAAe,EAIf,UAAU,EACV,WAAW,EACX,WAAW,EACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAY9C,MAAM,WAAW,0BAA0B;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAwBD,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,UAAQ,GAAG,OAAO,CAOtF;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,0BAA0B,GAAG,MAAM,CA2E/F;AAwZD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAY9E;AAkFD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAIhF"}
1
+ {"version":3,"file":"codegen-client.d.ts","sourceRoot":"","sources":["../src/codegen-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,SAAS,EACT,eAAe,EAIf,UAAU,EACV,WAAW,EACX,WAAW,EACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAa9C,MAAM,WAAW,0BAA0B;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAwBD,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,UAAQ,GAAG,OAAO,CAOtF;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,0BAA0B,GAAG,MAAM,CA2E/F;AAscD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAetH;AAuGD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAIhF"}
package/dist/index.js CHANGED
@@ -115,6 +115,17 @@ function toCSharpParameterName(name) {
115
115
  if (/^\d/.test(result)) result = `_${result}`;
116
116
  return escapeCSharpIdentifier(result);
117
117
  }
118
+ function bindCSharpParameterNames(names, taken) {
119
+ const unavailable = new Set(taken);
120
+ const bindings = /* @__PURE__ */ new Map();
121
+ for (const name of names) {
122
+ let local = toCSharpParameterName(name).replace(/^@/, "");
123
+ while (unavailable.has(local)) local += "_";
124
+ unavailable.add(local);
125
+ bindings.set(name, escapeCSharpIdentifier(local));
126
+ }
127
+ return bindings;
128
+ }
118
129
  function safeMemberName(propertyName, ownerTypeName) {
119
130
  if (propertyName === ownerTypeName || RESERVED_MEMBER_NAMES.has(propertyName)) return `${propertyName}Value`;
120
131
  return propertyName;
@@ -897,10 +908,12 @@ function observableOf(shape) {
897
908
  function generateMethod(route, op, ctx, methodName) {
898
909
  const base = methodBase(methodName);
899
910
  const shape = responseShape(op);
900
- const returnType = returnTypeFor(shape, base, ctx);
911
+ const returnType = returnTypeFor(shape, op, base, ctx);
901
912
  const observable = observableOf(shape);
902
913
  const expectStatuses = observable.filter((r) => r.statusCode < 200 || r.statusCode >= 300).map((r) => r.statusCode);
903
- const params = buildMethodParams(route, op, ctx);
914
+ const pathBindings = bindPathParams(route);
915
+ const params = buildMethodParams(route, op, ctx, pathBindings);
916
+ const bound = [...METHOD_LOCALS, ...params.map((p) => p.name.replace(/^@/, ""))];
904
917
  const signature = [...params.map((p) => `${p.type} ${p.name}${p.optional ? " = null" : ""}`), "CancellationToken cancellationToken = default"].join(
905
918
  ", "
906
919
  );
@@ -909,7 +922,7 @@ function generateMethod(route, op, ctx, methodName) {
909
922
  if (resolveModifiers(route, op).includes("deprecated")) lines.push('[Obsolete("Deprecated in the contract")]');
910
923
  lines.push(`public async ${returnType === "void" ? "Task" : `Task<${returnType}>`} ${methodName}(${signature})`);
911
924
  lines.push("{");
912
- const callArgs = [`HttpMethod.${httpMethodConstant(op.method)}`, buildPathExpression(route.path, route.params)];
925
+ const callArgs = [`HttpMethod.${httpMethodConstant(op.method)}`, buildPathExpression(route.path, route.params, pathBindings)];
913
926
  if (op.query) callArgs.push("query: http.Params(query)");
914
927
  if (op.headers) callArgs.push("headers: http.Params(customHeaders)");
915
928
  const content = bodyArgument(op);
@@ -921,16 +934,16 @@ function generateMethod(route, op, ctx, methodName) {
921
934
  callArgs.forEach((arg, index) => {
922
935
  lines.push(` ${arg}${index === callArgs.length - 1 ? ").ConfigureAwait(false);" : ","}`);
923
936
  });
924
- lines.push(...returnStatements(shape, base, ctx, where(route, op)));
937
+ lines.push(...returnStatements(shape, op, base, ctx, where(route, op), bound));
925
938
  lines.push("}");
926
939
  return lines;
927
940
  }
928
- function returnTypeFor(shape, base, ctx) {
941
+ function returnTypeFor(shape, op, base, ctx) {
929
942
  if (shape.kind !== "simple") return `${base}Response`;
930
943
  const response = shape.response;
931
944
  const body = response?.bodies[0];
932
945
  const headers = response?.headers ?? [];
933
- if (!body) return headers.length > 0 ? `${base}Headers` : "void";
946
+ if (!body) return headers.length > 0 ? headersRecordName(op, base) : "void";
934
947
  const dataType = bodyCSharpType(body, ctx);
935
948
  return headers.length > 0 ? `${base}Result` : dataType;
936
949
  }
@@ -954,18 +967,18 @@ function bodyReadExpr(body, ctx) {
954
967
  return `http.ReadJson<${renderCSharpType(body.bodyType, ctx, false)}>(response)`;
955
968
  }
956
969
  }
957
- function returnStatements(shape, base, ctx, place) {
970
+ function returnStatements(shape, op, base, ctx, place, bound) {
958
971
  if (shape.kind === "simple") {
959
972
  const response = shape.response;
960
973
  const body = response?.bodies[0];
961
974
  const headers = response?.headers ?? [];
962
975
  if (headers.length === 0) return body ? [` return ${bodyReadExpr(body, ctx)};`] : [];
963
- const lines2 = readHeaderLines(headers, `${base}Headers`, ctx, place, " ");
976
+ const lines2 = readHeaderLines(headers, headersRecordName(op, base), ctx, place, " ", bound);
964
977
  return body ? [...lines2, ` return new ${base}Result(${bodyReadExpr(body, ctx)}, headers);`] : [...lines2, " return headers;"];
965
978
  }
966
979
  if (shape.kind === "multiMime") {
967
980
  const headers = shape.response.headers ?? [];
968
- const lines2 = headers.length > 0 ? readHeaderLines(headers, `${base}Headers`, ctx, place, " ") : [];
981
+ const lines2 = headers.length > 0 ? readHeaderLines(headers, headersRecordName(op, base), ctx, place, " ", bound) : [];
969
982
  lines2.push(...mimeSwitch(shape.response, base, void 0, ctx, " ", headers.length > 0));
970
983
  return lines2;
971
984
  }
@@ -974,21 +987,21 @@ function returnStatements(shape, base, ctx, place) {
974
987
  for (const response of rest) {
975
988
  lines.push(` case ${response.statusCode}:`);
976
989
  lines.push(" {");
977
- lines.push(...statusBranch(response, base, response.statusCode, ctx, place, " "));
990
+ lines.push(...statusBranch(response, op, base, response.statusCode, ctx, place, " ", bound));
978
991
  lines.push(" }");
979
992
  lines.push("");
980
993
  }
981
994
  lines.push(" default:");
982
995
  lines.push(" {");
983
- lines.push(...statusBranch(fallback, base, fallback.statusCode, ctx, place, " "));
996
+ lines.push(...statusBranch(fallback, op, base, fallback.statusCode, ctx, place, " ", bound));
984
997
  lines.push(" }");
985
998
  lines.push(" }");
986
999
  return lines;
987
1000
  }
988
- function statusBranch(response, base, statusCode, ctx, place, indent) {
1001
+ function statusBranch(response, op, base, statusCode, ctx, place, indent, bound) {
989
1002
  const lines = [];
990
1003
  const headers = response.headers ?? [];
991
- if (headers.length > 0) lines.push(...readHeaderLines(headers, headersRecordName(base, statusCode), ctx, place, indent));
1004
+ if (headers.length > 0) lines.push(...readHeaderLines(headers, headersRecordName(op, base, statusCode), ctx, place, indent, bound));
992
1005
  lines.push(...mimeSwitch(response, base, statusCode, ctx, indent, headers.length > 0));
993
1006
  return lines;
994
1007
  }
@@ -1029,8 +1042,12 @@ function bodyArgument(op) {
1029
1042
  return `content: http.JsonContent(body, ${mime})`;
1030
1043
  }
1031
1044
  }
1032
- function headersRecordName(base, statusCode) {
1033
- return statusCode === void 0 ? `${base}Headers` : `${base}${statusCode}Headers`;
1045
+ function headersRecordName(op, base, statusCode) {
1046
+ if (statusCode !== void 0) return `${base}${statusCode}Headers`;
1047
+ return declaresRequestHeadersRecord(op) ? `${base}ResponseHeaders` : `${base}Headers`;
1048
+ }
1049
+ function declaresRequestHeadersRecord(op) {
1050
+ return op.headers?.kind === "params" && op.headers.nodes.length > 0;
1034
1051
  }
1035
1052
  function leafRecordName(response, body, statusCode) {
1036
1053
  const statusPart = statusCode === void 0 ? "" : `Status${statusCode}`;
@@ -1056,12 +1073,12 @@ function responseDeclarations(route, op, ctx) {
1056
1073
  const response = shape.response;
1057
1074
  const headers = response?.headers ?? [];
1058
1075
  if (headers.length === 0) return lines;
1059
- headerRecord(headers, headersRecordName(base));
1076
+ headerRecord(headers, headersRecordName(op, base));
1060
1077
  const body = response?.bodies[0];
1061
1078
  if (body) {
1062
1079
  lines.push("");
1063
1080
  lines.push(...xmlDocLines(`The body of ${place}, with the response headers the contract declares.`, ""));
1064
- lines.push(`public sealed record ${base}Result(${bodyCSharpType(body, ctx)} Data, ${headersRecordName(base)} Headers);`);
1081
+ lines.push(`public sealed record ${base}Result(${bodyCSharpType(body, ctx)} Data, ${headersRecordName(op, base)} Headers);`);
1065
1082
  }
1066
1083
  return lines;
1067
1084
  }
@@ -1069,7 +1086,7 @@ function responseDeclarations(route, op, ctx) {
1069
1086
  const withStatus = shape.kind === "multiStatus";
1070
1087
  for (const response of responses) {
1071
1088
  const headers = response.headers ?? [];
1072
- if (headers.length > 0) headerRecord(headers, headersRecordName(base, withStatus ? response.statusCode : void 0));
1089
+ if (headers.length > 0) headerRecord(headers, headersRecordName(op, base, withStatus ? response.statusCode : void 0));
1073
1090
  }
1074
1091
  lines.push("");
1075
1092
  lines.push(
@@ -1091,7 +1108,7 @@ function responseDeclarations(route, op, ctx) {
1091
1108
  const name = leafRecordName(response, body, statusCode);
1092
1109
  const parameters = [];
1093
1110
  if (body) parameters.push(`${bodyCSharpType(body, ctx)} Data`);
1094
- if (headers.length > 0) parameters.push(`${headersRecordName(base, statusCode)} Headers`);
1111
+ if (headers.length > 0) parameters.push(`${headersRecordName(op, base, statusCode)} Headers`);
1095
1112
  lines.push("");
1096
1113
  lines.push(` public sealed record ${name}(${parameters.join(", ")}) : ${base}Response;`);
1097
1114
  }
@@ -1137,12 +1154,16 @@ function describeHeaderType(type) {
1137
1154
  if (type.kind === "ref") return `the contract '${type.name}'`;
1138
1155
  return `${type.kind === "array" || type.kind === "inlineObject" ? "an" : "a"} ${type.kind}`;
1139
1156
  }
1140
- function readHeaderLines(headers, typeName, ctx, place, indent) {
1157
+ function readHeaderLines(headers, typeName, ctx, place, indent, bound) {
1158
+ const locals = bindCSharpParameterNames(
1159
+ headers.filter((h) => h.optional).map((h) => h.name),
1160
+ bound
1161
+ );
1141
1162
  const args = headers.map((header) => {
1142
1163
  const reader = headerReader(header, place);
1143
1164
  const name = quoteCSharpString(header.name);
1144
1165
  if (!header.optional) return reader.read(`http.RequireHeader(response, ${name})`);
1145
- const local = toCSharpParameterName(header.name);
1166
+ const local = locals.get(header.name);
1146
1167
  return `response.Header(${name}) is { } ${local} ? ${reader.read(local)} : null`;
1147
1168
  });
1148
1169
  const lines = [`${indent}var headers = new ${typeName}(`];
@@ -1165,22 +1186,30 @@ function httpMethodConstant(method) {
1165
1186
  return lower.charAt(0).toUpperCase() + lower.slice(1);
1166
1187
  }
1167
1188
  var PATH_PLACEHOLDER = /\{([a-zA-Z_$][a-zA-Z0-9_$.-]*)\}/g;
1168
- function buildPathExpression(path, params) {
1189
+ function buildPathExpression(path, params, bindings) {
1169
1190
  const args = path.split("/").filter(Boolean).map((raw) => {
1170
1191
  PATH_PLACEHOLDER.lastIndex = 0;
1171
1192
  const match = PATH_PLACEHOLDER.exec(raw);
1172
1193
  if (!match || match[0] !== raw) return quoteCSharpString(raw);
1173
- const value = params && params.kind !== "params" ? `pathParams.${toCSharpPropertyName(match[1])}` : toCSharpParameterName(match[1]);
1194
+ const value = params && params.kind !== "params" ? `pathParams.${toCSharpPropertyName(match[1])}` : bindings?.get(match[1]) ?? toCSharpParameterName(match[1]);
1174
1195
  return `http.Segment(${value})`;
1175
1196
  });
1176
1197
  return `http.Path(${args.join(", ")})`;
1177
1198
  }
1178
- function buildMethodParams(route, op, ctx) {
1199
+ var METHOD_LOCALS = ["body", "query", "customHeaders", "pathParams", "cancellationToken", "response", "headers", "http"];
1200
+ function bindPathParams(route) {
1201
+ if (route.params?.kind !== "params") return /* @__PURE__ */ new Map();
1202
+ return bindCSharpParameterNames(
1203
+ route.params.nodes.map((n) => n.name),
1204
+ METHOD_LOCALS
1205
+ );
1206
+ }
1207
+ function buildMethodParams(route, op, ctx, pathBindings) {
1179
1208
  const params = [];
1180
1209
  if (route.params) {
1181
1210
  if (route.params.kind === "params") {
1182
1211
  for (const node of route.params.nodes) {
1183
- params.push({ name: toCSharpParameterName(node.name), type: renderCSharpType(node.type, ctx, true), optional: false });
1212
+ params.push({ name: pathBindings.get(node.name), type: renderCSharpType(node.type, ctx, true), optional: false });
1184
1213
  }
1185
1214
  } else {
1186
1215
  params.push({ name: "pathParams", type: renderParamSourceType(route.params, ctx, ""), optional: false });