From 711bcebc0bfb98e034ffd63bbc5bc38932d8eb66 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Tue, 15 May 2018 15:50:12 -0400 Subject: [PATCH] Reference external Typescript models --- .../lib/angel_serialize_generator.dart | 1 + angel_serialize_generator/lib/typescript.dart | 44 ++++++++++++++----- angel_serialize_generator/test/book_test.dart | 9 ++++ .../test/models/author.d.ts | 3 +- .../test/models/book.d.ts | 2 +- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/angel_serialize_generator/lib/angel_serialize_generator.dart b/angel_serialize_generator/lib/angel_serialize_generator.dart index e3f2b2a1..d7e32214 100644 --- a/angel_serialize_generator/lib/angel_serialize_generator.dart +++ b/angel_serialize_generator/lib/angel_serialize_generator.dart @@ -7,6 +7,7 @@ import 'package:angel_serialize/angel_serialize.dart'; import 'package:build/build.dart'; import 'package:code_buffer/code_buffer.dart'; import 'package:code_builder/code_builder.dart'; +import 'package:path/path.dart' as p; import 'package:recase/recase.dart'; import 'package:source_gen/source_gen.dart' hide LibraryBuilder; import 'build_context.dart'; diff --git a/angel_serialize_generator/lib/typescript.dart b/angel_serialize_generator/lib/typescript.dart index 6737dcb6..bf8bb592 100644 --- a/angel_serialize_generator/lib/typescript.dart +++ b/angel_serialize_generator/lib/typescript.dart @@ -12,8 +12,13 @@ class TypeScriptDefinitionBuilder implements Builder { }; } - Future compileToTypeScriptType(BuildContext ctx, String fieldName, - InterfaceType type, List ext, BuildStep buildStep) async { + Future compileToTypeScriptType( + BuildContext ctx, + String fieldName, + InterfaceType type, + List refs, + List ext, + BuildStep buildStep) async { String typeScriptType = 'any'; var types = const { @@ -30,14 +35,14 @@ class TypeScriptDefinitionBuilder implements Builder { if (isListModelType(type)) { var arg = await compileToTypeScriptType( - ctx, fieldName, type.typeArguments[0], ext, buildStep); + ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); typeScriptType = '$arg[]'; } else if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type) && type.typeArguments.length == 2) { var key = await compileToTypeScriptType( - ctx, fieldName, type.typeArguments[0], ext, buildStep); + ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); var value = await compileToTypeScriptType( - ctx, fieldName, type.typeArguments[1], ext, buildStep); + ctx, fieldName, type.typeArguments[1], refs, ext, buildStep); //var modelType = type.typeArguments[1]; /*var innerCtx = await buildContext( modelType.element, @@ -63,10 +68,26 @@ class TypeScriptDefinitionBuilder implements Builder { typeScriptType = 'any[]'; else { var arg = await compileToTypeScriptType( - ctx, fieldName, type.typeArguments[0], ext, buildStep); + ctx, fieldName, type.typeArguments[0], refs, ext, buildStep); typeScriptType = '$arg[]'; } } else if (isModelClass(type)) { + var sourcePath = buildStep.inputId.uri.toString(); + var targetPath = type.element.source.uri.toString(); + + if (!p.equals(sourcePath, targetPath)) { + //var relative = p.relative(targetPath, from: sourcePath); + var relative = (p.dirname(targetPath) == p.dirname(sourcePath)) + ? p.basename(targetPath) + : p.relative(targetPath, from: sourcePath); + var parent = p.dirname(relative); + var filename = + p.setExtension(p.basenameWithoutExtension(relative), '.d.ts'); + relative = p.joinAll(p.split(parent).toList()..add(filename)); + var ref = '/// '; + if (!refs.contains(ref)) refs.add(ref); + } + var ctx = await buildContext( type.element, new ConstantReader( @@ -122,6 +143,7 @@ class TypeScriptDefinitionBuilder implements Builder { if (contexts.isEmpty) return; + var refs = []; var buf = new CodeBuffer( trailingNewline: true, sourceUrl: buildStep.inputId.uri, @@ -148,11 +170,10 @@ class TypeScriptDefinitionBuilder implements Builder { var alias = ctx.resolveFieldName(field.name); var typeScriptType = await compileToTypeScriptType( - ctx, field.name, field.type, ext, buildStep); + ctx, field.name, field.type, refs, ext, buildStep); // foo: string; - if (!ctx.requiredFields.containsKey(field.name)) - alias += '?'; + if (!ctx.requiredFields.containsKey(field.name)) alias += '?'; buf.writeln('$alias: $typeScriptType;'); } @@ -168,10 +189,13 @@ class TypeScriptDefinitionBuilder implements Builder { //buf // ..outdent() // ..writeln('}'); + var finalBuf = new CodeBuffer(); + refs.forEach(finalBuf.writeln); + buf.copyInto(finalBuf); buildStep.writeAsString( buildStep.inputId.changeExtension('.d.ts'), - buf.toString(), + finalBuf.toString(), ); } } diff --git a/angel_serialize_generator/test/book_test.dart b/angel_serialize_generator/test/book_test.dart index cde4d824..6f0011c2 100644 --- a/angel_serialize_generator/test/book_test.dart +++ b/angel_serialize_generator/test/book_test.dart @@ -91,6 +91,15 @@ main() { expect(library.copyWith(), library); }); + test('required fields fromMap', () { + expect(() => AuthorSerializer.fromMap({}), throwsFormatException); + }); + + test('required fields toMap', () { + var author = new Author(name: null, age: 24); + expect(() => author.toJson(), throwsFormatException); + }); + group('deserialization', () { test('deserialization sets proper fields', () { var book = BookSerializer.fromMap(deathlyHallowsMap); diff --git a/angel_serialize_generator/test/models/author.d.ts b/angel_serialize_generator/test/models/author.d.ts index 9a7b5f24..25ddec6b 100644 --- a/angel_serialize_generator/test/models/author.d.ts +++ b/angel_serialize_generator/test/models/author.d.ts @@ -1,3 +1,4 @@ +/// // GENERATED CODE - DO NOT MODIFY BY HAND interface Library { id?: string; @@ -15,4 +16,4 @@ interface Bookmark { comment?: string; created_at?: any; updated_at?: any; -} +} \ No newline at end of file diff --git a/angel_serialize_generator/test/models/book.d.ts b/angel_serialize_generator/test/models/book.d.ts index 4dcb3ac3..676749be 100644 --- a/angel_serialize_generator/test/models/book.d.ts +++ b/angel_serialize_generator/test/models/book.d.ts @@ -9,4 +9,4 @@ interface Book { camelCase?: string; created_at?: any; updated_at?: any; -} +} \ No newline at end of file