├── dist ├── core.js ├── yql.js ├── odata.js ├── sqlite.js ├── webapi.js ├── facebook.js ├── indexeddb.js ├── inmemory.js ├── mongodb.js ├── compatiblity.js └── package.json ├── .babelrc ├── .nuget ├── NuGet.exe └── NuGet.Config ├── test ├── compatiblity.js ├── jsconfig.json ├── unit-tests │ ├── jsconfig.json │ ├── scripts │ │ └── qunitToMocha.js │ ├── ModelBinder.spec.js │ ├── NorthwindServiceTest.js │ └── T2.js ├── qunit │ ├── gulpfile.js │ ├── scripts │ │ ├── NodeJS │ │ │ ├── JaySvcUtil │ │ │ │ ├── xml.xml │ │ │ │ ├── xslt.xslt │ │ │ │ ├── Test │ │ │ │ │ ├── index.html │ │ │ │ │ └── EdmTypeMapping.xslt.xsl │ │ │ │ ├── EdmTypeMapping.xslt │ │ │ │ ├── jaysus-test.js │ │ │ │ ├── JaySvcUtil.js │ │ │ │ └── JaySvcUtilNode.js │ │ │ ├── cuJavaScriptTest.js │ │ │ ├── eventClientTests.js │ │ │ ├── context.js │ │ │ ├── service.js │ │ │ ├── eventTests.js │ │ │ ├── contextapiClientTests.js │ │ │ ├── commonTests.js │ │ │ ├── contextFactoryTests.js │ │ │ └── typeTests.js │ │ ├── storageModelTests.js │ │ ├── ValidatonPluginTest.js │ │ ├── dataDistributeTest.js │ │ └── oDataProviderTests_auth.js │ ├── package.json │ ├── .gitignore │ ├── JayServiceHtmlClient.html │ ├── JayServiceNodeClient.js │ ├── index.html │ ├── server_oData.js │ ├── websqlClient.html │ └── nodeJsTest.js └── core.js ├── .vscode └── settings.json ├── src ├── JaySvcUtil │ ├── jsconfig.json │ ├── index.js │ └── Example │ │ └── index.html ├── Types │ ├── StorageProviders │ │ ├── WebApi │ │ │ └── index.js │ │ ├── IndexedDB │ │ │ └── index.js │ │ ├── oData │ │ │ ├── SaveStrategies │ │ │ │ ├── empty.js │ │ │ │ ├── single.js │ │ │ │ └── batch.js │ │ │ ├── index.js │ │ │ ├── oDataPagingCompiler.js │ │ │ └── oDataRequestActivities.js │ │ ├── InMemory │ │ │ └── index.js │ │ ├── YQL │ │ │ ├── index.js │ │ │ └── YQLConverter.js │ │ ├── Facebook │ │ │ ├── EntitySets │ │ │ │ ├── FQL │ │ │ │ │ └── friend.js │ │ │ │ └── FQLContext.js │ │ │ ├── index.js │ │ │ └── FacebookConverter.js │ │ ├── mongoDB │ │ │ ├── index.js │ │ │ ├── ClientObjectID.js │ │ │ └── mongoDBPagingCompiler.js │ │ └── SqLite │ │ │ ├── SqlPagingCompiler.js │ │ │ ├── index.js │ │ │ ├── SqlExpressionMonitor.js │ │ │ └── SqlOrderCompiler.js │ ├── Ajax │ │ ├── jQueryAjaxWrapper.js │ │ ├── ExtJSAjaxWrapper.js │ │ ├── AjaxStub.js │ │ └── WinJSAjaxWrapper.js │ ├── EntityState.js │ ├── EntityWrapper.js │ ├── Expressions │ │ ├── ThisExpression.js │ │ ├── EntityExpressions │ │ │ ├── ProjectionExpression.js │ │ │ ├── AssociationInfoExpression.js │ │ │ ├── RepresentationExpression.js │ │ │ ├── MemberInfoExpression.js │ │ │ ├── ParametricQueryExpression.js │ │ │ ├── EntityFieldOperationExpression.js │ │ │ ├── QueryParameterExpression.js │ │ │ ├── IncludeExpression.js │ │ │ ├── EntityContextExpression.js │ │ │ ├── EntityFieldExpression.js │ │ │ ├── CodeExpression.js │ │ │ ├── OrderExpression.js │ │ │ ├── FrameOperationExpression.js │ │ │ ├── ComplexTypeExpression.js │ │ │ ├── ServiceOperationExpression.js │ │ │ ├── ExpressionMonitor.js │ │ │ └── EntityExpression.js │ │ ├── DistinctExpression.js │ │ ├── GroupExpression.js │ │ ├── ObjectFieldExpression.js │ │ ├── PagingExpression.js │ │ ├── Visitors │ │ │ ├── LogicalSchemaBinderVisitor.js │ │ │ ├── LocalContextProcessor.js │ │ │ ├── ParameterProcessor.js │ │ │ ├── LambdaParameterProcessor.js │ │ │ └── GlobalContextProcessor.js │ │ ├── ArrayLiteralExpression.js │ │ ├── ParameterExpression.js │ │ ├── ConstantExpression.js │ │ ├── SimpleBinaryExpression.js │ │ ├── ObjectLiteralExpression.js │ │ ├── FunctionExpression.js │ │ ├── CallExpression.js │ │ ├── PropertyExpression.js │ │ └── ASTParser.js │ ├── DbClient │ │ ├── DbCommand.js │ │ ├── DbConnection.js │ │ ├── SqLiteNjClient │ │ │ ├── SqLiteNjConnection.js │ │ │ └── SqLiteNjCommand.js │ │ ├── JayStorageClient │ │ │ ├── JayStorageConnection.js │ │ │ └── JayStorageCommand.js │ │ └── OpenDatabaseClient │ │ │ ├── OpenDbConnection.js │ │ │ └── OpenDbCommand.js │ ├── Notifications │ │ ├── ChangeDistributorBase.js │ │ ├── ChangeCollectorBase.js │ │ ├── ChangeDistributor.js │ │ └── ChangeCollector.js │ ├── QueryProvider.js │ ├── EntityStateManager.js │ ├── Authentication │ │ ├── Anonymous.js │ │ ├── AuthenticationBase.js │ │ └── BasicAuth.js │ ├── Transaction.js │ ├── EntityAttachModes.js │ ├── AuthEntityContext.js │ ├── Validation │ │ └── EntityValidationBase.js │ ├── QueryBuilder.js │ ├── Query.js │ ├── JayStorm.js │ ├── index.js │ └── Promise.js ├── index.js ├── TypeSystem │ ├── Trace │ │ ├── Trace.js │ │ └── Logger.js │ ├── VS2010Intellisense.js │ ├── initializeJayDataClient.js │ ├── initializeJayData.js │ ├── index.js │ ├── Types │ │ ├── SimpleBase.js │ │ ├── Geospatial.js │ │ ├── Guid.js │ │ └── Types.js │ └── Extensions.js └── JayDataModules │ ├── qDeferred.js │ ├── errorhandler.js │ ├── deferred.js │ ├── inMemory.js │ ├── jaydata.mscrm.server.js │ └── template.js ├── jsconfig.json ├── Math.uuid.js-licences.txt ├── jaydata-compatibility.js ├── example ├── requirejs │ ├── index.html │ └── app.js └── inheritance │ ├── inheritence.js │ └── basetype.js ├── tests └── integration.spec.js ├── .gitignore ├── MIT-LICENSE.txt ├── nightwatch.conf.json ├── bower.json └── packages.config /dist/core.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/index.js'); 2 | -------------------------------------------------------------------------------- /dist/yql.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/YQL/index.js'); -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "es2015" ], 3 | "plugins": [ "add-module-exports" ] 4 | } -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaystack/jaydata/HEAD/.nuget/NuGet.exe -------------------------------------------------------------------------------- /dist/odata.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/oData/index.js'); -------------------------------------------------------------------------------- /dist/sqlite.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/SqLite/index.js'); -------------------------------------------------------------------------------- /dist/webapi.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/WebApi/index.js'); -------------------------------------------------------------------------------- /dist/facebook.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/Facebook/index.js'); -------------------------------------------------------------------------------- /dist/indexeddb.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/IndexedDB/index.js'); -------------------------------------------------------------------------------- /dist/inmemory.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/InMemory/index.js'); -------------------------------------------------------------------------------- /dist/mongodb.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/Types/StorageProviders/mongoDB/index.js'); -------------------------------------------------------------------------------- /test/compatiblity.js: -------------------------------------------------------------------------------- 1 | window.Container = $data.Container; 2 | $data.setModelContainer(window); 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /test/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /src/JaySvcUtil/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /test/unit-tests/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs" 5 | }, 6 | "exclude": [ 7 | "**/*.js" 8 | ] 9 | 10 | } -------------------------------------------------------------------------------- /test/qunit/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var qunit = require('node-qunit-phantomjs'); 3 | 4 | gulp.task('qunit', function () { 5 | return qunit('test.html'); 6 | }); -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Math.uuid.js-licences.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | Math.uuid.js (v1.4) 3 | http://www.broofa.com 4 | mailto:robert@broofa.com 5 | 6 | Copyright (c) 2010 Robert Kieffer 7 | Dual licensed under the MIT and GPL licenses. 8 | */ 9 | 10 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/WebApi/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | import WebApiConverter from './WebApiConverter.js'; 4 | import WebApiProvider from './WebApiProvider.js'; 5 | 6 | export default $data; 7 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import $data from './TypeSystem/index.js'; 2 | import expressions from './Types/Expressions/index.js'; 3 | import jaysvcutil from './JaySvcUtil/index.js'; 4 | import types from './Types/index.js'; 5 | 6 | export default $data 7 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/IndexedDB/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | import IndexedDBConverter from './IndexedDBConverter.js'; 4 | import IndexedDBStorageProvider from './IndexedDBStorageProvider.js'; 5 | 6 | export default $data; 7 | -------------------------------------------------------------------------------- /src/Types/Ajax/jQueryAjaxWrapper.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | if (typeof jQuery !== 'undefined' && jQuery.ajax) { 4 | $data.ajax = $data.ajax || jQuery.ajax; 5 | } 6 | 7 | export default $data 8 | -------------------------------------------------------------------------------- /jaydata-compatibility.js: -------------------------------------------------------------------------------- 1 | (function(g){ 2 | $data.setModelContainer(g); 3 | g.Container = $data.Container; 4 | g.Guard = $data.Guard; 5 | g.$C = $data.$C; 6 | g.Exception = $data.Exception; 7 | g.MemberDefinition = $data.MemberDefinition; 8 | })(window); -------------------------------------------------------------------------------- /src/Types/EntityState.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.EntityState = { 4 | Detached:0, 5 | Unchanged: 10, 6 | Added: 20, 7 | Modified: 30, 8 | Deleted: 40 9 | }; 10 | 11 | export default $data 12 | -------------------------------------------------------------------------------- /test/qunit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qunit", 3 | "version": "0.0.0", 4 | "description": "qunit", 5 | "main": "server.js", 6 | "author": { 7 | "name": "nochtap", 8 | "email": "" 9 | }, 10 | "devDependencies": { 11 | "gulp": "^3.8.11" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Types/EntityWrapper.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Base.extend('$data.EntityWrapper', { 4 | getEntity: function () { 5 | Guard.raise("pure object"); 6 | } 7 | }); 8 | 9 | export default $data 10 | -------------------------------------------------------------------------------- /src/TypeSystem/Trace/Trace.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | $data.Class.define('$data.TraceBase', null, null, { 4 | log: function () { }, 5 | warn: function () { }, 6 | error: function () { } 7 | }); 8 | 9 | $data.Trace = new $data.TraceBase(); 10 | 11 | export default $data 12 | -------------------------------------------------------------------------------- /src/Types/Expressions/ThisExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ThisExpression', $data.Expressions.ExpressionNode, null, { 4 | nodeType: { value: $data.Expressions.ExpressionType.This } 5 | }); 6 | 7 | export default $data 8 | -------------------------------------------------------------------------------- /src/Types/Ajax/ExtJSAjaxWrapper.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | if (typeof Ext !== 'undefined' && typeof Ext.Ajax) { 4 | $data.ajax = $data.ajax || function (options) { 5 | Ext.Ajax.request(options); 6 | }; 7 | } 8 | 9 | export default $data 10 | -------------------------------------------------------------------------------- /test/core.js: -------------------------------------------------------------------------------- 1 | var Module = require('module'); 2 | var realResolve = Module._resolveFilename; 3 | Module._resolveFilename = function fakeResolve(request, parent) { 4 | if (request === 'jaydata/core') { 5 | return require('path').join(__dirname, '../src/index.js'); 6 | } 7 | return realResolve(request, parent); 8 | }; -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/cuJavaScriptTest.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | 3 | $data.ServiceBase.extend('MyService', { 4 | HelloWorld: (function(){ 5 | return 'Hello World!'; 6 | }).toServiceOperation().returns('string') 7 | }); 8 | 9 | exports = module.exports = { 10 | serviceTypes: [MyService] 11 | }; 12 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/SaveStrategies/empty.js: -------------------------------------------------------------------------------- 1 | 2 | var strategy = { 3 | name: 'empty', 4 | condition: function (provider, convertedItems) { 5 | return true; 6 | }, 7 | save: function (provider, convertedItems, callBack) { 8 | callBack.success(0); 9 | } 10 | } 11 | 12 | 13 | export { strategy } -------------------------------------------------------------------------------- /src/Types/DbClient/DbCommand.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.DbCommand', null, null, 4 | { 5 | connection: {}, 6 | parameters: {}, 7 | execute: function (callback) { 8 | Guard.raise("Pure class"); 9 | } 10 | }, null); 11 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/InMemory/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | import InMemoryConverter from './InMemoryConverter.js'; 4 | import InMemoryProvider from './InMemoryProvider.js'; 5 | import InMemoryCompiler from './InMemoryCompiler.js'; 6 | import InMemoryFunctionCompiler from './InMemoryFunctionCompiler.js'; 7 | 8 | export default $data; 9 | -------------------------------------------------------------------------------- /src/Types/Ajax/AjaxStub.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.ajax = $data.ajax || function () { 4 | var cfg = arguments[arguments.length - 1]; 5 | var clb = $data.PromiseHandlerBase.createCallbackSettings(cfg); 6 | clb.error("Not implemented"); 7 | }; 8 | 9 | export default $data 10 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/YQL/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | import YQLConverter from './YQLConverter.js'; 4 | import YQLProvider from './YQLProvider.js'; 5 | import YQLCompiler from './YQLCompiler.js'; 6 | import geo from './EntitySets/geo.js'; 7 | import YQLContext from './EntitySets/YQLContext.js'; 8 | 9 | export default $data; 10 | -------------------------------------------------------------------------------- /src/Types/Notifications/ChangeDistributorBase.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Notifications.ChangeDistributorBase', null, null, { 4 | distributeData: function (collectorData) { 5 | Guard.raise("Pure class"); 6 | } 7 | }, null); 8 | 9 | export default $data 10 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/Facebook/EntitySets/FQL/friend.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | 4 | $data.Class.define("$data.Facebook.types.FbFriend", $data.Entity, null, { 5 | uid1: { type: "number", key: true, searchable: true }, 6 | uid2: { type: "number", key: true, searchable: true } 7 | }, null); 8 | -------------------------------------------------------------------------------- /src/TypeSystem/VS2010Intellisense.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IMPORTANT: 4 | !!! Do not reference this file to html! !!! 5 | 6 | */ 7 | 8 | (function (window) { 9 | if (typeof window.intellisense === 'undefined') { 10 | window.intellisense = { 11 | annotate: function () { }, 12 | logMessage: function () { } 13 | }; 14 | } 15 | })(window); -------------------------------------------------------------------------------- /src/TypeSystem/initializeJayDataClient.js: -------------------------------------------------------------------------------- 1 | export default function _data_handler() { 2 | //console.log("@@@@", this); 3 | if (this instanceof _data_handler) { 4 | var type = _data_handler["implementation"].apply(this, arguments); 5 | return new type(arguments[1]); 6 | } else { 7 | return _data_handler["implementation"].apply(this, arguments) 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /example/requirejs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Using JayData with Require.js 4 | 5 | 6 | 7 | 8 | 9 |

Using JayData with Require.js

10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/integration.spec.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "JayData" : function (browser) { 3 | browser 4 | .url("http://localhost:53999/test.html") 5 | .waitForElementVisible('body', 1000) 6 | .waitForElementVisible('#qunit-testresult .passed', 999999) 7 | .assert.containsText('#qunit-testresult .total', '20650') 8 | .assert.containsText('#qunit-testresult .passed', '20647') 9 | .end(); 10 | } 11 | }; -------------------------------------------------------------------------------- /src/Types/QueryProvider.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.QueryProvider', null, null, 4 | { 5 | //TODO: instance member????? 6 | constructor: function () { this.requiresExpressions= false }, 7 | executeQuery: function (queryable, resultHandler) { 8 | }, 9 | getTraceString: function (queryable) { 10 | } 11 | }, null); 12 | 13 | export default $data 14 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/ProjectionExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ProjectionExpression', $data.Expressions.EntitySetExpression, null, { 4 | constructor: function (source, selector, params, instance) { 5 | 6 | }, 7 | nodeType: { value: $data.Expressions.ExpressionType.Projection, enumerable: true } 8 | 9 | }); 10 | 11 | export default $data 12 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/AssociationInfoExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.AssociationInfoExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (associationInfo) { 5 | this.associationInfo = associationInfo; 6 | }, 7 | nodeType: { value: $data.Expressions.ExpressionType.AssociationInfo, enumerable: true } 8 | }); 9 | 10 | export default $data 11 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/Facebook/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | import FacebookConverter from './FacebookConverter.js'; 4 | import FacebookProvider from './FacebookProvider.js'; 5 | import FacebookCompiler from './FacebookCompiler.js'; 6 | import user from './EntitySets/FQL/user.js'; 7 | import friend from './EntitySets/FQL/friend.js'; 8 | import page from './EntitySets/FQL/page.js'; 9 | import FQLContext from './EntitySets/FQLContext.js'; 10 | 11 | export default $data; 12 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | import converter from './oDataConverter.js'; 3 | import provider from './oDataProvider.js'; 4 | import compiler from './oDataCompiler.js'; 5 | import order from './oDataWhereCompiler.js'; 6 | import include from './oDataIncludeCompiler.js'; 7 | import paging from './oDataOrderCompiler.js'; 8 | import projection from './oDataPagingCompiler.js'; 9 | import where from './oDataProjectionCompiler.js'; 10 | 11 | export default $data; 12 | -------------------------------------------------------------------------------- /src/JaySvcUtil/index.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem/index.js'; 2 | import { DynamicMetadata, odatajs, Annotations, Metadata } from 'jaydata-dynamic-metadata'; 3 | 4 | $data.Annotations = Annotations; 5 | $data.Metadata = Metadata; 6 | 7 | $data.DynamicMetadata = DynamicMetadata; 8 | var dynamicMetadata = new DynamicMetadata($data); 9 | $data.service = dynamicMetadata.service.bind(dynamicMetadata); 10 | $data.initService = dynamicMetadata.initService.bind(dynamicMetadata); 11 | $data.odatajs = odatajs; 12 | 13 | export default $data 14 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/RepresentationExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.RepresentationExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (kind) { 5 | }, 6 | 7 | getMemberDefinition: function (name) { 8 | return this.entityType.getMemberDefinition(name); 9 | }, 10 | 11 | nodeType: { value: $data.Expressions.ExpressionType.Entity } 12 | }); 13 | 14 | export default $data 15 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/MemberInfoExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.MemberInfoExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (memberDefinition) { 5 | this.memberDefinition = memberDefinition; 6 | this.memberName = memberDefinition.name; 7 | }, 8 | nodeType: { value: $data.Expressions.ExpressionType.MemberInfo, enumerable: true } 9 | 10 | }); 11 | 12 | export default $data 13 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/ParametricQueryExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ParametricQueryExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (expression, parameters) { 5 | this.expression = expression; 6 | this.parameters = parameters || []; 7 | }, 8 | nodeType: { value: $data.Expressions.ExpressionType.ParametricQuery, enumerable: true } 9 | }); 10 | 11 | export default $data 12 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/EntityFieldOperationExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.EntityFieldOperationExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, operation, parameters) { 5 | this.source = source; 6 | this.operation = operation; 7 | this.parameters = parameters; 8 | }, 9 | nodeType: { value: $data.Expressions.ExpressionType.EntityFieldOperation } 10 | 11 | }); 12 | 13 | export default $data 14 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/eventClientTests.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | var serviceUrl = 'http://localhost:12345/eventtest' 3 | 4 | require('../../JaySvcUtil/JaySvcUtil.js'); 5 | 6 | $data.MetadataLoader.debugMode = true; 7 | $data.MetadataLoader.load(serviceUrl, function (factory, ctxType, text) { 8 | console.log(text); 9 | var context = factory(); 10 | context.AAA.add(new $test.A({ Value: 'aaa' })); 11 | context.AAA.add(new $test.A({ Value: 'bbb' })); 12 | 13 | context.saveChanges(function(cnt){ 14 | console.log('saved', cnt); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /example/requirejs/app.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | baseUrl: '../../dist/public', 3 | paths: { 4 | 'jaydata/core': 'jaydata', 5 | 'jaydata/odata': 'jaydataproviders/oDataProvider' 6 | }, 7 | shim: { 8 | 'jaydata/odata': { 9 | deps: ['jaydata/core'] 10 | } 11 | } 12 | }); 13 | 14 | requirejs(['jaydata/core', 'jaydata/odata'], function ($data) { 15 | document.body.innerHTML += $data.version; 16 | if ('oData' in $data.RegisteredStorageProviders) document.body.innerHTML += '
JayData OData provider is available'; 17 | }); 18 | -------------------------------------------------------------------------------- /src/Types/EntityStateManager.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.EntityStateManager', null, null, 4 | { 5 | constructor: function (entityContext) { 6 | this.entityContext = null; 7 | this.trackedEntities = []; 8 | this.init(entityContext); 9 | }, 10 | init: function (entityContext) { 11 | this.entityContext = entityContext; 12 | }, 13 | reset: function () { 14 | this.trackedEntities = []; 15 | } 16 | }, null); 17 | 18 | export default $data 19 | -------------------------------------------------------------------------------- /src/Types/DbClient/DbConnection.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.DbConnection', null, null, 4 | { 5 | connectionParams: {}, 6 | database: {}, 7 | isOpen: function () { 8 | Guard.raise("Pure class"); 9 | }, 10 | open: function () { 11 | Guard.raise("Pure class"); 12 | }, 13 | close: function () { 14 | Guard.raise("Pure class"); 15 | }, 16 | createCommand: function () { 17 | Guard.raise("Pure class"); 18 | } 19 | }, null); 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .idea 3 | *.pwd.js 4 | *.suo 5 | *.*.suo 6 | CommandLine.dll 7 | JayData_readme.txt 8 | JaySvcUtil.exe 9 | Scripts/jaydata* 10 | /obj/* 11 | /3rdparty/* 12 | /bin/* 13 | !bin/Antlr3.Runtime.dll 14 | !bin/EntityFramework.dll 15 | !bin/System.Net.Http.dll 16 | !bin/System.Net.Http.WebRequest.dll 17 | !bin/System.Web.Optimization.dll 18 | !bin/System.Web.Providers.dll 19 | !bin/WebGrease.dll 20 | packages 21 | node_modules 22 | npm-debug.log 23 | nugetpkg 24 | /dist/* 25 | !dist/package.json 26 | !dist/*.js 27 | release 28 | coverage 29 | docs 30 | jaydata.js 31 | test.js 32 | apidocs 33 | .history/* 34 | .vscode -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/QueryParameterExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.QueryParameterExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (name, index, value, type) { 5 | this.name = name; 6 | this.index = index; 7 | this.value = value; 8 | //TODO 9 | this.type = Container.getTypeName(value); 10 | }, 11 | 12 | nodeType: { value: $data.Expressions.ExpressionType.QueryParameter, writable: false } 13 | }); 14 | 15 | export default $data 16 | -------------------------------------------------------------------------------- /src/Types/Authentication/Anonymous.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define("$data.Authentication.Anonymous", $data.Authentication.AuthenticationBase, null, { 4 | constructor: function (cfg) { 5 | this.configuration = cfg || {}; 6 | this.Authenticated = false; 7 | }, 8 | /// { error:, abort:, pending:, success: } 9 | Login: function (callbacks) { 10 | }, 11 | Logout: function () { 12 | }, 13 | CreateRequest: function (cfg) { 14 | $data.ajax(cfg); 15 | } 16 | 17 | }, null); 18 | 19 | export default $data 20 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/mongoDB/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | import objectid from './ClientObjectID.js'; 3 | import converter from './mongoDBConverter.js'; 4 | import modelbinder from './mongoDBModelBinderConfigCompiler.js'; 5 | import filter from './mongoDBFilterCompiler.js'; 6 | import fn from './mongoDBFunctionCompiler.js'; 7 | import order from './mongoDBOrderCompiler.js'; 8 | import paging from './mongoDBPagingCompiler.js'; 9 | import projection from './mongoDBProjectionCompiler.js'; 10 | import compiler from './mongoDBCompiler.js'; 11 | import provider from './mongoDBStorageProvider.js'; 12 | 13 | export default $data; 14 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/xslt.xslt: -------------------------------------------------------------------------------- 1 | 6 | 7 | asdasd 8 | 9 | 10 |
11 | 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/IncludeExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.IncludeExpression', $data.Expressions.EntitySetExpression, null, { 4 | constructor: function (source, selector) { 5 | }, 6 | nodeType: { value: $data.Expressions.ExpressionType.Include, writable: true }, 7 | 8 | toString: function (debug) { 9 | //var result; 10 | //result = debug ? this.type + " " : ""; 11 | //result = result + this.name; 12 | var result = "unimplemented"; 13 | return result; 14 | } 15 | }, null); 16 | 17 | export default $data 18 | -------------------------------------------------------------------------------- /src/Types/Notifications/ChangeCollectorBase.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Notifications.ChangeCollectorBase', null, null, { 4 | buildData: function (entityContextData) { 5 | Guard.raise("Pure class"); 6 | }, 7 | processChangedData: function (entityData) { 8 | if (this.Distrbutor && this.Distrbutor.distributeData) 9 | this.Distrbutor.distributeData(this.buildData(entityData)); 10 | }, 11 | Distrbutor: { enumerable: false, dataType: $data.Notifications.ChangeDistributorBase, storeOnObject: true } 12 | }, null); 13 | 14 | export default $data 15 | -------------------------------------------------------------------------------- /test/qunit/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 27 | node_modules 28 | 29 | build 30 | 31 | .ntvs_analysis.dat -------------------------------------------------------------------------------- /test/qunit/JayServiceHtmlClient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/qunit/JayServiceNodeClient.js: -------------------------------------------------------------------------------- 1 | require('odata'); 2 | require('jaydata'); 3 | var Q = require('q'); 4 | 5 | var connect = require('connect'); 6 | 7 | 8 | 9 | var app = connect(); 10 | app.use("/", function(req, res) { 11 | $data.serviceClient('http://342-cu.amazon.jaystack.net/personApi').then( function(context) { 12 | 13 | 14 | context.getPersonsByAge(100, function(persons) { 15 | persons.forEach(function(person) { 16 | res.write("Person: " + person.FirstName + "(" + person.Age + ")"); 17 | }); 18 | res.end("Total number of persons a century old:" + persons.length); 19 | }) 20 | }); 21 | 22 | }).listen(3002); 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Types/Authentication/AuthenticationBase.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define("$data.Authentication.AuthenticationBase", null, null, { 4 | constructor: function (cfg) { 5 | this.configuration = cfg || {}; 6 | this.Authenticated = false; 7 | }, 8 | /// { error:, abort:, pending:, success: } 9 | Login: function (callbacks) { 10 | Guard.raise("Pure class"); 11 | }, 12 | Logout: function () { 13 | Guard.raise("Pure class"); 14 | }, 15 | CreateRequest: function (cfg) { 16 | Guard.raise("Pure class"); 17 | } 18 | 19 | }, null); 20 | 21 | export default $data 22 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/EntityContextExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.EntityContextExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (instance) { 5 | /// 6 | //Object.defineProperty(this, "instance", { value: instance, enumerable: false }); 7 | this.instance = instance; 8 | //this.storage_type = {}; 9 | //this.typeName = this.type.name; 10 | }, 11 | instance: { enumerable: false }, 12 | nodeType : { value: $data.Expressions.ExpressionType.EntityContext, enumerable: true } 13 | 14 | }); 15 | 16 | export default $data 17 | -------------------------------------------------------------------------------- /src/Types/Expressions/DistinctExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.DistinctExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function constructor(source, expression, nType) { 5 | /// 6 | /// 7 | this.source = source; 8 | }, 9 | nodeType: { value: $data.Expressions.ExpressionType.Distinct }, 10 | toString: function (debug) { 11 | //var result; 12 | //result = debug ? this.type + " " : ""; 13 | //result = result + this.name; 14 | var result = "unimplemented"; 15 | return result; 16 | } 17 | }, null); 18 | 19 | export default $data -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/Test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Types/Notifications/ChangeDistributor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Notifications.ChangeDistributor', $data.Notifications.ChangeDistributorBase, null, { 4 | constructor: function (broadcastUrl) { 5 | this.broadcastUrl = broadcastUrl; 6 | }, 7 | distributeData: function (data) { 8 | $data.ajax({ 9 | url: this.broadcastUrl, 10 | type: "POST", 11 | data: 'data=' + JSON.stringify(data), 12 | succes: this.success, 13 | error: this.error 14 | }); 15 | }, 16 | broadcastUrl: { dataType: "string" }, 17 | success: function () { }, 18 | error: function () { } 19 | }, null); 20 | 21 | export default $data 22 | -------------------------------------------------------------------------------- /test/qunit/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Test source
8 | Test JayData
9 | Test JayData CDN
10 | Test JayData (min)
11 | Test JayData from nuget
12 | Test JayData from nuget (min)
13 | Test JayData from nuget (auto provider loader)
14 | Test LocalItemStore
15 | Test Handlebars
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Types/Transaction.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Transaction', null, null, { 4 | constructor: function () { 5 | this._objectId = (new Date()).getTime(); 6 | $data.Trace.log("create: ", this._objectId); 7 | 8 | this.oncomplete = new $data.Event("oncomplete", this); 9 | this.onerror = new $data.Event("onerror", this); 10 | }, 11 | abort: function () { 12 | Guard.raise(new Exception('Not Implemented', 'Not Implemented', arguments)); 13 | }, 14 | 15 | _objectId: { type: $data.Integer }, 16 | transaction: { type: $data.Object }, 17 | 18 | oncomplete: { type: $data.Event }, 19 | onerror: { type: $data.Event } 20 | }, null); 21 | 22 | export default $data 23 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/SqLite/SqlPagingCompiler.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | import { SqlStatementBlocks } from './SqLiteCompiler.js'; 3 | 4 | $C('$data.sqLite.SqlPagingCompiler', $data.Expressions.EntityExpressionVisitor, null, { 5 | constructor: function (provider) { 6 | this.provider = provider; 7 | }, 8 | compile: function (expression, context) { 9 | this.Visit(expression, context); 10 | }, 11 | VisitPagingExpression: function (expression, sqlBuilder) { 12 | this.Visit(expression.amount, sqlBuilder); 13 | }, 14 | VisitConstantExpression: function (expression, sqlBuilder) { 15 | sqlBuilder.addParameter(expression.value); 16 | sqlBuilder.addText(SqlStatementBlocks.parameter); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/EntityFieldExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.EntityFieldExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, selector) { 5 | /// 6 | /// 7 | this.selector = selector; 8 | this.source = source; 9 | 10 | 11 | if (this.selector instanceof $data.Expressions.MemberInfoExpression || this.selector.name) { 12 | this.memberName = this.selector.name; 13 | } 14 | }, 15 | 16 | nodeType: { value: $data.Expressions.ExpressionType.EntityField } 17 | }); 18 | 19 | export default $data 20 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/CodeExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.CodeExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, parameters) { 5 | if (Container.resolveType(Container.getTypeName(source)) == $data.String && 6 | source.replace(/^[\s\xA0]+/, "").match("^function") != "function" && 7 | !/^[^\.]*(=>)/.test(source.replace(/^[\s\xA0]+/, ""))) 8 | { 9 | source = "function (it) { return " + source + "; }"; 10 | } 11 | 12 | this.source = source; 13 | this.parameters = parameters; 14 | }, 15 | nodeType: { value: $data.Expressions.ExpressionType.Code, enumerable: true } 16 | }); 17 | 18 | export default $data 19 | -------------------------------------------------------------------------------- /src/Types/Expressions/GroupExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.GroupExpression', $data.Expressions.EntitySetExpression, null, { 4 | constructor: function constructor(source, expression) { 5 | /// 6 | /// 7 | //this.source = source; 8 | //this.selector = expression; 9 | }, 10 | nodeType: { value: $data.Expressions.ExpressionType.GroupBy, enumerable: true }, 11 | toString: function toString(debug) { 12 | //var result; 13 | //result = debug ? this.type + " " : ""; 14 | //result = result + this.name; 15 | var result = "unimplemented"; 16 | return result; 17 | } 18 | }, null); 19 | 20 | export default $data -------------------------------------------------------------------------------- /src/Types/Expressions/ObjectFieldExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ObjectFieldExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (fieldName, expression) { 5 | /// 6 | /// 7 | this.fieldName = fieldName; 8 | this.expression = expression; 9 | }, 10 | nodeType: { value: $data.Expressions.ExpressionType.ObjectField, writable: true }, 11 | 12 | toString: function (debug) { 13 | //var result; 14 | //result = debug ? this.type + " " : ""; 15 | //result = result + this.name; 16 | var result = "unimplemented"; 17 | return result; 18 | } 19 | }, null); 20 | 21 | export default $data 22 | -------------------------------------------------------------------------------- /src/Types/Expressions/PagingExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.PagingExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, expression, nType) { 5 | /// 6 | /// 7 | this.source = source; 8 | this.amount = expression; 9 | this.nodeType = nType; 10 | }, 11 | nodeType: { value: $data.Expressions.ExpressionType.Unknown, writable: true }, 12 | 13 | toString: function (debug) { 14 | //var result; 15 | //result = debug ? this.type + " " : ""; 16 | //result = result + this.name; 17 | var result = "unimplemented"; 18 | return result; 19 | } 20 | }, null); 21 | 22 | export default $data 23 | -------------------------------------------------------------------------------- /src/TypeSystem/Trace/Logger.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | $data.Class.define('$data.Logger', $data.TraceBase, null, { 4 | log: function () { 5 | Array.prototype.unshift.call(arguments, this.getDateFormat()); 6 | console.log.apply(console, arguments); 7 | }, 8 | warn: function () { 9 | Array.prototype.unshift.call(arguments, this.getDateFormat()); 10 | console.warn.apply(console, arguments); 11 | }, 12 | error: function () { 13 | Array.prototype.unshift.call(arguments, this.getDateFormat()); 14 | console.error.apply(console, arguments); 15 | }, 16 | 17 | getDateFormat: function () { 18 | var date = new Date(); 19 | return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds() + '.' + date.getMilliseconds(); 20 | } 21 | }); 22 | 23 | export default $data 24 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/OrderExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.OrderExpression', $data.Expressions.EntitySetExpression, null, { 4 | constructor: function (source, expression, nType) { 5 | /// 6 | /// 7 | //this.source = source; 8 | //this.selector = expression; 9 | this.nodeType = nType; 10 | }, 11 | nodeType: { value: $data.Expressions.ExpressionType.OrderBy, writable: true }, 12 | 13 | toString: function (debug) { 14 | //var result; 15 | //result = debug ? this.type + " " : ""; 16 | //result = result + this.name; 17 | var result = "unimplemented"; 18 | return result; 19 | } 20 | }, null); 21 | 22 | export default $data 23 | -------------------------------------------------------------------------------- /src/Types/DbClient/SqLiteNjClient/SqLiteNjConnection.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.sqLiteNJClient.SqLiteNjConnection', $data.dbClient.DbConnection, null, 4 | { 5 | constructor: function (params) { 6 | this.connectionParams = params; 7 | }, 8 | isOpen: function () { 9 | return this.database !== null && this.database !== undefined; 10 | }, 11 | open: function () { 12 | if (this.database == null) { 13 | var p = this.connectionParams; 14 | this.database = new sqLiteModule.Database(p.fileName); 15 | } 16 | }, 17 | close: function () { 18 | //not supported yet (performance issue) 19 | }, 20 | createCommand: function (queryStr, params) { 21 | var cmd = new $data.dbClient.sqLiteNJClient.SqLiteNjCommand(this, queryStr, params); 22 | return cmd; 23 | } 24 | }, null); 25 | -------------------------------------------------------------------------------- /src/Types/Expressions/Visitors/LogicalSchemaBinderVisitor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | //"use strict"; // suspicious code 4 | 5 | $C('$data.Expressions.LogicalSchemaBinderVisitor', 6 | $data.Expressions.ExpressionVisitor, null, 7 | { 8 | constructor: function (expression, binder) { 9 | 10 | }, 11 | 12 | VisitProperty: function (expression, context) { 13 | /// 14 | var exp = this.Visit(expression.expression, context); 15 | var mem = this.Visit(expression.member, context); 16 | 17 | var type = exp.type; 18 | var memberType = context.memberResolver.resolve(type, mem.value); 19 | mem.type = memberType; 20 | return Container.createPropertyExpression(exp, mem); 21 | } 22 | 23 | }, {}); 24 | 25 | export default $data 26 | -------------------------------------------------------------------------------- /src/TypeSystem/initializeJayData.js: -------------------------------------------------------------------------------- 1 | import $data from './initializeJayDataClient.js'; 2 | import * as acorn from 'acorn'; 3 | import * as pkg from '../../package.json'; 4 | 5 | if (typeof console === 'undefined') { 6 | console = { 7 | warn: function() {}, 8 | error: function() {}, 9 | log: function() {}, 10 | dir: function() {}, 11 | time: function() {}, 12 | timeEnd: function() {} 13 | }; 14 | } 15 | 16 | if (!console.warn) console.warn = function() {}; 17 | if (!console.error) console.error = function() {}; 18 | 19 | (function($data) { 20 | /// 21 | /// Collection of JayData services 22 | /// 23 | $data.__namespace = true; 24 | $data.version = "JayData " + pkg.version; 25 | $data.versionNumber = pkg.version; 26 | $data.root = {}; 27 | $data.Acorn = acorn; 28 | 29 | })($data); 30 | export default $data 31 | // Do not remove this block, it is used by jsdoc 32 | /** 33 | @name $data.Base 34 | @class base class 35 | */ 36 | -------------------------------------------------------------------------------- /src/Types/DbClient/JayStorageClient/JayStorageConnection.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.jayStorageClient.JayStorageConnection', $data.dbClient.DbConnection, null, 4 | { 5 | constructor: function (params) { 6 | this.connectionParams = params; 7 | }, 8 | isOpen: function () { 9 | return true; 10 | //return this.database !== null && this.database !== undefined; 11 | }, 12 | open: function () { 13 | /*if (this.database == null) { 14 | var p = this.connectionParams; 15 | this.database = new sqLiteModule.Database(p.fileName); 16 | }*/ 17 | }, 18 | close: function () { 19 | //not supported yet (performance issue) 20 | }, 21 | createCommand: function (queryStr, params) { 22 | var cmd = new $data.dbClient.jayStorageClient.JayStorageCommand(this, queryStr, params); 23 | return cmd; 24 | } 25 | }, null); 26 | -------------------------------------------------------------------------------- /src/Types/EntityAttachModes.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Class.define("$data.EntityAttachMode", null, null, {}, { 4 | defaultMode: 'Default', 5 | AllChanged: function (data) { 6 | var memDefs = data.getType().memberDefinitions.getPublicMappedProperties(); 7 | for (var i = 0; i < memDefs.length; i++) { 8 | data._setPropertyChanged(memDefs[i]); 9 | } 10 | data.entityState = $data.EntityState.Modified; 11 | }, 12 | KeepChanges: function (data) { 13 | if (data.changedProperties && data.changedProperties.length > 0) { 14 | data.entityState = $data.EntityState.Modified; 15 | } else { 16 | data.entityState = $data.EntityState.Unchanged; 17 | } 18 | }, 19 | Default: function (data) { 20 | data.entityState = $data.EntityState.Unchanged; 21 | data.changedProperties = undefined; 22 | } 23 | }); 24 | 25 | export default $data 26 | -------------------------------------------------------------------------------- /src/TypeSystem/index.js: -------------------------------------------------------------------------------- 1 | import $data, { $C as _$C, Container as _container } from './TypeSystem.js'; 2 | import Types from './Types/Types.js'; 3 | import Trace from './Trace/Trace.js'; 4 | import Logger from './Trace/Logger.js'; 5 | import SimpleBase from './Types/SimpleBase.js'; 6 | import Geospatial from './Types/Geospatial.js'; 7 | import Geography from './Types/Geography.js'; 8 | import Geometry from './Types/Geometry.js'; 9 | import Guid from './Types/Guid.js'; 10 | import Blob from './Types/Blob.js'; 11 | import EdmTypes from './Types/EdmTypes.js'; 12 | import Converter from './Types/Converter.js'; 13 | 14 | import { Guard as _guard, Exception as _exception } from 'jaydata-error-handler'; 15 | 16 | import { PromiseHandler } from 'jaydata-promise-handler'; 17 | PromiseHandler.use($data); 18 | 19 | export var Guard = _guard; 20 | $data.Guard = _guard; 21 | 22 | export var Exception = _exception; 23 | $data.Exception = _exception; 24 | 25 | export var $C = _$C; 26 | $data.$C = _$C; 27 | 28 | export var Container = _container; 29 | export default $data; 30 | -------------------------------------------------------------------------------- /src/JayDataModules/qDeferred.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | import * as q from 'q' 3 | 4 | class Deferred extends $data.PromiseHandlerBase{ 5 | constructor(){ 6 | super(); 7 | this.deferred = new q.defer(); 8 | } 9 | createCallback(callBack){ 10 | callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack); 11 | var self = this; 12 | 13 | return { 14 | success: function () { 15 | callBack.success.apply(self.deferred, arguments); 16 | self.deferred.resolve.apply(self.deferred, arguments); 17 | }, 18 | error: function () { 19 | Array.prototype.push.call(arguments, self.deferred); 20 | callBack.error.apply(self.deferred, arguments); 21 | } 22 | }; 23 | } 24 | getPromise(){ 25 | return this.deferred.promise; 26 | } 27 | } 28 | 29 | $data.PromiseHandler = $data.Deferred = Deferred; 30 | export default $data; 31 | -------------------------------------------------------------------------------- /src/TypeSystem/Types/SimpleBase.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | /* $data.SimpleBase */ 4 | $data.SimpleBase = function SimpleBase(data) { 5 | if (typeof data === 'object' && data) { 6 | if (Array.isArray(this.constructor.validMembers)) { 7 | for (var i = 0; i < this.constructor.validMembers.length; i++) { 8 | var name = this.constructor.validMembers[i]; 9 | 10 | if (data[name] !== undefined) { 11 | this[name] = data[name]; 12 | } 13 | } 14 | 15 | } else { 16 | delete data.type; 17 | $data.typeSystem.extend(this, data); 18 | } 19 | } 20 | } 21 | $data.SimpleBase.registerType = function (name, type, base) { 22 | base = base || $data.SimpleBase; 23 | 24 | type.type = name; 25 | type.prototype = Object.create(base.prototype); 26 | type.prototype.constructor = type; 27 | } 28 | $data.Container.registerType(['$data.SimpleBase', 'SimpleBase'], $data.SimpleBase); 29 | 30 | export default $data 31 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/mongoDB/ClientObjectID.js: -------------------------------------------------------------------------------- 1 | import btoa from 'btoa'; 2 | import $data from 'jaydata/core'; 3 | 4 | $data.Class.define('$data.storageProviders.mongoDB.mongoDBProvider.ClientObjectID', null, null, { 5 | constructor: function(){ 6 | var time = Math.floor(new Date().getTime() / 1000).toString(16); 7 | 8 | var b64ua = btoa(navigator ? navigator.userAgent : 'nodejs'); 9 | var machine = (b64ua.charCodeAt(0) + b64ua.charCodeAt(1)).toString(16) + (b64ua.charCodeAt(2) + b64ua.charCodeAt(3)).toString(16) + (b64ua.charCodeAt(4) + b64ua.charCodeAt(5)).toString(16); 10 | 11 | var pid = ('0000' + Math.floor(Math.random() * 0xffff).toString(16)).slice(-4); 12 | var inc = ('000000' + (++$data.storageProviders.mongoDB.mongoDBProvider.ClientObjectID.idSeed).toString(16)).slice(-6); 13 | 14 | this.toString = this.toLocaleString = this.valueOf = function(){ return btoa(time + machine + pid + inc); }; 15 | }, 16 | value: { value: null } 17 | }, { 18 | idSeed: { value: Math.floor(Math.random() * 0xff) } 19 | }); 20 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/EdmTypeMapping.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Types/Expressions/ArrayLiteralExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ArrayLiteralExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (items) { 5 | /// 6 | /// 7 | /// 8 | this.items = items || []; 9 | }, 10 | nodeType: { value: $data.Expressions.ExpressionType.ArrayLiteral, writable: true }, 11 | 12 | items: { value: undefined, dataType: Array, elementType: $data.Expressions.ExpressionNode }, 13 | 14 | toString: function (debug) { 15 | //var result; 16 | //result = debug ? this.type + " " : ""; 17 | //result = result + this.name; 18 | /// 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/JayDataModules/errorhandler.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | (function(){ 4 | $data.__global.onerror = function(msg, url, line){ 5 | alert('Error' + (line ? ' in line ' + line : '') + '\n' + (url || '') + '\n' + msg); 6 | }; 7 | 8 | /*$data.__global.onerror = function(msg, url, line){ 9 | var html = '
{url}

{msg}

{line}
'; 10 | html = html.replace('{url}', url || ''); 11 | html = html.replace('{msg}', msg || ''); 12 | html = html.replace('{line}', line || ''); 13 | 14 | var container = document.querySelector ? document.querySelector('.jaydata-errorhandler') : document.getElementsByClassName('jaydata-errorhandler')[0]; 15 | if (!container){ 16 | container = document.createElement('DIV'); 17 | container.innerHTML = ''; 18 | container.className = 'jaydata-errorhandler'; 19 | document.body.appendChild(container); 20 | } 21 | 22 | container.innerHTML += html; 23 | };*/ 24 | })(); 25 | 26 | export default $data 27 | -------------------------------------------------------------------------------- /test/qunit/server_oData.js: -------------------------------------------------------------------------------- 1 | var $data = require('jaydata'); 2 | var news = require('./NewsReaderContext_server.js') 3 | var connect = require("connect"); 4 | var app = connect(); 5 | 6 | var dbAddress = '127.0.0.1'; 7 | var dbName = 'oDataUnitTests'; 8 | 9 | app.use(connect.query()); 10 | app.use($data.JayService.OData.BatchProcessor.connectBodyReader); 11 | app.use("/Services/emptyNewsReader.svc", $data.JayService.createAdapter( $news.Types.NewsContext, function() { 12 | console.log("===Query"); 13 | return new $news.Types.NewsContext({name: 'mongoDB', databaseName: dbName, address:dbAddress }) 14 | })) 15 | .use("/Services/oDataDbDelete.asmx/Delete", function(req, res){ 16 | console.log("===Delete"); 17 | var ctx = new $news.Types.NewsContext({name: 'mongoDB', databaseName: dbName, address:dbAddress,dbCreation:$data.storageProviders.DbCreationType.DropAllExistingTables }) 18 | ctx.onReady(function(){ 19 | res.write("ok"); 20 | res.end(); 21 | }); 22 | }) 23 | .use(connect.static("/home/nochtap/GitRepo/jaydata")) 24 | .listen(80); -------------------------------------------------------------------------------- /src/Types/StorageProviders/mongoDB/mongoDBPagingCompiler.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $C('$data.storageProviders.mongoDB.mongoDBPagingCompiler', $data.Expressions.EntityExpressionVisitor, null, { 4 | constructor: function (provider) { 5 | this.provider = provider; 6 | }, 7 | 8 | compile: function (expression, context) { 9 | this.Visit(expression, context); 10 | }, 11 | VisitPagingExpression: function (expression, context) { 12 | var pagingContext = { data: 0 }; 13 | this.Visit(expression.amount, pagingContext); 14 | switch (expression.nodeType) { 15 | case $data.Expressions.ExpressionType.Skip: context.options.skip = pagingContext.data; break; 16 | case $data.Expressions.ExpressionType.Take: context.options.limit = pagingContext.data; break; 17 | default: Guard.raise("Not supported nodeType"); break; 18 | } 19 | }, 20 | VisitConstantExpression: function (expression, context) { 21 | context.data += expression.value; 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/Types/AuthEntityContext.js: -------------------------------------------------------------------------------- 1 | //$data.EntitySetRights = { 2 | // None: 0, 3 | // ReadSingle: 1, 4 | // ReadMultiple: 2, 5 | // WriteAppend: 3, 6 | // WriteReplace: 4, 7 | // WriteDelete: 5, 8 | // WriteMerge: 6, 9 | // AllRead: 7, 10 | // AllWrite: 8, 11 | // All: 9 12 | //}; 13 | //$data.Class.define('$data.AuthEntityContext', $data.EntityContext, null, 14 | //{ 15 | // Users: { 16 | // dataType: $data.EntitySet, elementType: $data.Class.define("User", $data.Entity, null, { 17 | // Id: { dataType: "int", key: true, computed: true, required: true }, 18 | // UserName: { dataType: "string", required: true } 19 | // }, null) 20 | // }, 21 | // AccessRules: { 22 | // dataType: $data.EntitySet, elementType: $data.Class.define("AccessRule", $data.Entity, null, { 23 | // Id: { dataType: "int", key: true, computed: true, required: true }, 24 | // EntitySetName: { dataType: "string", required: true }, 25 | // Right: { dataType: "int", required: true }, 26 | // UserId: { dataType: "int", required: true } 27 | // }, null) 28 | // } 29 | //}, null); -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 JayStack Technologies LLC. http://jaydata.org/licensing 2 | 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 17 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 18 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/Types/Expressions/Visitors/LocalContextProcessor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C("$data.Expressions.LocalContextProcessor", $data.Expressions.GlobalContextProcessor, null, { 4 | constructor: function (evalMethod) { 5 | /// 6 | this.canResolve = function (paramExpression) { 7 | /// 8 | return paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter && 9 | (evalMethod("typeof " + paramExpression.name) !== 'undefined'); 10 | }; 11 | this.resolve = function(paramExpression) { 12 | /// 13 | /// 14 | var resultValue = evalMethod(paramExpression.name); 15 | var expression = Container.createConstantExpression(resultValue, typeof resultValue); 16 | return expression; 17 | }; 18 | 19 | } 20 | }); 21 | 22 | export default $data 23 | -------------------------------------------------------------------------------- /src/Types/Expressions/ParameterExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ParameterExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (name, type, nodeType) { 5 | /// 6 | /// 7 | //this.writePropertyValue("name", name); 8 | //this.writePropertyValue("type", type); 9 | this.nodeType = nodeType || $data.Expressions.ExpressionType.Parameter; 10 | this.name = name; 11 | this.type = type || "unknown"; 12 | var _owningFunction; 13 | }, 14 | 15 | owningFunction: { value: undefined, enumerable: false }, 16 | nodeType: { value: $data.Expressions.ExpressionType.Parameter, writable: true }, 17 | name: { value: undefined, dataType: String, writable: true }, 18 | type: { value: undefined, dataType: "object", writable: true}, 19 | toString: function (debug) { 20 | var result; 21 | result = debug ? this.type + " " : ""; 22 | result = result + this.name; 23 | return result; 24 | } 25 | }, null); 26 | 27 | export default $data 28 | -------------------------------------------------------------------------------- /dist/compatiblity.js: -------------------------------------------------------------------------------- 1 | var Module = require('module'); 2 | var realResolve = Module._resolveFilename; 3 | Module._resolveFilename = function fakeResolve(request, parent) { 4 | if (request === 'jaydata/core') { 5 | return require('path').join(__dirname, './lib/index.js'); 6 | } 7 | return realResolve(request, parent); 8 | }; 9 | 10 | (function(g){ 11 | var $data = require('./lib/index'); 12 | require('./lib/Types/StorageProviders/Facebook/index'); 13 | require('./lib/Types/StorageProviders/IndexedDB/index'); 14 | require('./lib/Types/StorageProviders/InMemory/index'); 15 | require('./lib/Types/StorageProviders/mongoDB/index'); 16 | require('./lib/Types/StorageProviders/oData/index'); 17 | require('./lib/Types/StorageProviders/SqLite/index'); 18 | require('./lib/Types/StorageProviders/WebApi/index'); 19 | require('./lib/Types/StorageProviders/YQL/index'); 20 | 21 | $data.setModelContainer(g); 22 | g.Container = $data.Container; 23 | g.Guard = $data.Guard; 24 | g.$C = $data.$C; 25 | g.Exception = $data.Exception; 26 | g.MemberDefinition = $data.MemberDefinition; 27 | 28 | g.$data = $data; 29 | module.exports = $data; 30 | })(global || window); -------------------------------------------------------------------------------- /src/Types/Expressions/Visitors/ParameterProcessor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C("$data.Expressions.ParameterProcessor", $data.Expressions.ExpressionVisitor, null, { 4 | constructor: function () { 5 | ///Provides a base class for several ParameterProcessors like GlobalParameterProcessor or LambdaParameterProcessor 6 | }, 7 | 8 | Visit: function (node, context) { 9 | if ((node instanceof $data.Expressions.ParameterExpression || 10 | node instanceof $data.Expressions.ThisExpression) 11 | && this.canResolve(node)) { 12 | var result = this.resolve(node, context); 13 | if (result !== node) 14 | result["resolvedBy"] = this.constructor.name; 15 | return result; 16 | } else { 17 | return node; 18 | } 19 | }, 20 | 21 | canResolve: function (paramExpression) { 22 | /// 23 | Guard.raise("Pure method"); 24 | }, 25 | resolve: function (paramExpression) { 26 | /// 27 | Guard.raise("Pure method"); 28 | } 29 | }); 30 | 31 | export default $data 32 | -------------------------------------------------------------------------------- /src/JayDataModules/deferred.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from 'jaydata/core'; 2 | import jQuery from 'jquery'; 3 | 4 | class Deferred extends $data.PromiseHandlerBase{ 5 | constructor(){ 6 | super(); 7 | this.deferred = new jQuery.Deferred(); 8 | } 9 | createCallback(callBack){ 10 | callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack); 11 | var self = this; 12 | 13 | return { 14 | success: function () { 15 | callBack.success.apply(self.deferred, arguments); 16 | self.deferred.resolve.apply(self.deferred, arguments); 17 | }, 18 | error: function () { 19 | Array.prototype.push.call(arguments, self.deferred); 20 | callBack.error.apply(self.deferred, arguments); 21 | }, 22 | notify: function () { 23 | callBack.notify.apply(self.deferred, arguments); 24 | self.deferred.notify.apply(self.deferred, arguments); 25 | } 26 | }; 27 | } 28 | getPromise(){ 29 | return this.deferred.promise(); 30 | } 31 | } 32 | 33 | $data.PromiseHandler = $data.Deferred = Deferred; 34 | export default $data; 35 | -------------------------------------------------------------------------------- /nightwatch.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_folders" : ["tests"], 3 | "output_folder" : "reports", 4 | "custom_commands_path" : "", 5 | "custom_assertions_path" : "", 6 | "page_objects_path" : "", 7 | "globals_path" : "", 8 | 9 | "selenium" : { 10 | "start_process" : false, 11 | "server_path" : "./selenium/selenium-server-standalone-2.48.2.jar", 12 | "log_path" : "", 13 | "host" : "127.0.0.1", 14 | "port" : 4444, 15 | "cli_args" : { 16 | "webdriver.chrome.driver" : "./selenium/chromedriver.exe", 17 | "webdriver.ie.driver" : "" 18 | } 19 | }, 20 | 21 | "test_settings" : { 22 | "default" : { 23 | "launch_url" : "http://localhost", 24 | "selenium_port" : 4444, 25 | "selenium_host" : "localhost", 26 | "silent": true, 27 | "screenshots" : { 28 | "enabled" : false, 29 | "path" : "" 30 | }, 31 | "desiredCapabilities": { 32 | "browserName": "chrome", 33 | "javascriptEnabled": true, 34 | "acceptSslCerts": true 35 | } 36 | }, 37 | 38 | "firefox" : { 39 | "desiredCapabilities": { 40 | "browserName": "firefox", 41 | "javascriptEnabled": true, 42 | "acceptSslCerts": true 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/oDataPagingCompiler.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $C('$data.storageProviders.oData.oDataPagingCompiler', $data.Expressions.EntityExpressionVisitor, null, { 4 | constructor: function (provider) { 5 | this.provider = provider; 6 | }, 7 | 8 | compile: function (expression, context) { 9 | this.Visit(expression, context); 10 | }, 11 | VisitPagingExpression: function (expression, context) { 12 | var pagingContext = { data: "" }; 13 | this.Visit(expression.amount, pagingContext); 14 | switch (expression.nodeType) { 15 | case $data.Expressions.ExpressionType.Skip: context['$skip'] = pagingContext.data; break; 16 | case $data.Expressions.ExpressionType.Take: context['$top'] = pagingContext.data; break; 17 | default: Guard.raise("Not supported nodeType"); break; 18 | } 19 | }, 20 | VisitConstantExpression: function (expression, context) { 21 | var typeName = Container.resolveName(expression.type); 22 | var converter = this.provider.fieldConverter.escape[typeName]; 23 | context.data += converter ? converter(expression.value) : expression.value; 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /src/Types/Expressions/ConstantExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ConstantExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (value, type, name, elementType) { 5 | this.value = value; 6 | //TODO 7 | //this.type = Container.getTypeName(value); 8 | 9 | this.type = type; 10 | this.name = name; 11 | this.elementType = elementType; 12 | if (!Guard.isNullOrUndefined(this.value)) { 13 | this.type = Container.resolveType(this.type) 14 | if ((this.type === $data.Array && this.elementType) || Container.resolveType(Container.getTypeName(this.value)) !== this.type) 15 | this.value = Container.convertTo(value, this.type, this.elementType); 16 | } 17 | }, 18 | nodeType: { value: $data.Expressions.ExpressionType.Constant, enumerable: true }, 19 | type: { value: Object, writable: true }, 20 | elementType: { value: Object, writable: true }, 21 | value: { value: undefined, writable: true }, 22 | toString: function (debug) { 23 | //return "[constant: " + this.value.toString() + "]"; 24 | return this.value.toString(); 25 | } 26 | }); 27 | 28 | export default $data 29 | -------------------------------------------------------------------------------- /src/Types/Expressions/SimpleBinaryExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.SimpleBinaryExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (left, right, nodeType, operator, type, resolution) { 5 | ///Represents a bin operation with left and right operands and an operator/// 6 | ///The left element of the binary operation 7 | ///The right element of the binary operation 8 | /// 9 | this.left = left; 10 | this.right = right; 11 | this.nodeType = nodeType; 12 | this.operator = operator; 13 | this.type = type; 14 | this.resolution = resolution; 15 | }, 16 | 17 | implementation: { 18 | get: function () { 19 | return $data.binaryOperators.getOperator(this.operator).implementation; 20 | }, 21 | set: function () { } 22 | 23 | }, 24 | //nodeType: { value: $data.Expressions.ExpressionType }, 25 | type: { value: "number", writable: true } 26 | }); 27 | 28 | export default $data 29 | -------------------------------------------------------------------------------- /test/qunit/scripts/storageModelTests.js: -------------------------------------------------------------------------------- 1 | var providerConfig = { name: "oData", databaseName: 'T1', oDataServiceHost: "/Services/emptyNewsReader.svc", serviceUrl: '/Services/oDataDbDelete.asmx', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }; 2 | module("Storage model tests"); 3 | test('Filter_noFilter_orderby', function () { 4 | 5 | stop(2); 6 | (new $news.Types.NewsContext(providerConfig)).onReady(function (db) { 7 | start(1); 8 | window['ctx'] = db; 9 | console.dir(db._storageModel); 10 | 11 | var usr1 = Container.createUser({ LoginName: 'User1', Email: 'email1@test.com' }); 12 | var usr2 = Container.createUser({ LoginName: 'User1', Email: 'email1@test.com' }); 13 | var apple = Container.createTag({ Title: 'apple' }); 14 | var pear = Container.createTag({ Title: 'pear' }); 15 | var banana = Container.createTag({ Title: 'banana' }); 16 | var item1 = Container.createTestItem({ Id: 1, User: usr1, Tags: [apple, pear] }); 17 | var item2 = Container.createTestItem({ Id: 3, User: usr1, Tags: [banana, pear] }); 18 | db.TestTable.add(item1); 19 | db.TestTable.add(item2); 20 | db.saveChanges(function () { 21 | start(1); 22 | ok(true); 23 | }); 24 | }); 25 | }); -------------------------------------------------------------------------------- /src/JayDataModules/inMemory.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | (function ($data) { 4 | 5 | $data.Array.prototype.toQueryable = function () { 6 | if (this.length > 0) { 7 | var firtsItem = this[0]; 8 | var type = Container.resolveType(Container.getTypeName(firtsItem)); 9 | 10 | if (!type.isAssignableTo || !type.isAssignableTo($data.Entity)) 11 | Guard.raise(new Exception("Type '" + Container.resolveName(type) + "' is not subclass of $data.Entity", "Not supported", type)); 12 | 13 | for (var i = 0; i < this.length; i++) { 14 | Guard.requireType('array item check', this[i], type); 15 | } 16 | 17 | } 18 | 19 | var typeName = 'inMemoryArray_' + type.name; 20 | if (!Container.isTypeRegistered(typeName)) { 21 | $data.EntityContext.extend(typeName, { 22 | Source: { 23 | type: $data.EntitySet, 24 | elementType: type 25 | } 26 | }); 27 | } 28 | 29 | var context = Container['create' + typeName]({ name: 'InMemory', source: { Source: this} }); 30 | 31 | return context.Source; 32 | } 33 | 34 | })($data); 35 | 36 | export default $data 37 | -------------------------------------------------------------------------------- /src/Types/Expressions/ObjectLiteralExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ObjectLiteralExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (members) { 5 | ///Represent an object initializer literal expression Ex: { prop: value} 6 | /// 7 | this.members = members; 8 | }, 9 | nodeType: { value: $data.Expressions.ExpressionType.ObjectLiteral, writable: true }, 10 | 11 | toString: function (debug) { 12 | //var result; 13 | //result = debug ? this.type + " " : ""; 14 | //result = result + this.name; 15 | var result = "unimplemented"; 16 | return result; 17 | }, 18 | 19 | implementation: { 20 | get: function () { 21 | return function(namesAndValues) { 22 | var result = { }; 23 | namesAndValues.forEach(function(item) { 24 | result[item.name] = item.value; 25 | }); 26 | return result; 27 | }; 28 | }, 29 | set: function () { 30 | } 31 | } 32 | 33 | }, null); 34 | 35 | export default $data 36 | -------------------------------------------------------------------------------- /test/qunit/websqlClient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 31 | 32 | 33 | 34 |
35 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/context.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var contextTypes = {}; 4 | 5 | $data.Entity.extend("$news.Types.Category", { 6 | Id: { type: "id", key: true, computed: true, required: true }, 7 | Title: { type: "string" }, 8 | Articles: { type: "Array", elementType: "id" } 9 | }); 10 | 11 | $data.Entity.extend("$news.Types.Article", { 12 | Id: { type: "id", key: true, computed: true, required: true }, 13 | Title: { type: "string" }, 14 | Lead: { type: "string" }, 15 | Body: { type: "string" }, 16 | CreateDate: { type: "datetime" }, 17 | Thumbnail_LowRes: { type: "blob" }, 18 | Thumbnail_HighRes: { type: "blob" }, 19 | Category: { type: "id" }, 20 | Tags: { type: "Array", elementType: "string" }, 21 | Comment: { type: "string" }, 22 | Foobar: { type: "string" }, 23 | Google: { type: "number" } 24 | }); 25 | 26 | $data.EntityContext.extend("$news.Types.Context", { 27 | Categories: { type: $data.EntitySet, elementType: $news.Types.Category, beforeCreate: function(data){ 28 | data[0].Title = data[0].Title.toUpperCase(); 29 | } 30 | }, 31 | Articles: { type: $data.EntitySet, elementType: $news.Types.Article } 32 | }); 33 | 34 | contextTypes["NewsReader"] = $news.Types.Context; 35 | 36 | exports = module.exports = { contextTypes: contextTypes }; 37 | 38 | })(); 39 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/FrameOperationExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.FrameOperationExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, operation, parameters) { 5 | this.source = source; 6 | this.operation = operation; 7 | this.parameters = parameters; 8 | 9 | switch (true) { 10 | case this.source instanceof $data.Expressions.EntitySetExpression: 11 | case this.source instanceof $data.Expressions.FrameOperationExpression: 12 | this.elementType = this.source.elementType; 13 | this.storageModel = this.source.storageModel; 14 | break; 15 | } 16 | }, 17 | nodeType: { value: $data.Expressions.ExpressionType.FrameOperation } 18 | 19 | }); 20 | 21 | $C('$data.Expressions.EntityFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { 22 | nodeType: { value: $data.Expressions.ExpressionType.EntityFunctionOperation } 23 | }); 24 | 25 | $C('$data.Expressions.ContextFunctionOperationExpression', $data.Expressions.FrameOperationExpression, null, { 26 | nodeType: { value: $data.Expressions.ExpressionType.ContextFunctionOperation } 27 | }); 28 | 29 | export default $data 30 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/SqLite/index.js: -------------------------------------------------------------------------------- 1 | import $data from 'jaydata/core'; 2 | 3 | //dbCommand 4 | import DbCommand from '../../DbClient/DbCommand.js'; 5 | import DbConnection from '../../DbClient/DbConnection.js'; 6 | import OpenDbCommand from '../../DbClient/OpenDatabaseClient/OpenDbCommand.js'; 7 | import OpenDbConnection from '../../DbClient/OpenDatabaseClient/OpenDbConnection.js'; 8 | import JayStorageCommand from '../../DbClient/JayStorageClient/JayStorageCommand.js'; 9 | import JayStorageConnection from '../../DbClient/JayStorageClient/JayStorageConnection.js'; 10 | import SqLiteNjCommand from '../../DbClient/SqLiteNjClient/SqLiteNjCommand.js'; 11 | import SqLiteNjConnection from '../../DbClient/SqLiteNjClient/SqLiteNjConnection.js'; 12 | 13 | //provider 14 | import SqLiteConverter from './SqLiteConverter.js'; 15 | import SqLiteStorageProvider from './SqLiteStorageProvider.js'; 16 | import SqLiteCompiler from './SqLiteCompiler.js'; 17 | import SqlPagingCompiler from './SqlPagingCompiler.js'; 18 | import SqlOrderCompiler from './SqlOrderCompiler.js'; 19 | import SqlProjectionCompiler from './SqlProjectionCompiler.js'; 20 | import SqlExpressionMonitor from './SqlExpressionMonitor.js'; 21 | import SqlFilterCompiler from './SqlFilterCompiler.js'; 22 | import sqLite_ModelBinderCompiler from './ModelBinder/sqLite_ModelBinderCompiler.js'; 23 | 24 | export default $data; 25 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JayData", 3 | "version": "1.3.5", 4 | "homepage": "http://jaydata.org", 5 | "authors": ["Hajnalka Battancs ", "Dániel József", "János Roden", "László Horváth", "Peter Nochta ", 6 | "Péter Zentai ", "Róbert Bónay ", "Szabolcs Czinege", "Viktor Borza ", "Viktor Lázár ", 7 | "Zoltán Gyebrovszki", "Gábor Dolla"], 8 | "description": "JayData is a unified data access library for JavaScript to CRUD data from different sources like WebSQL, IndexedDB, MongoDb, WebAPI, OData, HTML5 localStorage, Facebook or YQL. The library can be integrated with KendoUI, Knockout.js, Handlebars.js or Sencha Touch 2 and can be used on Node.js as well.", 9 | "main": ["./release/jaydata.min.js","./release/jaydata.js","./release/jaydata-vsdoc.js"], 10 | "keywords": ["mobile data", "javascipt data", "local storage", "mobile platform", "html5", "html5 application", "html5 applications", "html5 local", "html5 local storage", "html5 mobile", "crossplatform mobile developement", "opensource mobile", "opensource data library", "html5 library", "hybrid mobile", "nodejs data", 11 | "jadata","odata", "web api", "kendo ui", "sencha touch", "websql", "sqlite", "mongodb" 12 | ], 13 | "license": "MIT" 14 | } 15 | -------------------------------------------------------------------------------- /src/JayDataModules/jaydata.mscrm.server.js: -------------------------------------------------------------------------------- 1 | (function (window, undefined) { 2 | window.parent.postMessage({ MessageHandlerLoaded: true }, '*'); 3 | window.addEventListener("message", function (e) { 4 | if (e.data.requestProxy) { 5 | var cnf = e.data; 6 | var xhttp = new XMLHttpRequest(); 7 | xhttp.open("GET", cnf.url, true); 8 | if (cnf.httpHeaders) { 9 | Object.keys(cnf.httpHeaders).forEach(function (header) { 10 | xhttp.setRequestHeader(header, cnf.httpHeaders[header]); 11 | }); 12 | } 13 | xhttp.onreadystatechange = function () { 14 | if (xhttp.readyState === 4) { 15 | var response = { requestUri: cnf.url, statusCode: xhttp.status, statusText: xhttp.statusText, responseText: xhttp.responseText }; 16 | xhttp = null; 17 | e.source.postMessage(response, e.origin); 18 | } 19 | }; 20 | 21 | xhttp.send(""); 22 | } else { 23 | window.OData.request(e.data, function (data, response) { 24 | e.source.postMessage(response, e.origin); 25 | }, 26 | function (error) { 27 | e.source.postMessage(error, e.origin); 28 | }); 29 | } 30 | }, false); 31 | })(window); 32 | -------------------------------------------------------------------------------- /test/qunit/nodeJsTest.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | try{ require('jaydata-mongodb-pro'); }catch(err){} 3 | require('./NewsReaderContext.js'); 4 | 5 | $data.Class.define('$data.Logger', $data.TraceBase, null, { 6 | log: function () {}, 7 | warn: function () {}, 8 | error: function () {} 9 | }); 10 | 11 | require('./test_Node.js'); 12 | 13 | var reporter = require('nodeunit').reporters.default; 14 | 15 | //Tests 16 | exports['commonTests'] = require('./UnitTests/NodeJS/commonTests.js'); 17 | exports['EntityTransform'] = require('./UnitTests/NodeJS/EntityTransformTests.js'); 18 | exports['oDataMetaDataGenerator'] = require('./UnitTests/NodeJS/oDataMetaDataGeneratorTests.js'); 19 | exports['oDataResponseDataBuilder'] = require('./UnitTests/NodeJS/oDataResponseDataBuilderTests.js'); 20 | exports['oDataBatchTest'] = require('./UnitTests/NodeJS/oDataBatchTests.js'); 21 | //exports['oDataGeoTests'] = require('./UnitTests/NodeJS/oDataGeoTests.js'); 22 | exports['argumentBinderTests'] = require('./UnitTests/NodeJS/argumentBinderTests.js'); 23 | exports['oDataXmlResultTests'] = require('./UnitTests/NodeJS/oDataXmlResultTests.js'); 24 | 25 | try{ exports['mongoProviderTests'] = require('./Pro/UnitTests/mongoProviderTests.js'); } 26 | catch(err){ exports['mongoProviderTests'] = require('./UnitTests/mongoProviderTests.js'); } 27 | 28 | reporter.run(exports, null, function(){ 29 | process.exit(); 30 | }); 31 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/service.js: -------------------------------------------------------------------------------- 1 | (function(contextTypes){ 2 | 3 | var connect = require("connect"); 4 | 5 | var app53999 = connect(); 6 | app53999.use(function (req, res, next){ 7 | res.setHeader("Access-Control-Allow-Origin", "*"); 8 | res.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, MaxDataServiceVersion, DataServiceVersion"); 9 | res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, MERGE"); 10 | if (req.method === "OPTIONS") res.end(); else next(); 11 | }); 12 | app53999.use(connect.query()); 13 | app53999.use($data.JayService.OData.BatchProcessor.connectBodyReader); 14 | $data.Class.defineEx("newsreader", [contextTypes["NewsReader"], $data.ServiceBase]); 15 | app53999.use("/newsreader", $data.JayService.createAdapter(newsreader, function(req, res){ 16 | return new newsreader({ name: "mongoDB", databaseName: req.headers["X-AppId"] + "_NewsReader" }); 17 | })); 18 | 19 | $data.Class.defineEx("newsreader2", [contextTypes["NewsReader"], ObjectIDFactory]); 20 | app53999.use("/newsreader2", $data.JayService.createAdapter(newsreader2, function(req, res){ 21 | return new newsreader2({ name: "mongoDB", databaseName: req.headers["X-AppId"] + "_NewsReader" }); 22 | })); 23 | 24 | app53999.use("/ObjectIDFactory", $data.JayService.createAdapter(ObjectIDFactory, function(req, res){ 25 | return new ObjectIDFactory(); 26 | })); 27 | 28 | app53999.listen(53999); 29 | 30 | })(require("./context.js").contextTypes); 31 | -------------------------------------------------------------------------------- /src/TypeSystem/Types/Geospatial.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | $data.Geospatial = function Geospatial() { 4 | this.type = this.constructor.type; 5 | if (Array.isArray(this.constructor.validMembers)) { 6 | for (var i = 0; i < this.constructor.validMembers.length; i++) { 7 | var name = this.constructor.validMembers[i]; 8 | this[name] = undefined; 9 | } 10 | } 11 | 12 | $data.SimpleBase.apply(this, arguments); 13 | this.type = this.constructor.type || 'Unknown'; 14 | }; 15 | $data.SimpleBase.registerType('Geospatial', $data.Geospatial); 16 | $data.Container.registerType(['$data.Geospatial', 'Geospatial'], $data.Geospatial); 17 | 18 | $data.point = function (arg) { 19 | if (arg && arg.crs) { 20 | if (arg.crs.properties && arg.crs.properties.name === $data.GeometryBase.defaultCrs.properties.name) { 21 | return new $data.GeometryPoint(arg); 22 | } else { 23 | return new $data.GeographyPoint(arg); 24 | } 25 | } else if(arg) { 26 | if ('x' in arg && 'y' in arg) { 27 | return new $data.GeometryPoint(arg.x, arg.y); 28 | } else if ('longitude' in arg && 'latitude' in arg) { 29 | return new $data.GeographyPoint(arg.longitude, arg.latitude); 30 | } else if ('lng' in arg && 'lat' in arg) { 31 | return new $data.GeographyPoint(arg.lng, arg.lat); 32 | } 33 | } 34 | }; 35 | 36 | export default $data 37 | -------------------------------------------------------------------------------- /test/unit-tests/scripts/qunitToMocha.js: -------------------------------------------------------------------------------- 1 | import mock$data from '../../core.js'; 2 | import $data from 'jaydata/core'; 3 | import { expect } from 'chai'; 4 | 5 | var exports = module.exports = {}; 6 | 7 | exports.equal = function(actual, expected, msg) { 8 | it(msg, () => { 9 | expect(actual).to.equal(expected); 10 | }); 11 | }; 12 | 13 | exports.deepEqual = function(actual, expected, msg) { 14 | it(msg, () => { 15 | expect(actual).to.deep.equal(expected); 16 | }); 17 | }; 18 | 19 | exports.notEqual = function(actual, expected, msg) { 20 | it(msg, () => { 21 | expect(actual).to.not.equal(expected); 22 | }); 23 | }; 24 | 25 | exports.ok = function(actual, msg) { 26 | it(msg, () => { 27 | expect(actual !== undefined).to.equal(true); 28 | }); 29 | }; 30 | 31 | exports.test = function(testText, count, next) { 32 | describe(testText, next); 33 | }; 34 | 35 | exports.stop = function(int) {}; 36 | exports.start = function(int) {}; 37 | 38 | exports.asyncQTM = { 39 | test : function(testText, count, next) { 40 | it(testText, next); 41 | }, 42 | equal : function(actual, expected, msg) { 43 | expect(actual).to.equal(expected, msg); 44 | }, 45 | notequal : function(actual, expected, msg) { 46 | expect(actual).to.not.equal(expected, msg); 47 | }, 48 | stop : function(int) {}, 49 | ok : function(actual, msg) { 50 | expect(!!actual).to.equal(true, msg); 51 | }, 52 | deepEqual : function(actual, expected, msg) { 53 | expect(actual).to.deep.equal(expected, msg); 54 | } 55 | } -------------------------------------------------------------------------------- /src/Types/Notifications/ChangeCollector.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Notifications.ChangeCollector', $data.Notifications.ChangeCollectorBase, null, { 4 | buildData: function (entities) { 5 | var result = []; 6 | entities.forEach(function (element) { 7 | var resObj = { entityState: element.data.entityState, typeName: element.data.getType().name }; 8 | var enumerableMemDefCollection = []; 9 | 10 | switch (element.data.entityState) { 11 | case $data.EntityState.Added: 12 | enumerableMemDefCollection = element.data.getType().memberDefinitions.getPublicMappedProperties(); 13 | break; 14 | case $data.EntityState.Modified: 15 | enumerableMemDefCollection = element.data.changedProperties; 16 | break; 17 | case $data.EntityState.Deleted: 18 | enumerableMemDefCollection = element.data.getType().memberDefinitions.getKeyProperties(); 19 | break; 20 | default: 21 | break; 22 | } 23 | 24 | enumerableMemDefCollection.forEach(function (memDef) { 25 | resObj[memDef.name] = element.data[memDef.name]; 26 | }); 27 | 28 | result.push(resObj); 29 | }); 30 | 31 | return result; 32 | } 33 | }, null); 34 | 35 | export default $data 36 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/ComplexTypeExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ComplexTypeExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, selector) { 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | Guard.requireType("source", source, [$data.Expressions.EntityExpression, $data.Expressions.ComplexTypeExpression]); 14 | Guard.requireType("selector", selector, [$data.Expressions.EntityExpression, $data.Expressions.MemberInfoExpression]); 15 | this.source = source; 16 | this.selector = selector; 17 | var memDef = source.entityType.getMemberDefinition(selector.memberName); 18 | var dt = memDef.elementType || memDef.dataType; 19 | var t = Container.resolveType(dt); 20 | this.entityType = t; 21 | }, 22 | 23 | getMemberDefinition: function (name) { 24 | return this.entityType.getMemberDefinition(name); 25 | }, 26 | 27 | nodeType: { value: $data.Expressions.ExpressionType.Com } 28 | }); 29 | 30 | export default $data 31 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/eventTests.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | 3 | $data.Entity.extend('$test.A', { 4 | Id: { type: 'id', required: true, key: true, computed: true }, 5 | Value: { type: 'string' } 6 | }); 7 | 8 | $data.EntityContext.extend('$test.Context', { 9 | AAA: { type: $data.EntitySet, elementType: $test.A, beforeCreate: function(){ 10 | return function(cb, data){ 11 | //console.log('beforeCreate', arguments.callee.caller.toString()); 12 | cb(true); 13 | }; 14 | } }, 15 | test: (function(){ 16 | var self = this; 17 | return function(success, error){ 18 | self.AAA.add(new $test.A({ Value: 'aaa' })); 19 | self.AAA.add(new $test.A({ Value: 'bbb' })); 20 | 21 | self.saveChanges(function(cnt){ 22 | console.log('saved', cnt); 23 | self.executionContext.success(cnt); 24 | }); 25 | }; 26 | }).toServiceOperation().returns('int') 27 | }); 28 | 29 | var connect = require('connect'); 30 | var app = connect(); 31 | 32 | $data.Class.defineEx('$test.Service', [$test.Context, $data.ServiceBase]); 33 | 34 | app.use(connect.query()); 35 | app.use(connect.bodyParser()); 36 | app.use($data.JayService.OData.BatchProcessor.connectBodyReader); 37 | 38 | app.use("/client", connect.static(__dirname + '/client')); 39 | app.use("/eventtest", $data.JayService.createAdapter($test.Service, function(){ 40 | return new $test.Service({ name: 'mongoDB', databaseName: 'eventtest' }); 41 | })); 42 | 43 | app.listen(12345); 44 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/jaysus-test.js: -------------------------------------------------------------------------------- 1 | require('./jaysus.js'); 2 | $data.MetadataLoader.load('http://services.odata.org/Northwind/Northwind.svc', function(result) { 3 | console.log(result); 4 | }); 5 | 6 | 7 | //var fs = require('fs'); 8 | //fs.readFile('JayDataContextGenerator_OData.xslt.template','UTF-8', function() { 9 | // var xsl = arguments[1]; 10 | // //xsl = xsl.replace('%%EDM_NAMESPACE', schemaNS); 11 | // //var result = xslt.transform(xsl, doc, ['SerivceUri', "'" + serviceUri + "'"]); 12 | // console.log(xsl); 13 | //// fs.readFile('./' + transformer, 'UTF-8', function() { 14 | //// var xslt = require('node_xslt'); 15 | //// }); 16 | //}); 17 | 18 | //var fs = require('fs'); 19 | //fs.readFile('JayDataContextGenerator_OData.xslt.template', 'UTF-8', function() { 20 | // console.dir(arguments); 21 | // var r = fs.readFileSync('JayDataContextGenerator_OData.xslt.template','UTF-8'); 22 | //}); 23 | //require('datajs'); 24 | //var $data = require('jaydata'); 25 | //require('./northwind.js'); 26 | 27 | //var xslt = require('node_xslt'); 28 | // 29 | //var d = xslt.readXmlFile('./xml.xml'); 30 | //var s = xslt.readXsltFile('./xslt.xslt'); 31 | //var sss = 'abc'; 32 | //var result = xslt.transform(s,d, ['apple','aaa']); 33 | //console.log(result); 34 | // 35 | //console.log(result); 36 | 37 | // 38 | //var xslt = require('node_xslt'); 39 | // 40 | //var d = xslt.readXmlString('') 41 | //var ss = xslt.readXsltFile('./JayDataContextGenerator_OData_V2.xslt'); 42 | //var result = xslt.transform(ss, d,[]); 43 | //console.log(result); -------------------------------------------------------------------------------- /src/Types/Validation/EntityValidationBase.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Validation.ValidationError', null, null, { 4 | constructor: function (message, propertyDefinition, type) { 5 | /// 6 | /// 7 | 8 | this.Message = message; 9 | this.PropertyDefinition = propertyDefinition; 10 | this.Type = type; 11 | }, 12 | Type: { dataType: 'string' }, 13 | Message: { dataType: "string" }, 14 | PropertyDefinition: { dataType: $data.MemberDefinition } 15 | }, null); 16 | 17 | $data.Class.define('$data.Validation.EntityValidationBase', null, null, { 18 | 19 | ValidateEntity: function (entity) { 20 | /// 21 | return []; 22 | }, 23 | 24 | ValidateEntityField: function (entity, memberDefinition) { 25 | /// 26 | /// 27 | return []; 28 | }, 29 | 30 | getValidationValue: function (memberDefinition, validationName) { 31 | Guard.raise("Pure class"); 32 | }, 33 | getValidationMessage: function (memberDefinition, validationName, defaultMessage) { 34 | Guard.raise("Pure class"); 35 | } 36 | 37 | }, null); 38 | 39 | $data.Validation = $data.Validation || {}; 40 | $data.Validation.Entity = new $data.Validation.EntityValidationBase(); 41 | 42 | export default $data 43 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/SqLite/SqlExpressionMonitor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $C('$data.sqLite.SqlExpressionMonitor', $data.Expressions.ExpressionMonitor, null, { 4 | constructor: function (monitorDefinition) { 5 | this.VisitIncludeExpression = function (expression, context) { 6 | var newSourceExpression = this.Visit(expression.source, context); 7 | monitorDefinition.isMapped = true; 8 | var newSelectorExpresion = this.Visit(expression.selector, context); 9 | monitorDefinition.isMapped = false; 10 | 11 | if (newSourceExpression !== expression.source || newSelectorExpresion !== expression.selector) { 12 | return Container.createIncludeExpression(newSourceExpression, newSelectorExpresion); 13 | } 14 | return expression; 15 | }; 16 | this.VisitProjectionExpression = function (expression, context) { 17 | var source = this.Visit(expression.source, context); 18 | monitorDefinition.isMapped = true; 19 | var selector = this.Visit(expression.selector, context); 20 | monitorDefinition.isMapped = false; 21 | if (source !== expression.source || selector !== expression.selector) { 22 | var expr = Container.createProjectionExpression(source, selector, expression.params, expression.instance); 23 | expr.projectionAs = expression.projectionAs; 24 | return expr; 25 | } 26 | return expression; 27 | }; 28 | } 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /test/unit-tests/ModelBinder.spec.js: -------------------------------------------------------------------------------- 1 | // import mock$data from '../core.js'; 2 | // import $data from 'jaydata/core'; 3 | // import { expect } from 'chai'; 4 | 5 | // describe('OpenType Entity', () => { 6 | // it('should transform raw open type JSON to typed entity with dynamic fields', () => { 7 | // var type = $data.Entity.extend('OpenEntity', { 8 | // id: { type: 'int', key: true, computed: true }, 9 | // key: { type: 'string' }, 10 | // value: { type: 'string' } 11 | // }, { 12 | // openType: { value: 'external' } 13 | // }); 14 | // var mb = new $data.ModelBinder({ 15 | // storageProvider: { 16 | // fieldConverter: { 17 | // fromDb: { 18 | // '$data.Integer': (value) => { return value; }, 19 | // '$data.String': (value) => { return value; } 20 | // } 21 | // } 22 | // } 23 | // }); 24 | // var mbConfig = { 25 | // $type: $data.Array, 26 | // $item: { 27 | // $type: type, 28 | // id: 'id', 29 | // key: 'key', 30 | // value: 'value' 31 | // } 32 | // }; 33 | // var result = mb.call([{ 34 | // id: 1, 35 | // key: 'key', 36 | // value: 'value', 37 | // dyn1: 42, 38 | // dyn2: 'cats', 39 | // dyn3: { 40 | // a: 1, 41 | // b: 2 42 | // }, 43 | // dyn4: true 44 | // }], mbConfig); 45 | 46 | // expect(result[0].id).to.equal(1); 47 | // expect(result[0].key).to.equal('key'); 48 | // expect(result[0].value).to.equal('value'); 49 | // expect(result[0].external).to.deep.equal({ 50 | // dyn1: 42, 51 | // dyn2: 'cats', 52 | // dyn3: { 53 | // a: 1, 54 | // b: 2 55 | // }, 56 | // dyn4: true 57 | // }); 58 | // }); 59 | // }); -------------------------------------------------------------------------------- /src/Types/Expressions/FunctionExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.FunctionExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (name, parameters, body) { 5 | /// 6 | ///Represents a function declaration. 7 | ///Function name 8 | ///The list of function parameters 9 | /// 10 | /// 11 | ///The list of function parameters 12 | ///The function body 13 | 14 | this.parameters = parameters || []; 15 | this.name = name; 16 | this.body = body; 17 | }, 18 | 19 | toString: function (debug) { 20 | var paramStrings = this.parameters.map(function (p) { 21 | return p.toString(); 22 | }); 23 | paramStrings = paramStrings.join(","); 24 | var bodyString = (this.body ? this.body.toString(debug) : ''); 25 | return "function " + this.name + "(" + paramStrings + ") { " + bodyString + "}"; 26 | }, 27 | nodeType: { value: $data.Expressions.ExpressionType.Function, writable: true }, 28 | parameters: { value: undefined, dataType: Array, elementType: $data.Expressions.ParameterExpression }, 29 | body: { value: undefined, dataType: $data.Expressions.ExpressionNode }, 30 | type: {} 31 | }, null); 32 | 33 | export default $data 34 | -------------------------------------------------------------------------------- /src/Types/Expressions/CallExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.CallExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (expression, member, args) { 5 | ///Represents a call to an object or global method 6 | ///The expression for object that has the method 7 | ///The member descriptor 8 | this.expression = expression; 9 | this.member = member; 10 | this.args = args; 11 | }, 12 | 13 | nodeType: { 14 | value: $data.Expressions.ExpressionType.Call 15 | }, 16 | 17 | expression: { 18 | value: undefined, 19 | dataType: $data.Expressions.ExpressionNode, 20 | writable: true 21 | }, 22 | 23 | member: { 24 | value: undefined, 25 | dataType: $data.MemberDefinition, 26 | writable: true 27 | }, 28 | 29 | type: { 30 | value: undefined, 31 | writable: true 32 | }, 33 | 34 | implementation: { 35 | get: function () { 36 | return function(thisObj, method, args) { 37 | if (typeof method !== 'function') { 38 | method = thisObj[method]; 39 | } 40 | Guard.requireType("method", method, Function); 41 | return method.apply(thisObj, args); 42 | }; 43 | }, 44 | set: function (value) { Guard.raise("Property can not be set"); } 45 | }, 46 | 47 | toString: function (debug) { 48 | return this.object.toString() + "." + this.member.toString() + "(" + ")"; 49 | } 50 | 51 | }); 52 | 53 | export default $data 54 | -------------------------------------------------------------------------------- /src/Types/Expressions/Visitors/LambdaParameterProcessor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C("$data.Expressions.LambdaParameterProcessor", $data.Expressions.ParameterProcessor, null, { 4 | constructor: function (lambdaParameterTypeInfos) { 5 | /// 6 | /// 7 | var paramIndices = {}; 8 | var $idx = "name"; 9 | 10 | this.canResolve = function (paramExpression, context) { 11 | if (paramExpression.nodeType == $data.Expressions.ExpressionType.LambdaParameter) { 12 | var fnParams = paramExpression.owningFunction.parameters; 13 | 14 | if (fnParams.length == 1 && paramExpression.name == fnParams[0].name) { 15 | paramIndices[paramExpression.name] = lambdaParameterTypeInfos[0]; 16 | return true; 17 | } 18 | 19 | for (var j = 0; j < fnParams.length; j++) { 20 | if (fnParams[j].name == paramExpression.name) { 21 | paramIndices[paramExpression.name] = lambdaParameterTypeInfos[j]; 22 | return true; 23 | } 24 | } 25 | return false; 26 | } 27 | return false; 28 | }; 29 | 30 | this.resolve = function(paramExpression, context) { 31 | var lambdaParamType = paramIndices[paramExpression.name]; 32 | var result = Container.createParameterExpression(paramExpression.name, 33 | lambdaParamType, 34 | $data.Expressions.ExpressionType.LambdaParameter); 35 | result.owningFunction = paramExpression.owningFunction; 36 | return result; 37 | }; 38 | } 39 | 40 | }); 41 | 42 | export default $data 43 | -------------------------------------------------------------------------------- /src/TypeSystem/Extensions.js: -------------------------------------------------------------------------------- 1 | export var StringFunctions = { 2 | startsWith: function () { 3 | var self, str; 4 | if (arguments.length == 2) { 5 | self = arguments[0]; 6 | str = arguments[1]; 7 | } else if (arguments.length == 1 && typeof this === 'string') { 8 | self = this; 9 | str = arguments[0]; 10 | } else if (this instanceof String) { 11 | self = this.valueOf(); 12 | str = arguments[0]; 13 | } else 14 | return false; 15 | 16 | if (typeof self !== 'string') return false; 17 | return self.indexOf(str) === 0; 18 | }, 19 | endsWith: function () { 20 | var self, str; 21 | if (arguments.length == 2) { 22 | self = arguments[0]; 23 | str = arguments[1]; 24 | } else if (arguments.length == 1 && typeof this === 'string') { 25 | self = this; 26 | str = arguments[0]; 27 | } else if (this instanceof String) { 28 | self = this.valueOf(); 29 | str = arguments[0]; 30 | } else 31 | return false; 32 | 33 | if (typeof self !== 'string') return false; 34 | return self.slice(-str.length) === str; 35 | }, 36 | contains: function () { 37 | var self, str; 38 | if (arguments.length == 2) { 39 | self = arguments[0]; 40 | str = arguments[1]; 41 | } else if (arguments.length == 1 && typeof this === 'string') { 42 | self = this; 43 | str = arguments[0]; 44 | } else if (this instanceof String) { 45 | self = this.valueOf(); 46 | str = arguments[0]; 47 | } else 48 | return false; 49 | 50 | if (typeof self !== 'string') return false; 51 | return self.indexOf(str) >= 0; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/contextapiClientTests.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | var Q = require('q'); 3 | 4 | var serviceUrl = 'http://localhost:3001/newsreader.svc' 5 | 6 | require('../../JayDataModules/qDeferred.js'); 7 | require('../../JaySvcUtil/JaySvcUtil.js'); 8 | 9 | exports.testService = function(test){ 10 | test.expect(5); 11 | 12 | $data.MetadataLoader.debugMode = true; 13 | $data.MetadataLoader.load(serviceUrl, function (factory, ctxType, text) { 14 | console.log(text); 15 | var context = factory(); 16 | 17 | var cat1 = new $news.Types.Category({ Title: 'World' }); 18 | 19 | context.Categories.add(cat1); 20 | context.saveChanges(function(cnt){ 21 | test.equal(cnt, 1, 'Category not created'); 22 | test.ok(cat1.Id, 'Category ID missing'); 23 | 24 | var art1 = new $news.Types.Article({ 25 | Title: 'Article1', 26 | Lead: 'Article1 lead...', 27 | Body: 'Hello Article!', 28 | CreateDate: new Date(), 29 | Category: cat1.Id 30 | }); 31 | context.Articles.add(art1); 32 | 33 | context.saveChanges(function(cnt){ 34 | test.equal(cnt, 1, 'Article not created'); 35 | test.ok(art1.Id, 'Article ID missing'); 36 | 37 | context.Categories.attach(cat1); 38 | cat1.Articles = [art1.Id]; 39 | 40 | context.Articles.attach(art1); 41 | art1.Tags = ['hello', 'fubar']; 42 | 43 | context.saveChanges(function(cnt){ 44 | test.equal(cnt, 2, 'Category and Article not updated'); 45 | test.done(); 46 | }); 47 | }) 48 | }) 49 | }); 50 | }; 51 | -------------------------------------------------------------------------------- /src/Types/Ajax/WinJSAjaxWrapper.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | if (typeof WinJS !== 'undefined' && WinJS.xhr) { 4 | $data.ajax = $data.ajax || function (options) { 5 | $data.typeSystem.extend(options, { 6 | dataType: 'json', 7 | headers: {} 8 | }); 9 | var dataTypes = { 10 | 'json': { 11 | accept: 'application/json, text/javascript', 12 | convert: JSON.parse 13 | }, 14 | 'text': { 15 | accept: 'text/plain', 16 | convert: function (e) { return e; } 17 | }, 18 | 'html': { 19 | accept: 'text/html', 20 | convert: function (e) { return e; } 21 | }, 22 | 'xml': { 23 | accept: 'application/xml, text/xml', 24 | convert: function (e) { 25 | // TODO? 26 | return e; 27 | } 28 | } 29 | } 30 | var dataTypeContext = dataTypes[options.dataType.toLowerCase()]; 31 | 32 | options.headers.Accept = dataTypeContext.accept; 33 | 34 | var successClb = options.success || $data.defaultSuccessCallback; 35 | var errorClb = options.error || $data.defaultErrorCallback; 36 | var progressClb = options.progress; 37 | 38 | var success = function (r) { 39 | var result = dataTypeContext.convert(r.responseText); 40 | successClb(result); 41 | } 42 | var error = function (r) { 43 | var error = dataTypeContext.convert(r.responseText); 44 | errorClb(error); 45 | } 46 | var progress = progressClb; 47 | 48 | WinJS.xhr(options) 49 | .done(success, error, progress); 50 | } 51 | } 52 | 53 | export default $data 54 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/Facebook/EntitySets/FQLContext.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.storageProviders.Facebook.EntitySets.Command', null, null, { 4 | constructor: function (cfg) { 5 | this.Config = $data.typeSystem.extend({ 6 | CommandValue: "" 7 | }, cfg); 8 | }, 9 | toString: function () { 10 | return this.Config.CommandValue; 11 | }, 12 | Config: {} 13 | }, { 14 | 'to$data.Integer': function (value) { 15 | return value; 16 | }, 17 | 'to$data.Number': function (value) { 18 | return value; 19 | } 20 | }); 21 | 22 | $data.Class.define("$data.Facebook.FQLContext", $data.EntityContext, null, { 23 | constructor: function(){ 24 | var friendsQuery = this.Friends 25 | .where(function (f) { return f.uid1 == this.me; }, { me: $data.Facebook.FQLCommands.me }) 26 | .select(function (f) { return f.uid2; }); 27 | 28 | this.MyFriends = this.Users 29 | .where(function (u) { return u.uid in this.friends; }, { friends: friendsQuery }); 30 | }, 31 | Users: { 32 | dataType: $data.EntitySet, 33 | tableName: 'user', 34 | elementType: $data.Facebook.types.FbUser 35 | }, 36 | Friends: { 37 | dataType: $data.EntitySet, 38 | tableName: 'friend', 39 | elementType: $data.Facebook.types.FbFriend 40 | }, 41 | Pages: { 42 | dataType: $data.EntitySet, 43 | tableName: 'page', 44 | elementType: $data.Facebook.types.FbPage 45 | } 46 | }, null); 47 | 48 | $data.Facebook.FQLCommands = { 49 | __namespace: true, 50 | me: new $data.storageProviders.Facebook.EntitySets.Command({ CommandValue: "me()" }), 51 | now: new $data.storageProviders.Facebook.EntitySets.Command({ CommandValue: "now()" }) 52 | }; 53 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/commonTests.js: -------------------------------------------------------------------------------- 1 | exports.Test = { 2 | 'Q exists': function (test) { 3 | test.expect(2); 4 | 5 | $data.Class.define('$example.inMemoryQContext', $data.EntityContext, null, { 6 | Items: { 7 | type: $data.EntitySet, 8 | elementType: $data.Entity.extend('$example.inmemoryQEntity', { 9 | Id: { type: 'int'}, 10 | Prop1: {type: 'string'} 11 | }) 12 | } 13 | }) 14 | 15 | var context = new $example.inMemoryQContext({ name: 'InMemory' }); 16 | context.onReady(function(){ 17 | var promise = context.Items.toArray(); 18 | var q = require('q'); 19 | 20 | test.equal(q.isPromise(new $data.PromiseHandlerBase().getPromise()), false, '$data.PromiseHandlerBase returns Q promise failed!'); 21 | test.equal(q.isPromise(promise), true, '$data.PromiseHandler returns Q promise failed!' + promise); 22 | 23 | test.done(); 24 | }); 25 | }, 26 | 'Trace exists': function (test) { 27 | test.expect(4); 28 | 29 | test.equal(typeof $data.TraceBase, 'function', '$data.TraceBase exists failed'); 30 | test.notEqual(typeof $data.Trace, 'undefined', '$data.Trace exists failed'); 31 | test.equal(typeof $data.Logger, 'function', '$data.Logger exists failed'); 32 | 33 | try { 34 | $data.Trace.log('hello', 'console', 42, { prop: 24 }, [1, 2, 3]); 35 | $data.Trace = new $data.Logger(); 36 | $data.Trace.log('hello', 'console', 42, { prop: 24 }, [1, 2, 3]); 37 | test.ok(true, '$data.Trace log not throw exception'); 38 | $data.Trace = new $data.TraceBase(); 39 | } catch (e) { 40 | test.ok(false, '$data.Trace failed: ' + e); 41 | } 42 | 43 | test.done(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/SaveStrategies/single.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | var strategy = { 4 | name: 'single', 5 | condition: function (provider, convertedItems) { 6 | var requests = convertedItems.getItems(); 7 | return requests.length > 0; 8 | }, 9 | save: function (provider, convertedItems, callBack) { 10 | var that = provider; 11 | var items = convertedItems.getItems(); 12 | 13 | var doSave = function(items, index, done){ 14 | var item = items[index]; 15 | if(!item) return done() 16 | 17 | var request = item.request.build().get(); 18 | var requestData = [request, function (data, response) { 19 | if (response.statusCode >= 200 && response.statusCode < 300) { 20 | var item = convertedItems.getByResponse(response, index); 21 | if(item instanceof $data.Entity && response.statusCode != 204){ 22 | that.reload_fromResponse(item, data, response); 23 | convertedItems.setProcessed(item); 24 | } 25 | 26 | doSave(items, ++index, done); 27 | } else { 28 | done(response); 29 | } 30 | 31 | }, done]; 32 | 33 | that.appendBasicAuth(requestData[0], that.providerConfiguration.user, that.providerConfiguration.password, that.providerConfiguration.withCredentials); 34 | that.context.prepareRequest.call(that, requestData); 35 | that.oData.request.apply(that, requestData); 36 | } 37 | 38 | doSave(items, 0, function(err, result){ 39 | if(err) return callBack.error(that.parseError(err)); 40 | callBack.success(result); 41 | }) 42 | } 43 | } 44 | 45 | 46 | export { strategy } -------------------------------------------------------------------------------- /example/inheritance/inheritence.js: -------------------------------------------------------------------------------- 1 | var $data = require('../../dist/odata'); 2 | var TripPin = require('./TripPin'); 3 | 4 | TripPin.factory({ useParameterAlias: true }).onReady(function(ctx){ 5 | //ctx.GetNearestAirport(47.4979, 19.0402, console.log.bind(console)); 6 | /*ctx.getPeople('russellwhyte').getTrips(1003).getPlanItems(21).update(new ($data('Microsoft.OData.SampleService.Models.TripPin.Flight'))({ 7 | ConfirmationCode: "JH58494_updated2" 8 | }), function(r){ 9 | console.log('result:', r); 10 | });*/ 11 | //ctx.getPeople('russellwhyte').getTrips(1003).getPlanItems().read(console.log.bind(console)); 12 | /*ctx.getPeople('russellwhyte').getTrips(1003).getPlanItems().create(new ($data('Microsoft.OData.SampleService.Models.TripPin.Event'))({ 13 | "ConfirmationCode": "4372899DD", 14 | "Description": "Client Meeting", 15 | "Duration": "PT3H", 16 | "EndsAt": "2014-06-01T23:11:17.5479185-07:00", 17 | "OccursAt": { 18 | //"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation", 19 | "Address": "100 Church Street, 8th Floor, Manhattan, 10007", 20 | "BuildingInfo": "Regus Business Center", 21 | "City": { 22 | //"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", 23 | "CountryRegion": "United States", 24 | "Name": "New York City", 25 | "Region": "New York" 26 | } 27 | }, 28 | "PlanItemId": 33, 29 | "StartsAt": "2014-05-25T23:11:17.5459178-07:00" 30 | }), function(r){ 31 | console.log('result:', r); 32 | });*/ 33 | /*ctx.getPeople('russellwhyte').getTrips(1003).getPlanItems(21).delete(function(r){ 34 | console.log('result:', r); 35 | });*/ 36 | ctx.People.include('Trips.PlanItems').find('russellwhyte', function(r){ 37 | console.log(r.Trips[0].PlanItems); 38 | }); 39 | }); -------------------------------------------------------------------------------- /src/Types/StorageProviders/Facebook/FacebookConverter.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.FacebookConverter = { 4 | fromDb: { 5 | '$data.Byte': $data.Container.proxyConverter, 6 | '$data.SByte': $data.Container.proxyConverter, 7 | '$data.Decimal': $data.Container.proxyConverter, 8 | '$data.Float': $data.Container.proxyConverter, 9 | '$data.Int16': $data.Container.proxyConverter, 10 | '$data.Int64': $data.Container.proxyConverter, 11 | '$data.Number': $data.Container.proxyConverter, 12 | '$data.Integer': $data.Container.proxyConverter, 13 | '$data.String': $data.Container.proxyConverter, 14 | '$data.Date': function (value) { return new Date(typeof value === "string" ? parseInt(value) : value); }, 15 | '$data.Boolean': function (value) { return !!value }, 16 | '$data.Blob': $data.Container.proxyConverter, 17 | '$data.Array': function (value) { if (value === undefined) { return new $data.Array(); } return value; } 18 | }, 19 | toDb: { 20 | '$data.Byte': $data.Container.proxyConverter, 21 | '$data.SByte': $data.Container.proxyConverter, 22 | '$data.Decimal': $data.Container.proxyConverter, 23 | '$data.Float': $data.Container.proxyConverter, 24 | '$data.Int16': $data.Container.proxyConverter, 25 | '$data.Int64': $data.Container.proxyConverter, 26 | '$data.Number': $data.Container.proxyConverter, 27 | '$data.Integer': $data.Container.proxyConverter, 28 | '$data.String': function (value) { return "'" + value + "'"; }, 29 | '$data.Date': function (value) { return value ? value.valueOf() : null; }, 30 | '$data.Boolean': $data.Container.proxyConverter, 31 | '$data.Blob': $data.Container.proxyConverter, 32 | '$data.Array': function (value) { return '(' + value.join(', ') + ')'; } 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/contextFactoryTests.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | var fs = require('fs'); 3 | require('../../JaySvcUtil/JaySvcUtil.js'); 4 | 5 | var connect = require('connect'); 6 | var app = connect(); 7 | 8 | require('../../Types/StorageProviders/mongoDB/ClientObjectID.js'); 9 | $data.ServiceBase.extend('ObjectIDFactory', { 10 | newObjectID: (function(){ 11 | var id = new $data.storageProviders.mongoDB.mongoDBProvider.ClientObjectID().toString(); 12 | //var ret = new Buffer(id, 'ascii').toString('base64'); 13 | //console.log(new $data.mongoDBDriver.ObjectID.createFromHexString(new Buffer(ret, 'base64').toString('ascii'))); 14 | return id; 15 | }).toServiceOperation().returns('string'), 16 | resetSeed: (function(){ 17 | $data.storageProviders.mongoDB.mongoDBProvider.ClientObjectID.idSeed = 1; 18 | }).toServiceOperation() 19 | }); 20 | 21 | var storm = require('../../JayService/StormFactory.js'); 22 | fs.exists('./service.js', function(exists){ 23 | if (exists) require('./service.js'); 24 | 25 | app.use(storm.contextFactory({ 26 | apiUrl: 'http://localhost:3000/contextapi.svc', 27 | databases: [{ name: 'NewsReader' }], 28 | filename: './context.js' 29 | })); 30 | 31 | app.use(storm.serviceFactory({ 32 | services: [{ 33 | serviceName: 'newsreader', 34 | database: 'NewsReader', 35 | port: 53999 36 | }, { 37 | serviceName: 'newsreader2', 38 | extend: 'ObjectIDFactory', 39 | database: 'NewsReader', 40 | port: 53999 41 | }, { 42 | serviceName: 'ObjectIDFactory', 43 | port: 53999 44 | }], 45 | context: './context.js', 46 | filename: './service.js' 47 | })); 48 | 49 | app.use(function(req, res, next){ 50 | require('./service.js'); 51 | next(); 52 | }); 53 | 54 | app.listen(9999); 55 | }); 56 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/SqLite/SqlOrderCompiler.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | import { SqlStatementBlocks } from './SqLiteCompiler.js'; 3 | 4 | $C('$data.sqLite.SqlOrderCompiler', $data.Expressions.EntityExpressionVisitor, null, { 5 | constructor: function (provider) { 6 | this.provider = provider; 7 | }, 8 | compile: function (expression, sqlBuilder) { 9 | this.Visit(expression, sqlBuilder); 10 | }, 11 | VisitEntitySetExpression: function (expression, sqlBuilder) { 12 | /// 13 | /// 14 | 15 | var alias = sqlBuilder.getExpressionAlias(expression); 16 | sqlBuilder.addText(alias); 17 | sqlBuilder.addText(SqlStatementBlocks.nameSeparator); 18 | }, 19 | VisitOrderExpression: function (expression, sqlBuilder) { 20 | this.Visit(expression.selector, sqlBuilder); 21 | if (expression.nodeType == $data.Expressions.ExpressionType.OrderByDescending) { 22 | sqlBuilder.addText(" DESC"); 23 | } else { 24 | sqlBuilder.addText(" ASC"); 25 | } 26 | }, 27 | VisitParametricQueryExpression: function (expression, sqlBuilder) { 28 | this.Visit(expression.expression, sqlBuilder); 29 | }, 30 | VisitEntityFieldExpression: function (expression, sqlBuilder) { 31 | this.Visit(expression.source, sqlBuilder); 32 | this.Visit(expression.selector, sqlBuilder); 33 | }, 34 | VisitMemberInfoExpression: function (expression, sqlBuilder) { 35 | sqlBuilder.addText(expression.memberName); 36 | }, 37 | VisitComplexTypeExpression: function (expression, sqlBuilder) { 38 | this.Visit(expression.source, sqlBuilder); 39 | this.Visit(expression.selector, sqlBuilder); 40 | sqlBuilder.addText('__'); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /src/Types/QueryBuilder.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $C('$data.queryBuilder', null, null, { 4 | constructor: function () { 5 | this._fragments = {}; 6 | this.selectedFragment = null; 7 | this._binderConfig = {}; 8 | this.modelBinderConfig = this._binderConfig; 9 | this._binderConfigPropertyStack = []; 10 | }, 11 | selectTextPart: function (name) { 12 | if (!this._fragments[name]) { 13 | this._fragments[name] = { text: '', params: [] }; 14 | } 15 | this.selectedFragment = this._fragments[name]; 16 | }, 17 | getTextPart: function (name) { 18 | return this._fragments[name]; 19 | }, 20 | addText: function (textParticle) { 21 | this.selectedFragment.text += textParticle; 22 | }, 23 | addParameter: function (param) { 24 | this.selectedFragment.params.push(param); 25 | }, 26 | selectModelBinderProperty: function (name) { 27 | this._binderConfigPropertyStack.push(this.modelBinderConfig); 28 | if (!(name in this.modelBinderConfig)) { 29 | this.modelBinderConfig[name] = {}; 30 | } 31 | this.modelBinderConfig = this.modelBinderConfig[name]; 32 | }, 33 | popModelBinderProperty: function () { 34 | if (this._binderConfigPropertyStack.length === 0) { 35 | this.modelBinderConfig = this._binderConfig(); 36 | } else { 37 | this.modelBinderConfig = this._binderConfigPropertyStack.pop(); 38 | } 39 | }, 40 | resetModelBinderProperty: function (name) { 41 | this._binderConfigPropertyStack = []; 42 | this.modelBinderConfig = this._binderConfig; 43 | }, 44 | addKeyField: function (name) { 45 | if(!this.modelBinderConfig['$keys']){ 46 | this.modelBinderConfig['$keys'] = new Array(); 47 | } 48 | this.modelBinderConfig['$keys'].push(name); 49 | } 50 | }); 51 | 52 | export default $data 53 | -------------------------------------------------------------------------------- /test/unit-tests/NorthwindServiceTest.js: -------------------------------------------------------------------------------- 1 | import mock$data from '../core.js'; 2 | import $data from 'jaydata/core'; 3 | import oData from '../../src/Types/StorageProviders/oData' 4 | import atob from 'atob' 5 | import { expect } from 'chai'; 6 | 7 | describe('OData protocol tests', function () { 8 | this.timeout(30 * 1000) 9 | 10 | var ctx = null 11 | before((done) => { 12 | $data.initService("http://services.odata.org/V4/Northwind/Northwind.svc", {}, { 13 | success: (_ctx) => { 14 | ctx = _ctx 15 | done() 16 | }, 17 | error: (x) => { 18 | console.log(JSON.stringify(x)) 19 | done() 20 | } 21 | }) 22 | }) 23 | 24 | describe('Online northwind context test', () => { 25 | it('Entity sets', () => { 26 | expect(ctx.Categories.elementType === $data.Container.resolveType('NorthwindModel.Category')).to.equal(true) 27 | var cat = new ctx.Categories.elementType() 28 | expect(cat instanceof $data.Container.resolveType('NorthwindModel.Category')).to.equal(true) 29 | }) 30 | 31 | it('items count in entity set', (done) => { 32 | ctx.Categories.count((c) => { 33 | expect(typeof c).to.equal("number") 34 | done() 35 | }) 36 | }) 37 | 38 | 39 | 40 | it('read from entity set', (done) => { 41 | ctx.Categories.take(5).toArray((r) => { 42 | expect(r.length > 0).to.equal(true) 43 | expect(r.length <= 5).to.equal(true) 44 | done() 45 | }) 46 | }) 47 | 48 | it('cannonical url read', (done) => { 49 | ctx.Customers.getCustomers("ALFKI").getOrders(10643).read((r) => { 50 | expect(r instanceof $data.Container.resolveType('NorthwindModel.Order')).to.equal(true) 51 | done() 52 | }) 53 | }) 54 | }) 55 | 56 | }) -------------------------------------------------------------------------------- /src/Types/Query.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $C('$data.Query', null, null, 4 | { 5 | constructor: function (expression, defaultType, context) { 6 | /// 7 | /// 8 | /// 9 | 10 | this.expression = expression; 11 | this.context = context; 12 | 13 | //TODO: expressions get as JSON string?! 14 | 15 | this.expressions = expression; 16 | this.defaultType = defaultType; 17 | this.result = []; 18 | this.rawDataList = []; 19 | this.modelBinderConfig = {}; 20 | this.context = context; 21 | }, 22 | 23 | rawDataList: { dataType: "Array" }, 24 | result: { dataType: "Array" }, 25 | resultType: {}, 26 | buildResultSet: function (ctx) { 27 | var converter = new $data.ModelBinder(this.context); 28 | this.result = converter.call(this.rawDataList, this.modelBinderConfig); 29 | return; 30 | }, 31 | getEntitySets: function(){ 32 | var ret = []; 33 | var ctx = this.context; 34 | 35 | var fn = function(expression){ 36 | if (expression instanceof $data.Expressions.EntitySetExpression){ 37 | if (ctx._entitySetReferences[expression.elementType.name] && ret.indexOf(ctx._entitySetReferences[expression.elementType.name]) < 0) 38 | ret.push(ctx._entitySetReferences[expression.elementType.name]); 39 | } 40 | if (expression.source) fn(expression.source); 41 | if (expression.members) { 42 | for (var i = 0; i < expression.members.length; i++) { 43 | fn(expression.members[i].expression); 44 | } 45 | } 46 | }; 47 | 48 | fn(this.expression); 49 | 50 | return ret; 51 | } 52 | }, null); 53 | 54 | export default $data 55 | -------------------------------------------------------------------------------- /src/Types/Expressions/PropertyExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.PropertyExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (expression, member) { 5 | ///Represents accessing a property or field of an object 6 | ///The expression for the property owner object 7 | ///The member descriptor 8 | ///The expression for the property owner object 9 | ///The member descriptor 10 | 11 | this.expression = expression; 12 | this.member = member; 13 | 14 | this.type = member.dataType; 15 | }, 16 | 17 | nodeType: { 18 | value: $data.Expressions.ExpressionType.MemberAccess 19 | }, 20 | 21 | expression: { 22 | value: undefined, 23 | dataType: $data.Expressions.ExpressionNode, 24 | writable: true 25 | }, 26 | 27 | implementation: { 28 | get: function () { 29 | return function (holder, memberName) { 30 | if (holder[memberName] === undefined) 31 | Guard.raise(new Exception("Parameter '" + memberName + "' not found in context", 'Property not found!')); 32 | return holder[memberName]; 33 | }; 34 | }, 35 | set: function () { 36 | } 37 | }, 38 | 39 | member: { 40 | value: undefined, 41 | dataType: $data.MemberDefinition, 42 | writable: true 43 | }, 44 | 45 | type: { 46 | value: undefined, 47 | writable: true 48 | }, 49 | 50 | toString: function (debug) { 51 | return this.expression.toString() + "." + this.member.toString(); 52 | } 53 | 54 | }); 55 | 56 | export default $data 57 | -------------------------------------------------------------------------------- /src/Types/JayStorm.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | (function ($data) { 4 | 5 | $data.initService = function (apiKey, options) { 6 | var d = new $data.PromiseHandler(); 7 | var cfg; 8 | 9 | if (typeof apiKey === 'object') { 10 | //appId, serviceName, ownerid, isSSL, port, license, url 11 | cfg = apiKey; 12 | var protocol = cfg.isSSL || cfg.isSSL === undefined ? 'https' : 'http'; 13 | var port = cfg.port ? (':' + cfg.port) : ''; 14 | 15 | if (typeof cfg.license === 'string' && cfg.license.toLowerCase() === 'business') { 16 | if (cfg.appId && cfg.serviceName) { 17 | apiKey = protocol + '://' + cfg.appId + '.jaystack.net' + port + '/' + cfg.serviceName; 18 | } else { 19 | apiKey = cfg.url; 20 | } 21 | } else { 22 | if (cfg.ownerId && cfg.appId && cfg.serviceName) { 23 | apiKey = protocol + '://open.jaystack.net/' + cfg.ownerId + '/' + cfg.appId + '/api/' + cfg.serviceName; 24 | } else { 25 | apiKey = cfg.url; 26 | } 27 | } 28 | 29 | delete cfg.url; 30 | cfg = $data.typeSystem.extend(cfg, options); 31 | } else { 32 | cfg = options; 33 | } 34 | 35 | $data.service(apiKey, cfg).then(function (factory) { 36 | var ctx = factory(); 37 | return ctx.onReady() 38 | .then(function (context) { 39 | context.serviceFactory = factory; 40 | d.deferred.resolve(context, factory, factory.type); 41 | }).fail(function () { 42 | d.deferred.reject.apply(d.deferred, arguments); 43 | }); 44 | }).fail(function(){ 45 | d.deferred.reject.apply(d.deferred, arguments); 46 | }); 47 | 48 | return d.getPromise(); 49 | }; 50 | 51 | })($data); 52 | 53 | export default $data 54 | -------------------------------------------------------------------------------- /test/unit-tests/T2.js: -------------------------------------------------------------------------------- 1 | import mock$data from '../core.js'; 2 | import $data from 'jaydata/core'; 3 | import { EntityContextTests } from './T1.js'; 4 | import { T3 } from './T3.js'; 5 | 6 | 7 | // T4_CrossProviderTests(); 8 | 9 | EntityContextTests({ name: 'oData', oDataServiceHost: "http://localhost:9000/odata", serviceUrl: 'http://localhost:9000/odata', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, 'oDataV4'); 10 | T3({ name: 'oData', oDataServiceHost: "http://localhost:9000/odata", serviceUrl: 'http://localhost:9000/odata', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, 'oDataV4'); 11 | // T3_oDataV3({ name: 'oData', oDataServiceHost: "http://localhost:9000/odata", serviceUrl: 'http://localhost:9000/odata', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, 'oDataV4'); 12 | // if ($data.StorageProviderLoader.isSupported('sqLite')) { 13 | // EntityContextTests({ name: "sqLite", databaseName: 'T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_Web_SQL'); 14 | // T3({ name: "sqLite", databaseName: 'T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_Web_SQL'); 15 | // GeoTests({ name: "sqLite", databaseName: 'GeoTests_T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_Web_SQL'); 16 | // GuidTests({ name: "sqLite", databaseName: 'GuidTests_T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_Web_SQL'); 17 | // TypeTests({ name: 'sqLite', databaseName: 'TypeTests_T2' }, 'sqLite'); 18 | // CollectionTests({ name: 'sqLite', databaseName: 'CollectionTests_T2' }, 'sqLite'); 19 | // LocalContextTests({ name: 'sqLite', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, 'sqLite'); 20 | // } 21 | 22 | // GeoTests({ name: "InMemory", databaseName: 'GeoTests_T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_InMemory'); 23 | // GuidTests({ name: "InMemory", databaseName: 'GuidTests_T1', dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }, '_InMemory'); -------------------------------------------------------------------------------- /src/Types/StorageProviders/YQL/YQLConverter.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.YQLConverter = { 4 | fromDb: { 5 | '$data.Byte': $data.Container.proxyConverter, 6 | '$data.SByte': $data.Container.proxyConverter, 7 | '$data.Decimal': $data.Container.proxyConverter, 8 | '$data.Float': $data.Container.proxyConverter, 9 | '$data.Int16': $data.Container.proxyConverter, 10 | '$data.Int32': $data.Container.proxyConverter, 11 | '$data.Int64': $data.Container.proxyConverter, 12 | '$data.Number': function (value) { return typeof value === "number" ? value : parseInt(value); }, 13 | '$data.Integer': function (value) { return typeof value === "number" ? value : parseFloat(value); }, 14 | '$data.String': $data.Container.proxyConverter, 15 | '$data.Date': function (value) { return new Date(typeof value === "string" ? parseInt(value) : value); }, 16 | '$data.Boolean': function (value) { return !!value }, 17 | '$data.Blob': $data.Container.proxyConverter, 18 | '$data.Array': function (value) { if (value === undefined) { return new $data.Array(); } return value; } 19 | }, 20 | toDb: { 21 | '$data.Byte': $data.Container.proxyConverter, 22 | '$data.SByte': $data.Container.proxyConverter, 23 | '$data.Decimal': $data.Container.proxyConverter, 24 | '$data.Float': $data.Container.proxyConverter, 25 | '$data.Int16': $data.Container.proxyConverter, 26 | '$data.Int32': $data.Container.proxyConverter, 27 | '$data.Int64': $data.Container.proxyConverter, 28 | '$data.Number': $data.Container.proxyConverter, 29 | '$data.Integer': $data.Container.proxyConverter, 30 | '$data.String': function (value) { return "'" + value + "'"; }, 31 | '$data.Date': function (value) { return value ? value.valueOf() : null; }, 32 | '$data.Boolean': $data.Container.proxyConverter, 33 | '$data.Blob': $data.Container.proxyConverter, 34 | '$data.Array': function (value) { return '(' + value.join(', ') + ')'; } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jaydata", 3 | "version": "1.5.13", 4 | "description": "Cross-platform HTML5 data-management, JavaScript Language Query (JSLQ) support for OData, SQLite, WebSQL, IndexedDB, YQL and Facebook (packaged for Node.JS)", 5 | "keywords": [ 6 | "HTML5 data management", 7 | "JavaScript", 8 | "JavaScript Language Query", 9 | "JSLQ", 10 | "OData", 11 | "MongoDB", 12 | "SQLite", 13 | "WebSQL", 14 | "IndexedDB", 15 | "YQL", 16 | "Facebook", 17 | "cross-platform", 18 | "Node.js", 19 | "iPhone", 20 | "Android" 21 | ], 22 | "homepage": "http://jaydata.org", 23 | "author": { 24 | "name": "JayData", 25 | "url": "http://jaydata.org" 26 | }, 27 | "main": "core.js", 28 | "scripts": { 29 | "test": "echo \"Error: no test specified\" && exit 1" 30 | }, 31 | "dependencies": { 32 | "acorn": "^3.3.0", 33 | "atob": "^2.0.0", 34 | "btoa": "^1.1.2", 35 | "dot": "^1.0.3", 36 | "jaydata-odatajs": "^4.0.1", 37 | "jaydata-error-handler": "^0.0.1", 38 | "jaydata-promise-handler": "^0.1.0", 39 | "jaydata-dynamic-metadata": "^0.1.17", 40 | "odata-v4-metadata": "^0.1.3", 41 | "xmldom": "^0.1.19" 42 | }, 43 | "contributors": [ 44 | { 45 | "name": "Dániel József" 46 | }, 47 | { 48 | "name": "Hajnalka Battancs" 49 | }, 50 | { 51 | "name": "János Roden" 52 | }, 53 | { 54 | "name": "László Horváth" 55 | }, 56 | { 57 | "name": "Péter Zentai" 58 | }, 59 | { 60 | "name": "Péter Nochta" 61 | }, 62 | { 63 | "name": "Róbert Bónay" 64 | }, 65 | { 66 | "name": "Szabolcs Czinege" 67 | }, 68 | { 69 | "name": "Viktor Borza" 70 | }, 71 | { 72 | "name": "Viktor Lázár" 73 | }, 74 | { 75 | "name": "Zoltán Gyebrovszki" 76 | } 77 | ], 78 | "repository": { 79 | "type": "git", 80 | "url": "git+ssh://git@github.com/jaydata/jaydata.git" 81 | }, 82 | "license": "(MIT OR GPL-2.0)", 83 | "bugs": { 84 | "url": "https://github.com/jaydata/jaydata/issues" 85 | }, 86 | "homepage": "https://github.com/jaydata/jaydata#readme" 87 | } 88 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/ServiceOperationExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ServiceOperationExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, selector, params, cfg, boundItem) { 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | Guard.requireType("source", source, [$data.Expressions.EntityContextExpression]); 12 | Guard.requireType("selector", source, [$data.Expressions.MemberInfoExpression]); 13 | 14 | this.source = source; 15 | this.selector = selector 16 | this.params = params 17 | this.cfg = cfg; 18 | this.boundItem = boundItem; 19 | 20 | function findContext() { 21 | //TODO: use source from function parameter and return a value at the end of the function 22 | var r = source; 23 | while (r) { 24 | if (r instanceof $data.Expressions.EntityContextExpression) { 25 | return r; 26 | } 27 | r = r.source; 28 | } 29 | } 30 | 31 | var c = findContext(); 32 | switch (true) { 33 | case this.source instanceof $data.Expressions.EntityContextExpression: 34 | this.elementType = cfg.elementType ? Container.resolveType(cfg.elementType) : (this.elementType ? Container.resolveType(cfg.returnType) : null); 35 | this.storageModel = cfg.elementType ? c.instance._storageModel.getStorageModel(Container.resolveType(cfg.elementType)) : null; 36 | break; 37 | default: 38 | Guard.raise("Unknown source type for EntitySetExpression: " + this.source.getType().name); 39 | } 40 | 41 | }, 42 | nodeType: { value: $data.Expressions.ExpressionType.ServiceOperation, enumerable: true } 43 | }); 44 | 45 | export default $data 46 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/typeTests.js: -------------------------------------------------------------------------------- 1 | exports.Test = { 2 | 'Geography': { 3 | 'exists': function (test) { 4 | test.expect(4); 5 | 6 | test.equal(typeof $data.GeographyPoint, 'function', '$data.GeographyPoint exists failed'); 7 | 8 | var geo = new $data.GeographyPoint(1234.1536, -43.543); 9 | test.equal(geo instanceof $data.GeographyPoint, true, '$data.GeographyPoint instanceof failed'); 10 | test.equal(geo.longitude, 1234.1536, '$data.GeographyPoint longitude failed'); 11 | test.equal(geo.latitude, -43.543, '$data.GeographyPoint latitude failed'); 12 | 13 | test.done(); 14 | }, 15 | 'in Filter': function (test) { 16 | test.expect(1); 17 | 18 | var context = $example.Context.getContext(); 19 | var query = context.Places.filter(function (p) { return p.Location == this.loc }, { loc: new $data.GeographyPoint(44.001, -33.123) }).toTraceString(); 20 | test.equal(query.queryText, "/Places?$filter=(Location eq geography'POINT(44.001 -33.123)')", 'GeographyPoint url failed'); 21 | 22 | test.done(); 23 | } 24 | }/*, 25 | 26 | 'Geometry': { 27 | 'exists': function (test) { 28 | test.expect(4); 29 | 30 | test.equal(typeof $data.GeometryPoint, 'function', '$data.GeometryPoint exists failed'); 31 | 32 | var geo = new $data.GeometryPoint(1234.1536, -43.543); 33 | test.equal(geo instanceof $data.GeometryPoint, true, '$data.GeometryPoint instanceof failed'); 34 | test.equal(geo.x, 1234.1536, '$data.GeometryPoint x failed'); 35 | test.equal(geo.y, -43.543, '$data.GeometryPoint y failed'); 36 | 37 | test.done(); 38 | }, 39 | 'in Filter': function (test) { 40 | test.expect(1); 41 | 42 | var context = $example.Context.getContext(); 43 | var query = context.Places.filter(function (p) { return p.Location == this.loc }, { loc: new $data.GeometryPoint(44.001, -33.123) }).toTraceString(); 44 | test.equal(query.queryText, "/Places?$filter=(Location eq geometry'POINT(44.001 -33.123)')", 'GeometryPoint url failed'); 45 | 46 | test.done(); 47 | } 48 | }*/ 49 | } -------------------------------------------------------------------------------- /src/Types/DbClient/OpenDatabaseClient/OpenDbConnection.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.openDatabaseClient.OpenDbConnection', $data.dbClient.DbConnection, null, 4 | { 5 | constructor: function (params) { 6 | this.connectionParams = params; 7 | }, 8 | isOpen: function () { 9 | return this.database !== null && this.database !== undefined && this.transaction !== null && this.transaction !== undefined; 10 | }, 11 | open: function (callBack, tran, isWrite) { 12 | if (isWrite === undefined) 13 | isWrite = true; 14 | 15 | callBack.oncomplete = callBack.oncomplete || function () { }; 16 | if (tran) { 17 | callBack.success(tran.transaction); 18 | } else if (this.database) { 19 | if (isWrite) { 20 | this.database.transaction(function (tran) { callBack.success(tran); }, callBack.error, callBack.oncomplete); 21 | } else { 22 | this.database.readTransaction(function (tran) { callBack.success(tran); }, callBack.error, callBack.oncomplete); 23 | } 24 | } else { 25 | var p = this.connectionParams; 26 | var con = this; 27 | this.database = openDatabase(p.fileName, p.version, p.displayName, p.maxSize); 28 | if (!this.database.readTransaction) { 29 | this.database.readTransaction = function () { 30 | con.database.transaction.apply(con.database, arguments); 31 | } 32 | } 33 | 34 | if (isWrite) { 35 | this.database.transaction(function (tran) { callBack.success(tran); }, callBack.error, callBack.oncomplete); 36 | } else { 37 | this.database.readTransaction(function (tran) { callBack.success(tran); }, callBack.error, callBack.oncomplete); 38 | } 39 | } 40 | }, 41 | close: function () { 42 | this.transaction = undefined; 43 | this.database = undefined; 44 | }, 45 | createCommand: function (queryStr, params) { 46 | var cmd = new $data.dbClient.openDatabaseClient.OpenDbCommand(this, queryStr, params); 47 | return cmd; 48 | } 49 | }, null); 50 | -------------------------------------------------------------------------------- /src/Types/index.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem/index.js'; 2 | import expressions from './Expressions/index.js'; 3 | 4 | import EntityValidationBase from './Validation/EntityValidationBase.js'; 5 | import EntityValidation from './Validation/EntityValidation.js'; 6 | import ChangeDistributorBase from './Notifications/ChangeDistributorBase.js'; 7 | import ChangeCollectorBase from './Notifications/ChangeCollectorBase.js'; 8 | import ChangeDistributor from './Notifications/ChangeDistributor.js'; 9 | import ChangeCollector from './Notifications/ChangeCollector.js'; 10 | import Transaction from './Transaction.js'; 11 | import Access from './Access.js'; 12 | //import Promise from './Promise.js'; 13 | import Entity from './Entity.js'; 14 | import Enum from './Enum.js'; 15 | import RelatedEntityProxy from './RelatedEntityProxy.js'; 16 | import EntityContext from './EntityContext.js'; 17 | import QueryProvider from './QueryProvider.js'; 18 | import ModelBinder from './ModelBinder.js'; 19 | import QueryBuilder from './QueryBuilder.js'; 20 | import Query from './Query.js'; 21 | import Queryable from './Queryable.js'; 22 | import EntitySet from './EntitySet.js'; 23 | import EntityState from './EntityState.js'; 24 | import EntityAttachModes from './EntityAttachModes.js'; 25 | import EntityStateManager from './EntityStateManager.js'; 26 | import ItemStore from './ItemStore.js'; 27 | import StorageProviderLoader from './StorageProviderLoader.js'; 28 | import StorageProviderBase from './StorageProviderBase.js'; 29 | import ServiceOperation from './ServiceOperation.js'; 30 | import EntityWrapper from './EntityWrapper.js'; 31 | import jQueryAjaxWrapper from './Ajax/jQueryAjaxWrapper.js'; 32 | import WinJSAjaxWrapper from './Ajax/WinJSAjaxWrapper.js'; 33 | import ExtJSAjaxWrapper from './Ajax/ExtJSAjaxWrapper.js'; 34 | import AjaxStub from './Ajax/AjaxStub.js'; 35 | import modelBinderConfigCompiler from './StorageProviders/modelBinderConfigCompiler.js'; 36 | import AuthenticationBase from './Authentication/AuthenticationBase.js'; 37 | import Anonymous from './Authentication/Anonymous.js'; 38 | import FacebookAuth from './Authentication/FacebookAuth.js'; 39 | import BasicAuth from './Authentication/BasicAuth.js'; 40 | //import JaySvcUtil from '../JaySvcUtil/JaySvcUtil.js'; 41 | //import deferred from '../JayDataModules/deferred.js'; 42 | //import JayStorm from './JayStorm.js'; 43 | 44 | 45 | 46 | export default $data 47 | -------------------------------------------------------------------------------- /src/Types/Expressions/ASTParser.js: -------------------------------------------------------------------------------- 1 | $data.ASTNode = function() { 2 | ///represents the kind of the AST node 3 | /// 4 | /// 5 | ///Contains the first part of the expression 6 | /// 7 | /// 8 | } 9 | 10 | $data.FunctionASTNode = function() { 11 | ///The name of the function 12 | ///Contains the function parameters 13 | ///The function body 14 | } 15 | $data.FunctionASTNode.prototype = new $data.ASTNode(); 16 | 17 | $data.ParameterASTNode = function() { 18 | ///The name of the parameter 19 | /// 20 | /// 21 | } 22 | $data.MemberAccessASTNode = function() { 23 | ///The name of the parameter 24 | /// 25 | /// 26 | /// 27 | } 28 | $data.MemberAccessASTNode.prototype = new $data.ASTNode(); 29 | 30 | $data.ConstantASTNode = function() { 31 | ///The datatype of the constant value 32 | ///The constant value 33 | } 34 | 35 | 36 | $data.ASTParserResult = function(result, tree, errors) { 37 | /// 38 | this.success = (tree != ''); 39 | this.result = result; 40 | this.tree = tree; 41 | this.errors = errors; 42 | } 43 | 44 | $data.ASTParser = function() { 45 | } 46 | 47 | $data.ASTParser.parseCode = function (code) { 48 | var codeStr; 49 | 50 | if (!code || (codeStr = code.toString()) === '') { 51 | return new $data.ASTParserResult(false, null, null); 52 | } 53 | 54 | if (typeof JAYLINT === 'undefined') { 55 | Guard.raise(new Exception('JAYLINT is required', 'Not Found!')); 56 | } 57 | 58 | var jsLint = JAYLINT(codeStr); 59 | var result = new $data.ASTParserResult(jsLint, JAYLINT.tree, JAYLINT.errors); 60 | 61 | return result; 62 | }; 63 | -------------------------------------------------------------------------------- /src/Types/Promise.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../TypeSystem/index.js'; 2 | 3 | $data.Class.define('$data.Promise', null, null, { 4 | always: function () { Guard.raise(new Exception('$data.Promise.always', 'Not implemented!')); }, 5 | done: function () { Guard.raise(new Exception('$data.Promise.done', 'Not implemented!')); }, 6 | fail: function () { Guard.raise(new Exception('$data.Promise.fail', 'Not implemented!')); }, 7 | isRejected: function () { Guard.raise(new Exception('$data.Promise.isRejected', 'Not implemented!')); }, 8 | isResolved: function () { Guard.raise(new Exception('$data.Promise.isResolved', 'Not implemented!')); }, 9 | //notify: function () { Guard.raise(new Exception('$data.Promise.notify', 'Not implemented!')); }, 10 | //notifyWith: function () { Guard.raise(new Exception('$data.Promise.notifyWith', 'Not implemented!')); }, 11 | pipe: function () { Guard.raise(new Exception('$data.Promise.pipe', 'Not implemented!')); }, 12 | progress: function () { Guard.raise(new Exception('$data.Promise.progress', 'Not implemented!')); }, 13 | promise: function () { Guard.raise(new Exception('$data.Promise.promise', 'Not implemented!')); }, 14 | //reject: function () { Guard.raise(new Exception('$data.Promise.reject', 'Not implemented!')); }, 15 | //rejectWith: function () { Guard.raise(new Exception('$data.Promise.rejectWith', 'Not implemented!')); }, 16 | //resolve: function () { Guard.raise(new Exception('$data.Promise.resolve', 'Not implemented!')); }, 17 | //resolveWith: function () { Guard.raise(new Exception('$data.Promise.resolveWith', 'Not implemented!')); }, 18 | state: function () { Guard.raise(new Exception('$data.Promise.state', 'Not implemented!')); }, 19 | then: function () { Guard.raise(new Exception('$data.Promise.then', 'Not implemented!')); } 20 | }, null); 21 | 22 | $data.Class.define('$data.PromiseHandlerBase', null, null, { 23 | constructor: function () { }, 24 | createCallback: function (callBack) { 25 | callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack); 26 | 27 | return { 28 | success: callBack.success, 29 | error: callBack.error, 30 | notify: callBack.notify 31 | }; 32 | }, 33 | getPromise: function () { 34 | return new $data.Promise(); 35 | } 36 | }, null); 37 | 38 | $data.PromiseHandler = $data.PromiseHandlerBase; 39 | 40 | export default $data 41 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/ExpressionMonitor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.ExpressionMonitor', $data.Expressions.EntityExpressionVisitor, null, { 4 | constructor: function (monitorDefinition) { 5 | this.Visit = function (expression, context) { 6 | 7 | var result = expression; 8 | var methodName; 9 | if (this.canVisit(expression)) { 10 | 11 | //if (monitorDefinition.FilterExpressionNode) { 12 | 13 | //}; 14 | 15 | if (monitorDefinition.VisitExpressionNode) { 16 | monitorDefinition.VisitExpressionNode.apply(monitorDefinition, arguments); 17 | }; 18 | 19 | methodName = "Visit" + expression.getType().name; 20 | if (methodName in monitorDefinition) { 21 | result = monitorDefinition[methodName].apply(monitorDefinition, arguments); 22 | } 23 | } 24 | 25 | 26 | //apply is about 3-4 times faster then call on webkit 27 | 28 | var args = arguments; 29 | if (result !== expression) args = [result, context]; 30 | result = $data.Expressions.EntityExpressionVisitor.prototype.Visit.apply(this, args); 31 | 32 | args = [result, context]; 33 | 34 | if (this.canVisit(result)) { 35 | var expressionTypeName = result.getType().name; 36 | if (monitorDefinition.MonitorExpressionNode) { 37 | monitorDefinition.MonitorExpressionNode.apply(monitorDefinition, args); 38 | } 39 | methodName = "Monitor" + expressionTypeName; 40 | if (methodName in monitorDefinition) { 41 | monitorDefinition[methodName].apply(monitorDefinition, args); 42 | } 43 | 44 | if (monitorDefinition.MutateExpressionNode) { 45 | monitorDefinition.MutateExpressionNode.apply(monitorDefinition, args); 46 | } 47 | methodName = "Mutate" + expressionTypeName; 48 | if (methodName in monitorDefinition) { 49 | result = monitorDefinition[methodName].apply(monitorDefinition, args); 50 | } 51 | 52 | } 53 | return result; 54 | }; 55 | } 56 | }); 57 | 58 | export default $data 59 | -------------------------------------------------------------------------------- /example/inheritance/basetype.js: -------------------------------------------------------------------------------- 1 | var $data = require('../../dist/odata'); 2 | var NewsReader = require('./basetype.context'); 3 | 4 | NewsReader.factory({ useParameterAlias: true }).onReady(function(ctx){ 5 | ctx.GenericArticles.filter(function(it){ return it.PublishedBy.Name == "InheritanceUser9"; }).orderBy(function(it){ return it.PublishedBy.Name; }).map(function(it){ return it.CreatedBy; }).toArray($data.fdebug); 6 | /*ctx.GenericArticles.include('CreatedBy').include('PublishedBy').include('PublishedBy.CreatedArticles').toArray({ 7 | success: function(r){ 8 | console.log(r.map(function(it){ 9 | it.initData["@odata.type"] = it.getType().fullName; 10 | if (it.CreatedBy){ 11 | it.initData.CreatedBy.initData["@odata.type"] = it.initData.CreatedBy.getType().fullName; 12 | it.initData.CreatedBy = it.initData.CreatedBy.initData; 13 | } 14 | if (it.PublishedBy){ 15 | it.initData.PublishedBy.initData["@odata.type"] = it.initData.PublishedBy.getType().fullName; 16 | it.initData.PublishedBy = it.initData.PublishedBy.initData; 17 | } 18 | if (it.PublishedBy && it.PublishedBy.CreatedArticles.length > 0) it.initData.CreatedArticles = it.PublishedBy.CreatedArticles[0]; 19 | return it.initData; 20 | })); 21 | }, 22 | error: function(err){ 23 | console.log(err); 24 | console.log('*********************', err.data[0].request); 25 | } 26 | }); 27 | var t1 = new ($data('Inheritance.InternalArticle'))({ 28 | Id: Math.floor(Math.random() * 1000) + 1000, 29 | InternalTitle: 'internal2', 30 | InternalBody: 'internal2', 31 | ValidTill: new Date('2016-12-31') 32 | }); 33 | var t2 = new ($data('Inheritance.PublicArticle'))({ 34 | Id: Math.floor(Math.random() * 1000) + 1000, 35 | Lead: 'lead', 36 | PublishDate: new Date() 37 | }); 38 | ctx.GenericArticles.add(t1); 39 | ctx.GenericArticles.add(t2); 40 | ctx.saveChanges({ 41 | success: function(c){ 42 | console.log(c); 43 | ctx.GenericArticles.toArray(console.log.bind(console)); 44 | }, 45 | error: function(err){ 46 | console.log(err); 47 | console.log('*********************', err.data[0].request); 48 | } 49 | });*/ 50 | }); -------------------------------------------------------------------------------- /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Types/Authentication/BasicAuth.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../TypeSystem/index.js'; 2 | 3 | $data.Class.define("$data.Authentication.BasicAuth.BasicAuth", $data.Authentication.AuthenticationBase, null, { 4 | constructor: function (cfg) { 5 | this.configuration = $data.typeSystem.extend({ 6 | Username: '', 7 | Password: '' 8 | }, cfg); 9 | }, 10 | Login: function (callbacks) { 11 | if (callbacks && typeof callbacks.pending == "function") 12 | callbacks.pending(); 13 | }, 14 | Logout: function () { 15 | }, 16 | CreateRequest: function (cfg) { 17 | if (!cfg) 18 | return; 19 | var _this = this; 20 | 21 | var origBeforeSend = cfg.beforeSend; 22 | cfg.beforeSend = function (xhr) { 23 | xhr.setRequestHeader("Authorization", "Basic " + _this.__encodeBase64(_this.configuration.Username + ":" + _this.configuration.Password)); 24 | 25 | if(typeof origBeforeSend == "function") 26 | origBeforeSend(xhr); 27 | }; 28 | 29 | $data.ajax(cfg); 30 | }, 31 | __encodeBase64: function (val) { 32 | var b64array = "ABCDEFGHIJKLMNOP" + 33 | "QRSTUVWXYZabcdef" + 34 | "ghijklmnopqrstuv" + 35 | "wxyz0123456789+/" + 36 | "="; 37 | 38 | input = val; 39 | var base64 = ""; 40 | var hex = ""; 41 | var chr1, chr2, chr3 = ""; 42 | var enc1, enc2, enc3, enc4 = ""; 43 | var i = 0; 44 | 45 | do { 46 | chr1 = input.charCodeAt(i++); 47 | chr2 = input.charCodeAt(i++); 48 | chr3 = input.charCodeAt(i++); 49 | 50 | enc1 = chr1 >> 2; 51 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 52 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 53 | enc4 = chr3 & 63; 54 | 55 | if (isNaN(chr2)) { 56 | enc3 = enc4 = 64; 57 | } else if (isNaN(chr3)) { 58 | enc4 = 64; 59 | } 60 | 61 | base64 = base64 + 62 | b64array.charAt(enc1) + 63 | b64array.charAt(enc2) + 64 | b64array.charAt(enc3) + 65 | b64array.charAt(enc4); 66 | chr1 = chr2 = chr3 = ""; 67 | enc1 = enc2 = enc3 = enc4 = ""; 68 | } while (i < input.length); 69 | 70 | return base64; 71 | } 72 | }, null); 73 | 74 | export default $data 75 | -------------------------------------------------------------------------------- /test/qunit/scripts/ValidatonPluginTest.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | module("ValidationTests"); 3 | 4 | 5 | $data.Class.define("UserModel", $data.Entity, null, { 6 | Id: { dataType: "int", key: true, computed: true }, 7 | UserName: { dataType: "string", required: true, minLength: 6, maxLength: 15 }, 8 | Bio: { dataType: "string", required: true }, 9 | Avatar: { dataType: "blob" }, 10 | Zip: { dataType: "int", minValue: { value: 1000, message: 'min value 1000' }, maxValue: 9999 }, 11 | Birthday: { dataType: "date", minValue: new Date(Date.parse("March 21, 2012")), errorMessage: "min date message" }, 12 | Regex: { dataType: "string", regex: '\\wb\\w', errorMessage: "regex error" }, 13 | CustomValid: { dataType: "string", required: { value: true, message: 'required' }, customValidator: function (v) { return !v || v.length == 3 }, errorMessage: "custom error" }, 14 | }, null); 15 | 16 | test("Validation plugin teszt", 18, function () { 17 | var user = new UserModel(); 18 | equal(typeof user.toJQueryValidate, 'function', 'model creator for validate'); 19 | 20 | var vModel = user.toJQueryValidate(); 21 | 22 | equal(typeof vModel.rules, 'object', 'rule set'); 23 | equal(typeof vModel.messages, 'object', 'message set'); 24 | 25 | equal(typeof vModel.rules.UserName, 'object', 'UserName rule set'); 26 | equal(vModel.rules.UserName.required, true, 'UserName is required'); 27 | equal(vModel.messages.UserName, undefined, 'UserName messages'); 28 | 29 | equal(vModel.rules.UserName.minlength, 6, 'UserName minlength'); 30 | 31 | equal(vModel.rules.UserName.maxlength, 15, 'UserName maxlength'); 32 | 33 | equal(vModel.rules.Zip.min, 1000, 'Zip min'); 34 | equal(vModel.messages.Zip.min, 'min value 1000', 'Zip min message'); 35 | 36 | equal(vModel.rules.Zip.max, 9999, 'Zip max'); 37 | equal(vModel.messages.Zip.max, undefined, 'Zip max message'); 38 | 39 | equal(vModel.rules.Birthday.Birthday_min, true, 'Birthday min'); 40 | 41 | equal(vModel.rules.Regex.Regex_regex, true, 'Regex regex'); 42 | 43 | equal(vModel.rules.CustomValid.required, true, 'CustomValid required'); 44 | equal(vModel.messages.CustomValid.required, 'required', 'CustomValid required message'); 45 | 46 | equal(vModel.rules.CustomValid.CustomValid_customValidator, true, 'CustomValid min'); 47 | equal(vModel.messages.CustomValid.CustomValid_customValidator, undefined, 'CustomValid customValidator message set by validator func'); 48 | }); 49 | 50 | }); -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/oDataRequestActivities.js: -------------------------------------------------------------------------------- 1 | export class RequestBuilder { 2 | constructor(context, request){ 3 | this._context = context; 4 | this._request = request || {}; 5 | this._activities = []; 6 | } 7 | get(){ 8 | return this._request; 9 | } 10 | add(...activities){ 11 | this._activities.push(...activities); 12 | return this; 13 | } 14 | build(){ 15 | this._request.headers = this._request.headers || {} 16 | this._request.data = this._request.data || {} 17 | 18 | this._activities.forEach((a) => a instanceof RequestActivity ? 19 | a.implementation(this._request, this._context) : 20 | a(this._request, this._context)) 21 | 22 | this._activities = []; 23 | return this; 24 | } 25 | } 26 | 27 | export class RequestActivity { 28 | constructor(){} 29 | implementation(request, provider){ } 30 | } 31 | 32 | export class SetRequestActivity extends RequestActivity { 33 | constructor(key, value){ 34 | super() 35 | this.key = key; 36 | this.value = value; 37 | } 38 | implementation(request, provider){ } 39 | } 40 | 41 | export class SetRequestProperty extends SetRequestActivity { 42 | implementation(request, provider){ 43 | request[this.key] = this.value 44 | } 45 | } 46 | 47 | export class SetDataProperty extends SetRequestActivity { 48 | implementation(request, provider){ 49 | request.data[this.key] = this.value 50 | } 51 | } 52 | 53 | export class SetHeaderProperty extends SetRequestActivity { 54 | implementation(request, provider){ 55 | request.headers[this.key] = this.value 56 | } 57 | } 58 | 59 | export class SetUrl extends SetRequestProperty { 60 | constructor(url){ 61 | super('requestUri', url) 62 | } 63 | } 64 | 65 | export class AppendUrl extends SetUrl { 66 | implementation(request, provider){ 67 | request[this.key] == request[this.key] || "" 68 | request[this.key] += this.value 69 | } 70 | } 71 | 72 | export class SetMethod extends SetRequestProperty { 73 | constructor(method){ 74 | super('method', method) 75 | } 76 | } 77 | 78 | export class SetProperty extends SetDataProperty { 79 | } 80 | 81 | export class SetNavigationProperty extends SetDataProperty { 82 | implementation(request, provider){ 83 | request.data[this.key] = this.value 84 | } 85 | } 86 | 87 | export class ClearRequestData extends RequestActivity { 88 | implementation(request, provider){ 89 | delete request.data; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Types/DbClient/JayStorageClient/JayStorageCommand.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.jayStorageClient.JayStorageCommand', $data.dbClient.DbCommand, null, 4 | { 5 | constructor: function (con, queryStr, params) { 6 | this.query = queryStr; 7 | this.connection = con; 8 | this.parameters = params; 9 | }, 10 | executeNonQuery: function (callback) { 11 | // TODO 12 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 13 | this.exec(this.query, this.parameters, callback.success, callback.error); 14 | }, 15 | executeQuery: function (callback) { 16 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 17 | this.exec(this.query, this.parameters, callback.success, callback.error); 18 | }, 19 | exec: function (query, parameters, callback, errorhandler) { 20 | if (parameters == null || parameters == undefined) { 21 | parameters = {}; 22 | } 23 | var single = false; 24 | if (!(query instanceof Array)) { 25 | single = true; 26 | query = [query]; 27 | parameters = [parameters]; 28 | } 29 | 30 | var provider = this; 31 | var results = []; 32 | var remainingCommands = query.length; 33 | var decClb = function () { 34 | if (--remainingCommands == 0) { 35 | callback(single ? results[0] : results); 36 | } 37 | }; 38 | 39 | query.forEach(function(q, i){ 40 | if (q){ 41 | $data.ajax({ 42 | url: 'http' + (this.connection.connectionParams.storage.ssl ? 's' : '') + '://' + this.connection.connectionParams.storage.src.replace('http://', '').replace('https://', '') + '?db=' + this.connection.connectionParams.storage.key, 43 | type: 'POST', 44 | headers: { 45 | 'X-PINGOTHER': 'pingpong' 46 | }, 47 | data: { query: q, parameters: parameters[i] }, 48 | dataType: 'json', 49 | contentType: 'application/json;charset=UTF-8', 50 | success: function(data){ 51 | if (data && data.error){ 52 | console.log('JayStorage error', data.error); 53 | errorhandler(data.error); 54 | return; 55 | } 56 | if (this.lastID){ 57 | results[i] = { insertId: this.lastID, rows: (data || { rows: [] }).rows }; 58 | }else results[i] = { rows: (data || { rows: [] }).rows }; 59 | decClb(); 60 | } 61 | }); 62 | }else{ 63 | results[i] = null; 64 | decClb(); 65 | } 66 | }, this); 67 | } 68 | }, null); 69 | -------------------------------------------------------------------------------- /src/Types/Expressions/EntityExpressions/EntityExpression.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C('$data.Expressions.EntityExpression', $data.Expressions.ExpressionNode, null, { 4 | constructor: function (source, selector) { 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | Guard.requireValue("source", source); 18 | Guard.requireValue("selector", selector); 19 | if (!(source instanceof $data.Expressions.EntitySetExpression) && !(source instanceof $data.Expressions.ServiceOperationExpression)) { 20 | Guard.raise("Only EntitySetExpressions can be the source for an EntityExpression"); 21 | } 22 | 23 | this.source = source; 24 | this.selector = selector; 25 | 26 | this.entityType = this.source.elementType; 27 | this.storageModel = this.source.storageModel; 28 | 29 | Guard.requireValue("entityType", this.entityType); 30 | Guard.requireValue("storageModel", this.storageModel); 31 | 32 | }, 33 | 34 | getMemberDefinition: function (name) { 35 | var memdef = this.entityType.getMemberDefinition(name); 36 | if (!memdef) { 37 | var findMember = function(type){ 38 | if (type.inheritedTo){ 39 | for (var i = 0; i < type.inheritedTo.length; i++){ 40 | memdef = type.inheritedTo[i].getMemberDefinition(name); 41 | if (!memdef) findMember(type.inheritedTo[i]); 42 | else break; 43 | } 44 | } 45 | }; 46 | findMember(this.entityType); 47 | if (!memdef){ 48 | Guard.raise(new Exception("Unknown member " + name + " on type " + this.entityType.name, "MemberNotFound")); 49 | } 50 | }; 51 | memdef.storageModel = this.storageModel; 52 | return memdef; 53 | }, 54 | 55 | nodeType: { value: $data.Expressions.ExpressionType.Entity } 56 | }); 57 | 58 | export default $data 59 | -------------------------------------------------------------------------------- /src/Types/DbClient/SqLiteNjClient/SqLiteNjCommand.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.sqLiteNJClient.SqLiteNjCommand', $data.dbClient.DbCommand, null, 4 | { 5 | constructor: function (con, queryStr, params) { 6 | this.query = queryStr; 7 | this.connection = con; 8 | this.parameters = params; 9 | }, 10 | executeNonQuery: function (callback) { 11 | // TODO 12 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 13 | this.exec(this.query, this.parameters, callback.success, callback.error); 14 | }, 15 | executeQuery: function (callback) { 16 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 17 | this.exec(this.query, this.parameters, callback.success, callback.error); 18 | }, 19 | exec: function (query, parameters, callback, errorhandler) { 20 | if (!this.connection.isOpen()) { 21 | this.connection.open(); 22 | } 23 | if (parameters == null || parameters == undefined) { 24 | parameters = {}; 25 | } 26 | var single = false; 27 | if (!(query instanceof Array)) { 28 | single = true; 29 | query = [query]; 30 | parameters = [parameters]; 31 | } 32 | 33 | var provider = this; 34 | var results = []; 35 | var remainingCommands = 0; 36 | var decClb = function () { 37 | if (--remainingCommands == 0) { 38 | provider.connection.database.exec('COMMIT'); 39 | callback(single ? results[0] : results); 40 | } 41 | }; 42 | provider.connection.database.exec('BEGIN'); 43 | query.forEach(function (q, i) { 44 | remainingCommands++; 45 | if (q) { 46 | var sqlClb = function (error, rows) { 47 | if (error != null) { 48 | errorhandler(error); 49 | return; 50 | } 51 | if (this.lastID) { 52 | results[i] = { insertId: this.lastID, rows: [] }; 53 | } else { 54 | results[i] = { rows: rows }; 55 | } 56 | decClb(); 57 | }; 58 | 59 | var stmt = provider.connection.database.prepare(q, parameters[i]); 60 | if (q.indexOf('SELECT') == 0) { 61 | stmt.all(sqlClb); 62 | } else { 63 | stmt.run(sqlClb); 64 | } 65 | stmt.finalize(); 66 | } else { 67 | results[i] = null; 68 | decClb(); 69 | } 70 | }, this); 71 | } 72 | }, null); 73 | -------------------------------------------------------------------------------- /src/TypeSystem/Types/Guid.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | $data.Guid = function Guid(value) { 4 | /// 5 | 6 | if (value === undefined || (typeof value === 'string' && /^[a-zA-z0-9]{8}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{4}-[a-zA-z0-9]{12}$/.test(value))) { 7 | this.value = value || '00000000-0000-0000-0000-000000000000'; 8 | } else { 9 | throw Guard.raise(new Exception('TypeError: ', 'value not convertable to $data.Guid', value)); 10 | } 11 | }; 12 | $data.Container.registerType(['$data.Guid', 'Guid', 'guid'], $data.Guid); 13 | $data.Container.registerConverter('$data.Guid', { 14 | '$data.String': function (value) { 15 | return value ? $data.parseGuid(value).toString() : value; 16 | }, 17 | '$data.Guid': function (value) { 18 | return value ? value.toString() : value; 19 | } 20 | }, { 21 | '$data.String': function (value) { 22 | return value ? value.toString() : value; 23 | } 24 | }); 25 | 26 | 27 | $data.Guid.prototype.toJSON = function () { 28 | return this.value; 29 | }; 30 | 31 | $data.Guid.prototype.valueOf = function () { 32 | return this.value; 33 | }; 34 | 35 | $data.Guid.prototype.toString = function () { 36 | return this.value; 37 | }; 38 | 39 | $data.Guid.NewGuid = function () { 40 | return $data.createGuid(); 41 | }; 42 | 43 | $data.parseGuid = function (guid) { 44 | return new $data.Guid(guid); 45 | }; 46 | 47 | (function () { 48 | /*! 49 | Math.uuid.js (v1.4) 50 | http://www.broofa.com 51 | mailto:robert@broofa.com 52 | 53 | Copyright (c) 2010 Robert Kieffer 54 | Dual licensed under the MIT and GPL licenses. 55 | */ 56 | 57 | var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 58 | 59 | $data.createGuid = function (guidString) { 60 | if (guidString) { 61 | return new $data.Guid(guidString); 62 | }; 63 | 64 | var len; 65 | var chars = CHARS, uuid = [], i; 66 | var radix = chars.length; 67 | 68 | if (len) { 69 | // Compact form 70 | for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; 71 | } else { 72 | // rfc4122, version 4 form 73 | var r; 74 | 75 | // rfc4122 requires these characters 76 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; 77 | uuid[14] = '4'; 78 | 79 | // Fill in random data. At i==19 set the high bits of clock sequence as 80 | // per rfc4122, sec. 4.1.5 81 | for (i = 0; i < 36; i++) { 82 | if (!uuid[i]) { 83 | r = 0 | Math.random() * 16; 84 | uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; 85 | } 86 | } 87 | } 88 | 89 | return $data.parseGuid(uuid.join('')); 90 | }; 91 | })(); 92 | 93 | export default $data 94 | -------------------------------------------------------------------------------- /test/qunit/scripts/dataDistributeTest.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | if (!$data.StorageProviderLoader.isSupported('sqLite')) return; 3 | 4 | module("dataDistributeTest"); 5 | 6 | test("simpleFieldDataTypeTest", 8, function () { 7 | var distributor = $data.Class.define('distributor', $data.Notifications.ChangeDistributor, null, { 8 | distributeData: function (data) { 9 | ok(true, 'true'); 10 | equal(data.some(function (e) { return e.entityState == $data.EntityState.Added }), true, "exists new element"); 11 | 12 | if(data.every(function (e) { return e.entityState == $data.EntityState.Added })){ 13 | equal(data.length, 2, 'changed Added data count'); 14 | } 15 | else 16 | { 17 | equal(data.length, 3, 'changed data count'); 18 | } 19 | } 20 | }, null); 21 | 22 | var collector = $data.Class.define('collector', $data.Notifications.ChangeCollector, null, { 23 | Distrbutor: { enumerable: false, dataType: $data.ChangeDistributorBase, storeOnObject: true, value: new distributor() } 24 | }, null); 25 | 26 | var context = $data.Class.define("ProviderTestContext", $data.EntityContext, null, { 27 | Table1Items: { 28 | dataType: $data.EntitySet, elementType: $data.Class.define("TestEntity", $data.Entity, null, { 29 | fld1: { dataType: 'integer', key: true, computed: true }, 30 | fld2: { dataType: 'string' }, 31 | fld3: { dataType: 'string' }, 32 | fld4: { dataType: 'string' } 33 | }, null) 34 | }, 35 | ChangeCollector: { enumerable: false, dataType: $data.Notifications.ChangeCollectorBase, storeOnObject: true, value: new collector() } 36 | }, null); 37 | 38 | stop(3); 39 | var c = new context({ databaseName: "sqLiteDataDistributeTest", name: "sqLite", dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables }); 40 | c.onReady(function (db) { 41 | db.Table1Items.add(new db.Table1Items.createNew({ fld2: 'prop2', fld3: 'prop3', fld4: 'prop4' })); 42 | db.Table1Items.add(new db.Table1Items.createNew({ fld2: 'prop22', fld3: 'prop23' })); 43 | 44 | db.saveChanges(function () { 45 | var d = db.Table1Items.entityContext.ChangeCollector.Distrbutor.Elements; 46 | start(); 47 | 48 | db.Table1Items.toArray(function (item) { 49 | start(); 50 | equal(item.length, 2, "new items added"); 51 | 52 | db.Table1Items.attach(item[0]); 53 | item[0].fld3 = "updateFld"; 54 | 55 | db.Table1Items.attach(item[1]); 56 | item[1].fld4 = "updateFld2"; 57 | 58 | db.Table1Items.add(new db.Table1Items.createNew({ fld2: 'prop32', fld3: 'prop33', fld4: 'prop34' })); 59 | 60 | db.saveChanges(function () { 61 | start(); 62 | ok(true, "all done"); 63 | }); 64 | }); 65 | 66 | 67 | }); 68 | }); 69 | }); 70 | }); -------------------------------------------------------------------------------- /src/JaySvcUtil/Example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/Types/Expressions/Visitors/GlobalContextProcessor.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception } from '../../../TypeSystem/index.js'; 2 | 3 | $C("$data.Expressions.GlobalContextProcessor", $data.Expressions.ParameterProcessor, null, { 4 | constructor: function (global) { 5 | /// 6 | this.global = global; 7 | }, 8 | 9 | canResolve: function (paramExpression) { 10 | /// 11 | return (paramExpression.nodeType == $data.Expressions.ExpressionType.Parameter || ($data.defaults.parameterResolutionCompatibility && paramExpression.nodeType == $data.Expressions.ExpressionType.ParameterReference)) && 12 | this.global && typeof this.global === 'object' && 13 | paramExpression.name in this.global; 14 | }, 15 | 16 | resolve: function (paramExpression) { 17 | /// 18 | /// 19 | var resultValue = this.global[paramExpression.name]; 20 | var expression = Container.createConstantExpression(resultValue, typeof resultValue, paramExpression.name); 21 | return expression; 22 | } 23 | 24 | }); 25 | 26 | 27 | 28 | $C("$data.Expressions.ConstantValueResolver", $data.Expressions.ParameterProcessor, null, { 29 | constructor: function (paramsObject, global, scopeContext) { 30 | /// 31 | this.globalResolver = Container.createGlobalContextProcessor(global); 32 | this.paramResolver = Container.createGlobalContextProcessor(paramsObject); 33 | this.paramsObject = paramsObject; 34 | this.scopeContext = scopeContext; 35 | }, 36 | 37 | canResolve: function (paramExpression) { 38 | /// 39 | if($data.defaults.parameterResolutionCompatibility){ 40 | return (paramExpression.name === '$context') || (paramExpression.nodeType == $data.Expressions.ExpressionType.This && this.paramsObject) 41 | ? true : (this.paramResolver.canResolve(paramExpression) || this.globalResolver.canResolve(paramExpression)); 42 | } 43 | return (paramExpression.name === '$context') ? true : this.paramResolver.canResolve(paramExpression); 44 | }, 45 | 46 | resolve: function (paramExpression) { 47 | /// 48 | /// 49 | if (paramExpression.name === '$context') { 50 | return Container.createEntityContextExpression(this.scopeContext); 51 | } 52 | if ($data.defaults.parameterResolutionCompatibility) { 53 | if (paramExpression.nodeType == $data.Expressions.ExpressionType.This) { 54 | return Container.createConstantExpression(this.paramsObject, typeof this.paramsObject, 'this'); 55 | } 56 | return this.paramResolver.canResolve(paramExpression) ? this.paramResolver.resolve(paramExpression) : this.globalResolver.resolve(paramExpression); 57 | } 58 | return this.paramResolver.resolve(paramExpression); 59 | } 60 | 61 | }); 62 | 63 | export default $data 64 | -------------------------------------------------------------------------------- /src/Types/StorageProviders/oData/SaveStrategies/batch.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | var strategy = { 4 | name: 'batch', 5 | condition: function (provider, convertedItems) { 6 | var disabled = false; 7 | if(typeof provider.providerConfiguration.disableBatch !== 'undefined'){ 8 | disabled = !!provider.providerConfiguration.disableBatch; 9 | } else { 10 | disabled = !!$data.defaults.OData.disableBatch; 11 | } 12 | 13 | if (!disabled) { 14 | var requests = convertedItems.getItems(); 15 | return requests.length > 1; 16 | } 17 | 18 | return false; 19 | }, 20 | save: function (provider, convertedItems, callBack) { 21 | var that = provider; 22 | var items = convertedItems.getItems(); 23 | var requests = items.map(function(it){ return it.request.build().get() }) 24 | 25 | var requestData = [{ 26 | requestUri: that.providerConfiguration.oDataServiceHost + "/$batch", 27 | method: "POST", 28 | data: { 29 | __batchRequests: [{ __changeRequests: requests }] 30 | }, 31 | headers: { 32 | } 33 | }, function (data, response) { 34 | if (response.statusCode == 200 || response.statusCode == 202) { 35 | var result = data.__batchResponses[0].__changeResponses; 36 | var errors = []; 37 | 38 | for (var i = 0; i < result.length; i++) { 39 | if (result[i].statusCode >= 200 && result[i].statusCode < 300) { 40 | var item = convertedItems.getByResponse(result[i], i); 41 | if(item instanceof $data.Entity && result[i].statusCode != 204){ 42 | that.reload_fromResponse(item, result[i].data, result[i]); 43 | convertedItems.setProcessed(item); 44 | } 45 | } else { 46 | errors.push(that.parseError(result[i])); 47 | } 48 | } 49 | if (errors.length > 0) { 50 | if (errors.length === 1) { 51 | callBack.error(errors[0]); 52 | } else { 53 | callBack.error(new Exception('See inner exceptions', 'Batch failed', errors)); 54 | } 55 | } else if (callBack.success) { 56 | callBack.success(convertedItems.length); 57 | } 58 | } else { 59 | callBack.error(that.parseError(response)); 60 | } 61 | 62 | }, function (e) { 63 | callBack.error(that.parseError(e)); 64 | }, that.oData.batch.batchHandler]; 65 | 66 | if (typeof that.providerConfiguration.useJsonLight !== 'undefined') { 67 | requestData[0].useJsonLight = that.providerConfiguration.useJsonLight; 68 | } 69 | 70 | that.appendBasicAuth(requestData[0], that.providerConfiguration.user, that.providerConfiguration.password, that.providerConfiguration.withCredentials); 71 | 72 | that.context.prepareRequest.call(that, requestData); 73 | that.oData.request.apply(that, requestData); 74 | } 75 | } 76 | 77 | 78 | export { strategy } -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/JaySvcUtil.js: -------------------------------------------------------------------------------- 1 | 2 | $data.Class.define('$data.MetadataLoaderClass', null, null, { 3 | load: function (metadataUri, username, password, callBack) { 4 | if (arguments.length < 4) { 5 | callBack = username; 6 | username = undefined; 7 | password = undefined; 8 | } 9 | callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack); 10 | 11 | var self = this; 12 | self._loadXMLDoc(metadataUri, username, password, function (xml) { 13 | var version = self._findVersion(xml); 14 | self._loadXMLDoc(self.xsltRepoUrl + self._supportedODataVersionXSLT[version], undefined, undefined, function (xsl) { 15 | var codeText = self._processResults(metadataUri, xml, xsl); 16 | eval(codeText); 17 | if (self.debugMode) 18 | callBack.success(codeText); 19 | else 20 | callBack.success(); 21 | }); 22 | }); 23 | }, 24 | debugMode: { type: 'bool', value: false }, 25 | xsltRepoUrl: {type: 'string', value: '' }, 26 | 27 | _loadXMLDoc: function (dname, u, p, callback) { 28 | var xhttp = new XMLHttpRequest(); 29 | xhttp.open("GET", dname, true, u, p); 30 | xhttp.onreadystatechange = function () { 31 | if (xhttp.readyState === 4) { 32 | callback(xhttp.responseXML); 33 | } 34 | }; 35 | xhttp.send(""); 36 | }, 37 | _processResults: function (metadataUri, metadata, xsl) { 38 | if (window.ActiveXObject) { 39 | return metadata.transformNode(xsl); 40 | } else if (document.implementation && document.implementation.createDocument) { 41 | var xsltProcessor = new XSLTProcessor(); 42 | xsltProcessor.importStylesheet(xsl); 43 | xsltProcessor.setParameter(null, 'SerivceUri', metadataUri.replace('/$metadata','')); 44 | resultDocument = xsltProcessor.transformToFragment(metadata, document); 45 | 46 | return resultDocument.textContent; 47 | } 48 | }, 49 | _findVersion: function (metadata) { 50 | var version = 'http://schemas.microsoft.com/ado/2008/09/edm'; 51 | var item = metadata.getElementsByTagName('Schema'); 52 | if (item) 53 | item = item[0]; 54 | if (item) 55 | item = item.attributes; 56 | if (item) 57 | item = item.getNamedItem('xmlns'); 58 | if (item) 59 | version = item.value; 60 | 61 | var versionNum = this._supportedODataVersions[version]; 62 | return versionNum 63 | }, 64 | _supportedODataVersions: { 65 | value: { 66 | "http://schemas.microsoft.com/ado/2006/04/edm": "V1", 67 | "http://schemas.microsoft.com/ado/2008/09/edm": "V2", 68 | "http://schemas.microsoft.com/ado/2009/11/edm": "V3", 69 | "http://schemas.microsoft.com/ado/2007/05/edm": "V11" 70 | } 71 | }, 72 | _supportedODataVersionXSLT: { 73 | value: { 74 | "V1": 'JayDataContextGenerator_OData_V1.xslt', 75 | "V2": 'JayDataContextGenerator_OData_V2.xslt', 76 | "V3": 'JayDataContextGenerator_OData_V3.xslt', 77 | "V11": 'JayDataContextGenerator_OData_V11.xslt' 78 | } 79 | } 80 | 81 | }); 82 | 83 | $data.MetadataLoader = new $data.MetadataLoaderClass(); 84 | -------------------------------------------------------------------------------- /src/JayDataModules/template.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | import jQuery from 'jquery' 3 | 4 | (function ($data, $) { 5 | var toTemplate = function (templateId, targetId, callback) { 6 | /// 7 | /// 8 | /// 9 | /// 10 | 11 | //Adat tulajdonság jelölése. Akár úgy is mint tmpl-ben: prefix: '\\${', postfix: '}' 12 | var prefix = '\\${', postfix = '}'; 13 | return this.toArray(function (data) { 14 | var template = document.getElementById(templateId); 15 | var target = document.getElementById(targetId); 16 | if (!template || !target) 17 | return; 18 | 19 | target.innerHTML = ""; 20 | var regex = new RegExp(prefix + "(.*?)" + postfix, "g"); 21 | var myArray = template.innerHTML.match(regex); 22 | for (var i = 0; i < data.length; i++) { 23 | var currTemp = template.innerHTML; 24 | for (var j = 0; j < myArray.length; j++) { 25 | var prop = myArray[j].substring(prefix.replace("\\", "").length, myArray[j].length - postfix.replace("\\", "").length); 26 | var root = data[i]; 27 | var parts = prop.split('.'); 28 | for (var k = 0; k < parts.length; k++) { 29 | if (root) 30 | root = root[parts[k]]; 31 | } 32 | currTemp = currTemp.replace(myArray[j], root); 33 | } 34 | target.innerHTML += currTemp; 35 | } 36 | 37 | if (typeof callback == "function") 38 | callback(data); 39 | }); 40 | }; 41 | var tojQueryTemplate = function (templateName, targetSelector, options, callback) { 42 | /// 43 | /// 44 | /// 45 | /// 46 | return this.toArray(function (data) { 47 | if ($ && $.tmpl) { 48 | var templateSource = $(templateName); 49 | if (templateSource.length) 50 | templateSource.tmpl(data, options).appendTo($(targetSelector)); 51 | else 52 | $.tmpl(templateName, data, options).appendTo($(targetSelector)); 53 | } 54 | if (typeof callback == "function") 55 | callback(data); 56 | }); 57 | }; 58 | 59 | $data.Queryable.prototype.toTemplate = $data.Queryable.prototype.toTemplate || toTemplate; 60 | $data.EntitySet.prototype.toTemplate = $data.EntitySet.prototype.toTemplate || toTemplate; 61 | 62 | if (typeof $ != 'undefined' && typeof $.tmpl != 'undefined') { 63 | $data.Queryable.prototype.tojQueryTemplate = $data.Queryable.prototype.tojQueryTemplate || tojQueryTemplate; 64 | $data.EntitySet.prototype.tojQueryTemplate = $data.EntitySet.prototype.tojQueryTemplate || tojQueryTemplate; 65 | } else { 66 | $data.Queryable.prototype.tojQueryTemplate = 67 | $data.EntitySet.prototype.tojQueryTemplate = function() { 68 | Guard.raise(new Exception('jQuery and jQuery tmpl plugin is required', 'Not Found!')); 69 | }; 70 | } 71 | 72 | })($data, jQuery); 73 | 74 | export default $data 75 | -------------------------------------------------------------------------------- /src/TypeSystem/Types/Types.js: -------------------------------------------------------------------------------- 1 | import $data from '../TypeSystem.js' 2 | 3 | $data.Number = typeof Number !== 'undefined' ? Number : function JayNumber() { }; 4 | $data.Date = typeof Date !== 'undefined' ? Date : function JayDate() { }; 5 | $data.String = typeof String !== 'undefined' ? String : function JayString() { }; 6 | $data.Boolean = typeof Boolean !== 'undefined' ? Boolean : function JayBoolean() { }; 7 | $data.Array = typeof Array !== 'undefined' ? Array : function JayArray() { }; 8 | $data.Object = typeof Object !== 'undefined' ? Object : function JayObject() { }; 9 | $data.Function = Function; 10 | 11 | $data.Byte = function JayByte() { }; 12 | $data.SByte = function JaySByte() { }; 13 | $data.Decimal = function JayDecimal() { }; 14 | $data.Float = $data.Single = function JayFloat() { }; 15 | $data.Integer = function JayInteger() { }; 16 | $data.Int16 = function JayInt16(v) { }; 17 | $data.Int32 = function JayInt32() { }; 18 | $data.Int64 = function JayInt64(v) { }; 19 | $data.ObjectID = typeof $data.mongoDBDriver !== 'undefined' && typeof $data.mongoDBDriver.ObjectID !== 'undefined' ? $data.mongoDBDriver.ObjectID : function JayObjectID() { }; 20 | $data.Time = function JayTime() { }; 21 | $data.Day = function JayDay() { }; 22 | $data.Duration = function JayDuration() { }; 23 | $data.DateTimeOffset = function JayDateTimeOffset(val) { 24 | this.value = val; 25 | }; 26 | $data.DateTimeOffset.prototype.toJSON = function () { 27 | return this.value instanceof Date ? this.value.toISOString() : this.value; 28 | }; 29 | 30 | $data.Container.registerType(["$data.Number", "number", "JayNumber", "double"], $data.Number); 31 | $data.Container.registerType(["$data.Integer", "int", "integer", "JayInteger"], $data.Integer); 32 | $data.Container.registerType(["$data.Int32", "int32", "JayInt32"], $data.Int32); 33 | $data.Container.registerType(["$data.Byte", "byte", "JayByte"], $data.Byte); 34 | $data.Container.registerType(["$data.SByte", "sbyte", "JaySByte"], $data.SByte); 35 | $data.Container.registerType(["$data.Decimal", "decimal", "JayDecimal"], $data.Decimal); 36 | $data.Container.registerType(["$data.Float", "$data.Single", "float", "single", "JayFloat"], $data.Float); 37 | $data.Container.registerType(["$data.Int16", "int16", "word", "JayInt16"], $data.Int16); 38 | $data.Container.registerType(["$data.Int64", "int64", "long", "JayInt64"], $data.Int64); 39 | $data.Container.registerType(["$data.String", "string", "text", "character", "JayString"], $data.String); 40 | $data.Container.registerType(["$data.Array", "array", "Array", "[]", "JayArray"], $data.Array, function () { 41 | return $data.Array.apply(undefined, arguments); 42 | }); 43 | $data.Container.registerType(["$data.Date", "datetime", "date", "JayDate"], $data.Date); 44 | $data.Container.registerType(["$data.Time", "time", "JayTime"], $data.Time); 45 | $data.Container.registerType(["$data.Day", "day", "JayDay"], $data.Day); 46 | $data.Container.registerType(["$data.Duration", "duration", "JayDuration"], $data.Duration); 47 | $data.Container.registerType(["$data.DateTimeOffset", "offset", "datetimeoffset", "JayDateTimeOffset"], $data.DateTimeOffset); 48 | $data.Container.registerType(["$data.Boolean", "bool", "boolean", "JayBoolean"], $data.Boolean); 49 | $data.Container.registerType(["$data.Object", "Object", "object", "{}", "JayObject"], $data.Object); 50 | $data.Container.registerType(["$data.Function", "Function", "function"], $data.Function); 51 | $data.Container.registerType(['$data.ObjectID', 'ObjectID', 'objectId', 'objectid', 'ID', 'Id', 'id', 'JayObjectID'], $data.ObjectID); 52 | 53 | export default $data 54 | -------------------------------------------------------------------------------- /test/qunit/scripts/NodeJS/JaySvcUtil/JaySvcUtilNode.js: -------------------------------------------------------------------------------- 1 | require('jaydata'); 2 | XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; 3 | 4 | $data.Class.define('$data.MetadataLoaderClass', null, null, { 5 | load: function (metadataUri, username, password, callBack) { 6 | if (arguments.length < 4) { 7 | callBack = username; 8 | username = undefined; 9 | password = undefined; 10 | } 11 | callBack = $data.PromiseHandlerBase.createCallbackSettings(callBack); 12 | 13 | var self = this; 14 | self._loadXMLDoc(metadataUri, username, password, function (xml) { 15 | console.log("!" + xml); 16 | // var version = self._findVersion(xml); 17 | // self._loadXMLDoc(self.xsltRepoUrl + self._supportedODataVersionXSLT[version], undefined, undefined, function (xsl) { 18 | 19 | //var codeText = self._processResults(metadataUri, xml, xsl); 20 | //eval(codeText); 21 | // if (self.debugMode) 22 | // callBack.success(codeText); 23 | // else 24 | // callBack.success(); 25 | // }); 26 | }); 27 | }, 28 | debugMode: { type: 'bool', value: false }, 29 | xsltRepoUrl: {type: 'string', value: '' }, 30 | 31 | _loadXMLDoc: function (dname, u, p, callback) { 32 | var xhttp = new XMLHttpRequest(); 33 | xhttp.open("GET", dname, true, u, p); 34 | xhttp.onreadystatechange = function () { 35 | if (xhttp.readyState === 4) { 36 | callback(xhttp.responseXML); 37 | } 38 | }; 39 | xhttp.send(""); 40 | }, 41 | _processResults: function (metadataUri, metadata, xsl) { 42 | if (window.ActiveXObject) { 43 | return metadata.transformNode(xsl); 44 | } else if (document.implementation && document.implementation.createDocument) { 45 | var xsltProcessor = new XSLTProcessor(); 46 | xsltProcessor.importStylesheet(xsl); 47 | xsltProcessor.setParameter(null, 'SerivceUri', metadataUri.replace('/$metadata','')); 48 | resultDocument = xsltProcessor.transformToFragment(metadata, document); 49 | 50 | return resultDocument.textContent; 51 | } 52 | }, 53 | _findVersion: function (metadata) { 54 | var version = 'http://schemas.microsoft.com/ado/2008/09/edm'; 55 | var item = metadata.getElementsByTagName('Schema'); 56 | if (item) 57 | item = item[0]; 58 | if (item) 59 | item = item.attributes; 60 | if (item) 61 | item = item.getNamedItem('xmlns'); 62 | if (item) 63 | version = item.value; 64 | 65 | var versionNum = this._supportedODataVersions[version]; 66 | return versionNum 67 | }, 68 | _supportedODataVersions: { 69 | value: { 70 | "http://schemas.microsoft.com/ado/2006/04/edm": "V1", 71 | "http://schemas.microsoft.com/ado/2008/09/edm": "V2", 72 | "http://schemas.microsoft.com/ado/2009/11/edm": "V3", 73 | "http://schemas.microsoft.com/ado/2007/05/edm": "V11" 74 | } 75 | }, 76 | _supportedODataVersionXSLT: { 77 | value: { 78 | "V1": 'JayDataContextGenerator_OData_V1.xslt', 79 | "V2": 'JayDataContextGenerator_OData_V2.xslt', 80 | "V3": 'JayDataContextGenerator_OData_V3.xslt', 81 | "V11": 'JayDataContextGenerator_OData_V11.xslt' 82 | } 83 | } 84 | 85 | }); 86 | 87 | $data.MetadataLoader = new $data.MetadataLoaderClass(); 88 | -------------------------------------------------------------------------------- /src/Types/DbClient/OpenDatabaseClient/OpenDbCommand.js: -------------------------------------------------------------------------------- 1 | import $data, { $C, Guard, Container, Exception, MemberDefinition } from 'jaydata/core'; 2 | 3 | $data.Class.define('$data.dbClient.openDatabaseClient.OpenDbCommand', $data.dbClient.DbCommand, null, 4 | { 5 | constructor: function (con, queryStr, params) { 6 | this.query = queryStr; 7 | this.connection = con; 8 | this.parameters = params; 9 | }, 10 | executeNonQuery: function (callback, tran, isWrite) { 11 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 12 | this.exec(this.query, this.parameters, callback.success, callback.error, tran, isWrite); 13 | }, 14 | executeQuery: function (callback, tran, isWrite) { 15 | callback = $data.PromiseHandlerBase.createCallbackSettings(callback); 16 | this.exec(this.query, this.parameters, callback.success, callback.error, tran, isWrite); 17 | }, 18 | exec: function (query, parameters, callback, errorhandler, transaction, isWrite) { 19 | // suspicious code 20 | /*if (console) { 21 | //console.log(query); 22 | }*/ 23 | this.connection.open({ 24 | error: errorhandler, 25 | success: function (tran) { 26 | var single = false; 27 | if (!(query instanceof Array)) { 28 | single = true; 29 | query = [query]; 30 | parameters = [parameters]; 31 | } 32 | 33 | var results = []; 34 | var remainingCommands = 0; 35 | 36 | function decClb() { 37 | if (--remainingCommands == 0) { 38 | callback(single ? results[0] : results, transaction); 39 | } 40 | } 41 | 42 | query.forEach(function (q, i) { 43 | remainingCommands++; 44 | if (q) { 45 | tran.executeSql( 46 | query[i], 47 | parameters[i], 48 | function (trx, result) { 49 | var r = { rows: [] }; 50 | try { 51 | r.insertId = result.insertId; 52 | } catch (e) {} 53 | if (typeof r.insertId !== 'number') { 54 | // If insertId is present, no rows are returned 55 | r.rowsAffected = result.rowsAffected; 56 | var maxItem = result.rows.length; 57 | for (var j = 0; j < maxItem; j++) { 58 | r.rows.push(result.rows.item(j)); 59 | } 60 | } 61 | results[i] = r; 62 | decClb(trx); 63 | }, 64 | function (trx, err) { 65 | var _q = q; 66 | var _i = i; 67 | 68 | if (errorhandler) 69 | errorhandler(err); 70 | 71 | return true; 72 | } 73 | ); 74 | } else { 75 | results[i] = null; 76 | decClb(); 77 | } 78 | }); 79 | } 80 | }, transaction, isWrite); 81 | } 82 | }, null); 83 | -------------------------------------------------------------------------------- /test/qunit/scripts/oDataProviderTests_auth.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | module("BasicAuth"); 3 | var protectedServiceURL = "Services/Protected/emptyNewsReader.svc"; 4 | test("Auth fail", 1, function () { 5 | stop(1); 6 | (new $news.Types.NewsContext({ name: "oData", oDataServiceHost: protectedServiceURL, user: "wronguser", password: "wrongpassword" })).onReady(function (db) { 7 | db.Tags.toArray({ 8 | success: function () { 9 | start(); 10 | ok(false, "Auth error"); 11 | }, error: function (error) { 12 | start(); 13 | ok(true, "Auth error"); 14 | } 15 | }); 16 | }); 17 | }); 18 | test("Auth ok", 7, function () { 19 | stop(1); 20 | (new $news.Types.NewsContext({ name: "oData", oDataServiceHost: protectedServiceURL, user: "user", password: "password" })).onReady(function (db) { 21 | db.Tags.toArray({ 22 | success: function (result) { 23 | ok(true, "Auth ok"); 24 | var count = result.length; 25 | var tag = new $news.Types.Tag({ Title: 'AuthTag' }) 26 | db.Tags.add(tag); 27 | db.saveChanges({ 28 | success: function () { 29 | ok(true, "Save tag"); 30 | db.Tags.toArray({ 31 | success: function (result) { 32 | ok(true, "Tag saved"); 33 | equal(result.length, count + 1, "Tag count saved ok"); 34 | db.Tags.remove(tag); 35 | db.saveChanges({ 36 | success: function () { 37 | ok(true, "Tag remove"); 38 | db.Tags.toArray({ 39 | success: function (result) { 40 | start(); 41 | ok(true, "Tag removed"); 42 | equal(result.length, count, "Tag removed count ok"); 43 | }, error: function () { 44 | start(); 45 | ok(false, "Tag removed"); 46 | } 47 | }); 48 | }, error: function () { 49 | start(); 50 | ok(false, "Tag remove"); 51 | } 52 | }); 53 | }, error: function () { 54 | start(); 55 | ok(false, "Tag saved"); 56 | } 57 | }); 58 | }, error: function () { 59 | start(); 60 | ok(false, "Save tag"); 61 | }}); 62 | }, error: function (error) { 63 | start(); 64 | ok(false, "Auth ok"); 65 | } 66 | }); 67 | }); 68 | }); 69 | }); --------------------------------------------------------------------------------