Skip to content

Instantly share code, notes, and snippets.

@dolmen
Created October 5, 2015 08:41
Show Gist options
  • Save dolmen/1ddd5e6a0f8ff54b5df8 to your computer and use it in GitHub Desktop.
Save dolmen/1ddd5e6a0f8ff54b5df8 to your computer and use it in GitHub Desktop.
Modifiy a Swagger 2.0 spec to inline global parameters (/parameters) and path scope parameters (for broken tools that do not handle them properly. eg: swagger-ui, go-swagger)
#!/usr/bin/env perl
# Refactoring of a Swagger 2.0 spec to make it compatible with broken tools
# that do not support the full spec.
use 5.010;
use strict;
use warnings;
use autodie;
use JSON::XS ();
sub inline_params
{
# $params: 'parameters' array
# $params_globals: '/parameters' object
my ($params, $params_global) = @_;
return unless defined $params;
for(my $i = $#$params; $i >= 0; $i--) {
next unless my $ref = $params->[$i]->{'$ref'};
die if $ref !~ m{^#/parameters/(.*)$};
$params->[$i] = $params_global->{$1} or die "missing /parameters/$1";
}
}
# In lower-case
my @HTTP_METHODS_LC = map { lc } qw< GET HEAD POST PUT PATCH DELETE OPTIONS LINK >;
# Inline parameters defined in global scope at '/parameters' as swagger-ui
# doesn't yet handle them properly
# Inline parameters defined in path scope into the operation scope
sub inline_global_parameters
{
my $spec = shift;
die if defined wantarray;
my $global_params = delete $spec->{parameters} or return;
foreach my $pathItem (values %{ $spec->{paths} }) {
my $path_params = delete $pathItem->{parameters};
inline_params($path_params, $global_params);
for my $op (map { $pathItem->{$_} // () } @HTTP_METHODS_LC) {
if (my $params = $op->{parameters}) {
inline_params($params, $global_params);
# Inline path-scope params in this scope
unshift @{ $params }, @$path_params if $path_params;
} elsif ($path_params) {
$op->{parameters} = [ @$path_params ];
}
}
}
}
@ARGV or die "usage: $0 <swagger.json>\n";
open my $f, '<:encoding(UTF-8)', $ARGV[0];
my $JSON = JSON::XS->new->canonical->utf8->pretty->space_before(0);
my $spec = $JSON->decode(do { local $/; scalar <$f> });
close $f;
inline_global_parameters($spec);
open $f, '>:encoding(UTF-8)', $ARGV[0];
print $f $JSON->encode($spec);
close $f;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment