Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -804,3 +804,31 @@ Please note that =.get(..)= and =.$get(..)= have same prototype
and usage than other function and do not require you to build a query
string as it'll encode in the URL as a querystring the data you've
provided.

* Contributing to Lokapi

This package is using ~npm~ to track dependendies, so you can install them
with:

#+begin_src sh
npm install
#+end_src

As this package is written in =typescript=. You can transpile to
=javascript= and transpile on file change with:

#+begin_src sh
## Compile and watch
npx tspc -w
#+end_src

Tests are managed through =vitest=


#+begin_src sh
## Run test once
npm run test
#+end_src

Note that you can also use ~npx vitest~ command to launch tests in
watch mode.
62 changes: 32 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
{
"name": "@lokavaluto/lokapi",
"version": "%%version%%",
"description": "Lokavaluto API",
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
"prepare": "tsc",
"lint": "eslint --ignore-path .gitignore --ext .js,.ts .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Valentin LAB",
"license": "MIT",
"repository": {
"type": "git",
"url": "git@github.com:Lokavaluto/lokapi.git"
},
"devDependencies": {
"@0k/prettier": "^0.2.1",
"@types/node": "^15.12.2",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"typedoc": "^0.22.8",
"typescript": "^4.4.4"
},
"dependencies": {
"@0k/types-request": "^1.0.0",
"qs": "^6.10.1"
}
"name": "@lokavaluto/lokapi",
"version": "0.1.1-alpha.202505101504",
"description": "Lokavaluto API",
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
"prepare": "tsc",
"lint": "eslint --ignore-path .gitignore --ext .js,.ts .",
"test": "vitest run"
},
"author": "Valentin LAB",
"license": "MIT",
"repository": {
"type": "git",
"url": "git@github.com:Lokavaluto/lokapi.git"
},
"devDependencies": {
"@0k/prettier": "^0.2.1",
"@types/node": "^22.15.3",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"jsdom": "^26.1.0",
"typedoc": "^0.22.8",
"typescript": "^4.7.4",
"vitest": "^3.1.2"
},
"dependencies": {
"@0k/types-request": "^1.0.0",
"qs": "^6.10.1"
}
}
5 changes: 4 additions & 1 deletion src/backend/odoo/account.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as t from '../../type'

import { BridgeObject } from '..'


export default class Account extends BridgeObject {
export default abstract class Account extends BridgeObject {

public async getPendingTopUp() {
let requests = await this.backends.odoo.$get(
Expand All @@ -12,4 +14,5 @@ export default class Account extends BridgeObject {
requests.map((e: any) => this.parent.makeCreditRequest(e))
)
}

}
31 changes: 31 additions & 0 deletions src/backend/odoo/recipient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as t from '../../type'

import { Contact } from './contact'
import UserAccount from './userAccount'


export default abstract class Recipient extends Contact {

abstract fromUserAccount: UserAccount
abstract walletInternalId: string

/**
* Request if administrative backend allows current account to
* transfer to given recipient account.
*
* @throws {RequestFailed, APIRequestFailed, InvalidCredentials, InvalidJson}
*
* @param recipient The recipient to which we check if transfer is allowed
*
* @returns boolean
*/
public async isTransferAllowedByAdministrativeBackend (): Promise<Boolean> {
debugger
const backendType = this.backendId.split(":")[0]
return await this.backends.odoo.$get('/partner/is_transaction_allowed', {
sender_wallet_ident: this.fromUserAccount.internalId,
recipient_wallet_ident: this.walletInternalId
})
}

}
6 changes: 5 additions & 1 deletion src/backend/odoo/userAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import { BridgeObject } from '..'
import { t } from '../..'


export default class UserAccount extends BridgeObject {
export default abstract class UserAccount extends BridgeObject {

abstract internalId: string

get isTopUpAllowed() {
return this.jsonData?.is_topup_allowed !== false
}

}
43 changes: 43 additions & 0 deletions src/exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,46 @@ export class CanceledOperation extends Error {
this.name = 'CanceledOperation'
}
}

// Payment exceptions

export class PrepareTransferError extends Error {
constructor (message) {
super(message)
this.name = 'PrepareTransferError'
}
}

export class PrepareTransferException extends PrepareTransferError {

origException: Error

constructor (message, origException?: Error) {
super(message)
this.name = 'PrepareTransferException'
this.origException = origException
}
}

export class PrepareTransferAmountError extends PrepareTransferError {
constructor (message) {
super(message)
this.name = 'PrepareTransferAmountError'
}
}

export class PrepareTransferInsufficientBalance extends PrepareTransferError {
constructor (message) {
super(message)
this.name = 'PrepareTransferInsufficientBalance'
}
}

export class PrepareTransferUnsafeBalance extends PrepareTransferError {
realBal: number
constructor (message, realBal) {
super(message)
this.name = 'PrepareTransferUnsafeBalance'
this.realBal
}
}
5 changes: 3 additions & 2 deletions src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ export interface IContact extends IBridge {


export interface IRecipient extends IContact {
walletInternalId: string
transfer(amount: number,
senderMemo: string,
recipientMemo: string): Promise<ITransaction>
recipientMemo: string): Promise<ITransaction[]>
}


Expand All @@ -107,7 +108,7 @@ export interface IAccount extends IBridge {
transfer(recipient: IRecipient,
amount: number,
senderMemo: string,
recipientMemo: string): Promise<ITransaction>
recipientMemo: string): Promise<ITransaction[]>
}


Expand Down
27 changes: 27 additions & 0 deletions tests/environment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Environment } from 'vitest'

export default <Environment>{
name: 'custom',
transformMode: 'ssr',
// optional - only if you support "experimental-vm" pool
async setupVM() {
const vm = await import('node:vm')
const context = vm.createContext()
return {
getVmContext() {
return context
},
teardown() {
// called after all tests with this env have been run
}
}
},
setup() {
// custom setup
return {
teardown() {
// called after all tests with this env have been run
}
}
}
}
11 changes: 11 additions & 0 deletions tests/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Buffer } from 'buffer'
import { afterAll, beforeAll } from 'vitest';

beforeAll(() => {
// global.Buffer = Buffer
});

afterAll(() => {
// delete global.Buffer
});

8 changes: 7 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@
"outDir": "build",
"paths": {
"*": ["src/types/*"]
}
},
"types": [
"vitest/importMeta"
],
"plugins": [
{ "transform": "./skip-prod-transpilation.ts" }
]
},
"typedocOptions": {
"name": "LokAPI",
Expand Down
14 changes: 14 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite'

const cfg = defineConfig({
test: {
include: ['src/**/*.{js,ts}'],
setupFiles: ['./tests/setup.ts'],
environment: 'jsdom',
passWithNoTests: true,
bail: 1,
},
})

export default cfg