Skip to content

Commit c706604

Browse files
Factor stripOpaqueJsonMarker into utils.ts
Move the inline `delete rewritten["x-opaque-json"]` out of the TS codegen's rewrite loop and into a named helper next to isOpaqueJson, so the paired `read the marker` / `ignore the marker` operations live together and each language codegen calls the one it needs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e7b77d0 commit c706604

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

scripts/codegen/typescript.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
isVoidSchema,
3838
isSchemaExperimental,
3939
getEnumValueDescriptions,
40+
stripOpaqueJsonMarker,
4041
type ApiSchema,
4142
type DefinitionCollections,
4243
type RpcMethod,
@@ -280,13 +281,12 @@ export function normalizeSchemaForTypeScript(schema: JSONSchema7): JSONSchema7 {
280281
Object.entries(value as Record<string, unknown>).map(([key, child]) => [key, rewrite(child)])
281282
) as Record<string, unknown>;
282283

283-
// Strip the `x-opaque-json` marker so json-schema-to-typescript sees
284-
// the original (typeless) schema and emits the same shape it did
285-
// before the marker was introduced. C# codegen reads the marker from
286-
// the un-normalized schema and emits `JsonElement` instead.
287-
if ("x-opaque-json" in rewritten) {
288-
delete rewritten["x-opaque-json"];
289-
}
284+
// The TypeScript codegen doesn't distinguish opaque JSON from any
285+
// other unconstrained value, so drop the marker before feeding the
286+
// schema to json-schema-to-typescript. C# codegen reads the marker
287+
// from its own (un-normalized) view of the schema and emits
288+
// `JsonElement` instead.
289+
stripOpaqueJsonMarker(rewritten);
290290

291291
const enumValueDescriptions = getEnumValueDescriptions(rewritten as JSONSchema7);
292292
if (enumValueDescriptions && Array.isArray(rewritten.enum) && rewritten.enum.every((entry) => typeof entry === "string")) {

scripts/codegen/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,17 @@ export function isOpaqueJson(schema: JSONSchema7 | null | undefined): boolean {
516516
return typeof schema === "object" && schema !== null && (schema as Record<string, unknown>)["x-opaque-json"] === true;
517517
}
518518

519+
/**
520+
* Removes the `x-opaque-json` marker from a schema node in place. Useful for
521+
* codegens (e.g. TypeScript) that don't distinguish opaque JSON from any other
522+
* unconstrained value and would otherwise have the marker confuse downstream
523+
* tooling. Codegens that *do* care (e.g. C#, which maps opaque JSON to
524+
* `JsonElement`) should call `isOpaqueJson` *before* this point.
525+
*/
526+
export function stripOpaqueJsonMarker(schema: Record<string, unknown>): void {
527+
delete schema["x-opaque-json"];
528+
}
529+
519530
/**
520531
* Append `@internal` and/or `@experimental` JSDoc-style tags to the `description`
521532
* of every property that carries `visibility: "internal"` or `stability: "experimental"`

0 commit comments

Comments
 (0)