Skip to content

Commit 5b46ef9

Browse files
ChreSyrSymeonOclocherkevmoo
authored
Added createJsonKeys (google#1401)
Fixes google#1400 Co-authored-by: Syméon ROUGEVIN <symeon@oclocher.fr> Co-authored-by: Kevin Moore <kevmoo@google.com>
1 parent 324acee commit 5b46ef9

18 files changed

+142
-13
lines changed

json_annotation/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## 4.8.2-wip
1+
## 4.9.0-wip
22

33
- Require Dart 3.0
4+
- Added `JsonSerializable(createJsonKeys: true)`.
5+
([#1401](https://github.com/google/json_serializable.dart/pull/1401))
46

57
## 4.8.1
68

json_annotation/lib/src/json_serializable.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ class JsonSerializable {
8787
/// such as [fieldRename].
8888
final bool? createFieldMap;
8989

90+
/// If `true` (defaults to false), a private class `_$ExampleJsonKeys`
91+
/// constant is created in the generated part file.
92+
///
93+
/// This class will contain every property, with the json key as value,
94+
/// exposing a secured way to access the json key from the property.
95+
///
96+
/// ```dart
97+
/// @JsonSerializable(createJsonKeys: true)
98+
/// class Example {
99+
/// // ...
100+
/// static const jsonKeys = _$PublicationImplJsonKeys();
101+
/// }
102+
/// ```
103+
final bool? createJsonKeys;
104+
90105
/// If `true` (defaults to false), a private, static `_$ExamplePerFieldToJson`
91106
/// abstract class will be generated in the part file.
92107
///
@@ -247,6 +262,7 @@ class JsonSerializable {
247262
this.checked,
248263
this.constructor,
249264
this.createFieldMap,
265+
this.createJsonKeys,
250266
this.createFactory,
251267
this.createToJson,
252268
this.disallowUnrecognizedKeys,

json_annotation/lib/src/json_serializable.g.dart

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_annotation/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: json_annotation
2-
version: 4.8.2-wip
2+
version: 4.9.0-wip
33
description: >-
44
Classes and helper functions that support JSON code generation via the
55
`json_serializable` package.

json_serializable/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## 6.7.2-wip
1+
## 6.8.0-wip
22

33
- Add type arguments to `Map` literals used for `Record` serialization.
4+
- Added support for generating `ExampleJsonKeys`, exposing a secured way to access the json keys from the properties.
5+
([#1164](https://github.com/google/json_serializable.dart/pull/1164))
46

57
## 6.7.1
68

json_serializable/README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ targets:
276276
constructor: ""
277277
create_factory: true
278278
create_field_map: false
279+
create_json_keys: false
279280
create_per_field_to_json: false
280281
create_to_json: true
281282
disallow_unrecognized_keys: false
@@ -297,15 +298,15 @@ targets:
297298
[`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html
298299
[`int`]: https://api.dart.dev/stable/dart-core/int-class.html
299300
[`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html
300-
[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonConverter-class.html
301-
[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum/valueField.html
302-
[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum-class.html
303-
[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/fromJson.html
304-
[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/toJson.html
305-
[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey-class.html
306-
[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonLiteral-class.html
307-
[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonSerializable-class.html
308-
[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonValue-class.html
301+
[`JsonConverter`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
302+
[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum/valueField.html
303+
[`JsonEnum`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum-class.html
304+
[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
305+
[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
306+
[`JsonKey`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey-class.html
307+
[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonLiteral-class.html
308+
[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html
309+
[`JsonValue`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonValue-class.html
309310
[`List`]: https://api.dart.dev/stable/dart-core/List-class.html
310311
[`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html
311312
[`num`]: https://api.dart.dev/stable/dart-core/num-class.html

json_serializable/lib/src/encoder_helper.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ mixin EncodeHelper implements HelperCore {
6363
return buffer.toString();
6464
}
6565

66+
/// Generates an object containing metadatas related to the encoding,
67+
/// destined to be used by other code-generators.
68+
String createJsonKeys(Set<FieldElement> accessibleFieldSet) {
69+
assert(config.createJsonKeys);
70+
71+
final buffer = StringBuffer(
72+
'abstract final class _\$${element.name.nonPrivate}JsonKeys {',
73+
);
74+
// ..write('static const _\$${element.name.nonPrivate}JsonKeys();');
75+
76+
for (final field in accessibleFieldSet) {
77+
buffer.writeln(
78+
'static const String ${field.name} = '
79+
'${escapeDartString(nameAccess(field))};',
80+
);
81+
}
82+
83+
buffer.write('}');
84+
85+
return buffer.toString();
86+
}
87+
6688
Iterable<String> createToJson(Set<FieldElement> accessibleFields) sync* {
6789
assert(config.createToJson);
6890

json_serializable/lib/src/generator_helper.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
132132
yield createFieldMap(accessibleFieldSet);
133133
}
134134

135+
if (config.createJsonKeys) {
136+
yield createJsonKeys(accessibleFieldSet);
137+
}
138+
135139
if (config.createPerFieldToJson) {
136140
yield createPerFieldToJson(accessibleFieldSet);
137141
}

json_serializable/lib/src/type_helpers/config_types.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ClassConfig {
4949
final bool createFactory;
5050
final bool createToJson;
5151
final bool createFieldMap;
52+
final bool createJsonKeys;
5253
final bool createPerFieldToJson;
5354
final bool disallowUnrecognizedKeys;
5455
final bool explicitToJson;
@@ -66,6 +67,7 @@ class ClassConfig {
6667
required this.createFactory,
6768
required this.createToJson,
6869
required this.createFieldMap,
70+
required this.createJsonKeys,
6971
required this.createPerFieldToJson,
7072
required this.disallowUnrecognizedKeys,
7173
required this.explicitToJson,
@@ -85,6 +87,8 @@ class ClassConfig {
8587
constructor: config.constructor ?? ClassConfig.defaults.constructor,
8688
createFieldMap:
8789
config.createFieldMap ?? ClassConfig.defaults.createFieldMap,
90+
createJsonKeys:
91+
config.createJsonKeys ?? ClassConfig.defaults.createJsonKeys,
8892
createPerFieldToJson: config.createPerFieldToJson ??
8993
ClassConfig.defaults.createPerFieldToJson,
9094
createFactory:
@@ -113,6 +117,7 @@ class ClassConfig {
113117
createFactory: true,
114118
createToJson: true,
115119
createFieldMap: false,
120+
createJsonKeys: false,
116121
createPerFieldToJson: false,
117122
disallowUnrecognizedKeys: false,
118123
explicitToJson: false,
@@ -129,6 +134,7 @@ class ClassConfig {
129134
createFactory: createFactory,
130135
createToJson: createToJson,
131136
createFieldMap: createFieldMap,
137+
createJsonKeys: createJsonKeys,
132138
createPerFieldToJson: createPerFieldToJson,
133139
ignoreUnannotated: ignoreUnannotated,
134140
explicitToJson: explicitToJson,

json_serializable/lib/src/utils.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ JsonSerializable _valueForAnnotation(ConstantReader reader) => JsonSerializable(
5858
createFactory: reader.read('createFactory').literalValue as bool?,
5959
createToJson: reader.read('createToJson').literalValue as bool?,
6060
createFieldMap: reader.read('createFieldMap').literalValue as bool?,
61+
createJsonKeys: reader.read('createJsonKeys').literalValue as bool?,
6162
createPerFieldToJson:
6263
reader.read('createPerFieldToJson').literalValue as bool?,
6364
disallowUnrecognizedKeys:
@@ -106,6 +107,7 @@ ClassConfig mergeConfig(
106107
createFactory: annotation.createFactory ?? config.createFactory,
107108
createToJson: annotation.createToJson ?? config.createToJson,
108109
createFieldMap: annotation.createFieldMap ?? config.createFieldMap,
110+
createJsonKeys: annotation.createJsonKeys ?? config.createJsonKeys,
109111
createPerFieldToJson:
110112
annotation.createPerFieldToJson ?? config.createPerFieldToJson,
111113
disallowUnrecognizedKeys:

json_serializable/pubspec.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: json_serializable
2-
version: 6.7.2-wip
2+
version: 6.8.0-wip
33
description: >-
44
Automatically generate code for converting to and from JSON by annotating
55
Dart classes.
@@ -29,6 +29,10 @@ dependencies:
2929
source_gen: ^1.3.2
3030
source_helper: ^1.3.0
3131

32+
dependency_overrides:
33+
json_annotation:
34+
path: ../json_annotation
35+
3236
dev_dependencies:
3337
_json_serial_shared_test:
3438
path: ../shared_test

json_serializable/test/config_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ const _invalidConfig = {
153153
'constructor': 42,
154154
'create_factory': 42,
155155
'create_field_map': 42,
156+
'create_json_keys': 42,
156157
'create_per_field_to_json': 42,
157158
'create_to_json': 42,
158159
'disallow_unrecognized_keys': 42,

json_serializable/test/integration/integration_test.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'converter_examples.dart';
1010
import 'create_per_field_to_json_example.dart';
1111
import 'field_map_example.dart';
1212
import 'json_enum_example.dart';
13+
import 'json_keys_example.dart' as js_keys;
1314
import 'json_test_common.dart' show Category, Platform, StatusCode;
1415
import 'json_test_example.dart';
1516

@@ -471,4 +472,8 @@ void main() {
471472
test('value field index fun', () {
472473
expect(enumValueFieldIndexValues, [0, 701, 2]);
473474
});
475+
476+
test('ModelJsonKeys', () {
477+
expect(js_keys.keys, {'first-name', 'LAST_NAME'});
478+
});
474479
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'package:json_annotation/json_annotation.dart';
2+
3+
part 'json_keys_example.g.dart';
4+
5+
@JsonSerializable(createJsonKeys: true, fieldRename: FieldRename.kebab)
6+
class Model {
7+
Model({
8+
required this.firstName,
9+
required this.lastName,
10+
this.ignoredName,
11+
});
12+
13+
factory Model.fromJson(Map<String, Object?> json) => _$ModelFromJson(json);
14+
15+
final String firstName;
16+
17+
@JsonKey(name: 'LAST_NAME')
18+
final String lastName;
19+
20+
@JsonKey(includeFromJson: false, includeToJson: false)
21+
final String? ignoredName;
22+
23+
String get fullName => '$firstName $lastName';
24+
25+
Map<String, Object?> toJson() => _$ModelToJson(this);
26+
}
27+
28+
// TODO: use this once https://github.com/dart-lang/sdk/issues/54543 is fixed
29+
typedef ModelJsonKeys = _$ModelJsonKeys;
30+
31+
// Work-around until https://github.com/dart-lang/sdk/issues/54543 is fixed
32+
Set<String> get keys => {_$ModelJsonKeys.firstName, _$ModelJsonKeys.lastName};

json_serializable/test/integration/json_keys_example.g.dart

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/test/shared_config.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ final generatorConfigNonDefaultJson =
2020
createFactory: false,
2121
createToJson: false,
2222
createFieldMap: true,
23+
createJsonKeys: true,
2324
createPerFieldToJson: true,
2425
disallowUnrecognizedKeys: true,
2526
explicitToJson: true,

json_serializable/test/test_sources/test_sources.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class ConfigurationImplicitDefaults {
1616
createFactory: true,
1717
createToJson: true,
1818
createFieldMap: false,
19+
createJsonKeys: false,
1920
createPerFieldToJson: false,
2021
disallowUnrecognizedKeys: false,
2122
explicitToJson: false,

json_serializable/tool/readme/readme_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ targets:
141141
constructor: ""
142142
create_factory: true
143143
create_field_map: false
144+
create_json_keys: false
144145
create_per_field_to_json: false
145146
create_to_json: true
146147
disallow_unrecognized_keys: false

0 commit comments

Comments
 (0)