@pax2pay/model-banking 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Account/Creatable.ts +9 -0
- package/Account/index.ts +43 -0
- package/Balances/index.ts +25 -0
- package/Event/index.ts +66 -0
- package/Operation/Creatable.ts +81 -0
- package/Operation/index.ts +69 -0
- package/Organization/Creatable.ts +9 -0
- package/Organization/index.ts +23 -0
- package/README.md +2 -2
- package/Rail/Iban.ts +11 -0
- package/Rail/PaxGiro.ts +12 -0
- package/Rail/Type.ts +1 -0
- package/Rail/index.ts +57 -0
- package/Rail/internal.ts +12 -0
- package/Transaction/Creatable.ts +28 -0
- package/Transaction/index.ts +50 -0
- package/dist/Account/Creatable.d.ts +6 -0
- package/dist/Account/Creatable.js +8 -0
- package/dist/Account/Creatable.js.map +1 -0
- package/dist/Account/index.d.ts +23 -0
- package/dist/Account/index.js +37 -0
- package/dist/Account/index.js.map +1 -0
- package/dist/Balances/index.d.ts +9 -0
- package/dist/Balances/index.js +19 -0
- package/dist/Balances/index.js.map +1 -0
- package/dist/Event/index.d.ts +33 -0
- package/dist/Event/index.js +65 -0
- package/dist/Event/index.js.map +1 -0
- package/dist/Operation/Creatable.d.ts +48 -0
- package/dist/Operation/Creatable.js +61 -0
- package/dist/Operation/Creatable.js.map +1 -0
- package/dist/Operation/index.d.ts +16 -0
- package/dist/Operation/index.js +56 -0
- package/dist/Operation/index.js.map +1 -0
- package/dist/Organization/Creatable.d.ts +6 -0
- package/dist/Organization/Creatable.js +8 -0
- package/dist/Organization/Creatable.js.map +1 -0
- package/dist/Organization/index.d.ts +11 -0
- package/dist/Organization/index.js +19 -0
- package/dist/Organization/index.js.map +1 -0
- package/dist/Rail/Iban.d.ts +8 -0
- package/dist/Rail/Iban.js +9 -0
- package/dist/Rail/Iban.js.map +1 -0
- package/dist/Rail/PaxGiro.d.ts +9 -0
- package/dist/Rail/PaxGiro.js +10 -0
- package/dist/Rail/PaxGiro.js.map +1 -0
- package/dist/Rail/Type.d.ts +1 -0
- package/dist/Rail/Type.js +2 -0
- package/dist/Rail/Type.js.map +1 -0
- package/dist/Rail/index.d.ts +17 -0
- package/dist/Rail/index.js +41 -0
- package/dist/Rail/index.js.map +1 -0
- package/dist/Rail/internal.d.ts +9 -0
- package/dist/Rail/internal.js +10 -0
- package/dist/Rail/internal.js.map +1 -0
- package/dist/Transaction/Creatable.d.ts +14 -0
- package/dist/Transaction/Creatable.js +19 -0
- package/dist/Transaction/Creatable.js.map +1 -0
- package/dist/Transaction/index.d.ts +20 -0
- package/dist/Transaction/index.js +37 -0
- package/dist/Transaction/index.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/index.ts +7 -1
- package/package.json +15 -10
package/Account/index.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
import * as isoly from "isoly"
|
|
3
|
+
import { Balances } from "../Balances"
|
|
4
|
+
import { Rail } from "../Rail"
|
|
5
|
+
import { Creatable as AccountCreatable } from "./Creatable"
|
|
6
|
+
|
|
7
|
+
export interface Account extends Account.Creatable {
|
|
8
|
+
readonly id: cryptly.Identifier
|
|
9
|
+
readonly created: isoly.DateTime
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export namespace Account {
|
|
13
|
+
export function fromCreatable(account: Creatable): Account {
|
|
14
|
+
return {
|
|
15
|
+
...account,
|
|
16
|
+
id: cryptly.Identifier.generate(8),
|
|
17
|
+
created: isoly.DateTime.now(),
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function is(account: Account | any): account is Account {
|
|
21
|
+
return (
|
|
22
|
+
Account.Creatable.is({ ...account }) && cryptly.Identifier.is(account.id, 8) && isoly.DateTime.is(account.created)
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
export function isIdentifier(value: cryptly.Identifier | any): value is cryptly.Identifier {
|
|
26
|
+
return cryptly.Identifier.is(value, 8)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type Creatable = AccountCreatable
|
|
30
|
+
export const Creatable = AccountCreatable
|
|
31
|
+
export type Info = Account & { rails: Rail[]; balances: Balances }
|
|
32
|
+
export namespace Info {
|
|
33
|
+
export function is(value: Info | any): value is Info {
|
|
34
|
+
return (
|
|
35
|
+
typeof value == "object" &&
|
|
36
|
+
Account.is({ ...value }) &&
|
|
37
|
+
Array.isArray(value.rails) &&
|
|
38
|
+
value.rails.every((r: any) => Rail.is(r)) &&
|
|
39
|
+
Balances.is(value.balances)
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as isoly from "isoly"
|
|
2
|
+
|
|
3
|
+
export type Balances = Partial<Record<isoly.Currency, Partial<Record<Balances.Entry, number>>>>
|
|
4
|
+
|
|
5
|
+
export namespace Balances {
|
|
6
|
+
export function is(value: Balances | any): value is Balances {
|
|
7
|
+
return (
|
|
8
|
+
typeof value == "object" &&
|
|
9
|
+
Object.entries(value).every(
|
|
10
|
+
([k, v]) =>
|
|
11
|
+
isoly.Currency.is(k) &&
|
|
12
|
+
typeof v == "object" &&
|
|
13
|
+
Object.entries(v as Record<string, unknown>).every(
|
|
14
|
+
([kInner, vInner]) => Balances.Entry.is(kInner) && typeof vInner == "number"
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
export type Entry = "actual" | "reserved"
|
|
20
|
+
export namespace Entry {
|
|
21
|
+
export function is(value: any | Entry): value is Entry {
|
|
22
|
+
return typeof value == "string" && (value == "actual" || value == "reserved")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/Event/index.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Account as modelAccount } from "../Account"
|
|
2
|
+
import { Operation as modelOperation } from "../Operation"
|
|
3
|
+
import { Organization as modelOrganization } from "../Organization"
|
|
4
|
+
import { Rail as modelRail } from "../Rail"
|
|
5
|
+
import { Transaction as modelTransaction } from "../Transaction"
|
|
6
|
+
|
|
7
|
+
export interface Event {
|
|
8
|
+
organization?: string
|
|
9
|
+
account?: string
|
|
10
|
+
entity: Entity
|
|
11
|
+
action: string
|
|
12
|
+
data: any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Entity = "account" | "transaction" | "operation" | "rail" | "organization" | "authorization"
|
|
16
|
+
export namespace Event {
|
|
17
|
+
export namespace Account {
|
|
18
|
+
export function created(account: modelAccount, organization: string): Event {
|
|
19
|
+
return { organization: organization, entity: "account", action: "created", data: account }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export namespace Operation {
|
|
23
|
+
export function performed(operation: modelOperation, organization: string, account: string): Event {
|
|
24
|
+
return { organization: organization, account: account, entity: "operation", action: "performed", data: operation }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export namespace Organization {
|
|
28
|
+
export function created(organization: modelOrganization): Event {
|
|
29
|
+
return { entity: "organization", action: "created", data: organization }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export namespace Rail {
|
|
33
|
+
export function added(rail: modelRail, organization: string, account: string): Event {
|
|
34
|
+
return { organization: organization, account: account, entity: "rail", action: "added", data: rail }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export namespace Transaction {
|
|
38
|
+
export function initiated(transaction: modelTransaction, organization: string, account: string): Event {
|
|
39
|
+
return {
|
|
40
|
+
organization: organization,
|
|
41
|
+
account: account,
|
|
42
|
+
entity: "transaction",
|
|
43
|
+
action: "initiated",
|
|
44
|
+
data: transaction,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function settled(transaction: modelTransaction, organization: string, account: string): Event {
|
|
48
|
+
return {
|
|
49
|
+
organization: organization,
|
|
50
|
+
account: account,
|
|
51
|
+
entity: "transaction",
|
|
52
|
+
action: "settled",
|
|
53
|
+
data: transaction,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function incoming(transaction: modelTransaction, organization: string, account: string): Event {
|
|
57
|
+
return {
|
|
58
|
+
organization: organization,
|
|
59
|
+
account: account,
|
|
60
|
+
entity: "transaction",
|
|
61
|
+
action: "incoming",
|
|
62
|
+
data: transaction,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as isoly from "isoly"
|
|
2
|
+
import { Balances } from "../Balances"
|
|
3
|
+
|
|
4
|
+
export type OperationStatus = "pending" | "success" | "failed" //| "cancelled"
|
|
5
|
+
|
|
6
|
+
type ChangeType = { type: "add" | "subtract"; amount: number; status: OperationStatus }
|
|
7
|
+
export type Change = Partial<Record<Balances.Entry, ChangeType>>
|
|
8
|
+
|
|
9
|
+
export namespace Change {
|
|
10
|
+
export function is(value: any | Change): value is Change {
|
|
11
|
+
return (
|
|
12
|
+
typeof value == "object" &&
|
|
13
|
+
(value.actual == undefined || isChangeType(value.actual)) &&
|
|
14
|
+
(value.reserved == undefined || isChangeType(value.reserved)) &&
|
|
15
|
+
(value.actual || value.reserved)
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
export function isChangeType(value: ChangeType | any): value is ChangeType {
|
|
19
|
+
return (
|
|
20
|
+
typeof value == "object" &&
|
|
21
|
+
typeof value.amount == "number" &&
|
|
22
|
+
value.amount > 0 &&
|
|
23
|
+
(value.type == "add" || value.type == "subtract") &&
|
|
24
|
+
typeof value.status == "string" &&
|
|
25
|
+
(value.status == "pending" || value.status == "success" || value.status == "failed")
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
export type Reservation = { reserved: { type: "add"; amount: number } }
|
|
29
|
+
export type Deposit = { actual: { type: "add"; amount: number } }
|
|
30
|
+
export type Finalization = {
|
|
31
|
+
reserved: { type: "subtract"; amount: number }
|
|
32
|
+
actual: { type: "subtract"; amount: number }
|
|
33
|
+
}
|
|
34
|
+
export function isReservation(value: Reservation | any): value is Reservation {
|
|
35
|
+
return (
|
|
36
|
+
Change.is({ ...value }) &&
|
|
37
|
+
value.actual == undefined &&
|
|
38
|
+
typeof value.reserved == "object" &&
|
|
39
|
+
value.reserved.type == "add"
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
export function isDeposit(value: Deposit | any): value is Deposit {
|
|
43
|
+
return (
|
|
44
|
+
Change.is({ ...value }) &&
|
|
45
|
+
value.reserved == undefined &&
|
|
46
|
+
typeof value.actual == "object" &&
|
|
47
|
+
value.actual.type == "add"
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
export function isFinalization(value: Finalization | any): value is Finalization {
|
|
51
|
+
return (
|
|
52
|
+
Change.is({ ...value }) &&
|
|
53
|
+
typeof value.actual == "object" &&
|
|
54
|
+
value.actual.type == "subtract" &&
|
|
55
|
+
typeof value.reserved == "object" &&
|
|
56
|
+
value.reserved.type == "subtract"
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Creatable {
|
|
62
|
+
currency: isoly.Currency
|
|
63
|
+
change: Change
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export namespace Creatable {
|
|
67
|
+
export function is(value: any | Creatable): value is Creatable {
|
|
68
|
+
return (
|
|
69
|
+
typeof value == "object" &&
|
|
70
|
+
isoly.Currency.is(value.currency) &&
|
|
71
|
+
typeof value.change == "object" &&
|
|
72
|
+
Change.is(value.change)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
export function openReservation(currency: isoly.Currency, amount: number): Creatable {
|
|
76
|
+
return { currency: currency, change: { reserved: { type: "add", amount: amount, status: "pending" } } }
|
|
77
|
+
}
|
|
78
|
+
export function openDeposit(currency: isoly.Currency, amount: number): Creatable {
|
|
79
|
+
return { currency: currency, change: { actual: { type: "add", amount: amount, status: "pending" } } }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
import * as gracely from "gracely"
|
|
3
|
+
import * as isoly from "isoly"
|
|
4
|
+
import { Creatable as OperationCreatable } from "./Creatable"
|
|
5
|
+
|
|
6
|
+
export interface Operation extends OperationCreatable {
|
|
7
|
+
id: cryptly.Identifier
|
|
8
|
+
created: isoly.DateTime
|
|
9
|
+
//index?: number
|
|
10
|
+
}
|
|
11
|
+
export namespace Operation {
|
|
12
|
+
export function is(value: any | Operation): value is Operation {
|
|
13
|
+
return (
|
|
14
|
+
typeof value == "object" &&
|
|
15
|
+
cryptly.Identifier.is(value.id, 8) &&
|
|
16
|
+
isoly.DateTime.is(value.created) &&
|
|
17
|
+
OperationCreatable.is({ ...value })
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
export function fromCreatable(operation: Creatable): Operation {
|
|
21
|
+
const id = cryptly.Identifier.generate(8)
|
|
22
|
+
const timestamp = isoly.DateTime.now()
|
|
23
|
+
return {
|
|
24
|
+
...operation,
|
|
25
|
+
id: id,
|
|
26
|
+
created: timestamp,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function reverse(operation: Operation): Operation {
|
|
31
|
+
const id = cryptly.Identifier.generate(8)
|
|
32
|
+
const timestamp = isoly.DateTime.now()
|
|
33
|
+
const reverseChange = Object.fromEntries(
|
|
34
|
+
Object.entries(operation.change)
|
|
35
|
+
.filter(([k, v]) => v.status == "success")
|
|
36
|
+
.map(([k, v]) => [k, { type: v.type == "add" ? "subtract" : "add", amount: v.amount, status: "pending" }])
|
|
37
|
+
)
|
|
38
|
+
return {
|
|
39
|
+
...operation,
|
|
40
|
+
id: id,
|
|
41
|
+
created: timestamp,
|
|
42
|
+
change: reverseChange,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function openFinalization(reservation: Operation): Operation | gracely.Error {
|
|
46
|
+
return typeof reservation.change.actual == "object" ||
|
|
47
|
+
typeof reservation.change.reserved == "undefined" ||
|
|
48
|
+
reservation.change.reserved.status == "failed"
|
|
49
|
+
? gracely.client.invalidContent("Operation", "Amount is not reserved.")
|
|
50
|
+
: {
|
|
51
|
+
id: cryptly.Identifier.generate(8),
|
|
52
|
+
created: isoly.DateTime.now(),
|
|
53
|
+
currency: reservation.currency,
|
|
54
|
+
change: {
|
|
55
|
+
actual: { type: "subtract", amount: reservation.change.reserved.amount, status: "pending" },
|
|
56
|
+
reserved: { type: "subtract", amount: reservation.change.reserved.amount, status: "pending" },
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// export function id(operation: Operation): string {
|
|
62
|
+
// return `${operation.created}/${operation.id}`
|
|
63
|
+
// }
|
|
64
|
+
|
|
65
|
+
export type Creatable = OperationCreatable
|
|
66
|
+
export const Creatable = OperationCreatable
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//export { ChangeType, Change }
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
import { Creatable as OrganizationCreatable } from "./Creatable"
|
|
3
|
+
|
|
4
|
+
export interface Organization extends OrganizationCreatable {
|
|
5
|
+
readonly id: cryptly.Identifier
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export namespace Organization {
|
|
9
|
+
export function is(value: Organization | any): value is Organization {
|
|
10
|
+
return !!(
|
|
11
|
+
value &&
|
|
12
|
+
typeof value == "object" &&
|
|
13
|
+
cryptly.Identifier.is(value.id, 8) &&
|
|
14
|
+
typeof value.name == "string" &&
|
|
15
|
+
typeof value.value == "number"
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
export function fromCreatable(organization: Creatable): Organization {
|
|
19
|
+
return { ...organization, id: cryptly.Identifier.generate(8) }
|
|
20
|
+
}
|
|
21
|
+
export type Creatable = OrganizationCreatable
|
|
22
|
+
export const Creatable = OrganizationCreatable
|
|
23
|
+
}
|
package/README.md
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# Pax2Pay Model Banking
|
|
2
|
+
Typescript library containing data models and functions for the Pax2Pay Banking API.
|
package/Rail/Iban.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Iban {
|
|
2
|
+
type: "iban"
|
|
3
|
+
iban: string
|
|
4
|
+
}
|
|
5
|
+
export namespace Iban {
|
|
6
|
+
export const currencies = ["EUR", "GBP", "SEK", "USD"] as const
|
|
7
|
+
// maybe do the Iban checksum check below?
|
|
8
|
+
export function is(value: Iban | any): value is Iban {
|
|
9
|
+
return typeof value == "object" && typeof value.iban == "string" && value.type == "iban"
|
|
10
|
+
}
|
|
11
|
+
}
|
package/Rail/PaxGiro.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
|
|
3
|
+
export interface PaxGiro {
|
|
4
|
+
type: "paxgiro"
|
|
5
|
+
identifier: cryptly.Identifier
|
|
6
|
+
}
|
|
7
|
+
export namespace PaxGiro {
|
|
8
|
+
export const currencies = ["EUR", "GBP", "SEK", "USD"] as const
|
|
9
|
+
export function is(value: PaxGiro | any): value is PaxGiro {
|
|
10
|
+
return typeof value == "object" && cryptly.Identifier.is(value.identifier, 8) && value.type == "paxgiro"
|
|
11
|
+
}
|
|
12
|
+
}
|
package/Rail/Type.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Type = "iban" | "paxgiro" | "swedish" | "internal"
|
package/Rail/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Iban as RailIban } from "./Iban"
|
|
2
|
+
import { Internal as RailInternal } from "./internal"
|
|
3
|
+
import { PaxGiro as RailPaxGiro } from "./PaxGiro"
|
|
4
|
+
import { Type as RailType } from "./Type"
|
|
5
|
+
|
|
6
|
+
export type Rail = RailPaxGiro | RailIban | RailInternal
|
|
7
|
+
|
|
8
|
+
export namespace Rail {
|
|
9
|
+
export function parse(value: string): Rail | undefined {
|
|
10
|
+
let result: Rail | undefined
|
|
11
|
+
const splitted = value.split("-")
|
|
12
|
+
switch (splitted[0]) {
|
|
13
|
+
//case "iban":
|
|
14
|
+
// result = splitted.length == 2 ? { type: "iban", reference: splitted[1] } : undefined
|
|
15
|
+
// break
|
|
16
|
+
case "pxg":
|
|
17
|
+
result = splitted.length == 2 ? { type: "paxgiro", identifier: splitted[1] } : undefined
|
|
18
|
+
break
|
|
19
|
+
//case "swe":
|
|
20
|
+
// result =
|
|
21
|
+
// splitted.length == 3
|
|
22
|
+
// ? { type: "swedish", clearing: Number.parseInt(splitted[1]), account: Number.parseInt(splitted[2]) }
|
|
23
|
+
// : undefined
|
|
24
|
+
// break
|
|
25
|
+
}
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
export function stringify(rail: Rail): string {
|
|
29
|
+
let result: string
|
|
30
|
+
switch (rail.type) {
|
|
31
|
+
case "iban":
|
|
32
|
+
result = `iban-${rail.iban}`
|
|
33
|
+
break
|
|
34
|
+
case "paxgiro":
|
|
35
|
+
result = `pxg-${rail.identifier}`
|
|
36
|
+
break
|
|
37
|
+
case "internal":
|
|
38
|
+
result = ""
|
|
39
|
+
break
|
|
40
|
+
//case "swedish":
|
|
41
|
+
// result = `swe-${rail.clearing}-${rail.account}`
|
|
42
|
+
// break
|
|
43
|
+
}
|
|
44
|
+
return result
|
|
45
|
+
}
|
|
46
|
+
export function is(value: Rail | any): value is Rail {
|
|
47
|
+
return typeof value == "object" && (PaxGiro.is(value) || Iban.is(value) || Internal.is(value))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type Type = RailType
|
|
51
|
+
export type PaxGiro = RailPaxGiro
|
|
52
|
+
export const PaxGiro = RailPaxGiro
|
|
53
|
+
export type Iban = RailIban
|
|
54
|
+
export const Iban = RailIban
|
|
55
|
+
export type Internal = RailInternal
|
|
56
|
+
export const Internal = RailInternal
|
|
57
|
+
}
|
package/Rail/internal.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
|
|
3
|
+
export interface Internal {
|
|
4
|
+
type: "internal"
|
|
5
|
+
identifier: cryptly.Identifier
|
|
6
|
+
}
|
|
7
|
+
export namespace Internal {
|
|
8
|
+
export const currencies = ["EUR", "GBP", "SEK", "USD"] as const
|
|
9
|
+
export function is(value: Internal | any): value is Internal {
|
|
10
|
+
return typeof value == "object" && cryptly.Identifier.is(value.identifier, 8) && value.type == "internal"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as isoly from "isoly"
|
|
2
|
+
import { Operation } from "../Operation"
|
|
3
|
+
import { Rail } from "../Rail"
|
|
4
|
+
|
|
5
|
+
export interface Creatable {
|
|
6
|
+
account: Rail
|
|
7
|
+
counterpart: Rail
|
|
8
|
+
currency: isoly.Currency
|
|
9
|
+
amount: number
|
|
10
|
+
description?: string
|
|
11
|
+
operations?: Operation.Creatable[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export namespace Creatable {
|
|
15
|
+
export function is(value: any | Creatable): value is Creatable {
|
|
16
|
+
return (
|
|
17
|
+
typeof value == "object" &&
|
|
18
|
+
Rail.is(value.account) &&
|
|
19
|
+
Rail.is(value.counterpart) &&
|
|
20
|
+
isoly.Currency.is(value.currency) &&
|
|
21
|
+
typeof value.amount == "number" &&
|
|
22
|
+
value.amount > 0 &&
|
|
23
|
+
(value.description == undefined || typeof value.description == "string") &&
|
|
24
|
+
(value.operations == undefined ||
|
|
25
|
+
(Array.isArray(value.operations) && value.operations.every(Operation.Creatable.is)))
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as cryptly from "cryptly"
|
|
2
|
+
import * as isoly from "isoly"
|
|
3
|
+
import { Operation } from "../Operation"
|
|
4
|
+
import { Creatable as TransactionCreatable } from "./Creatable"
|
|
5
|
+
|
|
6
|
+
export interface Transaction extends TransactionCreatable {
|
|
7
|
+
readonly id: cryptly.Identifier
|
|
8
|
+
readonly timestamp: isoly.DateTime
|
|
9
|
+
type: "actual" | "available"
|
|
10
|
+
balance: number
|
|
11
|
+
//status: "pending" | "settled" | "rejected" | "cancelled"
|
|
12
|
+
operations: Operation[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export namespace Transaction {
|
|
16
|
+
export function is(value: any | Transaction): value is Transaction {
|
|
17
|
+
return (
|
|
18
|
+
typeof value == "object" &&
|
|
19
|
+
TransactionCreatable.is({ ...value }) &&
|
|
20
|
+
cryptly.Identifier.is(value.id, 8) &&
|
|
21
|
+
isoly.DateTime.is(value.timestamp) &&
|
|
22
|
+
(value.type == "actual" || value.type == "available") &&
|
|
23
|
+
typeof value.balance == "number" &&
|
|
24
|
+
Array.isArray(value.operations) &&
|
|
25
|
+
value.operations.every(Operation.is)
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
export function fromCreatable(
|
|
29
|
+
transaction: Creatable & { operations: Operation.Creatable[] },
|
|
30
|
+
type: "actual" | "available",
|
|
31
|
+
result: number
|
|
32
|
+
): Transaction {
|
|
33
|
+
const id = cryptly.Identifier.generate(8)
|
|
34
|
+
const timestamp = isoly.DateTime.now()
|
|
35
|
+
return {
|
|
36
|
+
id: id,
|
|
37
|
+
timestamp: timestamp,
|
|
38
|
+
type: type,
|
|
39
|
+
balance: result,
|
|
40
|
+
...transaction,
|
|
41
|
+
operations: transaction.operations.map(Operation.fromCreatable),
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function isIdentifier(value: cryptly.Identifier | any): value is cryptly.Identifier {
|
|
45
|
+
return cryptly.Identifier.is(value, 8)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type Creatable = TransactionCreatable
|
|
49
|
+
export const Creatable = TransactionCreatable
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Creatable.js","sourceRoot":"../","sources":["Account/Creatable.ts"],"names":[],"mappings":"AAIA,MAAM,KAAW,SAAS,CAIzB;AAJD,WAAiB,SAAS;IACzB,SAAgB,EAAE,CAAC,KAAsB;QACxC,OAAO,OAAO,KAAK,IAAI,QAAQ,IAAI,OAAO,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAA;IACjE,CAAC;IAFe,YAAE,KAEjB,CAAA;AACF,CAAC,EAJgB,SAAS,KAAT,SAAS,QAIzB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as cryptly from "cryptly";
|
|
2
|
+
import * as isoly from "isoly";
|
|
3
|
+
import { Balances } from "../Balances";
|
|
4
|
+
import { Rail } from "../Rail";
|
|
5
|
+
import { Creatable as AccountCreatable } from "./Creatable";
|
|
6
|
+
export interface Account extends Account.Creatable {
|
|
7
|
+
readonly id: cryptly.Identifier;
|
|
8
|
+
readonly created: isoly.DateTime;
|
|
9
|
+
}
|
|
10
|
+
export declare namespace Account {
|
|
11
|
+
function fromCreatable(account: Creatable): Account;
|
|
12
|
+
function is(account: Account | any): account is Account;
|
|
13
|
+
function isIdentifier(value: cryptly.Identifier | any): value is cryptly.Identifier;
|
|
14
|
+
type Creatable = AccountCreatable;
|
|
15
|
+
const Creatable: typeof AccountCreatable;
|
|
16
|
+
type Info = Account & {
|
|
17
|
+
rails: Rail[];
|
|
18
|
+
balances: Balances;
|
|
19
|
+
};
|
|
20
|
+
namespace Info {
|
|
21
|
+
function is(value: Info | any): value is Info;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as cryptly from "cryptly";
|
|
2
|
+
import * as isoly from "isoly";
|
|
3
|
+
import { Balances } from "../Balances";
|
|
4
|
+
import { Rail } from "../Rail";
|
|
5
|
+
import { Creatable as AccountCreatable } from "./Creatable";
|
|
6
|
+
export var Account;
|
|
7
|
+
(function (Account) {
|
|
8
|
+
function fromCreatable(account) {
|
|
9
|
+
return {
|
|
10
|
+
...account,
|
|
11
|
+
id: cryptly.Identifier.generate(8),
|
|
12
|
+
created: isoly.DateTime.now(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
Account.fromCreatable = fromCreatable;
|
|
16
|
+
function is(account) {
|
|
17
|
+
return (Account.Creatable.is({ ...account }) && cryptly.Identifier.is(account.id, 8) && isoly.DateTime.is(account.created));
|
|
18
|
+
}
|
|
19
|
+
Account.is = is;
|
|
20
|
+
function isIdentifier(value) {
|
|
21
|
+
return cryptly.Identifier.is(value, 8);
|
|
22
|
+
}
|
|
23
|
+
Account.isIdentifier = isIdentifier;
|
|
24
|
+
Account.Creatable = AccountCreatable;
|
|
25
|
+
let Info;
|
|
26
|
+
(function (Info) {
|
|
27
|
+
function is(value) {
|
|
28
|
+
return (typeof value == "object" &&
|
|
29
|
+
Account.is({ ...value }) &&
|
|
30
|
+
Array.isArray(value.rails) &&
|
|
31
|
+
value.rails.every((r) => Rail.is(r)) &&
|
|
32
|
+
Balances.is(value.balances));
|
|
33
|
+
}
|
|
34
|
+
Info.is = is;
|
|
35
|
+
})(Info = Account.Info || (Account.Info = {}));
|
|
36
|
+
})(Account || (Account = {}));
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../","sources":["Account/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAO3D,MAAM,KAAW,OAAO,CA+BvB;AA/BD,WAAiB,OAAO;IACvB,SAAgB,aAAa,CAAC,OAAkB;QAC/C,OAAO;YACN,GAAG,OAAO;YACV,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;SAC7B,CAAA;IACF,CAAC;IANe,qBAAa,gBAM5B,CAAA;IACD,SAAgB,EAAE,CAAC,OAAsB;QACxC,OAAO,CACN,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAClH,CAAA;IACF,CAAC;IAJe,UAAE,KAIjB,CAAA;IACD,SAAgB,YAAY,CAAC,KAA+B;QAC3D,OAAO,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IACvC,CAAC;IAFe,oBAAY,eAE3B,CAAA;IAGY,iBAAS,GAAG,gBAAgB,CAAA;IAEzC,IAAiB,IAAI,CAUpB;IAVD,WAAiB,IAAI;QACpB,SAAgB,EAAE,CAAC,KAAiB;YACnC,OAAO,CACN,OAAO,KAAK,IAAI,QAAQ;gBACxB,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;gBACxB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;gBAC1B,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC3B,CAAA;QACF,CAAC;QARe,OAAE,KAQjB,CAAA;IACF,CAAC,EAVgB,IAAI,GAAJ,YAAI,KAAJ,YAAI,QAUpB;AACF,CAAC,EA/BgB,OAAO,KAAP,OAAO,QA+BvB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as isoly from "isoly";
|
|
2
|
+
export type Balances = Partial<Record<isoly.Currency, Partial<Record<Balances.Entry, number>>>>;
|
|
3
|
+
export declare namespace Balances {
|
|
4
|
+
function is(value: Balances | any): value is Balances;
|
|
5
|
+
type Entry = "actual" | "reserved";
|
|
6
|
+
namespace Entry {
|
|
7
|
+
function is(value: any | Entry): value is Entry;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as isoly from "isoly";
|
|
2
|
+
export var Balances;
|
|
3
|
+
(function (Balances) {
|
|
4
|
+
function is(value) {
|
|
5
|
+
return (typeof value == "object" &&
|
|
6
|
+
Object.entries(value).every(([k, v]) => isoly.Currency.is(k) &&
|
|
7
|
+
typeof v == "object" &&
|
|
8
|
+
Object.entries(v).every(([kInner, vInner]) => Balances.Entry.is(kInner) && typeof vInner == "number")));
|
|
9
|
+
}
|
|
10
|
+
Balances.is = is;
|
|
11
|
+
let Entry;
|
|
12
|
+
(function (Entry) {
|
|
13
|
+
function is(value) {
|
|
14
|
+
return typeof value == "string" && (value == "actual" || value == "reserved");
|
|
15
|
+
}
|
|
16
|
+
Entry.is = is;
|
|
17
|
+
})(Entry = Balances.Entry || (Balances.Entry = {}));
|
|
18
|
+
})(Balances || (Balances = {}));
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../","sources":["Balances/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,KAAW,QAAQ,CAoBxB;AApBD,WAAiB,QAAQ;IACxB,SAAgB,EAAE,CAAC,KAAqB;QACvC,OAAO,CACN,OAAO,KAAK,IAAI,QAAQ;YACxB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAC1B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,OAAO,CAAC,IAAI,QAAQ;gBACpB,MAAM,CAAC,OAAO,CAAC,CAA4B,CAAC,CAAC,KAAK,CACjD,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,IAAI,QAAQ,CAC5E,CACF,CACD,CAAA;IACF,CAAC;IAZe,WAAE,KAYjB,CAAA;IAED,IAAiB,KAAK,CAIrB;IAJD,WAAiB,KAAK;QACrB,SAAgB,EAAE,CAAC,KAAkB;YACpC,OAAO,OAAO,KAAK,IAAI,QAAQ,IAAI,CAAC,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,UAAU,CAAC,CAAA;QAC9E,CAAC;QAFe,QAAE,KAEjB,CAAA;IACF,CAAC,EAJgB,KAAK,GAAL,cAAK,KAAL,cAAK,QAIrB;AACF,CAAC,EApBgB,QAAQ,KAAR,QAAQ,QAoBxB"}
|