toSwaggerUI method
Generate a static Swagger UI website from OpenApi object
These assets utilize the latest Swagger UI release
title: Will override the title of the Swagger UI HTML page.
By default, this is set to the Info.title
value
replace: Will delete the destination directory if it already exists
Set a custom favicon by defining paths to the following files:
favicon16x16: The path to a 16x16 PNG favicon image
favicon32x32: The path to a 32x32 PNG favicon image
Implementation
Future<void> toSwaggerUI({
required String destination,
String? title,
bool replace = false,
String? favicon16x16,
String? favicon32x32,
bool quiet = false,
String? url = '/openapi.json',
}) async {
final dir = Directory(destination);
final dirPath = p.normalize(dir.absolute.path);
// https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
if (dir.existsSync()) {
if (replace) {
await dir.delete(recursive: true);
} else {
throw Exception(
'Destination directory already exists: $dirPath\n\nEither remove it or set the "replace" option to true to delete the existing destination\n',
);
}
}
// Ensure that the directory exists
Directory(p.dirname(dirPath)).createSync(recursive: true);
// Get the path to the swagger-ui static content
final packageUri = Uri.parse('package:openapi_spec/static/swagger-ui');
final packagePath = (await Isolate.resolvePackageUri(packageUri))?.path;
if (packagePath == null) {
throw Exception('Could not resolve package URI: $packageUri');
}
// Copy the source to the destination
final source = Directory(packagePath);
await Process.run('cp', ['-r', source.path, dirPath]);
// Generate the spec file in the destination
final oasFile = p.join(dirPath, 'openapi.json');
toJsonFile(destination: oasFile);
// ignore: avoid_print
if (!quiet) print('Created OpenAPI spec file:\n - $oasFile');
// Create a Javascript object for local parsing
// Avoids the need to spin up a server to simply view the Swagger UI output
final init = File(p.join(dirPath, 'swagger-initializer.js'));
if (url == null) {
init.writeAsStringSync(
'let spec = ${_encoder.convert(toJson())}',
mode: FileMode.append,
);
} else {
init.writeAsStringSync(
init.readAsStringSync().replaceAll(
'spec: spec,',
"url: '$url',",
),
mode: FileMode.write,
);
}
// Apply the index.html customizations
final index = File(p.join(dirPath, 'index.html'));
var indexText = index.readAsStringSync().replaceAll(
'OAS_HTML_TITLE',
info.title,
);
index.writeAsStringSync(indexText);
// Replace the favicons
for (final favicon in [favicon16x16, favicon32x32]) {
if (favicon == null) {
continue;
}
final f = File(favicon);
final faviconpath = p.normalize(f.absolute.path);
if (f.existsSync()) {
await Process.run('cp', [faviconpath, dir.absolute.path]);
// ignore: avoid_print
if (!quiet) print('Copied favicon16x16:\n - $faviconpath');
} else {
throw Exception(
'Could not find favicon at defined path: \n\n$faviconpath\n',
);
}
}
// ignore: avoid_print
if (!quiet) print('Static HTML generated in:\n - $dirPath');
}