0.0.17 • Published 2 years ago

lokapi v0.0.17

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

-- ispell-local-dictionary: "english" --

#+SETUPFILE: ~/.emacs.d/etc/setup/default.setup #+SETUPFILE: ~/.emacs.d/etc/setup/latex.setup #+SETUPFILE: ~/.emacs.d/etc/setup/html-readtheorg-local.setup

#+TITLE: Lokavaluto's LokAPI #+LATEX: \pagebreak

LokAPI is a javascript library intended to be used in mobile applications or web application to abstract all logics with lokavaluto's server.

#+LATEX: \pagebreak #+LATEX: \pagebreak

  • Adding =lokapi= to your project

From the root of your project:

#+begin_src sh npm install --save lokapi #+end_src

Or better, as =lokapi= is still in early release,

#+begin_src sh npm install --save Lokavaluto/lokapi#master #+end_src

To be sure to get the latest version, relaunch this last command whenever you want to update.

  • Setting up =lokapi=

** Subclassing main LokAPIAbstract

Lokapi will require a way to make HTTP request, access to a permanent store, or various other tasks. Depending on your platform or environment, you might have different way to implement these.

To inject these exchangeable dependency, you are invited to subclass LokAPIAbstract and define these objects:

  • httpRequest :: an implementation of =HTTPRequest=
  • base64Encode :: a function to encode a string to base64
  • persistentStore :: an object implementing this interface:

    #+begin_src typescript export interface IPersistentStore { get(key: string, defaultValue?: string): string set(key: string, value: string): void del(key: string): void } #+end_src

  • (optional) requestLogin :: a function to trigger a login screen on authorization failed.

** Instanciating lokapi

On instantiation time, =LokAPI= class will require you to provide:

  • host :: as a =string= (example: "lokavaluto.fr")

  • database :: as a =string= (example: "myodoodb")

*** Example for node

Using node's core =https= as HTTP requestion implementation:

#+begin_src typescript

import https from "https"

import { LokAPIAbstract, e as LokAPIExc, t as LokAPIType } from "lokapi"

class cookieStore implements LokAPIType.IPersistentStore { constructor() { VueCookieNext.config({ expire: '7d' }) } get(key: string, defaultValue?: string): string { return VueCookieNext.getCookie("lokapi" + key) } set(key: string, value: string): void { VueCookieNext.setCookie("lokapi" + key, value) } del(key: string): void { VueCookieNext.removeCookie("lokapi_" + key) } }

class NodeLokAPI extends LokApiAbstract {

httpRequest = (opts: LokAPIType.coreHttpOpts) => {
    if (opts.protocol !== 'https') {
        throw new Error(`Protocol ${opts.protocol} unsupported by this implementation`)
    }
    const httpsOpts: LokAPIType.coreHttpOpts = {
        host: opts.host,
        path: opts.path,
        method: opts.method,
        headers: opts.headers,
    }
    return new Promise((resolve, reject) => {

        let req = https.request(httpsOpts, (res) => {
            const { statusCode } = res

            let rawData = ''

            res.on('data', (chunk) => { rawData += chunk })
            res.on('end', () => {
                if (!statusCode || statusCode.toString().slice(0, 1) !== '2') {
                    res.resume();
                    reject(new LokAPIExc.HttpError(statusCode, res.statusMessage, "", res))
                    return
                } else {
                    resolve(rawData)
                }
            });
        })

        if (opts.data) req.write(JSON.stringify(opts.data))

        req.end();
        req.on('error', (err) => {
            console.error(`Encountered an error trying to make a request: ${err.message}`);
            reject(new LokAPIExc.RequestFailed(err.message))
        });
    })

}

base64Encode = (s: string) => Buffer.from(s).toString('base64')
persistentStore = new cookieStore()

}

if (!process.env.VUE_APP_LOKAPI_HOST) { throw new Error("Please specify VUE_APP_LOKAPI_HOST in '.env'") }

if (!process.env.VUE_APP_LOKAPI_DB) { throw new Error("Please specify VUE_APP_LOKAPI_DB in '.env'") }

var lokAPI = new LokAPI( process.env.VUE_APP_LOKAPI_HOST, process.env.VUE_APP_LOKAPI_DB, ) #+end_src

*** Example for =nativescript=

Using =@nativescript-community/https= as HTTP request implementation:

#+begin_src typescript import * as https from '@nativescript-community/https';

import { LokAPIAbstract, e as LokAPIExc, t as LokAPIType } from "lokapi"

import { getString, remove as removeSetting, setString } from '@nativescript/core/application-settings';

class applicationSetting implements LokAPIType.IPersistentStore { get(key: string, defaultValue?: string): string { return getString("lokapi" + key, defaultValue) } set(key: string, value: string): void { setString("lokapi" + key, value) } del(key: string): void { removeSetting(key) } }

class NativeLokAPI extends LokAPIAbstract {

  httpRequest = async (opts: LokAPIType.coreHttpOpts) => {
      const nativeRequestOpts = {
          url: opts.protocol + "://" + opts.host + opts.path,
          method: opts.method,
          headers: opts.headers,
          body: opts.data,
          useLegacy: true,
      }
      let response
      try {
          response = await https.request(nativeRequestOpts)
      } catch (err) {
          console.error(
              `Encountered an error trying to make a request: ${err.message}`);
          reject(new LokAPIExc.RequestFailed(err.message))
      }

      const statusCode = response.statusCode;
      let rawData = await response.content.toStringAsync();

      if (!statusCode || statusCode.toString().slice(0, 1) !== '2') {
          throw new LokAPIExc.HttpError(statusCode, response.reason, "", response)
      }

      return rawData
  }

  base64Encode = base64Encode
  persistentStore = new applicationSetting()

}

var lokAPI = new NativeLokAPI(APP_HOST, APP_DB)

#+end_src

  • Usage

** Login

You must log in to the server with an existing Odoo Lokavaluto account:

#+begin_src typescript await lokApi.login("myuser", "mypassword") #+end_src

** Accessing accounts

We assume that you've instanciated =LokAPI= as stated in the previous section, and you have logged in.

#+begin_src typescript let accounts = await lokAPI.getAccounts()

let balance = await accounts0.getBalance() let symbol= await accounts0.getSymbol()

console.log(balance in first account: ${balance} ${symbol}) #+end_src

  • =backend.getAccounts()= is the list of accounts in that connection (warning, this is a promise).

  • =account.getBalance()= is the balance of the account

  • =account.getSymbol()= is the currency symbol for the account

** Looking for recipients

Recipient are possible receiving end of a transfer of money. These are connected to identities in lokapi.

#+begin_src typescript let recipients = await lokAPI.searchRecipients("Alain")

recipients.forEach(recipient => { console.log(name: ${recipient.name}) }) #+end_src

** Transfer money between an account to a recipient

Transfering money is done from an account of the logged-in user to a recipient:

#+begin_src typescript // Get my accounts let accounts = await lokAPI.getAccounts()

// Fetch recipients named 'Alain' let recipients = await lokAPI.searchRecipients("Alain")

await lokAPI.transfer(accounts0, recipients0, "12", "Dinner Party participation") // or: await accounts0.transfer(recipients0, "13", "Coffee")

#+end_src

** Requesting info on given partner

The method =lokAPI.getUserInfo(userId?: number)= allows you to get back user info given it's user id. If you don't provide this user id, you'll get your own information. This is useful especially if you don't know yet your own =userId=:

#+begin_src typescript

let partnerId = 9

let userInfo = await lokAPI.getUserInfo(partnerId) console.log(Partner 9 name: ${userInfo.name})

// My own information let myOwnInfo = await lokAPI.getUserInfo() console.log(My user id: ${myOwnInfo.id})

#+end_src

** Setting/Unsetting Favorite status of a contact

You can set or unset the "favorite" state of a given contact with the =lokAPI.setFavorite(..)=, =lokAPI.unsetFavorite(..)=, or =lokAPI.toggleFavorite(..)= method. The argument can be a recipient (from =.searchRecipients()=) or a contact (from =.getUserInfo()=).

It'll return a new contact with the updated information.

#+begin_src typescript let recipients = await lokAPI.searchRecipients("Alain")

await lokAPI.setFavorite(recipients2) await lokAPI.unsetFavorite(recipients3) #+end_src

** List transactions

List past transactions for the current logged in user.

#+begin_src typescript let transactions = await $lokapi.getTransactions()

transactions.forEach((tr:any) => { console.log(${tr.date} ${tr.amount} ${tr.currency}) }) #+end_src

** Direct request to odoo api

You can use =lokapi= instance to query directly the odoo api trough the =get=, =post=, =put=, =delete= methods and their authenticated counterparts, =$get=, =$post=, =$put=, =$delete=.

#+begin_src typescript

// All 8 methods have this signature: // type restMethod = (path: string, data?: any, headers?: any) => any

// Notice that the next call is an example, but you don't need to // use this endpoint as it is used by the lokAPI.login() and // manages token for you. lokAPI.post('/auth/authenticate', { api_version: 2, db: 'mydb', params: 'lcc_app' }, { 'Authorization': '', })

lokAPI.$post(/partner/${userId}) lokAPI.$post(/partner/favorite) lokAPI.$post(/partner/${userId}/toggle_favorite) #+end_src

0.0.17

2 years ago

0.0.16

3 years ago

0.0.15

3 years ago

0.0.14

3 years ago

0.0.12

3 years ago

0.0.11

3 years ago

0.0.10

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.5

3 years ago

0.0.3

3 years ago

0.0.4

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago