Merge remote-tracking branch 'xo-lib/master'
This commit is contained in:
commit
060ba6423e
65
packages/xo-lib/.editorconfig
Normal file
65
packages/xo-lib/.editorconfig
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# http://EditorConfig.org
|
||||||
|
#
|
||||||
|
# Julien Fontanet's configuration
|
||||||
|
# https://gist.github.com/julien-f/8096213
|
||||||
|
|
||||||
|
# Top-most EditorConfig file.
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Common config.
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespaces = true
|
||||||
|
|
||||||
|
# CoffeeScript
|
||||||
|
#
|
||||||
|
# https://github.com/polarmobile/coffeescript-style-guide/blob/master/README.md
|
||||||
|
[*.{,lit}coffee]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# Markdown
|
||||||
|
[*.{md,mdwn,mdown,markdown}]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# Package.json
|
||||||
|
#
|
||||||
|
# This indentation style is the one used by npm.
|
||||||
|
[/package.json]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# Jade
|
||||||
|
[*.jade]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# JavaScript
|
||||||
|
#
|
||||||
|
# Two spaces seems to be the standard most common style, at least in
|
||||||
|
# Node.js (http://nodeguide.com/style.html#tabs-vs-spaces).
|
||||||
|
[*.js]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# Less
|
||||||
|
[*.less]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# Sass
|
||||||
|
#
|
||||||
|
# Style used for http://libsass.com
|
||||||
|
[*.s[ac]ss]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# YAML
|
||||||
|
#
|
||||||
|
# Only spaces are allowed.
|
||||||
|
[*.yaml]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
7
packages/xo-lib/.gitignore
vendored
Normal file
7
packages/xo-lib/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/dist/
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
|
npm-debug.log
|
||||||
|
npm-debug.log.*
|
||||||
|
pnpm-debug.log
|
||||||
|
pnpm-debug.log.*
|
10
packages/xo-lib/.npmignore
Normal file
10
packages/xo-lib/.npmignore
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/examples/
|
||||||
|
example.js
|
||||||
|
example.js.map
|
||||||
|
*.example.js
|
||||||
|
*.example.js.map
|
||||||
|
|
||||||
|
/test/
|
||||||
|
/tests/
|
||||||
|
*.spec.js
|
||||||
|
*.spec.js.map
|
9
packages/xo-lib/.travis.yml
Normal file
9
packages/xo-lib/.travis.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- stable
|
||||||
|
- 6
|
||||||
|
- 4
|
||||||
|
|
||||||
|
# Use containers.
|
||||||
|
# http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||||
|
sudo: false
|
168
packages/xo-lib/README.md
Normal file
168
packages/xo-lib/README.md
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# xo-lib [](https://travis-ci.org/vatesfr/xo-lib)
|
||||||
|
|
||||||
|
> Library to connect to XO-Server.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Installation of the [npm package](https://npmjs.org/package/xo-lib):
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install --save xo-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
Then require the package:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import Xo from 'xo-lib'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
> If the URL is not provided and the current environment is a web
|
||||||
|
> browser, the location of the current page will be used.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Connect to XO.
|
||||||
|
const xo = new Xo({ url: 'https://xo.company.tld' })
|
||||||
|
|
||||||
|
// Let's start by opening the connection.
|
||||||
|
await xo.open()
|
||||||
|
|
||||||
|
// Must sign in before being able to call any methods (all calls will
|
||||||
|
// be buffered until signed in).
|
||||||
|
await xo.signIn({
|
||||||
|
email: 'admin@admin.net',
|
||||||
|
password: 'admin'
|
||||||
|
})
|
||||||
|
|
||||||
|
console('signed as', xo.user)
|
||||||
|
```
|
||||||
|
|
||||||
|
The credentials can also be passed directly to the constructor:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const xo = Xo({
|
||||||
|
url: 'https://xo.company.tld',
|
||||||
|
credentials: {
|
||||||
|
email: 'admin@admin.net',
|
||||||
|
password: 'admin',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
xo.open()
|
||||||
|
|
||||||
|
xo.on('authenticated', () => {
|
||||||
|
console.log(xo.user)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
> If the URL is not provided and the current environment is a web
|
||||||
|
> browser, the location of the current page will be used.
|
||||||
|
|
||||||
|
### Connection
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
await xo.open()
|
||||||
|
|
||||||
|
console.log('connected')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disconnection
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
xo.close()
|
||||||
|
|
||||||
|
console.log('disconnected')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method call
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const token = await xo.call('token.create')
|
||||||
|
|
||||||
|
console.log('Token created', token)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
The connection status is available through the status property which
|
||||||
|
is *open*, *connecting* or *closed*.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
console.log('%s to xo-server', xo.status)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Current user
|
||||||
|
|
||||||
|
Information about the user account used to sign in is available
|
||||||
|
through the `user` property.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
console.log('Current user is', xo.user)
|
||||||
|
```
|
||||||
|
|
||||||
|
> This property is null when the status is not connected.
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
xo.on('open', () => {
|
||||||
|
console.log('connected')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
xo.on('closed', () => {
|
||||||
|
console.log('disconnected')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
xo.on('notification', function (notif) {
|
||||||
|
console.log('notification:', notif.method, notif.params)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
xo.on('authenticated', () => {
|
||||||
|
console.log('authenticated as', xo.user)
|
||||||
|
})
|
||||||
|
|
||||||
|
xo.on('authenticationFailure', () => {
|
||||||
|
console.log('failed to authenticate')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```
|
||||||
|
# Install dependencies
|
||||||
|
> npm install
|
||||||
|
|
||||||
|
# Run the tests
|
||||||
|
> npm test
|
||||||
|
|
||||||
|
# Continuously compile
|
||||||
|
> npm run dev
|
||||||
|
|
||||||
|
# Continuously run the tests
|
||||||
|
> npm run dev-test
|
||||||
|
|
||||||
|
# Build for production (automatically called by npm install)
|
||||||
|
> npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributions
|
||||||
|
|
||||||
|
Contributions are *very* welcomed, either on the documentation or on
|
||||||
|
the code.
|
||||||
|
|
||||||
|
You may:
|
||||||
|
|
||||||
|
- report any [issue](https://github.com/vatesfr/xo-lib/issues)
|
||||||
|
you've encountered;
|
||||||
|
- fork and create a pull request.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
ISC © [Vates SAS](http://vates.fr)
|
45
packages/xo-lib/example.js
Normal file
45
packages/xo-lib/example.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.on('unhandledRejection', function (error) {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
var Xo = require('./').default
|
||||||
|
|
||||||
|
var xo = new Xo({
|
||||||
|
url: 'localhost:9000'
|
||||||
|
})
|
||||||
|
|
||||||
|
xo.open().then(function () {
|
||||||
|
return xo.call('acl.get', {}).then(function (result) {
|
||||||
|
console.log('success:', result)
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('failure:', error)
|
||||||
|
})
|
||||||
|
}).then(function () {
|
||||||
|
return xo.signIn({
|
||||||
|
email: 'admin@admin.net',
|
||||||
|
password: 'admin'
|
||||||
|
}).then(function () {
|
||||||
|
console.log('connected as ', xo.user)
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('failure:', error)
|
||||||
|
})
|
||||||
|
}).then(function () {
|
||||||
|
return xo.signIn({
|
||||||
|
email: 'tom',
|
||||||
|
password: 'tom'
|
||||||
|
}).then(function () {
|
||||||
|
console.log('connected as', xo.user)
|
||||||
|
|
||||||
|
return xo.call('acl.get', {}).then(function (result) {
|
||||||
|
console.log('success:', result)
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('failure:', error)
|
||||||
|
})
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('failure', error)
|
||||||
|
})
|
||||||
|
}).then(function () {
|
||||||
|
return xo.close()
|
||||||
|
})
|
86
packages/xo-lib/package.json
Normal file
86
packages/xo-lib/package.json
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"name": "xo-lib",
|
||||||
|
"version": "0.8.2",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "Library to connect to XO-Server",
|
||||||
|
"keywords": [
|
||||||
|
"xen",
|
||||||
|
"orchestra",
|
||||||
|
"xen-orchestra"
|
||||||
|
],
|
||||||
|
"homepage": "https://github.com/vatesfr/xo-lib",
|
||||||
|
"bugs": "https://github.com/vatesfr/xo-lib/issues",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/vatesfr/xo-lib"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "Julien Fontanet",
|
||||||
|
"email": "julien.fontanet@vates.fr"
|
||||||
|
},
|
||||||
|
"preferGlobal": false,
|
||||||
|
"main": "dist/",
|
||||||
|
"bin": {},
|
||||||
|
"files": [
|
||||||
|
"dist/"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jsonrpc-websocket-client": "^0.1.2",
|
||||||
|
"lodash": "^4.17.2",
|
||||||
|
"make-error": "^1.0.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-cli": "^6.18.0",
|
||||||
|
"babel-eslint": "^7.1.1",
|
||||||
|
"babel-plugin-lodash": "^3.2.9",
|
||||||
|
"babel-preset-env": "^1.0.1",
|
||||||
|
"babel-preset-stage-0": "^6.16.0",
|
||||||
|
"cross-env": "^3.1.3",
|
||||||
|
"dependency-check": "^2.6.0",
|
||||||
|
"ghooks": "^1.3.2",
|
||||||
|
"rimraf": "^2.5.4",
|
||||||
|
"standard": "^8.5.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
|
||||||
|
"clean": "rimraf dist/",
|
||||||
|
"depcheck": "dependency-check ./package.json",
|
||||||
|
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
|
||||||
|
"lint": "standard",
|
||||||
|
"posttest": "npm run lint && npm run depcheck",
|
||||||
|
"prebuild": "npm run clean",
|
||||||
|
"predev": "npm run clean",
|
||||||
|
"prepublish": "npm run build"
|
||||||
|
},
|
||||||
|
"babel": {
|
||||||
|
"plugins": [
|
||||||
|
"lodash"
|
||||||
|
],
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"browsers": "> 2%",
|
||||||
|
"node": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"standard": {
|
||||||
|
"ignore": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"ghooks": {
|
||||||
|
"commit-msg": "npm test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
packages/xo-lib/src/index.js
Normal file
83
packages/xo-lib/src/index.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import JsonRpcWebSocketClient, {
|
||||||
|
OPEN,
|
||||||
|
CLOSED
|
||||||
|
} from 'jsonrpc-websocket-client'
|
||||||
|
import { BaseError } from 'make-error'
|
||||||
|
import { startsWith } from 'lodash'
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
const noop = () => {}
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
export class XoError extends BaseError {}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
export default class Xo extends JsonRpcWebSocketClient {
|
||||||
|
constructor (opts) {
|
||||||
|
const url = opts && opts.url || '.'
|
||||||
|
super(`${url === '/' ? '' : url}/api/`)
|
||||||
|
|
||||||
|
this._credentials = opts && opts.credentials || null
|
||||||
|
this._user = null
|
||||||
|
|
||||||
|
this.on(OPEN, () => {
|
||||||
|
if (this._credentials) {
|
||||||
|
this._signIn(this._credentials).catch(noop)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.on(CLOSED, () => {
|
||||||
|
this._user = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get user () {
|
||||||
|
return this._user
|
||||||
|
}
|
||||||
|
|
||||||
|
call (method, args, i) {
|
||||||
|
if (startsWith(method, 'session.')) {
|
||||||
|
return Promise.reject(
|
||||||
|
new XoError('session.*() methods are disabled from this interface')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const promise = super.call(method, args)
|
||||||
|
promise.retry = (predicate) => promise.catch((error) => {
|
||||||
|
i = (i || 0) + 1
|
||||||
|
if (predicate(error, i)) {
|
||||||
|
return this.call(method, args, i)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshUser () {
|
||||||
|
return super.call('session.getUser').then(user => {
|
||||||
|
return (this._user = user)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
signIn (credentials) {
|
||||||
|
// Register this credentials for future use.
|
||||||
|
this._credentials = credentials
|
||||||
|
|
||||||
|
return this._signIn(credentials)
|
||||||
|
}
|
||||||
|
|
||||||
|
_signIn (credentials) {
|
||||||
|
return super.call('session.signIn', credentials).then(
|
||||||
|
user => {
|
||||||
|
this._user = user
|
||||||
|
this.emit('authenticated')
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.emit('authenticationFailure', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user