Read typespec-ts client user-agent version dynamically from package.json#4859
Read typespec-ts client user-agent version dynamically from package.json#4859xirzec wants to merge 7 commits into
Conversation
Stop defaulting package-details.version in the data model so an unset version stays undefined; each consumer (package.json, CHANGELOG, README, user-agent) now applies the 1.0.0-beta.1 default locally. This makes the derived isVersionUserProvided flag redundant, so it is removed from the PackageDetails interface, emitter option schema, and docs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The client user-agent version was burned into the generated source from the emitter's package-details.version option. Since a generated package's version is owned by its package.json, emit a self-referencing JSON import (import pkgJson from '<name>/package.json' with { type: 'json' }) and interpolate pkgJson.version at runtime instead. Uses the package's existing './package.json' export so the specifier is identical in src and dist.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The client user-agent version is now read dynamically from package.json at runtime, so there is no burned-in version constant for dev-tool to bump. Remove the //metadata.constantPaths userAgentInfo generation, the clientContextPaths option threaded through buildPackageFile/updatePackageFile/buildAzureMonorepoPackage, and the getRelativeContextPaths helper, along with the now-obsolete unit tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
All changed packages have been documented.
Show changes
|
commit: |
|
You can try these changes here
|
⚡ Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 1.01s | 🔴 1.08s | +6.4% 🔴 |
| loader | 🟡 305.6ms | 🟡 323.0ms | +5.7% 🔴 |
| resolver | 🟢 40.1ms | 🟢 42.8ms | +6.7% 🔴 |
| checker | 🟡 364.2ms | 🟡 391.5ms | +7.5% 🔴 |
| validation | 🟢 84.6ms | 🟢 89.0ms | +5.2% 🔴 |
| ↳ validation/@azure-tools/typespec-azure-core | 🟡 12.6ms | 🟡 13.3ms | +5.6% |
| ↳ validation/@typespec/http | 🟡 15.5ms | 🟡 16.4ms | +6.1% |
| ↳ validation/@typespec/rest | 🟢 1.6ms | 🟢 1.8ms | +9.4% |
| ↳ validation/@typespec/versioning | 🔴 50.9ms | 🔴 53.4ms | +4.7% |
| ↳ validation/compiler | 🟢 3.8ms | 🟢 4.1ms | +6.1% |
| linter | 🟡 215.2ms | 🟡 228.3ms | +6.1% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.1ms | 🟢 0.1ms | +6.9% |
| ↳ linter/@azure-tools/typespec-azure-core/bad-record-type | 🟢 0.6ms | 🟢 0.6ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🟢 8.4ms | 🟢 8.9ms | +6.6% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 1.5ms | 🟢 1.5ms | +5.2% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 0.2ms | 🟢 0.2ms | +6.6% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟢 2.0ms | 🟢 2.1ms | +5.2% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟢 1.4ms | 🟢 1.5ms | +5.4% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 0.4ms | 🟢 0.4ms | +7.0% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 0.5ms | 🟢 0.5ms | +5.2% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 0.8ms | 🟢 0.9ms | +4.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 0.7ms | 🟢 0.7ms | +4.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 1.0ms | 🟢 1.0ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.2ms | 🟢 0.3ms | +5.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 0.3ms | 🟢 0.3ms | +6.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 0.2ms | 🟢 0.2ms | +8.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 0.8ms | 🟢 0.9ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 0.8ms | 🟢 0.9ms | +6.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🔴 26.7ms | 🔴 28.4ms | +6.5% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🟢 2.1ms | 🟢 2.1ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.2ms | 🟢 0.3ms | +9.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 0.4ms | 🟢 0.4ms | +7.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟢 2.0ms | 🟢 2.1ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🟢 2.3ms | 🟢 2.4ms | +2.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🟢 3.2ms | 🟢 3.3ms | +4.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🔴 27.8ms | 🔴 29.7ms | +6.9% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-response-body | 🔴 33.3ms | 🔴 34.9ms | +4.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces | 🟢 0.1ms | 🟢 0.1ms | +19.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch | 🟢 7.7ms | 🟢 8.2ms | +6.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 0.4ms | 🟢 0.4ms | +8.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.1ms | 🟢 0.2ms | +7.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 0.3ms | 🟢 0.4ms | +15.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 0.8ms | 🟢 0.8ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 0.4ms | 🟢 0.4ms | +4.2% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 0.5ms | 🟢 0.5ms | +4.4% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.1ms | 🟢 0.1ms | +8.4% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🔴 32.7ms | 🔴 35.2ms | +7.8% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.7ms | 🟢 0.7ms | +5.1% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 0.5ms | 🟢 0.5ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-names | 🟢 7.6ms | 🟢 8.1ms | +6.6% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations | 🟢 0.3ms | 🟢 0.3ms | +5.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources | 🔴 21.1ms | 🔴 22.1ms | +5.0% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations | 🟢 0.3ms | 🟢 0.3ms | +4.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🟡 12.1ms | 🟡 12.8ms | +6.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.2ms | 🟢 0.2ms | +5.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +5.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 5.0ms | 🟢 4.6ms | -8.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🟡 17.0ms | 🟡 17.9ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 0.6ms | 🟢 0.7ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 1.4ms | 🟢 1.5ms | +8.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.2ms | 🟢 0.2ms | -2.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 0.4ms | 🟢 0.5ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 0.4ms | 🟢 0.4ms | +7.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.1ms | 🟢 0.1ms | -3.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 0.2ms | 🟢 0.2ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.3ms | 🟢 0.3ms | +4.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.2ms | 🟢 0.2ms | +3.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 0.5ms | 🟢 0.5ms | +3.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.1ms | 🟢 0.2ms | +11.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 0.5ms | 🟢 0.6ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🟢 9.0ms | 🟢 9.4ms | +4.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 0.8ms | 🟢 0.9ms | +7.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 0.4ms | 🟢 0.4ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.4ms | 🟢 0.5ms | +5.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.2ms | 🟢 0.2ms | +6.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 0.4ms | 🟢 0.4ms | +2.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.1ms | 🟢 0.1ms | +5.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🟡 19.7ms | 🔴 21.2ms | +7.9% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.1ms | 🟢 0.2ms | +7.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 1.0ms | 🟢 1.0ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.3ms | 🟢 0.3ms | +7.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props | 🟢 0.3ms | 🟢 0.3ms | +6.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property | 🟢 0.2ms | 🟢 0.2ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 0.5ms | 🟢 0.5ms | +7.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🔴 29.8ms | 🔴 32.3ms | +8.2% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 0.4ms | 🟢 0.4ms | +6.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 0.4ms | 🟢 0.5ms | +3.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🟢 5.4ms | 🟢 5.8ms | +8.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 0.7ms | 🟢 0.7ms | +0.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.3ms | 🟢 0.3ms | +2.7% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🟢 2.3ms | 🟢 2.4ms | +4.9% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 1.7ms | 🟢 1.8ms | +5.6% |
| emit | 🔴 6.04s | 🔴 6.42s | +6.4% 🔴 |
| ↳ emit/@Azure-Tools | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@azure-tools/typespec-autorest | 🟢 125.4ms | 🟢 132.7ms | +5.8% 🔴 |
| ↳ emit/@azure-tools/typespec-python | 🔴 2.25s | 🔴 2.40s | +6.5% 🔴 |
| ↳ emit/@typespec | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ emit/@typespec/http-client-js | 🔴 571.0ms | 🔴 605.1ms | +6.0% 🔴 |
| ↳ emit/@typespec/openapi3 | 🟢 107.9ms | 🟢 113.8ms | +5.4% 🔴 |
| ↳ emit/@typespec/openapi3/compute | 🟢 93.8ms | 🟢 98.8ms | +5.4% 🔴 |
| ↳ emit/@typespec/openapi3/write | 🟢 13.8ms | 🟢 14.6ms | +6.0% |
Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)
…-user-provided-flag # Conflicts: # packages/typespec-ts/src/modular/helpers/client-helpers.ts
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Address CI failures: run prettier on the merged build-azure-monorepo-package.ts and client-helpers.test.ts, and commit the regenerated typespec-ts README emitter-options table (column widths shrank once isVersionUserProvided was removed). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…json import Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9d488e2f-cc7e-4b97-84d5-5c6adde5f75e
Why
The
@azure-tools/typespec-tsemitter burned thepackage-details.versionemitter option into the generated client's user-agent string. Once a package is generated, that version is really owned by the package's ownpackage.json, so hardcoding it forced a whole machinery (the//metadata.constantPathsuserAgentInfoentries) to exist purely sodev-toolcould rewrite the burned-in constant on every release. This PR removes that coupling and simplifies the version handling along the way.What changed
1. Stop defaulting
package-details.versionin the datamodel; default at the point of use.The version was previously defaulted to
1.0.0-beta.1during option transform, and a separateisVersionUserProvidedflag was carried around so the README logic could tell "user set it" from "we defaulted it." That flag existed for exactly one consumer. Nowversionstaysundefinedwhen unset and each consumer (package.json, CHANGELOG, README, user-agent) applies its own default locally, soisVersionUserProvidedis gone entirely.2. Emit code that reads the version dynamically at runtime.
Instead of interpolating a literal version into the generated source,
buildUserAgentOptionsnow emits a self-referencing JSON import and readspkgJson.version:The self-reference (
<packageName>/package.json) relies on the"./package.json"export the emitted package already declares, so the specifier resolves identically fromsrcand from the builtdistoutput regardless of directory depth. The import is deduped per file and only emitted for the api context (the classical-client prefix never surfaceduserAgentInfo).3. Remove the now-obsolete
constantPathsplumbing.With no literal version in the source, there is nothing for
dev-toolto bump, so the//metadata.constantPathsuserAgentInfogeneration and theclientContextPathsoption threaded throughbuildPackageFile/updatePackageFile/buildAzureMonorepoPackage(plus thegetRelativeContextPathshelper) are dead. All removed.Notes for reviewers
test-next(252) andunit-modular(657) all pass. The modular snapshot scenarios don't setpackage-details, so there is zero snapshot churn.azure-sdk-for-jsbuild (tshy + api-extractor) to confirm the JSON import compiles end to end in a real generated package. The syntax and module resolution are correct, but that integration path is out of scope for this environment.value: "json") because the writer auto-quotes it.