Commit 8023e60d authored by Amirjanyan's avatar Amirjanyan
Browse files

Merge remote-tracking branch 'origin/dev' into 158-deduplication-flow-in-cvu

# Conflicts:
#	lib/MemriApp/Controllers/Database/DatabaseQuery.dart
parents 61290745 799ea88c
Showing with 1431 additions and 166 deletions
+1431 -166
CryptoKey {
title: "CryptoKey"
defaultRenderer: generalEditor
editActionButton: toggleEditMode
contextButtons: star
[renderer = generalEditor] {
layout: [
{ section: header, exclude: starred }
/* { section: owner, edges: owner, type: Person } */ /* TODO: Single edge */ /* TODO: Hard crash when edge iso edges */
{ section: "Key Information", fields: name type role key active }
{ section: owner, edges: owner, type: Person }
{ section: "Key Information", fields: name type role keystr active }
{ section: other, fields: * }
{ section: dates }
]
header {
showTitle: false
dividers: false
VStack {
padding: 20 36 10 36
HStack {
Text {
text: "{.active ? '' : '[INACTIVE] '}{.name or .itemType or '<Unnamed Key>'}"
......@@ -35,7 +34,7 @@ CryptoKey {
spacing: 5
show: {{.label}}
list: {{ .label[] }}
Button {
onPress: openViewByName {
viewName: all-items-with-label
......@@ -44,11 +43,11 @@ CryptoKey {
uid: {{.uid}}
}
}
VStack {
background: {{.color}}
cornerRadius: 5
Text {
text: "{.computedTitle()}"
font: 16 semibold
......@@ -58,25 +57,25 @@ CryptoKey {
}
}
}
HStack {
alignment: center
MemriButton {
edge: {{._owner}}
padding: 10 0 0 0
}
ActionButton {
show: {{!readOnly}}
font: 12 regular
margin: 8 0 0 10
onPress: openViewByName {
renderAs: popup
title: "Set Owner"
color: #2a3fe0 /* TODO: Unable to set the color */
viewName: "choose-item-by-query"
viewArguments: {
query: "Person" /* AND ANY allEdges.targetItemID = {.uid} */
......@@ -92,26 +91,26 @@ CryptoKey {
}
}
}
key {
keystr {
ZStack {
HStack {
show: {{readOnly}}
Text {
text: "******"
padding: 0 20 0 0
}
Button {
onPress: copyToClipboard {
value: {{.key}}
value: {{.keystr}}
}
Text { text: "copy" }
}
}
SecureField {
value: {{.key}}
value: {{.keystr}}
}
}
}
......@@ -124,87 +123,92 @@ CryptoKey {
emptyResultText: "There are no keys here yet"
defaultRenderer: list
sortFields: title dateModified dateAccessed dateCreated
[datasource = pod] {
query: "CryptoKey"
sortProperty: dateAccessed
sortAscending: false
}
actionButton:
addItem {
template {
_type: CryptoKey
}
}
editActionButton: toggleEditMode
filterButtons: showStarred toggleFilterPanel
}
CryptoKey > list {
VStack {
alignment: left
spacing: 3
HStack {
alignment: left
Text {
/* TODO: Bug when .role is not set still displays - {.role ? ' — ' : ''}{.role ? .role : ''} */
text: "{.active ? '' : '[INACTIVE] '}{.name or .itemType or '<Unnamed Key>'}"
lineLimit: 1
font: 18 semibold
color: {{.active ? "#333" : "#999"}}
padding: 0 0 0 0
}
Image {
systemName: "star.fill"
font: 14
color: #eecc00
margin: 5
show: {{.starred}}
}
onPress: openView {
renderer: generalEditor
}
HStack {
alignment: bottomright
VStack {
Text {
show: {{.itemType}}
text: "{.itemType}"
lineLimit: 1
removeWhiteSpace: true
maxChar: 100
color: #333
font: 14 regular
}
VStack {
alignment: left
spacing: 3
HStack {
alignment: left
Text {
/* TODO: Why does .role not work?? */
show: {{.role.count > 0}}
text: "Role: {.role.firstUppercased}"
/* TODO: Bug when .role is not set still displays - {.role ? ' — ' : ''}{.role ? .role : ''} */
text: "{.active ? '' : '[INACTIVE] '}{.name or .itemType or '<Unnamed Key>'}"
lineLimit: 1
removeWhiteSpace: true
maxChar: 100
color: #555
font: 14 regular
padding: 3 0 0 0
font: 18 semibold
color: {{.active ? "#333" : "#999"}}
padding: 0 0 0 0
}
Text {
text: "{.dateAccessed.format() or .dateCreated.format()}"
lineLimit: 1
font: 11 regular
color: #888
padding: 5 0 0 0
Image {
systemName: "star.fill"
font: 14
color: #eecc00
margin: 5
show: {{.starred}}
}
}
Spacer
MemriButton {
show: {{.owner}}
edge: {{._owner}}
HStack {
alignment: bottomright
VStack {
Text {
show: {{.itemType}}
text: "{.itemType}"
lineLimit: 1
removeWhiteSpace: true
maxChar: 100
color: #333
font: 14 regular
}
Text {
/* TODO: Why does .role not work?? */
show: {{.role}}
text: "Role: {.role.firstUppercased()}"
lineLimit: 1
removeWhiteSpace: true
maxChar: 100
color: #555
font: 14 regular
padding: 3 0 0 0
}
Text {
text: "{.dateCreated}"
lineLimit: 1
font: 11 regular
color: #888
padding: 5 0 0 0
}
}
Spacer
MemriButton {
title: "Owner"
item: {{.owner}}
}
}
}
}
}
[
{
"_type": "Setting",
"key": "defaults/general/gui/showEditButton",
"json": {
"value": true
}
},
{
"_type": "Setting",
"key": "defaults/general/gui/showDateAgo",
"json": {
"value": true
}
},
{
"_type": "Setting",
"key": "defaults/general/gui/useMapBox",
"json": {
"value": false
}
},
{
"_type": "Setting",
"key": "defaults/sensors/location/track",
"json": {
"value": false
}
},
{
"_type": "Setting",
"key": "defaults/formatting/date",
"json": {
"value": "yyyy/MM/dd HH:mm"
}
},
{
"_type": "Setting",
"key": "defaults/pod/host",
"json": {
"value": "http://localhost:3030"
}
},
{
"_type": "Setting",
"key": "defaults/pod/username",
"json": {
"value": ""
}
},
{
"_type": "Setting",
"key": "defaults/pod/password",
"json": {
"value": ""
}
},
{
"_type": "Setting",
"key": "defaults/debug/autoShowErrorConsole",
"json": {
"value": false
}
},
{
"_type": "Setting",
"key": "defaults/debug/autoReloadCVU",
"json": {
"value": true
}
},
{
"_type": "NavigationItem",
"itemType": "heading",
......@@ -153,6 +84,12 @@
"title": "addresses",
"sessionName": "allAddresses"
},
{
"_type": "NavigationItem",
"itemType": "item",
"title": "crypto keys",
"sessionName": "allCryptoKeys"
},
{
"_type": "NavigationItem",
"title": "labels",
......@@ -258,7 +195,7 @@
{
"_type": "Indexer",
"name": "Note Label Indexer",
"query": "Note",
"querystr": "Note",
"runDestination": "ios",
"itemDescription": "This indexer extracts labels from notes. You can specify aliases in the labels to add keywords that are used to match against.",
"icon": "tag"
......@@ -266,7 +203,7 @@
{
"_type": "Indexer",
"name": "Note List Indexer",
"query": "Note",
"querystr": "Note",
"indexerClass": "NotesListIndexer",
"itemDescription": "This indexer extracts lists from notes. It detects both structured and unstructured lists",
"icon": "text.badge.plus"
......
{
"properties": [
{
"item_type": "ItemPropertySchema",
"property": "itemType",
"value_type": "string"
},
{
"item_type": "ItemPropertySchema",
"property": "propertyName",
"value_type": "string"
},
{
"item_type": "ItemPropertySchema",
"property": "valueType",
"value_type": "string"
},
{
"item_type": "Account",
"property": "handle",
......@@ -162,7 +177,7 @@
},
{
"item_type": "AuditItem",
"property": "action",
"property": "actionname",
"value_type": "string"
},
{
......@@ -182,7 +197,7 @@
},
{
"item_type": "CVUStoredDefinition",
"property": "query",
"property": "querystr",
"value_type": "string"
},
{
......@@ -302,7 +317,7 @@
},
{
"item_type": "CryptoKey",
"property": "key",
"property": "keystr",
"value_type": "string"
},
{
......@@ -315,6 +330,11 @@
"property": "name",
"value_type": "string"
},
{
"item_type": "CryptoKey",
"property": "starred",
"value_type": "bool"
},
{
"item_type": "CryptoCurrency",
"property": "name",
......@@ -607,7 +627,7 @@
},
{
"item_type": "File",
"property": "key",
"property": "keystr",
"value_type": "string"
},
{
......@@ -822,7 +842,7 @@
},
{
"item_type": "Indexer",
"property": "query",
"property": "querystr",
"value_type": "string"
},
{
......@@ -857,7 +877,7 @@
},
{
"item_type": "IndexerRun",
"property": "query",
"property": "querystr",
"value_type": "string"
},
{
......@@ -1012,7 +1032,7 @@
},
{
"item_type": "MedicalCondition",
"property": "type",
"property": "conditiontype",
"value_type": "string"
},
{
......@@ -1657,7 +1677,7 @@
},
{
"item_type": "Setting",
"property": "key",
"property": "keystr",
"value_type": "string"
},
{
......@@ -2177,6 +2197,11 @@
"edge": "review",
"target_type": "Review"
},
{
"source_type": "CryptoKey",
"edge": "owner",
"target_type": "Person"
},
{
"source_type": "CryptoCurrency",
"edge": "picture",
......
......@@ -12,6 +12,10 @@ import 'package:memri/MemriApp/Controllers/Database/DatabaseController.dart';
import 'CVUUINode.dart';
import 'CVUValue.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUParsedDefinition.g.dart';
/// An enum describing the different types of definition in CVU.
/// These have different ways of being expressed in CVU eg. [renderer = ...], Text, .someViewName
enum CVUDefinitionType { view, views, uiNode, sessions, renderer, datasource, language, other }
......@@ -20,6 +24,7 @@ enum CVUDefinitionDomain { user }
/// A struct holding the content of a CVUDefinition
/// Contains properties, children, and sub-definitions
@JsonSerializable()
class CVUDefinitionContent extends CVUStringConvertible with EquatableMixin {
List<CVUParsedDefinition> definitions;
List<CVUUINode> children;
......@@ -121,11 +126,16 @@ class CVUDefinitionContent extends CVUStringConvertible with EquatableMixin {
return result;
}
factory CVUDefinitionContent.fromJson(Map<String, dynamic> json) =>
_$CVUDefinitionContentFromJson(json);
Map<String, dynamic> toJson() => _$CVUDefinitionContentToJson(this);
@override
List<Object?> get props => [definitions, children, properties];
}
/// A swift representation of a CVU definition
@JsonSerializable()
class CVUParsedDefinition extends CVUStringConvertible with EquatableMixin {
CVUDefinitionType type = CVUDefinitionType.other;
CVUDefinitionDomain domain = CVUDefinitionDomain.user;
......@@ -192,6 +202,10 @@ class CVUParsedDefinition extends CVUStringConvertible with EquatableMixin {
return result;
}
factory CVUParsedDefinition.fromJson(Map<String, dynamic> json) =>
_$CVUParsedDefinitionFromJson(json);
Map<String, dynamic> toJson() => _$CVUParsedDefinitionToJson(this);
@override
List<Object?> get props => [type, domain, selector, name, renderer, parsed];
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUParsedDefinition.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUDefinitionContent _$CVUDefinitionContentFromJson(Map<String, dynamic> json) {
return CVUDefinitionContent(
definitions: (json['definitions'] as List<dynamic>?)
?.map((e) => CVUParsedDefinition.fromJson(e as Map<String, dynamic>))
.toList(),
children: (json['children'] as List<dynamic>?)
?.map((e) => CVUUINode.fromJson(e as Map<String, dynamic>))
.toList(),
properties: (json['properties'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, CVUValue.fromJson(e)),
),
);
}
Map<String, dynamic> _$CVUDefinitionContentToJson(CVUDefinitionContent instance) =>
<String, dynamic>{
'definitions': instance.definitions,
'children': instance.children,
'properties': instance.properties,
};
CVUParsedDefinition _$CVUParsedDefinitionFromJson(Map<String, dynamic> json) {
return CVUParsedDefinition(
type: _$enumDecode(_$CVUDefinitionTypeEnumMap, json['type']),
domain: _$enumDecode(_$CVUDefinitionDomainEnumMap, json['domain']),
selector: json['selector'] as String?,
renderer: json['renderer'] as String?,
name: json['name'] as String?,
parsed: json['parsed'] == null
? null
: CVUDefinitionContent.fromJson(json['parsed'] as Map<String, dynamic>),
);
}
Map<String, dynamic> _$CVUParsedDefinitionToJson(CVUParsedDefinition instance) => <String, dynamic>{
'type': _$CVUDefinitionTypeEnumMap[instance.type],
'domain': _$CVUDefinitionDomainEnumMap[instance.domain],
'selector': instance.selector,
'name': instance.name,
'renderer': instance.renderer,
'parsed': instance.parsed,
};
K _$enumDecode<K, V>(
Map<K, V> enumValues,
Object? source, {
K? unknownValue,
}) {
if (source == null) {
throw ArgumentError(
'A value must be provided. Supported values: '
'${enumValues.values.join(', ')}',
);
}
return enumValues.entries.singleWhere(
(e) => e.value == source,
orElse: () {
if (unknownValue == null) {
throw ArgumentError(
'`$source` is not one of the supported values: '
'${enumValues.values.join(', ')}',
);
}
return MapEntry(unknownValue, enumValues.values.first);
},
).key;
}
const _$CVUDefinitionTypeEnumMap = {
CVUDefinitionType.view: 'view',
CVUDefinitionType.views: 'views',
CVUDefinitionType.uiNode: 'uiNode',
CVUDefinitionType.sessions: 'sessions',
CVUDefinitionType.renderer: 'renderer',
CVUDefinitionType.datasource: 'datasource',
CVUDefinitionType.language: 'language',
CVUDefinitionType.other: 'other',
};
const _$CVUDefinitionDomainEnumMap = {
CVUDefinitionDomain.user: 'user',
};
......@@ -9,7 +9,12 @@ import 'package:uuid/uuid.dart';
import 'CVUUIElementFamily.dart';
import 'CVUValue.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUUINode.g.dart';
/// This represents a CVU definition of how to show a data item. It can contain properties (eg. onPress action), and children (eg. UI elements to show)
@JsonSerializable()
class CVUUINode extends CVUStringConvertible with EquatableMixin {
final CVUUIElementFamily type;
List<CVUUINode> children = [];
......@@ -19,7 +24,7 @@ class CVUUINode extends CVUStringConvertible with EquatableMixin {
false; //TODO maybe there is a better way to handle flutter layout constraints and expands?
bool shouldExpandHeight = false;
var id = Uuid();
String id = Uuid().v4();
CVUUINode({required this.type, required this.children, required this.properties}) {
children.forEach((element) {
......@@ -72,6 +77,9 @@ class CVUUINode extends CVUStringConvertible with EquatableMixin {
return toCVUString(0, " ", true);
}
factory CVUUINode.fromJson(Map<String, dynamic> json) => _$CVUUINodeFromJson(json);
Map<String, dynamic> toJson() => _$CVUUINodeToJson(this);
@override
List<Object?> get props => [type, children, properties, id];
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUUINode.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUUINode _$CVUUINodeFromJson(Map<String, dynamic> json) {
return CVUUINode(
type: _$enumDecode(_$CVUUIElementFamilyEnumMap, json['type']),
children: (json['children'] as List<dynamic>)
.map((e) => CVUUINode.fromJson(e as Map<String, dynamic>))
.toList(),
properties: (json['properties'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, CVUValue.fromJson(e)),
),
)
..shouldExpandWidth = json['shouldExpandWidth'] as bool
..shouldExpandHeight = json['shouldExpandHeight'] as bool
..id = json['id'] as String;
}
Map<String, dynamic> _$CVUUINodeToJson(CVUUINode instance) => <String, dynamic>{
'type': _$CVUUIElementFamilyEnumMap[instance.type],
'children': instance.children,
'properties': instance.properties,
'shouldExpandWidth': instance.shouldExpandWidth,
'shouldExpandHeight': instance.shouldExpandHeight,
'id': instance.id,
};
K _$enumDecode<K, V>(
Map<K, V> enumValues,
Object? source, {
K? unknownValue,
}) {
if (source == null) {
throw ArgumentError(
'A value must be provided. Supported values: '
'${enumValues.values.join(', ')}',
);
}
return enumValues.entries.singleWhere(
(e) => e.value == source,
orElse: () {
if (unknownValue == null) {
throw ArgumentError(
'`$source` is not one of the supported values: '
'${enumValues.values.join(', ')}',
);
}
return MapEntry(unknownValue, enumValues.values.first);
},
).key;
}
const _$CVUUIElementFamilyEnumMap = {
CVUUIElementFamily.ForEach: 'ForEach',
CVUUIElementFamily.VStack: 'VStack',
CVUUIElementFamily.HStack: 'HStack',
CVUUIElementFamily.ZStack: 'ZStack',
CVUUIElementFamily.FlowStack: 'FlowStack',
CVUUIElementFamily.Text: 'Text',
CVUUIElementFamily.SmartText: 'SmartText',
CVUUIElementFamily.Textfield: 'Textfield',
CVUUIElementFamily.Image: 'Image',
CVUUIElementFamily.Toggle: 'Toggle',
CVUUIElementFamily.Picker: 'Picker',
CVUUIElementFamily.MemriButton: 'MemriButton',
CVUUIElementFamily.Button: 'Button',
CVUUIElementFamily.ActionButton: 'ActionButton',
CVUUIElementFamily.Map: 'Map',
CVUUIElementFamily.Empty: 'Empty',
CVUUIElementFamily.Spacer: 'Spacer',
CVUUIElementFamily.Divider: 'Divider',
CVUUIElementFamily.HorizontalLine: 'HorizontalLine',
CVUUIElementFamily.Circle: 'Circle',
CVUUIElementFamily.Rectangle: 'Rectangle',
CVUUIElementFamily.EditorSection: 'EditorSection',
CVUUIElementFamily.EditorRow: 'EditorRow',
CVUUIElementFamily.SubView: 'SubView',
CVUUIElementFamily.HTMLView: 'HTMLView',
CVUUIElementFamily.TimelineItem: 'TimelineItem',
CVUUIElementFamily.FileThumbnail: 'FileThumbnail',
CVUUIElementFamily.Null: 'Null',
CVUUIElementFamily.Grid: 'Grid',
};
......@@ -12,46 +12,85 @@ import 'CVUParsedDefinition.dart';
import 'CVUValue_Constant.dart';
import 'CVUValue_Expression.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUValue.g.dart';
@JsonSerializable()
class CVUValueExpression extends CVUValue {
final CVUExpressionNode value;
CVUValueExpression(this.value);
factory CVUValueExpression.fromJson(Map<String, dynamic> json) =>
_$CVUValueExpressionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueExpressionToJson(this)..addAll({"type": runtimeType.toString()});
}
@JsonSerializable()
class CVUValueConstant extends CVUValue {
final CVUConstant value;
CVUValueConstant(this.value);
factory CVUValueConstant.fromJson(Map<String, dynamic> json) => _$CVUValueConstantFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueConstantToJson(this)..addAll({"type": runtimeType.toString()});
}
@JsonSerializable()
class CVUValueItem extends CVUValue {
final int value;
CVUValueItem(this.value);
factory CVUValueItem.fromJson(Map<String, dynamic> json) => _$CVUValueItemFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueItemToJson(this)..addAll({"type": runtimeType.toString()});
}
@JsonSerializable()
class CVUValueArray extends CVUValue {
final List<CVUValue> value;
CVUValueArray(this.value);
factory CVUValueArray.fromJson(Map<String, dynamic> json) => _$CVUValueArrayFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueArrayToJson(this)..addAll({"type": runtimeType.toString()});
}
@JsonSerializable()
class CVUValueDictionary extends CVUValue {
final Map<String, CVUValue> value;
CVUValueDictionary(this.value);
factory CVUValueDictionary.fromJson(Map<String, dynamic> json) =>
_$CVUValueDictionaryFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueDictionaryToJson(this)..addAll({"type": runtimeType.toString()});
}
@JsonSerializable()
class CVUValueSubdefinition extends CVUValue {
final CVUDefinitionContent value;
CVUValueSubdefinition(this.value);
factory CVUValueSubdefinition.fromJson(Map<String, dynamic> json) =>
_$CVUValueSubdefinitionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUValueSubdefinitionToJson(this)..addAll({"type": runtimeType.toString()});
}
/// A value of a CVU property that can be serialised both to CVU format and to JSON
abstract class CVUValue with EquatableMixin implements CVUStringConvertible {
get value;
CVUValue();
@override
String toCVUString(int depth, String tab, bool includeInitialTab) {
var cvuValue = this;
......@@ -92,6 +131,27 @@ abstract class CVUValue with EquatableMixin implements CVUStringConvertible {
}
}
factory CVUValue.fromJson(json) {
switch (json["type"]) {
case "CVUValueExpression":
return CVUValueExpression.fromJson(json);
case "CVUValueConstant":
return CVUValueConstant.fromJson(json);
case "CVUValueItem":
return CVUValueItem.fromJson(json);
case "CVUValueArray":
return CVUValueArray.fromJson(json);
case "CVUValueDictionary":
return CVUValueDictionary.fromJson(json);
case "CVUValueSubdefinition":
return CVUValueSubdefinition.fromJson(json);
default:
throw Exception("Unknown CVUValue: ${json["type"]}");
}
}
Map<String, dynamic> toJson();
@override
List<Object?> get props => [value];
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUValue.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUValueExpression _$CVUValueExpressionFromJson(Map<String, dynamic> json) {
return CVUValueExpression(
CVUExpressionNode.fromJson(json['value']),
);
}
Map<String, dynamic> _$CVUValueExpressionToJson(CVUValueExpression instance) => <String, dynamic>{
'value': instance.value,
};
CVUValueConstant _$CVUValueConstantFromJson(Map<String, dynamic> json) {
return CVUValueConstant(
CVUConstant.fromJson(json['value']),
);
}
Map<String, dynamic> _$CVUValueConstantToJson(CVUValueConstant instance) => <String, dynamic>{
'value': instance.value,
};
CVUValueItem _$CVUValueItemFromJson(Map<String, dynamic> json) {
return CVUValueItem(
json['value'] as int,
);
}
Map<String, dynamic> _$CVUValueItemToJson(CVUValueItem instance) => <String, dynamic>{
'value': instance.value,
};
CVUValueArray _$CVUValueArrayFromJson(Map<String, dynamic> json) {
return CVUValueArray(
(json['value'] as List<dynamic>).map((e) => CVUValue.fromJson(e)).toList(),
);
}
Map<String, dynamic> _$CVUValueArrayToJson(CVUValueArray instance) => <String, dynamic>{
'value': instance.value,
};
CVUValueDictionary _$CVUValueDictionaryFromJson(Map<String, dynamic> json) {
return CVUValueDictionary(
(json['value'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, CVUValue.fromJson(e)),
),
);
}
Map<String, dynamic> _$CVUValueDictionaryToJson(CVUValueDictionary instance) => <String, dynamic>{
'value': instance.value,
};
CVUValueSubdefinition _$CVUValueSubdefinitionFromJson(Map<String, dynamic> json) {
return CVUValueSubdefinition(
CVUDefinitionContent.fromJson(json['value'] as Map<String, dynamic>),
);
}
Map<String, dynamic> _$CVUValueSubdefinitionToJson(CVUValueSubdefinition instance) =>
<String, dynamic>{
'value': instance.value,
};
......@@ -5,9 +5,19 @@
// Created by T Brennan on 28/1/21.
//
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUValue_Constant.g.dart';
/// A constant value that can be serialised to/from CVU and JSON
/// This can be an argument (single word string with no quotes), string, number, bool, colorHex (eg. #FFFFFF), or nil
abstract class CVUConstant {
abstract class CVUConstant with EquatableMixin {
get value => null;
CVUConstant();
/// Get a string representation of the value
String asString() {
var cvuConstant = this;
......@@ -118,42 +128,90 @@ abstract class CVUConstant {
throw Exception("Unknown CVUConstant ${cvuConstant.toString()}");
}
}
factory CVUConstant.fromJson(json) {
switch (json["type"]) {
case "CVUConstantArgument":
return CVUConstantArgument.fromJson(json);
case "CVUConstantNumber":
return CVUConstantNumber.fromJson(json);
case "CVUConstantInt":
return CVUConstantInt.fromJson(json);
case "CVUConstantString":
return CVUConstantString.fromJson(json);
case "CVUConstantBool":
return CVUConstantBool.fromJson(json);
case "CVUConstantColorHex":
return CVUConstantColorHex.fromJson(json);
case "CVUConstantNil":
return CVUConstantNil();
default:
throw Exception("Unknown CVUConstant: ${json["type"]}");
}
}
Map<String, dynamic> toJson() => {'value': value, 'type': runtimeType.toString()};
@override
List<Object?> get props => [value];
}
@JsonSerializable(createToJson: false)
class CVUConstantArgument extends CVUConstant {
final String value;
CVUConstantArgument(this.value);
factory CVUConstantArgument.fromJson(Map<String, dynamic> json) =>
_$CVUConstantArgumentFromJson(json);
}
@JsonSerializable(createToJson: false)
class CVUConstantNumber extends CVUConstant {
final double value;
CVUConstantNumber(this.value);
factory CVUConstantNumber.fromJson(Map<String, dynamic> json) =>
_$CVUConstantNumberFromJson(json);
}
@JsonSerializable(createToJson: false)
class CVUConstantInt extends CVUConstant {
final int value;
CVUConstantInt(this.value);
factory CVUConstantInt.fromJson(Map<String, dynamic> json) => _$CVUConstantIntFromJson(json);
}
@JsonSerializable(createToJson: false)
class CVUConstantString extends CVUConstant {
final String value;
CVUConstantString(this.value);
factory CVUConstantString.fromJson(Map<String, dynamic> json) =>
_$CVUConstantStringFromJson(json);
}
@JsonSerializable(createToJson: false)
class CVUConstantBool extends CVUConstant {
final bool value;
CVUConstantBool(this.value);
factory CVUConstantBool.fromJson(Map<String, dynamic> json) => _$CVUConstantBoolFromJson(json);
}
@JsonSerializable(createToJson: false)
class CVUConstantColorHex extends CVUConstant {
final String value;
CVUConstantColorHex(this.value);
factory CVUConstantColorHex.fromJson(Map<String, dynamic> json) =>
_$CVUConstantColorHexFromJson(json);
}
class CVUConstantNil extends CVUConstant {}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUValue_Constant.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUConstantArgument _$CVUConstantArgumentFromJson(Map<String, dynamic> json) {
return CVUConstantArgument(
json['value'] as String,
);
}
CVUConstantNumber _$CVUConstantNumberFromJson(Map<String, dynamic> json) {
return CVUConstantNumber(
(json['value'] as num).toDouble(),
);
}
CVUConstantInt _$CVUConstantIntFromJson(Map<String, dynamic> json) {
return CVUConstantInt(
json['value'] as int,
);
}
CVUConstantString _$CVUConstantStringFromJson(Map<String, dynamic> json) {
return CVUConstantString(
json['value'] as String,
);
}
CVUConstantBool _$CVUConstantBoolFromJson(Map<String, dynamic> json) {
return CVUConstantBool(
json['value'] as bool,
);
}
CVUConstantColorHex _$CVUConstantColorHexFromJson(Map<String, dynamic> json) {
return CVUConstantColorHex(
json['value'] as String,
);
}
......@@ -11,6 +11,9 @@ import 'package:memri/MemriApp/CVU/parsing/CVUExpressionLexer.dart';
import 'package:memri/MemriApp/CVU/parsing/CVUExpressionParser.dart';
import 'CVUValue_LookupNode.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUValue_Expression.g.dart';
/// A CVU Expression node. Nodes are nestable and the chain ends in either a CVU constant or a lookup node.
abstract class CVUExpressionNode extends Equatable {
......@@ -18,6 +21,8 @@ abstract class CVUExpressionNode extends Equatable {
return "$this";
}
CVUExpressionNode();
static CVUExpressionNode create(String code, bool stringMode) {
CVUExpressionLexer lexer = CVUExpressionLexer(code, stringMode);
List<ExprToken> tokens = lexer.tokenize();
......@@ -71,122 +76,318 @@ abstract class CVUExpressionNode extends Equatable {
}
}
factory CVUExpressionNode.fromJson(json) {
switch (json["type"]) {
case "CVUExpressionNodeLookup":
return CVUExpressionNodeLookup.fromJson(json);
case "CVUExpressionNodeStringMode":
return CVUExpressionNodeStringMode.fromJson(json);
case "CVUExpressionNodeConditional":
return CVUExpressionNodeConditional.fromJson(json);
case "CVUExpressionNodeOr":
return CVUExpressionNodeOr.fromJson(json);
case "CVUExpressionNodeNegation":
return CVUExpressionNodeNegation.fromJson(json);
case "CVUExpressionNodeAddition":
return CVUExpressionNodeAddition.fromJson(json);
case "CVUExpressionNodeSubtraction":
return CVUExpressionNodeSubtraction.fromJson(json);
case "CVUExpressionNodeMultiplication":
return CVUExpressionNodeMultiplication.fromJson(json);
case "CVUExpressionNodeDivision":
return CVUExpressionNodeDivision.fromJson(json);
case "CVUExpressionNodeConstant":
return CVUExpressionNodeConstant.fromJson(json);
case "CVUExpressionNodeLessThan":
return CVUExpressionNodeLessThan.fromJson(json);
case "CVUExpressionNodeGreaterThan":
return CVUExpressionNodeGreaterThan.fromJson(json);
case "CVUExpressionNodeLessThanOrEqual":
return CVUExpressionNodeLessThanOrEqual.fromJson(json);
case "CVUExpressionNodeGreaterThanOrEqual":
return CVUExpressionNodeGreaterThanOrEqual.fromJson(json);
case "CVUExpressionNodeAreEqual":
return CVUExpressionNodeAreEqual.fromJson(json);
case "CVUExpressionNodeAreNotEqual":
return CVUExpressionNodeAreNotEqual.fromJson(json);
case "CVUExpressionNodeAnd":
return CVUExpressionNodeAnd.fromJson(json);
default:
throw Exception("Unknown CVUExpressionNode: ${json["type"]}");
}
}
Map<String, dynamic> toJson();
@override
List<Object?> get props => [];
}
@JsonSerializable()
class CVUExpressionNodeLookup extends CVUExpressionNode {
final List<CVULookupNode> nodes;
CVUExpressionNodeLookup(this.nodes);
factory CVUExpressionNodeLookup.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeLookupFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeLookupToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [nodes];
}
@JsonSerializable()
class CVUExpressionNodeStringMode extends CVUExpressionNode {
final List<CVUExpressionNode> nodes;
CVUExpressionNodeStringMode(this.nodes);
factory CVUExpressionNodeStringMode.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeStringModeFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeStringModeToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [nodes];
}
@JsonSerializable()
class CVUExpressionNodeConditional extends CVUExpressionNode {
final CVUExpressionNode condition;
final CVUExpressionNode trueExp;
final CVUExpressionNode falseExp;
CVUExpressionNodeConditional(this.condition, this.trueExp, this.falseExp);
factory CVUExpressionNodeConditional.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeConditionalFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeConditionalToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [condition, trueExp, falseExp];
}
@JsonSerializable()
class CVUExpressionNodeOr extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeOr(this.lhs, this.rhs);
factory CVUExpressionNodeOr.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeOrFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeOrToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeNegation extends CVUExpressionNode {
final CVUExpressionNode expression;
CVUExpressionNodeNegation(this.expression);
factory CVUExpressionNodeNegation.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeNegationFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeNegationToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [expression];
}
@JsonSerializable()
class CVUExpressionNodeAddition extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeAddition(this.lhs, this.rhs);
factory CVUExpressionNodeAddition.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeAdditionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeAdditionToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeSubtraction extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeSubtraction(this.lhs, this.rhs);
factory CVUExpressionNodeSubtraction.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeSubtractionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeSubtractionToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeMultiplication extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeMultiplication(this.lhs, this.rhs);
factory CVUExpressionNodeMultiplication.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeMultiplicationFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeMultiplicationToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeDivision extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeDivision(this.lhs, this.rhs);
factory CVUExpressionNodeDivision.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeDivisionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeDivisionToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeConstant extends CVUExpressionNode {
final CVUConstant value;
CVUExpressionNodeConstant(this.value);
factory CVUExpressionNodeConstant.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeConstantFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeConstantToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [value];
}
@JsonSerializable()
class CVUExpressionNodeLessThan extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeLessThan(this.lhs, this.rhs);
factory CVUExpressionNodeLessThan.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeLessThanFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeLessThanToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeGreaterThan extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeGreaterThan(this.lhs, this.rhs);
factory CVUExpressionNodeGreaterThan.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeGreaterThanFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeGreaterThanToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeLessThanOrEqual extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeLessThanOrEqual(this.lhs, this.rhs);
factory CVUExpressionNodeLessThanOrEqual.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeLessThanOrEqualFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeLessThanOrEqualToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeGreaterThanOrEqual extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeGreaterThanOrEqual(this.lhs, this.rhs);
factory CVUExpressionNodeGreaterThanOrEqual.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeGreaterThanOrEqualFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeGreaterThanOrEqualToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeAreEqual extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeAreEqual(this.lhs, this.rhs);
factory CVUExpressionNodeAreEqual.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeAreEqualFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeAreEqualToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeAreNotEqual extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeAreNotEqual(this.lhs, this.rhs);
factory CVUExpressionNodeAreNotEqual.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeAreNotEqualFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeAreNotEqualToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
@JsonSerializable()
class CVUExpressionNodeAnd extends CVUExpressionNode {
final CVUExpressionNode lhs;
final CVUExpressionNode rhs;
CVUExpressionNodeAnd(this.lhs, this.rhs);
factory CVUExpressionNodeAnd.fromJson(Map<String, dynamic> json) =>
_$CVUExpressionNodeAndFromJson(json);
Map<String, dynamic> toJson() =>
_$CVUExpressionNodeAndToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [lhs, rhs];
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUValue_Expression.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUExpressionNodeLookup _$CVUExpressionNodeLookupFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeLookup(
(json['nodes'] as List<dynamic>)
.map((e) => CVULookupNode.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
Map<String, dynamic> _$CVUExpressionNodeLookupToJson(CVUExpressionNodeLookup instance) =>
<String, dynamic>{
'nodes': instance.nodes,
};
CVUExpressionNodeStringMode _$CVUExpressionNodeStringModeFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeStringMode(
(json['nodes'] as List<dynamic>).map((e) => CVUExpressionNode.fromJson(e)).toList(),
);
}
Map<String, dynamic> _$CVUExpressionNodeStringModeToJson(CVUExpressionNodeStringMode instance) =>
<String, dynamic>{
'nodes': instance.nodes,
};
CVUExpressionNodeConditional _$CVUExpressionNodeConditionalFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeConditional(
CVUExpressionNode.fromJson(json['condition']),
CVUExpressionNode.fromJson(json['trueExp']),
CVUExpressionNode.fromJson(json['falseExp']),
);
}
Map<String, dynamic> _$CVUExpressionNodeConditionalToJson(CVUExpressionNodeConditional instance) =>
<String, dynamic>{
'condition': instance.condition,
'trueExp': instance.trueExp,
'falseExp': instance.falseExp,
};
CVUExpressionNodeOr _$CVUExpressionNodeOrFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeOr(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeOrToJson(CVUExpressionNodeOr instance) => <String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeNegation _$CVUExpressionNodeNegationFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeNegation(
CVUExpressionNode.fromJson(json['expression']),
);
}
Map<String, dynamic> _$CVUExpressionNodeNegationToJson(CVUExpressionNodeNegation instance) =>
<String, dynamic>{
'expression': instance.expression,
};
CVUExpressionNodeAddition _$CVUExpressionNodeAdditionFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeAddition(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeAdditionToJson(CVUExpressionNodeAddition instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeSubtraction _$CVUExpressionNodeSubtractionFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeSubtraction(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeSubtractionToJson(CVUExpressionNodeSubtraction instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeMultiplication _$CVUExpressionNodeMultiplicationFromJson(
Map<String, dynamic> json) {
return CVUExpressionNodeMultiplication(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeMultiplicationToJson(
CVUExpressionNodeMultiplication instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeDivision _$CVUExpressionNodeDivisionFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeDivision(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeDivisionToJson(CVUExpressionNodeDivision instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeConstant _$CVUExpressionNodeConstantFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeConstant(
CVUConstant.fromJson(json['value']),
);
}
Map<String, dynamic> _$CVUExpressionNodeConstantToJson(CVUExpressionNodeConstant instance) =>
<String, dynamic>{
'value': instance.value,
};
CVUExpressionNodeLessThan _$CVUExpressionNodeLessThanFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeLessThan(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeLessThanToJson(CVUExpressionNodeLessThan instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeGreaterThan _$CVUExpressionNodeGreaterThanFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeGreaterThan(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeGreaterThanToJson(CVUExpressionNodeGreaterThan instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeLessThanOrEqual _$CVUExpressionNodeLessThanOrEqualFromJson(
Map<String, dynamic> json) {
return CVUExpressionNodeLessThanOrEqual(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeLessThanOrEqualToJson(
CVUExpressionNodeLessThanOrEqual instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeGreaterThanOrEqual _$CVUExpressionNodeGreaterThanOrEqualFromJson(
Map<String, dynamic> json) {
return CVUExpressionNodeGreaterThanOrEqual(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeGreaterThanOrEqualToJson(
CVUExpressionNodeGreaterThanOrEqual instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeAreEqual _$CVUExpressionNodeAreEqualFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeAreEqual(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeAreEqualToJson(CVUExpressionNodeAreEqual instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeAreNotEqual _$CVUExpressionNodeAreNotEqualFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeAreNotEqual(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeAreNotEqualToJson(CVUExpressionNodeAreNotEqual instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
CVUExpressionNodeAnd _$CVUExpressionNodeAndFromJson(Map<String, dynamic> json) {
return CVUExpressionNodeAnd(
CVUExpressionNode.fromJson(json['lhs']),
CVUExpressionNode.fromJson(json['rhs']),
);
}
Map<String, dynamic> _$CVUExpressionNodeAndToJson(CVUExpressionNodeAnd instance) =>
<String, dynamic>{
'lhs': instance.lhs,
'rhs': instance.rhs,
};
......@@ -5,10 +5,16 @@
// Created by T Brennan on 28/1/21.
//
import 'package:equatable/equatable.dart';
import 'CVUValue_Expression.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUValue_LookupNode.g.dart';
/// A single node in a CVU Expression lookup. The `default` node (`.` in CVU) represents the current item in the CVU context
class CVULookupNode {
@JsonSerializable()
class CVULookupNode with EquatableMixin {
String name;
bool isArray;
CVULookupType type;
......@@ -29,20 +35,66 @@ class CVULookupNode {
return '$name${isArray ? "[]" : ""}';
}
}
factory CVULookupNode.fromJson(Map<String, dynamic> json) => _$CVULookupNodeFromJson(json);
Map<String, dynamic> toJson() => _$CVULookupNodeToJson(this);
@override
List<Object?> get props => [name, isArray, type];
}
class CVULookupTypeDefault extends CVULookupType {}
class CVULookupTypeDefault extends CVULookupType {
Map<String, dynamic> toJson() => {"type": runtimeType.toString()};
@override
List<Object?> get props => [];
}
@JsonSerializable()
class CVULookupTypeLookup extends CVULookupType {
final CVUExpressionNode? subExpression;
CVULookupTypeLookup([this.subExpression]);
factory CVULookupTypeLookup.fromJson(Map<String, dynamic> json) =>
_$CVULookupTypeLookupFromJson(json);
Map<String, dynamic> toJson() =>
_$CVULookupTypeLookupToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [subExpression];
}
@JsonSerializable()
class CVULookupTypeFunction extends CVULookupType {
final List<CVUExpressionNode> args;
CVULookupTypeFunction(this.args);
factory CVULookupTypeFunction.fromJson(Map<String, dynamic> json) =>
_$CVULookupTypeFunctionFromJson(json);
Map<String, dynamic> toJson() =>
_$CVULookupTypeFunctionToJson(this)..addAll({"type": runtimeType.toString()});
@override
List<Object?> get props => [args];
}
abstract class CVULookupType {}
abstract class CVULookupType with EquatableMixin {
CVULookupType();
factory CVULookupType.fromJson(json) {
switch (json["type"]) {
case "CVULookupTypeDefault":
return CVULookupTypeDefault();
case "CVULookupTypeLookup":
return CVULookupTypeLookup.fromJson(json);
case "CVULookupTypeFunction":
return CVULookupTypeFunction.fromJson(json);
default:
throw Exception("Unknown CVULookupType: ${json["type"]}");
}
}
Map<String, dynamic> toJson();
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUValue_LookupNode.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVULookupNode _$CVULookupNodeFromJson(Map<String, dynamic> json) {
return CVULookupNode(
name: json['name'] as String,
type: CVULookupType.fromJson(json['type']),
isArray: json['isArray'] as bool,
);
}
Map<String, dynamic> _$CVULookupNodeToJson(CVULookupNode instance) => <String, dynamic>{
'name': instance.name,
'isArray': instance.isArray,
'type': instance.type,
};
CVULookupTypeLookup _$CVULookupTypeLookupFromJson(Map<String, dynamic> json) {
return CVULookupTypeLookup(
json['subExpression'] == null ? null : CVUExpressionNode.fromJson(json['subExpression']),
);
}
Map<String, dynamic> _$CVULookupTypeLookupToJson(CVULookupTypeLookup instance) => <String, dynamic>{
'subExpression': instance.subExpression,
};
CVULookupTypeFunction _$CVULookupTypeFunctionFromJson(Map<String, dynamic> json) {
return CVULookupTypeFunction(
(json['args'] as List<dynamic>).map((e) => CVUExpressionNode.fromJson(e)).toList(),
);
}
Map<String, dynamic> _$CVULookupTypeFunctionToJson(CVULookupTypeFunction instance) =>
<String, dynamic>{
'args': instance.args,
};
......@@ -9,6 +9,11 @@ import 'package:equatable/equatable.dart';
import 'package:memri/MemriApp/CVU/definitions/CVUValue.dart';
import 'package:memri/MemriApp/Controllers/Database/ItemRecord.dart';
import 'package:json_annotation/json_annotation.dart';
part 'CVUViewArguments.g.dart';
@JsonSerializable()
class CVUViewArguments with EquatableMixin {
// The view arguments
Map<String, CVUValue> args;
......@@ -22,6 +27,9 @@ class CVUViewArguments with EquatableMixin {
CVUViewArguments({Map<String, CVUValue>? args, this.argumentItem, this.parentArguments})
: this.args = args ?? {};
factory CVUViewArguments.fromJson(Map<String, dynamic> json) => _$CVUViewArgumentsFromJson(json);
Map<String, dynamic> toJson() => _$CVUViewArgumentsToJson(this);
@override
List<Object?> get props => [args, argumentItem, parentArguments];
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'CVUViewArguments.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CVUViewArguments _$CVUViewArgumentsFromJson(Map<String, dynamic> json) {
return CVUViewArguments(
args: (json['args'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, CVUValue.fromJson(e)),
),
argumentItem: json['argumentItem'] == null
? null
: ItemRecord.fromJson(json['argumentItem'] as Map<String, dynamic>),
parentArguments: json['parentArguments'] == null
? null
: CVUViewArguments.fromJson(json['parentArguments'] as Map<String, dynamic>),
);
}
Map<String, dynamic> _$CVUViewArgumentsToJson(CVUViewArguments instance) => <String, dynamic>{
'args': instance.args,
'argumentItem': instance.argumentItem,
'parentArguments': instance.parentArguments,
};
......@@ -18,7 +18,7 @@ class PodAPIConnectionDetails {
{this.scheme = "http",
this.host = "localhost",
this.port = 3030,
this.apiVersion = "v2",
this.apiVersion = "v3",
this.ownerKey = "ownerKeyHere",
this.databaseKey = "databaseKeyHere"});
}
import 'PodAPIConnectionDetails.dart';
/// A type representing the most common `post` body for pod API requests.
/// This typically includes a database key, and a payload (different for each API endpoints)
class PodAPIRequestBody<Payload> {
Map<String, String> auth;
Payload payload;
PodAPIRequestBody({required PodAPIConnectionDetails connectionConfig, required this.payload})
: auth = {
"type": "ClientAuth",
"databaseKey": connectionConfig.databaseKey
}; //TODO: change to pair, when encrypt will be implemented
Map toJson() => {'auth': auth, 'payload': payload};
}
/// A namespace for types representing Pod API payloads. Refer to pod API documentation for expected payloads for each API.
abstract class PodAPIPayload {
Map<String, dynamic> toJson() => {};
}
class PodAPIPayloadEmptyPayload extends PodAPIPayload {}
class PodAPIPayloadFileSHA extends PodAPIPayload {
String sha;
PodAPIPayloadFileSHA(this.sha);
toJson() => {
'sha': sha,
};
}
class PodAPIPayloadItemId extends PodAPIPayload {
String uid;
PodAPIPayloadItemId(this.uid);
toJson() => {
'uid': uid,
};
}
class PodAPIPayloadItemUIDList extends PodAPIPayload {
Set<String> uids;
PodAPIPayloadItemUIDList(this.uids);
toJson() => {
'uids': uids,
};
}
class PodAPIPayloadItemUIDWithServicePayload extends PodAPIPayload {
String uid;
PodAPIPayloadServicePayload servicePayload;
PodAPIPayloadItemUIDWithServicePayload({required this.uid, required this.servicePayload});
toJson() => {'uid': uid, 'servicePayload': servicePayload};
}
/// Some of the pod APIs require a `servicePayload` included in the main payload
class PodAPIPayloadServicePayload extends PodAPIPayload {
String databaseKey;
String ownerKey;
PodAPIPayloadServicePayload(PodAPIConnectionDetails connectionConfig)
: databaseKey = connectionConfig.databaseKey,
ownerKey = connectionConfig.ownerKey;
toJson() => {
'databaseKey': databaseKey,
'ownerKey': ownerKey,
};
}
class PodAPIPayloadBulkAction extends PodAPIPayload {
List<Map<String, dynamic>> createItems;
List<Map<String, dynamic>> updateItems;
List<Map<String, dynamic>> createEdges;
List<String> deleteItems;
PodAPIPayloadBulkAction(
{required this.createItems,
required this.updateItems,
required this.deleteItems,
required this.createEdges});
toJson() => {
'createItems': createItems,
'updateItems': updateItems,
'deleteItems': deleteItems,
'createEdges': createEdges
};
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'PodAPIConnectionDetails.dart';
import 'PodAPIPayloads.dart';
enum HTTPMethod { get, post, delete, put }
extension HTTPMethodExtension on HTTPMethod {
String get inString {
return this.toString().toUpperCase();
}
}
class PodAPIStandardRequest<Payload> {
HTTPMethod method = HTTPMethod.post;
String path;
Map<String, String> headers;
Payload payload;
PodAPIStandardRequest(
{this.method = HTTPMethod.post, required this.path, headers, required this.payload})
: headers = headers ?? {"content-type": "application/json"};
Future<http.Response> _executeRequest(PodAPIConnectionDetails connectionConfig) async {
Uri url = Uri(
scheme: connectionConfig.scheme,
host: connectionConfig.host,
port: connectionConfig.port,
path: "/${connectionConfig.apiVersion}/${connectionConfig.ownerKey}/$path");
/// For a `post` request (or other types of request) encode our payload into the body of the request.
var body = jsonEncode(PodAPIRequestBody(connectionConfig: connectionConfig, payload: payload));
switch (method) {
case HTTPMethod.get:
if (payload is PodAPIPayload) {
if (path == "version") {
url = Uri(
scheme: connectionConfig.scheme,
host: connectionConfig.host,
port: connectionConfig.port,
path: "/$path");
} else {
url = Uri(
scheme: connectionConfig.scheme,
host: connectionConfig.host,
port: connectionConfig.port,
path: "/${connectionConfig.apiVersion}/${connectionConfig.ownerKey}/$path",
queryParameters: (payload as PodAPIPayload).toJson());
}
}
/// For a `get` request, encode our payload into the URL.
return await http.get(url, headers: headers);
case HTTPMethod.post:
return await http.post(url, headers: headers, body: body);
case HTTPMethod.delete:
return await http.delete(url, headers: headers, body: body);
case HTTPMethod.put:
return await http.put(url, headers: headers, body: body);
}
}
Future<http.Response> execute(PodAPIConnectionDetails connectionConfig) async {
return await _executeRequest(connectionConfig);
}
/*static PodAPIStandardRequest getItemWithEdges(PodAPIPayload id) {
// Note payload is just item UID (no JSON)
var payload = id;
return PodAPIStandardRequest(path: "get_item", payload: payload);
}
static PodAPIStandardRequest getItemsWithEdges(Set<String> itemIDs) {
var payload = PodAPIPayloadItemUIDList(itemIDs);
return PodAPIStandardRequest(path: "get_items_with_edges", payload: payload);
}*/
static PodAPIStandardRequest searchAction<Payload>(Payload payload) {
return PodAPIStandardRequest(path: "search", payload: payload);
}
static PodAPIStandardRequest createItem(Map<String, dynamic> syncDict) {
return PodAPIStandardRequest(path: "create_item", payload: syncDict);
}
static PodAPIStandardRequest updateItem(Map<String, dynamic> syncDict) {
return PodAPIStandardRequest(path: "update_item", payload: syncDict);
}
static PodAPIStandardRequest deleteItem(String itemId) {
// Note payload is just item UID (no JSON)
return PodAPIStandardRequest(path: "delete_item", payload: itemId);
}
static PodAPIStandardRequest getItem<Payload>(Payload payload) {
return PodAPIStandardRequest(path: "get_item", payload: payload);
}
static PodAPIStandardRequest bulkAction<Payload>(Payload payload) {
return PodAPIStandardRequest(path: "bulk", payload: payload);
}
static PodAPIStandardRequest getVersion() {
return PodAPIStandardRequest(method: HTTPMethod.get, path: "version", payload: {});
}
}
/*struct PodAPIUploadRequest<Payload: Encodable> {
var path: String
var fileURL: URL
var payload: Payload
func constructRequest(connectionConfig: PodAPIConnectionDetails) throws -> URLRequest {
var components = URLComponents()
components.scheme = connectionConfig.scheme
components.host = connectionConfig.host
components.port = connectionConfig.port
components.path = "/\(connectionConfig.apiVersion)/\(connectionConfig.keys.ownerKey)/\(path)"
guard let url = components.url else {
throw StringError(description: "Failed to construct URL for APIRequest")
}
var request = URLRequest(url: url)
request.method = .post
if !(Payload.self == PodAPIPayload.EmptyPayload.self) {
request = try URLEncodedFormParameterEncoder().encode(payload, into: request)
}
return request
}
func execute(connectionConfig: PodAPIConnectionDetails) throws -> AnyPublisher<DataResponse<Any, AFError>, Never> {
AF.upload(fileURL, with: try constructRequest(connectionConfig: connectionConfig))
.publishResponse(using: JSONResponseSerializer()).eraseToAnyPublisher()
}
func execute<T: Decodable>(connectionConfig: PodAPIConnectionDetails) throws -> AnyPublisher<DataResponse<T, AFError>, Never> {
AF.upload(fileURL, with: try constructRequest(connectionConfig: connectionConfig))
.publishDecodable().eraseToAnyPublisher()
}
}
struct PodAPIDownloadRequest<Payload: Encodable> {
var path: String
var method: HTTPMethod = .post
var payload: Payload
var fileUID: String
var destination: DownloadRequest.Destination { { _, _ in
let fileURL = FileStorageController.getURLForFile(withUUID: fileUID)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
}
func constructRequest(connectionConfig: PodAPIConnectionDetails) throws -> URLRequest {
var components = URLComponents()
components.scheme = connectionConfig.scheme
components.host = connectionConfig.host
components.port = connectionConfig.port
components.path = "/\(connectionConfig.apiVersion)/\(connectionConfig.keys.ownerKey)/\(path)"
guard let url = components.url else {
throw StringError(description: "Failed to construct URL for APIRequest")
}
print(url)
var request = URLRequest(url: url)
request.method = method
switch method {
case .get:
/// For a `get` request, encode our payload into the URL.
if !(Payload.self == PodAPIPayload.EmptyPayload.self) {
request = try URLEncodedFormParameterEncoder().encode(payload, into: request)
}
default:
/// For a `post` request (or other types of request) encode our payload into the body of the request.
let body = PodAPIRequestBody(connectionConfig: connectionConfig,
payload: payload)
request = try JSONParameterEncoder().encode(body, into: request)
}
return request
}
func execute(connectionConfig: PodAPIConnectionDetails) throws -> AnyPublisher<DownloadResponse<URL, AFError>, Never> {
AF.download(try constructRequest(connectionConfig: connectionConfig), to: destination)
.publishURL().eraseToAnyPublisher()
}
}*/
/*
extension PodAPIDownloadRequest {
static func downloadFile(fileSHAHash: String, fileUID: String) -> PodAPIDownloadRequest where Payload == PodAPIPayload.FileSHA {
PodAPIDownloadRequest(path: "get_file", payload: PodAPIPayload.FileSHA(sha: fileSHAHash), fileUID: fileUID)
}
}
extension PodAPIUploadRequest {
static func uploadFile(fileURL: URL, fileSHAHash: String? = nil, connectionConfig: PodAPIConnectionDetails) throws -> PodAPIUploadRequest where Payload == PodAPIPayload.EmptyPayload {
let sha = try fileSHAHash ?? FileHelper.getSHAHash(url: fileURL)
let path = "upload_file/\(connectionConfig.keys.dbKey)/\(sha)"
return PodAPIUploadRequest(path: path, fileURL: fileURL, payload: PodAPIPayload.EmptyPayload())
}
}*/
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment