@temboplus/afloat 0.2.1-beta.8 → 0.2.1

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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -207
  3. package/dist/index.cjs.js +1 -1
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.d.ts +5 -4
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.esm.js +1 -1
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/lib/api/base-repository.d.ts +2 -2
  10. package/dist/lib/api/base-repository.d.ts.map +1 -0
  11. package/dist/lib/api/index.d.ts +1 -0
  12. package/dist/lib/api/index.d.ts.map +1 -0
  13. package/dist/lib/error/error.api.d.ts +3 -2
  14. package/dist/lib/error/error.api.d.ts.map +1 -0
  15. package/dist/lib/error/error.permission.d.ts +2 -1
  16. package/dist/lib/error/error.permission.d.ts.map +1 -0
  17. package/dist/lib/error/error.utils.d.ts +1 -0
  18. package/dist/lib/error/error.utils.d.ts.map +1 -0
  19. package/dist/lib/error/index.d.ts +1 -0
  20. package/dist/lib/error/index.d.ts.map +1 -0
  21. package/dist/lib/query/index.d.ts +3 -2
  22. package/dist/lib/query/index.d.ts.map +1 -0
  23. package/dist/lib/query/pagination/pagination.d.ts +1 -0
  24. package/dist/lib/query/pagination/pagination.d.ts.map +1 -0
  25. package/dist/lib/query/pagination/pagination.schemas.d.ts +8 -61
  26. package/dist/lib/query/pagination/pagination.schemas.d.ts.map +1 -0
  27. package/dist/lib/query/query.builder.d.ts +10 -3
  28. package/dist/lib/query/query.builder.d.ts.map +1 -0
  29. package/dist/lib/query/query.types.d.ts +1 -0
  30. package/dist/lib/query/query.types.d.ts.map +1 -0
  31. package/dist/modules/auth/auth.contract.d.ts +10 -69
  32. package/dist/modules/auth/auth.contract.d.ts.map +1 -0
  33. package/dist/modules/auth/auth.dtos.d.ts +8 -67
  34. package/dist/modules/auth/auth.dtos.d.ts.map +1 -0
  35. package/dist/modules/auth/auth.repository.d.ts +1 -0
  36. package/dist/modules/auth/auth.repository.d.ts.map +1 -0
  37. package/dist/modules/auth/company-membership.model.d.ts +7 -86
  38. package/dist/modules/auth/company-membership.model.d.ts.map +1 -0
  39. package/dist/modules/auth/index.d.ts +3 -2
  40. package/dist/modules/auth/index.d.ts.map +1 -0
  41. package/dist/modules/auth/user.model.d.ts +26 -163
  42. package/dist/modules/auth/user.model.d.ts.map +1 -0
  43. package/dist/modules/beneficiary/beneficiary-info.model.d.ts +30 -67
  44. package/dist/modules/beneficiary/beneficiary-info.model.d.ts.map +1 -0
  45. package/dist/modules/beneficiary/beneficiary-input-handler.d.ts +3 -2
  46. package/dist/modules/beneficiary/beneficiary-input-handler.d.ts.map +1 -0
  47. package/dist/modules/beneficiary/beneficiary.api-contract.d.ts +16 -115
  48. package/dist/modules/beneficiary/beneficiary.api-contract.d.ts.map +1 -0
  49. package/dist/modules/beneficiary/beneficiary.dtos.d.ts +6 -34
  50. package/dist/modules/beneficiary/beneficiary.dtos.d.ts.map +1 -0
  51. package/dist/modules/beneficiary/beneficiary.model.d.ts +5 -27
  52. package/dist/modules/beneficiary/beneficiary.model.d.ts.map +1 -0
  53. package/dist/modules/beneficiary/beneficiary.repository.d.ts +2 -1
  54. package/dist/modules/beneficiary/beneficiary.repository.d.ts.map +1 -0
  55. package/dist/modules/beneficiary/index.d.ts +5 -4
  56. package/dist/modules/beneficiary/index.d.ts.map +1 -0
  57. package/dist/modules/login/index.d.ts +1 -0
  58. package/dist/modules/login/index.d.ts.map +1 -0
  59. package/dist/modules/login/login.api-contract.d.ts +3 -28
  60. package/dist/modules/login/login.api-contract.d.ts.map +1 -0
  61. package/dist/modules/login/login.dtos.d.ts +5 -56
  62. package/dist/modules/login/login.dtos.d.ts.map +1 -0
  63. package/dist/modules/login/login.model.d.ts +7 -34
  64. package/dist/modules/login/login.model.d.ts.map +1 -0
  65. package/dist/modules/login/login.repository.d.ts +2 -1
  66. package/dist/modules/login/login.repository.d.ts.map +1 -0
  67. package/dist/modules/login/permission.type.d.ts +1 -0
  68. package/dist/modules/login/permission.type.d.ts.map +1 -0
  69. package/dist/modules/payout/index.d.ts +3 -2
  70. package/dist/modules/payout/index.d.ts.map +1 -0
  71. package/dist/modules/payout/payout-channel-handler.d.ts +5 -4
  72. package/dist/modules/payout/payout-channel-handler.d.ts.map +1 -0
  73. package/dist/modules/payout/payout.api-contract.d.ts +78 -666
  74. package/dist/modules/payout/payout.api-contract.d.ts.map +1 -0
  75. package/dist/modules/payout/payout.dtos.d.ts +99 -506
  76. package/dist/modules/payout/payout.dtos.d.ts.map +1 -0
  77. package/dist/modules/payout/payout.model.d.ts +8 -85
  78. package/dist/modules/payout/payout.model.d.ts.map +1 -0
  79. package/dist/modules/payout/payout.query.d.ts +3 -2
  80. package/dist/modules/payout/payout.query.d.ts.map +1 -0
  81. package/dist/modules/payout/payout.repository.d.ts +7 -6
  82. package/dist/modules/payout/payout.repository.d.ts.map +1 -0
  83. package/dist/modules/profile/index.d.ts +1 -0
  84. package/dist/modules/profile/index.d.ts.map +1 -0
  85. package/dist/modules/profile/profile.api-contract.d.ts +2 -19
  86. package/dist/modules/profile/profile.api-contract.d.ts.map +1 -0
  87. package/dist/modules/profile/profile.dtos.d.ts +3 -38
  88. package/dist/modules/profile/profile.dtos.d.ts.map +1 -0
  89. package/dist/modules/profile/profile.model.d.ts +5 -42
  90. package/dist/modules/profile/profile.model.d.ts.map +1 -0
  91. package/dist/modules/profile/profile.repository.d.ts +1 -0
  92. package/dist/modules/profile/profile.repository.d.ts.map +1 -0
  93. package/dist/modules/team-member/index.d.ts +3 -2
  94. package/dist/modules/team-member/index.d.ts.map +1 -0
  95. package/dist/modules/team-member/role.model.d.ts +6 -21
  96. package/dist/modules/team-member/role.model.d.ts.map +1 -0
  97. package/dist/modules/team-member/team-member.contract.d.ts +74 -615
  98. package/dist/modules/team-member/team-member.contract.d.ts.map +1 -0
  99. package/dist/modules/team-member/team-member.dtos.d.ts +15 -162
  100. package/dist/modules/team-member/team-member.dtos.d.ts.map +1 -0
  101. package/dist/modules/team-member/team-member.model.d.ts +7 -66
  102. package/dist/modules/team-member/team-member.model.d.ts.map +1 -0
  103. package/dist/modules/team-member/team-member.repository.d.ts +3 -2
  104. package/dist/modules/team-member/team-member.repository.d.ts.map +1 -0
  105. package/dist/modules/wallet/index.d.ts +4 -2
  106. package/dist/modules/wallet/index.d.ts.map +1 -0
  107. package/dist/modules/wallet/narration.model.d.ts +3 -8
  108. package/dist/modules/wallet/narration.model.d.ts.map +1 -0
  109. package/dist/modules/wallet/statement-entry.model.d.ts +14 -131
  110. package/dist/modules/wallet/statement-entry.model.d.ts.map +1 -0
  111. package/dist/modules/wallet/wallet.contract.d.ts +17 -90
  112. package/dist/modules/wallet/wallet.contract.d.ts.map +1 -0
  113. package/dist/modules/wallet/wallet.dtos.d.ts +33 -138
  114. package/dist/modules/wallet/wallet.dtos.d.ts.map +1 -0
  115. package/dist/modules/wallet/wallet.model.d.ts +5 -26
  116. package/dist/modules/wallet/wallet.model.d.ts.map +1 -0
  117. package/dist/modules/wallet/wallet.query.d.ts +2 -1
  118. package/dist/modules/wallet/wallet.query.d.ts.map +1 -0
  119. package/dist/modules/wallet/wallet.repository.d.ts +49 -25
  120. package/dist/modules/wallet/wallet.repository.d.ts.map +1 -0
  121. package/dist/modules/wallet/wallet.timezone.d.ts +87 -0
  122. package/dist/modules/wallet/wallet.timezone.d.ts.map +1 -0
  123. package/dist/modules/wallet/wallet.utils.d.ts +3 -2
  124. package/dist/modules/wallet/wallet.utils.d.ts.map +1 -0
  125. package/package.json +40 -29
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 TemboPlus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,255 +1,102 @@
1
1
  # @temboplus/afloat
2
2
 
3
- A foundational JavaScript/TypeScript library for TemboPlus-Afloat projects, providing abstracted server communication, shared utilities, and standardized data models for consistent development.
3
+ Type-safe client library for the TemboPlus-Afloat API. Repository classes wrap each resource (wallets, payouts, beneficiaries, profile, team members, identity, auth) so consumers never talk to HTTP directly.
4
4
 
5
- ## Key Features
5
+ ## Quick Start
6
6
 
7
- * **Abstracted Server Communication**
8
- * Simplifies front-end development by abstracting all interactions with the server behind model-specific repositories
9
- * Consuming projects only need to interact with these repositories, decoupling them from the underlying API implementation
10
-
11
- * **Authentication-Agnostic Repositories**
12
- * The library does not own session state or export an auth singleton
13
- * Consuming applications log in, store the returned token, and pass that token to repositories
14
-
15
- * **Data Models**
16
- * Defines standardized data structures and interfaces for consistent data representation throughout the Afloat ecosystem
17
-
18
- * **Cross-Environment Compatibility**
19
- * Works seamlessly in both client-side and server-side environments
20
-
21
- ## Usage
22
-
23
- ### Login
24
-
25
- Use `AuthRepository.logIn(...)` for the unauthenticated login request. The returned `User` contains the token that should be stored by your app and passed to other repositories.
26
-
27
- ```typescript
28
- import { AuthRepository } from "@temboplus/afloat";
29
-
30
- try {
31
- const authRepo = new AuthRepository();
32
- const user = await authRepo.logIn("user@example.com", "password123");
33
-
34
- storeSession({
35
- token: user.token,
36
- user: user.toJSON(),
37
- });
38
- } catch (error) {
39
- const message = error instanceof Error ? error.message : "Unknown error";
40
- console.error("Login failed:", message);
41
- }
7
+ ```bash
8
+ bun add @temboplus/afloat
9
+ # or: npm install @temboplus/afloat
42
10
  ```
43
11
 
44
- `AuthRepository` also has authenticated methods. Construct it with a token before calling those:
45
-
46
12
  ```typescript
47
- import { AuthRepository } from "@temboplus/afloat";
13
+ import { AuthRepository, WalletRepository } from "@temboplus/afloat";
48
14
 
49
- const authRepo = new AuthRepository({ token });
15
+ // 1. Log in. The returned User contains the token.
16
+ const authRepo = new AuthRepository();
17
+ const user = await authRepo.logIn("user@example.com", "password123");
50
18
 
51
- await authRepo.updatePassword("currentPassword", "newPassword");
52
- const accessList = await authRepo.getAccessList();
19
+ // 2. Pass the token to any other repository.
20
+ const walletRepo = new WalletRepository({ token: user.token });
21
+ const [wallet] = await walletRepo.getWallets();
53
22
  ```
54
23
 
55
- ### Repository Usage
24
+ ## Usage
56
25
 
57
- Authenticated repositories share the same construction shape:
26
+ afloat is **session-agnostic** — it does not own login state or export an auth singleton. Your application logs in, stores the token, and passes it into every authenticated repository.
58
27
 
59
28
  ```typescript
60
29
  const repo = new SomeRepository({
61
30
  token: "user-auth-token",
62
- root: "https://api.afloat.money/v1", // optional
31
+ root: "https://api.afloat.money/v1", // optional override
63
32
  });
64
33
  ```
65
34
 
66
- Use this shape for:
35
+ Available repositories:
67
36
 
68
- * `WalletRepository`
69
- * `PayoutRepository`
70
- * `BeneficiaryRepository`
71
- * `ProfileRepository`
72
- * `TeamMemberRepository`
73
- * `IdentityRepository`
74
- * `AuthRepository` when calling authenticated methods like `updatePassword` or `getAccessList`
37
+ - `AuthRepository` — `logIn`, `updatePassword`, `getAccessList`
38
+ - `WalletRepository` — wallets, balances, statements
39
+ - `PayoutRepository` — create, approve, reject, list, count
40
+ - `BeneficiaryRepository` — create, edit, remove, lookup
41
+ - `ProfileRepository` — current profile
42
+ - `TeamMemberRepository` — team members and roles
43
+ - `IdentityRepository` authenticated `/login/me`
75
44
 
76
- The TypeScript constructors accept optional fields because the base repository supports a global token getter, but authenticated Afloat API calls still require a token. Passing `{ token }` explicitly is the recommended and documented integration path.
45
+ ### Permissions
77
46
 
78
- #### Wallet Example
47
+ The `User` returned by `logIn` carries the permission set:
79
48
 
80
49
  ```typescript
81
- import { Permissions, WalletRepository } from "@temboplus/afloat";
82
-
83
- const walletRepo = new WalletRepository({ token });
84
- const [wallet] = await walletRepo.getWallets();
85
-
86
- if (!wallet) {
87
- throw new Error("No wallet available");
88
- }
50
+ import { Permissions, PayoutRepository } from "@temboplus/afloat";
89
51
 
90
- if (user.can(Permissions.Wallet.ViewBalance)) {
91
- const balance = await walletRepo.getBalance({ wallet });
92
- console.log(balance.label);
52
+ if (user.can(Permissions.Payout.Create)) {
53
+ const payoutRepo = new PayoutRepository({ token: user.token });
54
+ await payoutRepo.pay(input);
93
55
  }
94
-
95
- const entries = await walletRepo.getStatement({
96
- wallet,
97
- range: {
98
- startDate: new Date("2024-01-01"),
99
- endDate: new Date("2024-01-31"),
100
- },
101
- });
102
56
  ```
103
57
 
104
- #### Identity Example
58
+ ### Server-side usage
105
59
 
106
- `IdentityRepository` reads the authenticated `/login/me` data. It is not the login request itself, so it requires a token.
107
-
108
- ```typescript
109
- import { IdentityRepository } from "@temboplus/afloat";
110
-
111
- const identityRepo = new IdentityRepository({ token });
112
- const identity = await identityRepo.getIdentity();
113
- ```
114
-
115
- #### Server Route Example
60
+ Repositories work on the server too extract the bearer token from the incoming request and pass it through:
116
61
 
117
62
  ```typescript
118
63
  import { WalletRepository } from "@temboplus/afloat";
119
64
 
120
- function extractBearerToken(req): string | undefined {
121
- return req.headers.authorization?.replace(/^Bearer\s+/i, "");
122
- }
123
-
124
65
  app.get("/api/wallets", async (req, res) => {
125
- const token = extractBearerToken(req);
126
-
127
- if (!token) {
128
- return res.status(401).json({ error: "Unauthorized" });
129
- }
66
+ const token = req.headers.authorization?.replace(/^Bearer\s+/i, "");
67
+ if (!token) return res.status(401).json({ error: "Unauthorized" });
130
68
 
131
69
  const walletRepo = new WalletRepository({ token });
132
- const wallets = await walletRepo.getWallets();
133
-
134
- return res.json({ wallets });
70
+ return res.json({ wallets: await walletRepo.getWallets() });
135
71
  });
136
72
  ```
137
73
 
138
- ## Architecture Overview
139
-
140
- ### Host Application Responsibilities
141
-
142
- * Call `AuthRepository.logIn(...)` to create a session
143
- * Store the returned token in your own state, cookie, storage, or server session
144
- * Rehydrate `User` with `User.fromJSON(...)` when needed
145
- * Pass `{ token }` to repositories before calling authenticated endpoints
146
- * Check permissions with the returned `User` instance, for example `user.can(Permissions.Wallet.ViewBalance)`
147
-
148
- ### Library Responsibilities
149
-
150
- * Provide typed repositories for Afloat API resources
151
- * Attach the token and request ID headers to repository calls
152
- * Convert API responses into domain models where repositories support it
153
- * Surface API errors through `APIError` or repository-specific errors
154
-
155
- ## Best Practices
156
-
157
- ### Token Handling
158
-
159
- ```typescript
160
- import {
161
- AuthRepository,
162
- ProfileRepository,
163
- WalletRepository,
164
- } from "@temboplus/afloat";
165
-
166
- const authRepo = new AuthRepository();
167
- const user = await authRepo.logIn(email, password);
168
-
169
- saveToken(user.token);
170
-
171
- const walletRepo = new WalletRepository({ token: user.token });
172
- const profileRepo = new ProfileRepository({ token: user.token });
173
- ```
174
-
175
- ### Permission Checks
176
-
177
- ```typescript
178
- import { Permissions, PayoutRepository } from "@temboplus/afloat";
179
-
180
- if (user.can(Permissions.Payout.Create)) {
181
- const payoutRepo = new PayoutRepository({ token: user.token });
182
- await payoutRepo.pay(input);
183
- }
184
- ```
185
-
186
- ## Troubleshooting
187
-
188
- ### Common Issues
189
-
190
- #### `AfloatAuth` Import Errors
191
-
192
- **Problem**: `AfloatAuth` is undefined or cannot be imported.
193
-
194
- **Solution**: Replace `AfloatAuth` usage with `AuthRepository.logIn(...)` plus application-owned session state.
195
-
196
- ```typescript
197
- import { AuthRepository } from "@temboplus/afloat";
198
-
199
- const authRepo = new AuthRepository();
200
- const user = await authRepo.logIn(email, password);
201
- const token = user.token;
202
- ```
203
-
204
- #### Repository Token Issues
74
+ ## Consumed By
205
75
 
206
- **Problem**: Repository calls fail with authentication errors.
76
+ - **TemboPlus Afloat** (Next.js frontend) customer-facing app.
77
+ - **TemboPlus Reports** (NestJS backend) — Afloat-specific report generation.
207
78
 
208
- **Solution**: Ensure the token from login or the incoming request is passed into the repository.
79
+ ## Development
209
80
 
210
- ```typescript
211
- if (!extractedToken) {
212
- throw new Error("Missing authentication token");
213
- }
81
+ Bun for everything, Biome for lint+format, mise for the toolchain pin.
214
82
 
215
- const repo = new WalletRepository({ token: extractedToken });
83
+ ```bash
84
+ mise install # one-time: installs pinned Bun
85
+ bun install
86
+ bun run dev # rollup build in watch mode
216
87
  ```
217
88
 
218
- #### Identity Repository Confusion
219
-
220
- **Problem**: `IdentityRepository` is used for login.
221
-
222
- **Solution**: Use `AuthRepository.logIn(...)` for login. Use `IdentityRepository({ token }).getIdentity()` only after you have a token.
89
+ | Script | Does |
90
+ | --- | --- |
91
+ | `bun run dev` | Rollup build in watch mode |
92
+ | `bun run build` | Rollup build to `dist/` (CJS + ESM + `.d.ts`) |
93
+ | `bun run test` | `bun:test` (passes with zero tests; smoke test only) |
94
+ | `bun run lint` | Biome check |
95
+ | `bun run format` | Biome auto-fix |
96
+ | `bun run typecheck` | `tsc --noEmit` |
223
97
 
224
- ## API Reference
98
+ Tag-driven releases via `.github/workflows/release.yml` — update `CHANGELOG.md`, bump `package.json`, push a `vX.Y.Z` tag.
225
99
 
226
- ### Login and Auth
227
-
228
- * `AuthRepository.logIn(email, password)` - Authenticate without an existing token and return a `User`
229
- * `AuthRepository({ token }).updatePassword(current, next)` - Update the current user's password
230
- * `AuthRepository({ token }).getAccessList()` - Fetch the current user's access list
231
- * `User.token` - Token to pass into repositories
232
- * `User.can(permission)` - Check a single permission
233
- * `User.canAny(permissions)` - Check if the user has at least one permission
234
- * `User.canAll(permissions)` - Check if the user has all permissions
235
-
236
- ### Authenticated Repositories
237
-
238
- All authenticated repositories use:
239
-
240
- ```typescript
241
- new RepositoryName({
242
- token: "user-auth-token",
243
- root: "custom-api-root", // optional
244
- });
245
- ```
246
-
247
- Available repositories:
100
+ ## License
248
101
 
249
- * `WalletRepository` - Wallet operations, balances, and statements
250
- * `PayoutRepository` - Payout creation, approval, rejection, lookup, and counting
251
- * `BeneficiaryRepository` - Beneficiary create, edit, remove, and lookup
252
- * `ProfileRepository` - Current profile lookup
253
- * `TeamMemberRepository` - Team member and role management
254
- * `IdentityRepository` - Current `/login/me` identity data
255
- * `AuthRepository` - Login without token; password and access-list operations with token
102
+ [MIT](./LICENSE) © TemboPlus