How to use AllowedFilterProperties and AllowedExpandProperties under ODataQueryOptionDescriptionContext

Is there an existing issue for this?

[X] I have searched the existing issues

Describe the bug
Not sure it is a bug or not. But I have scenario that we only have limit properties can be used as expand and filter and would like to show as description in Swagger. I saw ODataQueryOptionDescriptionContext exposes AllowedFilterProperties  and AllowedExpandProperties, since we only can set max depth and max node.
options.QueryOptions.Controller()
.Action( c => c.Get( default ) )
.Allow( Filter | Expand )
.AllowExpand( 2 )
.AllowFilter( 4 );
Would you mind to give any suggestions how I can use these two properties?
Expected Behavior
Having a way to use AllowedFilterProperties and AllowedExpandProperties.
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
7.0.100
Anything else?
No response

For an example of how to use the ODataQueryOptionDescriptionContext, you can have a look at: DefaultODataQueryOptionDescriptionProvider. The default provider can be extended or replaced and configured via:
builder.Services
       .AddApiVersioning()
       .AddOData()
       .AddODataApiExplorer(options => options.DescriptionProvider = new MyProvider());

However, I think you are asking how do you set or otherwise populate AllowedFilterProperties and AllowedExpandProperties. This is a good question and it clearly is not all that obvious (but it's supposed to be).
A key goal is to minimize the amount of configuration required and use what you've already defined to populate the query options. The cases where you can explicitly set conventions are only meant to cover the documentation gaps where you can't otherwise specify the information. As an example, if you used ODataQuerySettings and ODataValidationSettings directly in a controller action, there is no other way to surface this information. These classes do not have a way to limit $filter or $expand property names, which is why you can't find a built-in extension method convention for them.
The way these values are specified is via Model Bound settings. They are configured as attributes on your model classes or set
using the fluent conventions when you configure the EDM. This is required for OData to enforce the policies. The API Versioning extensions are of aware of this and will pick them up and document them for you. It might seem clunky, but it would be weird (and bad) if a limited set of properties were specified in the documentation, but they weren't actually limited by OData. Most settings can be configured multiple ways, but this happens to be some that can only be done this way (unless I've made a mistake or things have changed).
For example, you can apply:
[Expand("NoExpand", ExpandType = SelectExpandType.Disabled)]

To disable expand on an entire type, enable selective members, and set maximum depth. If you don't want to use attributes, you can use the fluent API a la:
builder.EntitySet<Order>("Orders")
                .EntityType.Expand(6)
                .Expand(SelectExpandType.Disabled, "NoExpand");

No matter which approach you choose, the API Versioning extensions should detect it. If there's something I've missed or there's some other method you're using that I'm not aware of, please. share.

The problem for us is our service want to just use a set of OData query ability rather than being an fully OData service, so we don't  create EDM model and register when service is up. By looking at the source code, I think the easiest way is to extend DefaultODataQueryOptionDescriptionProvider and base on the ApiDescription under ODataQueryOptionDescriptionContext to set limit properties for each controller and action, otherwise need to rewrite entire ODataControllerQueryOptionsConventionBuilder and ODataActionQueryOptionsConventionBuilder(with T also).

I see. You probably should have led with that. 😉 Things work a little different with some OData.
There are still a few options:

Create and add a custom IODataQueryOptionsConvention, which can be added to the default builder
Extend/customize the default ODataQueryOptionsConventionBuilder
Extend/customize the DefaultODataQueryOptionDescriptionProvider

The ODataQueryOptionDescriptionContext is ultimately just a monad to collect all the discovered information from standard OData attributes and settings. There isn't anything that special about it. If you have your own convention or you know what you're looking for (in your own code), then it's pretty straight forward to add the necessary ApiParameterDescription instances. For example, you could create your own attribute that you know to look for (ex: [AllowedProperties("...")]).
Admittedly, there is limited support for some OData. This is an area could use some additional enhancements.

For the options you mentioned:

I though about to build my own ODataValidationSettingsConvention which is inherited from IODataQueryOptionsConvention, but if I do that, I need to write my own ODataActionQueryOptionsConventionBuilder and override the Build method from base class ODataActionQueryOptionsConventionBuilderBase. Would you mind to let me know how to add to the default builder?

Yeap, as I mentioned by using ApiDescription, I will add attribute and use attribute to control it. The other approach I can think is by using Swagger OperationFilter with parameter and attribute to edit description.

I haven't tried it E2E, but something like this should work:
Provide some way to define allowed properties. Attributes are one way.
[AttributeUsage( AttributeTargets.Method, AllowMultiple = false, Inherited = true )]
internal sealed class AllowedPropertiesAttribute : Attribute
{
   public AllowedPropertiesAttribute( string property, params string[] otherProperties )
   {
      var properties = new string[otherProperties.Length + 1];

      properties[0] = property;

      if ( otherProperties.Length > 0 )
      {
         Array.Copy( otherProperties, 0, properties, 1, otherProperties.Length );
      }

      Properties = properties;
   }

   public IReadOnlyList Properties { get; }
}

There's a few ways this might be used. Something like:
[EnableQuery(AllowedQueryOptions = AllowQueryOptions.Expand)]
[AllowedProperties("customer", "lineItems")]
public IActionResult Get(int id) => Ok();

Now you can create a convention that looks like:
internal sealed class AllowedPropertiesConvention : IODataQueryOptionsConvention
{
   private readonly ODataQueryOptionSettings settings;

   public AllowedPropertiesConvention(
      IODataQueryOptionDescriptionProvider descriptionProvider,
      IModelMetadataProvider modelMetadataProvider,
      ODataOptions option )
   {
      settings = new()
      {
         NoDollarPrefix = true,
         DescriptionProvider = descriptionProvider,
         DefaultQuerySettings = options.QuerySettings,
         ModelMetadataProvider = modelMetadataProvider,
      }
   }

   public void ApplyTo( ApiDescription apiDescription )
   {
      // applying the convention as endpoint metadata is probably a better way to do this
      // but it requires more initial setup
      var method = ((ControllerActionDescriptor) apiDescription.ActionDescriptor).MethodInfo;
      var enableQuery = method.GetCustomAttribute<EnableQueryAttribute>();
      var allowed = method.GetCustomAttribute<AllowedPropertiesAttribute>();

      if ( enableQuery == null || allowed == null )
      {
         return;
      }

      var queryOption = enableQuery.AllowedQueryOptions;

      switch ( enableQuery.AllowedQueryOptions )
      {
         case AllowedQueryOptions.Expand:
         case AllowedQueryOptions.Filter:
            break;
         default:
            return;
      }

      var context = new ODataQueryOptionDescriptionContext( apiDescription );

      for ( var i = 0; i < allowed.Properties.Count; i++ )
      {
         context.AllowedProperties.Add( allowed.Properites[i] );
      }

      var name = ( settings.NoDollarPrefix ? string.Empty : "$" ) +
                 option.ToString().ToLowerInvariant();
      var type = typeof( string );
      var description = settings.DescriptionProvider.Describe( queryOption, context );
      var parameter = new ApiParameterDescription()
      {
            IsRequired = false,
            ModelMetadata = new ODataQueryOptionModelMetadata(
                settings.ModelMetadataProvider,
                type,
                description ),
            Name = name,
            ParameterDescriptor = new()
            {
                Name = name,
                ParameterType = type,
            },
            Source = BindingSource.Query,
            Type = type,
        };

      apiDescription.Parameters.Add( parameter );
   }
}

Finally, since DI is needed to get some of the services to build out the convention, we need IConfigureOptions<T>:
public sealed class ODataConventionSetup : IConfigureOptions<ODataApiExplorerOptions>
{
   private readonly IModelMetadataProvider modelMetadataProvider;
   private readonly IOptions<ODataOptions> odataOptions;

   public ODataConventionSetup(
      IModelMetadataProvider modelMetadataProvider,
      IOptions<ODataOptions> odataOptions )
   {
      this.modelMetadataProvider = modelMetadataProvider;
      this.odataOptions = odataOptions;
   }

   public void Configure( ODataApiExplorerOptions options )
   {
      var convention = new AllowedPropertiesConvention(
         options.DescriptionProvider,
         modelMetadataProvider,
         odataOptions );

      options.QueryOptions.Add( convention );
   }
}

This might seem like a lot of ceremony, but the challenge is trying to add a convention where no convention exists. As I mentioned the existing functionality for the fluent conventions API is to have parity with ODataQuerySettings and ODataValidationSettings. Neither of these have a way to specify the properties allowed with $expand or $filter. I'm not opposed to supporting it as an enhancement, but it's not there today.
Another possible option is to use the current, albeit limited, support for $expand and $filter conventions and update the description after the parameter is added with the additional properties. Of course, you could go down the Swashbuckle or OpenAPI extensions, but you'll have many of the same challenges.
Hopefully that give you a few ideas.

Yes, you could create a EDM just for the purposes of metadata. It would have no effect on the surface area of the API. You need to have the OData services and features enabled change the wire protocol. I haven't tried it, but it should be possible to use the EDM just to provide this documentation.

I haven't tried it E2E, but something like this should work:
Provide some way to define allowed properties. Attributes are one way.
[AttributeUsage( AttributeTargets.Method, AllowMultiple = false, Inherited = true )]
internal sealed class AllowedPropertiesAttribute : Attribute
{
   public AllowedPropertiesAttribute( string property, params string[] otherProperties )
   {
      var properties = new string[otherProperties.Length + 1];

      properties[0] = property;

      if ( otherProperties.Length > 0 )
      {
         Array.Copy( otherProperties, 0, properties, 1, otherProperties.Length );
      }

      Properties = properties;
   }

   public IReadOnlyList Properties { get; }
}

There's a few ways this might be used. Something like:
[EnableQuery(AllowedQueryOptions = AllowQueryOptions.Expand)]
[AllowedProperties("customer", "lineItems")]
public IActionResult Get(int id) => Ok();

Now you can create a convention that looks like:
internal sealed class AllowedPropertiesConvention : IODataQueryOptionsConvention
{
   private readonly ODataQueryOptionSettings settings;

   public AllowedPropertiesConvention(
      IODataQueryOptionDescriptionProvider descriptionProvider,
      IModelMetadataProvider modelMetadataProvider,
      ODataOptions option )
   {
      settings = new()
      {
         NoDollarPrefix = true,
         DescriptionProvider = descriptionProvider,
         DefaultQuerySettings = options.QuerySettings,
         ModelMetadataProvider = modelMetadataProvider,
      }
   }

   public void ApplyTo( ApiDescription apiDescription )
   {
      // applying the convention as endpoint metadata is probably a better way to do this
      // but it requires more initial setup
      var method = ((ControllerActionDescriptor) apiDescription.ActionDescriptor).MethodInfo;
      var enableQuery = method.GetCustomAttribute<EnableQueryAttribute>();
      var allowed = method.GetCustomAttribute<AllowedPropertiesAttribute>();

      if ( enableQuery == null || allowed == null )
      {
         return;
      }

      var queryOption = enableQuery.AllowedQueryOptions;

      switch ( enableQuery.AllowedQueryOptions )
      {
         case AllowedQueryOptions.Expand:
         case AllowedQueryOptions.Filter:
            break;
         default:
            return;
      }

      var context = new ODataQueryOptionDescriptionContext( apiDescription );

      for ( var i = 0; i < allowed.Properties.Count; i++ )
      {
         context.AllowedProperties.Add( allowed.Properites[i] );
      }

      var name = ( settings.NoDollarPrefix ? string.Empty : "$" ) +
                 option.ToString().ToLowerInvariant();
      var type = typeof( string );
      var description = settings.DescriptionProvider.Describe( queryOption, context );
      var parameter = new ApiParameterDescription()
      {
            IsRequired = false,
            ModelMetadata = new ODataQueryOptionModelMetadata(
                settings.ModelMetadataProvider,
                type,
                description ),
            Name = name,
            ParameterDescriptor = new()
            {
                Name = name,
                ParameterType = type,
            },
            Source = BindingSource.Query,
            Type = type,
        };

      apiDescription.Parameters.Add( parameter );
   }
}

Finally, since DI is needed to get some of the services to build out the convention, we need IConfigureOptions<T>:
public sealed class ODataConventionSetup : IConfigureOptions<ODataApiExplorerOptions>
{
   private readonly IModelMetadataProvider modelMetadataProvider;
   private readonly IOptions<ODataOptions> odataOptions;

   public ODataConventionSetup(
      IModelMetadataProvider modelMetadataProvider,
      IOptions<ODataOptions> odataOptions )
   {
      this.modelMetadataProvider = modelMetadataProvider;
      this.odataOptions = odataOptions;
   }

   public void Configure( ODataApiExplorerOptions options )
   {
      var convention = new AllowedPropertiesConvention(
         options.DescriptionProvider,
         modelMetadataProvider,
         odataOptions );

      options.QueryOptions.Add( convention );
   }
}

This might seem like a lot of ceremony, but the challenge is trying to add a convention where no convention exists. As I mentioned the existing functionality for the fluent conventions API is to have parity with ODataQuerySettings and ODataValidationSettings. Neither of these have a way to specify the properties allowed with $expand or $filter. I'm not opposed to supporting it as an enhancement, but it's not there today.
Another possible option is to use the current, albeit limited, support for $expand and $filter conventions and update the description after the parameter is added with the additional properties. Of course, you could go down the Swashbuckle or OpenAPI extensions, but you'll have many of the same challenges.
Hopefully that give you a few ideas.

Thanks very much @commonsensesoftware, I tried to extend DefaultODataQueryOptionDescriptionProvider with attribute approach, it works perfectly, I will try to use this approach also.

I'm interested in hearing about the challenges and extension points you need[ed] when you get to a working state when you're done. Supporting  partial OData features has been an area I've been wanting to continue improving. There used to be virtually no support at all. Since there isn't an EDM or even necessarily attributes for metadata to discover things from, I suspect it will all have to be by custom conventions. I'd support enhancing what's possible today to make it easier for folks, like yourself.

Yes, you could create a EDM just for the purposes of metadata. It would have no effect on the surface area of the API. You need to have the OData services and features enabled change the wire protocol. I haven't tried it, but it should be possible to use the EDM just to provide this documentation.

I just had conversation with Sam Xu, he suggested we can use SelectorModel to build an EDM and register into its EndpointMetadata as different metadata (Maybe called FlightODataModelMetadata), so when ODataQueryOptionDescriptionContext try to get model, it can get this metadata from the actionDescriptor's EndpointMetadata. But in order to achieve this, we need to build our own ODataQueryOptionDescriptionContext and write a convention by ourself like the sample you mentioned above, is my assumption correct or there is better way to customize this.

That sounds like something Sam would suggest.
That approach could be made to work. API Versioning doesn't specifically care about the SelectorModel. At the end of the day, you just need an EDM associated with the Endpoint (a la the metadata):

API Versioning is looking for IODataRoutingMetadata in the endpoint metadata.
a. This could be any implementation; it doesn't need to be an OData one
b. Only the Model property is used/considered
API Versioning uses and expects one EDM per API version
a. That can be a little tedious, the VersionedODataModelBuilder may help there
b. The constructed IEdmModel must have the ApiVersionAnnotation applied
i. That's how API Versioning will match up the current API version with the correct EDM
ii. Each EDM an only have this annotation applied once; hence, you need one EDM per API version
iii. If you have endpoint that services more than one API version, then you need multiple IODataRoutingMetadata instances
The metadata can be applied via:
a. IApplicationModelProvider
b. IControllerModelProvider
c. IActionModelProvider

You add the metadata via a SelectModel, but you only need one. You might have extension that looks something like this:
    internal static void AddEndpointMetadata( this ActionModel action, object metadata )
    {
        var selectors = action.Selectors;

        if ( selectors.Count == 0 )
        {
            selectors.Add( new() );
        }

        for ( var i = 0; i < selectors.Count; i++ )
        {
            selectors[i].EndpointMetadata.Add( metadata );
        }
    }

Which is how API Versioning adds ApiVersionMetadata.
If you're able to connect the pieces this way and then apply the conventions via ODataModelBuilder or Model Bound attributes (which get picked up in GetEdm()), then I think this approach should work.

It's pretty yucky, but here's a working baseline that you should be able to build off of. I was able to get this to show a restricted $filter property using the Some OData OpenAPI Example. This will require API Versioning 6.3.1+ or 7.0.0-rc1.+.
This approach uses IApiDescriptionProvider, which should only affect the API Explorer. The necessary metadata to document the OData query options are temporarily added prior to exploration and then subsequently removed. This should guarantee zero chance of affecting the routing process and also prevents frivolous allocated memory from hanging around for no reason.
You have to do the following:

Collate all API versions (this is probably also possible through the IApiVersionDescriptionProvider service)
Create a VersionedODataModelBuilder that will be based on each API version
a. This sample uses a simple, default callback, but you probably want separate methods or use IModelConfiguration
Before exploration, for every action where the API version of the EDM applies, add the EDM as metadata to the endpoint
After exploration, remove the EDM metadata added; it's not needed for anything else

There may be some other oddities in the mix somewhere. The Metadata and Service Document endpoints have special handling. You have construct routing info that will not match that. It can be virtually anything (as seen below).
Register it with:
builder.Services.TryAddEnumerable(
    ServiceDescriptor.Transient<IApiDescriptionProvider, AdHocModelBoundSettingsProvider>() );

The magic 🧙🏽 ...
using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
using Asp.Versioning.OData;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.OData.Routing;
using Microsoft.AspNetCore.OData.Routing.Template;
using Microsoft.Extensions.Options;
using Microsoft.OData.Edm;
using Microsoft.OData.UriParser;
using static Asp.Versioning.ApiVersionMapping;

public class AdHocModelBoundSettingsProvider : IApiDescriptionProvider
{
    private const int Last = int.MaxValue;
    private readonly VersionedODataModelBuilder builder;

    public AdHocModelBoundSettingsProvider(
        IEnumerable<IApiVersionMetadataCollationProvider> providers,
        IOptions<ApiVersioningOptions> options )
    {
        // a single, simple, inline configuration for all versions.
        // a separate function or IModelConfiguration registrations
        // are probably better here
        builder = new(
            CollateApiVersions( providers.ToArray(), options ),
            Enumerable.Empty<IModelConfiguration>() )
        {
            DefaultModelConfiguration = ( modelBuilder, apiVersion, routePrefix ) =>
            {
                modelBuilder.EntitySet<Book>( "Books" )
                            .EntityType.Filter( "author" );
            }
        };
    }

    public int Order => Last;

    public void OnProvidersExecuting( ApiDescriptionProviderContext context )
    {
        // 1. build edm for each api version (handled by builder)
        // 2. for each action and edm:
        //    a. get action api version metadata
        //    b. get edm api version
        //    c. if edm api version applies to action, add it
        var models = builder.GetEdmModels();
        var actions = context.Actions;

        for ( var i = 0; i < actions.Count; i++ )
        {
            var action = actions[i];
            var metadata = action.GetApiVersionMetadata();

            for ( var j = 0; j < models.Count; j++ )
            {
                var model = models[j];
                var version = model.GetAnnotationValue<ApiVersionAnnotation>( model )?.ApiVersion;

                if ( metadata.IsMappedTo( version ) )
                {
                    action.EndpointMetadata.Add( new EdmMetadata( model ) );
                }
            }
        }
    }

    public void OnProvidersExecuted( ApiDescriptionProviderContext context )
    {
        // clear/remove temporary metadata we added for
        // exploration (e.g. no chance of affecting routing)
        var actions = context.Actions;

        for ( var i = 0; i < actions.Count; i++ )
        {
            var metadata = actions[i].EndpointMetadata;

            for ( var j = metadata.Count - 1; j >= 0; j-- )
            {
                if ( metadata[j] is IODataRoutingMetadata )
                {
                    metadata.Remove( j );
                }
            }
        }
    }

    private static ODataApiVersionCollectionProvider CollateApiVersions(
        IApiVersionMetadataCollationProvider[] providers,
        IOptions<ApiVersioningOptions> options )
    {
        var context = new ApiVersionMetadataCollationContext();

        for ( var i = 0; i < providers.Length; i++ )
        {
            providers[i].Execute( context );
        }

        var results = context.Results;
        var versions = new SortedSet<ApiVersion>();

        for ( var i = 0; i < results.Count; i++ )
        {
            var model = results[i].Map( Explicit | Implicit );
            var declared = model.DeclaredApiVersions;

            for ( var j = 0; j < declared.Count; j++ )
            {
                versions.Add( declared[j] );
            }
        }

        if ( versions.Count == 0 )
        {
            versions.Add( options.Value.DefaultApiVersion );
        }

        return new() { ApiVersions = versions.ToArray() };
    }

    private static void ApplyEdmMetadata( IList<ControllerModel> controllers, IReadOnlyList<IEdmModel> models )
    {
        for ( var i = 0; i < controllers.Count; i++ )
        {
            var actions = controllers[i].Actions;

            for ( var j = 0; j < actions.Count; j++ )
            {
                var action = actions[j];
                var metadata = action.Selectors
                                     .SelectMany( s => s.EndpointMetadata )
                                     .OfType<ApiVersionMetadata>()
                                     .FirstOrDefault();

                if ( metadata == null )
                {
                    continue;
                }

                for ( var k = 0; k < models.Count; k++ )
                {
                    var model = models[k];
                    var version = model.GetAnnotationValue<ApiVersionAnnotation>( model )?.ApiVersion;

                    if ( !metadata.IsMappedTo( version ) )
                    {
                        continue;
                    }

                    var selectors = action.Selectors;

                    for ( var l = 0; l < selectors.Count; l++ )
                    {
                        selectors[l].EndpointMetadata.Add( new EdmMetadata( model ) );
                    }
                }
            }
        }
    }

    private sealed class ODataApiVersionCollectionProvider : IODataApiVersionCollectionProvider
    {
        public IReadOnlyList<ApiVersion> ApiVersions { get; set; }
    }

    private sealed class EdmMetadata : IODataRoutingMetadata
    {
        // metadata (~/$metadata) and service (~/) doc have special handling.
        // make sure we don't match the service doc
        private readonly static ODataPathTemplate FakeODataTemplate =
            new( new DynamicSegmentTemplate( new DynamicPathSegment( "fake" ) ) );

        public EdmMetadata( IEdmModel model ) => Model = model;

        public string Prefix => string.Empty;

        public IEdmModel Model { get; }

        public ODataPathTemplate Template => FakeODataTemplate;

        public bool IsConventional => false;
    }
}

Having looked at it a couple of times, I think this is what a generic, comprehensive feature for partial OData uses would look like. I would have to detect if you registered AddODataApiExplorer without calling AddOData. IODataApiVersionCollectionProvider and VersionedODataModelBuilder aren't registed in DI otherwise. Furthermore, their registrations (as seen in the example) would be quite different from full OData.
Another edge case to be careful of would be mixture of some full OData and some partial OData. I think it may be possible these concepts to coexist. I already have some bits in there to detect if an action is OData-like, which is how/why exploration of OData query options for non-OData actions works at all.
I need to cogitate on this some more, but this is likely the general approach. This example illustrates how to apply the configuration, but how would a developer configure the EDM? Normally, this would be done via VersionedODataModelBuilder or IModelConfiguration that is picked up or exposed by DI. If both OData and non-OData actions coexist, how do you tell them apart? It might be a non-issue, but I have to think that through. If I can solve that, then you can configure your OData query options in the EDM just like other Model Bound settings. The fake, temporary EDM can be handled for you behind the scenes. 😉

Having looked at it a couple of times, I think this is what a generic, comprehensive feature for partial OData uses would look like. I would have to detect if you registered AddODataApiExplorer without calling AddOData. IODataApiVersionCollectionProvider and VersionedODataModelBuilder aren't registed in DI otherwise. Furthermore, their registrations (as seen in the example) would be quite different from full OData.
Another edge case to be careful of would be a mixture of some full OData and some partial OData. I think it may be possible for these concepts to coexist. I already have some bits in there to detect if an action is OData-like, which is how/why exploration of OData query options for non-OData actions works at all.
I need to cogitate on this some more, but this is likely the general approach. This example illustrates how to apply the configuration, but how would a developer configure the EDM? Normally, this would be done via VersionedODataModelBuilder or IModelConfiguration that is picked up or exposed by DI. If both OData and non-OData actions coexist, how do you tell them apart? It might be a non-issue, but I have to think that through. If I can solve that, then you can configure your OData query options in the EDM just like other Model Bound settings. The fake, temporary EDM can be handled for you behind the scenes. 😉

@commonsensesoftware, just want to confirm I added AddOData. I am currently trying to approach Sam Xu provided, I will check your approach also. Hopefully this weekend I can give you a summary of what I tried and give your suggestions.

Cool. To be clear, I made it work without AddOData. Since my example doesn't resolve any of the other OData-specific services from DI, it should still work if you called it. I look forward to hearing/seeing your findings.

Cool. To be clear, I made it work without IApiVersioningBuilder.AddOData. Since my example doesn't resolve any of the other OData-specific services from DI, it should still work if you called it. I look forward to hearing/seeing your findings.

@commonsensesoftware, one thing we figured out when looking at the source code for IApiVersioningBuilder.AddOData, underlying it will replace the origin IOptions with VersionedODataOptions.
services.Replace( Singleton<IOptions>( sp => sp.GetRequiredService() ) );
So the global setting .AddControllers().AddOData(opt =>opt.Filter().Expand()) will be gone. So if we add IApiVersioningBuilder.AddOData, it will not work and I guess the reason why the global setting is gone is due to we don't register EDM.

Not exactly, but kinda...
There's no other way to get in front of OData and the design simply isn't extensible - unfortunately. Since you didn't use AddOData and you don't have any true OData endpoints, I'm guessing the process is skipped. What you are looking for is here:
https://github.com/dotnet/aspnet-api-versioning/blob/0d1b9fa3ae13d5f51cc24546d55b583448212579/src/AspNetCore/OData/src/Asp.Versioning.OData/OData/ODataMultiModelApplicationModelProvider.cs#L147
By using IOptionsFactory<ODataOptions> you can create all the ODataOptions you need. The key will always be Options.DefaultName because OData options aren't named (but I guess you could register it that way). Creating an instance of ODataOptions this way will take you through the global callback in the original AddOData configuration. It's a bit strange, but I did it that way so you didn't end up having to configure global options differently per API version. Arguably, that wouldn't be global for the application anymore. Furthermore, they are unlikely to be different across API versions.
I'm not sure off-hand, but there's a reasonable chance you'll have to go through ODataOptions.AddRouteComponents with fake values that you'll never use. Add a minimal, you'd have to invoke the configuration callback. I'll have to look at the OData source again to see what it does.
Good update. I hope that helps steer you in the right direction.

It was definitely involved to make the solution generic, but I was able to get something working over the weekend. I was able to polish things up last night. You can have a look and provide any feedback in PR #933.
In short, you won't have to do anything special to make the Model Bound settings get picked up. Any use of the defined attributes will be picked up automatically. No additional registration will be required. It's magic 🧙🏽♂.
If you don't want use the Model Bound attributes, then you can use pure conventions a la:
builder.Services
       .AddApiVersioning()
       .AddODataApiExplorer(
           options.AdHocModelBuilder.DefaultModelConfiguration =
               ( b, v, p ) => b.EntitySet<Book>( "Books" ).EntityType.Filter( "title", "published" ) );

If you don't want your configuration to be inline, you can create IModelConfiguration implementations and use them just like you would for normal OData configurations. You likely wouldn't need to, but if you need information prior to the configuration being built, you can also implement IODataQueryOptionsConvention. It acts as a visitor.
It turns out that there really isn't a need to know if you're configuring a normal entity or an ad hoc one. More than one configuration for the same CLR type and API version combination doesn't make sense. Finally, ad hoc models will honor other things you configure in the EDM. Just like with normal OData, if the EDM doesn't exactly match the corresponding CLR type, then the model is substituted with a dynamically generated surrogate type. For example, you can exclude a specific property with:
if ( apiVersion == new ApiVersion( 1.0 ) )
{
   builder.EntitySet<Book>( "Books" ).EntityType.Ignore( book => book.NumberOfPages );
}

Let me know if you have any other questions or feedback. I was even able to get this to work with OData in ASP.NET Web API too! 😄 . I expect this to land in 7.0, which is just around the corner.

It was definitely involved to make the solution generic, but I was able to get something working over the weekend. I was able to polish things up last night. You can have a look and provide any feedback in PR #933.
In short, you won't have to do anything special to make the Model Bound settings get picked up. Any use of the defined attributes will be picked up automatically. No additional registration will be required. It's magic 🧙🏽♂.
If you don't want use the Model Bound attributes, then you can use pure conventions a la:
builder.Services
       .AddApiVersioning()
       .AddODataApiExplorer(
           options.AdHocModelBuilder.DefaultModelConfiguration =
               ( b, v, p ) => b.EntitySet<Book>( "Books" ).EntityType.Filter( "title", "published" ) );

If you don't want your configuration to be inline, you can create IModelConfiguration implementations and use them just like you would for normal OData configurations. You likely wouldn't need to, but if you need information prior to the configuration being built, you can also implement IODataQueryOptionsConvention. It acts as a visitor.
It turns out that there really isn't a need to know if you're configuring a normal entity or an ad hoc one. More than one configuration for the same CLR type and API version combination doesn't make sense. Finally, ad hoc models will honor other things you configure in the EDM. Just like with normal OData, if the EDM doesn't exactly match the corresponding CLR type, then the model is substituted with a dynamically generated surrogate type. For example, you can exclude a specific property with:
if ( apiVersion == new ApiVersion( 1.0 ) )
{
   builder.EntitySet<Book>( "Books" ).EntityType.Ignore( book => book.NumberOfPages );
}

Let me know if you have any other questions or feedback. I was even able to get this to work with OData in ASP.NET Web API too! 😄 . I expect this to land in 7.0, which is just around the corner.

@commonsensesoftware, this is awesome, update from my side, I was doing the approach you mentioned earlier and it worked perfectly. For the PR, I will take a look once I get some time and may get a branch and do some testing.

I integrated all of this into the final release. 7.0.0 has been published and has this feature in it; credit to you. Try it out and if you run into any issues or limitations, we'll get them patched. 😄

@commonsensesoftware, thanks for the help. However our service is still in .NET 6. Is there any chance we can also have a nuget library update for .Net 6?

Yikes! I think I can backport it into a 6.4 iteration that will not break anything. The other option would be multi-target net6.0, but that includes 5 packages. I guess I should have considered that since OData doesn't support net7.0 officially. The OData release cadence doesn't seem to pay any mind to the rest of the ASP.NET Core stack.
Either of the two approaches should work. I need to mull over which one makes the most sense.

@commonsensesoftware, thanks for the help on this. Let me know once you make the decision :). Meanwhile, I create a new project and trying this new nuget package. Will post the feedbacks here.

I'll get you covered either way. I just need to debate which method makes the most sense from a maintenance perspective. It's tough being an Army of One. 😉

@commonsensesoftware, I tried the model configuration approach with new library, it works great.

@commonsensesoftware,
Couple of feedbacks:

Net 6 support as we discussed.
For default model (don't configure on AdHocModelBuilder ), in OData default model builder will treat every complex type as entity type and skip the key validation. Here's the codes (https://github.com/OData/ModelBuilder/blob/main/src/Microsoft.OData.ModelBuilder/ODataConventionModelBuilder.cs#L1157-L1162), I think we should also follow this logic rather than do the validations.

Thanks.
I'm not sure 100% follow the second item. Are you saying the AdHocModelBuilder should use ODataModelBuilder instead of ODataConventionModelBuilder?
The VersionedODataModelBuilder is not actually an extension of ODataModelBuilder despite the name. The ModelBuilderFactory is a function use to create builder instances and allows you to create/change the default configuration of a builder. The factory is called to create a new ODataModelBuilder for each API version.

I think I see what you're saying. You want to default to a complex type instead of an entity. I presume that is largely to skip validation on the entity key 🤔 . That seems reasonable. I'll have to give it a whirl to verify all the query options allowed.

No, that is not what I mean :), wish we can have a call :). Current OData library behavior is treating every complex type as entity type and skip the key validation for non-edm scenario (what we need to do is to skip the key validation), What I am afraid is if someone also use the partial OData like me without registering EDM, and use the previous Asp.net Core API Version library. Now when he/she upgrades to this new one, the swagger will fail as 500 if the data model doesn't have key.
OData source code for skip validation key, we need to set _isQueryCompositionMode as true if we detect there are not merging configurations.
https://github.com/OData/ModelBuilder/blob/main/src/Microsoft.OData.ModelBuilder/ODataConventionModelBuilder.cs#L1157-L1162

Oh, I see. Well, subclassing ODataConventionBuilder overriding ValidateModel to do nothing and using that as the default by the factory is possible. I'll look into it.

@commonsensesoftware, one more feedback, not sure it makes sense or not :)
Since I am using model configuration, one benefit is that I can based on the api version to change the model, like add or ignore properties based on API Version, but the add/ignore properties changes are not reflected in the swagger, I think the reason is it is just an adhoc edm and we are not really register it, also I want the model show in swagger as regular rest not odata contract. I guess maybe should have some similar model configuration in the rest side :).

Correct. That is facilitated by the IModelTypeBuilder. I updated the DefaultModelTypeBuilder constructor to accept bool includeAdHocModels = false. I originally started by having it enabled by default, but when I tried to use myself in an example, I realized it doesn't really make sense.
The reason it's not enabled by default is because you'd need to make changes in the controller or model in order to get them to match. Normally, this is handled by OData through its media type formatters based on the EDM. Since that is not enabled or included, they do not match. You would likely have to use different models for each version, which is basically the same thing you have to do without any OData (e.g. create model per version). As a result, you don't really get any of the benefits and there is some internal performance costs that can be avoided not considering ad hoc models.
If you want to re-enable the behavior for ad hoc models, you just need to update the service registration with:
services.Replace(ServiceDescriptor.Singleton<IModelTypeBuilder>(new DefaultModelTypeBuilder(includeAdHocModels: true)));

If you choose this path, then you're on your own to actually make sure the model data members match.
There are multiple approaches you can use to make the request/response match:

Distinct model per version (clearest separation)
Inheritance (only works for additive)
Model adapters (over a single model which adds/removes the necessary members over the wire)
Custom converter (ex: custom JsonConverter)

To skip the model validation, you just need something like:
internal sealed class AdHocModelBuilder : ODataConventionModelBuilder
{
    public override void ValidateModel(IEdmModel model) { }
}

The wire it up with:
options.AdHocModelBuilder.ModelBuilderFactory = () => new AdHocModelBuilder();

I'll investigate whether this makes sense to make as the default, but you can achieve it now without waiting for me. 😄

To skip the model validation, you just need something like:
internal sealed class AdHocModelBuilder : ODataConventionModelBuilder
{
    public override void ValidateModel(IEdmModel model) { }
}

The wire it up with:
options.AdHocModelBuilder.ModelBuilderFactory = () => new AdHocModelBuilder();

I'll investigate whether this makes sense to make as the default, but you can achieve it now without waiting for me. 😄

Thanks, this one is not in hurry at all. Most important thing for me is the library support .NET 6 :)

@commonsensesoftware, since we would really like to use the new library. Would you mind sharing an ETA for the new features supported in .NET 6? Really thanks for your help on this.

Sure. My actual day j-o-b has been getting in the way.  I can probably get something out by this weekend. Will that work for you?

Sure. My actual day j-o-b has been getting in the way. I can probably get something out by this weekend. Will that work for you?

Just realized you left Microsoft, this weekend is for sure working for us. Again, really thanks for your help on this.

Yep. Been almost 2 years now. It's been quite the challenge keeping this project going without any other MS support. Unfortunately, I was never part of the ASP.NET team nor was this project was never part of daytime job. I might have stayed if it was. Who knows what happen in the future? 😉
If I'm able to finish it up earlier, I'll let you know ASAP.

@commonsensesoftware, just saw you are trying to kick off 6.4 release which contains all the changes we need. Really thanks for all the helps you provided.

Yep. Almost there. Breaking for dinner, but I should have it out later tonight.
I ultimately decided to refactor to use complex types for ad hoc models instead of entities. It's much simpler and there is no need to worry about validation or subclassing the ODataModelBuilder just to disable validation. Thanks for the feedback. This actually uncovered a previously undetected bug if the EDM only contains complex types, which will go out as well.
There's still a gap with auto-generating subtypes for OpenAPI via the API Explorer, but that is because what is reported would be a lie by default. If you know or have a way to restrict the members without using any of the built-in OData capabilities, you can re-enable this feature with:
services.Replace(
    typeof(IModelTypeBuilder),
    ServiceDescriptor.Singleton(new DefaultModelTypeBuilder(includeAdHocModels: true)));

I'm working on FI'ing these changes to 7.0.1 as well. If you ever move to .NET 7+, it will be covered there as well.

6.4.0 is ready and out in the wild. Let me know if you run into any problems.

Yep. Almost there. Breaking for dinner, but I should have it out later tonight.
I ultimately decided to refactor to use complex types for ad hoc models instead of entities. It's much simpler and there is no need to worry about validation or subclassing the ODataModelBuilder just to disable validation. Thanks for the feedback. This actually uncovered a previously undetected bug if the EDM only contains complex types, which will go out as well.
There's still a gap with auto-generating subtypes for OpenAPI via the API Explorer, but that is because what is reported would be a lie by default. If you know or have a way to restrict the members without using any of the built-in OData capabilities, you can re-enable this feature with:
services.Replace(
    typeof(IModelTypeBuilder),
    ServiceDescriptor.Singleton<IModelTypeBuilder>(new DefaultModelTypeBuilder(includeAdHocModels: true)));

I'm working on FI'ing these changes to 7.0.1 as well. If you ever move to .NET 7+, it will be covered there as well.

@commonsensesoftware, the change you made to  use complex types for ad hoc models is just for default aka when people call AddODataApiExplorer without customize any AdHocModelBuilder, right?
e.g.:
.AddODataApiExplorer(opt =>
{
opt.GroupNameFormat = "'v'VVV";
opt.SubstituteApiVersionInUrl = true;
});

If I use model configuration to set AdHocModelBuilder and the ModelConfiguration set complex type as entity, in this scenario, you will treat it as entity, right?
.AddODataApiExplorer(opt =>
        {
            opt.GroupNameFormat = "'v'VVV";
            opt.SubstituteApiVersionInUrl = true;
            opt.AdHocModelBuilder.ModelConfigurations.Add(new TemplateModelConfiguration());
        });

public class TemplateModelConfiguration : IModelConfiguration
{
    public void Apply(ODataModelBuilder builder, ApiVersion apiVersion, string? routePrefix)
    {
        builder.EntitySet<Template>(nameof(Template)).EntityType
            .Expand(nameof(Template.Thumbnails), nameof(Template.Affordances))
            .Filter(nameof(Template.ContentType), nameof(Template.Language))
            .Page(null, null);
        builder.EntityType<Thumbnail>().HasKey(m => m.Uri).Filter(nameof(Thumbnail.Size), nameof(Thumbnail.ContentType));
        builder.EntityType<Affordance>().HasKey(m => m.Link).Filter(nameof(Affordance.Type));

        // In the future we can based on api version to change model property.
    }
}

That is correct. Once you configure a type explicitly, be it an entity or complex type, no implicit behaviors apply. Since a complex type doesn't need a key, validation, or an entity set, it's a better default choice. You have full control once you explicitly configure things.

That is correct. Once you configure a type explicitly, be it an entity or complex type, no implicit behaviors apply. Since a complex type doesn't need a key, validation, or an entity set, it's a better default choice. You have full control once you explicitly configure things.

@commonsensesoftware, got it, so I use model configuration above to configure a type explicitly, it will not invoke ImplicitModelBoundSettingsConvention, is my assumption correctly?

@SamGuoMsft where you able to get things working the way you want? The wiki has been updated with a Partial OData Query Options topic.

@commonsensesoftware, sorry was busy in other tasks, will do the verification next week, and get back to you :)

@commonsensesoftware , sorry to get back late, I am doing the test. And during the test, I have a question for setting allow function or logical operators. I don't see there is way we can set via model configuration, the only approaches are:

Using EnableQueryAttribute AllowedLogicalOperators and AllowedFunctions
Set via options.QueryOptions.Controller()
.Action( c => c.Get( default ) )

Please correct me if I am wrong.

As far as I can tell, yes. ModelBoundQuerySettings does not appear to have any such properties or configuration. This is on OData and out of my hands. The configuration between Model Bound settings and EnableQueryAttribute is very incongruent.
The fluent API I provide for configuring the equivalent settings for [EnableQuery] is purely to map to ODataQuerySettings and ODataValidationSettings, which supports the use case where you apply these settings imperatively in an action rather than use [EnableQuery].
Unfortunately, it seems you have to configure some things one way and other things another way. I don't know of a way around that in the current OData design. It's probably feedback for the OData team.

@commonsensesoftware, for sure this topic is on OData team, just want to confirm whether there are some other way to handle it in case I missed anything. I am still doing my testing, hope can be done moro :).

@commonsensesoftware, with continuing doing my testing, find another thing, not sure whether it is bug or not.
If I change the action return from IQueryable to IActionResult, the swagger will only show the expand section. The filter, pagination sections are all gone. But once I put     [ProducesResponseType(typeof(IQueryable), StatusCodes.Status200OK)],
then everything becomes normal. This behavior is making sense since library needs to know the return type so that can read filter and pagination info. But just want to confirm with you that it is expected and not a bug.

Correct. The following will not work without specifying the response type:

void
Task
IActionResult
Task<IActionResult>
IEnumerable
IQueryable

There might be a few I missed. The following will work:

Task<T>
IEnumerable<T>
IQueryable<T>
IAsyncEnumerable<T>
ActionResult<T>
SingleResult<T>

provided that T is not one of the listed response types that will not work.

@commonsensesoftware , today when use EnableQueryAttributes, like  [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.Expand | AllowedQueryOptions.Filter | AllowedQueryOptions.Skip | AllowedQueryOptions.Top)], the ApiVersion library will read the enable query attribute and try to show the settings in the swagger.
If I don't plan to use EnableQuery since it did so many things, the only other option is set it via AddODataApiExplorer, is my understand correct? If there are other options to do it, please let me know.

Yes... and no. 😛
Yes, you do have to use conventions. There simply is no other way to advertise this information. Without an attribute, it doesn't exist in the code and can't be interrogated. Since it also does not exist in the EDM, there is nothing to probe there either.
The OData query options Conventions API is flexible. I provide a fluent API out-of-the-box, but you do not have to use it. You can also use the non-generic flavor of options.QueryOptions.Controller(typeof(BooksController)), which might be easier in some cases. If you don't want to put all the logic directly in the start, you can always move it to your own IConfigureOptions<ODataApiExplorerOptions> implementation with DI. You are free to create your own conventions as well. Your convention might map by type or you could combine a convention with your own custom attribute to indicate the available options.
A full solution is a bit involved, but a custom convention would be something like this:
public sealed class ODataQueryOptionsAttribute : Attribute
{
    public ODataQueryOptionsAttribute(AllowedQueryOptions allowed) => Allowed = allowed;
    public AllowedQueryOptions Allowed { get; }
}

You can technically use IODataQueryOptionsConvention, but it's probably simpler to start with ODataValidationSettingsConvention like this:
using static Microsoft.AspNetCore.OData.Query.AllowedQueryOptions;

public sealed class MyCustomConvention : ODataValidationSettingsConvention
{
    // you'd likely accept ODataOptions.QuerySettings, but you don't have to
    public MyCustomConvention( ODataQueryOptionSettings? settings = default )
        : base( DefaultValidationSettings(), settings ?? new() ) { }

    private static ODataValidationSettings DefaultValidationSettings() => new();

    public virtual void ApplyTo( ApiDescription apiDescription )
    {
        var controllerAttributes = controllerAction.ControllerTypeInfo.GetCustomAttributes<ODataQueryOptionsAttribute>( inherit: true );
        var actionAttributes = controllerAction.MethodInfo.GetCustomAttributes<ODataQueryOptionsAttribute>( inherit: true );
        var attributes = controllerAttributes.Concat( actionAttributes ).ToArray();

        if ( attributes.Length == 0 )
        {
            return;
        }

        var context = new ODataQueryOptionDescriptionContext( apiDescription, ValidationSettings );

        // TODO: merge options from the attributes
        var options = ?;
        var parameterDescriptions = apiDescription.ParameterDescriptions;

        // example usage:

        if ( options.HasFlag( Top ) )
        {
            parameterDescriptions.Add( NewTopParameter( context ) );
        }

        if ( options.HasFlag( Skip ) )
        {
            parameterDescriptions.Add( NewSkipParameter( context ) );
        }

        // ...
    }
}

ODataValidationSettingsConvention.cs can provide additional details on how you would implement it. Then you just add it to the configuration:
services.AddApiVersioning().AddODataApiExplorer( options => options.QueryOptions.Add( new MyCustomConvention() ) );

Nice design pattern, I was looking at how EnableQueryAttribute got consumed via ODataAttributeVisitor, Will take your suggestion and give it a try since EnableQueryAttribute is too heavy and did so many things :)

@commonsensesoftware , I tried the approach above, the new ODataQueryOptionDescriptionContext( apiDescription, ValidationSettings ) is internal constructor, don't think I can use it. Also for how to initialize the convention, I am thinking of using ConfigureOptions approach

ODataQueryOptionDescriptionContext has a public constructor. The use of ODataValidationSettings is a specific variant. I wasn't sure I wanted to open that up. You have 2 options:

Use the normal public constructor and initialize the other properties outside of the constructor from ODataValidationSettings.
a. The constructor logic is just a shortcut not a barrier
The constructor is protected internal and the class is not sealed. You can extend ODataQueryOptionDescriptionContext to get access to the constructor if you really want it.

As I mentioned, you will likely need a IConfigureOptions<ODataApiExplorerOptions> implementation to wire your conventions. IOptions<T> is a singleton so your IConfigureOptions<T> should be transient as it should only ever be used once.
What you are observing appears to be a behavior of Swashbuckle and not something I can control. You can see at:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIBuilderExtensions.cs#L33
that a container scope and IOptionsSnapshot<T> is used, which will almost certainly result in another instance being created. It's out of my hands, but I don't think it should be a problem either. Are you actually running into a problem or you just made an observation?

ODataQueryOptionDescriptionContext has a public constructor. The use of ODataValidationSettings is a specific variant. I wasn't sure I wanted to open that up. You have 2 options:

Use the normal public constructor and initialize the other properties outside of the constructor from ODataValidationSettings.
a. The constructor logic is just a shortcut not a barrier
The constructor is protected internal and the class is not sealed. You can extend ODataQueryOptionDescriptionContext to get access to the constructor if you really want it.

As I mentioned, you will likely need a IConfigureOptions<ODataApiExplorerOptions> implementation to wire your conventions. IOptions<T> is a singleton so your IConfigureOptions<T> should be transient as it should only ever be used once.
What you are observing appears to be a behavior of Swashbuckle and not something I can control. You can see at:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIBuilderExtensions.cs#L33
that a container scope and IOptionsSnapshot<T> is used, which will almost certainly result in another instance being created. It's out of my hands, but I don't think it should be a problem either. Are you actually running into a problem or you just made an observation?

@commonsensesoftware , I landup use the first option and took IModelMetadataProvider and IOptions as DI dependency. It looks pretty good. However once I added my convention, each odata query parameters api supported showed up as twice, by looking at the code, I think the reason is I am using the model configuration for showing the limited properties our api can expand and filter, ODataValidationSettingsConvention will visit the model configuration bounding and try to set parameter description, and then my custom attribute was added again via my convention.  In this case, I think I should use merge rather than add.

That sounds about right. I'm leading you down the path, but how you want to implement the solution is at your discretion. The point of the context is build up a set of initial configuration from global query options and some standard set of validation settings, if any. Then you will need to traverse (e.g. visit) your custom attributes to accumulate the settings which is logically a merge in most cases. Then, and only then, you can use the final set of options to build out the necessary parameters.
Honestly, the default implementation could have broken out the entry point to adding all the parameters because what you need should be exactly the same as the default implementation. This is an enhancement I may consider in the next release. Not a lot of people have gone down this rabbit hole of customization so I don't have a ton of feedback in this area. Regardless, it might be a little bit more verbose, but you should have all the necessary pieces to replicate the process of adding all the parameters. If there's certain things you don't want to support or you know you can optimize, you have full control over that.

@commonsensesoftware , not sure it is a bug, but want to discuss about it. I use model configuration to set max top and default page size

But for one api, we don't need pagination, so I use EnableQueryAttribute and didn't set skip and top

But this in OData, Model setting overrides EnableQueryAttribute, and from your code it directly set skip and top.
https://github.com/dotnet/aspnet-api-versioning/blob/3857a332057d970ad11bac0edfdbff8a559a215d/src/Common/src/Common.OData.ApiExplorer/Conventions/ODataAttributeVisitor.cs#:~:text=AllowedQueryOptions |%3D Skip | Top%3B
My question is whether there is a way so that I can control this in each action level. I guess I need to remove the max top and page size setting in model configuration and put it on ODataQueryAttribute for each action :)

If that is Sam's text, it's not all that clarifying; however, now that we've had a lengthy chat and I've spelunked a lot of the OData source code, I have a better understanding of how the code works. I think, the visitation logic is correct, but it may be backward.
We know that Model Bound Settings are validated first and that EnableQueryAttribute is processed last because it's an IActionFilter. This means the model should be visited first and the attributes second. The explicit logic to $skip and $top as AllowedQueryOptions is correct when you use [Page] because there is no other way to configure this information when you use Model Bound Settings alone. However, if that was always implicitly set and then overridden by EnableQueryAttribute, you would get the correct behavior. The challenge in this feature has always been clearly knowing the correct order of evaluation. The fact that the two configuration approaches are incongruent doesn't help.
Let me reverse the logic and make sure it doesn't break anything. You've presented a very valid use case that I can add to the test suite as well. If all goes well, I'll accept/create a bug for it and publish a patch. I'll get back to you ASAP.

Thanks @commonsensesoftware, the statement below actually is coming from https://learn.microsoft.com/en-us/odata/webapi/modelbound-attribute#overall-query-setting-precedence. Also I did tests on $expand and $filter too, it has the same pattern as $skip and $top: if I didn't set them in EnableQueryAttributes, but set Expand and Filter properties via ModelConfiguration, now I pass $expand or $filter in the request, I get bad request.

@SamGuoMsft the change seems simple. I've created PR #973, which you can take a 👀 at. All I did was reorder visitation so that Model Bound settings are processed first. If there is a subsequent EnableQueryAttribute found, it will override those settings when applicable. All of the previous code continued working as expected. I added a new test that should represent your test case and it now behaves as you expect.
Let me know if you see any other scenario or configuration that I might have missed. I still need to cherry pick this commit and backport it to the .NET 6 package for you. While it's not absolutely necessary, it would be nice to more 👀 on the changes. I should be able to have the patch out for you by Monday if not over the weekend.

@SamGuoMsft the change seems simple. I've created PR #973, which you can take a 👀 at. All I did was reorder visitation so that Model Bound settings are processed first. If there is a subsequent EnableQueryAttribute found, it will override those settings when applicable. All of the previous code continued working as expected. I added a new test that should represent your test case and it now behaves as you expect.
Let me know if you see any other scenario or configuration that I might have missed. I still need to cherry pick this commit and backport it to the .NET 6 package for you. While it's not absolutely necessary, it would be nice to more 👀 on the changes. I should be able to have the patch out for you by Monday if not over the weekend.

Thanks @commonsensesoftware , I am going to make the same changes in my local branch and test my scenario, will post here.

@commonsensesoftware , the changes looks good. Ship it :)

Fantastic! I'll work on getting the PRs merged and the packages published so you can pick it up by the AM. Stay tuned. 😄

@commonsense7software , thanks very much, would you mind to publish this to both asp.net 6 and 7. We plan to move to asp.net  7 in middle of next month.

6.4.1 and 7.0.2 have been published with the changes. Pick them up at your leisure.

Checking back in. @SamGuoMsft did the patch finally solve your issue?

@commonsensesoftware, we updated the packages to this latest version and got an exception when requesting the openapi.json. I didn't change anything else... Happens with both versions:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.MissingMethodException: Method not found: 'Microsoft.OData.ModelBuilder.Config.DefaultQuerySettings Microsoft.AspNetCore.OData.ODataOptions.get_QuerySettings()'.
         at Asp.Versioning.ApiExplorer.ODataApiDescriptionProvider.ExploreQueryOptions(IEnumerable`1 apiDescriptions)
         at Asp.Versioning.ApiExplorer.ODataApiDescriptionProvider.OnProvidersExecuted(ApiDescriptionProviderContext context)
         at Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider.GetCollection(ActionDescriptorCollection actionDescriptors)
         at Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider.get_ApiDescriptionGroups()
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerDocumentWithoutFilters(String documentName, String host, String basePath)
         at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerAsync(String documentName, String host, String basePath)
         at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Here is my reproduction: https://github.com/dnperfors/eLibrary/blob/main/src/eLibrary.WebApi.OData.Versioning/Program.cs

@dnperfors The issue you are describing is related to #980. You can track what's happening there as well as the deep link over to the OData repo.

Checking back in. @SamGuoMsft did the patch finally solve your issue?

@commonsensesoftware, sorry for later reply. The issue is solved, thanks very much for your help on this.

Thanks for confirming. I wanted to wait on closing it out until you confirmed it was resolved. Thanks. You helped make things better.


Add ability to use all NoiseMakerProps

I think it should be possible to use any NoiseMakerProps.
This should add support for modded items and items like the cash register ^^
I made it configurable and turned it off by default to honor your decision to only make it work for horns.
I hope this will be merged :)

Ooh, I'll probably do that once I come up with a way to make things less spammable (I don't want to add support for something and then have it bee really easy for ghosts to annoy people).


Proposal: Provide access to cookies in WebView

Proposal: Provide access to cookies in WebView
Summary
Make several methods in Windows.UI.Xaml.Controls.WebView that allow apps to read and modify cookies in WebView, regardless of which execution mode is used (WebViewExecutionMode.SeparateProcess, SeparateThread, or SameThread), as if the execution mode makes no difference.
Rationale

Although Windows.Web.Http.Filters.HttpBaseProtocolFilter.CookieManager can get and set cookies, it stops working when WebView.ExecutionMode is WebViewExecutionMode.SeparateProcess.   To be precise, you can still use it with persistent cookies (stored on-disk), but you cannot use it to get or set important temporary/session cookies in the separate WebView process.
If WebView is given its own methods to get and set cookies, then apps can avoid using HttpBaseProtocolFilter.CookieManager, meaning apps can avoid the confusion and unreliability of HttpBaseProtocolFilter.CookieManager in regards to different execution modes and the upcoming transition to WebView2 (Chromium).  The situation would be simpler and more reliable if HttpBaseProtocolFilter is removed from the equation.
HttpBaseProtocolFilter.CookieManager is completely unusable with WebView2 (Chromium) because WebView2 does not use "WinINet.dll" anymore.
Although cookies are normally shared between WebView and Windows.Web.Http.HttpClient instances created in the same app/process, this stops working when WebView.ExecutionMode is WebViewExecutionMode.SeparateProcess.  Temporary/session cookies in the separate WebView process are invisible to HttpClient running in the app.  This causes HttpClient to fail to download documents from websites that require the session cookies to be present.
If a WebView.GetCookies method or property is created, then apps will be able to copy cookies from WebView to Windows.Web.Http.HttpClient or System.Net.Http.HttpClient, regardless of which execution mode is used.
If a WebView.AddOrReplaceCookies method is created, then apps will be able to copy cookies from HttpClient to WebView.
The separate-process mode is impressive, but it is a sad situation when apps cannot use this impressive feature because of the cookie problem.  For example, in our environment, the separate-process mode is completely unusable because of the cookie problem, because our customer requirements make it critically essential to use HttpClient together with WebView.
In the case of WebView-for-WPF, you cannot work around the cookie problem by using  WebViewExecutionMode.SeparateThread because it only supports SeparateProcess (currently the WebView-for-WPF package is at version 6.0.0-preview7.1).
WebView2 (Chromium) supports only a separate-process mode.  If I understood correctly, this is the only mode it will ever support.  This further strengthens the need for cookie methods in WebView and WebView2.

Scope

Capability
Priority

Produce same results regardless of which WebViewExecutionMode
Must

Provide access to both temporary and persistent cookies
Must

Identical API in WebView and WebView2 for accessing cookies
Should

Internal implementation may use "WinINet.dll" but public API doesn't require this
Must

Get/read a specified single cookie
Must

Get/read all cookies (listing)
Must

Search for all cookies matching a specified criteria
Could

Set (add or replace) a single cookie
Must

Set (add or replace) multiple cookies
Should

Delete specified cookie
Must

Delete all cookies
Must

Delete all cookies and add the specified cookies
Could

In our environment, it's much less important to support setting cookies than getting cookies, but both are desirable.  Getting cookies solves the problem where WebView is used first, followed by Windows.Web.Http.HttpClient, but what about the reverse order?  In situations where HttpClient is used first, followed by WebView, ideally WebView would support setting of cookies in order to copy cookies from HttpClient to WebView.
Proposed API
// Get one cookie by name (exact match of domain, path, name):
// Returns null if no matching cookie is found:
public Windows.Web.Http.HttpCookie GetCookie(string domain, string path, string name);

// Get all cookies for the specified domain:
// Matches any value of `HttpCookie.Path` and `HttpCookie.Name`:
public Windows.Web.Http.HttpCookieCollection GetCookies(string domain);

// Property to get (and maybe set) collection of all cookies in the WebView:
public Windows.Web.Http.HttpCookieCollection Cookies { get; set; }

// Alternatively, if not a "Cookies" property, then a "GetCookies" or "GetAllCookies" method:
public Windows.Web.Http.HttpCookieCollection GetCookies();

// Add or replace (but not delete) multiple cookies in WebView:
public void AddOrReplaceCookies(Windows.Web.Http.HttpCookieCollection newCookies);

// Add or replace one cookie in WebView:
// This could be named "AddOrReplaceCookie" or "SetCookie":
public void AddOrReplaceCookie(Windows.Web.Http.HttpCookie newCookie);

// Delete one cookie:
public void DeleteCookie(string domain, string path, string name);
// Alternatively:
public void DeleteCookie(Windows.Web.Http.HttpCookie cookie);

// Delete all cookies in the WebView:
public void DeleteAllCookies();

If it's too difficult to support all of those, then at least the "GetCookies" method alone would be a big relief in our case.
A WebView.Cookies property could be get-only.  If this property also supports setting, then it would replace all cookies in WebView, thus it would also delete cookies (in the normal manner of replacing the contents of a collection).  However I don't think it's important for this property to support setting.
Important Notes
Temporary/session cookies means:

Cookies that don't have any expiration date (when Windows.Web.Http.HttpCookie.Expires is null).
Cookies that have Windows.Web.Http.HttpCookie.HttpOnly set to true.

According to the rules of "WinINet.dll" (used by WebView/Edge), temporary/session cookies are only stored in the RAM of the calling process, not on disk, thus an app loses access to these cookies when using WebView's SeparateProcess mode because the cookies are stored in the RAM of the separate web process.  Persistent cookies (stored on-disk) remain accessible with all execution modes, but this is insufficient because many websites require temporary cookies for authentication and/or session-management purposes.  The proposed cookie methods in WebView would behave (or appear to behave) the same regardless of which execution mode is used.
WebView2 (Chromium) does not use "WinINet.dll" anymore, thus Windows.Web.Http.Filters.HttpBaseProtocolFilter.CookieManager is completely unusable with WebView2.  This further increases the need for methods in WebView and WebView2 to access cookies.  Although WebView2 does store temporary/session cookies on-disk, "WinINet.dll" has no access, and there is no other way of accessing these cookies in WebView2 until WebView2 provides its own methods for accessing cookies.  WebView and WebView2 could be given exactly the same methods/API for accessing cookies, with the same public API but different internal implementation.
In the case of WebView2 (Chromium), the cookie methods in WebView2 would only affect the cookies stored in WebView2's "environment/user data folder", not the entire computer.  In the case of WebView 1 (Edge), the scope of the affected cookies is wider because it uses "WinINet.dll".  Regardless of this implementation difference, the cookie methods in WebView 1 and WebView2 can have the same public API.
Open Questions

Should WebView have a Cookies property or a GetCookies method?
If WebView has a Cookies property, should it be get-only or also support setting?
Should WebView support an ability to search for all cookies matching a specified criteria?  Or is it sufficient to make your app retrieve the entire collection of cookies and then search them by yourself?

See also

"WebView stops sharing temp cookies with HttpClient and HttpBaseProtocolFilter when mode is SeparateProcess" -- https://github.com/microsoft/microsoft-ui-xaml/issues/1297
"WPF WebView does not work with HttpBaseProtocolFilter.CookieManager" -- https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/issues/169
"Add support for cookie retrieval" -- https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/issues/120
"Support for getting and setting the cookies for the current page" -- https://github.com/MicrosoftEdge/WebViewFeedback/issues/4

Also, a WebAccountProvider used to be able to read or set (session) cookies from / on behalf of a signed in user account: if you added the account to windows using WebAccountProvider, then the browser could automatically have a session for the accompanying website based on cookies that the WebAccountProvider set. Also, the WebAccountProvider could read (session) cookies from the browser. This is a core part of Windows 10.
See e.g. WebAccountProviderRetrieveCookiesOperation and https://github.com/jaimerodriguez/WebAccountProvider.
Will this still work with the move to Chromium and its accompanying WebView2?


Create lstchain_mc_dl2_to_irfs.py

🥳 🥳 🥳 🥳
Speaking about the tree path, a do you think that saving the irfs into a IRFs directory (at the same level that running_analysis, dl1 etc...) will be ok ? inside analysis_logs maybe ? Or would you prefer to keep them "home made" for the moment and save them elsewhere ?

Will 🧐🧐🧐  the code now carefully 😛

@vuillaut can we then close this PR  ?

Replaced by PR #89


Issue with numpy versions?

Hello -
I dont know if the pegasusio repo is monitored (there's almost no issues), so apologies for cross-posting here. I think there's a compatibility issue with demuxEM/pegasusio and the latest numpy releases. See here for more specifics and an associated PR that might fix this: https://github.com/lilab-bcb/pegasusio/issues/100.

Hello @bbimber . Your PR in PegasusIO has been merged and reflected in PegasusIO v0.8.0.


Please add license

I would be interested in using this work in a derivative product. As it stands right now, we are unable to since it is not licensed. Would you be open to putting an MIT license on this?

@ChrisSandison can I interest you with llorllale/sql4j? It's licensed, but also inactive, but I'm willing to develop it further if there is any interest.

@ChrisSandison https://github.com/snail007/go-activerecord/tree/master/mysql


Support for styled components

Hi - do you have any plans to support styled components?
This is roughly what you would have to do: https://www.styled-components.com/docs/basics#styling-any-components

Also thanks for supporting this library! 🥇


[Feat]:  Blog creation

Description
Blog creation endpoint

Related Issue https://github.com/hngprojects/hng_boilerplate_nestjs/issues/46

Motivation and Context
To allow users create blog

How Has This Been Tested?
phpunit

Screenshots (if appropriate - Postman, etc):

Types of changes

[ ] Bug fix (non-breaking change which fixes an issue)
[x] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

[x] My code follows the code style of this project.
[] My change requires a change to the documentation.
[x] I have updated the documentation accordingly.
[x] I have read the CONTRIBUTING document.
[x] I have added tests to cover my changes.
[x] All new and existing tests passed.

Fill this form well!, fix your merge conflict


Toggle Line Comment in Fenced code blocks for LaTeX doesn't work well

This problem still occurs even if you disable all extensions and occurs in both stable and insider.
Demonstration
Create the following Fenced code blocks for LaTeX in Markdown file.
```latex
\documentclass{article}
\begin{document}
    Hello, \LaTeX{}!!
\end{document}
```

Then run Toggle Line Comment (Ctrl+/) on the line with Hello, \LaTeX{}!!.
You will get the following results:
```latex
\documentclass{article}
\begin{document}
    <!-- Hello, \LaTeX{}!! -->
\end{document}
```

The correct result is:
```latex
\documentclass{article}
\begin{document}
    % Hello, \LaTeX{}!!
\end{document}
```

GIF animation
Execute Ctrl+/ repeatedly

Version
 Version: 1.67.2 (user setup)
  Commit: c3511e6c69bb39013c4a4b7b9566ec1ca73fc4d5
    Date: 2022-05-17T18:15:52.058Z
Electron: 17.4.1
Chromium: 98.0.4758.141
 Node.js: 16.13.0
      V8: <IP_ADDRESS>-electron.0
      OS: Windows_NT x64 10.0.19043

 Version: 1.68.0-insider (user setup)
  Commit: c0769274fa136b45799edeccc0d0a2f645b75caf
    Date: 2022-05-23T05:17:12.256Z
Electron: 17.4.4
Chromium: 98.0.4758.141
 Node.js: 16.13.0
      V8: <IP_ADDRESS>-electron.0
      OS: Windows_NT x64 10.0.19043

Hi @Yarakashi-Kikohshi
Did you save the file? I disabled all my extensions for vscode insider and can't reproduce this issue.
Is this still happening for you?

@nerdjfpb

Did you save the file?

Yes. And all extensions are disabled.

Is this still happening for you?

Yes.

The insider version was updated to the following versions because has been available for updating. However, the problem continues to be reproduced.
 Version: 1.68.0-insider (user setup)
  Commit: 2260d7cca34384a2838c728850afdd38113ddb47
    Date: 2022-06-04T00:31:50.829Z
Electron: 17.4.6
Chromium: 98.0.4758.141
 Node.js: 16.13.0
      V8: <IP_ADDRESS>-electron.0
      OS: Windows_NT x64 10.0.19043

@mjbvz Hi, I'm having the same issue. I'm new to the codebase. Can I try to solve this issue?

@nerdjfpb @Priyankcoder
I had previously submitted similar issue. It may help to solve the issue. See https://github.com/microsoft/vscode/issues/142960.

@Yarakashi-Kikohshi thanks for this, It will help me solve this issue. I am working on this.

Hey @mjbvz, I made the PR. Could you please check it?


WIP: Various improvements

Don't merge until backend profile branch is merged first.
Implement subscription button (needs styling)

Add placeholder for empty profile fields

Fix button icons with correct coloring and spacing

Implement allowing club owners to specify schools/majors to target

Various small bug fixes
Implement better invitation page (with public toggling)

From the invitation page, can we make the name of the club a link to the club page?

Great idea, I'll implement that!

Just a few comments after those are resolved I think we are gtg. This PR looks very solid.


Script uses Set-AzureRmVMOperatingSystem but the usage is not explained in Script explanation section

As in the title; the script has been updated but the explanation does not have information about the cmdlet.

Document details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: e3883b13-efbc-dd65-f4ca-7dd3d34a74f7
Version Independent ID: 57a50d6a-b75e-bcf9-08ab-07f606d61cfb
Content: Azure PowerShell Script Sample - Create a Linux VM
Content Source: articles/virtual-machines/scripts/virtual-machines-linux-powershell-sample-create-vm.md
Service: virtual-machines-linux
GitHub Login: @neilpeterson
Microsoft Alias: nepeters

I apologize, but I can't figure out how the pages work or I'd make a PR. The PowerShell script seems to 404 as well.

@nromyn - thanks, patch is going in. This issue will auto close once the updates have been merged.

Well, I thought it would auto close, I must have miss-typed something.
Thanks again..
#please-close

This script runs clean up through the final command, "New-AzureRmVM -ResourceGroupName $resourceGroupName -Location $location -VM $vmConfig"
The error from this command is: "Required parameter 'osDisk' is missing (null)."

@DonBranson - what version of the PowerShell module are you using?


Adding all current parameters for VSTest

Please do not merge until I squash.
This adds the following parameters:

Parallel
EnableCodeCoverage
UseVsixExtensions
TestAdapterPath
TestCaseFilter
Diag

This is all the usable parameters as per the latest VSTest in VS2015.3, except the /List* parameters which didn't quite fit the flow because they return information instead of running tests.
The summaries are straight from the console documentation, except...
Major complaint: I think there is great value in copying the command line help description of each parameter. The build-enforced Gets or sets and Gets or sets a value indicating whether is frustrating to work into the summary and brings down the documentation quality here and on the website. I especially like the If set, because it clarifies instinctively what the default is. Also, this made me sad. So did this.
Question: Lots of tests on Should_Not_Use_*_By_Default that are entirely identical. Would it be better to have a single default settings test?

Hi @jnm2, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!
The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.
TTYL, DNFBOT;

And this:

/// Gets or sets a value indicating whether [suppress root directory].
HeatSettings.cs

@jnm2 was there an issue raised for this?
As per our contributing guidelines, we like to have an issue that we can reference: https://github.com/cake-build/cake/blob/develop/CONTRIBUTING.md

@gep13 Will do. #1279

So I still have those two questions. Can I get rid of the inflexible "Gets or sets a value UK indicating whether", and can the defaults tests be merged into once since they're identical?

@jnm2 No, we want to test one thing in every test.

@jnm2 said...
Can I get rid of the inflexible "Gets or sets a value indicating whether"

This is a standard convention used across the whole of Cake, so no, we aren't going to change that in this instance.

@jnm2 Yes, @gep13 is correct about this.
However, I take back what I wrote to you before. I misunderstood the question. Those identical tests can in fact be replaced with a single test. I misunderstood, sorry.

@gep13 @patriksvensson :+1:

@gep13 @patriksvensson :+1: Done.

@jnm2 Merged! Thank you for your contribution! 😄 👍


cf login without --sso fails

Command
cf login
cf login --sso
CLI Version
cf version 6.15.0+fa1bfe2-2016-01-13
Error
'cf login' fails to login, but works with 'cf login --sso'.
The API server should have a 'default_authenication_method' that can be set to SSO.  Currently every single cf client continually has to add '--sso' every time they log in.
CC API Endpoint Version
API endpoint: https://api.cloud.gov (API version: 2.53.0)

Hi @sharms
Sounds like a feature request for the API server, not for the CLI team?
Can you submit it to https://github.com/cloudfoundry/cloud_controller_ng/issues instead and the CLI team will add support once the backend supports it?
Cheers,
Dies Koper
CF CLI PM

As discussed on the uaa channel on Slack, the CLI reads login.endpoint/login, and could possibly be enhanced to assume --sso when the passcode field is there and the username and password fields are not:
{
    "prompts": {
        "username": ["text", "Email"],
        "password": ["password", "Password"],
        "passcode": ["password", "One Time Code ( Get one at https://login.cloud.gov/passcode )"]
    }
}

This would mean of course that the passcode would become the only way of authentication.
If that's acceptable, as this requires UAA to allow you to suppress those fields, please submit an enhancement request to their tracker and reopen this one with a link so we can try to align our change with theirs.

for IBM Bluemix, i noticed cf login --sso issue started happening when bluemix was integrated with SSO, users who created bluemix after the integration cannot login using the normal cf login  command but users prior to the sso can login without using --sso command, but when using the normal cf login command, the password to use must be the last password used before SSO was integrated and not the password that SSO uses if the password is not the same.

Still I am getting
{"error":"invalid_grant","error_description":"User authentication failed: Unauthorized"}
When trying
cf login without --sso fails


Feature Request: How to migrate from ASDF

The "old" README included a section titled "How do I migrate from asdf?" (see here), which was removed in this commit.
I couldn’t find this section in the new documentation site. It would be helpful to have a "Migrate" section that explains how to transition from asdf or other tools.

ok found it via google but not via the included search:
https://mise.jdx.dev/faq.html#how-do-i-migrate-from-asdf

I would suggest to add a link to this section at the page:
https://mise.jdx.dev/dev-tools/comparison-to-asdf.html

created pull request:
#3095


feat!: Upgrade to ESLint v9

BREAKING CHANGE
Blocked by:

eslint-plugin-react-hooks

[ ] https://github.com/facebook/react/issues/28313
[ ] https://github.com/facebook/react/pull/29770

eslint-plugin-testing-library

[x] https://github.com/testing-library/eslint-plugin-testing-library/issues/899
[ ] https://github.com/testing-library/eslint-plugin-testing-library/issues/897
[x] https://github.com/testing-library/eslint-plugin-testing-library/issues/924
[ ] https://github.com/testing-library/eslint-plugin-testing-library/pull/925

Already resolved:

[x] replaced eslint-plugin-import with eslint-plugin-import-x in #64 (see PR message)
[x] https://github.com/cypress-io/eslint-plugin-cypress/issues/155
[x] https://github.com/eslint-community/eslint-plugin-promise/issues/449
[x] https://github.com/jsx-eslint/eslint-plugin-react/issues/3699 & https://github.com/jsx-eslint/eslint-plugin-react/pull/3759
[x] https://github.com/typescript-eslint/typescript-eslint/issues/8211
[x] https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/978 & https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/1009

Optionally to add:

[ ] https://github.com/ihordiachenko/eslint-plugin-chai-friendly/issues/32

TODO: revert a574dff7afa925606ab331ce62f41fecef6b4345

Just an FYI while https://github.com/facebook/react/issues/28313 is still open for docs and other internal changes, they have released v5 that includes eslint v9 support: https://github.com/facebook/react/releases/tag/eslint-plugin-react-hooks%405.0.0, so should no longer be a blocker :)

@jamescrowley I know, I merged #204 some time ago, just didn't update the message here


RFC: Partial Mutability

This RFC proposes to add partiality to mutability to have partial mutable variables, including Partial mutable references.
This RFC is much simpler then Mixed mutable variables #3427
Rendered
let mut p1 : mut.%{x,y} Point = Point {x:1.0, y:2.0, was_x: 4.0, was_y: 5.0, state: 12.0};
	// p1 : mut.%{x,y} Point
let mut p2 : mut.%{x,was_x} Point = Point {x:1.0, y:2.0, was_x: 4.0, was_y: 5.0, state: 12.0};
	// p2 : mut.%{x,was_x} Point

let ref_p1 = &mut p1;
	// ref_p1 : &mut.%{x, y} Point

let refnr_p2 = &mut.%{x} p2;
	// refnr_p2 : &mut.%{x} Point

fn vz_restore (&mut p : &mut.%{was_x} Point2)  {
   *p.x = *p.was_x;
}

vz_restore(&mut p2);

pub fn mx_rstate(&mut p : &mix Point.%{mut x, state, %any}) { /* ... */ }
// mixed partiality of type and mutability

This is an extension to  Partial Types Proposal #3426

Generally the "pre-rfc" process (where you attempt to turn a partial idea into a full RFC) is done on the internals forum, https://internals.rust-lang.org/, or on the zulip, https://rust-lang.zulipchat.com/, rather than posting a draft PR.

Partial Mutability will be part Partial Types (v3) Proposal, so I close this draft proposal.
Thanks to everyone read it!


Review PR for contribute.md

Guidelines for reviewers
Using this Pull Request (PR), you can:

Add general comments about the article in this PR
Add a comment to a specific line in one of the files that make up this article
Propose edits to the article

You can view the published version of this article at:
https://azure.microsoft.com/documentation/articles/contribute/
Add general comments
To add a general comment, use this page (Conversation tab)
Add comments to a specific line
To add a comment to specific line, go to the Files changed tab, hover your mouse pointer over the line in the file and click the blue + to add a new line comment.
Propose edits to the article
To propose edits to this article, go to the Files changed tab, find the file you want to edit and click the pencil icon (Change this file using the online editor), and make your changes. When you are done you will be prompted to create a PR that contains your proposed changes.

Note: The PR with your proposed changes will be pushing changes to the dominicbetts/azure-content-pr:edit-contribute branch.

Processed all feedback up to here


[Addition]: Same maker witnessing cluster

Hotspot b58 Addresses
11t9BqCKZ3zN4JPiBCmFbRMP36VjcGTduHQpy3hr8sRLNKic5it
112TX8RdqNATFj98H8iDQruHjUErTLmcv84h71MWkunGCS9NHyrM
1112teJZ6AcVoraV4JJCbiEeHhFBfBfL9puKMFPmyLvBUGzrYqC
Discord Handle
No response
Reason(s)
Some clusters witnessing only same maker.
Some different rssi/snr/distance patterns.
Witnessing cross country / cross continent and not seeing other makers.


Question: vc_redist.x64.exe

How does the viewsvg-win.zip distribution handles the included vc_redist.x64.exe? There is no readme or information on this.
Any plan to release resvg.exe only package, for console applications?

It should be executed manually. Will add a readme.
Yes, I plan to have an automated releases.

Thanks, maybe you can also label the viewsvg-win.zip with x64 to indicate it requires 64-bits windows.


Windows ARM64 fails when loading model, error code 0xc000001d

What is the issue?
I installed the latest Ollama for Windows (ARM64 build) on my 2023 Windows Dev Kit, which has an 8-core ARM processor, a Snapdragon 8cx Gen 3. It's running Windows 11 Pro.
I can pull models, but when I go to run them, I get an error. It doesn't matter what model I run, I've tried several. Here's an example.
C:\Users\Mike Chambers>ollama pull gemma2:2b
pulling manifest
pulling<PHONE_NUMBER>d6... 100% ▕████████████████████████████████████████████████████████▏ 1.6 GB
pulling e0a42594d802... 100% ▕████████████████████████████████████████████████████████▏  358 B
pulling 097a36493f71... 100% ▕████████████████████████████████████████████████████████▏ 8.4 KB
pulling 2490e7468436... 100% ▕████████████████████████████████████████████████████████▏   65 B
pulling e18ad7af7efb... 100% ▕████████████████████████████████████████████████████████▏  487 B
verifying sha256 digest
writing manifest
success

C:\Users\Mike Chambers>ollama run gemma2:2b
Error: llama runner process has terminated: exit status 0xc000001d

C:\Users\Mike Chambers>

OS
Windows
GPU
No response
CPU
Other
Ollama version
0.3.13
server.log

Server logs will aid in debugging.

Server logs will aid in debugging.

Edited original post and added at the end.

Unfortunately the logs don't show anything interesting.  Please add OLLAMA_DEBUG=1 to the server environment and try again.

We've been primarily focused on the new Snapdragon X Elite CPUs, so perhaps we're compiling the binary with features enabled that aren't supported on the Snapdragon 8cx Gen 3.
@mikechambers84 if you have the ability to build from source, https://github.com/ollama/ollama/blob/main/llama/llama.go#L53-L54 might need some defines turned off.
https://github.com/ollama/ollama/blob/main/docs/development.md#windows-arm64-1

same issue


Does not use most recent version of babe-project

Currently, it uses version 0.0.25, which has a "bad" babe.css-file. (Pictures are displayed too large and overlap with the questions.)
As this is our example, it think it should always use the most recent version of babe-project.
Otherwise people will clone this repository and work with an old version babe-project.
Therefore we should exchange the fixed version number in package.json with something like latest or 0.x or ^0.0.26. I'm not sure what the best/correct way would be, but the fixed version number is definitely not the best idea.

Usually one fixes the version number when the software is stable. This repo is a bit special in that it is intended to serve as a template/scaffold from which new projects are to be developed. Therefore it might just make sense to depend on the newest babe-project version provided that each commit is tested to work well.

Yes,  we could depend on the newest babe-project version and push all changes to prereleases using the next-tag, so the normal users won't see them, test them and then push them to latest.

Another thing is to fix a major version, e.g. ^1.0.0, and ensure that every new release of babe-project in that major version is compatible with a previous release. Breaking changes to babe-project would happen in the next major version, so this package wouldn't be affected anyways.
Or fix a minor version such as ~0.1.0, if we haven't released any major version yet.

Fixing the minor version is probably the best way for now.
We still can use prereleases to make it easier for us to test the new versions.

Apparently using ^ in versions prior to 1.0.0 does not work.
I now fixed it to the minor version.


Placeholder texts

In the UI we have made room for about texts for each filter. But someone has to write those descriptions.
https://github.com/gbif/gbif-web/blob/master/packages/react-components/src/locales/en.js#L229
We might not want if for all - or we might not have it for all to begin with. So for now we should either add an about text or remove the text (by removing the key, the about option will disappear).
Similar we have placeholder texts for input "placeholder" i.e. the greyed out text in search boxes.

Are these customizable within hosted portal instances?

No - that isn't the intention. The idea is to have a shared version (managed in Crowdin). So that e.g. all spanish version have the same help texts. If there is disagreements on what a help text should be, then that discussion can take place in Crowdin among the translators. Or if different variations of spanish is needed and there is a desire among the translators to have spanish in Pan-American, Caribbean and Catalan then that is fine.
If there is a desire to customise messages on an instance level, then I see no technical challenges in doing so, but I believe we should start with a shared version.
Do you ask because you already now foresee a need to customise them?

I expect that there will arise the need to customize them, but not because
we have one at this moment. I agree that the best starting point is to have
good shared versions. I think we are interested in providing these. Should
we do that through a pull request on this repo?
On Mon, Apr 26, 2021 at 4:43 AM Morten Høfft @.***>
wrote:

No - that isn't the intention. The idea is to have a shared version
(managed in Crowdin). So that e.g. all spanish version have the same help
texts. If there is disagreements on what a help text should be, then that
discussion can take place in Crowdin among the translators. Or if different
variations of spanish is needed and there is a desire among the translators
to have spanish in Pan-American, Caribbean and Catalan then that is fine.
If there is a desire to customise messages on an instance level, then I
see no technical challenges in doing so, but I believe we should start with
a shared version.
Do you ask because you already now foresee a need to customise them?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/gbif/hosted-portals/issues/134#issuecomment-826591840,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADQ725ZQQJV24ZLYZ473KLTKUKRPANCNFSM43N5HXBQ
.

This question seem to be the same as https://github.com/gbif/hosted-portals/issues/60#issuecomment-827125356 ?
My primary concern with that is my worry that someone/you waste effort because we/I later decide to restructure something in the UI that make that help text unused. But that might be worrying too much.
Secondly, then some texts are still hardcoded, so you might not be able to find everything in the translation files.
And lastly, the format of the translation file will likely change, but that won't influence any text.
You are welcome to do pull requests with text changes to the project. Or just provide them here and I will copy them (if it becomes overwhelming I might back down on that approach and accept pull requests only).

I am in the process of amending commonFilters.js, getCommonSuggests.js, and locales/en.js There are three terms that aren't clear to me to what they refer. I don't see anything in the hosted portals to which they might refer. Can you tell me what they are suppose to be? They are:
name
city
code

I created a pull request with English text for as many terms as I could identify.

First of all - thank you for correcting all those texts!

Can you tell me what they are suppose to be? They are:
name
city
code

The list of filters is used across search for publishers/datasets/occurrences/institutions/collections/literature
name, city and code are specific to institutions and collections. You can see it in use here https://react-components.gbif-staging.org/iframe.html?id=search-collectionsearch--example&args=&viewMode=story

Thanks to @tucotuco I will close this issue. There is likely more placeholder values and mistaken hardcoded help texts lingering, but the large bulk is solved now.