Clean up rlc-common debt and decouple modular generation in typespec-ts#4726
Conversation
The static/ helpers (paginate-content, polling-content, serialize-helper, sample-template) and the Karma config builder are leftovers from the removed RLC generator. They are not imported or invoked anywhere in the Modular emit path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the former rlc-common module's live code out of the vestigial rlc-common/ folder: naming/model helpers to src/utils, the client model interfaces to src/interfaces.ts, and the metadata/test scaffolding builders to src/metadata. Drop the barrel; callers import from the new homes directly. No symbol renames or behavior change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Relocate the former test-next/unit/rlc-common tests alongside the code they exercise: helper tests to test-next/unit/utils and metadata/test builder tests to test-next/unit/metadata. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pass 2) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The client code model is only consumed by metadata generation, not by modular source generation. Move buildClientCodeModels() to be owned by generateMetadataAndTest(), make it a pure function, and relocate the generateSample baseline reset out of transformClientModel() so the two phases no longer have a hidden ordering dependency. Also removes the dead serviceNameToClientModelsMap/needUnexpectedHelper maps. Works toward Azure/autorest.typescript#2726. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GenerationDirDetail carried both sourcesDir and modularSourcesDir, which were always assigned the same value - a leftover from when RLC and modular emitted to separate directories. Unify on a single sourcesDir field. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Modular is the only generation mode, so the qualifier added no signal on index.ts-local names. Renames generateModularSources -> generateSources and modularSourcesRoot -> sourcesRoot, and drops the vestigial "for modular packages" framing from a comment. Shared Modular* types are intentionally left untouched: dropping "modular" there would collide with EmitterOptions and ClientOptions, which are genuinely distinct concepts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The type carries a per-sub-client path/name descriptor (subfolder, clientName) and is unrelated to the ClientOptions resolved-options bag despite the similar name. Rename it and its producer getModularClientOptions -> getClientModuleInfo (and the local var) so the name reflects what it actually models. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old guide predated the move into typespec-azure and described the defunct RLC generator: wrong clone URL, nonexistent test suites/scripts, dead start-test-server/smoke-test flows, and VS Code launch profiles that no longer exist. Rewrite it around the actual monorepo setup (submodule init, pnpm filtered build), the three vitest projects, the spector generate -> check:tree pipeline, and the real Debug Current Test File profile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
README documented an option as applying "in RLC"; lib.ts already dropped that qualifier, so align the README. Also remove the stale "experimental" descriptor from the README tagline and the package.json description -- this is the production Azure TypeScript emitter, not an experiment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This option only ever influenced the transform/client-code-model (RLC lineage) serialization path -- it was read solely by getSpecialSerializeInfo and getParameterSerializationInfo, both reached only from transform/*. The modular query-collection serialization goes through getCollectionFormatHelper, which never consulted the flag. With RLC output gone the option is dead, and no spec/SDK repo sets it. Remove the option (lib.ts interface + schema, ClientOptions field) and the now-dead branches. Its default was false, so getHasMultiCollection collapses to header-only multi and the parameter-utils union fallback drops -- both identical to prior default behavior, making this output-neutral. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
All changed packages have been documented.
Show changes
|
commit: |
⚡ Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 604.5ms | 🔴 605.8ms | +0.2% |
| loader | 🟢 193.4ms | 🟢 178.8ms | -7.5% 🟢 |
| resolver | 🟢 18.7ms | 🟢 18.2ms | -2.8% |
| checker | 🟢 186.1ms | 🟢 187.0ms | +0.5% |
| validation | 🟢 44.9ms | 🟢 44.2ms | -1.7% |
| ↳ validation/@azure-tools/typespec-azure-core | 🟢 6.5ms | 🟢 6.4ms | -2.5% |
| ↳ validation/@typespec/http | 🟢 5.4ms | 🟢 5.4ms | +0.8% |
| ↳ validation/@typespec/rest | 🟢 0.6ms | 🟢 0.6ms | -0.8% |
| ↳ validation/@typespec/versioning | 🔴 30.7ms | 🔴 29.3ms | -4.6% |
| ↳ validation/compiler | 🟢 1.7ms | 🟢 1.7ms | +0.2% |
| linter | 🟢 131.3ms | 🟢 139.3ms | +6.1% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.0ms | 🟢 0.0ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-core/bad-record-type | 🟢 0.2ms | 🟢 0.2ms | +4.5% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🟢 5.9ms | 🟢 5.7ms | -3.3% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 0.6ms | 🟢 0.6ms | -2.5% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 0.1ms | 🟢 0.1ms | +13.0% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟢 0.8ms | 🟢 0.9ms | +0.3% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟢 0.6ms | 🟢 0.6ms | -1.9% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 0.2ms | 🟢 0.2ms | +3.4% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 0.3ms | 🟢 0.3ms | +15.4% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 0.3ms | 🟢 0.3ms | +1.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 0.2ms | 🟢 0.2ms | +2.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 0.3ms | 🟢 0.3ms | +0.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.0ms | 🟢 0.0ms | +8.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 0.1ms | 🟢 0.1ms | +2.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 0.1ms | 🟢 0.1ms | +7.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 0.5ms | 🟢 0.5ms | +1.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 0.4ms | 🟢 0.4ms | +2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🟡 17.9ms | 🟡 19.0ms | +6.5% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🟢 1.2ms | 🟢 1.2ms | -1.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.1ms | 🟢 0.1ms | +2.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 0.2ms | 🟢 0.3ms | +7.0% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟢 1.2ms | 🟢 1.2ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🟢 1.9ms | 🟢 2.1ms | +10.0% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🟢 2.0ms | 🟢 2.0ms | -0.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🟡 19.6ms | 🟡 19.3ms | -1.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-response-body | 🔴 24.0ms | 🔴 23.5ms | -1.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces | 🟢 0.0ms | 🟢 0.0ms | +1.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch | 🟢 4.9ms | 🟢 5.6ms | +15.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 0.2ms | 🟢 0.2ms | -1.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.0ms | 🟢 0.0ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 0.2ms | 🟢 0.2ms | -0.7% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 0.4ms | 🟢 0.3ms | -0.9% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 0.2ms | 🟢 0.2ms | -5.3% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 0.3ms | 🟢 0.3ms | -6.8% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.0ms | 🟢 0.0ms | -6.4% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🔴 20.9ms | 🔴 22.4ms | +7.3% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.3ms | 🟢 0.3ms | +3.0% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 0.3ms | 🟢 0.3ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-names | 🟢 4.7ms | 🟢 5.6ms | +18.1% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations | 🟢 0.1ms | 🟢 0.1ms | +2.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources | 🟢 4.1ms | 🟢 4.3ms | +7.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations | 🟢 0.0ms | 🟢 0.0ms | +13.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🟢 4.0ms | 🟢 4.4ms | +9.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.1ms | 🟢 0.1ms | -2.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +3.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 1.0ms | 🟢 1.7ms | +71.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🟢 4.3ms | 🟢 5.0ms | +17.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 0.4ms | 🟢 0.3ms | -3.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 0.4ms | 🟢 0.5ms | +7.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.0ms | 🟢 0.0ms | +0.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 0.2ms | 🟢 0.2ms | +5.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 0.1ms | 🟢 0.1ms | +5.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.0ms | 🟢 0.0ms | +25.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 0.1ms | 🟢 0.1ms | +4.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.1ms | 🟢 0.1ms | +6.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.0ms | 🟢 0.0ms | +1.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 0.2ms | 🟢 0.2ms | +2.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.0ms | 🟢 0.0ms | -0.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 0.2ms | 🟢 0.2ms | +9.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🟢 4.4ms | 🟢 5.6ms | +27.5% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 0.3ms | 🟢 0.3ms | +7.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 0.2ms | 🟢 0.2ms | +8.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.1ms | 🟢 0.1ms | +7.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.1ms | 🟢 0.1ms | +5.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 0.2ms | 🟢 0.2ms | +3.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.0ms | 🟢 0.0ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🟡 15.1ms | 🟡 13.3ms | -12.1% 🟢 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.0ms | 🟢 0.0ms | -1.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 0.3ms | 🟢 0.3ms | +1.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.1ms | 🟢 0.1ms | +9.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props | 🟢 0.1ms | 🟢 0.1ms | -6.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 0.2ms | 🟢 0.2ms | +11.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🟡 19.6ms | 🟡 19.7ms | +0.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 0.1ms | 🟢 0.2ms | +11.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 0.2ms | 🟢 0.1ms | -2.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🟢 2.4ms | 🟢 2.8ms | +18.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 0.4ms | 🟢 0.4ms | +0.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.0ms | 🟢 0.0ms | +1.3% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🟢 1.1ms | 🟢 1.3ms | +19.4% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 0.2ms | 🟢 0.2ms | -5.0% |
| emit | 🔴 5.50s | 🔴 5.48s | -0.3% |
| ↳ emit/@azure-tools/typespec-autorest | 🟢 158.4ms | 🟢 159.4ms | +0.6% |
| ↳ emit/@azure-tools/typespec-python | 🔴 4.17s | 🔴 4.18s | +0.1% |
| ↳ emit/@typespec/http-client-js | 🔴 1.02s | 🔴 953.1ms | -6.2% 🟢 |
| ↳ emit/@typespec/openapi3 | 🟢 145.0ms | 🟢 145.3ms | +0.2% |
| ↳ emit/@typespec/openapi3/compute | 🟢 127.3ms | 🟢 124.2ms | -2.4% |
| ↳ emit/@typespec/openapi3/write | 🟢 17.3ms | 🟢 20.9ms | +20.7% 🔴 |
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)
|
You can try these changes here
|
Run prettier --write across files touched by the rlc-common cleanup and de-RLC rename passes. The relocation appended/modified imports that prettier's import-sort plugin reorders and re-wraps; this brings them in line so `prettier . --check` (CI format job) passes. Formatting-only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run `pnpm regen-docs` so the website reference reflects the removed `compatibility-query-multi-format` emitter option and the dropped "experimental" framing in the emitter description. The Website CI job regenerates these docs during validation and fails on any drift. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolves the rename+modify conflict GitHub flagged: main's `use-tslib-catalog-monorepo` fix edited build-azure-monorepo-package.ts at its old src/rlc-common/... path, while this branch relocated that file to src/metadata/package-json/. Git rename detection carried main's `tslib: "catalog:"` change into the relocated file. Also picks up the core submodule bump (ae88584 -> 924435b) and main's changeset. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
What & why
The
typespec-tsemitter still carried a large amount of vestigial debt from the now-defunct RLC (Rest Level Client) generator, even though it only emits Modular clients today. This PR pays that debt down and refreshes the docs. The work is internal/refactor + docs only — no change to generated output (proven viacheck:tree, see below).Works toward and closes Azure/autorest.typescript#2726.
Changes
rlc-common cleanup
rlc-commoncode (static helpers, karma config) and relocate the live code into logical homes in the main source tree; move the associated unit tests to mirror the new layout.De-RLC naming
RLCModel→ClientModel), discriminants, context keys, and comments —srcis now free ofrlc/RLCtokens.ModularClientOptions→ClientModuleInfo(+getModularClientOptions→getClientModuleInfo): it's a per-sub-client path/name descriptor, unrelated to theClientOptionsresolved-options bag despite the old name.Structural decoupling (Azure/autorest.typescript#2726)
buildClientCodeModelsis now a pure function owned by metadata generation, and the hiddengenerateSampleordering side-effect was relocated.modularSourcesDirintosourcesDir.modularqualifier fromindex.ts-local names now that modular is the only mode (sharedModular*types intentionally kept — dropping "modular" there would collide withEmitterOptions/ClientOptions).Dead option removal
compatibility-query-multi-formatemitter option. It only ever influenced the transform/client-code-model (RLC lineage) path and was never consulted by modular serialization; its default wasfalse, so removal is output-neutral.Docs
CONTRIBUTING.mdfor current reality (correct repo URL + submodule init, real vitest projects/scripts, the spectorgenerate → check:treepipeline, valid debug profile).README.mdand drop the stale "experimental" framing from the README tagline andpackage.jsondescription.Verification
pnpm build✓,pnpm lint(--max-warnings=0) ✓pnpm test-next(244) ✓,pnpm unit-test(657) ✓copy:typespec→generate-tsp-only→check:tree— passes with a clean tree, proving zero generated-output drift across all the refactors.