tru-402 0.1.1 → 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.
- package/dist/src/challenge.js +11 -11
- package/dist/src/challenge.js.map +1 -1
- package/dist/src/identity.d.ts +1 -1
- package/dist/src/identity.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware.d.ts +6 -0
- package/dist/src/middleware.d.ts.map +1 -1
- package/dist/src/middleware.js +38 -10
- package/dist/src/middleware.js.map +1 -1
- package/dist/src/session.d.ts +16 -0
- package/dist/src/session.d.ts.map +1 -1
- package/dist/src/session.js +38 -0
- package/dist/src/session.js.map +1 -1
- package/package.json +1 -1
package/dist/src/challenge.js
CHANGED
|
@@ -31,7 +31,7 @@ export function generateChallenge(params) {
|
|
|
31
31
|
// Self-documenting body
|
|
32
32
|
const body = {
|
|
33
33
|
error: 'payment_required',
|
|
34
|
-
message: `This API costs $${amountDollars.toFixed(2)} per request.
|
|
34
|
+
message: `This API costs $${amountDollars.toFixed(2)} per request. Usage is batched and settled daily — one charge, not one per request.`,
|
|
35
35
|
amount: amountDollars,
|
|
36
36
|
currency,
|
|
37
37
|
description: options.description || undefined,
|
|
@@ -49,8 +49,9 @@ export function generateChallenge(params) {
|
|
|
49
49
|
email: '<your_email>',
|
|
50
50
|
},
|
|
51
51
|
step_1_note: "If you don't have a tru account, open the auth_url below in the user's browser first.",
|
|
52
|
-
step_2: 'The response includes an authorization_header value',
|
|
52
|
+
step_2: 'The response includes an authorization_header value and your email',
|
|
53
53
|
step_3: 'Retry this same request with that Authorization header',
|
|
54
|
+
step_4: 'For subsequent requests, send X-Tru-User: <your_email> header instead — no re-auth needed',
|
|
54
55
|
},
|
|
55
56
|
auth_url: `${config.apiUrl}/connect`,
|
|
56
57
|
auth_url_note: 'First-time users: open this URL to link a payment method via Stripe Link (10 seconds)',
|
|
@@ -63,15 +64,14 @@ export function generateChallenge(params) {
|
|
|
63
64
|
expires,
|
|
64
65
|
},
|
|
65
66
|
};
|
|
66
|
-
// Include
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
67
|
+
// Include daily settlement info
|
|
68
|
+
const dailyCap = options.dailyCap ?? 25;
|
|
69
|
+
body.billing = {
|
|
70
|
+
model: 'daily_settlement',
|
|
71
|
+
message: `Usage is tracked per request and settled once daily (or when $${dailyCap.toFixed(2)} cap is reached). One charge, not one per request.`,
|
|
72
|
+
daily_cap: dailyCap,
|
|
73
|
+
subsequent_requests: 'After your first payment, send X-Tru-User: <your_email> header — no re-auth needed.',
|
|
74
|
+
};
|
|
75
75
|
// Include plan upsell if configured
|
|
76
76
|
if (options.plan) {
|
|
77
77
|
body.plan_available = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../src/challenge.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B;;GAEG;AACH,SAAS,WAAW,CAAC,GAA4B;IAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;SACpC,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxB,CAAC;AAeD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAuB;IACvD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC/C,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACxC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ;IAE5E,kCAAkC;IAClC,MAAM,OAAO,GAAG,WAAW,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;QAC7B,QAAQ;QACR,GAAG,EAAE,UAAU;KAChB,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC;IAEjD,0BAA0B;IAC1B,MAAM,MAAM,GAAG,eAAe,WAAW,aAAa,KAAK,8CAA8C,OAAO,eAAe,OAAO,GAAG,CAAC;IAE1I,wBAAwB;IACxB,MAAM,IAAI,GAA4B;QACpC,KAAK,EAAE,kBAAkB;QACzB,OAAO,EAAE,mBAAmB,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../src/challenge.ts"],"names":[],"mappings":"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"}
|
package/dist/src/identity.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,GAAG,CAAC,EAAE,WAAW,CAAC;SACnB;KACF;CACF"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { createMiddleware as trux } from './middleware.js';
|
|
|
2
2
|
export type { TruIdentity, TruxOptions, TruxPlan, TruxConfig } from './identity.js';
|
|
3
3
|
export { generateChallenge } from './challenge.js';
|
|
4
4
|
export { verifyCredential } from './verify.js';
|
|
5
|
-
export { debitSession, createSession } from './session.js';
|
|
5
|
+
export { recordUsage, debitSession, createSession } from './session.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createMiddleware as trux } from './middleware.js';
|
|
2
2
|
export { generateChallenge } from './challenge.js';
|
|
3
3
|
export { verifyCredential } from './verify.js';
|
|
4
|
-
export { debitSession, createSession } from './session.js';
|
|
4
|
+
export { recordUsage, debitSession, createSession } from './session.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/src/middleware.d.ts
CHANGED
|
@@ -3,6 +3,12 @@ import type { TruxOptions } from './identity.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Create the trux Express middleware.
|
|
5
5
|
*
|
|
6
|
+
* Flow:
|
|
7
|
+
* 1. Existing auth (API keys, sessions) → pass through
|
|
8
|
+
* 2. X-Tru-User header (returning user) → record usage, settle daily
|
|
9
|
+
* 3. SPT credential (first request after 402) → verify, record usage, return X-Tru-User for next time
|
|
10
|
+
* 4. No auth → 402 with self-documenting payment instructions
|
|
11
|
+
*
|
|
6
12
|
* Usage:
|
|
7
13
|
* ```
|
|
8
14
|
* app.post('/api/generate', trux({ amount: 0.05 }), handler);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,eAAe,CAAC;AA4E7D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,IAGrC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAmE9D"}
|
package/dist/src/middleware.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { generateChallenge } from './challenge.js';
|
|
2
2
|
import { verifyCredential } from './verify.js';
|
|
3
|
-
import { debitSession } from './session.js';
|
|
3
|
+
import { recordUsage, debitSession } from './session.js';
|
|
4
4
|
/**
|
|
5
5
|
* Resolve trux config from environment variables.
|
|
6
6
|
*/
|
|
@@ -40,23 +40,25 @@ function extractCredential(authHeader) {
|
|
|
40
40
|
}
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract user email from X-Tru-User header.
|
|
45
|
+
* Set after initial 402 resolution — allows usage tracking without re-verification.
|
|
46
|
+
*/
|
|
47
|
+
function extractTruUser(req) {
|
|
48
|
+
return req.headers['x-tru-user'] || null;
|
|
49
|
+
}
|
|
43
50
|
/**
|
|
44
51
|
* Check if request has existing auth that should bypass payment.
|
|
45
|
-
* Looks for API keys, session cookies, or other standard auth mechanisms.
|
|
46
52
|
*/
|
|
47
53
|
function hasExistingAuth(req, options) {
|
|
48
|
-
// Custom passthrough check
|
|
49
54
|
if (options.passthrough?.(req))
|
|
50
55
|
return true;
|
|
51
|
-
// Standard auth headers (non-SPT bearer tokens, basic auth, API keys)
|
|
52
56
|
const auth = req.headers.authorization;
|
|
53
57
|
if (auth && !auth.startsWith('Payment ') && !auth.startsWith('Bearer spt_')) {
|
|
54
58
|
return true;
|
|
55
59
|
}
|
|
56
|
-
// Common API key headers
|
|
57
60
|
if (req.headers['x-api-key'] || req.headers['api-key'])
|
|
58
61
|
return true;
|
|
59
|
-
// Session cookies
|
|
60
62
|
if (req.cookies?.session || req.cookies?.token)
|
|
61
63
|
return true;
|
|
62
64
|
return false;
|
|
@@ -64,6 +66,12 @@ function hasExistingAuth(req, options) {
|
|
|
64
66
|
/**
|
|
65
67
|
* Create the trux Express middleware.
|
|
66
68
|
*
|
|
69
|
+
* Flow:
|
|
70
|
+
* 1. Existing auth (API keys, sessions) → pass through
|
|
71
|
+
* 2. X-Tru-User header (returning user) → record usage, settle daily
|
|
72
|
+
* 3. SPT credential (first request after 402) → verify, record usage, return X-Tru-User for next time
|
|
73
|
+
* 4. No auth → 402 with self-documenting payment instructions
|
|
74
|
+
*
|
|
67
75
|
* Usage:
|
|
68
76
|
* ```
|
|
69
77
|
* app.post('/api/generate', trux({ amount: 0.05 }), handler);
|
|
@@ -74,21 +82,42 @@ export function createMiddleware(options) {
|
|
|
74
82
|
return async (req, res, next) => {
|
|
75
83
|
try {
|
|
76
84
|
const config = getConfig();
|
|
85
|
+
const endpoint = `${req.method} ${req.route?.path || req.path}`;
|
|
77
86
|
// 1. Passthrough for existing auth (existing customers unaffected)
|
|
78
87
|
if (hasExistingAuth(req, options)) {
|
|
79
88
|
return next();
|
|
80
89
|
}
|
|
81
|
-
// 2. Check for
|
|
90
|
+
// 2. Check for returning user (X-Tru-User header — set after first payment)
|
|
91
|
+
// Record usage for daily batch settlement. No Stripe call.
|
|
92
|
+
const truUser = extractTruUser(req);
|
|
93
|
+
if (truUser) {
|
|
94
|
+
const dailyCapCents = Math.round((options.dailyCap ?? 25) * 100);
|
|
95
|
+
const result = await recordUsage(truUser, amountCents, config, {
|
|
96
|
+
description: options.description,
|
|
97
|
+
agentName: req.headers['x-tru-agent'],
|
|
98
|
+
endpoint,
|
|
99
|
+
dailyCapCents,
|
|
100
|
+
});
|
|
101
|
+
if (result.ok && result.identity) {
|
|
102
|
+
req.tru = result.identity;
|
|
103
|
+
return next();
|
|
104
|
+
}
|
|
105
|
+
// User not found or no payment method — fall through to 402
|
|
106
|
+
}
|
|
107
|
+
// 3. Check for SPT credential (Authorization: Payment <spt_xxx>)
|
|
108
|
+
// This is the first request after resolving a 402 challenge.
|
|
82
109
|
const credential = extractCredential(req.headers.authorization);
|
|
83
110
|
if (credential) {
|
|
84
111
|
const result = await verifyCredential(credential, amountCents, config);
|
|
85
112
|
if (result.valid && result.identity) {
|
|
86
113
|
req.tru = result.identity;
|
|
114
|
+
// Tell the agent to use X-Tru-User for subsequent requests
|
|
115
|
+
res.setHeader('X-Tru-User', result.identity.email);
|
|
87
116
|
return next();
|
|
88
117
|
}
|
|
89
118
|
// Invalid credential — fall through to 402
|
|
90
119
|
}
|
|
91
|
-
//
|
|
120
|
+
// 4. Check for session header (X-Tru-Session — legacy pre-auth sessions)
|
|
92
121
|
const sessionId = req.headers['x-tru-session'];
|
|
93
122
|
if (sessionId) {
|
|
94
123
|
const result = await debitSession(sessionId, amountCents, config);
|
|
@@ -96,9 +125,8 @@ export function createMiddleware(options) {
|
|
|
96
125
|
req.tru = result.identity;
|
|
97
126
|
return next();
|
|
98
127
|
}
|
|
99
|
-
// Session exhausted or invalid — fall through to 402
|
|
100
128
|
}
|
|
101
|
-
//
|
|
129
|
+
// 5. No valid auth — return 402 with self-documenting challenge
|
|
102
130
|
const requestUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
|
|
103
131
|
const challenge = generateChallenge({
|
|
104
132
|
options,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEzD;;GAEG;AACH,SAAS,aAAa;IACpB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAEvC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK;QACL,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,gBAAgB;QACnD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QACrC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;KAC1C,CAAC;AACJ,CAAC;AAED,+BAA+B;AAC/B,IAAI,OAAO,GAAsB,IAAI,CAAC;AACtC,SAAS,SAAS;IAChB,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,aAAa,EAAE,CAAC;IACxC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,UAA8B;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACzC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAY;IAClC,OAAQ,GAAG,CAAC,OAAO,CAAC,YAAY,CAAY,IAAI,IAAI,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAY,EAAE,OAAoB;IACzD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;IACvC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAE5D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAErD,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC/D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAEhE,mEAAmE;YACnE,IAAI,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;gBAClC,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAED,4EAA4E;YAC5E,8DAA8D;YAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;gBACjE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE;oBAC7D,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAW;oBAC/C,QAAQ;oBACR,aAAa;iBACd,CAAC,CAAC;gBACH,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACjC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;oBAC1B,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBACD,4DAA4D;YAC9D,CAAC;YAED,iEAAiE;YACjE,gEAAgE;YAChE,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAChE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;gBACvE,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACpC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;oBAC1B,2DAA2D;oBAC3D,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACnD,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBACD,2CAA2C;YAC7C,CAAC;YAED,yEAAyE;YACzE,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAuB,CAAC;YACrE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;gBAClE,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACjC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;oBAC1B,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;YAED,gEAAgE;YAChE,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAC5E,MAAM,SAAS,GAAG,iBAAiB,CAAC;gBAClC,OAAO;gBACP,MAAM;gBACN,UAAU;aACX,CAAC,CAAC;YAEH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;iBACZ,GAAG,CAAC,kBAAkB,EAAE,SAAS,CAAC,MAAM,CAAC;iBACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/src/session.d.ts
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import type { TruIdentity, TruxConfig } from './identity.js';
|
|
2
|
+
interface RecordUsageResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
usage_id?: string;
|
|
5
|
+
identity?: TruIdentity;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Record usage for daily batch settlement. No Stripe charge happens now —
|
|
10
|
+
* tru settles all usage at end of day in one charge per user.
|
|
11
|
+
*/
|
|
12
|
+
export declare function recordUsage(userEmail: string, amountCents: number, config: TruxConfig, opts?: {
|
|
13
|
+
description?: string;
|
|
14
|
+
agentName?: string;
|
|
15
|
+
endpoint?: string;
|
|
16
|
+
dailyCapCents?: number;
|
|
17
|
+
}): Promise<RecordUsageResult>;
|
|
2
18
|
interface SessionDebitResult {
|
|
3
19
|
ok: boolean;
|
|
4
20
|
remaining_cents?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI7D,UAAU,iBAAiB;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7F,OAAO,CAAC,iBAAiB,CAAC,CAoC5B;AAID,UAAU,kBAAkB;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAkB1D"}
|
package/dist/src/session.js
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record usage for daily batch settlement. No Stripe charge happens now —
|
|
3
|
+
* tru settles all usage at end of day in one charge per user.
|
|
4
|
+
*/
|
|
5
|
+
export async function recordUsage(userEmail, amountCents, config, opts) {
|
|
6
|
+
const res = await fetch(`${config.apiUrl}/api/mpp/usage`, {
|
|
7
|
+
method: 'POST',
|
|
8
|
+
headers: {
|
|
9
|
+
'Content-Type': 'application/json',
|
|
10
|
+
'X-API-Key': config.apiKey,
|
|
11
|
+
},
|
|
12
|
+
body: JSON.stringify({
|
|
13
|
+
user_email: userEmail,
|
|
14
|
+
amount_cents: amountCents,
|
|
15
|
+
description: opts?.description,
|
|
16
|
+
agent_name: opts?.agentName,
|
|
17
|
+
endpoint: opts?.endpoint,
|
|
18
|
+
daily_cap_cents: opts?.dailyCapCents,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
const data = await res.json();
|
|
22
|
+
if (!res.ok || !data.ok) {
|
|
23
|
+
return { ok: false, error: data.error || `HTTP ${res.status}` };
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
ok: true,
|
|
27
|
+
usage_id: data.usage_id,
|
|
28
|
+
identity: data.identity ? {
|
|
29
|
+
email: data.identity.email,
|
|
30
|
+
name: data.identity.name,
|
|
31
|
+
userId: data.identity.userId,
|
|
32
|
+
cardBrand: data.identity.cardBrand,
|
|
33
|
+
cardLast4: data.identity.cardLast4,
|
|
34
|
+
agentName: data.identity.agentName,
|
|
35
|
+
chargeId: data.identity.chargeId,
|
|
36
|
+
} : undefined,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
1
39
|
/**
|
|
2
40
|
* Debit from an existing trux session.
|
|
3
41
|
*/
|
package/dist/src/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|