Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
fix: Update Validator json schemas (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanwlee authored Apr 30, 2024
1 parent 2cab7d7 commit 42e7cac
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 45 deletions.
4 changes: 2 additions & 2 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schemas:
@git submodule update --init --recursive
@cp -r tbdex/hosted/json-schemas lib/src/protocol
#!/bin/bash
dart run generate_schemas.dart

get:
@dart pub get
Expand Down
53 changes: 53 additions & 0 deletions generate_schemas.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'dart:io';
import 'package:path/path.dart' as p;

void main() {
final schemasPath = p.join('tbdex', 'hosted', 'json-schemas');
final outputDir = Directory('lib/src/protocol/json-schemas')
..createSync(recursive: true);

Directory(schemasPath)
.listSync()
.whereType<File>()
.where((file) => file.path.endsWith('.json'))
.forEach((file) {
final json = file.readAsStringSync();
final dartCode = _generateCode(file.path, json);

File(p.join(outputDir.path, '${_getFileName(file.path)}.dart'))
.writeAsStringSync(dartCode);
});
}

String _generateCode(String filePath, String jsonString) => '''
class ${_getClassName(filePath)} {
static const String json = r\'\'\'
$jsonString\'\'\';
}''';

String _getFileName(String filePath) {
var segments = p.split(filePath);
final index = segments.indexOf('json-schemas');
final baseName = segments[index + 1].split('.').first;

return '${_toSnakeCase(baseName)}_schema';
}

String _getClassName(String filePath) {
var segments = p.split(filePath);
final index = segments.indexOf('json-schemas');
final baseName = segments[index + 1].split('.').first;

return '${_toCamelCase(baseName)}Schema';
}

String _toSnakeCase(String input) => input.replaceAll('-', '_').toLowerCase();

String _toCamelCase(String input) => input
.split(RegExp('[_-]'))
.map(
(str) => str.isEmpty
? ''
: str[0].toUpperCase() + str.substring(1).toLowerCase(),
)
.join();
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class BalanceSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/balance.schema.json",
"type": "object",
Expand All @@ -18,3 +20,5 @@
"available"
]
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class CloseSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/close.schema.json",
"type": "object",
Expand All @@ -11,4 +13,5 @@
"type": "boolean"
}
}
}''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class DefinitionsSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/definitions.json",
"type": "object",
Expand All @@ -12,4 +14,5 @@
"pattern": "^([0-9]+(?:[.][0-9]+)?)$"
}
}
}''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class MessageSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/message.schema.json",
"definitions": {
Expand Down Expand Up @@ -64,3 +66,5 @@
"additionalProperties": false,
"required": ["metadata", "data", "signature"]
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class OfferingSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/offering.schema.json",
"type": "object",
Expand Down Expand Up @@ -151,3 +153,5 @@
"payoutUnitsPerPayinUnit"
]
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
class OrderSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/order.schema.json",
"type": "object",
"additionalProperties": false,
"properties": {}
}''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class OrderstatusSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/orderstatus.schema.json",
"type": "object",
Expand All @@ -11,4 +13,5 @@
"type":"string"
}
}
}''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class QuoteSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/quote.schema.json",
"definitions": {
Expand Down Expand Up @@ -55,3 +57,5 @@
},
"required": ["expiresAt", "payin", "payout"]
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
class ReputationSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/reputation.schema.json"
}''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class ResourceSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/resource.schema.json",
"type": "object",
Expand Down Expand Up @@ -48,3 +50,5 @@
"required": ["metadata", "data", "signature"],
"description": "ResourceModel"
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class RfqPrivateSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/rfq-private.schema.json",
"type": "object",
Expand Down Expand Up @@ -38,3 +40,5 @@
},
"required": ["salt"]
}
''';
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
class RfqSchema {
static const String json = r'''
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://tbdex.dev/rfq.schema.json",
"type": "object",
Expand Down Expand Up @@ -46,3 +48,5 @@
},
"required": ["offeringId", "payin", "payout"]
}
''';
}
78 changes: 47 additions & 31 deletions lib/src/protocol/validator.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import 'dart:convert';
import 'dart:io';

import 'package:json_schema/json_schema.dart';
import 'package:path/path.dart' as p;
import 'package:tbdex/src/protocol/exceptions.dart';
import 'package:tbdex/src/protocol/json-schemas/close_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/definitions_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/message_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/offering_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/order_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/orderstatus_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/quote_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/resource_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/rfq_private_schema.dart';
import 'package:tbdex/src/protocol/json-schemas/rfq_schema.dart';
import 'package:tbdex/src/protocol/models/close.dart';
import 'package:tbdex/src/protocol/models/message.dart';
import 'package:tbdex/src/protocol/models/offering.dart';
Expand Down Expand Up @@ -38,7 +47,10 @@ class Validator {

void _validate(Map<String, dynamic> json, String schemaName) {
final schema = _schemaMap[schemaName] ??
(throw TbdexValidatorException(TbdexExceptionCode.validatorNoSchema, 'no schema with name $schemaName exists'));
(throw TbdexValidatorException(
TbdexExceptionCode.validatorNoSchema,
'no schema with name $schemaName exists',
));
final validationResult = schema.validate(json);

if (!validationResult.isValid) {
Expand All @@ -49,8 +61,10 @@ class Validator {
void _validateMessage(Message message) {
final matchedKind = MessageKind.values.firstWhere(
(kind) => kind == message.metadata.kind,
orElse: () =>
throw TbdexValidatorException(TbdexExceptionCode.validatorUnknownMessageKind, 'unknown message kind: ${message.metadata.kind}'),
orElse: () => throw TbdexValidatorException(
TbdexExceptionCode.validatorUnknownMessageKind,
'unknown message kind: ${message.metadata.kind}',
),
);

switch (matchedKind) {
Expand Down Expand Up @@ -88,8 +102,10 @@ class Validator {
void _validateResource(Resource resource) {
final matchedKind = ResourceKind.values.firstWhere(
(kind) => kind == resource.metadata.kind,
orElse: () =>
throw TbdexValidatorException(TbdexExceptionCode.validatorUnknownResourceKind, 'unknown resource kind: ${resource.metadata.kind}'),
orElse: () => throw TbdexValidatorException(
TbdexExceptionCode.validatorUnknownResourceKind,
'unknown resource kind: ${resource.metadata.kind}',
),
);

switch (matchedKind) {
Expand All @@ -106,41 +122,41 @@ class Validator {

void _handleValidationError(List<ValidationError> errors) {
if (errors.isNotEmpty) {
throw TbdexValidatorException(TbdexExceptionCode.validatorJsonSchemaError, errors.join(', '));
throw TbdexValidatorException(
TbdexExceptionCode.validatorJsonSchemaError,
errors.join(', '),
);
}
}

static void _initialize() {
final schemasPath = p.join('lib', 'src', 'protocol', 'json-schemas');
final refProvider = _createRefProvider(schemasPath);

final schemaFiles = {
'close': 'close.schema.json',
'definitions': 'definitions.json',
'offering': 'offering.schema.json',
'message': 'message.schema.json',
'order': 'order.schema.json',
'orderstatus': 'orderstatus.schema.json',
'quote': 'quote.schema.json',
'resource': 'resource.schema.json',
'rfq': 'rfq.schema.json',
'rfqPrivate': 'rfq-private.schema.json',
};

for (final entry in schemaFiles.entries) {
final filePath = p.join(schemasPath, entry.value);
final schemaJsonString = File(filePath).readAsStringSync();
final schemaJson = json.decode(schemaJsonString);

_schemaMap[entry.key] =
JsonSchema.create(schemaJson, refProvider: refProvider);
}
_schemaMap['close'] =
JsonSchema.create(CloseSchema.json, refProvider: refProvider);
_schemaMap['definitions'] =
JsonSchema.create(DefinitionsSchema.json, refProvider: refProvider);
_schemaMap['offering'] =
JsonSchema.create(OfferingSchema.json, refProvider: refProvider);
_schemaMap['message'] =
JsonSchema.create(MessageSchema.json, refProvider: refProvider);
_schemaMap['order'] =
JsonSchema.create(OrderSchema.json, refProvider: refProvider);
_schemaMap['orderstatus'] =
JsonSchema.create(OrderstatusSchema.json, refProvider: refProvider);
_schemaMap['quote'] =
JsonSchema.create(QuoteSchema.json, refProvider: refProvider);
_schemaMap['resource'] =
JsonSchema.create(ResourceSchema.json, refProvider: refProvider);
_schemaMap['rfq'] =
JsonSchema.create(RfqSchema.json, refProvider: refProvider);
_schemaMap['rfqPrivate'] =
JsonSchema.create(RfqPrivateSchema.json, refProvider: refProvider);
}

static RefProvider _createRefProvider(String schemasPath) {
final schemaJson = json.decode(
File(p.join(schemasPath, 'definitions.json')).readAsStringSync(),
);
final schemaJson = json.decode(DefinitionsSchema.json);

return RefProvider.sync(
(ref) => ref == 'https://tbdex.dev/definitions.json' ? schemaJson : null,
Expand Down

0 comments on commit 42e7cac

Please sign in to comment.