@qelos/sdk 3.11.11 → 4.1.0
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/README.md +31 -0
- package/dist/__tests__/blueprints.types.test-d.d.ts +28 -0
- package/dist/__tests__/blueprints.types.test-d.js +11 -0
- package/dist/__tests__/blueprints.types.test-d.js.map +1 -0
- package/dist/administrator/events.d.ts +5 -0
- package/dist/administrator/events.js +8 -0
- package/dist/administrator/events.js.map +1 -1
- package/dist/administrator/payments.d.ts +47 -1
- package/dist/administrator/payments.js +34 -0
- package/dist/administrator/payments.js.map +1 -1
- package/dist/ai/agents.d.ts +56 -0
- package/dist/ai/agents.js +116 -0
- package/dist/ai/agents.js.map +1 -0
- package/dist/ai/index.d.ts +9 -3
- package/dist/ai/index.js +8 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/types.d.ts +61 -0
- package/dist/authentication.d.ts +64 -1
- package/dist/authentication.js +137 -0
- package/dist/authentication.js.map +1 -1
- package/dist/base-sdk.d.ts +3 -0
- package/dist/base-sdk.js +16 -2
- package/dist/base-sdk.js.map +1 -1
- package/dist/blueprints-entities.d.ts +26 -0
- package/dist/blueprints-entities.js +91 -5
- package/dist/blueprints-entities.js.map +1 -1
- package/dist/blueprints.d.ts +3 -0
- package/dist/blueprints.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/payments.d.ts +28 -2
- package/dist/payments.js +24 -0
- package/dist/payments.js.map +1 -1
- package/dist/workspaces.d.ts +16 -0
- package/dist/workspaces.js +40 -0
- package/dist/workspaces.js.map +1 -1
- package/docs/payments.md +301 -0
- package/package.json +2 -2
- package/src/__tests__/blueprints.types.test-d.ts +49 -0
- package/src/administrator/events.ts +6 -1
- package/src/administrator/payments.ts +74 -1
- package/src/ai/agents.ts +171 -0
- package/src/ai/index.ts +22 -4
- package/src/ai/types.ts +66 -0
- package/src/authentication.ts +181 -1
- package/src/base-sdk.ts +16 -2
- package/src/blueprints-entities.ts +113 -5
- package/src/blueprints.ts +9 -2
- package/src/index.ts +26 -1
- package/src/payments.ts +38 -2
- package/src/workspaces.ts +63 -0
- package/test/authentication-social.test.ts +48 -0
- package/test/base-sdk.test.ts +26 -1
- package/test/index.test.ts +2 -1
- package/test/qelos-sdk-refresh.test.ts +2 -1
- package/test/workspaces.test.ts +170 -0
package/dist/payments.d.ts
CHANGED
|
@@ -2,11 +2,19 @@ import { QelosSDKOptions } from './types';
|
|
|
2
2
|
import BaseSDK from './base-sdk';
|
|
3
3
|
import { IPlan, ISubscription, IInvoice, ICoupon, BillingCycle } from '@qelos/global-types';
|
|
4
4
|
export interface CheckoutRequest {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/** Required when not providing `subscriptionId`. Must be a non-dynamic plan. */
|
|
6
|
+
planId?: string;
|
|
7
|
+
/** Required when not providing `subscriptionId`. */
|
|
8
|
+
billingCycle?: BillingCycle;
|
|
7
9
|
couponCode?: string;
|
|
8
10
|
successUrl?: string;
|
|
9
11
|
cancelUrl?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Pre-created subscription ID. Required for dynamic plans — the admin must set
|
|
14
|
+
* `dynamicAmount` on the subscription before this checkout call will succeed.
|
|
15
|
+
* When provided, `planId` and `billingCycle` are ignored.
|
|
16
|
+
*/
|
|
17
|
+
subscriptionId?: string;
|
|
10
18
|
}
|
|
11
19
|
export interface CheckoutResponse {
|
|
12
20
|
subscriptionId: string;
|
|
@@ -22,6 +30,24 @@ export default class QlPayments extends BaseSDK {
|
|
|
22
30
|
isActive?: boolean;
|
|
23
31
|
}): Promise<IPlan[]>;
|
|
24
32
|
getPlan(planId: string): Promise<IPlan>;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a pending subscription for the authenticated user without initiating
|
|
35
|
+
* payment. Use this as the first step for any plan, and the only step before
|
|
36
|
+
* `checkout()` for dynamic plans (the admin must call `setSubscriptionDynamicAmount`
|
|
37
|
+
* before the user can complete checkout).
|
|
38
|
+
*/
|
|
39
|
+
subscribeToPlan(planId: string, billingCycle: BillingCycle, couponCode?: string): Promise<ISubscription>;
|
|
40
|
+
/**
|
|
41
|
+
* Initiates a provider checkout session.
|
|
42
|
+
*
|
|
43
|
+
* **Static plans**: pass `planId` + `billingCycle` (a subscription is created
|
|
44
|
+
* inline).
|
|
45
|
+
*
|
|
46
|
+
* **Dynamic plans**: the user must first call `subscribeToPlan()` to create a
|
|
47
|
+
* pending subscription, then an admin must set the dynamic amount via
|
|
48
|
+
* `setSubscriptionDynamicAmount()`. Only then should this method be called with
|
|
49
|
+
* `subscriptionId` pointing to that pending subscription.
|
|
50
|
+
*/
|
|
25
51
|
checkout(params: CheckoutRequest): Promise<CheckoutResponse>;
|
|
26
52
|
getMySubscription(): Promise<ISubscription>;
|
|
27
53
|
cancelSubscription(subscriptionId: string): Promise<ISubscription>;
|
package/dist/payments.js
CHANGED
|
@@ -11,6 +11,30 @@ export default class QlPayments extends BaseSDK {
|
|
|
11
11
|
getPlan(planId) {
|
|
12
12
|
return this.callJsonApi(`${this.relativePath}/plans/${planId}`);
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a pending subscription for the authenticated user without initiating
|
|
16
|
+
* payment. Use this as the first step for any plan, and the only step before
|
|
17
|
+
* `checkout()` for dynamic plans (the admin must call `setSubscriptionDynamicAmount`
|
|
18
|
+
* before the user can complete checkout).
|
|
19
|
+
*/
|
|
20
|
+
subscribeToPlan(planId, billingCycle, couponCode) {
|
|
21
|
+
return this.callJsonApi(`${this.relativePath}/subscriptions`, {
|
|
22
|
+
method: 'post',
|
|
23
|
+
headers: { 'content-type': 'application/json' },
|
|
24
|
+
body: JSON.stringify({ planId, billingCycle, couponCode }),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Initiates a provider checkout session.
|
|
29
|
+
*
|
|
30
|
+
* **Static plans**: pass `planId` + `billingCycle` (a subscription is created
|
|
31
|
+
* inline).
|
|
32
|
+
*
|
|
33
|
+
* **Dynamic plans**: the user must first call `subscribeToPlan()` to create a
|
|
34
|
+
* pending subscription, then an admin must set the dynamic amount via
|
|
35
|
+
* `setSubscriptionDynamicAmount()`. Only then should this method be called with
|
|
36
|
+
* `subscriptionId` pointing to that pending subscription.
|
|
37
|
+
*/
|
|
14
38
|
checkout(params) {
|
|
15
39
|
return this.callJsonApi(`${this.relativePath}/checkout`, {
|
|
16
40
|
method: 'post',
|
package/dist/payments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;AA2BjC,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IACrC,YAAY,GAAG,MAAM,CAAC;IAE9B,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,QAAQ,CAAC,KAA8B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAU,GAAG,IAAI,CAAC,YAAY,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAQ,GAAG,IAAI,CAAC,YAAY,UAAU,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAc,EAAE,YAA0B,EAAE,UAAmB;QAC7E,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,gBAAgB,EACpC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;SAC3D,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAuB;QAC9B,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,WAAW,EAC/B;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CACF,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,CAAgB,GAAG,IAAI,CAAC,YAAY,mBAAmB,CAAC,CAAC;IAClF,CAAC;IAED,kBAAkB,CAAC,cAAsB;QACvC,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,kBAAkB,cAAc,SAAS,EAC7D,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,KAA2B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAa,GAAG,IAAI,CAAC,YAAY,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,WAAW,CAAW,GAAG,IAAI,CAAC,YAAY,aAAa,SAAS,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,cAAc,CAAC,IAAY,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,mBAAmB,EACvC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACvC,CACF,CAAC;IACJ,CAAC;CACF"}
|
package/dist/workspaces.d.ts
CHANGED
|
@@ -6,8 +6,11 @@ export interface IWorkspaceMember {
|
|
|
6
6
|
created?: string | Date;
|
|
7
7
|
}
|
|
8
8
|
export interface IInvite {
|
|
9
|
+
_id?: string;
|
|
9
10
|
name?: string;
|
|
10
11
|
email: string;
|
|
12
|
+
phone?: string;
|
|
13
|
+
roles?: string[];
|
|
11
14
|
created?: string | Date;
|
|
12
15
|
}
|
|
13
16
|
export interface IWorkspace {
|
|
@@ -31,4 +34,17 @@ export default class QlWorkspaces extends BaseSDK {
|
|
|
31
34
|
name: string;
|
|
32
35
|
}): Promise<IWorkspace>;
|
|
33
36
|
activate(workspaceId: string): Promise<IWorkspace>;
|
|
37
|
+
inviteUser(workspaceId: string, email: string, roles?: string[]): Promise<IWorkspace>;
|
|
38
|
+
removeMember(workspaceId: string, userId: string): Promise<{
|
|
39
|
+
message: string;
|
|
40
|
+
removedMemberId?: string;
|
|
41
|
+
userId?: string;
|
|
42
|
+
}>;
|
|
43
|
+
updateMemberRoles(workspaceId: string, userId: string, roles: string[]): Promise<{
|
|
44
|
+
message: string;
|
|
45
|
+
updatedMember?: IWorkspaceMember;
|
|
46
|
+
workspaceId?: string;
|
|
47
|
+
}>;
|
|
48
|
+
listInvites(workspaceId: string): Promise<IInvite[]>;
|
|
49
|
+
revokeInvite(workspaceId: string, inviteId: string): Promise<IWorkspace>;
|
|
34
50
|
}
|
package/dist/workspaces.js
CHANGED
|
@@ -36,5 +36,45 @@ export default class QlWorkspaces extends BaseSDK {
|
|
|
36
36
|
headers: { 'content-type': 'application/json' },
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
+
async inviteUser(workspaceId, email, roles) {
|
|
40
|
+
const ws = await this.getWorkspace(workspaceId);
|
|
41
|
+
const inviteRoles = roles && roles.length > 0 ? roles : ['member'];
|
|
42
|
+
const invites = [...(ws.invites || [])];
|
|
43
|
+
const normalized = email.trim().toLowerCase();
|
|
44
|
+
const index = invites.findIndex((i) => (i.email || '').trim().toLowerCase() === normalized);
|
|
45
|
+
if (index >= 0) {
|
|
46
|
+
invites[index] = { ...invites[index], email: invites[index].email || email, roles: inviteRoles };
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
invites.push({ email, roles: inviteRoles });
|
|
50
|
+
}
|
|
51
|
+
return this.update(workspaceId, { invites });
|
|
52
|
+
}
|
|
53
|
+
removeMember(workspaceId, userId) {
|
|
54
|
+
const path = `${this.relativePath}/${workspaceId}/members/${encodeURIComponent(userId)}`;
|
|
55
|
+
return this.callJsonApi(path, { method: 'delete' });
|
|
56
|
+
}
|
|
57
|
+
updateMemberRoles(workspaceId, userId, roles) {
|
|
58
|
+
const path = `${this.relativePath}/${workspaceId}/members/${encodeURIComponent(userId)}`;
|
|
59
|
+
return this.callJsonApi(path, {
|
|
60
|
+
method: 'put',
|
|
61
|
+
headers: { 'content-type': 'application/json' },
|
|
62
|
+
body: JSON.stringify({ roles }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async listInvites(workspaceId) {
|
|
66
|
+
const ws = await this.getWorkspace(workspaceId);
|
|
67
|
+
return ws.invites ?? [];
|
|
68
|
+
}
|
|
69
|
+
async revokeInvite(workspaceId, inviteId) {
|
|
70
|
+
const ws = await this.getWorkspace(workspaceId);
|
|
71
|
+
const prev = ws.invites || [];
|
|
72
|
+
const idStr = String(inviteId);
|
|
73
|
+
const invites = prev.filter((inv) => String(inv._id ?? '') !== idStr);
|
|
74
|
+
if (invites.length === prev.length) {
|
|
75
|
+
throw new Error('Invitation not found');
|
|
76
|
+
}
|
|
77
|
+
return this.update(workspaceId, { invites });
|
|
78
|
+
}
|
|
39
79
|
}
|
|
40
80
|
//# sourceMappingURL=workspaces.js.map
|
package/dist/workspaces.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"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"}
|
package/docs/payments.md
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Payments SDK
|
|
2
|
+
|
|
3
|
+
The payments SDK is split into two classes:
|
|
4
|
+
|
|
5
|
+
- **`QlPayments`** (`sdk.payments`) — available to any authenticated user. Covers subscribing, checkout, invoices, and coupon validation. Users cannot set prices.
|
|
6
|
+
- **`QlPaymentsAdmin`** (`adminSdk.payments`) — available to privileged callers only. Extends the user surface with plan/coupon management, cross-entity subscription control, and the ability to set dynamic amounts.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { QelosSDK } from '@qelos/sdk';
|
|
14
|
+
import { QelosAdminSDK } from '@qelos/sdk/administrator';
|
|
15
|
+
|
|
16
|
+
const sdk = new QelosSDK({ baseUrl: 'https://your-qelos-instance.com' });
|
|
17
|
+
const adminSdk = new QelosAdminSDK({ baseUrl: 'https://your-qelos-instance.com' });
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Static Plan Checkout (One Step)
|
|
23
|
+
|
|
24
|
+
For plans where the price is fixed, the user can subscribe and pay in a single `checkout()` call. Qelos creates the pending subscription internally.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// List available plans
|
|
28
|
+
const plans = await sdk.payments.getPlans({ isActive: true });
|
|
29
|
+
const plan = plans.find(p => p.name === 'Pro');
|
|
30
|
+
|
|
31
|
+
// Validate an optional coupon
|
|
32
|
+
const coupon = await sdk.payments.validateCoupon('SUMMER20', plan._id);
|
|
33
|
+
|
|
34
|
+
// Initiate checkout — subscription is created inline
|
|
35
|
+
const result = await sdk.payments.checkout({
|
|
36
|
+
planId: plan._id,
|
|
37
|
+
billingCycle: 'monthly',
|
|
38
|
+
couponCode: 'SUMMER20',
|
|
39
|
+
successUrl: 'https://myapp.com/success',
|
|
40
|
+
cancelUrl: 'https://myapp.com/cancel',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Redirect the user
|
|
44
|
+
window.location.href = result.checkoutUrl;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Dynamic Plan Two-Phase Flow
|
|
50
|
+
|
|
51
|
+
Dynamic plans have variable pricing (e.g., usage-based). The user cannot set the amount — only an admin can. The flow is:
|
|
52
|
+
|
|
53
|
+
1. User creates a pending subscription.
|
|
54
|
+
2. Admin reviews usage / context and sets the amount.
|
|
55
|
+
3. User initiates checkout with the subscription ID.
|
|
56
|
+
|
|
57
|
+
### Step 1 — User subscribes
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const subscription = await sdk.payments.subscribeToPlan(
|
|
61
|
+
'dynamic-plan-id',
|
|
62
|
+
'monthly',
|
|
63
|
+
);
|
|
64
|
+
// subscription.status === 'pending'
|
|
65
|
+
// Store subscription._id and show the user a "waiting for quote" state
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Step 2 — Admin sets the amount
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Admin SDK — run server-side or in the admin dashboard
|
|
72
|
+
await adminSdk.payments.setSubscriptionDynamicAmount(
|
|
73
|
+
subscription._id,
|
|
74
|
+
149.00, // amount in the plan's currency
|
|
75
|
+
);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 3 — User completes checkout
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const result = await sdk.payments.checkout({
|
|
82
|
+
subscriptionId: subscription._id,
|
|
83
|
+
successUrl: 'https://myapp.com/success',
|
|
84
|
+
cancelUrl: 'https://myapp.com/cancel',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
window.location.href = result.checkoutUrl;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Admin convenience shortcut
|
|
91
|
+
|
|
92
|
+
Admins can collapse steps 1–3 into a single call. This creates a pending subscription with the given amount and immediately initiates checkout:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const result = await adminSdk.payments.checkout({
|
|
96
|
+
planId: 'dynamic-plan-id',
|
|
97
|
+
billingCycle: 'monthly',
|
|
98
|
+
amount: 149.00,
|
|
99
|
+
billableEntityType: 'workspace',
|
|
100
|
+
billableEntityId: 'workspace-id',
|
|
101
|
+
successUrl: 'https://myapp.com/success',
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Listing Plans and Subscriptions
|
|
108
|
+
|
|
109
|
+
### User SDK
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Public plan listing (unauthenticated)
|
|
113
|
+
const plans = await sdk.payments.getPlans({ isActive: true });
|
|
114
|
+
|
|
115
|
+
// Single plan
|
|
116
|
+
const plan = await sdk.payments.getPlan('plan-id');
|
|
117
|
+
|
|
118
|
+
// Current user's active subscription
|
|
119
|
+
const subscription = await sdk.payments.getMySubscription();
|
|
120
|
+
|
|
121
|
+
// User's invoices
|
|
122
|
+
const invoices = await sdk.payments.getInvoices();
|
|
123
|
+
const invoice = await sdk.payments.getInvoice('invoice-id');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Admin SDK
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// All plans (including inactive)
|
|
130
|
+
const allPlans = await adminSdk.payments.getPlans();
|
|
131
|
+
|
|
132
|
+
// All subscriptions with optional filters
|
|
133
|
+
const workspaceSubs = await adminSdk.payments.getSubscriptions({
|
|
134
|
+
billableEntityType: 'workspace',
|
|
135
|
+
billableEntityId: 'workspace-id',
|
|
136
|
+
status: 'active',
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// All invoices across entities
|
|
140
|
+
const invoices = await adminSdk.payments.getInvoices({
|
|
141
|
+
billableEntityType: 'user',
|
|
142
|
+
billableEntityId: 'user-id',
|
|
143
|
+
status: 'paid',
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Coupon Validation
|
|
150
|
+
|
|
151
|
+
Validate a coupon before showing it applied in the UI:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
try {
|
|
155
|
+
const coupon = await sdk.payments.validateCoupon('PROMO10', 'plan-id');
|
|
156
|
+
console.log(coupon.discountType); // 'percentage' | 'fixed'
|
|
157
|
+
console.log(coupon.discountValue); // e.g. 10 (%)
|
|
158
|
+
} catch (err) {
|
|
159
|
+
// err.code: COUPON_NOT_FOUND | COUPON_EXPIRED | COUPON_NOT_APPLICABLE | ...
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Invoice Retrieval
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// User's own invoices
|
|
169
|
+
const invoices = await sdk.payments.getInvoices({ status: 'paid' });
|
|
170
|
+
|
|
171
|
+
// Single invoice (e.g. for download link)
|
|
172
|
+
const invoice = await sdk.payments.getInvoice('invoice-id');
|
|
173
|
+
console.log(invoice.invoiceUrl);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Cancellation
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// User cancels their own subscription
|
|
182
|
+
await sdk.payments.cancelSubscription('subscription-id');
|
|
183
|
+
|
|
184
|
+
// Admin cancels any subscription
|
|
185
|
+
await adminSdk.payments.cancelSubscription('subscription-id');
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Admin Plan Management
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Create a plan
|
|
194
|
+
const plan = await adminSdk.payments.createPlan({
|
|
195
|
+
name: 'Enterprise',
|
|
196
|
+
monthlyPrice: 299,
|
|
197
|
+
yearlyPrice: 2990,
|
|
198
|
+
currency: 'USD',
|
|
199
|
+
dynamic: false,
|
|
200
|
+
isActive: true,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Create a dynamic plan
|
|
204
|
+
const dynamicPlan = await adminSdk.payments.createPlan({
|
|
205
|
+
name: 'Usage-Based',
|
|
206
|
+
currency: 'USD',
|
|
207
|
+
dynamic: true,
|
|
208
|
+
isActive: true,
|
|
209
|
+
monthlyPrice: 0,
|
|
210
|
+
yearlyPrice: 0,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Update
|
|
214
|
+
await adminSdk.payments.updatePlan(plan._id, { monthlyPrice: 349 });
|
|
215
|
+
|
|
216
|
+
// Delete
|
|
217
|
+
await adminSdk.payments.deletePlan(plan._id);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Admin Coupon Management
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Create a 20% off coupon
|
|
226
|
+
const coupon = await adminSdk.payments.createCoupon({
|
|
227
|
+
code: 'SUMMER20',
|
|
228
|
+
discountType: 'percentage',
|
|
229
|
+
discountValue: 20,
|
|
230
|
+
isActive: true,
|
|
231
|
+
applicablePlanIds: ['plan-id'],
|
|
232
|
+
maxRedemptions: 100,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Update
|
|
236
|
+
await adminSdk.payments.updateCoupon(coupon._id, { isActive: false });
|
|
237
|
+
|
|
238
|
+
// Delete
|
|
239
|
+
await adminSdk.payments.deleteCoupon(coupon._id);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## `QlPayments` Reference (User SDK)
|
|
245
|
+
|
|
246
|
+
| Method | Description |
|
|
247
|
+
|---|---|
|
|
248
|
+
| `getPlans(query?)` | List public plans |
|
|
249
|
+
| `getPlan(planId)` | Get a single plan |
|
|
250
|
+
| `subscribeToPlan(planId, billingCycle, couponCode?)` | Create a pending subscription (first step for dynamic plans) |
|
|
251
|
+
| `checkout(params)` | Initiate a checkout session |
|
|
252
|
+
| `getMySubscription()` | Get the current user's active subscription |
|
|
253
|
+
| `cancelSubscription(subscriptionId)` | Cancel a subscription |
|
|
254
|
+
| `getInvoices(query?)` | List the current user's invoices |
|
|
255
|
+
| `getInvoice(invoiceId)` | Get a single invoice |
|
|
256
|
+
| `validateCoupon(code, planId?)` | Validate a coupon code |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## `QlPaymentsAdmin` Reference (Admin SDK)
|
|
261
|
+
|
|
262
|
+
| Method | Description |
|
|
263
|
+
|---|---|
|
|
264
|
+
| `getPlans(query?)` | List all plans |
|
|
265
|
+
| `getPlan(planId)` | Get a single plan |
|
|
266
|
+
| `createPlan(data)` | Create a plan |
|
|
267
|
+
| `updatePlan(planId, data)` | Update a plan |
|
|
268
|
+
| `deletePlan(planId)` | Delete a plan |
|
|
269
|
+
| `checkout(params)` | Initiate checkout with entity overrides and optional `amount` |
|
|
270
|
+
| `getSubscriptions(query?)` | List subscriptions across all entities |
|
|
271
|
+
| `getSubscription(subscriptionId)` | Get a single subscription |
|
|
272
|
+
| `createSubscription(data)` | Create a pending subscription on behalf of any entity |
|
|
273
|
+
| `cancelSubscription(subscriptionId)` | Cancel any subscription |
|
|
274
|
+
| `setSubscriptionDynamicAmount(subscriptionId, amount)` | Set or update the dynamic amount on a pending subscription |
|
|
275
|
+
| `getInvoices(query?)` | List invoices across all entities |
|
|
276
|
+
| `getInvoice(invoiceId)` | Get a single invoice |
|
|
277
|
+
| `getCoupons(query?)` | List coupons |
|
|
278
|
+
| `getCoupon(couponId)` | Get a single coupon |
|
|
279
|
+
| `createCoupon(data)` | Create a coupon |
|
|
280
|
+
| `updateCoupon(couponId, data)` | Update a coupon |
|
|
281
|
+
| `deleteCoupon(couponId)` | Delete a coupon |
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Permissions Summary
|
|
286
|
+
|
|
287
|
+
| Action | User SDK | Admin SDK |
|
|
288
|
+
|---|---|---|
|
|
289
|
+
| List/get plans | public plans only | all plans |
|
|
290
|
+
| Create/update/delete plans | no | yes |
|
|
291
|
+
| Create subscription (own entity) | yes | yes |
|
|
292
|
+
| Create subscription (any entity) | no | yes |
|
|
293
|
+
| Set `dynamicAmount` | no | yes |
|
|
294
|
+
| Initiate checkout | yes | yes, with entity override |
|
|
295
|
+
| Set checkout `amount` directly | no | yes (dynamic plans) |
|
|
296
|
+
| List own subscriptions/invoices | yes | yes |
|
|
297
|
+
| List all subscriptions/invoices | no | yes |
|
|
298
|
+
| Cancel own subscription | yes | yes |
|
|
299
|
+
| Cancel any subscription | no | yes |
|
|
300
|
+
| Validate coupon | yes | yes |
|
|
301
|
+
| Manage coupons | no | yes |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qelos/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "SDK for Qelos API",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"access": "public"
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
|
-
"@qelos/global-types": "^
|
|
105
|
+
"@qelos/global-types": "^4.1.0"
|
|
106
106
|
},
|
|
107
107
|
"devDependencies": {
|
|
108
108
|
"tsx": "^4.21.0",
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Compile-only type test for `BlueprintEntitiesRegistry` augmentation
|
|
2
|
+
// and the overloaded `entitiesOf` signatures. Runs as part of `tsc --noEmit`
|
|
3
|
+
// (type-check / build); not executed by `node --test`.
|
|
4
|
+
|
|
5
|
+
import QlBlueprints from '../blueprints';
|
|
6
|
+
import type { IBaseBlueprintEntity } from '../blueprints-entities';
|
|
7
|
+
import type QlBlueprintEntities from '../blueprints-entities';
|
|
8
|
+
|
|
9
|
+
interface TodoProperties {
|
|
10
|
+
title: string;
|
|
11
|
+
done: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface TodoEntity extends IBaseBlueprintEntity, TodoProperties {}
|
|
15
|
+
|
|
16
|
+
declare module '../blueprints' {
|
|
17
|
+
interface BlueprintEntitiesRegistry {
|
|
18
|
+
todo: TodoEntity;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type Equal<A, B> =
|
|
23
|
+
(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
|
|
24
|
+
type Expect<T extends true> = T;
|
|
25
|
+
|
|
26
|
+
declare const blueprints: QlBlueprints;
|
|
27
|
+
|
|
28
|
+
// 1. Registry-keyed lookup resolves to the augmented entity type.
|
|
29
|
+
const todos = blueprints.entitiesOf('todo');
|
|
30
|
+
type TodosCheck = Expect<Equal<typeof todos, QlBlueprintEntities<TodoEntity>>>;
|
|
31
|
+
|
|
32
|
+
// `find()` returns the merged entity shape from the registry.
|
|
33
|
+
declare const found: Awaited<ReturnType<typeof todos.find>>;
|
|
34
|
+
type FoundCheck = Expect<Equal<typeof found, (IBaseBlueprintEntity & TodoEntity)[]>>;
|
|
35
|
+
|
|
36
|
+
// 2. Explicit-generic fallback still compiles for unregistered keys.
|
|
37
|
+
interface AdHoc {
|
|
38
|
+
name: string;
|
|
39
|
+
}
|
|
40
|
+
const adhoc = blueprints.entitiesOf<AdHoc>('not-in-registry');
|
|
41
|
+
type AdHocCheck = Expect<Equal<typeof adhoc, QlBlueprintEntities<AdHoc>>>;
|
|
42
|
+
|
|
43
|
+
// 3. Plain string key with no generic falls back to `any` (legacy behavior).
|
|
44
|
+
const dynamicKey: string = 'todo';
|
|
45
|
+
const loose = blueprints.entitiesOf(dynamicKey);
|
|
46
|
+
type LooseCheck = Expect<Equal<typeof loose, QlBlueprintEntities<any>>>;
|
|
47
|
+
|
|
48
|
+
// Mark generated checks as used so the file remains a valid module.
|
|
49
|
+
export type _Checks = [TodosCheck, FoundCheck, AdHocCheck, LooseCheck];
|
|
@@ -4,6 +4,7 @@ import BaseSDK from '../base-sdk';
|
|
|
4
4
|
export interface IQelosEvent {
|
|
5
5
|
tenant: string;
|
|
6
6
|
user?: string;
|
|
7
|
+
workspace?: string;
|
|
7
8
|
source: string;
|
|
8
9
|
kind: string;
|
|
9
10
|
eventName: string;
|
|
@@ -19,15 +20,19 @@ export default class QlEvents extends BaseSDK {
|
|
|
19
20
|
super(options)
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
getList(params?: { page?: number; kind?: string; eventName?: string; source?: string; user?: string; workspace?: string; period?: string }) {
|
|
23
|
+
getList(params?: { page?: number; limit?: number; kind?: string; eventName?: string; source?: string; user?: string; workspace?: string; search?: string; period?: string; from?: string; to?: string }) {
|
|
23
24
|
const queryParams = new URLSearchParams();
|
|
24
25
|
if (params?.page !== undefined) queryParams.append('page', params.page.toString());
|
|
26
|
+
if (params?.limit !== undefined) queryParams.append('limit', params.limit.toString());
|
|
25
27
|
if (params?.kind) queryParams.append('kind', params.kind);
|
|
26
28
|
if (params?.eventName) queryParams.append('eventName', params.eventName);
|
|
27
29
|
if (params?.source) queryParams.append('source', params.source);
|
|
28
30
|
if (params?.user) queryParams.append('user', params.user);
|
|
29
31
|
if (params?.workspace) queryParams.append('workspace', params.workspace);
|
|
32
|
+
if (params?.search) queryParams.append('search', params.search);
|
|
30
33
|
if (params?.period) queryParams.append('period', params.period);
|
|
34
|
+
if (params?.from) queryParams.append('from', params.from);
|
|
35
|
+
if (params?.to) queryParams.append('to', params.to);
|
|
31
36
|
|
|
32
37
|
const queryString = queryParams.toString();
|
|
33
38
|
return this.callJsonApi<IQelosEvent[]>(this.relativePath + (queryString ? '?' + queryString : ''));
|
|
@@ -2,9 +2,42 @@ import { QelosSDKOptions } from '../types';
|
|
|
2
2
|
import BaseSDK from '../base-sdk';
|
|
3
3
|
import {
|
|
4
4
|
IPlan, ISubscription, IInvoice, ICoupon,
|
|
5
|
-
BillableEntityType, SubscriptionStatus, InvoiceStatus,
|
|
5
|
+
BillableEntityType, SubscriptionStatus, InvoiceStatus, BillingCycle,
|
|
6
6
|
} from '@qelos/global-types';
|
|
7
7
|
|
|
8
|
+
export interface AdminCheckoutRequest {
|
|
9
|
+
planId: string;
|
|
10
|
+
billingCycle: BillingCycle;
|
|
11
|
+
/** When omitted, the authenticated user / default billable entity is used (same as public checkout). */
|
|
12
|
+
billableEntityType?: BillableEntityType;
|
|
13
|
+
billableEntityId?: string;
|
|
14
|
+
couponCode?: string;
|
|
15
|
+
successUrl?: string;
|
|
16
|
+
cancelUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Admin-only. For plans with `dynamic: true`, sets the `dynamicAmount` on the
|
|
19
|
+
* pending subscription before initiating checkout. Regular users cannot set this;
|
|
20
|
+
* use `setSubscriptionDynamicAmount()` + a separate `checkout()` call instead.
|
|
21
|
+
*/
|
|
22
|
+
amount?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CreateSubscriptionData {
|
|
26
|
+
planId: string;
|
|
27
|
+
billingCycle: BillingCycle;
|
|
28
|
+
billableEntityType: BillableEntityType;
|
|
29
|
+
billableEntityId: string;
|
|
30
|
+
/** Required for plans with `dynamic: true` before checkout can be initiated. */
|
|
31
|
+
dynamicAmount?: number;
|
|
32
|
+
couponCode?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface AdminCheckoutResponse {
|
|
36
|
+
subscriptionId: string;
|
|
37
|
+
checkoutUrl?: string;
|
|
38
|
+
clientToken?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
8
41
|
export default class QlPaymentsAdmin extends BaseSDK {
|
|
9
42
|
constructor(private options: QelosSDKOptions) {
|
|
10
43
|
super(options);
|
|
@@ -41,6 +74,18 @@ export default class QlPaymentsAdmin extends BaseSDK {
|
|
|
41
74
|
return this.callJsonApi<IPlan>(`/api/plans/${planId}`, { method: 'delete' });
|
|
42
75
|
}
|
|
43
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Start subscription checkout (same as `sdk.payments.checkout`, plus optional billable-entity overrides for admins).
|
|
79
|
+
* For plans with `dynamic: true`, `amount` is required.
|
|
80
|
+
*/
|
|
81
|
+
checkout(params: AdminCheckoutRequest) {
|
|
82
|
+
return this.callJsonApi<AdminCheckoutResponse>('/api/checkout', {
|
|
83
|
+
method: 'post',
|
|
84
|
+
headers: { 'content-type': 'application/json' },
|
|
85
|
+
body: JSON.stringify(params),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
44
89
|
// --- Subscriptions ---
|
|
45
90
|
|
|
46
91
|
getSubscriptions(query?: {
|
|
@@ -56,6 +101,19 @@ export default class QlPaymentsAdmin extends BaseSDK {
|
|
|
56
101
|
return this.callJsonApi<ISubscription>(`/api/subscriptions/${subscriptionId}`);
|
|
57
102
|
}
|
|
58
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Creates a pending subscription on behalf of any billable entity. Admins can
|
|
106
|
+
* also set `dynamicAmount` here for dynamic plans, making the subscription
|
|
107
|
+
* immediately ready for checkout.
|
|
108
|
+
*/
|
|
109
|
+
createSubscription(data: CreateSubscriptionData) {
|
|
110
|
+
return this.callJsonApi<ISubscription>('/api/subscriptions', {
|
|
111
|
+
method: 'post',
|
|
112
|
+
headers: { 'content-type': 'application/json' },
|
|
113
|
+
body: JSON.stringify(data),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
59
117
|
cancelSubscription(subscriptionId: string) {
|
|
60
118
|
return this.callJsonApi<ISubscription>(
|
|
61
119
|
`/api/subscriptions/${subscriptionId}/cancel`,
|
|
@@ -63,6 +121,21 @@ export default class QlPaymentsAdmin extends BaseSDK {
|
|
|
63
121
|
);
|
|
64
122
|
}
|
|
65
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Sets or updates the dynamic amount for a pending subscription. Only admins
|
|
126
|
+
* can call this. Must be done before a user can complete checkout on a dynamic plan.
|
|
127
|
+
*/
|
|
128
|
+
setSubscriptionDynamicAmount(subscriptionId: string, amount: number) {
|
|
129
|
+
return this.callJsonApi<ISubscription>(
|
|
130
|
+
`/api/subscriptions/${subscriptionId}/dynamic-amount`,
|
|
131
|
+
{
|
|
132
|
+
method: 'put',
|
|
133
|
+
headers: { 'content-type': 'application/json' },
|
|
134
|
+
body: JSON.stringify({ amount }),
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
66
139
|
// --- Invoices ---
|
|
67
140
|
|
|
68
141
|
getInvoices(query?: {
|