mppx 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cli/cli.d.ts.map +1 -1
  3. package/dist/cli/cli.js +2 -0
  4. package/dist/cli/cli.js.map +1 -1
  5. package/dist/cli/plugins/stripe.d.ts.map +1 -1
  6. package/dist/cli/plugins/stripe.js +32 -12
  7. package/dist/cli/plugins/stripe.js.map +1 -1
  8. package/dist/cli/utils.d.ts.map +1 -1
  9. package/dist/cli/utils.js +1 -1
  10. package/dist/cli/utils.js.map +1 -1
  11. package/dist/cli/validate/challenge.d.ts +14 -0
  12. package/dist/cli/validate/challenge.d.ts.map +1 -0
  13. package/dist/cli/validate/challenge.js +211 -0
  14. package/dist/cli/validate/challenge.js.map +1 -0
  15. package/dist/cli/validate/discovery.d.ts +10 -0
  16. package/dist/cli/validate/discovery.d.ts.map +1 -0
  17. package/dist/cli/validate/discovery.js +128 -0
  18. package/dist/cli/validate/discovery.js.map +1 -0
  19. package/dist/cli/validate/helpers.d.ts +33 -0
  20. package/dist/cli/validate/helpers.d.ts.map +1 -0
  21. package/dist/cli/validate/helpers.js +136 -0
  22. package/dist/cli/validate/helpers.js.map +1 -0
  23. package/dist/cli/validate/index.d.ts +17 -0
  24. package/dist/cli/validate/index.d.ts.map +1 -0
  25. package/dist/cli/validate/index.js +224 -0
  26. package/dist/cli/validate/index.js.map +1 -0
  27. package/dist/cli/validate/payment.d.ts +7 -0
  28. package/dist/cli/validate/payment.d.ts.map +1 -0
  29. package/dist/cli/validate/payment.js +381 -0
  30. package/dist/cli/validate/payment.js.map +1 -0
  31. package/dist/evm/client/Charge.d.ts +2 -2
  32. package/dist/evm/client/Charge.d.ts.map +1 -1
  33. package/dist/evm/client/Charge.js +11 -17
  34. package/dist/evm/client/Charge.js.map +1 -1
  35. package/dist/evm/server/Charge.d.ts +5 -5
  36. package/dist/evm/server/Charge.d.ts.map +1 -1
  37. package/dist/evm/server/Charge.js +15 -7
  38. package/dist/evm/server/Charge.js.map +1 -1
  39. package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
  40. package/dist/tempo/internal/auto-swap.js +6 -1
  41. package/dist/tempo/internal/auto-swap.js.map +1 -1
  42. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  43. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  44. package/dist/tempo/server/internal/html.gen.js +1 -1
  45. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  46. package/dist/x402/Assets.d.ts +40 -0
  47. package/dist/x402/Assets.d.ts.map +1 -1
  48. package/dist/x402/Assets.js +73 -0
  49. package/dist/x402/Assets.js.map +1 -1
  50. package/dist/x402/client/Exact.d.ts +2 -2
  51. package/dist/x402/client/Exact.d.ts.map +1 -1
  52. package/dist/x402/client/Exact.js +6 -13
  53. package/dist/x402/client/Exact.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/cli/cli.test.ts +134 -29
  56. package/src/cli/cli.ts +2 -0
  57. package/src/cli/mcp.test.ts +1 -0
  58. package/src/cli/plugins/stripe.ts +31 -12
  59. package/src/cli/utils.test.ts +36 -2
  60. package/src/cli/utils.ts +2 -1
  61. package/src/cli/validate/challenge.ts +335 -0
  62. package/src/cli/validate/discovery.ts +120 -0
  63. package/src/cli/validate/helpers.ts +154 -0
  64. package/src/cli/validate/index.ts +348 -0
  65. package/src/cli/validate/payment.ts +488 -0
  66. package/src/cli/validate.test.ts +539 -0
  67. package/src/evm/PublicInterface.test-d.ts +15 -2
  68. package/src/evm/client/Charge.test.ts +248 -0
  69. package/src/evm/client/Charge.ts +12 -23
  70. package/src/evm/server/Charge.test.ts +140 -0
  71. package/src/evm/server/Charge.ts +19 -12
  72. package/src/tempo/internal/auto-swap.test.ts +26 -9
  73. package/src/tempo/internal/auto-swap.ts +15 -2
  74. package/src/tempo/server/internal/html.gen.ts +1 -1
  75. package/src/x402/Assets.test.ts +211 -0
  76. package/src/x402/Assets.ts +116 -0
  77. package/src/x402/client/Exact.test.ts +129 -0
  78. package/src/x402/client/Exact.ts +7 -19
@@ -0,0 +1,211 @@
1
+ import * as Challenge from '../../Challenge.js';
2
+ import * as Constants from '../../Constants.js';
3
+ import { chainId as tempoChainIds } from '../../tempo/internal/defaults.js';
4
+ import { pc } from '../utils.js';
5
+ import { extractRequestBodyFromDiscovery } from './discovery.js';
6
+ import { buildUrl, check, fail, fetchWithTimeout, isValidAddress, isValidIntegerAmount, skip, warn, } from './helpers.js';
7
+ function detectTestnet(challenge) {
8
+ const request = challenge.request;
9
+ const methodDetails = request.methodDetails;
10
+ if (typeof methodDetails?.chainId === 'number') {
11
+ return methodDetails.chainId !== tempoChainIds.mainnet;
12
+ }
13
+ return false;
14
+ }
15
+ export async function validateChallenge(baseUrl, endpoint, verbose, options) {
16
+ const results = [];
17
+ const url = buildUrl(baseUrl, endpoint, options?.query);
18
+ const fetchHeaders = {};
19
+ let fetchBody;
20
+ // Make bare unauthenticated request first (no body)
21
+ let response;
22
+ try {
23
+ response = await fetchWithTimeout(url, { method: endpoint.method });
24
+ }
25
+ catch (error) {
26
+ results.push(fail('Request failed', error.message));
27
+ return { results };
28
+ }
29
+ // If we got 400, retry with body (explicit --body or auto-generated from schema)
30
+ if (response.status === 400) {
31
+ const bodyToTry = options?.body ??
32
+ (options?.discoveryDoc
33
+ ? extractRequestBodyFromDiscovery(options.discoveryDoc, endpoint)
34
+ : undefined);
35
+ if (bodyToTry) {
36
+ if (verbose)
37
+ console.log(pc.dim(` Retrying with body: ${bodyToTry}`));
38
+ fetchBody = bodyToTry;
39
+ fetchHeaders['content-type'] = 'application/json';
40
+ try {
41
+ response = await fetchWithTimeout(url, {
42
+ method: endpoint.method,
43
+ headers: fetchHeaders,
44
+ body: fetchBody,
45
+ });
46
+ }
47
+ catch (error) {
48
+ results.push(fail('Request failed', error.message));
49
+ return { results };
50
+ }
51
+ }
52
+ }
53
+ // Check 402
54
+ if (response.status !== 402) {
55
+ if (response.status === 200) {
56
+ results.push(skip('Returns 402 without credentials', 'Got 200 (endpoint may not require payment in all cases)'));
57
+ }
58
+ else if (response.status === 401 || response.status === 403) {
59
+ results.push(skip('Returns 402 without credentials', `Got ${response.status} (endpoint requires auth before payment gate)`));
60
+ }
61
+ else {
62
+ results.push(fail('Returns 402 without credentials', `Got ${response.status} instead`, response.status === 400
63
+ ? 'Server requires a valid request body before returning 402. Add a requestBody schema with examples to your OpenAPI doc, or use --body.'
64
+ : 'Endpoints that require payment must return HTTP 402 with a WWW-Authenticate: Payment header when no valid credential is provided.'));
65
+ }
66
+ return { results };
67
+ }
68
+ results.push(check('Returns 402 without credentials'));
69
+ // Check WWW-Authenticate header
70
+ const wwwAuth = response.headers.get(Constants.Headers.wwwAuthenticate);
71
+ if (!wwwAuth) {
72
+ results.push(skip('Not an MPP endpoint', 'No WWW-Authenticate header (may be x402 or other protocol)'));
73
+ return { results };
74
+ }
75
+ if (!wwwAuth.startsWith(`${Constants.Schemes.payment} `)) {
76
+ results.push(skip('Not an MPP endpoint', `WWW-Authenticate scheme is not Payment`));
77
+ return { results };
78
+ }
79
+ results.push(check('WWW-Authenticate header present', 'Payment scheme'));
80
+ // Parse challenge
81
+ let challenge;
82
+ try {
83
+ challenge = Challenge.fromResponse(response);
84
+ }
85
+ catch (error) {
86
+ results.push(fail('Challenge parseable', error.message));
87
+ return { results };
88
+ }
89
+ results.push(check('Challenge parseable', `${challenge.method}/${challenge.intent}`));
90
+ // Validate required fields
91
+ if (!challenge.id)
92
+ results.push(fail('Challenge has id', undefined, 'Every challenge must include a unique id field. Generate a random string or hash per challenge.'));
93
+ else
94
+ results.push(check('Challenge has id'));
95
+ if (!challenge.realm)
96
+ results.push(fail('Challenge has realm', undefined, "Set realm to your server's hostname. It tells clients who they are paying."));
97
+ else
98
+ results.push(check('Challenge has realm'));
99
+ if (!challenge.method)
100
+ results.push(fail('Challenge has method', undefined, 'Set method to the payment method (e.g. "tempo", "stripe").'));
101
+ if (!challenge.intent)
102
+ results.push(fail('Challenge has intent', undefined, 'Set intent to the payment type (e.g. "charge", "session").'));
103
+ // Semantic checks
104
+ if (challenge.expires) {
105
+ const expiresDate = new Date(challenge.expires);
106
+ const now = new Date();
107
+ if (expiresDate <= now) {
108
+ results.push(fail('Challenge expires in the future', `Expired at ${challenge.expires}`, 'The expires timestamp must be in the future when the challenge is issued. Use a 5-10 minute window from the current time.'));
109
+ }
110
+ else {
111
+ const diffMs = expiresDate.getTime() - now.getTime();
112
+ const diffMin = Math.round(diffMs / 60000);
113
+ results.push(check('Challenge expires in the future', `${diffMin}m from now`));
114
+ }
115
+ }
116
+ else {
117
+ results.push(warn('Challenge has expiration', 'No expires field set', 'Add an expires field (ISO 8601 datetime) to prevent replay attacks. Recommended: 5 minutes from issuance.'));
118
+ }
119
+ // Realm check (allow subdomain matches)
120
+ try {
121
+ const serverHost = new URL(baseUrl).hostname;
122
+ const realm = challenge.realm ?? '';
123
+ const matches = serverHost === realm || serverHost.endsWith(`.${realm}`);
124
+ if (matches) {
125
+ results.push(check('Realm matches server hostname'));
126
+ }
127
+ else {
128
+ results.push(warn('Realm matches server hostname', `realm="${realm}" vs host="${serverHost}"`, 'Set the realm to your production hostname (or base domain) in the challenge. Clients use realm to verify they are paying the right server.'));
129
+ }
130
+ }
131
+ catch { }
132
+ // Method-specific validation
133
+ const request = challenge.request;
134
+ if (challenge.method === Constants.Methods.tempo) {
135
+ if (isValidAddress(request.recipient)) {
136
+ results.push(check('Valid recipient address'));
137
+ }
138
+ else {
139
+ results.push(fail('Valid recipient address', `Got: ${String(request.recipient)}`, 'Set request.recipient to a valid 0x-prefixed 40-hex-char address. This is where payment will be sent.'));
140
+ }
141
+ if (isValidAddress(request.currency)) {
142
+ const isTestnet = detectTestnet(challenge);
143
+ const network = isTestnet ? 'testnet' : 'mainnet';
144
+ results.push(check('Valid currency address', `${network}`));
145
+ }
146
+ else {
147
+ results.push(fail('Valid currency address', `Got: ${String(request.currency)}`, 'Set request.currency to a valid token address. Common: "0x20c0000000000000000000000000000000000000" (PathUSD).'));
148
+ }
149
+ if (isValidIntegerAmount(request.amount)) {
150
+ results.push(check('Amount is valid integer string'));
151
+ }
152
+ else if (request.amount === undefined || request.amount === null) {
153
+ results.push(warn('Amount is valid integer string', 'No amount (dynamic pricing?)', 'Set request.amount to a string of digits in the token\'s smallest unit (e.g. "10000" = $0.01 for 6-decimal tokens).'));
154
+ }
155
+ else {
156
+ results.push(fail('Amount is valid integer string', `Got: ${String(request.amount)}`, 'request.amount must be a string of digits (no decimals, no prefix). Example: "10000" for $0.01 with 6-decimal tokens.'));
157
+ }
158
+ }
159
+ else if (challenge.method === Constants.Methods.stripe) {
160
+ if (request.amount !== undefined) {
161
+ results.push(check('Stripe challenge has amount'));
162
+ }
163
+ else {
164
+ results.push(warn('Stripe challenge has amount', 'No amount field'));
165
+ }
166
+ }
167
+ if (verbose) {
168
+ console.log(pc.dim(` Challenge: ${JSON.stringify(challenge, null, 2)}`));
169
+ }
170
+ return { results, resolvedBody: fetchBody };
171
+ }
172
+ export async function validateErrorHandling(baseUrl, endpoint, options) {
173
+ const results = [];
174
+ const url = buildUrl(baseUrl, endpoint, options?.query);
175
+ const fetchHeaders = {
176
+ [Constants.Headers.authorization]: `${Constants.Schemes.payment} dGhpcyBpcyBnYXJiYWdl`,
177
+ };
178
+ let fetchBody;
179
+ if (options?.body) {
180
+ fetchBody = options.body;
181
+ fetchHeaders['content-type'] = 'application/json';
182
+ }
183
+ try {
184
+ const response = await fetchWithTimeout(url, {
185
+ method: endpoint.method,
186
+ headers: fetchHeaders,
187
+ body: fetchBody ?? null,
188
+ });
189
+ if (response.status === 402) {
190
+ results.push(check('Malformed credential returns 402', 'not 500'));
191
+ const wwwAuth = response.headers.get(Constants.Headers.wwwAuthenticate);
192
+ if (wwwAuth?.startsWith(`${Constants.Schemes.payment} `)) {
193
+ results.push(check('Error response includes fresh challenge'));
194
+ }
195
+ else {
196
+ results.push(warn('Error response includes fresh challenge', 'No WWW-Authenticate header', 'When rejecting an invalid credential, respond with 402 and include a fresh WWW-Authenticate: Payment challenge so the client can retry.'));
197
+ }
198
+ }
199
+ else if (response.status >= 500) {
200
+ results.push(fail('Malformed credential returns 402', `Got ${response.status} (server error)`, 'When the Authorization header contains an invalid credential, respond with 402 (not 500). Catch credential validation errors and return a fresh challenge.'));
201
+ }
202
+ else {
203
+ results.push(warn('Malformed credential returns 402', `Got ${response.status}`, `When the Authorization header contains an invalid Payment credential, respond with 402 and a fresh WWW-Authenticate challenge. Returning ${response.status} prevents the client from retrying with a valid payment.`));
204
+ }
205
+ }
206
+ catch (error) {
207
+ results.push(fail('Error handling test', error.message));
208
+ }
209
+ return results;
210
+ }
211
+ //# sourceMappingURL=challenge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../../src/cli/validate/challenge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { EndpointSpec } from './helpers.js';
2
+ export declare function fetchDiscoveryDoc(baseUrl: string): Promise<{
3
+ doc: unknown;
4
+ raw: string;
5
+ } | {
6
+ error: string;
7
+ }>;
8
+ export declare function extractEndpointsFromDiscovery(doc: Record<string, unknown>): EndpointSpec[];
9
+ export declare function extractRequestBodyFromDiscovery(doc: Record<string, unknown>, endpoint: EndpointSpec): string | undefined;
10
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGhD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAc5D;AAKD,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,CA0B1F;AA2CD,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,EAAE,YAAY,GACrB,MAAM,GAAG,SAAS,CAuBpB"}
@@ -0,0 +1,128 @@
1
+ import { fetchWithTimeout, HTTP_METHODS } from './helpers.js';
2
+ export async function fetchDiscoveryDoc(baseUrl) {
3
+ const url = new URL('/openapi.json', baseUrl).href;
4
+ try {
5
+ const response = await fetchWithTimeout(url, {});
6
+ if (!response.ok)
7
+ return { error: `HTTP ${response.status}` };
8
+ const raw = await response.text();
9
+ const doc = JSON.parse(raw);
10
+ return { doc, raw };
11
+ }
12
+ catch (error) {
13
+ if (error instanceof DOMException && error.name === 'AbortError')
14
+ return { error: 'Request timed out after 15s' };
15
+ if (error instanceof SyntaxError)
16
+ return { error: 'Invalid JSON' };
17
+ return { error: error.message };
18
+ }
19
+ }
20
+ // Extracts testable endpoints from an OpenAPI doc. Prefers endpoints with
21
+ // explicit x-payment-info (the server declares them as paid). Falls back to
22
+ // endpoints that list a 402 response (weaker signal, but still worth testing).
23
+ export function extractEndpointsFromDiscovery(doc) {
24
+ const withPaymentInfo = [];
25
+ const with402Response = [];
26
+ const paths = doc.paths;
27
+ if (!paths)
28
+ return [];
29
+ for (const [pathKey, pathItem] of Object.entries(paths)) {
30
+ for (const [method, operation] of Object.entries(pathItem)) {
31
+ if (!HTTP_METHODS.has(method))
32
+ continue;
33
+ if (!operation || typeof operation !== 'object' || Array.isArray(operation))
34
+ continue;
35
+ const op = operation;
36
+ if (op['x-payment-info']) {
37
+ const payInfo = op['x-payment-info'];
38
+ withPaymentInfo.push({
39
+ method: method.toUpperCase(),
40
+ path: pathKey,
41
+ amount: payInfo.amount,
42
+ });
43
+ }
44
+ else {
45
+ const responses = op.responses;
46
+ if (responses && '402' in responses) {
47
+ with402Response.push({ method: method.toUpperCase(), path: pathKey });
48
+ }
49
+ }
50
+ }
51
+ }
52
+ return withPaymentInfo.length > 0 ? withPaymentInfo : with402Response;
53
+ }
54
+ // Recursively generates a minimal valid value from a JSON Schema definition.
55
+ // Fills only required fields, preferring const > example > default > synthetic.
56
+ function generateValueFromSchema(schema) {
57
+ if (schema.const !== undefined)
58
+ return schema.const;
59
+ if (schema.example !== undefined)
60
+ return schema.example;
61
+ if (schema.default !== undefined)
62
+ return schema.default;
63
+ switch (schema.type) {
64
+ case 'string': {
65
+ if (schema.format === 'email')
66
+ return 'test@example.com';
67
+ if (schema.format === 'uuid')
68
+ return '00000000-0000-0000-0000-000000000000';
69
+ if (schema.format === 'uri' || schema.format === 'url')
70
+ return 'https://example.com';
71
+ if (schema.enum && Array.isArray(schema.enum))
72
+ return schema.enum[0];
73
+ return 'test';
74
+ }
75
+ case 'number':
76
+ case 'integer':
77
+ return schema.minimum ?? 1;
78
+ case 'boolean':
79
+ return true;
80
+ case 'array':
81
+ return [];
82
+ case 'object': {
83
+ const properties = schema.properties;
84
+ if (!properties)
85
+ return {};
86
+ const required = schema.required || [];
87
+ const obj = {};
88
+ for (const key of required) {
89
+ const prop = properties[key];
90
+ if (prop)
91
+ obj[key] = generateValueFromSchema(prop);
92
+ }
93
+ return obj;
94
+ }
95
+ default:
96
+ return null;
97
+ }
98
+ }
99
+ // Looks up the requestBody schema for an endpoint in the OpenAPI doc and
100
+ // returns a JSON string suitable for the request. Uses the doc's example
101
+ // if one exists, otherwise generates a minimal body from the schema.
102
+ export function extractRequestBodyFromDiscovery(doc, endpoint) {
103
+ const paths = doc.paths;
104
+ if (!paths)
105
+ return undefined;
106
+ const pathItem = paths[endpoint.path];
107
+ if (!pathItem)
108
+ return undefined;
109
+ const op = pathItem[endpoint.method.toLowerCase()];
110
+ if (!op?.requestBody)
111
+ return undefined;
112
+ const rb = op.requestBody;
113
+ const content = rb.content;
114
+ const jsonContent = content?.['application/json'];
115
+ if (!jsonContent)
116
+ return undefined;
117
+ if (jsonContent.example)
118
+ return JSON.stringify(jsonContent.example);
119
+ const schema = jsonContent.schema;
120
+ if (!schema || schema.type !== 'object')
121
+ return undefined;
122
+ const result = generateValueFromSchema(schema);
123
+ if (result && typeof result === 'object' && Object.keys(result).length > 0) {
124
+ return JSON.stringify(result);
125
+ }
126
+ return undefined;
127
+ }
128
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/cli/validate/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export type CheckResult = {
2
+ label: string;
3
+ detail?: string | undefined;
4
+ hint?: string | undefined;
5
+ severity: 'pass' | 'fail' | 'warn' | 'skip';
6
+ };
7
+ export type EndpointSpec = {
8
+ method: string;
9
+ path: string;
10
+ amount?: string | undefined;
11
+ };
12
+ export declare function check(label: string, detail?: string): CheckResult;
13
+ export declare function fail(label: string, detail?: string, hint?: string): CheckResult;
14
+ export declare function warn(label: string, detail?: string, hint?: string): CheckResult;
15
+ export declare function skip(label: string, detail?: string, hint?: string): CheckResult;
16
+ export declare function printCheck(result: CheckResult): void;
17
+ export declare function printSection(title: string): void;
18
+ export type Counts = {
19
+ passed: number;
20
+ failed: number;
21
+ warnings: number;
22
+ skipped: number;
23
+ };
24
+ export declare function printResults(results: CheckResult[], counts: Counts): void;
25
+ export declare function fetchWithTimeout(url: string, init: RequestInit, timeoutMs?: number): Promise<Response>;
26
+ export declare function buildUrl(baseUrl: string, endpoint: EndpointSpec, query?: string[]): string;
27
+ export declare function formatBytes(bytes: number): string;
28
+ export declare const HTTP_METHODS: Set<string>;
29
+ export declare function isValidAddress(addr: unknown): boolean;
30
+ export declare function isValidIntegerAmount(amount: unknown): boolean;
31
+ export declare function parseEndpointArg(input: string): EndpointSpec | null;
32
+ export declare function resolveBodyForEndpoint(rawBody: string | undefined, endpointPath: string): string | undefined;
33
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/helpers.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAC5C,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B,CAAA;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAEjE;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAK/E;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAK/E;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAI/E;AASD,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,QAO7C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,QAEzC;AAED,MAAM,MAAM,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1F,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,QAQlE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,SAAS,SAAS,GACjB,OAAO,CAAC,QAAQ,CAAC,CAQnB;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAW1F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,eAAO,MAAM,YAAY,aASvB,CAAA;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAErD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE7D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CASnE;AAID,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,YAAY,EAAE,MAAM,GACnB,MAAM,GAAG,SAAS,CAcpB"}
@@ -0,0 +1,136 @@
1
+ import { pc } from '../utils.js';
2
+ export function check(label, detail) {
3
+ return detail ? { label, detail, severity: 'pass' } : { label, severity: 'pass' };
4
+ }
5
+ export function fail(label, detail, hint) {
6
+ const r = { label, severity: 'fail' };
7
+ if (detail)
8
+ r.detail = detail;
9
+ if (hint)
10
+ r.hint = hint;
11
+ return r;
12
+ }
13
+ export function warn(label, detail, hint) {
14
+ const r = { label, severity: 'warn' };
15
+ if (detail)
16
+ r.detail = detail;
17
+ if (hint)
18
+ r.hint = hint;
19
+ return r;
20
+ }
21
+ export function skip(label, detail, hint) {
22
+ const r = detail ? { label, detail, severity: 'skip' } : { label, severity: 'skip' };
23
+ if (hint)
24
+ r.hint = hint;
25
+ return r;
26
+ }
27
+ const SEVERITY_ICONS = {
28
+ pass: pc.green('✓'),
29
+ fail: pc.red('✗'),
30
+ warn: pc.yellow('⚠'),
31
+ skip: pc.dim('○'),
32
+ };
33
+ export function printCheck(result) {
34
+ const icon = SEVERITY_ICONS[result.severity];
35
+ const text = result.detail ? `${result.label} (${result.detail})` : result.label;
36
+ console.log(` ${icon} ${text}`);
37
+ if (result.hint && result.severity !== 'pass') {
38
+ console.log(pc.dim(` → ${result.hint}`));
39
+ }
40
+ }
41
+ export function printSection(title) {
42
+ console.log(`\n${pc.bold(title)}`);
43
+ }
44
+ export function printResults(results, counts) {
45
+ for (const result of results) {
46
+ printCheck(result);
47
+ if (result.severity === 'pass')
48
+ counts.passed++;
49
+ else if (result.severity === 'fail')
50
+ counts.failed++;
51
+ else if (result.severity === 'warn')
52
+ counts.warnings++;
53
+ else if (result.severity === 'skip')
54
+ counts.skipped++;
55
+ }
56
+ }
57
+ export async function fetchWithTimeout(url, init, timeoutMs = 15_000) {
58
+ const controller = new AbortController();
59
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
60
+ try {
61
+ return await fetch(url, { ...init, signal: controller.signal });
62
+ }
63
+ finally {
64
+ clearTimeout(timeout);
65
+ }
66
+ }
67
+ export function buildUrl(baseUrl, endpoint, query) {
68
+ let url = new URL(endpoint.path, baseUrl).href;
69
+ if (query) {
70
+ const u = new URL(url);
71
+ for (const q of query) {
72
+ const [key, ...rest] = q.split('=');
73
+ if (key)
74
+ u.searchParams.set(key, rest.join('='));
75
+ }
76
+ url = u.href;
77
+ }
78
+ return url;
79
+ }
80
+ export function formatBytes(bytes) {
81
+ if (bytes < 1024)
82
+ return `${bytes}B`;
83
+ if (bytes < 1024 * 1024)
84
+ return `${(bytes / 1024).toFixed(1)}KB`;
85
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
86
+ }
87
+ export const HTTP_METHODS = new Set([
88
+ 'get',
89
+ 'post',
90
+ 'put',
91
+ 'patch',
92
+ 'delete',
93
+ 'head',
94
+ 'options',
95
+ 'trace',
96
+ ]);
97
+ export function isValidAddress(addr) {
98
+ return typeof addr === 'string' && /^0x[0-9a-fA-F]{40}$/.test(addr);
99
+ }
100
+ export function isValidIntegerAmount(amount) {
101
+ return typeof amount === 'string' && /^(0|[1-9][0-9]*)$/.test(amount);
102
+ }
103
+ export function parseEndpointArg(input) {
104
+ const sep = input.indexOf(':');
105
+ if (sep < 1)
106
+ return null;
107
+ const method = input.slice(0, sep).toLowerCase();
108
+ if (!HTTP_METHODS.has(method))
109
+ return null;
110
+ const path = input.slice(sep + 1);
111
+ if (!path)
112
+ return null;
113
+ const normalizedPath = path.startsWith('/') ? path : '/' + path;
114
+ return { method: method.toUpperCase(), path: normalizedPath };
115
+ }
116
+ // Resolves --body input: if JSON with all keys starting with /, it's a
117
+ // per-path mapping. Otherwise it's a global body for all endpoints.
118
+ export function resolveBodyForEndpoint(rawBody, endpointPath) {
119
+ if (!rawBody)
120
+ return undefined;
121
+ try {
122
+ const parsed = JSON.parse(rawBody);
123
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
124
+ const keys = Object.keys(parsed);
125
+ if (keys.length > 0 && keys.every((k) => k.startsWith('/'))) {
126
+ const value = parsed[endpointPath];
127
+ if (value === undefined)
128
+ return undefined;
129
+ return typeof value === 'string' ? value : JSON.stringify(value);
130
+ }
131
+ }
132
+ }
133
+ catch { }
134
+ return rawBody;
135
+ }
136
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/cli/validate/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { Cli } from 'incur';
2
+ declare const validate: Cli.Cli<{
3
+ [x: string]: {
4
+ args: {
5
+ url: string;
6
+ };
7
+ options: {
8
+ verbose: number;
9
+ yes: boolean;
10
+ endpoint?: string | undefined;
11
+ body?: string | undefined;
12
+ query?: string[] | undefined;
13
+ };
14
+ };
15
+ }, undefined, undefined, undefined>;
16
+ export default validate;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAK,MAAM,OAAO,CAAA;AAuB9B,QAAA,MAAM,QAAQ;;;;;;;;;;;;;mCA4CZ,CAAA;AAEF,eAAe,QAAQ,CAAA"}