Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,16 @@ export class DifferenceDetector {
});
}

// Filters out class property removals that are "by design" in HLC -> Modular migration.
// A removed property is considered non-breaking when it is still accessible via constructor
// signatures in the Modular client, either as:
// Filters out class property removals that are "by design" when a property is no longer
// a public class member but is still accessible via the current client's constructor
// signatures. This is applied to every SDK transition (not just HLC -> Modular), because
// the baseline SDK type detected from a downloaded npm package can be unreliable, and the
// constructor-based check below is sufficient on its own to decide whether the removal is
// non-breaking. A removed property is considered non-breaking when it is still accessible as:
// 1. The constructor parameter name itself (e.g. subscriptionId)
// 2. A property on the constructor parameter type (e.g. options?: XxxOptionalParams
// exposing apiVersion, cloudSetting, etc.)
private filterClassPropertiesMovedToInternals(v: DiffPair[], className: string): DiffPair[] {
Comment thread
skywing918 marked this conversation as resolved.
const isHlcToModular =
this.baselineApiViewOptions.sdkType === SDKType.HighLevelClient &&
this.currentApiViewOptions.sdkType === SDKType.ModularClient;
if (!isHlcToModular) return v;

const currentClass = this.context!.current.getClass(className);
if (!currentClass) return v;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,59 @@ export interface ResourceManagementClientOptionalParams extends ClientOptions {
expect(items[0]).toBe('Class ResourceManagementClient no longer has parameter tagsOperations');
});

test('Class Property Removed that remains a constructor parameter is filtered regardless of SDK type', async () => {
// The HLC -> Modular guard was removed from filterClassPropertiesMovedToInternals,
// so properties that are still accessible via constructor signatures are filtered
// for ANY transition. This case uses Modular -> Modular to prove the filtering is
// no longer tied to the HLC -> Modular transition.
const baselineApiView = `
\`\`\`ts
// @public
export class DataProductClient {
constructor(credential: TokenCredential, subscriptionId: string, options?: DataProductClientOptionalParams);
subscriptionId: string;
readonly dataProducts: DataProducts;
readonly analytics: Analytics;
}

// @public
export interface DataProductClientOptionalParams extends ClientOptions {
apiVersion?: string;
}
\`\`\`
`;
// subscriptionId — filtered because it is still a direct constructor parameter
// apiVersion — not present as a property here, but exposed via the options bag
// analytics — BREAKING: genuinely removed, must still be reported
const currentApiView = `
\`\`\`ts
// @public
export class DataProductClient {
constructor(credential: TokenCredential, subscriptionId: string, options?: DataProductClientOptionalParams);
readonly dataProducts: DataProducts;
}

// @public
export interface DataProductClientOptionalParams extends ClientOptions {
apiVersion?: string;
}
\`\`\`
`;
const changelogItems = await generateChangelogItems(
{
apiView: baselineApiView,
sdkType: SDKType.ModularClient,
},
{
apiView: currentApiView,
sdkType: SDKType.ModularClient,
}
);
const items = getItemsByCategory(changelogItems, ChangelogItemCategory.ClassPropertyRemoved);
expect(items).toHaveLength(1);
expect(items[0]).toBe('Class DataProductClient no longer has parameter analytics');
});

test('Class Property Optional To Required', async () => {
const baselineApiView = `
\`\`\`ts
Expand Down