-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Release] Add initial capabilities (#1)
- Loading branch information
Showing
15 changed files
with
480 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,3 +19,7 @@ doc/api/ | |
*.js_ | ||
*.js.deps | ||
*.js.map | ||
|
||
lib/src/graphql | ||
|
||
build.yaml.dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 1.0.0 | ||
|
||
- Initial version. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,39 @@ | ||
# graphql_types_builder | ||
<!-- | ||
This README describes the package. If you publish this package to pub.dev, | ||
this README's contents appear on the landing page for your package. | ||
For information about how to write a good package README, see the guide for | ||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages). | ||
For general information about developing packages, see the Dart guide for | ||
[creating packages](https://dart.dev/guides/libraries/create-library-packages) | ||
and the Flutter guide for | ||
[developing packages and plugins](https://flutter.dev/developing-packages). | ||
--> | ||
|
||
TODO: Put a short description of the package here that helps potential users | ||
know whether this package might be useful for them. | ||
|
||
## Features | ||
|
||
TODO: List what your package can do. Maybe include images, gifs, or videos. | ||
|
||
## Getting started | ||
|
||
TODO: List prerequisites and provide or point to information on how to | ||
start using the package. | ||
|
||
## Usage | ||
|
||
TODO: Include short and useful examples for package users. Add longer examples | ||
to `/example` folder. | ||
|
||
```dart | ||
const like = 'sample'; | ||
``` | ||
|
||
## Additional information | ||
|
||
TODO: Tell users more about the package: where to find more information, how to | ||
contribute to the package, how to file issues, what response they can expect | ||
from the package authors, and more. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# This file configures the static analysis results for your project (errors, | ||
# warnings, and lints). | ||
# | ||
# This enables the 'recommended' set of lints from `package:lints`. | ||
# This set helps identify many issues that may lead to problems when running | ||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic | ||
# style and format. | ||
# | ||
# If you want a smaller set of lints you can change this to specify | ||
# 'package:lints/core.yaml'. These are just the most critical lints | ||
# (the recommended set includes the core lints). | ||
# The core lints are also what is used by pub.dev for scoring packages. | ||
|
||
include: package:lints/recommended.yaml | ||
|
||
# Uncomment the following section to specify additional rules. | ||
|
||
# linter: | ||
# rules: | ||
# - camel_case_types | ||
|
||
# analyzer: | ||
# exclude: | ||
# - path/to/excluded/files/** | ||
|
||
# For more information about the core and recommended set of lints, see | ||
# https://dart.dev/go/core-lints | ||
|
||
# For additional information about configuring this file, see | ||
# https://dart.dev/guides/language/analysis-options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
targets: | ||
graphql_types_builder:graphql_types_builder: | ||
builders: | ||
graphql_types_builder|graphqlTypesBuilder: | ||
enabled: True | ||
generate_for: | ||
# TODO: Parse also queries and mutations | ||
- lib/src/**/*schema.graphql | ||
|
||
builders: | ||
graphqlTypesBuilder: | ||
import: 'package:graphql_types_builder/graphql_types_builder.dart' | ||
builder_factories: ['graphqlTypesBuilder'] | ||
build_extensions: | ||
.graphql: | ||
- .graphql.dart | ||
build_to: source | ||
auto_apply: dependents |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
library graphql_types_builder; | ||
|
||
import 'package:build/build.dart'; | ||
import 'package:graphql_types_builder/src/graphql_types_builder.dart'; | ||
|
||
Builder graphqlTypesBuilder(BuilderOptions options) => GraphqlTypesBuilder(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import 'package:build/build.dart'; | ||
|
||
import 'services/graphql_parser_service.dart'; | ||
|
||
class GraphqlTypesBuilder implements Builder { | ||
@override | ||
Map<String, List<String>> get buildExtensions => { | ||
'.graphql': ['.graphql.dart'], | ||
}; | ||
|
||
@override | ||
Future<void> build(BuildStep buildStep) async { | ||
// Retrive the current matched assets | ||
AssetId currentAssetId = buildStep.inputId; | ||
|
||
// Create a new target ID | ||
var copyAssetId = currentAssetId.changeExtension('.graphql.dart'); | ||
var assetContent = await buildStep.readAsString(currentAssetId); | ||
|
||
// Generate the dart classes based on the graphql schema | ||
String newAssetContent = GraphqlParserService().parse(assetContent); | ||
|
||
// Write the new asset | ||
await buildStep.writeAsString(copyAssetId, newAssetContent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
final _graphqlDefaultScalarTypes = ["ID", "String", "Boolean", "Int", "Float"]; | ||
|
||
final _isListRegex = RegExp(r'\[(\w*|\w*!)\]'); | ||
|
||
String _buildDartType(attributeType) { | ||
bool isList = _isListRegex.hasMatch(attributeType); | ||
if (isList) { | ||
attributeType = attributeType.replaceAll(r'\W', ''); | ||
return 'List<${_parseScalarType(attributeType)}>'; | ||
} | ||
|
||
return _parseScalarType(attributeType); | ||
} | ||
|
||
String _parseScalarType(attributeType) { | ||
switch (attributeType) { | ||
case 'ID': | ||
return 'String'; | ||
case 'Boolean': | ||
return 'bool'; | ||
case 'Int': | ||
return 'int'; | ||
case 'Float': | ||
return 'double'; | ||
default: | ||
return attributeType; | ||
} | ||
} | ||
|
||
class GraphqlAttribute { | ||
String name; | ||
bool isRequired; | ||
String type; | ||
String dartType; | ||
|
||
GraphqlAttribute({required this.name, required this.isRequired, required this.type, required this.dartType}); | ||
|
||
|
||
factory GraphqlAttribute.fromJson(Map<String, dynamic> json) => GraphqlAttribute( | ||
name: json['name'], | ||
isRequired: json['isRequired'], | ||
type: json['type'], | ||
dartType: _buildDartType(json['type']) | ||
); | ||
|
||
// ? String should be like: | ||
// attributeName: type! | ||
// attributeName: type | ||
factory GraphqlAttribute.fromString(String rawAttribute){ | ||
final List<String> attributeParts = rawAttribute.split(':'); | ||
|
||
final String attributeName = attributeParts.first.trim(); | ||
final bool attributeRquired = attributeParts.last.trim().endsWith('!'); | ||
final String attributeType = attributeParts.last.trim().replaceFirst('!', ''); | ||
|
||
return GraphqlAttribute( | ||
name: attributeName, | ||
isRequired: attributeRquired, | ||
type: attributeType, | ||
dartType: _buildDartType(attributeType), | ||
); | ||
} | ||
|
||
get attributeSymbol => isRequired ? '' : '?'; | ||
|
||
String get attributeDartType => isRequired ? '' : '?'; | ||
|
||
bool get isScalar => _graphqlDefaultScalarTypes.contains(type); | ||
|
||
bool get isList => dartType.startsWith('List<'); | ||
|
||
String get prettyType => _parseScalarType(type); | ||
|
||
// ignore: unnecessary_string_interpolations | ||
String get dartTypeWithoutList => '$dartType'.replaceAll('List<', '').replaceAll('>', ''); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import 'package:collection/collection.dart'; | ||
import 'package:graphql_types_builder/src/models/graphql_attribute.dart'; | ||
|
||
// ? Get type input | type | ||
final typeInputRegex = RegExp(r'input [A-Z]'); | ||
final typeTypeRegex = RegExp(r'type [A-Z]'); | ||
|
||
// ? Get attributes | ||
final attributesRegex = RegExp(r'\w{2,}?: [A-Z]\w*(!(?!.)|)'); | ||
|
||
// ? Get Name | ||
final nameRegex = RegExp(r'(?<=(input|type) )(.*?)(?= \{)'); | ||
|
||
const String tab1 = '\t'; | ||
const String tab2 = '\t\t'; | ||
const String tab3 = '\t\t\t'; | ||
|
||
|
||
class GraphQLClassGenerator { | ||
String rawGraphQLType = ''; | ||
bool identifyRequiredAttributes; | ||
|
||
String? _name = ''; | ||
// ignore: unused_field | ||
String? _type = ''; | ||
List<GraphqlAttribute> _attributes = []; | ||
|
||
|
||
GraphQLClassGenerator(this.rawGraphQLType, {this.identifyRequiredAttributes = false}); | ||
|
||
String generate() { | ||
_setUpClass(); | ||
|
||
return _writeClass(); | ||
} | ||
|
||
void _setUpClass() { | ||
_initializeType(); | ||
_initializeAttributes(); | ||
_initializeName(); | ||
} | ||
|
||
void _initializeType() { | ||
if(typeInputRegex.hasMatch(rawGraphQLType)) { | ||
_type = 'input'; | ||
return; | ||
} else if(typeTypeRegex.hasMatch(rawGraphQLType)) { | ||
_type = 'type'; | ||
return; | ||
} | ||
|
||
throw Exception('Unknown type for: $rawGraphQLType'); | ||
} | ||
|
||
void _initializeAttributes() { | ||
List<RegExpMatch> matches = attributesRegex.allMatches(rawGraphQLType).toList(); | ||
|
||
List<String> rawAttributes = matches.map((match) => match.group(0)).whereNotNull().toList(); | ||
|
||
_attributes = rawAttributes.map((rawAttribute) => GraphqlAttribute.fromString(rawAttribute)).toList(); | ||
} | ||
|
||
void _initializeName() { | ||
_name = nameRegex.stringMatch(rawGraphQLType); | ||
} | ||
|
||
String _writeClass() { | ||
final StringBuffer sb = StringBuffer(); | ||
|
||
sb.writeln('class $_name {'); | ||
sb.writeln(_writeAttributesAndConstructor()); | ||
sb.writeln('}'); | ||
|
||
return sb.toString(); | ||
} | ||
|
||
String _writeAttributesAndConstructor() { | ||
final String attributesString = _writeAttributes(); | ||
final String constructorString = _writeConstructor(); | ||
final String namedConstructorString = _writeNamedConstructor(); | ||
|
||
// TODO: Write `fromMap` contructor in another method and also write `toMap` method in another method and define the class contrsuctor. | ||
final StringBuffer sb = StringBuffer(); | ||
|
||
sb.writeln(attributesString); | ||
sb.writeln(constructorString); | ||
sb.writeln(namedConstructorString); | ||
|
||
return sb.toString(); | ||
} | ||
|
||
String _writeAttributes() { | ||
final StringBuffer sb = StringBuffer(); | ||
|
||
for (GraphqlAttribute attribute in _attributes) { | ||
String attributeSymbol = identifyRequiredAttributes ? attribute.attributeSymbol : '?'; | ||
|
||
sb.writeln('$tab1 final ${attribute.prettyType}$attributeSymbol ${attribute.name};'); | ||
} | ||
|
||
return sb.toString(); | ||
} | ||
|
||
String _writeConstructor() { | ||
final StringBuffer sb = StringBuffer(); | ||
sb.writeln('$tab1$_name({'); | ||
|
||
for (GraphqlAttribute attribute in _attributes) { | ||
sb.writeln('$tab2 this.${attribute.name},'); | ||
} | ||
|
||
sb.writeln('$tab1});'); | ||
|
||
return sb.toString(); | ||
} | ||
|
||
// ? .fromMap constructor | ||
String _writeNamedConstructor() { | ||
final StringBuffer sb = StringBuffer(); | ||
sb.writeln('$tab1 factory $_name.fromMap(Map<String, dynamic> map) {'); | ||
sb.writeln('$tab2 return $_name('); | ||
|
||
for (GraphqlAttribute attribute in _attributes) { | ||
_writeAttributeInitilization(sb, attribute); | ||
} | ||
|
||
sb.writeln('$tab2);'); | ||
sb.writeln('$tab1}'); | ||
|
||
return sb.toString(); | ||
} | ||
|
||
void _writeAttributeInitilization(StringBuffer sb, GraphqlAttribute attribute) { | ||
if (attribute.isScalar) { | ||
return sb.writeln('$tab3${attribute.name}: map["${attribute.name}"],'); | ||
} | ||
|
||
if (attribute.isList) { | ||
return sb.writeln('$tab3${attribute.name}: ${attribute.dartType}.from(map["${attribute.name}"]?.map((x) => ${attribute.dartTypeWithoutList}.fromMap(x))),'); | ||
} | ||
|
||
sb.writeln('$tab3${attribute.name}: ${attribute.dartType}.fromMap(map["${attribute.name}"]),'); | ||
} | ||
} |
Oops, something went wrong.