Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TCGC]: SdkCredentialParameter should be limited to SdkCredentialType #1274

Open
4 tasks done
MaryGao opened this issue Jul 31, 2024 · 7 comments
Open
4 tasks done

[TCGC]: SdkCredentialParameter should be limited to SdkCredentialType #1274

MaryGao opened this issue Jul 31, 2024 · 7 comments
Assignees
Labels
lib:tcgc Issues for @azure-tools/typespec-client-generator-core library

Comments

@MaryGao
Copy link
Contributor

MaryGao commented Jul 31, 2024

Request Change

Here is the definition of SdkCredentialParameter and it contains a union of SdkUnionType which will not be scoped into credential kind. But in fact any detailed type of crednetial parameter should be credential kind. When traversing the union items we need to castcade to SdkCredentialType.

export interface SdkCredentialParameter extends SdkModelPropertyTypeBase {
  kind: "credential";
  type: SdkCredentialType | SdkUnionType; // union of credentials
  onClient: true;
}

Proposal

So my proposal is we could make SdkUnionType generic. And then in SdkCredentialParameter we could pass SdkCredentialType in union type.

export interface SdkCredentialParameter extends SdkModelPropertyTypeBase {
  kind: "credential";
  type: SdkCredentialType | SdkUnionType<SdkCredentialType>; // union of credentials
  onClient: true;
}

export interface SdkUnionType<ValueType extends SdkType = SdkType> extends SdkTypeBase {
  name: string;
  isGeneratedName: boolean;
  kind: "union";
  values: ValueType[];
  crossLanguageDefinitionId: string;
}

With this change we could better narrow down the type info with credential only. But please note this would be a breaking change for emitters.

declare const credentialParam: SdkCredentialParameter;
if (credentialParam.type.kind === "union") {
  for (const auth of credentialParam.type.values) {
    switch (auth.scheme.type) {
      case "http":
        // ...
        break;
      case "apiKey":
      // ...
    }
  }
}

Checklist

  • Follow our Code of Conduct
  • Check that this issue is about the Azure libraries for typespec. For bug in the typespec language or core libraries file it in the TypeSpec repo
  • Check that there isn't already an issue that request the same bug to avoid creating a duplicate.
  • The provided reproduction is a minimal reproducible example of the bug.
@MaryGao MaryGao added the bug Something isn't working label Jul 31, 2024
@MaryGao MaryGao changed the title [TCGC][Bug]: SdkCredentialParameter should be limited to SdkCredentialType [TCGC]: SdkCredentialParameter should be limited to SdkCredentialType Jul 31, 2024
@MaryGao MaryGao added lib:tcgc Issues for @azure-tools/typespec-client-generator-core library and removed bug Something isn't working needs-area labels Jul 31, 2024
@ArcturusZhang
Copy link
Member

So the generic parameter here for union type is providing the lower boundary of those type variants, I cannot say I like it because in majority of cases, it is not really helpful.

I kind of like a solution that we update the SdkCredentialType itself so that, the type of this parameter is just simply SdkCredentialType, and the SdkCredentialType itself could represent that we have multiple choices and which are them.
Such as:

export interface SdkCredentialParameter extends SdkModelPropertyTypeBase {
  kind: "credential";
  type: SdkCredentialType;
  onClient: true;
}

export interface SdkCredentialType extends SdkTypeBase {
  kind: "credential";
  supportedSchemes: HttpAuth[];
}

It is a bigger breaking change, but I think this makes more sense.

@MaryGao

This comment was marked as outdated.

@MaryGao
Copy link
Contributor Author

MaryGao commented Aug 1, 2024

Here we have two options:
Option 1

export interface SdkCredentialParameter extends SdkModelPropertyTypeBase {
  kind: "credential";
  type: SdkCredentialType | SdkUnionType<SdkCredentialType>; // union of credentials
  onClient: true;
}

Option 2

export interface SdkCredentialType extends SdkTypeBase {
  kind: "credential";
  supportedSchemes: HttpAuth[];
}

As we offline discussed Option 1 could better present the client type for credential information(credential is either a credential or a union of credentials). And Option 2 would explicitly present credential type but with implicit union meaning here, it is a list of supported schemas.

So personally I would vote for Option 1 for a clear type information.

@tadelesh @iscai-msft I notice we also talked about the endpoint parameter changes not sure there is similar issue with credential parameter. I'd like to hear your insight.

@iscai-msft
Copy link
Contributor

@MaryGao I like option 1 as well. I think we can type the SdkUnionType as SdkUnionType<T1, ..., Tn> to represent a union with the item types T1, …, Tn. You don't need an entry for every single value in SdkUnionType, just one for each possible type.

@ArcturusZhang
Copy link
Member

@MaryGao I like option 1 as well. I think we can type the SdkUnionType as SdkUnionType<T1, ..., Tn> to represent a union with the item types T1, …, Tn. You don't need an entry for every single value in SdkUnionType, just one for each possible type.

So SdkUnionType does not have a value, I assume you are referring values (which I believe is a really bad name, they are not values).
Even if you are doing this, we must have values.
For instance, even for built-in types, each instance of SdkBuiltInType with a specific kind could be totally different types, such as we have a union of SdkUnionType<SdkBuiltInType, SdkBuiltInType> from the spec:

model Foo
{
	prop: string | azureLocation;
}

in the values we have:

kind: "union"
values: [
{
"kind": "string",
"crossLanguageDefinitionId": "TypeSpec.string", // this represent it is string
},
{
"kind": "string",
"crossLanguageDefinitionId": "Azure.Core.azureLocation" // this is azure location
}
]

Or you could think how the type A | B below looks like:

model Foo
{
prop: A | B;
}
model A {}
model B {}

The generic parameter helps, but we still cannot remove the values.

@MaryGao
Copy link
Contributor Author

MaryGao commented Aug 2, 2024

@iscai-msft Could you expand your idea of SdkUnionType<T1, ..., Tn> a little? I may be not aware that we have features to spread generic arugements(see issues).

Back to Option 1, if we have possible values with SdkCredentialType or SdkEndpointType we may use | like SdkUnionType<SdkCredentialType | SdkEndpointType>.

@iscai-msft
Copy link
Contributor

In SdkUnionType we would list the possible types that .values could be. This follows your options 1, it just expands it to also allow for multiple types.

model MyModel {
  prop: string[] | string;
}

Would result in an SdkUnionType<Array<string>, string>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib:tcgc Issues for @azure-tools/typespec-client-generator-core library
Projects
None yet
Development

No branches or pull requests

4 participants