tru-402 0.4.0 → 0.5.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/dist/bin/trux.js +1 -2
- package/dist/bin/trux.js.map +1 -1
- package/dist/src/challenge.d.ts +5 -3
- package/dist/src/challenge.d.ts.map +1 -1
- package/dist/src/challenge.js +11 -18
- package/dist/src/challenge.js.map +1 -1
- package/dist/src/identity.d.ts +1 -15
- package/dist/src/identity.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/index.d.ts +5 -0
- package/dist/src/init/index.d.ts.map +1 -1
- package/dist/src/init/index.js +73 -119
- package/dist/src/init/index.js.map +1 -1
- package/dist/src/middleware.d.ts +17 -5
- package/dist/src/middleware.d.ts.map +1 -1
- package/dist/src/middleware.js +78 -72
- package/dist/src/middleware.js.map +1 -1
- package/dist/src/session.d.ts +28 -0
- package/dist/src/session.d.ts.map +1 -1
- package/dist/src/session.js +4 -0
- package/dist/src/session.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/trux.js
CHANGED
|
@@ -13,7 +13,7 @@ else if (command === '--help' || command === '-h') {
|
|
|
13
13
|
tru-402 — One-line middleware for agent commerce
|
|
14
14
|
|
|
15
15
|
Usage:
|
|
16
|
-
npx tru-402 init
|
|
16
|
+
npx tru-402 init Install tru-402 + MCP server, then set up via your AI assistant
|
|
17
17
|
|
|
18
18
|
Options:
|
|
19
19
|
--help, -h Show this help message
|
|
@@ -23,7 +23,6 @@ Learn more: https://tru.so/docs
|
|
|
23
23
|
`);
|
|
24
24
|
}
|
|
25
25
|
else if (command === '--version' || command === '-v') {
|
|
26
|
-
// Read version from package.json at runtime
|
|
27
26
|
const { readFileSync } = await import('fs');
|
|
28
27
|
const { resolve, dirname } = await import('path');
|
|
29
28
|
const { fileURLToPath } = await import('url');
|
package/dist/bin/trux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trux.js","sourceRoot":"","sources":["../../bin/trux.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACnC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;CAWb,CAAC,CAAC;AACH,CAAC;KAAM,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IACvD,
|
|
1
|
+
{"version":3,"file":"trux.js","sourceRoot":"","sources":["../../bin/trux.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACnC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;CAWb,CAAC,CAAC;AACH,CAAC;KAAM,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/src/challenge.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TruxConfig } from './identity.js';
|
|
2
2
|
export interface ChallengeParams {
|
|
3
|
-
|
|
4
|
-
options: Omit<TruxOptions, 'amount'> & {
|
|
3
|
+
options: {
|
|
5
4
|
amount: number;
|
|
5
|
+
currency?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
dailyCap?: number;
|
|
6
8
|
};
|
|
7
9
|
config: TruxConfig;
|
|
8
10
|
requestUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../src/challenge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../src/challenge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAahD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxF,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,iBAAiB,CAsE5E"}
|
package/dist/src/challenge.js
CHANGED
|
@@ -36,8 +36,13 @@ export function generateChallenge(params) {
|
|
|
36
36
|
currency,
|
|
37
37
|
description: options.description || undefined,
|
|
38
38
|
how_to_pay: {
|
|
39
|
-
step_1: `POST ${config.apiUrl}/api/
|
|
40
|
-
step_1_body: {
|
|
39
|
+
step_1: `POST ${config.apiUrl}/api/auth/session`,
|
|
40
|
+
step_1_body: { app: realm },
|
|
41
|
+
step_1_note: 'Creates a login session. Response: { code, login_url }',
|
|
42
|
+
step_2: 'Open login_url in the user\'s browser so they can sign in or create an account (Stripe Link — about 10 seconds).',
|
|
43
|
+
step_3: `Poll GET ${config.apiUrl}/api/auth/session/{code} every 2s until status is "complete". Response: { status: "complete", token: "<jwt>", user: { email: "..." } }`,
|
|
44
|
+
step_4: `POST ${config.apiUrl}/api/mpp/resolve-challenge with Authorization: Bearer <token> header`,
|
|
45
|
+
step_4_body: {
|
|
41
46
|
challenge: {
|
|
42
47
|
id: challengeId,
|
|
43
48
|
realm,
|
|
@@ -46,15 +51,12 @@ export function generateChallenge(params) {
|
|
|
46
51
|
request,
|
|
47
52
|
expires,
|
|
48
53
|
},
|
|
49
|
-
email: '<
|
|
54
|
+
email: '<user.email from step 3>',
|
|
50
55
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
step_4: 'The response includes an X-Tru-Token header. Send it on subsequent requests — no re-auth needed.',
|
|
56
|
+
step_4_note: 'Response: { status: "approved", tru_token: "...", email: "..." }',
|
|
57
|
+
step_5: 'Retry the original request with the tru_token as an X-Tru-Token header.',
|
|
58
|
+
step_5_note: 'Send X-Tru-Token on all subsequent requests too — no re-auth needed for 24 hours.',
|
|
55
59
|
},
|
|
56
|
-
auth_url: `${config.apiUrl}/connect`,
|
|
57
|
-
auth_url_note: 'First-time users: open this URL to link a payment method via Stripe Link (10 seconds)',
|
|
58
60
|
challenge: {
|
|
59
61
|
id: challengeId,
|
|
60
62
|
realm,
|
|
@@ -72,15 +74,6 @@ export function generateChallenge(params) {
|
|
|
72
74
|
daily_cap: dailyCap,
|
|
73
75
|
subsequent_requests: 'After your first payment, the response includes an X-Tru-Token header. Send it on subsequent requests — no re-auth needed.',
|
|
74
76
|
};
|
|
75
|
-
// Include plan upsell if configured
|
|
76
|
-
if (options.plan) {
|
|
77
|
-
body.plan_available = {
|
|
78
|
-
name: options.plan.name,
|
|
79
|
-
price: options.plan.price,
|
|
80
|
-
interval: options.plan.interval,
|
|
81
|
-
message: `The ${options.plan.name} plan ($${options.plan.price}/${options.plan.interval}) gives unlimited access.`,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
77
|
return { header, body };
|
|
85
78
|
}
|
|
86
79
|
//# sourceMappingURL=challenge.js.map
|
|
@@ -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;
|
|
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,qFAAqF;QACzI,MAAM,EAAE,aAAa;QACrB,QAAQ;QACR,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;QAE7C,UAAU,EAAE;YACV,MAAM,EAAE,QAAQ,MAAM,CAAC,MAAM,mBAAmB;YAChD,WAAW,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;YAC3B,WAAW,EAAE,wDAAwD;YACrE,MAAM,EAAE,kHAAkH;YAC1H,MAAM,EAAE,YAAY,MAAM,CAAC,MAAM,wIAAwI;YACzK,MAAM,EAAE,QAAQ,MAAM,CAAC,MAAM,sEAAsE;YACnG,WAAW,EAAE;gBACX,SAAS,EAAE;oBACT,EAAE,EAAE,WAAW;oBACf,KAAK;oBACL,MAAM,EAAE,KAAK;oBACb,MAAM,EAAE,QAAQ;oBAChB,OAAO;oBACP,OAAO;iBACR;gBACD,KAAK,EAAE,0BAA0B;aAClC;YACD,WAAW,EAAE,kEAAkE;YAC/E,MAAM,EAAE,yEAAyE;YACjF,WAAW,EAAE,mFAAmF;SACjG;QAED,SAAS,EAAE;YACT,EAAE,EAAE,WAAW;YACf,KAAK;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,QAAQ;YAChB,OAAO;YACP,OAAO;SACR;KACF,CAAC;IAEF,gCAAgC;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,OAAO,GAAG;QACb,KAAK,EAAE,kBAAkB;QACzB,OAAO,EAAE,iEAAiE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,oDAAoD;QACjJ,SAAS,EAAE,QAAQ;QACnB,mBAAmB,EAAE,4HAA4H;KAClJ,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC"}
|
package/dist/src/identity.d.ts
CHANGED
|
@@ -11,32 +11,18 @@ export interface TruIdentity {
|
|
|
11
11
|
chargeId: string;
|
|
12
12
|
sessionId?: string;
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Plan configuration for subscription upsell.
|
|
16
|
-
*/
|
|
17
|
-
export interface TruxPlan {
|
|
18
|
-
name: string;
|
|
19
|
-
price: number;
|
|
20
|
-
interval: 'month' | 'year';
|
|
21
|
-
suggestAfter?: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Options passed to the trux() middleware factory.
|
|
25
|
-
*/
|
|
26
14
|
/**
|
|
27
15
|
* Amount can be a fixed number or a function that calculates price from the request.
|
|
28
|
-
* Useful for APIs where cost depends on the request body (e.g. model, resolution, tokens).
|
|
29
16
|
*
|
|
30
17
|
* Examples:
|
|
31
18
|
* trux({ amount: 0.05 })
|
|
32
19
|
* trux({ amount: (req) => req.body.model === 'premium' ? 0.25 : 0.05 })
|
|
33
20
|
*/
|
|
34
|
-
export type TruxAmount = number | ((req: any) => number);
|
|
21
|
+
export type TruxAmount = number | ((req: any) => number | Promise<number>);
|
|
35
22
|
export interface TruxOptions {
|
|
36
23
|
amount: TruxAmount;
|
|
37
24
|
currency?: string;
|
|
38
25
|
description?: string;
|
|
39
|
-
plan?: TruxPlan;
|
|
40
26
|
dailyCap?: number;
|
|
41
27
|
passthrough?: (req: any) => boolean;
|
|
42
28
|
}
|
|
@@ -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
|
|
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;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { createMiddleware as trux } from './middleware.js';
|
|
2
|
-
export type { TruIdentity, TruxOptions,
|
|
2
|
+
export type { TruIdentity, TruxOptions, TruxConfig } from './identity.js';
|
|
3
3
|
export { generateChallenge } from './challenge.js';
|
|
4
|
-
export {
|
|
5
|
-
export { recordUsage, debitSession, createSession } from './session.js';
|
|
4
|
+
export { recordUsage } from './session.js';
|
|
6
5
|
//# 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,
|
|
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,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { createMiddleware as trux } from './middleware.js';
|
|
2
2
|
export { generateChallenge } from './challenge.js';
|
|
3
|
-
export {
|
|
4
|
-
export { recordUsage, debitSession, createSession } from './session.js';
|
|
3
|
+
export { recordUsage } from './session.js';
|
|
5
4
|
//# 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,
|
|
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,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/src/init/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Main init orchestrator for `npx tru-402 init`.
|
|
3
|
+
*
|
|
4
|
+
* 1. Install tru-402 as a dependency
|
|
5
|
+
* 2. Configure the tru MCP server for detected AI assistants
|
|
6
|
+
* 3. Install tru-cli globally
|
|
7
|
+
* 4. Print next steps
|
|
3
8
|
*/
|
|
4
9
|
export declare function runInit(): Promise<void>;
|
|
5
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/init/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/init/index.ts"],"names":[],"mappings":"AA2CA;;;;;;;GAOG;AACH,wBAAsB,OAAO,kBAqD5B"}
|
package/dist/src/init/index.js
CHANGED
|
@@ -1,134 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { resolve, join, dirname } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
function detectMcpTargets(cwd) {
|
|
6
|
+
const home = homedir();
|
|
7
|
+
const platform = process.platform;
|
|
8
|
+
const targets = [
|
|
9
|
+
{ name: 'Claude Code', path: join(cwd, '.mcp.json'), alwaysCreate: true },
|
|
10
|
+
];
|
|
11
|
+
if (platform === 'darwin') {
|
|
12
|
+
targets.push({ name: 'Claude Desktop', path: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'), alwaysCreate: false });
|
|
13
|
+
}
|
|
14
|
+
else if (platform === 'win32') {
|
|
15
|
+
targets.push({ name: 'Claude Desktop', path: join(home, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json'), alwaysCreate: false });
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
targets.push({ name: 'Claude Desktop', path: join(home, '.config', 'Claude', 'claude_desktop_config.json'), alwaysCreate: false });
|
|
19
|
+
}
|
|
20
|
+
targets.push({ name: 'Cursor', path: join(cwd, '.cursor', 'mcp.json'), alwaysCreate: false });
|
|
21
|
+
return targets;
|
|
22
|
+
}
|
|
23
|
+
function readJson(path) {
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
6
31
|
/**
|
|
7
32
|
* Main init orchestrator for `npx tru-402 init`.
|
|
33
|
+
*
|
|
34
|
+
* 1. Install tru-402 as a dependency
|
|
35
|
+
* 2. Configure the tru MCP server for detected AI assistants
|
|
36
|
+
* 3. Install tru-cli globally
|
|
37
|
+
* 4. Print next steps
|
|
8
38
|
*/
|
|
9
39
|
export async function runInit() {
|
|
40
|
+
const cwd = process.cwd();
|
|
10
41
|
console.log('\n tru-402 — One-line middleware for agent commerce\n');
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
console.log('
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
42
|
+
// 1. Install tru-402 as a dependency
|
|
43
|
+
ensureDependency(cwd);
|
|
44
|
+
// 2. Configure MCP server
|
|
45
|
+
console.log(' Configuring tru MCP server...');
|
|
46
|
+
const mcpEntry = { command: 'npx', args: ['-y', 'tru-mcp'] };
|
|
47
|
+
const targets = detectMcpTargets(cwd);
|
|
48
|
+
const written = [];
|
|
49
|
+
for (const t of targets) {
|
|
50
|
+
const exists = existsSync(t.path);
|
|
51
|
+
if (!exists && !t.alwaysCreate)
|
|
52
|
+
continue;
|
|
53
|
+
mkdirSync(dirname(t.path), { recursive: true });
|
|
54
|
+
const config = exists ? readJson(t.path) : {};
|
|
55
|
+
if (!config.mcpServers)
|
|
56
|
+
config.mcpServers = {};
|
|
57
|
+
config.mcpServers.tru = mcpEntry;
|
|
58
|
+
writeFileSync(t.path, JSON.stringify(config, null, 2) + '\n');
|
|
59
|
+
written.push(t.name);
|
|
19
60
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (existingEnv.TRU_APP_ID && existingEnv.TRU_API_KEY) {
|
|
23
|
-
console.log('\n Already initialized! Found TRU_APP_ID and TRU_API_KEY in .env');
|
|
24
|
-
console.log(' To re-initialize, remove those values from .env first.\n');
|
|
25
|
-
return;
|
|
61
|
+
if (written.length > 0) {
|
|
62
|
+
console.log(` Installed tru MCP server in: ${written.join(', ')}`);
|
|
26
63
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
let registerResult;
|
|
31
|
-
try {
|
|
32
|
-
// Dynamic import of tru-cli auth module
|
|
33
|
-
const { registerViaBrowser } = await import('tru-cli/auth');
|
|
34
|
-
const serviceName = project.name
|
|
35
|
-
.toLowerCase()
|
|
36
|
-
.replace(/[^a-z0-9-]/g, '-')
|
|
37
|
-
.replace(/-+/g, '-')
|
|
38
|
-
.replace(/^-|-$/g, '');
|
|
39
|
-
registerResult = await registerViaBrowser({
|
|
40
|
-
service_name: serviceName,
|
|
41
|
-
display_name: project.displayName || project.name,
|
|
42
|
-
description: project.description || `${project.name} API`,
|
|
43
|
-
});
|
|
44
|
-
console.log(` App registered: ${registerResult.app.display_name} (${registerResult.app.service_name})`);
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
if (err.code === 'MODULE_NOT_FOUND') {
|
|
48
|
-
console.log(' tru-cli not found. Installing...');
|
|
49
|
-
const { execSync } = await import('child_process');
|
|
50
|
-
execSync('npm install -g tru-cli', { stdio: 'inherit' });
|
|
51
|
-
console.log('\n Please run `npx tru-402 init` again.');
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
throw err;
|
|
64
|
+
else {
|
|
65
|
+
console.log(' No MCP client detected. Add this to your MCP config:\n');
|
|
66
|
+
console.log(JSON.stringify({ mcpServers: { tru: mcpEntry } }, null, 2));
|
|
55
67
|
}
|
|
56
|
-
//
|
|
57
|
-
console.log('\n Step 2: Connect your Stripe account');
|
|
58
|
-
console.log(' Opening Stripe Connect...\n');
|
|
68
|
+
// 3. Install tru-cli globally
|
|
59
69
|
try {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (connectResult.url) {
|
|
63
|
-
const { exec } = await import('child_process');
|
|
64
|
-
const platform = process.platform;
|
|
65
|
-
const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';
|
|
66
|
-
exec(`${cmd} "${connectResult.url}"`);
|
|
67
|
-
console.log(' Stripe Connect OAuth opened in browser.');
|
|
68
|
-
console.log(` If it didn't open: ${connectResult.url}`);
|
|
69
|
-
console.log('\n Complete the Stripe connection, then come back here.');
|
|
70
|
-
// Poll for connection (check every 3s for up to 5 min)
|
|
71
|
-
const { lookupAppByServiceName } = await import('tru-cli/api-client');
|
|
72
|
-
let connected = false;
|
|
73
|
-
for (let i = 0; i < 100; i++) {
|
|
74
|
-
await new Promise(r => setTimeout(r, 3000));
|
|
75
|
-
try {
|
|
76
|
-
const app = await lookupAppByServiceName(registerResult.app.service_name);
|
|
77
|
-
if (app.app?.stripe_connected) {
|
|
78
|
-
connected = true;
|
|
79
|
-
console.log(' Stripe connected!');
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
catch { /* keep polling */ }
|
|
84
|
-
}
|
|
85
|
-
if (!connected) {
|
|
86
|
-
console.log('\n Stripe connection timed out. You can connect later via the tru dashboard.');
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else if (connectResult.already_connected) {
|
|
90
|
-
console.log(' Stripe already connected!');
|
|
91
|
-
}
|
|
70
|
+
execSync('npm install -g tru-cli', { stdio: 'pipe' });
|
|
71
|
+
console.log(' Installed tru-cli globally.');
|
|
92
72
|
}
|
|
93
|
-
catch
|
|
94
|
-
console.log(
|
|
95
|
-
console.log(' You can connect later via the tru dashboard.');
|
|
73
|
+
catch {
|
|
74
|
+
console.log(' Note: could not install tru-cli globally. Run `npm install -g tru-cli` if needed.');
|
|
96
75
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
TRU_APP_ID: registerResult.app.id,
|
|
101
|
-
TRU_API_KEY: registerResult.api_key,
|
|
102
|
-
TRU_APP_SECRET: registerResult.app_secret,
|
|
103
|
-
TRU_SERVICE_NAME: registerResult.app.service_name,
|
|
104
|
-
TRU_API_URL,
|
|
105
|
-
});
|
|
106
|
-
console.log(' Written to .env');
|
|
107
|
-
// 6. Add .env to .gitignore
|
|
108
|
-
ensureGitignore(process.cwd());
|
|
109
|
-
// 7. Done!
|
|
76
|
+
// 4. Add .env to .gitignore (tru setup will write credentials later)
|
|
77
|
+
ensureGitignore(cwd);
|
|
78
|
+
// 5. Done
|
|
110
79
|
console.log(`
|
|
111
|
-
Done!
|
|
112
|
-
|
|
113
|
-
Usage:
|
|
114
|
-
import { trux } from 'tru-402';
|
|
115
|
-
|
|
116
|
-
app.post('/api/generate', trux({ amount: 0.05 }), (req, res) => {
|
|
117
|
-
console.log(req.tru); // { email, name, userId, cardBrand, cardLast4, agentName, chargeId }
|
|
118
|
-
res.json({ result: '...' });
|
|
119
|
-
});
|
|
80
|
+
Done! Now open your AI assistant and say:
|
|
120
81
|
|
|
121
|
-
|
|
82
|
+
"Set up tru"
|
|
122
83
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
No API key or account needed. Call any endpoint — if payment
|
|
126
|
-
is required, you'll receive a 402 with payment instructions.
|
|
127
|
-
|
|
128
|
-
Dashboard: ${TRU_API_URL}/admin
|
|
84
|
+
The tru MCP server will walk you through registration,
|
|
85
|
+
Stripe Connect, provisioning, and agent discovery.
|
|
129
86
|
`);
|
|
130
87
|
}
|
|
131
|
-
|
|
88
|
+
function ensureDependency(cwd) {
|
|
132
89
|
const pkgPath = resolve(cwd, 'package.json');
|
|
133
90
|
if (!existsSync(pkgPath))
|
|
134
91
|
return;
|
|
@@ -136,13 +93,12 @@ async function ensureDependency(cwd) {
|
|
|
136
93
|
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
137
94
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
138
95
|
if (deps['tru-402'])
|
|
139
|
-
return;
|
|
96
|
+
return;
|
|
140
97
|
}
|
|
141
98
|
catch {
|
|
142
99
|
return;
|
|
143
100
|
}
|
|
144
101
|
console.log(' Installing tru-402...');
|
|
145
|
-
const { execSync } = await import('child_process');
|
|
146
102
|
execSync('npm install tru-402', { cwd, stdio: 'inherit' });
|
|
147
103
|
console.log(' Installed tru-402\n');
|
|
148
104
|
}
|
|
@@ -152,12 +108,10 @@ function ensureGitignore(cwd) {
|
|
|
152
108
|
const content = readFileSync(gitignorePath, 'utf-8');
|
|
153
109
|
if (!content.includes('.env')) {
|
|
154
110
|
writeFileSync(gitignorePath, content + '\n.env\n');
|
|
155
|
-
console.log(' Added .env to .gitignore');
|
|
156
111
|
}
|
|
157
112
|
}
|
|
158
113
|
else {
|
|
159
114
|
writeFileSync(gitignorePath, '.env\nnode_modules/\n');
|
|
160
|
-
console.log(' Created .gitignore with .env');
|
|
161
115
|
}
|
|
162
116
|
}
|
|
163
117
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/init/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/middleware.d.ts
CHANGED
|
@@ -3,16 +3,28 @@ import type { TruxOptions } from './identity.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Create the trux Express middleware.
|
|
5
5
|
*
|
|
6
|
-
* Flow:
|
|
6
|
+
* Flow (identity-first):
|
|
7
7
|
* 1. Existing auth (API keys, sessions) → pass through
|
|
8
|
-
* 2. X-Tru-
|
|
9
|
-
* 3.
|
|
10
|
-
* 4.
|
|
8
|
+
* 2. Identify user: X-Tru-Token / SPT credential / session
|
|
9
|
+
* 3. No identity → 402 with self-documenting payment instructions
|
|
10
|
+
* 4. Identity found → resolve amount (can be async, has access to req.tru)
|
|
11
|
+
* 5. Amount = 0 → free request, identity verified, no charge
|
|
12
|
+
* 6. Amount > 0 → record usage for daily batch settlement
|
|
11
13
|
*
|
|
12
14
|
* Usage:
|
|
13
15
|
* ```
|
|
16
|
+
* // Fixed price
|
|
14
17
|
* app.post('/api/generate', trux({ amount: 0.05 }), handler);
|
|
18
|
+
*
|
|
19
|
+
* // Free credits then pay (identity-first)
|
|
20
|
+
* app.post('/api/generate', trux({
|
|
21
|
+
* amount: async (req) => {
|
|
22
|
+
* if (!req.tru) return 0.02; // price shown in 402 challenge
|
|
23
|
+
* const user = await db.getUser(req.tru.email);
|
|
24
|
+
* return user?.credits > 0 ? 0 : 0.02;
|
|
25
|
+
* }
|
|
26
|
+
* }), handler);
|
|
15
27
|
* ```
|
|
16
28
|
*/
|
|
17
|
-
export declare function createMiddleware(options: TruxOptions): (req: Request, res: Response, next: NextFunction) => Promise<void
|
|
29
|
+
export declare function createMiddleware(options: TruxOptions): (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
|
|
18
30
|
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AACA,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":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,eAAe,CAAC;AA6F7D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,IACrC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,wDAyF9D"}
|
package/dist/src/middleware.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import { generateChallenge } from './challenge.js';
|
|
3
|
-
import {
|
|
4
|
-
import { recordUsage, debitSession } from './session.js';
|
|
3
|
+
import { recordUsage } from './session.js';
|
|
5
4
|
/**
|
|
6
5
|
* Resolve trux config from environment variables.
|
|
7
6
|
*/
|
|
@@ -26,30 +25,16 @@ function getConfig() {
|
|
|
26
25
|
_config = resolveConfig();
|
|
27
26
|
return _config;
|
|
28
27
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Extract credential from Authorization header.
|
|
31
|
-
* Supports: "Payment <credential>" and "Bearer <credential>" (where credential starts with spt_)
|
|
32
|
-
*/
|
|
33
|
-
function extractCredential(authHeader) {
|
|
34
|
-
if (!authHeader)
|
|
35
|
-
return null;
|
|
36
|
-
if (authHeader.startsWith('Payment ')) {
|
|
37
|
-
return authHeader.slice(8).trim();
|
|
38
|
-
}
|
|
39
|
-
if (authHeader.startsWith('Bearer spt_')) {
|
|
40
|
-
return authHeader.slice(7).trim();
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
28
|
/**
|
|
45
29
|
* Generate an HMAC-signed token for a verified user.
|
|
46
30
|
* Token format: email:date:hmac — valid for 24 hours.
|
|
47
31
|
* The agent sends this back on subsequent requests instead of re-authenticating.
|
|
48
32
|
*/
|
|
49
33
|
function generateTruToken(email, config) {
|
|
34
|
+
const secret = config.appSecret || config.apiKey;
|
|
50
35
|
const date = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
|
|
51
36
|
const payload = `${email}:${date}:${config.appId}`;
|
|
52
|
-
const hmac = crypto.createHmac('sha256',
|
|
37
|
+
const hmac = crypto.createHmac('sha256', secret).update(payload).digest('hex').slice(0, 32);
|
|
53
38
|
return `${email}:${date}:${hmac}`;
|
|
54
39
|
}
|
|
55
40
|
/**
|
|
@@ -58,8 +43,8 @@ function generateTruToken(email, config) {
|
|
|
58
43
|
*/
|
|
59
44
|
function verifyTruToken(token, config) {
|
|
60
45
|
const parts = token.split(':');
|
|
61
|
-
if (parts.length <
|
|
62
|
-
return null; // email:YYYY-MM-DD:hmac
|
|
46
|
+
if (parts.length < 3)
|
|
47
|
+
return null; // email:YYYY-MM-DD:hmac
|
|
63
48
|
const hmac = parts[parts.length - 1];
|
|
64
49
|
const date = parts[parts.length - 2];
|
|
65
50
|
const email = parts.slice(0, -2).join(':');
|
|
@@ -71,9 +56,10 @@ function verifyTruToken(token, config) {
|
|
|
71
56
|
const ageMs = now.getTime() - tokenDate.getTime();
|
|
72
57
|
if (ageMs < 0 || ageMs > 25 * 60 * 60 * 1000)
|
|
73
58
|
return null; // >25h (24h + 1h timezone grace)
|
|
74
|
-
// Verify HMAC
|
|
59
|
+
// Verify HMAC (uses appSecret, falls back to apiKey for backward compat)
|
|
60
|
+
const secret = config.appSecret || config.apiKey;
|
|
75
61
|
const payload = `${email}:${date}:${config.appId}`;
|
|
76
|
-
const expected = crypto.createHmac('sha256',
|
|
62
|
+
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex').slice(0, 32);
|
|
77
63
|
if (!crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(expected)))
|
|
78
64
|
return null;
|
|
79
65
|
return email;
|
|
@@ -85,7 +71,7 @@ function hasExistingAuth(req, options) {
|
|
|
85
71
|
if (options.passthrough?.(req))
|
|
86
72
|
return true;
|
|
87
73
|
const auth = req.headers.authorization;
|
|
88
|
-
if (auth
|
|
74
|
+
if (auth) {
|
|
89
75
|
return true;
|
|
90
76
|
}
|
|
91
77
|
if (req.headers['x-api-key'] || req.headers['api-key'])
|
|
@@ -97,15 +83,27 @@ function hasExistingAuth(req, options) {
|
|
|
97
83
|
/**
|
|
98
84
|
* Create the trux Express middleware.
|
|
99
85
|
*
|
|
100
|
-
* Flow:
|
|
86
|
+
* Flow (identity-first):
|
|
101
87
|
* 1. Existing auth (API keys, sessions) → pass through
|
|
102
|
-
* 2. X-Tru-
|
|
103
|
-
* 3.
|
|
104
|
-
* 4.
|
|
88
|
+
* 2. Identify user: X-Tru-Token / SPT credential / session
|
|
89
|
+
* 3. No identity → 402 with self-documenting payment instructions
|
|
90
|
+
* 4. Identity found → resolve amount (can be async, has access to req.tru)
|
|
91
|
+
* 5. Amount = 0 → free request, identity verified, no charge
|
|
92
|
+
* 6. Amount > 0 → record usage for daily batch settlement
|
|
105
93
|
*
|
|
106
94
|
* Usage:
|
|
107
95
|
* ```
|
|
96
|
+
* // Fixed price
|
|
108
97
|
* app.post('/api/generate', trux({ amount: 0.05 }), handler);
|
|
98
|
+
*
|
|
99
|
+
* // Free credits then pay (identity-first)
|
|
100
|
+
* app.post('/api/generate', trux({
|
|
101
|
+
* amount: async (req) => {
|
|
102
|
+
* if (!req.tru) return 0.02; // price shown in 402 challenge
|
|
103
|
+
* const user = await db.getUser(req.tru.email);
|
|
104
|
+
* return user?.credits > 0 ? 0 : 0.02;
|
|
105
|
+
* }
|
|
106
|
+
* }), handler);
|
|
109
107
|
* ```
|
|
110
108
|
*/
|
|
111
109
|
export function createMiddleware(options) {
|
|
@@ -113,64 +111,72 @@ export function createMiddleware(options) {
|
|
|
113
111
|
try {
|
|
114
112
|
const config = getConfig();
|
|
115
113
|
const endpoint = `${req.method} ${req.route?.path || req.path}`.slice(0, 200);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (!Number.isFinite(amountDollars) || amountDollars <= 0 || amountDollars > 9999.99) {
|
|
119
|
-
throw new Error(`tru-402: invalid amount ${amountDollars} — must be a positive number up to 9999.99`);
|
|
120
|
-
}
|
|
121
|
-
const amountCents = Math.round(amountDollars * 100);
|
|
122
|
-
// 1. Passthrough for existing auth (existing customers unaffected)
|
|
114
|
+
const agentName = (req.headers['x-tru-agent'] || '').slice(0, 100);
|
|
115
|
+
// 1. Passthrough for existing auth (API keys, sessions, Bearer tokens)
|
|
123
116
|
if (hasExistingAuth(req, options)) {
|
|
124
117
|
return next();
|
|
125
118
|
}
|
|
126
|
-
// 2. Check
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
endpoint,
|
|
136
|
-
dailyCapCents,
|
|
137
|
-
});
|
|
138
|
-
if (result.ok && result.identity) {
|
|
139
|
-
req.tru = result.identity;
|
|
140
|
-
return next();
|
|
119
|
+
// 2. Check X-Tru-Token (HMAC-signed, 24h validity)
|
|
120
|
+
const truTokenHeader = req.headers['x-tru-token'];
|
|
121
|
+
const truUserEmail = truTokenHeader ? verifyTruToken(truTokenHeader, config) : null;
|
|
122
|
+
// 3. No identity → 402 challenge with self-documenting instructions
|
|
123
|
+
if (!truUserEmail) {
|
|
124
|
+
const challengeAmount = typeof options.amount === 'function'
|
|
125
|
+
? await options.amount(req) : options.amount;
|
|
126
|
+
if (!Number.isFinite(challengeAmount) || challengeAmount < 0 || challengeAmount > 9999.99) {
|
|
127
|
+
throw new Error(`tru-402: invalid amount ${challengeAmount} — must be a number from 0 to 9999.99`);
|
|
141
128
|
}
|
|
142
|
-
|
|
129
|
+
const requestUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
|
|
130
|
+
const challenge = generateChallenge({
|
|
131
|
+
options: { ...options, amount: challengeAmount },
|
|
132
|
+
config,
|
|
133
|
+
requestUrl,
|
|
134
|
+
});
|
|
135
|
+
return res.status(402)
|
|
136
|
+
.set('WWW-Authenticate', challenge.header)
|
|
137
|
+
.json(challenge.body);
|
|
143
138
|
}
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Return a signed token for subsequent requests (no re-auth needed)
|
|
152
|
-
res.setHeader('X-Tru-Token', generateTruToken(result.identity.email, config));
|
|
153
|
-
return next();
|
|
154
|
-
}
|
|
155
|
-
// Invalid credential — fall through to 402
|
|
139
|
+
// 4. Identity verified — set partial identity so amount function can use req.tru.email
|
|
140
|
+
req.tru = { email: truUserEmail, name: '', userId: '', cardBrand: '', cardLast4: '', agentName, chargeId: '' };
|
|
141
|
+
// 5. Resolve amount (identity available on req.tru)
|
|
142
|
+
const amountDollars = typeof options.amount === 'function'
|
|
143
|
+
? await options.amount(req) : options.amount;
|
|
144
|
+
if (!Number.isFinite(amountDollars) || amountDollars < 0 || amountDollars > 9999.99) {
|
|
145
|
+
throw new Error(`tru-402: invalid amount ${amountDollars} — must be a number from 0 to 9999.99`);
|
|
156
146
|
}
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
147
|
+
const amountCents = Math.round(amountDollars * 100);
|
|
148
|
+
const dailyCapCents = Math.round((options.dailyCap ?? 25) * 100);
|
|
149
|
+
// 6. Record usage (tru verifies user + payment method, tracks for daily settlement)
|
|
150
|
+
const result = await recordUsage(truUserEmail, amountCents, config, {
|
|
151
|
+
description: options.description,
|
|
152
|
+
agentName,
|
|
153
|
+
endpoint,
|
|
154
|
+
dailyCapCents,
|
|
155
|
+
});
|
|
156
|
+
if (result.ok && result.identity) {
|
|
157
|
+
req.tru = result.identity;
|
|
158
|
+
// Surface plan upsell to agents via response header
|
|
159
|
+
if (result.plan_upsell) {
|
|
160
|
+
res.setHeader('X-Tru-Plan', JSON.stringify(result.plan_upsell));
|
|
161
|
+
}
|
|
162
|
+
if (result.limit_warning) {
|
|
163
|
+
res.setHeader('X-Tru-Limit-Warning', JSON.stringify(result.limit_warning));
|
|
164
164
|
}
|
|
165
|
+
if (result.trial_status) {
|
|
166
|
+
res.setHeader('X-Tru-Trial', JSON.stringify(result.trial_status));
|
|
167
|
+
}
|
|
168
|
+
return next();
|
|
165
169
|
}
|
|
166
|
-
//
|
|
170
|
+
// Usage recording failed (user not found, no payment method, etc.) — 402
|
|
171
|
+
const fallbackAmount = typeof options.amount === 'function'
|
|
172
|
+
? await options.amount(req) : options.amount;
|
|
167
173
|
const requestUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
|
|
168
174
|
const challenge = generateChallenge({
|
|
169
|
-
options: { ...options, amount:
|
|
175
|
+
options: { ...options, amount: Math.max(0, fallbackAmount) },
|
|
170
176
|
config,
|
|
171
177
|
requestUrl,
|
|
172
178
|
});
|
|
173
|
-
res.status(402)
|
|
179
|
+
return res.status(402)
|
|
174
180
|
.set('WWW-Authenticate', challenge.header)
|
|
175
181
|
.json(challenge.body);
|
|
176
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"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"}
|
package/dist/src/session.d.ts
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
import type { TruIdentity, TruxConfig } from './identity.js';
|
|
2
|
+
export interface PlanUpsell {
|
|
3
|
+
name: string;
|
|
4
|
+
price_cents: number;
|
|
5
|
+
interval: string;
|
|
6
|
+
monthly_spend_cents: number;
|
|
7
|
+
credit_cents: number;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LimitWarning {
|
|
11
|
+
limit_cents: number;
|
|
12
|
+
spent_cents: number;
|
|
13
|
+
remaining_cents: number;
|
|
14
|
+
pct_used: number;
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
export interface TrialStatus {
|
|
18
|
+
granted: boolean;
|
|
19
|
+
grant_reason: string | null;
|
|
20
|
+
cents_granted: number;
|
|
21
|
+
cents_used: number;
|
|
22
|
+
cents_remaining: number;
|
|
23
|
+
bonus_credits_cents: number;
|
|
24
|
+
exhausted: boolean;
|
|
25
|
+
}
|
|
2
26
|
interface RecordUsageResult {
|
|
3
27
|
ok: boolean;
|
|
4
28
|
usage_id?: string;
|
|
5
29
|
identity?: TruIdentity;
|
|
6
30
|
error?: string;
|
|
31
|
+
has_subscription?: boolean;
|
|
32
|
+
plan_upsell?: PlanUpsell;
|
|
33
|
+
limit_warning?: LimitWarning;
|
|
34
|
+
trial_status?: TrialStatus;
|
|
7
35
|
}
|
|
8
36
|
/**
|
|
9
37
|
* Record usage for daily batch settlement. No Stripe charge happens now —
|
|
@@ -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;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;
|
|
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,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,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;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;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,CAwC5B;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
|
@@ -25,6 +25,10 @@ export async function recordUsage(userEmail, amountCents, config, opts) {
|
|
|
25
25
|
return {
|
|
26
26
|
ok: true,
|
|
27
27
|
usage_id: data.usage_id,
|
|
28
|
+
has_subscription: data.has_subscription || false,
|
|
29
|
+
plan_upsell: data.plan_upsell || undefined,
|
|
30
|
+
limit_warning: data.limit_warning || undefined,
|
|
31
|
+
trial_status: data.trial_status || undefined,
|
|
28
32
|
identity: data.identity ? {
|
|
29
33
|
email: data.identity.email,
|
|
30
34
|
name: data.identity.name,
|
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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"}
|