generateSchema function

Future<GeneratedSchema> generateSchema(
  1. String sourcePath, {
  2. String? outputPath,
})

Analyzes sourcePath and generates a client without writing files.

outputPath determines relative imports and defaults to the source basename with an .orm.dart extension. Invalid declarations or output collisions throw GenerationException. Application default factories are never executed.

Implementation

Future<GeneratedSchema> generateSchema(
  String sourcePath, {
  String? outputPath,
}) async {
  final source = p.normalize(p.absolute(sourcePath));
  final output = p.normalize(
    p.absolute(outputPath ?? p.setExtension(source, '.orm.dart')),
  );
  if (p.extension(output) != '.dart' ||
      source == output ||
      source == _schemaSnapshotPath(output)) {
    throw const GenerationException(
      'Client and snapshot outputs must be separate Dart files from the source.',
    );
  }
  final contexts = AnalysisContextCollection(includedPaths: [source]);
  try {
    final resolved = await contexts
        .contextFor(source)
        .currentSession
        .getResolvedUnit(source);
    if (resolved is! ResolvedUnitResult) {
      throw GenerationException('Cannot analyze $source.');
    }
    final errors = resolved.diagnostics.where(
      (e) => e.severity.name.toLowerCase() == 'error',
    );
    if (errors.isNotEmpty) {
      throw GenerationException(errors.map((e) => e.toString()).join('\n'));
    }
    final import = p
        .relative(source, from: p.dirname(output))
        .replaceAll(r'\', '/');
    return await generateResolvedSchema(
      resolved.unit,
      resolved.libraryElement,
      import,
      (uri) => uri.scheme == 'file'
          ? p
                .relative(uri.toFilePath(), from: p.dirname(output))
                .replaceAll(r'\', '/')
          : uri.toString(),
      resolve: (library) async {
        final result = await library.session.getResolvedUnit(
          library.firstFragment.source.fullName,
        );
        if (result is! ResolvedUnitResult) {
          throw GenerationException('Cannot analyze ${library.uri}.');
        }
        final errors = result.diagnostics.where(
          (e) => e.severity.name.toLowerCase() == 'error',
        );
        if (errors.isNotEmpty) throw GenerationException(errors.join('\n'));
        return result.unit;
      },
    );
  } finally {
    await contexts.dispose();
  }
}