44using System . Text ;
55using System . Text . RegularExpressions ;
66using Humanizer ;
7- using Json . Schema ;
8- using Json . Schema . OpenApi ;
7+ using Humanizer . Inflections ;
98using Microsoft . OpenApi . Hidi . Extensions ;
109using Microsoft . OpenApi . Models ;
1110using Microsoft . OpenApi . Services ;
12- using Microsoft . OpenApi . Extensions ;
1311
1412namespace Microsoft . OpenApi . Hidi . Formatters
1513{
1614 internal class PowerShellFormatter : OpenApiVisitorBase
1715 {
1816 private const string DefaultPutPrefix = ".Update" ;
1917 private const string PowerShellPutPrefix = ".Set" ;
20- private readonly Stack < JsonSchema > _schemaLoop = new ( ) ;
18+ private readonly Stack < OpenApiSchema > _schemaLoop = new ( ) ;
2119 private static readonly Regex s_oDataCastRegex = new ( "(.*(?<=[a-z]))\\ .(As(?=[A-Z]).*)" , RegexOptions . Compiled , TimeSpan . FromSeconds ( 5 ) ) ;
2220 private static readonly Regex s_hashSuffixRegex = new ( @"^[^-]+" , RegexOptions . Compiled , TimeSpan . FromSeconds ( 5 ) ) ;
2321 private static readonly Regex s_oDataRefRegex = new ( "(?<=[a-z])Ref(?=[A-Z])" , RegexOptions . Compiled , TimeSpan . FromSeconds ( 5 ) ) ;
@@ -26,11 +24,11 @@ static PowerShellFormatter()
2624 {
2725 // Add singularization exclusions.
2826 // Enhancement: Read exclusions from a user provided file.
29- Humanizer . Inflections . Vocabularies . Default . AddSingular ( "(drive)s$" , "$1" ) ; // drives does not properly singularize to drive.
30- Humanizer . Inflections . Vocabularies . Default . AddSingular ( "(data)$" , "$1" ) ; // exclude the following from singularization.
31- Humanizer . Inflections . Vocabularies . Default . AddSingular ( "(delta)$" , "$1" ) ;
32- Humanizer . Inflections . Vocabularies . Default . AddSingular ( "(quota)$" , "$1" ) ;
33- Humanizer . Inflections . Vocabularies . Default . AddSingular ( "(statistics)$" , "$1" ) ;
27+ Vocabularies . Default . AddSingular ( "(drive)s$" , "$1" ) ; // drives does not properly singularize to drive.
28+ Vocabularies . Default . AddSingular ( "(data)$" , "$1" ) ; // exclude the following from singularization.
29+ Vocabularies . Default . AddSingular ( "(delta)$" , "$1" ) ;
30+ Vocabularies . Default . AddSingular ( "(quota)$" , "$1" ) ;
31+ Vocabularies . Default . AddSingular ( "(statistics)$" , "$1" ) ;
3432 }
3533
3634 //FHL task for PS
@@ -43,13 +41,13 @@ static PowerShellFormatter()
4341 // 5. Fix anyOf and oneOf schema.
4442 // 6. Add AdditionalProperties to object schemas.
4543
46- public override void Visit ( ref JsonSchema schema )
47- {
48- AddAdditionalPropertiesToSchema ( ref schema ) ;
49- schema = ResolveAnyOfSchema ( ref schema ) ;
50- schema = ResolveOneOfSchema ( ref schema ) ;
44+ public override void Visit ( OpenApiSchema schema )
45+ {
46+ AddAdditionalPropertiesToSchema ( schema ) ;
47+ ResolveAnyOfSchema ( schema ) ;
48+ ResolveOneOfSchema ( schema ) ;
5149
52- base . Visit ( ref schema ) ;
50+ base . Visit ( schema ) ;
5351 }
5452
5553 public override void Visit ( OpenApiPathItem pathItem )
@@ -165,237 +163,97 @@ private static IList<OpenApiParameter> ResolveFunctionParameters(IList<OpenApiPa
165163 // Replace content with a schema object of type array
166164 // for structured or collection-valued function parameters
167165 parameter . Content = null ;
168- parameter . Schema = new JsonSchemaBuilder ( )
169- . Type ( SchemaValueType . Array )
170- . Items ( new JsonSchemaBuilder ( )
171- . Type ( SchemaValueType . String ) )
172- ;
166+ parameter . Schema = new ( )
167+ {
168+ Type = "array" ,
169+ Items = new ( )
170+ {
171+ Type = "string"
172+ }
173+ } ;
173174 }
174175 return parameters ;
175176 }
176177
177- private void AddAdditionalPropertiesToSchema ( ref JsonSchema schema )
178+ private void AddAdditionalPropertiesToSchema ( OpenApiSchema schema )
178179 {
179- if ( schema != null && ! _schemaLoop . Contains ( schema ) && schema . GetJsonType ( ) . Equals ( SchemaValueType . Object ) )
180+ if ( schema != null && ! _schemaLoop . Contains ( schema ) && "object" . Equals ( ( string ) schema . Type , StringComparison . OrdinalIgnoreCase ) )
180181 {
181- var schemaBuilder = new JsonSchemaBuilder ( ) ;
182- if ( schema . Keywords != null )
183- {
184- foreach ( var keyword in schema . Keywords )
185- {
186- schemaBuilder . Add ( keyword ) ;
187- }
188- }
189-
190- schema = schemaBuilder . AdditionalProperties ( new JsonSchemaBuilder ( ) . Type ( SchemaValueType . Object ) ) ;
182+ schema . AdditionalProperties = new ( ) { Type = "object" } ;
191183
192184 /* Because 'additionalProperties' are now being walked,
193185 * we need a way to keep track of visited schemas to avoid
194186 * endlessly creating and walking them in an infinite recursion.
195187 */
196- var additionalProps = schema . GetAdditionalProperties ( ) ;
197-
198- if ( additionalProps != null )
199- {
200- _schemaLoop . Push ( additionalProps ) ;
201- }
188+ _schemaLoop . Push ( schema . AdditionalProperties ) ;
202189 }
203-
204190 }
205191
206- private static JsonSchema ResolveOneOfSchema ( ref JsonSchema schema )
192+ private static void ResolveOneOfSchema ( OpenApiSchema schema )
207193 {
208- if ( schema . GetOneOf ( ) ? . FirstOrDefault ( ) is { } newSchema )
194+ if ( schema . OneOf ? . FirstOrDefault ( ) is { } newSchema )
209195 {
210- var schemaBuilder = BuildSchema ( schema ) ;
211- schemaBuilder = schemaBuilder . Remove ( "oneOf" ) ;
212- schema = schemaBuilder . Build ( ) ;
213-
214- schema = FlattenSchema ( schema , newSchema ) ;
196+ schema . OneOf = null ;
197+ FlattenSchema ( schema , newSchema ) ;
215198 }
216-
217- return schema ;
218199 }
219200
220- private static JsonSchema ResolveAnyOfSchema ( ref JsonSchema schema )
201+ private static void ResolveAnyOfSchema ( OpenApiSchema schema )
221202 {
222- if ( schema . GetAnyOf ( ) ? . FirstOrDefault ( ) is { } newSchema )
203+ if ( schema . AnyOf ? . FirstOrDefault ( ) is { } newSchema )
223204 {
224- var schemaBuilder = BuildSchema ( schema ) ;
225- schemaBuilder = schemaBuilder . Remove ( "anyOf" ) ;
226- schema = schemaBuilder . Build ( ) ;
227-
228- schema = FlattenSchema ( schema , newSchema ) ;
205+ schema . AnyOf = null ;
206+ FlattenSchema ( schema , newSchema ) ;
229207 }
230-
231- return schema ;
232208 }
233209
234- private static JsonSchema FlattenSchema ( JsonSchema schema , JsonSchema newSchema )
210+ private static void FlattenSchema ( OpenApiSchema schema , OpenApiSchema newSchema )
235211 {
236212 if ( newSchema != null )
237213 {
238- var newSchemaRef = newSchema . GetRef ( ) ;
239-
240- if ( newSchemaRef != null )
214+ if ( newSchema . Reference != null )
241215 {
242- var schemaBuilder = BuildSchema ( schema ) ;
243- schema = schemaBuilder . Ref ( newSchemaRef ) ;
216+ schema . Reference = newSchema . Reference ;
217+ schema . UnresolvedReference = true ;
244218 }
245219 else
246220 {
247221 // Copies schema properties based on https://github.com/microsoft/OpenAPI.NET.OData/pull/264.
248- schema = CopySchema ( schema , newSchema ) ;
249- }
250- }
251-
252- return schema ;
253- }
254-
255- private static JsonSchema CopySchema ( JsonSchema schema , JsonSchema newSchema )
256- {
257- var schemaBuilder = new JsonSchemaBuilder ( ) ;
258- var keywords = schema . Keywords ;
259- if ( keywords != null )
260- {
261- foreach ( var keyword in keywords )
262- {
263- schemaBuilder . Add ( keyword ) ;
222+ CopySchema ( schema , newSchema ) ;
264223 }
265224 }
266-
267- if ( schema . GetTitle ( ) == null && newSchema . GetTitle ( ) is { } title )
268- {
269- schemaBuilder . Title ( title ) ;
270- }
271- if ( schema . GetJsonType ( ) == null && newSchema . GetJsonType ( ) is { } type )
272- {
273- schemaBuilder . Type ( type ) ;
274- }
275- if ( schema . GetFormat ( ) == null && newSchema . GetFormat ( ) is { } format )
276- {
277- schemaBuilder . Format ( format ) ;
278- }
279- if ( schema . GetDescription ( ) == null && newSchema . GetDescription ( ) is { } description )
280- {
281- schemaBuilder . Description ( description ) ;
282- }
283- if ( schema . GetMaximum ( ) == null && newSchema . GetMaximum ( ) is { } max )
284- {
285- schemaBuilder . Maximum ( max ) ;
286- }
287- if ( schema . GetExclusiveMaximum ( ) == null && newSchema . GetExclusiveMaximum ( ) is { } exclusiveMaximum )
288- {
289- schemaBuilder . ExclusiveMaximum ( exclusiveMaximum ) ;
290- }
291- if ( schema . GetMinimum ( ) == null && newSchema . GetMinimum ( ) is { } min )
292- {
293- schemaBuilder . Minimum ( min ) ;
294- }
295- if ( schema . GetExclusiveMinimum ( ) == null && newSchema . GetExclusiveMinimum ( ) is { } exclusiveMinimum )
296- {
297- schemaBuilder . ExclusiveMinimum ( exclusiveMinimum ) ;
298- }
299- if ( schema . GetMaxLength ( ) == null && newSchema . GetMaxLength ( ) is { } maxLength )
300- {
301- schemaBuilder . MaxLength ( maxLength ) ;
302- }
303- if ( schema . GetMinLength ( ) == null && newSchema . GetMinLength ( ) is { } minLength )
304- {
305- schemaBuilder . MinLength ( minLength ) ;
306- }
307- if ( schema . GetPattern ( ) == null && newSchema . GetPattern ( ) is { } pattern )
308- {
309- schemaBuilder . Pattern ( pattern ) ;
310- }
311- if ( schema . GetMultipleOf ( ) == null && newSchema . GetMultipleOf ( ) is { } multipleOf )
312- {
313- schemaBuilder . MultipleOf ( multipleOf ) ;
314- }
315- if ( schema . GetNot ( ) == null && newSchema . GetNot ( ) is { } not )
316- {
317- schemaBuilder . Not ( not ) ;
318- }
319- if ( schema . GetRequired ( ) == null && newSchema . GetRequired ( ) is { } required )
320- {
321- schemaBuilder . Required ( required ) ;
322- }
323- if ( schema . GetItems ( ) == null && newSchema . GetItems ( ) is { } items )
324- {
325- schemaBuilder . Items ( items ) ;
326- }
327- if ( schema . GetMaxItems ( ) == null && newSchema . GetMaxItems ( ) is { } maxItems )
328- {
329- schemaBuilder . MaxItems ( maxItems ) ;
330- }
331- if ( schema . GetMinItems ( ) == null && newSchema . GetMinItems ( ) is { } minItems )
332- {
333- schemaBuilder . MinItems ( minItems ) ;
334- }
335- if ( schema . GetUniqueItems ( ) == null && newSchema . GetUniqueItems ( ) is { } uniqueItems )
336- {
337- schemaBuilder . UniqueItems ( uniqueItems ) ;
338- }
339- if ( schema . GetProperties ( ) == null && newSchema . GetProperties ( ) is { } properties )
340- {
341- schemaBuilder . Properties ( properties ) ;
342- }
343- if ( schema . GetMaxProperties ( ) == null && newSchema . GetMaxProperties ( ) is { } maxProperties )
344- {
345- schemaBuilder . MaxProperties ( maxProperties ) ;
346- }
347- if ( schema . GetMinProperties ( ) == null && newSchema . GetMinProperties ( ) is { } minProperties )
348- {
349- schemaBuilder . MinProperties ( minProperties ) ;
350- }
351- if ( schema . GetDiscriminator ( ) == null && newSchema . GetDiscriminator ( ) is { } discriminator )
352- {
353- schemaBuilder . Discriminator ( discriminator . PropertyName , discriminator . Mapping , discriminator . Extensions ) ;
354- }
355- if ( schema . GetOpenApiExternalDocs ( ) == null && newSchema . GetOpenApiExternalDocs ( ) is { } externalDocs )
356- {
357- schemaBuilder . OpenApiExternalDocs ( externalDocs ) ;
358- }
359- if ( schema . GetEnum ( ) == null && newSchema . GetEnum ( ) is { } enumCollection )
360- {
361- schemaBuilder . Enum ( enumCollection ) ;
362- }
363-
364- if ( ! schema . GetReadOnly ( ) is { } && newSchema . GetReadOnly ( ) is { } newValue )
365- {
366- schemaBuilder . ReadOnly ( newValue ) ;
367- }
368-
369- if ( ! schema . GetWriteOnly ( ) is { } && newSchema . GetWriteOnly ( ) is { } newWriteOnlyValue )
370- {
371- schemaBuilder . WriteOnly ( newWriteOnlyValue ) ;
372- }
373-
374- if ( ! schema . GetNullable ( ) is { } && newSchema . GetNullable ( ) is { } newNullableValue )
375- {
376- schemaBuilder . Nullable ( newNullableValue ) ;
377- }
378-
379- if ( ! schema . GetDeprecated ( ) is { } && newSchema . GetDeprecated ( ) is { } newDepracatedValue )
380- {
381- schemaBuilder . Deprecated ( newDepracatedValue ) ;
382- }
383-
384- return schemaBuilder ;
385225 }
386226
387- private static JsonSchemaBuilder BuildSchema ( JsonSchema schema )
227+ private static void CopySchema ( OpenApiSchema schema , OpenApiSchema newSchema )
388228 {
389- var schemaBuilder = new JsonSchemaBuilder ( ) ;
390- if ( schema . Keywords != null )
391- {
392- foreach ( var keyword in schema . Keywords )
393- {
394- schemaBuilder . Add ( keyword ) ;
395- }
396- }
397-
398- return schemaBuilder ;
229+ schema . Title ??= newSchema . Title ;
230+ schema . Type ??= newSchema . Type ;
231+ schema . Format ??= newSchema . Format ;
232+ schema . Description ??= newSchema . Description ;
233+ schema . Maximum ??= newSchema . Maximum ;
234+ schema . ExclusiveMaximum ??= newSchema . ExclusiveMaximum ;
235+ schema . Minimum ??= newSchema . Minimum ;
236+ schema . ExclusiveMinimum ??= newSchema . ExclusiveMinimum ;
237+ schema . MaxLength ??= newSchema . MaxLength ;
238+ schema . MinLength ??= newSchema . MinLength ;
239+ schema . Pattern ??= newSchema . Pattern ;
240+ schema . MultipleOf ??= newSchema . MultipleOf ;
241+ schema . Not ??= newSchema . Not ;
242+ schema . Required ??= newSchema . Required ;
243+ schema . Items ??= newSchema . Items ;
244+ schema . MaxItems ??= newSchema . MaxItems ;
245+ schema . MinItems ??= newSchema . MinItems ;
246+ schema . UniqueItems ??= newSchema . UniqueItems ;
247+ schema . Properties ??= newSchema . Properties ;
248+ schema . MaxProperties ??= newSchema . MaxProperties ;
249+ schema . MinProperties ??= newSchema . MinProperties ;
250+ schema . Discriminator ??= newSchema . Discriminator ;
251+ schema . ExternalDocs ??= newSchema . ExternalDocs ;
252+ schema . Enum ??= newSchema . Enum ;
253+ schema . ReadOnly = ! schema . ReadOnly ? newSchema . ReadOnly : schema . ReadOnly ;
254+ schema . WriteOnly = ! schema . WriteOnly ? newSchema . WriteOnly : schema . WriteOnly ;
255+ schema . Nullable = ! schema . Nullable ? newSchema . Nullable : schema . Nullable ;
256+ schema . Deprecated = ! schema . Deprecated ? newSchema . Deprecated : schema . Deprecated ;
399257 }
400258 }
401259}
0 commit comments