@orth/cli 0.2.25 → 0.2.27

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/api.d.ts CHANGED
@@ -11,6 +11,8 @@ export interface SearchResponse {
11
11
  method: string;
12
12
  description: string;
13
13
  price?: number;
14
+ hasDynamicPricing?: boolean;
15
+ pricing_formula?: string;
14
16
  }>;
15
17
  }>;
16
18
  count: number;
@@ -26,6 +28,8 @@ export interface DetailsResponse {
26
28
  method?: string;
27
29
  description?: string;
28
30
  price?: number | string;
31
+ hasDynamicPricing?: boolean;
32
+ pricing_formula?: string;
29
33
  parameters?: {
30
34
  query?: Array<{
31
35
  name: string;
@@ -74,6 +78,9 @@ export interface RunResponse {
74
78
  price?: string;
75
79
  priceCents?: number;
76
80
  requestId?: string;
81
+ dryRun?: boolean;
82
+ estimatedPrice?: string;
83
+ estimatedPriceCents?: number;
77
84
  }
78
85
  export interface IntegrateResponse {
79
86
  api: string;
@@ -117,6 +124,8 @@ export interface ApiBySlugResponse {
117
124
  description?: string;
118
125
  price?: number;
119
126
  isPayable?: boolean;
127
+ hasDynamicPricing?: boolean;
128
+ pricing_formula?: string;
120
129
  docsUrl?: string;
121
130
  queryParams?: Array<{
122
131
  name: string;
@@ -139,5 +148,6 @@ export declare function run(api: string, path: string, options?: {
139
148
  method?: string;
140
149
  query?: Record<string, string>;
141
150
  body?: unknown;
151
+ dryRun?: boolean;
142
152
  }): Promise<RunResponse>;
143
153
  export declare function integrate(api: string, path: string, format?: string): Promise<IntegrateResponse>;
package/dist/api.js CHANGED
@@ -82,6 +82,7 @@ async function run(api, path, options = {}) {
82
82
  method: options.method || "GET",
83
83
  query: options.query,
84
84
  body: options.body,
85
+ dryRun: options.dryRun,
85
86
  },
86
87
  });
87
88
  }
@@ -58,11 +58,17 @@ async function apiCommand(slug, path, options) {
58
58
  console.log(chalk_1.default.gray(desc || "No description"));
59
59
  // Show price
60
60
  const endpointPrice = data.price ?? data.endpoint?.price;
61
- if (endpointPrice !== undefined && endpointPrice !== null) {
61
+ const isDynamic = data.hasDynamicPricing || !!data.pricing_formula;
62
+ if (isDynamic) {
63
+ console.log(chalk_1.default.bold("Price: ") +
64
+ chalk_1.default.yellow("dynamic") +
65
+ chalk_1.default.gray(" (use --dry-run to estimate)"));
66
+ }
67
+ else if (endpointPrice !== undefined && endpointPrice !== null) {
62
68
  const isFree = endpointPrice === 0 || endpointPrice === "free" || endpointPrice === "0";
63
69
  const priceDisplay = typeof endpointPrice === 'string'
64
70
  ? endpointPrice
65
- : `$${parseFloat((Number(endpointPrice) / 1000000).toFixed(4))}`;
71
+ : `$${parseFloat(Number(endpointPrice).toFixed(4))}`;
66
72
  console.log(chalk_1.default.bold("Price: ") +
67
73
  (isFree ? chalk_1.default.green("free") : chalk_1.default.yellow(priceDisplay)));
68
74
  }
@@ -145,12 +151,17 @@ async function apiCommand(slug, path, options) {
145
151
  for (const endpoint of apiData.endpoints) {
146
152
  const method = chalk_1.default.yellow(endpoint.method.padEnd(6));
147
153
  const ep = endpoint.price;
148
- const isFreePrice = ep === 0 || ep == null || ep === "free" || ep === "0";
149
- const price = isFreePrice
150
- ? chalk_1.default.green("free")
151
- : typeof ep === 'string'
152
- ? chalk_1.default.dim(ep)
153
- : chalk_1.default.dim(`$${parseFloat((Number(ep) / 1000000).toFixed(4))}`);
154
+ const epIsDynamic = endpoint.hasDynamicPricing || !!endpoint.pricing_formula;
155
+ const price = epIsDynamic
156
+ ? chalk_1.default.dim("dynamic")
157
+ : (() => {
158
+ const isFreePrice = ep === 0 || ep == null || ep === "free" || ep === "0";
159
+ return isFreePrice
160
+ ? chalk_1.default.green("free")
161
+ : typeof ep === 'string'
162
+ ? chalk_1.default.dim(ep)
163
+ : chalk_1.default.dim(`$${parseFloat(Number(ep).toFixed(4))}`);
164
+ })();
154
165
  console.log(`${method} ${chalk_1.default.white(endpoint.path)} ${price}`);
155
166
  if (endpoint.description) {
156
167
  console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
@@ -173,12 +184,17 @@ async function apiCommand(slug, path, options) {
173
184
  for (const endpoint of api.endpoints) {
174
185
  const method = chalk_1.default.yellow(endpoint.method.padEnd(6));
175
186
  const ep2 = endpoint.price;
176
- const isFreePrice = ep2 === 0 || ep2 == null || ep2 === "free" || ep2 === "0";
177
- const price = isFreePrice
178
- ? chalk_1.default.green("free")
179
- : typeof ep2 === 'string'
180
- ? chalk_1.default.dim(ep2)
181
- : chalk_1.default.dim(`$${parseFloat((Number(ep2) / 1000000).toFixed(4))}`);
187
+ const epIsDynamic2 = endpoint.hasDynamicPricing || !!endpoint.pricing_formula;
188
+ const price = epIsDynamic2
189
+ ? chalk_1.default.dim("dynamic")
190
+ : (() => {
191
+ const isFreePrice = ep2 === 0 || ep2 == null || ep2 === "free" || ep2 === "0";
192
+ return isFreePrice
193
+ ? chalk_1.default.green("free")
194
+ : typeof ep2 === 'string'
195
+ ? chalk_1.default.dim(ep2)
196
+ : chalk_1.default.dim(`$${parseFloat(Number(ep2).toFixed(4))}`);
197
+ })();
182
198
  console.log(`${method} ${chalk_1.default.white(endpoint.path)} ${price}`);
183
199
  if (endpoint.description) {
184
200
  console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
@@ -5,4 +5,5 @@ export declare function runCommand(api: string, path: string, options: {
5
5
  data?: string;
6
6
  raw?: boolean;
7
7
  output?: string;
8
+ dryRun?: boolean;
8
9
  }): Promise<void>;
@@ -121,8 +121,21 @@ async function runCommand(api, path, options) {
121
121
  method: options.method,
122
122
  query: Object.keys(query).length > 0 ? query : undefined,
123
123
  body,
124
+ dryRun: options.dryRun,
124
125
  });
125
126
  spinner.stop();
127
+ // Handle dry-run response
128
+ if (result.dryRun) {
129
+ const estimatedCost = result.estimatedPrice ||
130
+ (result.estimatedPriceCents != null
131
+ ? `$${parseFloat((result.estimatedPriceCents / 100).toFixed(4))}`
132
+ : null) ||
133
+ result.price ||
134
+ "unknown";
135
+ console.log(chalk_1.default.bold("\nEstimated cost: ") + chalk_1.default.yellow(estimatedCost));
136
+ console.log(chalk_1.default.gray("(Use without --dry-run to execute)"));
137
+ return;
138
+ }
126
139
  // Handle binary responses (base64-encoded by the server)
127
140
  if (isBinaryEnvelope(result.data)) {
128
141
  if (!options.output) {
package/dist/index.js CHANGED
@@ -112,6 +112,7 @@ apiGroup
112
112
  .option("-d, --data <json>", "Alias for --body")
113
113
  .option("--raw", "Output raw JSON without formatting")
114
114
  .option("-o, --output <file>", "Save response to file (auto-detects binary like images)")
115
+ .option("--dry-run", "Estimate cost without executing the call")
115
116
  .action(asyncAction(async (slug, path, options) => {
116
117
  (0, analytics_js_1.trackEvent)("api.run", { slug, path });
117
118
  await (0, run_js_1.runCommand)(slug, path, options);
@@ -333,6 +334,7 @@ program
333
334
  .option("-d, --data <json>", "Alias for --body")
334
335
  .option("--raw", "Output raw JSON without formatting")
335
336
  .option("-o, --output <file>", "Save response to file (auto-detects binary like images)")
337
+ .option("--dry-run", "Estimate cost without executing the call")
336
338
  .action(asyncAction(async (api, path, options) => {
337
339
  (0, analytics_js_1.trackEvent)("run", { api, path });
338
340
  await (0, run_js_1.runCommand)(api, path, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orth/cli",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "description": "CLI to access all APIs and skills on the Orthogonal platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {