Showing
22 changed files
with
720 additions
and
0 deletions
.gitignore
0 → 100644
README.md
0 → 100644
dist/api/device-info.d.ts
0 → 100644
dist/api/device-info.js
0 → 100644
| 1 | +"use strict"; |
dist/index.d.ts
0 → 100644
dist/index.js
0 → 100644
dist/services/device.d.ts
0 → 100644
dist/services/device.js
0 → 100644
| 1 | +"use strict"; | ||
| 2 | +var Device = (function () { | ||
| 3 | + function Device() { | ||
| 4 | + } | ||
| 5 | + Device.prototype.reload = function () { | ||
| 6 | + if (window && window.location) { | ||
| 7 | + window.location.reload(); | ||
| 8 | + } | ||
| 9 | + }; | ||
| 10 | + Device.prototype.exit = function () { | ||
| 11 | + if (window && window['require']) { | ||
| 12 | + var electron = window['require']('electron'); | ||
| 13 | + if (electron && electron.ipcRenderer) { | ||
| 14 | + electron.ipcRenderer.send('exit'); | ||
| 15 | + } | ||
| 16 | + } | ||
| 17 | + }; | ||
| 18 | + return Device; | ||
| 19 | +}()); | ||
| 20 | +exports.Device = Device; |
dist/services/repository.d.ts
0 → 100644
| 1 | +import { Rest } from './rest'; | ||
| 2 | +import { Device } from './device'; | ||
| 3 | +import { DeviceInfo } from '../api/device-info'; | ||
| 4 | +export declare class Repository { | ||
| 5 | + protected rest: Rest; | ||
| 6 | + protected device: Device; | ||
| 7 | + protected _db: any; | ||
| 8 | + protected _params: any; | ||
| 9 | + readonly db: any; | ||
| 10 | + constructor(rest: Rest, device: Device); | ||
| 11 | + findById(id: string): Promise<any>; | ||
| 12 | + findByIds(ids: Array<string>): Promise<Array<any>>; | ||
| 13 | + findByType(type: string): Promise<Array<any>>; | ||
| 14 | + replicate(deviceInfo: DeviceInfo): Promise<boolean>; | ||
| 15 | + prepare(url: string): Promise<any>; | ||
| 16 | + init(db_name: string): Promise<any>; | ||
| 17 | + parseUrl(url: string): { | ||
| 18 | + url: string; | ||
| 19 | + user: string; | ||
| 20 | + pass: string; | ||
| 21 | + domain: string; | ||
| 22 | + db_name: string; | ||
| 23 | + }; | ||
| 24 | + prepareDocs(res: any): Array<any>; | ||
| 25 | +} |
dist/services/repository.js
0 → 100644
| 1 | +"use strict"; | ||
| 2 | +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
| 3 | + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | ||
| 4 | + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | ||
| 5 | + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
| 6 | + return c > 3 && r && Object.defineProperty(target, key, r), r; | ||
| 7 | +}; | ||
| 8 | +var core_1 = require("@angular/core"); | ||
| 9 | +var Repository = (function () { | ||
| 10 | + function Repository(rest, device) { | ||
| 11 | + this.rest = rest; | ||
| 12 | + this.device = device; | ||
| 13 | + } | ||
| 14 | + Object.defineProperty(Repository.prototype, "db", { | ||
| 15 | + get: function () { | ||
| 16 | + return this._db; | ||
| 17 | + }, | ||
| 18 | + enumerable: true, | ||
| 19 | + configurable: true | ||
| 20 | + }); | ||
| 21 | + Repository.prototype.findById = function (id) { | ||
| 22 | + return this._db.get(id); | ||
| 23 | + }; | ||
| 24 | + Repository.prototype.findByIds = function (ids) { | ||
| 25 | + var _this = this; | ||
| 26 | + return new Promise(function (resolve, reject) { | ||
| 27 | + _this._db | ||
| 28 | + .allDocs({ | ||
| 29 | + include_docs: true, | ||
| 30 | + keys: ids | ||
| 31 | + }).then(function (res) { | ||
| 32 | + resolve(_this.prepareDocs(res)); | ||
| 33 | + }).catch(function (error) { | ||
| 34 | + reject(error); | ||
| 35 | + }); | ||
| 36 | + }); | ||
| 37 | + }; | ||
| 38 | + Repository.prototype.findByType = function (type) { | ||
| 39 | + var _this = this; | ||
| 40 | + var options = { | ||
| 41 | + include_docs: true | ||
| 42 | + }; | ||
| 43 | + if (type != "") { | ||
| 44 | + options['key'] = type; | ||
| 45 | + } | ||
| 46 | + return new Promise(function (resolve, reject) { | ||
| 47 | + _this._db | ||
| 48 | + .query('index_type/type', options) | ||
| 49 | + .then(function (res) { | ||
| 50 | + resolve(_this.prepareDocs(res)); | ||
| 51 | + }).catch(function (error) { | ||
| 52 | + reject(error); | ||
| 53 | + }); | ||
| 54 | + }); | ||
| 55 | + }; | ||
| 56 | + Repository.prototype.replicate = function (deviceInfo) { | ||
| 57 | + var _this = this; | ||
| 58 | + return new Promise(function (resolve, reject) { | ||
| 59 | + _this.rest.heartbeat(deviceInfo) | ||
| 60 | + .then(function (response) { | ||
| 61 | + if (response && response.restart == 1) { | ||
| 62 | + _this.device.reload(); | ||
| 63 | + } | ||
| 64 | + else if (response && response.exit == 1) { | ||
| 65 | + _this.device.exit(); | ||
| 66 | + } | ||
| 67 | + else { | ||
| 68 | + return _this.prepare(response.db_url); | ||
| 69 | + } | ||
| 70 | + }).then(function () { | ||
| 71 | + var changes = false; | ||
| 72 | + _this._db.replicate.from(_this._params.url) | ||
| 73 | + .once('change', function (info) { changes = true; }) | ||
| 74 | + .once('complete', function () { resolve(changes); }) | ||
| 75 | + .once('error', function (error) { reject('replication error'); }); | ||
| 76 | + }) | ||
| 77 | + .catch(function (error) { reject(error); }); | ||
| 78 | + }); | ||
| 79 | + }; | ||
| 80 | + Repository.prototype.prepare = function (url) { | ||
| 81 | + var _this = this; | ||
| 82 | + return new Promise(function (resolve, reject) { | ||
| 83 | + _this._params = _this.parseUrl(url); | ||
| 84 | + if (!_this._params) { | ||
| 85 | + reject(); | ||
| 86 | + } | ||
| 87 | + if (_this._db && _this._db.name == _this._params.db_name) { | ||
| 88 | + resolve(); | ||
| 89 | + } | ||
| 90 | + else if (!_this._db) { | ||
| 91 | + _this.init(_this._params.db_name).then(function () { | ||
| 92 | + resolve(); | ||
| 93 | + }); | ||
| 94 | + } | ||
| 95 | + else { | ||
| 96 | + _this._db.destroy() | ||
| 97 | + .then(function () { | ||
| 98 | + return _this.init(_this._params.db_name); | ||
| 99 | + }).then(function () { | ||
| 100 | + resolve(); | ||
| 101 | + }); | ||
| 102 | + } | ||
| 103 | + }); | ||
| 104 | + }; | ||
| 105 | + Repository.prototype.init = function (db_name) { | ||
| 106 | + if (window['PouchDB']) { | ||
| 107 | + this._db = new window['PouchDB'](db_name); | ||
| 108 | + } | ||
| 109 | + return this._db.putIfNotExists("_design/index_type", { | ||
| 110 | + views: { | ||
| 111 | + type: { | ||
| 112 | + map: (function (doc) { | ||
| 113 | + if (doc.type) { | ||
| 114 | + emit(doc.type); | ||
| 115 | + } | ||
| 116 | + }).toString() | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + }); | ||
| 120 | + }; | ||
| 121 | + Repository.prototype.parseUrl = function (url) { | ||
| 122 | + // matches: 0:user,1:password,2:domain,3:db_name | ||
| 123 | + var exp = /^https?:\/\/(\w+?):(\w+?)@([a-zA-Z0-9.\-_:]+?)\/([a-zA-Z0-9\-_]+?)$/; | ||
| 124 | + var match = url.match(exp); | ||
| 125 | + if (match) { | ||
| 126 | + return { | ||
| 127 | + url: match[0], | ||
| 128 | + user: match[1], | ||
| 129 | + pass: match[2], | ||
| 130 | + domain: match[3], | ||
| 131 | + db_name: 'local_' + match[4] | ||
| 132 | + }; | ||
| 133 | + } | ||
| 134 | + return null; | ||
| 135 | + }; | ||
| 136 | + Repository.prototype.prepareDocs = function (res) { | ||
| 137 | + var docs = []; | ||
| 138 | + if (res.total_rows > 0) { | ||
| 139 | + for (var _i = 0, _a = res.rows; _i < _a.length; _i++) { | ||
| 140 | + var row = _a[_i]; | ||
| 141 | + docs.push(row.doc); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + return docs; | ||
| 145 | + }; | ||
| 146 | + return Repository; | ||
| 147 | +}()); | ||
| 148 | +Repository = __decorate([ | ||
| 149 | + core_1.Injectable() | ||
| 150 | +], Repository); | ||
| 151 | +exports.Repository = Repository; |
dist/services/rest.d.ts
0 → 100644
| 1 | +import { Http } from '@angular/http'; | ||
| 2 | +import { DeviceInfo } from './../api/device-info'; | ||
| 3 | +export declare const ERROR_CODE_UNAUTHORIZED: string; | ||
| 4 | +export declare const ERROR_CODE_NOT_FOUND: string; | ||
| 5 | +export declare const ERROR_CODE_SERVER_ERROR: string; | ||
| 6 | +export declare class Rest { | ||
| 7 | + private http; | ||
| 8 | + static serviceUrl: string; | ||
| 9 | + constructor(http: Http); | ||
| 10 | + prepareDeviceInfo(deviceInfo: DeviceInfo, prefixed?: boolean): string; | ||
| 11 | + register(registerCode: string, deviceInfo: DeviceInfo): Promise<any>; | ||
| 12 | + heartbeat(deviceInfo: DeviceInfo): Promise<any>; | ||
| 13 | +} |
dist/services/rest.js
0 → 100644
| 1 | +"use strict"; | ||
| 2 | +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
| 3 | + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | ||
| 4 | + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | ||
| 5 | + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
| 6 | + return c > 3 && r && Object.defineProperty(target, key, r), r; | ||
| 7 | +}; | ||
| 8 | +var core_1 = require("@angular/core"); | ||
| 9 | +var http_1 = require("@angular/http"); | ||
| 10 | +exports.ERROR_CODE_UNAUTHORIZED = "unauthorized"; | ||
| 11 | +exports.ERROR_CODE_NOT_FOUND = "not-found"; | ||
| 12 | +exports.ERROR_CODE_SERVER_ERROR = "server-error"; | ||
| 13 | +var Rest = Rest_1 = (function () { | ||
| 14 | + function Rest(http) { | ||
| 15 | + this.http = http; | ||
| 16 | + } | ||
| 17 | + Rest.prototype.prepareDeviceInfo = function (deviceInfo, prefixed) { | ||
| 18 | + if (prefixed === void 0) { prefixed = true; } | ||
| 19 | + var output = ""; | ||
| 20 | + if (deviceInfo.id) { | ||
| 21 | + output += '&device_id=' + deviceInfo.id; | ||
| 22 | + } | ||
| 23 | + if (deviceInfo.hostname) { | ||
| 24 | + output += '&device_hostname=' + deviceInfo.hostname; | ||
| 25 | + } | ||
| 26 | + if (deviceInfo.platform) { | ||
| 27 | + output += '&device_platform=' + deviceInfo.platform; | ||
| 28 | + } | ||
| 29 | + if (deviceInfo.type) { | ||
| 30 | + output += '&device_type=' + deviceInfo.type; | ||
| 31 | + } | ||
| 32 | + if (deviceInfo.release) { | ||
| 33 | + output += '&device_release=' + deviceInfo.release; | ||
| 34 | + } | ||
| 35 | + if (deviceInfo.arch) { | ||
| 36 | + output += '&device_arch=' + deviceInfo.arch; | ||
| 37 | + } | ||
| 38 | + if (deviceInfo.code) { | ||
| 39 | + output += '®ister_code=' + deviceInfo.code; | ||
| 40 | + } | ||
| 41 | + // prefixed with & for url | ||
| 42 | + if (!prefixed) { | ||
| 43 | + output = output.substr(1); | ||
| 44 | + } | ||
| 45 | + return output; | ||
| 46 | + }; | ||
| 47 | + Rest.prototype.register = function (registerCode, deviceInfo) { | ||
| 48 | + var _this = this; | ||
| 49 | + return new Promise(function (resolve, reject) { | ||
| 50 | + var headers = new http_1.Headers(); | ||
| 51 | + headers.append('Content-Type', 'application/x-www-form-urlencoded'); | ||
| 52 | + deviceInfo.code = registerCode; | ||
| 53 | + _this.http.post(Rest_1.serviceUrl + "/config/register", _this.prepareDeviceInfo(deviceInfo), { headers: headers }).subscribe(function (response) { | ||
| 54 | + resolve(); | ||
| 55 | + }, function (error) { | ||
| 56 | + if (error.status == 401) { | ||
| 57 | + reject(exports.ERROR_CODE_UNAUTHORIZED); | ||
| 58 | + } | ||
| 59 | + else { | ||
| 60 | + reject(exports.ERROR_CODE_SERVER_ERROR); | ||
| 61 | + } | ||
| 62 | + }); | ||
| 63 | + }); | ||
| 64 | + }; | ||
| 65 | + Rest.prototype.heartbeat = function (deviceInfo) { | ||
| 66 | + var _this = this; | ||
| 67 | + return new Promise(function (resolve, reject) { | ||
| 68 | + var headers = new http_1.Headers(); | ||
| 69 | + headers.append('Content-Type', 'application/x-www-form-urlencoded'); | ||
| 70 | + _this.http.post(Rest_1.serviceUrl + "/config/heartbeat", _this.prepareDeviceInfo(deviceInfo, false), { headers: headers }) | ||
| 71 | + .subscribe(function (response) { | ||
| 72 | + resolve(response.json()); | ||
| 73 | + }, function (error) { | ||
| 74 | + switch (error.status) { | ||
| 75 | + case 401: | ||
| 76 | + reject(exports.ERROR_CODE_UNAUTHORIZED); | ||
| 77 | + break; | ||
| 78 | + case 404: | ||
| 79 | + reject(exports.ERROR_CODE_NOT_FOUND); | ||
| 80 | + break; | ||
| 81 | + default: | ||
| 82 | + reject(exports.ERROR_CODE_SERVER_ERROR); | ||
| 83 | + break; | ||
| 84 | + } | ||
| 85 | + }); | ||
| 86 | + }); | ||
| 87 | + }; | ||
| 88 | + return Rest; | ||
| 89 | +}()); | ||
| 90 | +Rest.serviceUrl = "http://someurl.com"; | ||
| 91 | +Rest = Rest_1 = __decorate([ | ||
| 92 | + core_1.Injectable() | ||
| 93 | +], Rest); | ||
| 94 | +exports.Rest = Rest; | ||
| 95 | +var Rest_1; |
package.json
0 → 100644
| 1 | +{ | ||
| 2 | + "name": "digsig-services", | ||
| 3 | + "version": "1.0.0", | ||
| 4 | + "description": "", | ||
| 5 | + "main": "dist/index.js", | ||
| 6 | + "module": "dist/index.js", | ||
| 7 | + "typings": "dist/index.d.ts", | ||
| 8 | + "scripts": { | ||
| 9 | + "build": "npm run clean && tsc", | ||
| 10 | + "clean": "rm -rf ./dist", | ||
| 11 | + "pretest": "tsc -p ./spec", | ||
| 12 | + "test": "jasmine .tmp/spec/index.js", | ||
| 13 | + "posttest": "rm -rf .tmp" | ||
| 14 | + }, | ||
| 15 | + "author": "", | ||
| 16 | + "license": "ISC", | ||
| 17 | + "devDependencies": { | ||
| 18 | + "@angular/common": "^2.4.8", | ||
| 19 | + "@angular/core": "^2.4.8", | ||
| 20 | + "@angular/http": "^2.4.8", | ||
| 21 | + "@angular/platform-browser": "^2.4.8", | ||
| 22 | + "@types/jasmine": "^2.5.43", | ||
| 23 | + "jasmine": "^2.5.3", | ||
| 24 | + "pouchdb": "^6.1.2", | ||
| 25 | + "pouchdb-upsert": "^2.0.2", | ||
| 26 | + "reflect-metadata": "^0.1.9", | ||
| 27 | + "rxjs": "^5.1.1", | ||
| 28 | + "typescript": "^2.1.6", | ||
| 29 | + "zone.js": "^0.7.7" | ||
| 30 | + }, | ||
| 31 | + "peerDependencies": { | ||
| 32 | + "@angular/core": "*", | ||
| 33 | + "@angular/http": "*", | ||
| 34 | + "rxjs": "*", | ||
| 35 | + "pouchdb": "*", | ||
| 36 | + "pouchdb-upsert": "*" | ||
| 37 | + } | ||
| 38 | +} |
spec/index.ts
0 → 100644
spec/rest.ts
0 → 100644
| 1 | +import {Rest} from '../src/services/rest'; | ||
| 2 | + | ||
| 3 | +describe('Rest API', () => { | ||
| 4 | + | ||
| 5 | + Rest.serviceUrl = "http://digsig.local/config/register"; | ||
| 6 | + let restService : Rest = new Rest(null); | ||
| 7 | + | ||
| 8 | + it('Prepare Device Info', () => { | ||
| 9 | + | ||
| 10 | + let deviceString = restService.prepareDeviceInfo({ | ||
| 11 | + id : 'some-id' , | ||
| 12 | + hostname : 'some-hostname' , | ||
| 13 | + arch : 'some-arch' , | ||
| 14 | + platform : 'some-platform' , | ||
| 15 | + type : 'some-type' , | ||
| 16 | + release : 'some-release' , | ||
| 17 | + code : 'some-code' | ||
| 18 | + }, false); | ||
| 19 | + | ||
| 20 | + expect(deviceString).toEqual('device_id=some-id&device_hostname=some-hostname&device_platform=some-platform&device_type=some-type&device_release=some-release&device_arch=some-arch®ister_code=some-code'); | ||
| 21 | + }); | ||
| 22 | + | ||
| 23 | +}); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
spec/tsconfig.json
0 → 100644
| 1 | +{ | ||
| 2 | + "compilerOptions": { | ||
| 3 | + "target": "es5", | ||
| 4 | + "module": "commonjs", | ||
| 5 | + "moduleResolution": "node", | ||
| 6 | + "sourceMap": false, | ||
| 7 | + "emitDecoratorMetadata": true, | ||
| 8 | + "experimentalDecorators": true, | ||
| 9 | + "lib": [ "es2015", "dom" ], | ||
| 10 | + "noImplicitAny": true, | ||
| 11 | + "suppressImplicitAnyIndexErrors": true, | ||
| 12 | + "outDir": "../.tmp" | ||
| 13 | + } | ||
| 14 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/api/device-info.ts
0 → 100644
src/index.ts
0 → 100644
src/services/device.ts
0 → 100644
| 1 | +export class Device { | ||
| 2 | + | ||
| 3 | + reload() { | ||
| 4 | + if (window && window.location) { | ||
| 5 | + window.location.reload(); | ||
| 6 | + } | ||
| 7 | + } | ||
| 8 | + | ||
| 9 | + exit() { | ||
| 10 | + if (window && window['require']) { | ||
| 11 | + let electron = window['require']('electron'); | ||
| 12 | + if (electron && electron.ipcRenderer) { | ||
| 13 | + electron.ipcRenderer.send('exit'); | ||
| 14 | + } | ||
| 15 | + } | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/services/repository.ts
0 → 100644
| 1 | +import {Injectable} from '@angular/core'; | ||
| 2 | +import {Rest} from './rest'; | ||
| 3 | +import { Device } from './device'; | ||
| 4 | +import {DeviceInfo} from '../api/device-info'; | ||
| 5 | + | ||
| 6 | +declare var emit:any; | ||
| 7 | + | ||
| 8 | +@Injectable() | ||
| 9 | +export class Repository { | ||
| 10 | + | ||
| 11 | + protected _db; | ||
| 12 | + protected _params; | ||
| 13 | + | ||
| 14 | + get db() { | ||
| 15 | + return this._db; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + constructor( | ||
| 19 | + protected rest:Rest , | ||
| 20 | + protected device:Device | ||
| 21 | + ) {} | ||
| 22 | + | ||
| 23 | + findById(id:string) : Promise<any> { | ||
| 24 | + return this._db.get(id); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + findByIds(ids:Array<string>) : Promise<Array<any>> { | ||
| 28 | + return new Promise<Array<any>>((resolve, reject) => { | ||
| 29 | + this._db | ||
| 30 | + .allDocs({ | ||
| 31 | + include_docs: true , | ||
| 32 | + keys : ids | ||
| 33 | + }).then((res) => { | ||
| 34 | + resolve(this.prepareDocs(res)); | ||
| 35 | + }).catch(error => { | ||
| 36 | + reject(error); | ||
| 37 | + }); | ||
| 38 | + }); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + findByType(type:string) : Promise<Array<any>> { | ||
| 42 | + let options = { | ||
| 43 | + include_docs : true | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + if (type != "") { | ||
| 47 | + options['key'] = type; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + return new Promise<Array<any>>((resolve, reject) => { | ||
| 51 | + this._db | ||
| 52 | + .query('index_type/type', options) | ||
| 53 | + .then((res) => { | ||
| 54 | + resolve(this.prepareDocs(res)); | ||
| 55 | + }).catch(error => { | ||
| 56 | + reject(error); | ||
| 57 | + }); | ||
| 58 | + }); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + replicate(deviceInfo: DeviceInfo) : Promise<boolean> { | ||
| 62 | + return new Promise<boolean>((resolve, reject) => { | ||
| 63 | + this.rest.heartbeat(deviceInfo) | ||
| 64 | + .then(response => { | ||
| 65 | + if (response && response.restart == 1) { | ||
| 66 | + this.device.reload(); | ||
| 67 | + } else if (response && response.exit == 1) { | ||
| 68 | + this.device.exit() | ||
| 69 | + } else { | ||
| 70 | + return this.prepare(response.db_url); | ||
| 71 | + } | ||
| 72 | + }).then(() => { | ||
| 73 | + let changes = false; | ||
| 74 | + this._db.replicate.from(this._params.url) | ||
| 75 | + .once('change', (info) => { changes = true; }) | ||
| 76 | + .once('complete', () => { resolve(changes); }) | ||
| 77 | + .once('error', (error) => { reject('replication error'); }); | ||
| 78 | + }) | ||
| 79 | + .catch(error => { reject(error); }); | ||
| 80 | + }); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + prepare(url:string) : Promise<any> { | ||
| 84 | + return new Promise<any>((resolve,reject) => { | ||
| 85 | + this._params = this.parseUrl(url); | ||
| 86 | + | ||
| 87 | + if (!this._params) { | ||
| 88 | + reject(); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + if (this._db && this._db.name == this._params.db_name) { | ||
| 92 | + resolve(); | ||
| 93 | + } else if(!this._db) { | ||
| 94 | + this.init(this._params.db_name).then(() => { | ||
| 95 | + resolve(); | ||
| 96 | + }); | ||
| 97 | + } else { | ||
| 98 | + this._db.destroy() | ||
| 99 | + .then(() => { | ||
| 100 | + return this.init(this._params.db_name); | ||
| 101 | + }).then(() => { | ||
| 102 | + resolve(); | ||
| 103 | + }); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + }); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + init(db_name:string) : Promise<any> { | ||
| 110 | + if (window['PouchDB']) { | ||
| 111 | + this._db = new window['PouchDB'](db_name); | ||
| 112 | + } | ||
| 113 | + return this._db.putIfNotExists("_design/index_type", { | ||
| 114 | + views : { | ||
| 115 | + type : { | ||
| 116 | + map : (function(doc) { | ||
| 117 | + if (doc.type) { emit(doc.type); } | ||
| 118 | + }).toString() | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + }); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + parseUrl(url:string) { | ||
| 125 | + // matches: 0:user,1:password,2:domain,3:db_name | ||
| 126 | + let exp = /^https?:\/\/(\w+?):(\w+?)@([a-zA-Z0-9.\-_:]+?)\/([a-zA-Z0-9\-_]+?)$/; | ||
| 127 | + let match = url.match(exp); | ||
| 128 | + | ||
| 129 | + if (match) { | ||
| 130 | + return { | ||
| 131 | + url : match[0] , | ||
| 132 | + user : match[1] , | ||
| 133 | + pass : match[2] , | ||
| 134 | + domain : match[3] , | ||
| 135 | + db_name : 'local_' + match[4] | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + return null; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + prepareDocs(res) : Array<any> { | ||
| 143 | + let docs = []; | ||
| 144 | + | ||
| 145 | + if (res.total_rows > 0) { | ||
| 146 | + for(let row of res.rows) { | ||
| 147 | + docs.push(row.doc); | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + return docs; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/services/rest.ts
0 → 100644
| 1 | +import {Injectable} from '@angular/core'; | ||
| 2 | +import {Http,Response,Headers} from '@angular/http'; | ||
| 3 | +import { DeviceInfo } from './../api/device-info'; | ||
| 4 | + | ||
| 5 | +export const ERROR_CODE_UNAUTHORIZED:string = "unauthorized"; | ||
| 6 | +export const ERROR_CODE_NOT_FOUND:string = "not-found"; | ||
| 7 | +export const ERROR_CODE_SERVER_ERROR:string = "server-error"; | ||
| 8 | + | ||
| 9 | +@Injectable() | ||
| 10 | +export class Rest { | ||
| 11 | + | ||
| 12 | + public static serviceUrl: string = "http://someurl.com"; | ||
| 13 | + | ||
| 14 | + constructor(private http:Http) {} | ||
| 15 | + | ||
| 16 | + prepareDeviceInfo(deviceInfo:DeviceInfo, prefixed:boolean = true) : string { | ||
| 17 | + let output = ""; | ||
| 18 | + | ||
| 19 | + if (deviceInfo.id) { | ||
| 20 | + output += '&device_id='+deviceInfo.id; | ||
| 21 | + } | ||
| 22 | + if (deviceInfo.hostname) { | ||
| 23 | + output += '&device_hostname='+deviceInfo.hostname; | ||
| 24 | + } | ||
| 25 | + if (deviceInfo.platform) { | ||
| 26 | + output += '&device_platform='+deviceInfo.platform; | ||
| 27 | + } | ||
| 28 | + if (deviceInfo.type) { | ||
| 29 | + output += '&device_type='+deviceInfo.type; | ||
| 30 | + } | ||
| 31 | + if (deviceInfo.release) { | ||
| 32 | + output += '&device_release='+deviceInfo.release; | ||
| 33 | + } | ||
| 34 | + if (deviceInfo.arch) { | ||
| 35 | + output += '&device_arch='+deviceInfo.arch; | ||
| 36 | + } | ||
| 37 | + if (deviceInfo.code) { | ||
| 38 | + output += '®ister_code='+deviceInfo.code; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + // prefixed with & for url | ||
| 42 | + if (!prefixed) { | ||
| 43 | + output = output.substr(1); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + return output; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + register(registerCode: string, deviceInfo:DeviceInfo) : Promise<any> { | ||
| 50 | + return new Promise<any>((resolve, reject) => { | ||
| 51 | + | ||
| 52 | + var headers = new Headers(); | ||
| 53 | + headers.append('Content-Type', 'application/x-www-form-urlencoded'); | ||
| 54 | + deviceInfo.code = registerCode; | ||
| 55 | + | ||
| 56 | + this.http.post(Rest.serviceUrl+"/config/register", | ||
| 57 | + this.prepareDeviceInfo(deviceInfo), | ||
| 58 | + { headers: headers }).subscribe((response:Response) => { | ||
| 59 | + resolve(); | ||
| 60 | + }, (error:Response) => { | ||
| 61 | + if (error.status == 401) { | ||
| 62 | + reject(ERROR_CODE_UNAUTHORIZED); | ||
| 63 | + } else { | ||
| 64 | + reject(ERROR_CODE_SERVER_ERROR); | ||
| 65 | + } | ||
| 66 | + }); | ||
| 67 | + }); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + heartbeat(deviceInfo:DeviceInfo) : Promise<any> { | ||
| 71 | + return new Promise<any>((resolve, reject) => { | ||
| 72 | + | ||
| 73 | + var headers = new Headers(); | ||
| 74 | + headers.append('Content-Type', 'application/x-www-form-urlencoded'); | ||
| 75 | + | ||
| 76 | + this.http.post(Rest.serviceUrl+"/config/heartbeat", | ||
| 77 | + this.prepareDeviceInfo(deviceInfo, false), | ||
| 78 | + { headers: headers }) | ||
| 79 | + .subscribe((response:Response) => { | ||
| 80 | + resolve(response.json()); | ||
| 81 | + },(error:Response) => { | ||
| 82 | + switch (error.status) { | ||
| 83 | + case 401: | ||
| 84 | + reject(ERROR_CODE_UNAUTHORIZED); | ||
| 85 | + break; | ||
| 86 | + case 404: | ||
| 87 | + reject(ERROR_CODE_NOT_FOUND); | ||
| 88 | + break; | ||
| 89 | + default: | ||
| 90 | + reject(ERROR_CODE_SERVER_ERROR); | ||
| 91 | + break; | ||
| 92 | + } | ||
| 93 | + }); | ||
| 94 | + }); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
tsconfig.json
0 → 100644
| 1 | +{ | ||
| 2 | + "compilerOptions": { | ||
| 3 | + "allowSyntheticDefaultImports": true, | ||
| 4 | + "declaration": true, | ||
| 5 | + "experimentalDecorators": true, | ||
| 6 | + "lib": ["dom", "es2015"], | ||
| 7 | + "noImplicitAny": false, | ||
| 8 | + "outDir": "./dist/", | ||
| 9 | + "target": "es5" | ||
| 10 | + }, | ||
| 11 | + "exclude": [ | ||
| 12 | + "node_modules", | ||
| 13 | + "spec" | ||
| 14 | + ] | ||
| 15 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment