Skip to content

Auto-generate ConfigurationSchema.json for JSON IntelliSense#10139

Open
Copilot wants to merge 17 commits intomainfrom
copilot/add-auto-generate-configuration-schema-json
Open

Auto-generate ConfigurationSchema.json for JSON IntelliSense#10139
Copilot wants to merge 17 commits intomainfrom
copilot/add-auto-generate-configuration-schema-json

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 25, 2026

  • Add WriteAdditionalFiles() virtual method to CodeModelGenerator
  • Create ConfigurationSchemaGenerator class in Microsoft.TypeSpec.Generator.ClientModel
  • Override WriteAdditionalFiles() in ScmCodeModelGenerator to invoke schema generation
  • Hook into CSharpGen.ExecuteAsync() to write additional output files
  • Add 19 unit tests for ConfigurationSchemaGenerator (all passing)
  • Verify all existing tests still pass
  • Code review feedback: Remove Azure-specific logic from base emitter
  • Code review feedback: Delete chronus changelog file
  • Run regeneration to generate ConfigurationSchema.json for test projects
  • Common definitions (credential, options) are inherited from the System.ClientModel base schema and referenced via $ref — not duplicated locally
  • Add local definitions for additional non-base types (e.g., enums, models used as custom option properties) referenced via $ref
  • Model options type inheritance: each client's options type is a named local definition that extends the base options via allOf (matching the Azure emitter pattern from azure-sdk-for-net#57548)
  • Re-run generation to update all ConfigurationSchema.json files
  • Update Check-GitChanges.ps1 to also detect new untracked files so the CI regen check catches newly generated files
  • Add test cases for options types with additional properties (string, integer, and multiple mixed types)
  • Add test case and support for options properties that contain model definitions (with properties exposed in local definitions)
  • Add test case for model type used as a constructor parameter (appears as top-level client property with $ref to local definition)
  • Verify ConfigurationSchema.json works end-to-end via local pack and JSON Schema draft-07 meta-validation

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Add schema generation for appsettings.json IntelliSense when a client
library has ClientSettings. The schema includes well-known client names
under 'Clients' (SCM) or 'AzureClients' (Azure) sections, with $ref to
shared credential/options definitions and allOf for client-specific
option extensions.

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/555ac5bb-bd9c-4d73-90ca-f2922cf55fa5
@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Mar 25, 2026

// Determine if Azure or SCM based on the options base type namespace.
var optionsBaseType = ScmCodeModelGenerator.Instance.TypeFactory.ClientPipelineApi.ClientPipelineOptionsType;
bool isAzure = optionsBaseType.Namespace?.StartsWith("Azure", StringComparison.Ordinal) == true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot we shouldn't have anything related to Azure in the base emitter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the Azure-specific namespace detection. Generate() now always uses "Clients" and "options" as defaults, with sectionName/optionsRef parameters that a derived emitter can override if needed. Fixed in 3541fb5.

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/555ac5bb-bd9c-4d73-90ca-f2922cf55fa5
Copilot AI changed the title [WIP] Add auto-generate ConfigurationSchema.json for JSON IntelliSense Auto-generate ConfigurationSchema.json for JSON IntelliSense Mar 25, 2026
Copilot AI requested a review from JoshLove-msft March 25, 2026 19:32
@@ -0,0 +1,29 @@
---
changeKind: feature
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot delete this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted in f3f72b7.

…rator

The base emitter should not contain Azure-specific code. Removed the
namespace-based Azure detection and made Generate() always use "Clients"
and "options" as defaults, with parameters allowing overrides by
derived emitters.

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/78f8c1a0-1d00-4e19-89d1-e9090dc2aeab
Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/7703f03f-8937-43a3-b716-e0e5f8090658
@JoshLove-msft
Copy link
Copy Markdown
Contributor

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 27, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@10139

commit: 577eac7

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 27, 2026

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the feature. Running it now generated 72 schema/ConfigurationSchema.json files across all test projects (Sample-TypeSpec + Spector). Committed in 2c0a31e.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/bin/astro.mjs build node s/.b�� tput-dir ../../w--llmstxt . .2_tmp_4499_0/no../../website/src/content/docs/docs/emitters/openapi3/reference --import @typespec/librar/home/REDACTED/work/typespec/typespec/packages/http-specs/node_modules�� --no-emit node /nod�� gen-extern-signature sh _modules/.bin/sh node scripts/buinode l/reference n/sh sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@JoshLove-msft
Copy link
Copy Markdown
Contributor

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the feature. Running it now generated 72 schema/ConfigurationSchema.json files across all test projects (Sample-TypeSpec + Spector). Committed in 2c0a31e.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

But why didn't the Regen check step fail on the diff then?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 27, 2026

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the featur...

Check-GitChanges.ps1 uses git diff (line 18), which only detects modifications to tracked files. Since the ConfigurationSchema.json files were brand new (untracked), they were invisible to the diff check. The script would need to also check for untracked files (e.g., via git status --porcelain) to catch newly generated files that aren't yet checked in.

"type": "string"
},
"Credential": {
"$ref": "#/definitions/credential"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot where are the definitions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a BuildDefinitions() method that generates the definitions section with credential (authentication configuration with Type property) and options (base ClientPipelineOptions properties including NetworkTimeout and RetryPolicy). All $ref pointers now resolve correctly. Fixed in 27184ed.

Copilot AI and others added 2 commits March 27, 2026 17:50
…ma.json

Common definitions (credential, options) are still inherited from the
System.ClientModel base schema. But custom types like enums used as
client option properties are now placed in a local `definitions` section
and referenced via $ref. This avoids inlining enum values and follows
JSON Schema best practices for type reuse.

Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/fc9787de-f41a-4056-bb05-0711db26ff84

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 27, 2026

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the feature, so no schema files were generated yet. The schemas are now generated and checked in.

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the featur...

Check-GitChanges.ps1 used git diff which only detects changes to tracked files. Since ConfigurationSchema.json files were brand new (untracked), they were invisible to the diff check. This has been fixed — the script now also checks for untracked files via git ls-files --others --exclude-standard.

Check-GitChanges

@copilot let's make that update

Done — Check-GitChanges.ps1 now checks for both tracked modifications (git diff) and untracked files (git ls-files --others --exclude-standard). Fixed in be700ca.

/// Generates a ConfigurationSchema.json file for JSON IntelliSense support in appsettings.json.
/// The schema defines well-known client names and their configuration properties.
/// </summary>
internal static class ConfigurationSchemaGenerator
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot we need to handle the options type inheriting from the core type. Here is an example using Azure options https://github.com/Azure/azure-sdk-for-net/pull/57548/changes

Note we will have a separate PR to handle the Azure config schema, but we need to have the same pattern for the unbranded options.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each client's options type is now modeled as a named local definition that inherits from the base options type using allOf. For example, SampleTypeSpecClientOptions becomes "sampleTypeSpecClientOptions": { "allOf": [{ "$ref": "#/definitions/options" }] }, and client-specific custom properties (when present) are added in a second allOf element. The client's "Options" property references this local definition via $ref. This matches the pattern from azure-sdk-for-net#57548. Fixed in 3de54bd.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please add test cases where an options type has additional properties as compared to the base.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot we should also add a test case where an options property contains a model definition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 3 new test cases in 06c5dba:

  • Generate_OptionsDefinition_IncludesStringProperty — options with a string additional property
  • Generate_OptionsDefinition_IncludesIntegerProperty — options with an integer additional property
  • Generate_OptionsDefinition_IncludesMultipleMixedProperties — options with string + boolean + integer additional properties

Each test verifies the allOf pattern has 2 elements (base $ref + extension object with typed properties). All 17 tests pass.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added GetJsonSchemaForModel that looks up model providers in the output library and creates local definitions with their properties (referenced via $ref). New test Generate_OptionsDefinition_IncludesModelProperty creates a RetryPolicyConfig model with MaxRetries (integer) and Delay (string) properties, then verifies the schema contains a retryPolicyConfig definition with those properties and the options extension references it via $ref. Fixed in 3db3324.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot let's also add a test where the model is a constructor parameter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test Generate_ConstructorParameter_IncludesModelDefinition — creates a ConnectionConfig model (with Host string and Port integer properties) as a required constructor parameter. The test verifies that:

  • The model appears as a local definitions entry (connectionConfig) with its properties
  • The model appears as a top-level client property (not under Options) with $ref to the definition

All 19 tests pass. Fixed in 577eac7.

…ions

Each client's options type is now defined as a named local definition that
inherits from the base 'options' type using allOf. This follows the same
pattern used in the Azure emitter (azure-sdk-for-net#57548) where client
options types extend the core options type.

- Options without custom properties: allOf with single base ref
- Options with custom properties: allOf with base ref + extension object
- The client's Options property references the local definition via $ref

Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/389f65d2-8aed-4cd9-a7cd-29e07b2af4f6

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
Copilot AI and others added 2 commits March 27, 2026 18:28
…nt, mixed)

Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/f557cd05-9182-46bb-806f-405ab81517b9

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
… test

Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/f557cd05-9182-46bb-806f-405ab81517b9

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
… type definitions in schema

Agent-Logs-Url: https://github.com/microsoft/typespec/sessions/9b678996-629b-4c2f-8a16-918f2026e9d0

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
@JoshLove-msft
Copy link
Copy Markdown
Contributor

@copilot verify that the configurationschema works using local pack of the test project

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 27, 2026

@copilot verify that the configurationschema works using local pack of the test project

Verified the ConfigurationSchema.json works:

  1. dotnet pack on Sample-TypeSpec succeeds — project builds cleanly with the schema file in the schema/ directory
  2. JSON Schema draft-07 meta-validation passes for all generated schemas (using Python jsonschema library)
  3. Structure validation confirmed:
    • All well-known clients have Credential ($ref#/definitions/credential) and Options ($ref → named local definition)
    • Options definitions use allOf to inherit from base options type
    • Enum types (e.g., clientType in Spector client-structure tests) are correctly defined with enum values
    • additionalProperties on the section allows custom-named instances
  4. Spector test projects with enums also pass validation (e.g., clientType with 5 known values)

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

The regen step didn't fail because Check-GitChanges.ps1 originally used only git diff, which doesn't detect new untracked files. This has been fixed — the script now also checks for untracked files via git ls-files --others --exclude-standard (fixed in be700ca).

@copilot why didn't the regen show a diff since we don't have a ConfigurationSchema.json checked in for the Test Project?

I hadn't run Generate.ps1 after adding the featur...

The Regen check step didn't fail because Check-GitChanges.ps1 only used git diff which detects changes to tracked files. Since the ConfigurationSchema.json files were brand new (untracked), they were invisible. This was fixed in be700ca — the script now also checks git ls-files --others --exclude-standard for untracked files.

Check-GitChanges

@copilot let's make that update

Already done in be700caCheck-GitChanges.ps1 now checks for both tracked modifications (git diff) and untracked files (git ls-files --others --exclude-standard).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants