Reference external Typescript models
This commit is contained in:
parent
90f7243c6b
commit
711bcebc0b
5 changed files with 47 additions and 12 deletions
|
@ -7,6 +7,7 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:code_buffer/code_buffer.dart';
|
import 'package:code_buffer/code_buffer.dart';
|
||||||
import 'package:code_builder/code_builder.dart';
|
import 'package:code_builder/code_builder.dart';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
|
import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
|
||||||
import 'build_context.dart';
|
import 'build_context.dart';
|
||||||
|
|
|
@ -12,8 +12,13 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> compileToTypeScriptType(BuildContext ctx, String fieldName,
|
Future<String> compileToTypeScriptType(
|
||||||
InterfaceType type, List<CodeBuffer> ext, BuildStep buildStep) async {
|
BuildContext ctx,
|
||||||
|
String fieldName,
|
||||||
|
InterfaceType type,
|
||||||
|
List<String> refs,
|
||||||
|
List<CodeBuffer> ext,
|
||||||
|
BuildStep buildStep) async {
|
||||||
String typeScriptType = 'any';
|
String typeScriptType = 'any';
|
||||||
|
|
||||||
var types = const {
|
var types = const {
|
||||||
|
@ -30,14 +35,14 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
|
|
||||||
if (isListModelType(type)) {
|
if (isListModelType(type)) {
|
||||||
var arg = await compileToTypeScriptType(
|
var arg = await compileToTypeScriptType(
|
||||||
ctx, fieldName, type.typeArguments[0], ext, buildStep);
|
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
|
||||||
typeScriptType = '$arg[]';
|
typeScriptType = '$arg[]';
|
||||||
} else if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type) &&
|
} else if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type) &&
|
||||||
type.typeArguments.length == 2) {
|
type.typeArguments.length == 2) {
|
||||||
var key = await compileToTypeScriptType(
|
var key = await compileToTypeScriptType(
|
||||||
ctx, fieldName, type.typeArguments[0], ext, buildStep);
|
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
|
||||||
var value = await compileToTypeScriptType(
|
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 modelType = type.typeArguments[1];
|
||||||
/*var innerCtx = await buildContext(
|
/*var innerCtx = await buildContext(
|
||||||
modelType.element,
|
modelType.element,
|
||||||
|
@ -63,10 +68,26 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
typeScriptType = 'any[]';
|
typeScriptType = 'any[]';
|
||||||
else {
|
else {
|
||||||
var arg = await compileToTypeScriptType(
|
var arg = await compileToTypeScriptType(
|
||||||
ctx, fieldName, type.typeArguments[0], ext, buildStep);
|
ctx, fieldName, type.typeArguments[0], refs, ext, buildStep);
|
||||||
typeScriptType = '$arg[]';
|
typeScriptType = '$arg[]';
|
||||||
}
|
}
|
||||||
} else if (isModelClass(type)) {
|
} 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 = '/// <reference path="$relative" />';
|
||||||
|
if (!refs.contains(ref)) refs.add(ref);
|
||||||
|
}
|
||||||
|
|
||||||
var ctx = await buildContext(
|
var ctx = await buildContext(
|
||||||
type.element,
|
type.element,
|
||||||
new ConstantReader(
|
new ConstantReader(
|
||||||
|
@ -122,6 +143,7 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
|
|
||||||
if (contexts.isEmpty) return;
|
if (contexts.isEmpty) return;
|
||||||
|
|
||||||
|
var refs = <String>[];
|
||||||
var buf = new CodeBuffer(
|
var buf = new CodeBuffer(
|
||||||
trailingNewline: true,
|
trailingNewline: true,
|
||||||
sourceUrl: buildStep.inputId.uri,
|
sourceUrl: buildStep.inputId.uri,
|
||||||
|
@ -148,11 +170,10 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
|
|
||||||
var alias = ctx.resolveFieldName(field.name);
|
var alias = ctx.resolveFieldName(field.name);
|
||||||
var typeScriptType = await compileToTypeScriptType(
|
var typeScriptType = await compileToTypeScriptType(
|
||||||
ctx, field.name, field.type, ext, buildStep);
|
ctx, field.name, field.type, refs, ext, buildStep);
|
||||||
|
|
||||||
// foo: string;
|
// foo: string;
|
||||||
if (!ctx.requiredFields.containsKey(field.name))
|
if (!ctx.requiredFields.containsKey(field.name)) alias += '?';
|
||||||
alias += '?';
|
|
||||||
buf.writeln('$alias: $typeScriptType;');
|
buf.writeln('$alias: $typeScriptType;');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +189,13 @@ class TypeScriptDefinitionBuilder implements Builder {
|
||||||
//buf
|
//buf
|
||||||
// ..outdent()
|
// ..outdent()
|
||||||
// ..writeln('}');
|
// ..writeln('}');
|
||||||
|
var finalBuf = new CodeBuffer();
|
||||||
|
refs.forEach(finalBuf.writeln);
|
||||||
|
buf.copyInto(finalBuf);
|
||||||
|
|
||||||
buildStep.writeAsString(
|
buildStep.writeAsString(
|
||||||
buildStep.inputId.changeExtension('.d.ts'),
|
buildStep.inputId.changeExtension('.d.ts'),
|
||||||
buf.toString(),
|
finalBuf.toString(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,15 @@ main() {
|
||||||
expect(library.copyWith(), library);
|
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', () {
|
group('deserialization', () {
|
||||||
test('deserialization sets proper fields', () {
|
test('deserialization sets proper fields', () {
|
||||||
var book = BookSerializer.fromMap(deathlyHallowsMap);
|
var book = BookSerializer.fromMap(deathlyHallowsMap);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/// <reference path="./book.d.ts" />
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
interface Library {
|
interface Library {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
Loading…
Reference in a new issue