diff --git a/bin/tapir.mjs b/bin/tapir.mjs index 7057aa0..d9b2b07 100644 --- a/bin/tapir.mjs +++ b/bin/tapir.mjs @@ -195,7 +195,7 @@ foreach my $service (@{ $document->services }) { sub describe_type { my ($type, $namespace, $want_perl) = @_; - my $namespaced_type = $type->isa('Thrift::IDL::Type::Base') ? $type->name : join '.', $namespace, $type->name; + my $namespaced_type = $type->isa('Thrift::IDL::Type::Custom') ? join '.', $namespace, $type->name : $type->name; if ($type->can('val_type')) { my %details = ( diff --git a/bin/tapir_buildjs b/bin/tapir_buildjs index daa7d4b..234ff94 100755 --- a/bin/tapir_buildjs +++ b/bin/tapir_buildjs @@ -8,6 +8,7 @@ use Thrift::IDL; use Tapir::Validator; use HTML::Mason; use FindBin; +use List::Util qw(first); my %opt; @@ -22,7 +23,7 @@ if (my @missing_args = grep { ! $opt{$_} } qw(idl out)) { my $document = Thrift::IDL->parse_thrift_file($opt{idl}); my $validator = Tapir::Validator->new(); -my $namespace = $document->headers->[0]->namespace('js'); +my $namespace = first { defined } map { $document->headers->[0]->namespace($_) } qw(js * perl); my @audit_errors = $validator->audit_idl_document($document); die "IDL file failed audit\n" if @audit_errors; diff --git a/htdocs/api_test.html b/htdocs/api_test.html index cf98bbf..d598f34 100644 --- a/htdocs/api_test.html +++ b/htdocs/api_test.html @@ -10,7 +10,7 @@ var $j = jQuery.noConflict(); @@ -133,16 +140,16 @@ var div = table.appendChild($$('tr', { class: 'methodField' })); div.appendChild( - $$('td', { class: 'methodFieldName' }, [ + $$('td', { class: 'fieldName' }, [ $$('div', { class: 'name' }, [_(Field.name)]), $$('div', { class: 'meta' }, [_('idx: ' + Field.index + ', type: ' + Field.type + ', opt: ' + Field.optional)]) ]) ); var valueDiv = div.appendChild( - $$('td', { class: 'methodFieldValue' }) + $$('td', { class: 'fieldValue' }) ); var errorDiv = div.appendChild( - $$('td', { class: 'methodFieldError', id: fieldId + '_error' }) + $$('td', { class: 'fieldError', id: fieldId + '_error' }) ); var collectorFunc = drawMethodField(Field, fieldId, valueDiv, defaultValues); @@ -164,7 +171,6 @@ } function drawMethodField (Field, fieldId, parentDiv, defaultValues) { - var baseType = Field.Type().baseType(); var classChain = baseType.classChainHash(); var collectorFunc = null; @@ -204,13 +210,14 @@ var subFieldId = fieldId + '_' + i; var tr = subDiv.appendChild( - $$('tr', {}, [ - $$('td', {}, [_( - subField.name + ' (idx: ' + subField.index + ', type: ' + subField.type + ', opt: ' + subField.optional + ')' - )]), + $$('tr', { class: 'structField' }, [ + $$('td', { class: 'fieldName' }, [ + $$('div', { class: 'name' }, [_(subField.name)]), + $$('div', { class: 'meta' }, [_('idx: ' + subField.index + ', type: ' + subField.type + ', opt: ' + subField.optional)]) + ]), ]) ); - var td = tr.appendChild($$('td')); + var td = tr.appendChild($$('td', { class: 'fieldValue' })); var collectorFunc = drawMethodField(subField, subFieldId, td, {}); if (collectorFunc == null) continue; @@ -234,7 +241,7 @@ if (defaultValues[ Field.name ]) input.checked = true; } else if (classChain['Tapir.Type.Container']) { - var subDiv = $$('table', { id: fieldId }); + var subDiv = $$('table', { class: 'container', id: fieldId }); parentDiv.appendChild(subDiv); var is_map = classChain['Tapir.Type.map'] ? true : false; @@ -259,22 +266,22 @@ var addFunc = function () { var tr, td, rowId, collectorFunc; - tr = subDiv.appendChild($$('tr')); + tr = subDiv.appendChild($$('tr', { class: 'containerItem' })); rowId = rowCounter++; collectorFuncs[rowId] = {}; if (is_map) { - td = tr.appendChild($$('td', {}, [_('Key:')])); + td = tr.appendChild($$('td', { class: 'key' })); collectorFunc = drawMethodField(keyField, fieldId + '_' + rowId + '_key', td, {}); if (collectorFunc != null) collectorFuncs[rowId]['key'] = collectorFunc; } - td = tr.appendChild($$('td', {}, [_('Value:')])); + td = tr.appendChild($$('td', { class: 'value' })); collectorFunc = drawMethodField(valField, fieldId + '_' + rowId + '_val', td, {}); if (collectorFunc != null) collectorFuncs[rowId]['val'] = collectorFunc; - td = tr.appendChild($$('td')); + td = tr.appendChild($$('td', { class: 'deleteItem'})); td.appendChild($$('button', {}, [_('Del')])) .addEventListenerChained('click', function (e) { delete collectorFuncs[rowId]; @@ -282,8 +289,14 @@ }); }; - var controlTd = $$('td'); - parentDiv.appendChild($$('tr', {}, [controlTd])); + var controlTd = $$('td', { colspan: is_map ? 3 : 2 }); + subDiv.appendChild($$('tr', { class: 'containerControl' }, [controlTd])); + + var header = $$('tr', { class: 'containerHeader' }); + if (is_map) + header.appendChild($$('td', {}, [_('Key (isa ...)')])); + header.appendChild($$('td', {}, [_('Value (isa ...)')])); + subDiv.appendChild(header); controlTd.appendChild($$('button', {}, [_('Add')])) .addEventListenerChained('click', function (e) { diff --git a/htdocs/js/Tappy.js b/htdocs/js/Tappy.js index 372ebeb..a967b42 100644 --- a/htdocs/js/Tappy.js +++ b/htdocs/js/Tappy.js @@ -28,41 +28,87 @@ array.forEach( "validateSpec" ], [ - "account_id", - "i32", + "coupon_code", + "string", [ { - "high" : "10000", - "low" : "1", - "type" : "range" + "pattern" : "^[0-9A-Z]{0,}$", + "type" : "regex" } ] ], [ - "password", + "coupon_group_id", + "i64", + [] + ], + [ + "coupon_id", + "i64", + [] + ], + [ + "coupon_prefix", "string", [ { - "pattern" : "^[^ ]+$", + "pattern" : "^[A-Z][A-Z0-9]{0,4}$", "type" : "regex" } ] ], [ - "username", + "coupon_site", + "string", + [] + ], + [ + "coupon_triggers", + { + "keyType" : "SSThrift.trigger_key", + "valType" : "SSThrift.trigger_value", + "type" : "map" + }, + [] + ], + [ + "date", "string", [ { - "high" : "8", - "low" : "1", - "type" : "length" + "pattern" : "^\\d{4}-\\d{2}-\\d{2}$", + "type" : "regex" + } + ] + ], + [ + "trigger_key", + "string", + [] + ], + [ + "trigger_value", + { + "valType" : "string", + "type" : "list" + }, + [] + ], + [ + "unix_time", + "i32", + [ + { + "high" : null, + "low" : "0", + "type" : "range" } ] ] ] ), function (type, i) { - dojo.declare('Tappy.' + type.name, Tapir.Type.Custom, type); + dojo.declare('SSThrift.' + type.name, Tapir.Type.Custom, type); } ); @@ -71,7 +117,7 @@ array.forEach( // Custom exceptions and structures -dojo.declare('Tappy.account', Tapir.Type.Struct, { +dojo.declare('SSThrift.coupon', Tapir.Type.Struct, { fieldSpec: _table2objects([ [ "index", @@ -84,27 +130,90 @@ dojo.declare('Tappy.account', Tapir.Type.Struct, { "1", "id", false, - "Tappy.account_id", + "SSThrift.coupon_id", [] ], [ "2", - "allocation", + "site", false, - "i32", + "SSThrift.coupon_site", [] ], [ "3", - "is_admin", - true, + "code", + false, + "SSThrift.coupon_code", + [] + ], + [ + "4", + "description", + false, + "string", + [] + ], + [ + "5", + "amount", + false, + "SSThrift.coupon_amount", + [] + ], + [ + "6", + "expires", + false, + "SSThrift.date", + [] + ], + [ + "7", + "use_once", + false, "bool", [] + ], + [ + "8", + "triggers", + false, + "SSThrift.coupon_triggers", + [] + ], + [ + "9", + "creator", + false, + "string", + [] + ], + [ + "10", + "created_epoch", + false, + "SSThrift.unix_time", + [] + ], + [ + "11", + "is_valid", + false, + "bool", + [] + ], + [ + "12", + "used_epoch", + true, + "SSThrift.unix_time", + [] ] ] ) }); -dojo.declare('Tappy.genericCode', Tapir.Type.Exception, { +dojo.declare('SSThrift.coupon_amount', Tapir.Type.Struct, { fieldSpec: _table2objects([ [ "index", @@ -115,22 +224,125 @@ dojo.declare('Tappy.genericCode', Tapir.Type.Exception, { ], [ "1", - "code", + "percent", + true, + "byte", + [] + ], + [ + "2", + "amount", + true, + "double", + [] + ], + [ + "4", + "currency", + true, + "string", + [] + ], + [ + "3", + "gift", + true, + "string", + [] + ] +] +) +}); +dojo.declare('SSThrift.coupon_group', Tapir.Type.Struct, { + fieldSpec: _table2objects([ + [ + "index", + "name", + "optional", + "type", + "validateSpec" + ], + [ + "1", + "site", false, - "i16", + "SSThrift.coupon_site", [] ], [ "2", - "message", + "id", + false, + "SSThrift.coupon_group_id", + [] + ], + [ + "3", + "code_prefix", + true, + "SSThrift.coupon_prefix", + [] + ], + [ + "4", + "code", + true, + "SSThrift.coupon_code", + [] + ], + [ + "5", + "description", false, "string", [] + ], + [ + "6", + "count", + false, + "i32", + [] + ], + [ + "7", + "amount", + false, + "SSThrift.coupon_amount", + [] + ], + [ + "8", + "expires", + false, + "SSThrift.date", + [] + ], + [ + "9", + "triggers", + false, + "SSThrift.coupon_triggers", + [] + ], + [ + "10", + "use_once", + false, + "bool", + [] + ], + [ + "11", + "number_of_used", + true, + "i32", + [] ] ] ) }); -dojo.declare('Tappy.insufficientResources', Tapir.Type.Exception, { +dojo.declare('SSThrift.coupon_groups_result', Tapir.Type.Struct, { fieldSpec: _table2objects([ [ "index", @@ -141,31 +353,162 @@ dojo.declare('Tappy.insufficientResources', Tapir.Type.Exception, { ], [ "1", - "code", + "pagination", false, - "i16", + "SSThrift.pagination_result", [] ], [ "2", - "message", + "groups", + false, + { + "valType" : "SSThrift.coupon_group", + "type" : "list" + }, + [] + ] +] +) +}); +dojo.declare('SSThrift.generic_result', Tapir.Type.Struct, { + fieldSpec: _table2objects([ + [ + "index", + "name", + "optional", + "type", + "validateSpec" + ], + [ + "1", + "is_success", false, + "bool", + [] + ], + [ + "2", + "message", + true, "string", [] ] ] ) }); +dojo.declare('SSThrift.get_coupons_result', Tapir.Type.Struct, { + fieldSpec: _table2objects([ + [ + "index", + "name", + "optional", + "type", + "validateSpec" + ], + [ + "1", + "pagination", + false, + "SSThrift.pagination_result", + [] + ], + [ + "2", + "coupons", + false, + { + "valType" : "SSThrift.coupon", + "type" : "list" + }, + [] + ] +] +) +}); +dojo.declare('SSThrift.pagination_request', Tapir.Type.Struct, { + fieldSpec: _table2objects([ + [ + "index", + "name", + "optional", + "type", + "validateSpec" + ], + [ + "1", + "records_per_page", + false, + "i32", + [] + ], + [ + "2", + "page", + false, + "i32", + [] + ] +] +) +}); +dojo.declare('SSThrift.pagination_result', Tapir.Type.Struct, { + fieldSpec: _table2objects([ + [ + "index", + "name", + "optional", + "type", + "validateSpec" + ], + [ + "1", + "records", + false, + "i32", + [] + ], + [ + "2", + "total_records", + false, + "i32", + [] + ], + [ + "3", + "page", + false, + "i32", + [] + ], + [ + "4", + "total_pages", + false, + "i32", + [] + ], + [ + "5", + "records_per_page", + false, + "i32", + [] + ] +] +) +}); // Services -dojo.declare('Tappy.Accounts', Tapir.Service, { - name: 'Accounts', - methods: [ "createAccount", "getAccount" ], - baseName: 'Tappy.Accounts' +dojo.declare('SSThrift.Commerce', Tapir.Service, { + name: 'Commerce', + methods: [ "create_coupon", "get_coupons", "get_coupon_groups", "get_coupon_by_code", "get_coupon_by_id", "update_coupon" ], + baseName: 'SSThrift.Commerce' }); -TapirClient.services.push('Tappy.Accounts'); +TapirClient.services.push('SSThrift.Commerce'); array.forEach( _table2objects([ @@ -176,80 +519,216 @@ array.forEach( "spec" ], [ - "createAccount", - "Accounts", + "create_coupon", + "Commerce", [ [ "1", - "username", + "site", false, - "Tappy.username", + "SSThrift.coupon_site", [] ], [ "2", - "password", + "code", + true, + "SSThrift.coupon_code", + [] + ], + [ + "3", + "code_prefix", + true, + "SSThrift.coupon_prefix", + [] + ], + [ + "4", + "description", false, - "Tappy.password", + "string", + [] + ], + [ + "6", + "count", + false, + "i32", [ { "high" : null, "low" : "1", - "type" : "length" + "type" : "range" } ] ], + [ + "7", + "amount", + false, + "SSThrift.coupon_amount", + [] + ], + [ + "8", + "expires", + false, + "SSThrift.date", + [] + ], + [ + "9", + "use_once", + false, + "bool", + [] + ], + [ + "10", + "triggers", + false, + "SSThrift.coupon_triggers", + [] + ] + ], + { + "exceptions" : [], + "returns" : "SSThrift.coupon_group_id" + } + ], + [ + "get_coupons", + "Commerce", + [ + [ + "1", + "site", + false, + "SSThrift.coupon_site", + [] + ], + [ + "2", + "id", + false, + "SSThrift.coupon_group_id", + [] + ], [ "3", - "is_admin", + "pagination", true, - "bool", + "SSThrift.pagination_request", [] ] ], { - "exceptions" : [ - [ - "1", - "insufficient", - false, - "Tappy.insufficientResources", - [] - ], - [ - "2", - "code", - false, - "Tappy.genericCode", - [] - ] + "exceptions" : [], + "returns" : "SSThrift.get_coupons_result" + } + ], + [ + "get_coupon_groups", + "Commerce", + [ + [ + "1", + "site", + false, + "SSThrift.coupon_site", + [] ], - "returns" : "Tappy.account" + [ + "2", + "pagination", + true, + "SSThrift.pagination_request", + [] + ] + ], + { + "exceptions" : [], + "returns" : "SSThrift.coupon_groups_result" } ], [ - "getAccount", - "Accounts", + "get_coupon_by_code", + "Commerce", [ [ "1", - "username", + "site", + false, + "SSThrift.coupon_site", + [] + ], + [ + "2", + "code", false, - "Tappy.username", + "SSThrift.coupon_code", [] ] ], { - "exceptions" : [ - [ - "1", - "code", - false, - "Tappy.genericCode", - [] - ] + "exceptions" : [], + "returns" : "SSThrift.coupon" + } + ], + [ + "get_coupon_by_id", + "Commerce", + [ + [ + "1", + "site", + false, + "SSThrift.coupon_site", + [] + ], + [ + "2", + "id", + false, + "SSThrift.coupon_id", + [] + ] + ], + { + "exceptions" : [], + "returns" : "SSThrift.coupon" + } + ], + [ + "update_coupon", + "Commerce", + [ + [ + "1", + "site", + false, + "SSThrift.coupon_site", + [] ], - "returns" : "Tappy.account" + [ + "2", + "code", + false, + "SSThrift.coupon_code", + [] + ], + [ + "3", + "is_used", + false, + "bool", + [] + ] + ], + { + "exceptions" : [], + "returns" : "SSThrift.generic_result" } ] ] @@ -258,7 +737,7 @@ array.forEach( function (method, i) { method.fieldSpec = _table2objects(method.fieldSpec, fieldHeader); method.spec.exceptions = _table2objects(method.spec.exceptions, fieldHeader); - dojo.declare('Tappy.' + method.serviceName + '.' + method.name, Tapir.Method, method); + dojo.declare('SSThrift.' + method.serviceName + '.' + method.name, Tapir.Method, method); } );