toSwaggerUI method

Future<void> toSwaggerUI({
  1. required String destination,
  2. String? title,
  3. bool replace = false,
  4. String? favicon16x16,
  5. String? favicon32x32,
  6. bool quiet = false,
  7. String? url = '/openapi.json',
})

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');
}