@contractkit/plugin-csharp 0.1.1 → 0.1.3

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/index.js CHANGED
@@ -1,10 +1,16 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
1
  // src/index.ts
5
2
  import { dirname, join, resolve } from "path";
6
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, rmdirSync, writeFileSync } from "fs";
7
- import { buildModelIndex as buildModelIndex2, collectTransitiveModelRefs, collectTypeRefs as collectTypeRefs2, emptyIncrementalManifest, hashFingerprint, parseIncrementalManifest, runIncrementalCodegen, serializeIncrementalManifest } from "@contractkit/core";
4
+ import {
5
+ buildModelIndex as buildModelIndex2,
6
+ collectTransitiveModelRefs,
7
+ collectTypeRefs as collectTypeRefs2,
8
+ emptyIncrementalManifest,
9
+ hashFingerprint,
10
+ parseIncrementalManifest,
11
+ runIncrementalCodegen,
12
+ serializeIncrementalManifest
13
+ } from "@contractkit/core";
8
14
 
9
15
  // src/codegen-models.ts
10
16
  import { buildModelIndex, computeModelsWithInput, resolveEffectiveFields, topoSortModels } from "@contractkit/core";
@@ -89,18 +95,10 @@ var CSHARP_KEYWORDS = /* @__PURE__ */ new Set([
89
95
  "volatile",
90
96
  "while"
91
97
  ]);
92
- var RESERVED_MEMBER_NAMES = /* @__PURE__ */ new Set([
93
- "Equals",
94
- "GetHashCode",
95
- "GetType",
96
- "ToString",
97
- "EqualityContract",
98
- "PrintMembers"
99
- ]);
98
+ var RESERVED_MEMBER_NAMES = /* @__PURE__ */ new Set(["Equals", "GetHashCode", "GetType", "ToString", "EqualityContract", "PrintMembers"]);
100
99
  function escapeCSharpIdentifier(name) {
101
100
  return CSHARP_KEYWORDS.has(name) ? `@${name}` : name;
102
101
  }
103
- __name(escapeCSharpIdentifier, "escapeCSharpIdentifier");
104
102
  function toCSharpPropertyName(name) {
105
103
  const words = splitWords(name);
106
104
  if (words.length === 0) return "_";
@@ -108,7 +106,6 @@ function toCSharpPropertyName(name) {
108
106
  if (/^\d/.test(result)) result = `_${result}`;
109
107
  return result;
110
108
  }
111
- __name(toCSharpPropertyName, "toCSharpPropertyName");
112
109
  function toCSharpParameterName(name) {
113
110
  const words = splitWords(name);
114
111
  if (words.length === 0) return "_";
@@ -118,12 +115,10 @@ function toCSharpParameterName(name) {
118
115
  if (/^\d/.test(result)) result = `_${result}`;
119
116
  return escapeCSharpIdentifier(result);
120
117
  }
121
- __name(toCSharpParameterName, "toCSharpParameterName");
122
118
  function safeMemberName(propertyName, ownerTypeName) {
123
119
  if (propertyName === ownerTypeName || RESERVED_MEMBER_NAMES.has(propertyName)) return `${propertyName}Value`;
124
120
  return propertyName;
125
121
  }
126
- __name(safeMemberName, "safeMemberName");
127
122
  function toCSharpTypeName(name) {
128
123
  const words = splitWords(name);
129
124
  if (words.length === 0) return "_";
@@ -131,7 +126,6 @@ function toCSharpTypeName(name) {
131
126
  if (/^\d/.test(result)) result = `_${result}`;
132
127
  return result;
133
128
  }
134
- __name(toCSharpTypeName, "toCSharpTypeName");
135
129
  function sanitizeCSharpTypeName(name) {
136
130
  let result = name.replace(/[^a-zA-Z0-9]/g, "");
137
131
  if (result.length === 0) return "_";
@@ -139,7 +133,6 @@ function sanitizeCSharpTypeName(name) {
139
133
  if (/^\d/.test(result)) result = `_${result}`;
140
134
  return result;
141
135
  }
142
- __name(sanitizeCSharpTypeName, "sanitizeCSharpTypeName");
143
136
  function toCSharpEnumMemberName(value) {
144
137
  const words = splitWords(value);
145
138
  if (words.length === 0) return "_";
@@ -147,43 +140,30 @@ function toCSharpEnumMemberName(value) {
147
140
  if (/^\d/.test(result)) result = `_${result}`;
148
141
  return result;
149
142
  }
150
- __name(toCSharpEnumMemberName, "toCSharpEnumMemberName");
151
143
  function deriveCSharpFileBase(file) {
152
144
  const base = file.split("/").pop()?.replace(/\.(op\.)?ck$/, "") ?? "models";
153
145
  return toCSharpTypeName(base);
154
146
  }
155
- __name(deriveCSharpFileBase, "deriveCSharpFileBase");
156
147
  function xmlDocLines(text, indent, tag = "summary") {
157
148
  if (text.length === 0) return [];
158
149
  const safe = escapeXml(text);
159
150
  const sourceLines = safe.split("\n");
160
- if (sourceLines.length === 1) return [
161
- `${indent}/// <${tag}>${sourceLines[0]}</${tag}>`
162
- ];
163
- return [
164
- `${indent}/// <${tag}>`,
165
- ...sourceLines.map((line) => `${indent}/// ${line}`.trimEnd()),
166
- `${indent}/// </${tag}>`
167
- ];
151
+ if (sourceLines.length === 1) return [`${indent}/// <${tag}>${sourceLines[0]}</${tag}>`];
152
+ return [`${indent}/// <${tag}>`, ...sourceLines.map((line) => `${indent}/// ${line}`.trimEnd()), `${indent}/// </${tag}>`];
168
153
  }
169
- __name(xmlDocLines, "xmlDocLines");
170
154
  function escapeXml(text) {
171
155
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
172
156
  }
173
- __name(escapeXml, "escapeXml");
174
157
  function quoteCSharpString(value) {
175
158
  const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\0/g, "\\0");
176
159
  return `"${escaped}"`;
177
160
  }
178
- __name(quoteCSharpString, "quoteCSharpString");
179
161
  function splitWords(name) {
180
162
  return name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
181
163
  }
182
- __name(splitWords, "splitWords");
183
164
  function capitalize(word) {
184
165
  return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
185
166
  }
186
- __name(capitalize, "capitalize");
187
167
 
188
168
  // src/codegen-models.ts
189
169
  var MODEL_USINGS = [
@@ -205,27 +185,18 @@ function generateCSharpModels(root, opts) {
205
185
  warn: opts.warn
206
186
  };
207
187
  const bodies = [];
208
- const append = /* @__PURE__ */ __name((lines) => {
188
+ const append = (lines) => {
209
189
  if (lines.length === 0) return;
210
190
  bodies.push("", ...lines);
211
- }, "append");
191
+ };
212
192
  for (const model of topoSortModels(root.models)) append(generateModel(model, ctx));
213
193
  for (const decl of opts.hoisted?.byFile.get(root.file) ?? []) append(generateHoisted(decl, ctx));
214
- return renderFile(`${opts.namespace}.Models`, ctx.globalAliases, [
215
- ...MODEL_USINGS
216
- ], bodies);
194
+ return renderFile(`${opts.namespace}.Models`, ctx.globalAliases, [...MODEL_USINGS], bodies);
217
195
  }
218
- __name(generateCSharpModels, "generateCSharpModels");
219
196
  function resolveModelsWithInput(models, external = /* @__PURE__ */ new Set()) {
220
197
  const seed = new Set(external);
221
- return /* @__PURE__ */ new Set([
222
- ...seed,
223
- ...computeModelsWithInput([
224
- ...models
225
- ], seed)
226
- ]);
227
- }
228
- __name(resolveModelsWithInput, "resolveModelsWithInput");
198
+ return /* @__PURE__ */ new Set([...seed, ...computeModelsWithInput([...models], seed)]);
199
+ }
229
200
  function createRenderContext(opts) {
230
201
  return {
231
202
  namespace: opts.namespace,
@@ -236,18 +207,10 @@ function createRenderContext(opts) {
236
207
  warn: opts.warn
237
208
  };
238
209
  }
239
- __name(createRenderContext, "createRenderContext");
240
210
  function renderFile(namespaceName, globalAliases, usings, bodies) {
241
- const lines = [
242
- "// <auto-generated/>",
243
- "// Generated by @contractkit/plugin-csharp. Do not edit manually.",
244
- "#nullable enable",
245
- ""
246
- ];
211
+ const lines = ["// <auto-generated/>", "// Generated by @contractkit/plugin-csharp. Do not edit manually.", "#nullable enable", ""];
247
212
  if (globalAliases.length > 0) {
248
- lines.push(...[
249
- ...globalAliases
250
- ].sort());
213
+ lines.push(...[...globalAliases].sort());
251
214
  lines.push("");
252
215
  }
253
216
  lines.push(...usings);
@@ -257,7 +220,6 @@ function renderFile(namespaceName, globalAliases, usings, bodies) {
257
220
  lines.push("");
258
221
  return lines.join("\n");
259
222
  }
260
- __name(renderFile, "renderFile");
261
223
  function renderCSharpType(type, ctx, forInput = false) {
262
224
  const decl = ctx.hoisted?.byNode.get(type);
263
225
  if (decl) return hoistedTypeName(decl, ctx, forInput);
@@ -273,7 +235,9 @@ function renderCSharpType(type, ctx, forInput = false) {
273
235
  const value = renderCSharpType(type.value, ctx, forInput);
274
236
  const stringType = qualify("string", "System.String", ctx);
275
237
  if (key !== stringType) {
276
- ctx.warn?.(`A record key of type '${key}' is not representable as a JSON object key; emitting Dictionary<string, ${value}>. Parse the key yourself, or declare the key as a string.`);
238
+ ctx.warn?.(
239
+ `A record key of type '${key}' is not representable as a JSON object key; emitting Dictionary<string, ${value}>. Parse the key yourself, or declare the key as a string.`
240
+ );
277
241
  }
278
242
  return `${qualify("Dictionary", "System.Collections.Generic.Dictionary", ctx)}<${stringType}, ${value}>`;
279
243
  }
@@ -302,25 +266,20 @@ function renderCSharpType(type, ctx, forInput = false) {
302
266
  return jsonElement(ctx);
303
267
  }
304
268
  }
305
- __name(renderCSharpType, "renderCSharpType");
306
269
  function hoistedTypeName(decl, ctx, forInput) {
307
270
  const bare = forInput && decl.needsInput ? `${decl.name}Input` : decl.name;
308
271
  const name = ctx.qualify ? `${ctx.namespace}.Models.${bare}` : bare;
309
272
  return decl.nullable ? `${name}?` : name;
310
273
  }
311
- __name(hoistedTypeName, "hoistedTypeName");
312
274
  function qualify(short, full, ctx) {
313
275
  return ctx.qualify ? full : short;
314
276
  }
315
- __name(qualify, "qualify");
316
277
  function jsonElement(ctx) {
317
278
  return qualify("JsonElement", "System.Text.Json.JsonElement", ctx);
318
279
  }
319
- __name(jsonElement, "jsonElement");
320
280
  function isNullScalar(type) {
321
281
  return type.kind === "scalar" && type.name === "null";
322
282
  }
323
- __name(isNullScalar, "isNullScalar");
324
283
  function renderScalar(name, ctx) {
325
284
  switch (name) {
326
285
  case "string":
@@ -365,14 +324,13 @@ function renderScalar(name, ctx) {
365
324
  }
366
325
  }
367
326
  }
368
- __name(renderScalar, "renderScalar");
369
327
  function literalCSharpType(value, ctx) {
370
328
  if (typeof value === "string") return qualify("string", "System.String", ctx);
371
329
  if (typeof value === "boolean") return qualify("bool", "System.Boolean", ctx);
372
330
  return Number.isInteger(value) ? qualify("long", "System.Int64", ctx) : qualify("double", "System.Double", ctx);
373
331
  }
374
- __name(literalCSharpType, "literalCSharpType");
375
- function renderDefault(value, type, ctx) {
332
+ function renderDefault(value, type, ctx, memberNames = /* @__PURE__ */ new Set()) {
333
+ const enumType = (name) => memberNames.has(name) ? `global::${ctx.namespace}.Models.${name}` : name;
376
334
  const inner = type.kind === "lazy" ? type.inner : type;
377
335
  if (typeof value === "boolean") return String(value);
378
336
  if (typeof value === "number") {
@@ -393,13 +351,13 @@ function renderDefault(value, type, ctx) {
393
351
  if (inner.kind === "enum") {
394
352
  const decl = ctx.hoisted?.byNode.get(inner);
395
353
  if (!decl || !inner.values.includes(value)) return void 0;
396
- return `${decl.name}.${enumMemberNames(inner.values).get(value)}`;
354
+ return `${enumType(decl.name)}.${enumMemberNames(inner.values).get(value)}`;
397
355
  }
398
356
  if (inner.kind === "ref") {
399
357
  const target = ctx.modelIndex.get(inner.name);
400
358
  const targetType = target?.type?.kind === "lazy" ? target.type.inner : target?.type;
401
359
  if (targetType?.kind !== "enum" || !targetType.values.includes(value)) return void 0;
402
- return `${inner.name}.${enumMemberNames(targetType.values).get(value)}`;
360
+ return `${enumType(inner.name)}.${enumMemberNames(targetType.values).get(value)}`;
403
361
  }
404
362
  if (inner.kind === "scalar") {
405
363
  switch (inner.name) {
@@ -418,28 +376,26 @@ function renderDefault(value, type, ctx) {
418
376
  }
419
377
  return quoteCSharpString(value);
420
378
  }
421
- __name(renderDefault, "renderDefault");
422
379
  function applyWireCase(name, wireCase) {
423
380
  if (!wireCase || wireCase === "camel") return name;
424
381
  if (wireCase === "snake") return name.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
425
382
  return name.charAt(0).toUpperCase() + name.slice(1);
426
383
  }
427
- __name(applyWireCase, "applyWireCase");
428
384
  function renamingCase(wireCase) {
429
385
  return wireCase && wireCase !== "camel" ? wireCase : void 0;
430
386
  }
431
- __name(renamingCase, "renamingCase");
432
387
  function wireCaseFor(model, forInput, split, ctx) {
433
388
  const input = renamingCase(model.inputCase);
434
389
  const output = renamingCase(model.outputCase);
435
390
  if (split) return forInput ? input : output;
436
391
  if (input && output && input !== output) {
437
- ctx.warn?.(`Contract '${model.name}' sets format(input=${input}) and format(output=${output}), but nothing about it splits into an Input variant, so one C# record carries both directions and can only spell one set of keys. The generated keys follow the output casing; a request built from this record will send the wrong ones.`);
392
+ ctx.warn?.(
393
+ `Contract '${model.name}' sets format(input=${input}) and format(output=${output}), but nothing about it splits into an Input variant, so one C# record carries both directions and can only spell one set of keys. The generated keys follow the output casing; a request built from this record will send the wrong ones.`
394
+ );
438
395
  return output;
439
396
  }
440
397
  return output ?? input;
441
398
  }
442
- __name(wireCaseFor, "wireCaseFor");
443
399
  function containsInlineObject(type) {
444
400
  if (!type) return false;
445
401
  switch (type.kind) {
@@ -461,13 +417,13 @@ function containsInlineObject(type) {
461
417
  return false;
462
418
  }
463
419
  }
464
- __name(containsInlineObject, "containsInlineObject");
465
420
  function warnUncasedNesting(model, fields, wireCase, ctx) {
466
421
  if (!wireCase) return;
467
422
  if (!fields.some((f) => containsInlineObject(f.type)) && !containsInlineObject(model.type)) return;
468
- ctx.warn?.(`Contract '${model.name}' is declared format(${model.outputCase ? "output" : "input"}=${wireCase}) and holds an anonymous object. The record hoisted out of that object keeps its declared key names, so its keys will not be ${wireCase}-cased. Name the shape as its own contract to fix it.`);
423
+ ctx.warn?.(
424
+ `Contract '${model.name}' is declared format(${model.outputCase ? "output" : "input"}=${wireCase}) and holds an anonymous object. The record hoisted out of that object keeps its declared key names, so its keys will not be ${wireCase}-cased. Name the shape as its own contract to fix it.`
425
+ );
469
426
  }
470
- __name(warnUncasedNesting, "warnUncasedNesting");
471
427
  function generateModel(model, ctx) {
472
428
  if (model.type) return generateAliasModel(model, ctx);
473
429
  const effective = effectiveFieldsFor(model, ctx);
@@ -481,7 +437,6 @@ function generateModel(model, ctx) {
481
437
  ...generateRecordForModel(`${model.name}Input`, inputFields, ctx, true, model, true)
482
438
  ];
483
439
  }
484
- __name(generateModel, "generateModel");
485
440
  function effectiveFieldsFor(model, ctx) {
486
441
  if (!model.bases || model.bases.length === 0) return model.fields;
487
442
  const { fields, unresolved } = resolveEffectiveFields(model.name, ctx.modelIndex);
@@ -490,7 +445,6 @@ function effectiveFieldsFor(model, ctx) {
490
445
  }
491
446
  return fields;
492
447
  }
493
- __name(effectiveFieldsFor, "effectiveFieldsFor");
494
448
  function generateAliasModel(model, ctx) {
495
449
  const type = model.type;
496
450
  const inner = type.kind === "lazy" ? type.inner : type;
@@ -504,40 +458,47 @@ function generateAliasModel(model, ctx) {
504
458
  const needsSplit = ctx.modelsWithInput.has(model.name) || fields.some((f) => f.visibility !== "normal");
505
459
  if (!needsSplit) return generateRecordForModel(model.name, fields, ctx, false, model, false);
506
460
  return [
507
- ...generateRecordForModel(model.name, fields.filter((f) => f.visibility !== "writeonly"), ctx, false, model, true),
461
+ ...generateRecordForModel(
462
+ model.name,
463
+ fields.filter((f) => f.visibility !== "writeonly"),
464
+ ctx,
465
+ false,
466
+ model,
467
+ true
468
+ ),
508
469
  "",
509
- ...generateRecordForModel(`${model.name}Input`, fields.filter((f) => f.visibility !== "readonly"), ctx, true, model, true)
470
+ ...generateRecordForModel(
471
+ `${model.name}Input`,
472
+ fields.filter((f) => f.visibility !== "readonly"),
473
+ ctx,
474
+ true,
475
+ model,
476
+ true
477
+ )
510
478
  ];
511
479
  }
512
480
  addAlias(model.name, type, ctx, false);
513
481
  if (ctx.modelsWithInput.has(model.name)) addAlias(`${model.name}Input`, type, ctx, true);
514
482
  return [];
515
483
  }
516
- __name(generateAliasModel, "generateAliasModel");
517
484
  function addAlias(name, type, ctx, forInput) {
518
- const target = renderCSharpType(type, {
519
- ...ctx,
520
- qualify: true
521
- }, forInput);
485
+ const target = renderCSharpType(type, { ...ctx, qualify: true }, forInput);
522
486
  let aliased = target;
523
487
  if (aliased.endsWith("?") && !isNullableValueType(type, ctx)) {
524
488
  aliased = aliased.slice(0, -1);
525
- ctx.warn?.(`Contract '${name}' aliases a nullable type, which C# cannot express as a using alias; '${name}' is generated as '${aliased}'. Declare the nullability at each use site instead.`);
489
+ ctx.warn?.(
490
+ `Contract '${name}' aliases a nullable type, which C# cannot express as a using alias; '${name}' is generated as '${aliased}'. Declare the nullability at each use site instead.`
491
+ );
526
492
  }
527
493
  ctx.globalAliases.push(`global using ${name} = ${aliased};`);
528
494
  }
529
- __name(addAlias, "addAlias");
530
495
  function isNullableValueType(type, ctx) {
531
496
  const inner = type.kind === "lazy" ? type.inner : type;
532
497
  if (inner.kind !== "union") return false;
533
498
  const nonNull = inner.members.filter((m) => !isNullScalar(m));
534
499
  if (nonNull.length !== 1) return false;
535
- return VALUE_TYPES.has(renderCSharpType(nonNull[0], {
536
- ...ctx,
537
- qualify: false
538
- }, false));
500
+ return VALUE_TYPES.has(renderCSharpType(nonNull[0], { ...ctx, qualify: false }, false));
539
501
  }
540
- __name(isNullableValueType, "isNullableValueType");
541
502
  var VALUE_TYPES = /* @__PURE__ */ new Set([
542
503
  "bool",
543
504
  "byte",
@@ -558,7 +519,6 @@ function enumMemberNames(values) {
558
519
  for (const value of values) out.set(value, uniqueName(toCSharpEnumMemberName(value), used));
559
520
  return out;
560
521
  }
561
- __name(enumMemberNames, "enumMemberNames");
562
522
  function generateEnum(name, values, ctx, description, deprecated) {
563
523
  const entries = enumMemberNames(values);
564
524
  const lines = [];
@@ -575,7 +535,6 @@ function generateEnum(name, values, ctx, description, deprecated) {
575
535
  if (ctx.modelsWithInput.has(name)) ctx.globalAliases.push(`global using ${name}Input = ${ctx.namespace}.Models.${name};`);
576
536
  return lines;
577
537
  }
578
- __name(generateEnum, "generateEnum");
579
538
  function supertypesFor(readName, ctx, forInput) {
580
539
  const unions = ctx.hoisted?.memberships.get(readName) ?? [];
581
540
  return unions.map((union) => {
@@ -583,14 +542,12 @@ function supertypesFor(readName, ctx, forInput) {
583
542
  return forInput && decl?.needsInput ? `${union}Input` : union;
584
543
  });
585
544
  }
586
- __name(supertypesFor, "supertypesFor");
587
545
  function generateRecordForModel(name, fields, ctx, forInput, model, split) {
588
546
  const readName = forInput && name.endsWith("Input") ? name.slice(0, -"Input".length) : name;
589
547
  const wireCase = wireCaseFor(model, forInput, split, ctx);
590
548
  if (!forInput) warnUncasedNesting(model, fields, wireCase, ctx);
591
549
  return renderRecord(name, fields, ctx, forInput, supertypesFor(readName, ctx, forInput), model.description, model.deprecated, wireCase);
592
550
  }
593
- __name(generateRecordForModel, "generateRecordForModel");
594
551
  function renderRecord(name, fields, ctx, forInput, supertypes, description, deprecated, wireCase) {
595
552
  const lines = [];
596
553
  lines.push(...docLines(description, deprecated, ""));
@@ -599,25 +556,28 @@ function renderRecord(name, fields, ctx, forInput, supertypes, description, depr
599
556
  lines.push(`public sealed record ${name}${implementsClause};`);
600
557
  return lines;
601
558
  }
559
+ const memberNames = new Set(fields.map((field) => memberName(field, name)));
602
560
  lines.push(`public sealed record ${name}${implementsClause}`);
603
561
  lines.push("{");
604
562
  fields.forEach((field, index) => {
605
563
  if (index > 0) lines.push("");
606
- lines.push(...renderField(field, ctx, forInput, name, wireCase));
564
+ lines.push(...renderField(field, ctx, forInput, name, memberNames, wireCase));
607
565
  });
608
566
  lines.push("}");
609
567
  return lines;
610
568
  }
611
- __name(renderRecord, "renderRecord");
612
- function renderField(field, ctx, forInput, ownerTypeName, wireCase) {
613
- const propName = safeMemberName(toCSharpPropertyName(field.name), ownerTypeName);
569
+ function memberName(field, ownerTypeName) {
570
+ return safeMemberName(toCSharpPropertyName(field.name), ownerTypeName);
571
+ }
572
+ function renderField(field, ctx, forInput, ownerTypeName, memberNames, wireCase) {
573
+ const propName = memberName(field, ownerTypeName);
614
574
  const wireName = applyWireCase(field.name, wireCase);
615
575
  let typeStr = renderCSharpType(field.type, ctx, forInput);
616
576
  if ((field.optional || field.nullable) && !typeStr.endsWith("?")) typeStr += "?";
617
- let initializer = field.default !== void 0 ? renderDefault(field.default, field.type, ctx) : void 0;
577
+ let initializer = field.default !== void 0 ? renderDefault(field.default, field.type, ctx, memberNames) : void 0;
618
578
  if (initializer === void 0 && !field.optional && !field.nullable) {
619
579
  const inner = field.type.kind === "lazy" ? field.type.inner : field.type;
620
- if (inner.kind === "literal") initializer = renderDefault(inner.value, inner, ctx);
580
+ if (inner.kind === "literal") initializer = renderDefault(inner.value, inner, ctx, memberNames);
621
581
  }
622
582
  const isRequired = !field.optional && initializer === void 0;
623
583
  const lines = [];
@@ -628,24 +588,25 @@ function renderField(field, ctx, forInput, ownerTypeName, wireCase) {
628
588
  lines.push(` public ${isRequired ? "required " : ""}${typeStr} ${propName} { get; init; }${suffix}`);
629
589
  return lines;
630
590
  }
631
- __name(renderField, "renderField");
632
591
  function generateHoisted(decl, ctx) {
633
592
  const read = generateHoistedVariant(decl, ctx, false);
634
593
  if (!decl.needsInput) return read;
635
- return [
636
- ...read,
637
- "",
638
- ...generateHoistedVariant(decl, ctx, true)
639
- ];
594
+ return [...read, "", ...generateHoistedVariant(decl, ctx, true)];
640
595
  }
641
- __name(generateHoisted, "generateHoisted");
642
596
  function generateHoistedVariant(decl, ctx, forInput) {
643
597
  const name = forInput ? `${decl.name}Input` : decl.name;
644
598
  switch (decl.kind) {
645
599
  case "enum":
646
600
  return generateEnum(name, decl.values ?? [], ctx, decl.description);
647
601
  case "record":
648
- return renderRecord(name, (decl.fields ?? []).filter((f) => forInput ? f.visibility !== "readonly" : f.visibility !== "writeonly"), ctx, forInput, supertypesFor(decl.name, ctx, forInput), decl.description);
602
+ return renderRecord(
603
+ name,
604
+ (decl.fields ?? []).filter((f) => forInput ? f.visibility !== "readonly" : f.visibility !== "writeonly"),
605
+ ctx,
606
+ forInput,
607
+ supertypesFor(decl.name, ctx, forInput),
608
+ decl.description
609
+ );
649
610
  case "tuple":
650
611
  return generateTupleRecord(decl, name, ctx, forInput);
651
612
  case "plainUnion":
@@ -654,11 +615,9 @@ function generateHoistedVariant(decl, ctx, forInput) {
654
615
  return generateDiscriminatedUnion(decl, name, ctx, forInput);
655
616
  }
656
617
  }
657
- __name(generateHoistedVariant, "generateHoistedVariant");
658
618
  function deserializeExpr(type, ctx, forInput) {
659
619
  return `element.Deserialize<${renderCSharpType(type, ctx, forInput)}>(options)!`;
660
620
  }
661
- __name(deserializeExpr, "deserializeExpr");
662
621
  function generateTupleRecord(decl, name, ctx, forInput) {
663
622
  const items = decl.items ?? [];
664
623
  const converterName = `${name}Converter`;
@@ -697,7 +656,6 @@ function generateTupleRecord(decl, name, ctx, forInput) {
697
656
  lines.push("}");
698
657
  return lines;
699
658
  }
700
- __name(generateTupleRecord, "generateTupleRecord");
701
659
  function generatePlainUnion(decl, name, ctx, forInput) {
702
660
  const converterName = `${name}Converter`;
703
661
  const members = decl.members ?? [];
@@ -751,13 +709,9 @@ function generatePlainUnion(decl, name, ctx, forInput) {
751
709
  lines.push("}");
752
710
  return lines;
753
711
  }
754
- __name(generatePlainUnion, "generatePlainUnion");
755
712
  function generateDiscriminatedUnion(decl, name, ctx, forInput) {
756
713
  const converterName = `${name}Converter`;
757
- const members = (decl.members ?? []).map((member) => ({
758
- ...member,
759
- recordName: memberRecordName(member.typeName, ctx, forInput)
760
- }));
714
+ const members = (decl.members ?? []).map((member) => ({ ...member, recordName: memberRecordName(member.typeName, ctx, forInput) }));
761
715
  const discriminator = decl.discriminator ?? "";
762
716
  const lines = [];
763
717
  lines.push(...docLines(decl.description, void 0, ""));
@@ -773,7 +727,9 @@ function generateDiscriminatedUnion(decl, name, ctx, forInput) {
773
727
  lines.push(" {");
774
728
  lines.push(" using var document = JsonDocument.ParseValue(ref reader);");
775
729
  lines.push(" var element = document.RootElement;");
776
- lines.push(` var tag = element.TryGetProperty(${quoteCSharpString(discriminator)}, out var tagElement) && tagElement.ValueKind == JsonValueKind.String`);
730
+ lines.push(
731
+ ` var tag = element.TryGetProperty(${quoteCSharpString(discriminator)}, out var tagElement) && tagElement.ValueKind == JsonValueKind.String`
732
+ );
777
733
  lines.push(" ? tagElement.GetString()");
778
734
  lines.push(" : null;");
779
735
  lines.push("");
@@ -802,21 +758,18 @@ function generateDiscriminatedUnion(decl, name, ctx, forInput) {
802
758
  lines.push("}");
803
759
  return lines;
804
760
  }
805
- __name(generateDiscriminatedUnion, "generateDiscriminatedUnion");
806
761
  function memberRecordName(typeName, ctx, forInput) {
807
762
  if (!forInput) return typeName;
808
763
  const decl = ctx.hoisted?.byName.get(typeName);
809
764
  if (decl) return decl.needsInput ? `${typeName}Input` : typeName;
810
765
  return ctx.modelsWithInput.has(typeName) ? `${typeName}Input` : typeName;
811
766
  }
812
- __name(memberRecordName, "memberRecordName");
813
767
  function docLines(description, deprecated, indent) {
814
768
  const lines = [];
815
769
  if (description) lines.push(...xmlDocLines(description, indent));
816
770
  if (deprecated) lines.push(...xmlDocLines("Deprecated in the contract.", indent, "remarks"));
817
771
  return lines;
818
772
  }
819
- __name(docLines, "docLines");
820
773
  function uniqueName(name, used) {
821
774
  if (!used.has(name)) {
822
775
  used.add(name);
@@ -827,7 +780,6 @@ function uniqueName(name, used) {
827
780
  used.add(`${name}${n}`);
828
781
  return `${name}${n}`;
829
782
  }
830
- __name(uniqueName, "uniqueName");
831
783
 
832
784
  // src/codegen-client.ts
833
785
  import { classifyContentType, observableResponses, resolveModifiers } from "@contractkit/core";
@@ -847,7 +799,6 @@ function clientUsings(namespaceName) {
847
799
  `using ${namespaceName}.Runtime;`
848
800
  ];
849
801
  }
850
- __name(clientUsings, "clientUsings");
851
802
  function hasPublicOperations(root, includeInternal = false) {
852
803
  for (const route of root.routes) {
853
804
  for (const op of route.operations) {
@@ -856,15 +807,12 @@ function hasPublicOperations(root, includeInternal = false) {
856
807
  }
857
808
  return false;
858
809
  }
859
- __name(hasPublicOperations, "hasPublicOperations");
860
810
  function deriveClientClassName(file) {
861
811
  return `${deriveCSharpFileBase(file)}Client`;
862
812
  }
863
- __name(deriveClientClassName, "deriveClientClassName");
864
813
  function deriveClientPropertyName(file) {
865
814
  return deriveCSharpFileBase(file);
866
815
  }
867
- __name(deriveClientPropertyName, "deriveClientPropertyName");
868
816
  function generateCSharpClient(root, opts) {
869
817
  const className = deriveClientClassName(root.file);
870
818
  const includeInternal = opts.includeInternal ?? false;
@@ -873,29 +821,22 @@ function generateCSharpClient(root, opts) {
873
821
  for (const route of root.routes) {
874
822
  for (const op of route.operations) {
875
823
  if (!includeInternal && resolveModifiers(route, op).includes("internal")) continue;
876
- publicOps.push({
877
- route,
878
- op
879
- });
824
+ publicOps.push({ route, op });
880
825
  }
881
826
  }
882
827
  const shapeLines = [];
883
828
  for (const { route, op } of publicOps) {
884
829
  const base = methodBase(deriveMethodName(op, route));
885
830
  for (const { source, suffix } of [
886
- {
887
- source: op.query,
888
- suffix: "Query"
889
- },
890
- {
891
- source: op.headers,
892
- suffix: "Headers"
893
- }
831
+ { source: op.query, suffix: "Query" },
832
+ { source: op.headers, suffix: "Headers" }
894
833
  ]) {
895
834
  if (source?.kind !== "params" || source.nodes.length === 0) continue;
896
835
  const shapeName = `${base}${suffix}`;
897
836
  shapeLines.push("");
898
- shapeLines.push(...xmlDocLines(`The ${suffix === "Query" ? "query parameters" : "request headers"} declared on ${where(route, op)}.`, ""));
837
+ shapeLines.push(
838
+ ...xmlDocLines(`The ${suffix === "Query" ? "query parameters" : "request headers"} declared on ${where(route, op)}.`, "")
839
+ );
899
840
  shapeLines.push(`public sealed record ${shapeName}`);
900
841
  shapeLines.push("{");
901
842
  source.nodes.forEach((node, index) => {
@@ -918,7 +859,9 @@ function generateCSharpClient(root, opts) {
918
859
  const methodName = deriveMethodName(op, route);
919
860
  const clash = seen.get(methodName);
920
861
  if (clash) {
921
- throw new Error(`plugin-csharp: ${where(route, op)} and ${clash} both generate the client method '${methodName}' on ${className}. Give one of them a distinct 'sdk:' name.`);
862
+ throw new Error(
863
+ `plugin-csharp: ${where(route, op)} and ${clash} both generate the client method '${methodName}' on ${className}. Give one of them a distinct 'sdk:' name.`
864
+ );
922
865
  }
923
866
  seen.set(methodName, where(route, op));
924
867
  methodLines.push("");
@@ -934,39 +877,23 @@ function generateCSharpClient(root, opts) {
934
877
  body.push(...shapeLines);
935
878
  return renderFile(`${opts.namespace}.Clients`, ctx.globalAliases, clientUsings(opts.namespace), body);
936
879
  }
937
- __name(generateCSharpClient, "generateCSharpClient");
938
880
  function where(route, op) {
939
881
  return `${op.method.toUpperCase()} ${route.path}`;
940
882
  }
941
- __name(where, "where");
942
883
  function methodBase(methodName) {
943
884
  return methodName.endsWith("Async") ? methodName.slice(0, -"Async".length) : methodName;
944
885
  }
945
- __name(methodBase, "methodBase");
946
886
  function responseShape(op) {
947
887
  const observable = observableResponses(op);
948
- if (observable.length > 1) return {
949
- kind: "multiStatus",
950
- responses: observable
951
- };
888
+ if (observable.length > 1) return { kind: "multiStatus", responses: observable };
952
889
  const response = observable[0];
953
- if (response && response.bodies.length > 1) return {
954
- kind: "multiMime",
955
- response
956
- };
957
- return {
958
- kind: "simple",
959
- response
960
- };
890
+ if (response && response.bodies.length > 1) return { kind: "multiMime", response };
891
+ return { kind: "simple", response };
961
892
  }
962
- __name(responseShape, "responseShape");
963
893
  function observableOf(shape) {
964
894
  if (shape.kind === "multiStatus") return shape.responses;
965
- return shape.response ? [
966
- shape.response
967
- ] : [];
895
+ return shape.response ? [shape.response] : [];
968
896
  }
969
- __name(observableOf, "observableOf");
970
897
  function generateMethod(route, op, ctx, methodName) {
971
898
  const base = methodBase(methodName);
972
899
  const shape = responseShape(op);
@@ -974,19 +901,15 @@ function generateMethod(route, op, ctx, methodName) {
974
901
  const observable = observableOf(shape);
975
902
  const expectStatuses = observable.filter((r) => r.statusCode < 200 || r.statusCode >= 300).map((r) => r.statusCode);
976
903
  const params = buildMethodParams(route, op, ctx);
977
- const signature = [
978
- ...params.map((p) => `${p.type} ${p.name}${p.optional ? " = null" : ""}`),
979
- "CancellationToken cancellationToken = default"
980
- ].join(", ");
904
+ const signature = [...params.map((p) => `${p.type} ${p.name}${p.optional ? " = null" : ""}`), "CancellationToken cancellationToken = default"].join(
905
+ ", "
906
+ );
981
907
  const lines = [];
982
908
  lines.push(...methodDoc(route, op, observable));
983
909
  if (resolveModifiers(route, op).includes("deprecated")) lines.push('[Obsolete("Deprecated in the contract")]');
984
910
  lines.push(`public async ${returnType === "void" ? "Task" : `Task<${returnType}>`} ${methodName}(${signature})`);
985
911
  lines.push("{");
986
- const callArgs = [
987
- `HttpMethod.${httpMethodConstant(op.method)}`,
988
- buildPathExpression(route.path, route.params)
989
- ];
912
+ const callArgs = [`HttpMethod.${httpMethodConstant(op.method)}`, buildPathExpression(route.path, route.params)];
990
913
  if (op.query) callArgs.push("query: http.Params(query)");
991
914
  if (op.headers) callArgs.push("headers: http.Params(customHeaders)");
992
915
  const content = bodyArgument(op);
@@ -1002,7 +925,6 @@ function generateMethod(route, op, ctx, methodName) {
1002
925
  lines.push("}");
1003
926
  return lines;
1004
927
  }
1005
- __name(generateMethod, "generateMethod");
1006
928
  function returnTypeFor(shape, base, ctx) {
1007
929
  if (shape.kind !== "simple") return `${base}Response`;
1008
930
  const response = shape.response;
@@ -1012,7 +934,6 @@ function returnTypeFor(shape, base, ctx) {
1012
934
  const dataType = bodyCSharpType(body, ctx);
1013
935
  return headers.length > 0 ? `${base}Result` : dataType;
1014
936
  }
1015
- __name(returnTypeFor, "returnTypeFor");
1016
937
  function bodyCSharpType(body, ctx) {
1017
938
  switch (classifyContentType(body.contentType)) {
1018
939
  case "text":
@@ -1023,7 +944,6 @@ function bodyCSharpType(body, ctx) {
1023
944
  return renderCSharpType(body.bodyType, ctx, false);
1024
945
  }
1025
946
  }
1026
- __name(bodyCSharpType, "bodyCSharpType");
1027
947
  function bodyReadExpr(body, ctx) {
1028
948
  switch (classifyContentType(body.contentType)) {
1029
949
  case "text":
@@ -1034,23 +954,14 @@ function bodyReadExpr(body, ctx) {
1034
954
  return `http.ReadJson<${renderCSharpType(body.bodyType, ctx, false)}>(response)`;
1035
955
  }
1036
956
  }
1037
- __name(bodyReadExpr, "bodyReadExpr");
1038
957
  function returnStatements(shape, base, ctx, place) {
1039
958
  if (shape.kind === "simple") {
1040
959
  const response = shape.response;
1041
960
  const body = response?.bodies[0];
1042
961
  const headers = response?.headers ?? [];
1043
- if (headers.length === 0) return body ? [
1044
- ` return ${bodyReadExpr(body, ctx)};`
1045
- ] : [];
962
+ if (headers.length === 0) return body ? [` return ${bodyReadExpr(body, ctx)};`] : [];
1046
963
  const lines2 = readHeaderLines(headers, `${base}Headers`, ctx, place, " ");
1047
- return body ? [
1048
- ...lines2,
1049
- ` return new ${base}Result(${bodyReadExpr(body, ctx)}, headers);`
1050
- ] : [
1051
- ...lines2,
1052
- " return headers;"
1053
- ];
964
+ return body ? [...lines2, ` return new ${base}Result(${bodyReadExpr(body, ctx)}, headers);`] : [...lines2, " return headers;"];
1054
965
  }
1055
966
  if (shape.kind === "multiMime") {
1056
967
  const headers = shape.response.headers ?? [];
@@ -1059,10 +970,7 @@ function returnStatements(shape, base, ctx, place) {
1059
970
  return lines2;
1060
971
  }
1061
972
  const [fallback, ...rest] = shape.responses;
1062
- const lines = [
1063
- " switch (response.Status)",
1064
- " {"
1065
- ];
973
+ const lines = [" switch (response.Status)", " {"];
1066
974
  for (const response of rest) {
1067
975
  lines.push(` case ${response.statusCode}:`);
1068
976
  lines.push(" {");
@@ -1077,7 +985,6 @@ function returnStatements(shape, base, ctx, place) {
1077
985
  lines.push(" }");
1078
986
  return lines;
1079
987
  }
1080
- __name(returnStatements, "returnStatements");
1081
988
  function statusBranch(response, base, statusCode, ctx, place, indent) {
1082
989
  const lines = [];
1083
990
  const headers = response.headers ?? [];
@@ -1085,23 +992,17 @@ function statusBranch(response, base, statusCode, ctx, place, indent) {
1085
992
  lines.push(...mimeSwitch(response, base, statusCode, ctx, indent, headers.length > 0));
1086
993
  return lines;
1087
994
  }
1088
- __name(statusBranch, "statusBranch");
1089
995
  function mimeSwitch(response, base, statusCode, ctx, indent, hasHeaders) {
1090
996
  const bodies = response.bodies;
1091
- const construct = /* @__PURE__ */ __name((body) => {
997
+ const construct = (body) => {
1092
998
  const args = [];
1093
999
  if (body) args.push(bodyReadExpr(body, ctx));
1094
1000
  if (hasHeaders) args.push("headers");
1095
1001
  return `new ${base}Response.${leafRecordName(response, body, statusCode)}(${args.join(", ")})`;
1096
- }, "construct");
1097
- if (bodies.length <= 1) return [
1098
- `${indent}return ${construct(bodies[0])};`
1099
- ];
1002
+ };
1003
+ if (bodies.length <= 1) return [`${indent}return ${construct(bodies[0])};`];
1100
1004
  const [fallback, ...rest] = bodies;
1101
- const lines = [
1102
- `${indent}switch (response.ContentType)`,
1103
- `${indent}{`
1104
- ];
1005
+ const lines = [`${indent}switch (response.ContentType)`, `${indent}{`];
1105
1006
  for (const body of rest) {
1106
1007
  lines.push(`${indent} case ${quoteCSharpString(body.contentType)}:`);
1107
1008
  lines.push(`${indent} return ${construct(body)};`);
@@ -1111,7 +1012,6 @@ function mimeSwitch(response, base, statusCode, ctx, indent, hasHeaders) {
1111
1012
  lines.push(`${indent}}`);
1112
1013
  return lines;
1113
1014
  }
1114
- __name(mimeSwitch, "mimeSwitch");
1115
1015
  function bodyArgument(op) {
1116
1016
  const body = op.request?.bodies[0];
1117
1017
  if (!body) return void 0;
@@ -1129,23 +1029,20 @@ function bodyArgument(op) {
1129
1029
  return `content: http.JsonContent(body, ${mime})`;
1130
1030
  }
1131
1031
  }
1132
- __name(bodyArgument, "bodyArgument");
1133
1032
  function headersRecordName(base, statusCode) {
1134
1033
  return statusCode === void 0 ? `${base}Headers` : `${base}${statusCode}Headers`;
1135
1034
  }
1136
- __name(headersRecordName, "headersRecordName");
1137
1035
  function leafRecordName(response, body, statusCode) {
1138
1036
  const statusPart = statusCode === void 0 ? "" : `Status${statusCode}`;
1139
1037
  if (response.bodies.length <= 1 || !body) return statusPart || "Body";
1140
1038
  return `${statusPart}${toCSharpTypeName(body.contentType.replace(/[+/.]/g, " "))}`;
1141
1039
  }
1142
- __name(leafRecordName, "leafRecordName");
1143
1040
  function responseDeclarations(route, op, ctx) {
1144
1041
  const shape = responseShape(op);
1145
1042
  const base = methodBase(deriveMethodName(op, route));
1146
1043
  const place = where(route, op);
1147
1044
  const lines = [];
1148
- const headerRecord = /* @__PURE__ */ __name((headers, name) => {
1045
+ const headerRecord = (headers, name) => {
1149
1046
  const parameters = headers.map((header) => {
1150
1047
  const reader = headerReader(header, place);
1151
1048
  const type = header.optional ? `${reader.type}?` : reader.type;
@@ -1154,7 +1051,7 @@ function responseDeclarations(route, op, ctx) {
1154
1051
  lines.push("");
1155
1052
  lines.push(...xmlDocLines(`Response headers declared on ${place}.`, ""));
1156
1053
  lines.push(`public sealed record ${name}(${parameters});`);
1157
- }, "headerRecord");
1054
+ };
1158
1055
  if (shape.kind === "simple") {
1159
1056
  const response = shape.response;
1160
1057
  const headers = response?.headers ?? [];
@@ -1175,18 +1072,21 @@ function responseDeclarations(route, op, ctx) {
1175
1072
  if (headers.length > 0) headerRecord(headers, headersRecordName(base, withStatus ? response.statusCode : void 0));
1176
1073
  }
1177
1074
  lines.push("");
1178
- lines.push(...xmlDocLines(`What ${place} returned.
1179
-
1180
- ` + (withStatus ? "The operation declares several statuses the service produces, so the status is part of the value." : "The status declares several content types, so which one arrived is part of the value."), ""));
1075
+ lines.push(
1076
+ ...xmlDocLines(
1077
+ `What ${place} returned.
1078
+
1079
+ ` + (withStatus ? "The operation declares several statuses the service produces, so the status is part of the value." : "The status declares several content types, so which one arrived is part of the value."),
1080
+ ""
1081
+ )
1082
+ );
1181
1083
  lines.push(`public abstract record ${base}Response`);
1182
1084
  lines.push("{");
1183
1085
  lines.push(` private ${base}Response() { }`);
1184
1086
  for (const response of responses) {
1185
1087
  const statusCode = withStatus ? response.statusCode : void 0;
1186
1088
  const headers = response.headers ?? [];
1187
- const bodies = response.bodies.length > 0 ? response.bodies : [
1188
- void 0
1189
- ];
1089
+ const bodies = response.bodies.length > 0 ? response.bodies : [void 0];
1190
1090
  for (const body of bodies) {
1191
1091
  const name = leafRecordName(response, body, statusCode);
1192
1092
  const parameters = [];
@@ -1199,7 +1099,6 @@ function responseDeclarations(route, op, ctx) {
1199
1099
  lines.push("}");
1200
1100
  return lines;
1201
1101
  }
1202
- __name(responseDeclarations, "responseDeclarations");
1203
1102
  function headerReader(header, place) {
1204
1103
  const scalar = header.type.kind === "scalar" ? header.type.name : void 0;
1205
1104
  switch (scalar) {
@@ -1208,66 +1107,36 @@ function headerReader(header, place) {
1208
1107
  case "url":
1209
1108
  case "interval":
1210
1109
  case "unknown":
1211
- return {
1212
- type: "string",
1213
- read: /* @__PURE__ */ __name((raw) => raw, "read")
1214
- };
1110
+ return { type: "string", read: (raw) => raw };
1215
1111
  case "number":
1216
- return {
1217
- type: "double",
1218
- read: /* @__PURE__ */ __name((raw) => `double.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1219
- };
1112
+ return { type: "double", read: (raw) => `double.Parse(${raw}, CultureInfo.InvariantCulture)` };
1220
1113
  case "int":
1221
- return {
1222
- type: "long",
1223
- read: /* @__PURE__ */ __name((raw) => `long.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1224
- };
1114
+ return { type: "long", read: (raw) => `long.Parse(${raw}, CultureInfo.InvariantCulture)` };
1225
1115
  case "bigint":
1226
- return {
1227
- type: "BigInteger",
1228
- read: /* @__PURE__ */ __name((raw) => `BigInteger.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1229
- };
1116
+ return { type: "BigInteger", read: (raw) => `BigInteger.Parse(${raw}, CultureInfo.InvariantCulture)` };
1230
1117
  case "boolean":
1231
- return {
1232
- type: "bool",
1233
- read: /* @__PURE__ */ __name((raw) => `${raw} == "true"`, "read")
1234
- };
1118
+ return { type: "bool", read: (raw) => `${raw} == "true"` };
1235
1119
  case "uuid":
1236
- return {
1237
- type: "Guid",
1238
- read: /* @__PURE__ */ __name((raw) => `Guid.Parse(${raw})`, "read")
1239
- };
1120
+ return { type: "Guid", read: (raw) => `Guid.Parse(${raw})` };
1240
1121
  case "date":
1241
- return {
1242
- type: "DateOnly",
1243
- read: /* @__PURE__ */ __name((raw) => `DateOnly.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1244
- };
1122
+ return { type: "DateOnly", read: (raw) => `DateOnly.Parse(${raw}, CultureInfo.InvariantCulture)` };
1245
1123
  case "time":
1246
- return {
1247
- type: "TimeOnly",
1248
- read: /* @__PURE__ */ __name((raw) => `TimeOnly.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1249
- };
1124
+ return { type: "TimeOnly", read: (raw) => `TimeOnly.Parse(${raw}, CultureInfo.InvariantCulture)` };
1250
1125
  case "datetime":
1251
- return {
1252
- type: "DateTimeOffset",
1253
- read: /* @__PURE__ */ __name((raw) => `DateTimeOffset.Parse(${raw}, CultureInfo.InvariantCulture)`, "read")
1254
- };
1126
+ return { type: "DateTimeOffset", read: (raw) => `DateTimeOffset.Parse(${raw}, CultureInfo.InvariantCulture)` };
1255
1127
  case "duration":
1256
- return {
1257
- type: "TimeSpan",
1258
- read: /* @__PURE__ */ __name((raw) => `XmlConvert.ToTimeSpan(${raw})`, "read")
1259
- };
1128
+ return { type: "TimeSpan", read: (raw) => `XmlConvert.ToTimeSpan(${raw})` };
1260
1129
  default:
1261
- throw new Error(`plugin-csharp: response header '${header.name}' on ${place} is declared as ${describeHeaderType(header.type)}, which cannot be read from an HTTP header. Header values arrive as strings \u2014 declare it as string, email, url, uuid, date, time, datetime, duration, interval, int, number, boolean or bigint.`);
1130
+ throw new Error(
1131
+ `plugin-csharp: response header '${header.name}' on ${place} is declared as ${describeHeaderType(header.type)}, which cannot be read from an HTTP header. Header values arrive as strings \u2014 declare it as string, email, url, uuid, date, time, datetime, duration, interval, int, number, boolean or bigint.`
1132
+ );
1262
1133
  }
1263
1134
  }
1264
- __name(headerReader, "headerReader");
1265
1135
  function describeHeaderType(type) {
1266
1136
  if (type.kind === "scalar") return `the '${type.name}' scalar`;
1267
1137
  if (type.kind === "ref") return `the contract '${type.name}'`;
1268
1138
  return `${type.kind === "array" || type.kind === "inlineObject" ? "an" : "a"} ${type.kind}`;
1269
1139
  }
1270
- __name(describeHeaderType, "describeHeaderType");
1271
1140
  function readHeaderLines(headers, typeName, ctx, place, indent) {
1272
1141
  const args = headers.map((header) => {
1273
1142
  const reader = headerReader(header, place);
@@ -1276,13 +1145,10 @@ function readHeaderLines(headers, typeName, ctx, place, indent) {
1276
1145
  const local = toCSharpParameterName(header.name);
1277
1146
  return `response.Header(${name}) is { } ${local} ? ${reader.read(local)} : null`;
1278
1147
  });
1279
- const lines = [
1280
- `${indent}var headers = new ${typeName}(`
1281
- ];
1148
+ const lines = [`${indent}var headers = new ${typeName}(`];
1282
1149
  args.forEach((arg, index) => lines.push(`${indent} ${arg}${index === args.length - 1 ? ");" : ","}`));
1283
1150
  return lines;
1284
1151
  }
1285
- __name(readHeaderLines, "readHeaderLines");
1286
1152
  function methodDoc(route, op, observable) {
1287
1153
  const lines = [];
1288
1154
  const parts = [];
@@ -1294,12 +1160,10 @@ function methodDoc(route, op, observable) {
1294
1160
  if (thrown.length > 0) lines.push(`/// <exception cref="SdkException">On ${thrown.join(", ")}.</exception>`);
1295
1161
  return lines;
1296
1162
  }
1297
- __name(methodDoc, "methodDoc");
1298
1163
  function httpMethodConstant(method) {
1299
1164
  const lower = method.toLowerCase();
1300
1165
  return lower.charAt(0).toUpperCase() + lower.slice(1);
1301
1166
  }
1302
- __name(httpMethodConstant, "httpMethodConstant");
1303
1167
  var PATH_PLACEHOLDER = /\{([a-zA-Z_$][a-zA-Z0-9_$.-]*)\}/g;
1304
1168
  function buildPathExpression(path, params) {
1305
1169
  const args = path.split("/").filter(Boolean).map((raw) => {
@@ -1311,65 +1175,36 @@ function buildPathExpression(path, params) {
1311
1175
  });
1312
1176
  return `http.Path(${args.join(", ")})`;
1313
1177
  }
1314
- __name(buildPathExpression, "buildPathExpression");
1315
1178
  function buildMethodParams(route, op, ctx) {
1316
1179
  const params = [];
1317
1180
  if (route.params) {
1318
1181
  if (route.params.kind === "params") {
1319
1182
  for (const node of route.params.nodes) {
1320
- params.push({
1321
- name: toCSharpParameterName(node.name),
1322
- type: renderCSharpType(node.type, ctx, true),
1323
- optional: false
1324
- });
1183
+ params.push({ name: toCSharpParameterName(node.name), type: renderCSharpType(node.type, ctx, true), optional: false });
1325
1184
  }
1326
1185
  } else {
1327
- params.push({
1328
- name: "pathParams",
1329
- type: renderParamSourceType(route.params, ctx, ""),
1330
- optional: false
1331
- });
1186
+ params.push({ name: "pathParams", type: renderParamSourceType(route.params, ctx, ""), optional: false });
1332
1187
  }
1333
1188
  }
1334
1189
  const body = op.request?.bodies[0];
1335
1190
  if (body) {
1336
1191
  switch (classifyContentType(body.contentType)) {
1337
1192
  case "multipart":
1338
- params.push({
1339
- name: "body",
1340
- type: "IEnumerable<SdkPart>",
1341
- optional: false
1342
- });
1193
+ params.push({ name: "body", type: "IEnumerable<SdkPart>", optional: false });
1343
1194
  break;
1344
1195
  case "binary":
1345
- params.push({
1346
- name: "body",
1347
- type: "byte[]",
1348
- optional: false
1349
- });
1196
+ params.push({ name: "body", type: "byte[]", optional: false });
1350
1197
  break;
1351
1198
  case "text":
1352
- params.push({
1353
- name: "body",
1354
- type: "string",
1355
- optional: false
1356
- });
1199
+ params.push({ name: "body", type: "string", optional: false });
1357
1200
  break;
1358
1201
  default:
1359
- params.push({
1360
- name: "body",
1361
- type: renderCSharpType(body.bodyType, ctx, true),
1362
- optional: false
1363
- });
1202
+ params.push({ name: "body", type: renderCSharpType(body.bodyType, ctx, true), optional: false });
1364
1203
  }
1365
1204
  }
1366
1205
  const base = methodBase(deriveMethodName(op, route));
1367
1206
  if (op.query) {
1368
- params.push({
1369
- name: "query",
1370
- type: renderParamSourceType(op.query, ctx, `${base}Query`),
1371
- optional: allFieldsOptional(op.query)
1372
- });
1207
+ params.push({ name: "query", type: renderParamSourceType(op.query, ctx, `${base}Query`), optional: allFieldsOptional(op.query) });
1373
1208
  }
1374
1209
  if (op.headers) {
1375
1210
  params.push({
@@ -1378,63 +1213,47 @@ function buildMethodParams(route, op, ctx) {
1378
1213
  optional: allFieldsOptional(op.headers)
1379
1214
  });
1380
1215
  }
1381
- const widened = params.map((p) => p.optional && !p.type.endsWith("?") ? {
1382
- ...p,
1383
- type: `${p.type}?`
1384
- } : p);
1385
- return [
1386
- ...widened.filter((p) => !p.optional),
1387
- ...widened.filter((p) => p.optional)
1388
- ];
1216
+ const widened = params.map((p) => p.optional && !p.type.endsWith("?") ? { ...p, type: `${p.type}?` } : p);
1217
+ return [...widened.filter((p) => !p.optional), ...widened.filter((p) => p.optional)];
1389
1218
  }
1390
- __name(buildMethodParams, "buildMethodParams");
1391
1219
  function allFieldsOptional(source) {
1392
1220
  if (source.kind !== "params") return true;
1393
1221
  return source.nodes.every((node) => Boolean(node.optional) || node.default !== void 0);
1394
1222
  }
1395
- __name(allFieldsOptional, "allFieldsOptional");
1396
1223
  function renderParamSourceType(source, ctx, generatedName) {
1397
- if (source.kind === "ref") return renderCSharpType({
1398
- kind: "ref",
1399
- name: source.name
1400
- }, ctx, true);
1224
+ if (source.kind === "ref") return renderCSharpType({ kind: "ref", name: source.name }, ctx, true);
1401
1225
  if (source.kind === "type") return renderCSharpType(source.node, ctx, true);
1402
1226
  return source.nodes.length > 0 ? generatedName : "IReadOnlyDictionary<string, string>";
1403
1227
  }
1404
- __name(renderParamSourceType, "renderParamSourceType");
1405
1228
  function deriveMethodName(op, route) {
1406
1229
  if (op.sdk) return `${toCSharpTypeName(op.sdk)}Async`;
1407
1230
  if (op.name) return `${toCSharpTypeName(op.name)}Async`;
1408
1231
  return `${inferMethodName(op.method, route.path)}Async`;
1409
1232
  }
1410
- __name(deriveMethodName, "deriveMethodName");
1411
1233
  function inferMethodName(method, path) {
1412
- const parts = [
1413
- toCSharpTypeName(method)
1414
- ];
1234
+ const parts = [toCSharpTypeName(method)];
1415
1235
  for (const segment of path.split("/").filter(Boolean)) {
1416
1236
  if (segment.startsWith("{")) parts.push(`By${toCSharpTypeName(segment.slice(1, -1))}`);
1417
1237
  else parts.push(toCSharpTypeName(segment));
1418
1238
  }
1419
1239
  return parts.join("");
1420
1240
  }
1421
- __name(inferMethodName, "inferMethodName");
1422
1241
 
1423
1242
  // src/codegen-sdk.ts
1424
1243
  function generateSdkCs(namespaceName, sdkName, clients) {
1425
- const lines = [
1426
- "// <auto-generated/>",
1427
- "// Generated by @contractkit/plugin-csharp. Do not edit manually.",
1428
- "#nullable enable",
1429
- ""
1430
- ];
1244
+ const lines = ["// <auto-generated/>", "// Generated by @contractkit/plugin-csharp. Do not edit manually.", "#nullable enable", ""];
1431
1245
  lines.push("using System;");
1432
1246
  if (clients.length > 0) lines.push(`using ${namespaceName}.Clients;`);
1433
1247
  lines.push(`using ${namespaceName}.Runtime;`);
1434
1248
  lines.push("");
1435
1249
  lines.push(`namespace ${namespaceName};`);
1436
1250
  lines.push("");
1437
- lines.push(...xmlDocLines("Entry point to the generated SDK.\n\nHolds one SdkHttp, shared by every client, so the SDK keeps a single connection pool.\nDisposing it disposes the underlying HttpClient, unless you supplied your own.", ""));
1251
+ lines.push(
1252
+ ...xmlDocLines(
1253
+ "Entry point to the generated SDK.\n\nHolds one SdkHttp, shared by every client, so the SDK keeps a single connection pool.\nDisposing it disposes the underlying HttpClient, unless you supplied your own.",
1254
+ ""
1255
+ )
1256
+ );
1438
1257
  lines.push(`public sealed class ${sdkName} : IDisposable`);
1439
1258
  lines.push("{");
1440
1259
  lines.push(` public ${sdkName}(SdkOptions options)`);
@@ -1457,7 +1276,6 @@ function generateSdkCs(namespaceName, sdkName, clients) {
1457
1276
  lines.push("");
1458
1277
  return lines.join("\n");
1459
1278
  }
1460
- __name(generateSdkCs, "generateSdkCs");
1461
1279
 
1462
1280
  // src/hoist.ts
1463
1281
  import { collectTypeRefs, resolveEffectiveFields as resolveEffectiveFields2 } from "@contractkit/core";
@@ -1480,14 +1298,8 @@ function collectHoistedTypes(roots, opts) {
1480
1298
  }
1481
1299
  }
1482
1300
  }
1483
- return {
1484
- byNode: state.byNode,
1485
- byName: state.byName,
1486
- byFile: state.byFile,
1487
- memberships: state.memberships
1488
- };
1301
+ return { byNode: state.byNode, byName: state.byName, byFile: state.byFile, memberships: state.memberships };
1489
1302
  }
1490
- __name(collectHoistedTypes, "collectHoistedTypes");
1491
1303
  function walkType(type, path, ownerFile, state, atAliasRoot, description) {
1492
1304
  switch (type.kind) {
1493
1305
  case "union":
@@ -1498,14 +1310,11 @@ function walkType(type, path, ownerFile, state, atAliasRoot, description) {
1498
1310
  return;
1499
1311
  case "enum":
1500
1312
  if (!atAliasRoot) {
1501
- hoist(type, {
1502
- kind: "enum",
1503
- name: claimFor(path, state, false),
1504
- ownerFile,
1505
- needsInput: false,
1506
- values: type.values,
1507
- description
1508
- }, state);
1313
+ hoist(
1314
+ type,
1315
+ { kind: "enum", name: claimFor(path, state, false), ownerFile, needsInput: false, values: type.values, description },
1316
+ state
1317
+ );
1509
1318
  }
1510
1319
  return;
1511
1320
  case "inlineObject":
@@ -1523,14 +1332,18 @@ function walkType(type, path, ownerFile, state, atAliasRoot, description) {
1523
1332
  }
1524
1333
  case "tuple":
1525
1334
  type.items.forEach((item, i) => walkType(item, `${path}Item${i}`, ownerFile, state, false));
1526
- hoist(type, {
1527
- kind: "tuple",
1528
- name: claimFor(path, state, false),
1529
- ownerFile,
1530
- needsInput: type.items.some((t) => typeNeedsInput(t, state)),
1531
- items: type.items,
1532
- description
1533
- }, state);
1335
+ hoist(
1336
+ type,
1337
+ {
1338
+ kind: "tuple",
1339
+ name: claimFor(path, state, false),
1340
+ ownerFile,
1341
+ needsInput: type.items.some((t) => typeNeedsInput(t, state)),
1342
+ items: type.items,
1343
+ description
1344
+ },
1345
+ state
1346
+ );
1534
1347
  return;
1535
1348
  case "array":
1536
1349
  walkType(type.item, path, ownerFile, state, false);
@@ -1545,20 +1358,22 @@ function walkType(type, path, ownerFile, state, atAliasRoot, description) {
1545
1358
  return;
1546
1359
  }
1547
1360
  }
1548
- __name(walkType, "walkType");
1549
1361
  function hoistRecord(node, fields, path, ownerFile, state, description) {
1550
1362
  const name = claimFor(path, state, false);
1551
1363
  for (const f of fields) walkType(f.type, `${name}${toCSharpTypeName(f.name)}`, ownerFile, state, false, f.description);
1552
- hoist(node, {
1553
- kind: "record",
1554
- name,
1555
- ownerFile,
1556
- needsInput: fields.some((f) => f.visibility !== "normal" || typeNeedsInput(f.type, state)),
1557
- fields,
1558
- description
1559
- }, state);
1364
+ hoist(
1365
+ node,
1366
+ {
1367
+ kind: "record",
1368
+ name,
1369
+ ownerFile,
1370
+ needsInput: fields.some((f) => f.visibility !== "normal" || typeNeedsInput(f.type, state)),
1371
+ fields,
1372
+ description
1373
+ },
1374
+ state
1375
+ );
1560
1376
  }
1561
- __name(hoistRecord, "hoistRecord");
1562
1377
  function hoistPlainUnion(type, path, ownerFile, state, atAliasRoot, description) {
1563
1378
  const nullable = type.members.some((m) => m.kind === "scalar" && m.name === "null");
1564
1379
  const members = type.members.filter((m) => !(m.kind === "scalar" && m.name === "null"));
@@ -1568,15 +1383,7 @@ function hoistPlainUnion(type, path, ownerFile, state, atAliasRoot, description)
1568
1383
  }
1569
1384
  if (members.every((m) => m.kind === "literal" && typeof m.value === "string")) {
1570
1385
  const values = members.map((m) => String(m.value));
1571
- hoist(type, {
1572
- kind: "enum",
1573
- name: claimFor(path, state, atAliasRoot),
1574
- ownerFile,
1575
- needsInput: false,
1576
- nullable,
1577
- values,
1578
- description
1579
- }, state);
1386
+ hoist(type, { kind: "enum", name: claimFor(path, state, atAliasRoot), ownerFile, needsInput: false, nullable, values, description }, state);
1580
1387
  return;
1581
1388
  }
1582
1389
  const name = claimFor(path, state, atAliasRoot);
@@ -1585,23 +1392,22 @@ function hoistPlainUnion(type, path, ownerFile, state, atAliasRoot, description)
1585
1392
  for (const member of members) {
1586
1393
  walkType(member, `${name}${toCSharpTypeName(memberLabel(member, state))}`, ownerFile, state, false);
1587
1394
  const typeName = memberTypeName(member, state);
1588
- hoisted.push({
1589
- typeName,
1590
- wrapperName: uniqueIn(`Of${toCSharpTypeName(memberLabel(member, state))}`, used),
1591
- type: member
1592
- });
1395
+ hoisted.push({ typeName, wrapperName: uniqueIn(`Of${toCSharpTypeName(memberLabel(member, state))}`, used), type: member });
1593
1396
  }
1594
- hoist(type, {
1595
- kind: "plainUnion",
1596
- name,
1597
- ownerFile,
1598
- needsInput: members.some((m) => typeNeedsInput(m, state)),
1599
- nullable,
1600
- members: hoisted,
1601
- description
1602
- }, state);
1397
+ hoist(
1398
+ type,
1399
+ {
1400
+ kind: "plainUnion",
1401
+ name,
1402
+ ownerFile,
1403
+ needsInput: members.some((m) => typeNeedsInput(m, state)),
1404
+ nullable,
1405
+ members: hoisted,
1406
+ description
1407
+ },
1408
+ state
1409
+ );
1603
1410
  }
1604
- __name(hoistPlainUnion, "hoistPlainUnion");
1605
1411
  function hoistDiscriminatedUnion(type, path, ownerFile, state, atAliasRoot, description) {
1606
1412
  const name = claimFor(path, state, atAliasRoot);
1607
1413
  const members = [];
@@ -1610,17 +1416,16 @@ function hoistDiscriminatedUnion(type, path, ownerFile, state, atAliasRoot, desc
1610
1416
  const discriminatorField = fields.find((f) => f.name === type.discriminator);
1611
1417
  const tagType = discriminatorField?.type.kind === "lazy" ? discriminatorField.type.inner : discriminatorField?.type;
1612
1418
  if (!tagType || tagType.kind !== "literal") {
1613
- state.warn?.(`Discriminated union '${name}' has a member whose '${type.discriminator}' is not a literal, so its tag is not known at build time; emitting a raw JSON value instead of an interface.`, ownerFile);
1419
+ state.warn?.(
1420
+ `Discriminated union '${name}' has a member whose '${type.discriminator}' is not a literal, so its tag is not known at build time; emitting a raw JSON value instead of an interface.`,
1421
+ ownerFile
1422
+ );
1614
1423
  release(name, state, atAliasRoot);
1615
1424
  return;
1616
1425
  }
1617
1426
  const tag = String(tagType.value);
1618
1427
  if (member.kind === "ref") {
1619
- members.push({
1620
- typeName: member.name,
1621
- tag,
1622
- type: member
1623
- });
1428
+ members.push({ typeName: member.name, tag, type: member });
1624
1429
  } else {
1625
1430
  const memberPath = `${name}${toCSharpTypeName(tag)}`;
1626
1431
  hoistRecord(member, fields, memberPath, ownerFile, state, void 0);
@@ -1629,11 +1434,7 @@ function hoistDiscriminatedUnion(type, path, ownerFile, state, atAliasRoot, desc
1629
1434
  release(name, state, atAliasRoot);
1630
1435
  return;
1631
1436
  }
1632
- members.push({
1633
- typeName: decl2.name,
1634
- tag,
1635
- type: member
1636
- });
1437
+ members.push({ typeName: decl2.name, tag, type: member });
1637
1438
  }
1638
1439
  }
1639
1440
  if (members.length === 0) {
@@ -1656,7 +1457,6 @@ function hoistDiscriminatedUnion(type, path, ownerFile, state, atAliasRoot, desc
1656
1457
  state.memberships.set(member.typeName, list);
1657
1458
  }
1658
1459
  }
1659
- __name(hoistDiscriminatedUnion, "hoistDiscriminatedUnion");
1660
1460
  function memberLabel(type, state) {
1661
1461
  switch (type.kind) {
1662
1462
  case "ref":
@@ -1677,23 +1477,18 @@ function memberLabel(type, state) {
1677
1477
  }
1678
1478
  }
1679
1479
  }
1680
- __name(memberLabel, "memberLabel");
1681
1480
  function memberTypeName(type, state) {
1682
1481
  const decl = state.byNode.get(type);
1683
1482
  if (decl) return decl.name;
1684
1483
  if (type.kind === "ref") return type.name;
1685
1484
  return "";
1686
1485
  }
1687
- __name(memberTypeName, "memberTypeName");
1688
1486
  function typeNeedsInput(type, state) {
1689
1487
  const refs = /* @__PURE__ */ new Set();
1690
1488
  collectTypeRefs(type, refs);
1691
- if ([
1692
- ...refs
1693
- ].some((r) => state.modelsWithInput.has(r))) return true;
1489
+ if ([...refs].some((r) => state.modelsWithInput.has(r))) return true;
1694
1490
  return hasVisibilityField(type);
1695
1491
  }
1696
- __name(typeNeedsInput, "typeNeedsInput");
1697
1492
  function hasVisibilityField(type) {
1698
1493
  switch (type.kind) {
1699
1494
  case "inlineObject":
@@ -1714,7 +1509,6 @@ function hasVisibilityField(type) {
1714
1509
  return false;
1715
1510
  }
1716
1511
  }
1717
- __name(hasVisibilityField, "hasVisibilityField");
1718
1512
  function hoist(node, decl, state) {
1719
1513
  state.byNode.set(node, decl);
1720
1514
  state.byName.set(decl.name, decl);
@@ -1722,16 +1516,13 @@ function hoist(node, decl, state) {
1722
1516
  list.push(decl);
1723
1517
  state.byFile.set(decl.ownerFile, list);
1724
1518
  }
1725
- __name(hoist, "hoist");
1726
1519
  function claimFor(path, state, atAliasRoot) {
1727
1520
  if (atAliasRoot) return path;
1728
1521
  return uniqueIn(sanitizeCSharpTypeName(path), state.taken);
1729
1522
  }
1730
- __name(claimFor, "claimFor");
1731
1523
  function release(name, state, atAliasRoot) {
1732
1524
  if (!atAliasRoot) state.taken.delete(name);
1733
1525
  }
1734
- __name(release, "release");
1735
1526
  function uniqueIn(base, taken) {
1736
1527
  if (!taken.has(base)) {
1737
1528
  taken.add(base);
@@ -1742,7 +1533,6 @@ function uniqueIn(base, taken) {
1742
1533
  taken.add(`${base}${n}`);
1743
1534
  return `${base}${n}`;
1744
1535
  }
1745
- __name(uniqueIn, "uniqueIn");
1746
1536
 
1747
1537
  // src/runtime.ts
1748
1538
  function generateRuntimeCs(namespaceName) {
@@ -2117,7 +1907,6 @@ public sealed class SdkHttp : IDisposable
2117
1907
  }
2118
1908
  `;
2119
1909
  }
2120
- __name(generateRuntimeCs, "generateRuntimeCs");
2121
1910
 
2122
1911
  // src/runtime-converters.ts
2123
1912
  function generateConvertersCs(namespaceName) {
@@ -2253,7 +2042,6 @@ public sealed class IsoTimeSpanConverter : JsonConverter<TimeSpan>
2253
2042
  }
2254
2043
  `;
2255
2044
  }
2256
- __name(generateConvertersCs, "generateConvertersCs");
2257
2045
 
2258
2046
  // src/scaffold.ts
2259
2047
  var SCAFFOLD_VERSIONS = {
@@ -2274,7 +2062,6 @@ function generateCsproj(namespaceName, sdkName) {
2274
2062
  </Project>
2275
2063
  `;
2276
2064
  }
2277
- __name(generateCsproj, "generateCsproj");
2278
2065
 
2279
2066
  // src/index.ts
2280
2067
  var CSHARP_CODEGEN_VERSION = "1";
@@ -2298,14 +2085,15 @@ function createCSharpSdkPlugin(config, rootDir) {
2298
2085
  }
2299
2086
  };
2300
2087
  }
2301
- __name(createCSharpSdkPlugin, "createCSharpSdkPlugin");
2302
2088
  var NAMESPACE_RE = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
2303
2089
  var SDK_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
2304
2090
  function assertValidConfig(config) {
2305
2091
  const { namespace, sdkName } = config;
2306
2092
  if (namespace !== void 0) {
2307
2093
  if (typeof namespace !== "string" || !NAMESPACE_RE.test(namespace)) {
2308
- throw new Error(`plugin-csharp: namespace '${String(namespace)}' is not a valid C# namespace \u2014 expected dot-separated identifiers, e.g. 'Acme.Sdk'.`);
2094
+ throw new Error(
2095
+ `plugin-csharp: namespace '${String(namespace)}' is not a valid C# namespace \u2014 expected dot-separated identifiers, e.g. 'Acme.Sdk'.`
2096
+ );
2309
2097
  }
2310
2098
  const keyword = namespace.split(".").find((segment) => CSHARP_KEYWORDS.has(segment));
2311
2099
  if (keyword) {
@@ -2320,17 +2108,13 @@ function assertValidConfig(config) {
2320
2108
  throw new Error(`plugin-csharp: sdkName '${sdkName}' is a C# keyword.`);
2321
2109
  }
2322
2110
  }
2323
- for (const key of [
2324
- "includeInternal",
2325
- "scaffold"
2326
- ]) {
2111
+ for (const key of ["includeInternal", "scaffold"]) {
2327
2112
  const value = config[key];
2328
2113
  if (value !== void 0 && typeof value !== "boolean") {
2329
2114
  throw new Error(`plugin-csharp: ${key} must be a boolean \u2014 got ${JSON.stringify(value)}.`);
2330
2115
  }
2331
2116
  }
2332
2117
  }
2333
- __name(assertValidConfig, "assertValidConfig");
2334
2118
  async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2335
2119
  assertValidConfig(config);
2336
2120
  const { contractRoots } = inputs;
@@ -2341,13 +2125,11 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2341
2125
  const allModels = contractRoots.flatMap((root) => root.models);
2342
2126
  const modelIndex = buildModelIndex2(allModels);
2343
2127
  const modelsWithInput = resolveModelsWithInput(allModels, inputs.modelsWithInput);
2344
- const modelsWithInputArray = [
2345
- ...modelsWithInput
2346
- ].sort();
2128
+ const modelsWithInputArray = [...modelsWithInput].sort();
2347
2129
  const hoisted = collectHoistedTypes(contractRoots, {
2348
2130
  modelIndex,
2349
2131
  modelsWithInput,
2350
- warn: /* @__PURE__ */ __name((message, file) => ctx.warn?.(message, file), "warn")
2132
+ warn: (message, file) => ctx.warn?.(message, file)
2351
2133
  });
2352
2134
  const prevManifest = ctx.cacheEnabled ? readManifest(manifestPath) : emptyIncrementalManifest(CSHARP_CODEGEN_VERSION);
2353
2135
  const units = [];
@@ -2357,20 +2139,9 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2357
2139
  const ownNames = new Set(root.models.map((m) => m.name));
2358
2140
  const referenced = referencedModelNames(root);
2359
2141
  const relevantInputModels = modelsWithInputArray.filter((name) => ownNames.has(name) || referenced.has(name));
2360
- const externalBases = [
2361
- ...referenced
2362
- ].filter((name) => !ownNames.has(name)).sort().map((name) => modelIndex.get(name)).filter((m) => m !== void 0);
2363
- const ownedDeclarations = (hoisted.byFile.get(root.file) ?? []).map((d) => ({
2364
- kind: d.kind,
2365
- name: d.name,
2366
- needsInput: d.needsInput
2367
- }));
2368
- const declaredMemberships = [
2369
- ...ownNames
2370
- ].sort().map((name) => [
2371
- name,
2372
- hoisted.memberships.get(name) ?? []
2373
- ]).filter(([, unions]) => unions.length > 0);
2142
+ const externalBases = [...referenced].filter((name) => !ownNames.has(name)).sort().map((name) => modelIndex.get(name)).filter((m) => m !== void 0);
2143
+ const ownedDeclarations = (hoisted.byFile.get(root.file) ?? []).map((d) => ({ kind: d.kind, name: d.name, needsInput: d.needsInput }));
2144
+ const declaredMemberships = [...ownNames].sort().map((name) => [name, hoisted.memberships.get(name) ?? []]).filter(([, unions]) => unions.length > 0);
2374
2145
  const fingerprint = hashFingerprint({
2375
2146
  kind: "models",
2376
2147
  v: CSHARP_CODEGEN_VERSION,
@@ -2385,7 +2156,7 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2385
2156
  units.push({
2386
2157
  key: `models::${relPath}`,
2387
2158
  fingerprint,
2388
- render: /* @__PURE__ */ __name(() => [
2159
+ render: () => [
2389
2160
  {
2390
2161
  relativePath: relPath,
2391
2162
  content: generateCSharpModels(root, {
@@ -2393,24 +2164,19 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2393
2164
  modelsWithInput,
2394
2165
  modelIndex,
2395
2166
  hoisted,
2396
- warn: /* @__PURE__ */ __name((message) => ctx.warn?.(message, root.file), "warn")
2167
+ warn: (message) => ctx.warn?.(message, root.file)
2397
2168
  })
2398
2169
  }
2399
- ], "render")
2170
+ ]
2400
2171
  });
2401
2172
  }
2402
2173
  for (const root of inputs.opRoots) {
2403
2174
  if (!hasPublicOperations(root, config.includeInternal)) continue;
2404
2175
  const relPath = `Clients/${deriveClientClassName(root.file)}.cs`;
2405
- clients.push({
2406
- className: deriveClientClassName(root.file),
2407
- propertyName: deriveClientPropertyName(root.file)
2408
- });
2176
+ clients.push({ className: deriveClientClassName(root.file), propertyName: deriveClientPropertyName(root.file) });
2409
2177
  const referenced = referencedOpModels(root, modelIndex);
2410
2178
  const relevantInputModels = modelsWithInputArray.filter((name) => referenced.has(name));
2411
- const referencedModels = [
2412
- ...referenced
2413
- ].sort().map((name) => modelIndex.get(name)).filter((m) => m !== void 0);
2179
+ const referencedModels = [...referenced].sort().map((name) => modelIndex.get(name)).filter((m) => m !== void 0);
2414
2180
  const fingerprint = hashFingerprint({
2415
2181
  kind: "client",
2416
2182
  v: CSHARP_CODEGEN_VERSION,
@@ -2424,7 +2190,7 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2424
2190
  units.push({
2425
2191
  key: `client::${relPath}`,
2426
2192
  fingerprint,
2427
- render: /* @__PURE__ */ __name(() => [
2193
+ render: () => [
2428
2194
  {
2429
2195
  relativePath: relPath,
2430
2196
  content: generateCSharpClient(root, {
@@ -2433,60 +2199,41 @@ async function runCSharpCodegen(inputs, ctx, config, rootDir) {
2433
2199
  modelIndex,
2434
2200
  hoisted,
2435
2201
  includeInternal: config.includeInternal,
2436
- warn: /* @__PURE__ */ __name((message) => ctx.warn?.(message, root.file), "warn")
2202
+ warn: (message) => ctx.warn?.(message, root.file)
2437
2203
  })
2438
2204
  }
2439
- ], "render")
2205
+ ]
2440
2206
  });
2441
2207
  }
2442
2208
  const globalFiles = [
2443
- {
2444
- relativePath: "Runtime/Converters.cs",
2445
- content: generateConvertersCs(namespaceName)
2446
- },
2447
- {
2448
- relativePath: "Runtime/SdkRuntime.cs",
2449
- content: generateRuntimeCs(namespaceName)
2450
- },
2451
- {
2452
- relativePath: `${sdkName}.cs`,
2453
- content: generateSdkCs(namespaceName, sdkName, clients)
2454
- }
2209
+ { relativePath: "Runtime/Converters.cs", content: generateConvertersCs(namespaceName) },
2210
+ { relativePath: "Runtime/SdkRuntime.cs", content: generateRuntimeCs(namespaceName) },
2211
+ { relativePath: `${sdkName}.cs`, content: generateSdkCs(namespaceName, sdkName, clients) }
2455
2212
  ];
2456
2213
  if (config.scaffold) {
2457
- globalFiles.push({
2458
- relativePath: `${sdkName}.csproj`,
2459
- content: generateCsproj(namespaceName, sdkName),
2460
- ifAbsent: true
2461
- });
2214
+ globalFiles.push({ relativePath: `${sdkName}.csproj`, content: generateCsproj(namespaceName, sdkName), ifAbsent: true });
2462
2215
  }
2463
2216
  const result = runIncrementalCodegen({
2464
2217
  codegenVersion: CSHARP_CODEGEN_VERSION,
2465
2218
  prevManifest,
2466
2219
  globalFiles,
2467
2220
  units,
2468
- fileExists: /* @__PURE__ */ __name((relPath) => existsSync(resolve(outDir, relPath)), "fileExists")
2221
+ fileExists: (relPath) => existsSync(resolve(outDir, relPath))
2469
2222
  });
2470
2223
  deleteStalePaths(outDir, result.deletedPaths);
2471
2224
  for (const { relativePath, content, ifAbsent } of result.filesToWrite) {
2472
- ctx.emitFile(resolve(outDir, relativePath), content, ifAbsent ? {
2473
- ifAbsent: true
2474
- } : void 0);
2225
+ ctx.emitFile(resolve(outDir, relativePath), content, ifAbsent ? { ifAbsent: true } : void 0);
2475
2226
  }
2476
2227
  writeManifest(manifestPath, result.manifest);
2477
2228
  }
2478
- __name(runCSharpCodegen, "runCSharpCodegen");
2479
2229
  function referencedOpModels(root, modelIndex) {
2480
2230
  const seeds = [];
2481
- const addParamSource = /* @__PURE__ */ __name((source) => {
2231
+ const addParamSource = (source) => {
2482
2232
  if (!source) return;
2483
2233
  if (source.kind === "params") seeds.push(...source.nodes.map((n) => n.type));
2484
- else if (source.kind === "ref") seeds.push({
2485
- kind: "ref",
2486
- name: source.name
2487
- });
2234
+ else if (source.kind === "ref") seeds.push({ kind: "ref", name: source.name });
2488
2235
  else seeds.push(source.node);
2489
- }, "addParamSource");
2236
+ };
2490
2237
  for (const route of root.routes) {
2491
2238
  addParamSource(route.params);
2492
2239
  for (const op of route.operations) {
@@ -2501,7 +2248,6 @@ function referencedOpModels(root, modelIndex) {
2501
2248
  }
2502
2249
  return collectTransitiveModelRefs(seeds, modelIndex);
2503
2250
  }
2504
- __name(referencedOpModels, "referencedOpModels");
2505
2251
  function referencedModelNames(root) {
2506
2252
  const refs = /* @__PURE__ */ new Set();
2507
2253
  for (const model of root.models) {
@@ -2511,7 +2257,6 @@ function referencedModelNames(root) {
2511
2257
  }
2512
2258
  return refs;
2513
2259
  }
2514
- __name(referencedModelNames, "referencedModelNames");
2515
2260
  function readManifest(manifestPath) {
2516
2261
  if (!existsSync(manifestPath)) return emptyIncrementalManifest(CSHARP_CODEGEN_VERSION);
2517
2262
  try {
@@ -2520,26 +2265,20 @@ function readManifest(manifestPath) {
2520
2265
  return emptyIncrementalManifest(CSHARP_CODEGEN_VERSION);
2521
2266
  }
2522
2267
  }
2523
- __name(readManifest, "readManifest");
2524
2268
  function writeManifest(manifestPath, manifest) {
2525
2269
  try {
2526
- mkdirSync(dirname(manifestPath), {
2527
- recursive: true
2528
- });
2270
+ mkdirSync(dirname(manifestPath), { recursive: true });
2529
2271
  writeFileSync(manifestPath, serializeIncrementalManifest(manifest), "utf-8");
2530
2272
  } catch {
2531
2273
  }
2532
2274
  }
2533
- __name(writeManifest, "writeManifest");
2534
2275
  function deleteStalePaths(outDir, relPaths) {
2535
2276
  if (relPaths.length === 0) return;
2536
2277
  const removedDirs = /* @__PURE__ */ new Set();
2537
2278
  for (const rel of relPaths) {
2538
2279
  const abs = resolve(outDir, rel);
2539
2280
  if (existsSync(abs)) {
2540
- rmSync(abs, {
2541
- force: true
2542
- });
2281
+ rmSync(abs, { force: true });
2543
2282
  removedDirs.add(join(abs, ".."));
2544
2283
  }
2545
2284
  }
@@ -2559,7 +2298,6 @@ function deleteStalePaths(outDir, relPaths) {
2559
2298
  }
2560
2299
  }
2561
2300
  }
2562
- __name(deleteStalePaths, "deleteStalePaths");
2563
2301
  export {
2564
2302
  CSHARP_CODEGEN_VERSION,
2565
2303
  assertValidConfig,