weflayr 0.22.2 → 0.23.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.
@@ -1,5 +1,30 @@
1
1
  import type { CamelCaseDeep } from '../caseConversion.js';
2
2
  import type * as generatedTypes from './types.gen.js';
3
+ export declare const getMargin: (options: import("../makeEndpoint.js").ClientOption & {
4
+ query?: {
5
+ customerNames?: string[] | undefined;
6
+ cursor?: string | undefined;
7
+ limit?: number | undefined;
8
+ dateFrom?: string | undefined;
9
+ dateTo?: string | undefined;
10
+ applyCredits?: boolean | undefined;
11
+ } | undefined;
12
+ body?: undefined;
13
+ path?: undefined;
14
+ }) => Promise<import("../makeEndpoint.js").CallResult<{
15
+ rows: {
16
+ customerName: string;
17
+ revenue: number;
18
+ cost: number;
19
+ margin: number;
20
+ marginPct: number | null;
21
+ profitabilityStatus: "healthy" | "watch" | "at_risk" | "unprofitable" | "unknown";
22
+ }[];
23
+ nextCursor: string | null;
24
+ hasMore: boolean;
25
+ }, {
26
+ error: string;
27
+ }>>;
3
28
  export declare const deleteRevenue: (options: import("../makeEndpoint.js").ClientOption & {
4
29
  query: {
5
30
  customerNames: string[];
@@ -35,9 +35,10 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  };
36
36
  })();
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.setCustomersTags = exports.getCustomersTags = exports.deleteCustomersTags = exports.setKeyMetrics = exports.getKeyMetrics = exports.deleteKeyMetrics = exports.setRevenue = exports.getRevenue = exports.deleteRevenue = void 0;
38
+ exports.setCustomersTags = exports.getCustomersTags = exports.deleteCustomersTags = exports.setKeyMetrics = exports.getKeyMetrics = exports.deleteKeyMetrics = exports.setRevenue = exports.getRevenue = exports.deleteRevenue = exports.getMargin = void 0;
39
39
  const makeEndpoint_js_1 = require("../makeEndpoint.js");
40
40
  const generated = __importStar(require("./sdk.gen.js"));
41
+ exports.getMargin = (0, makeEndpoint_js_1.makeEndpoint)(generated.getMargin);
41
42
  exports.deleteRevenue = (0, makeEndpoint_js_1.makeEndpoint)(generated.deleteRevenue);
42
43
  exports.getRevenue = (0, makeEndpoint_js_1.makeEndpoint)(generated.getRevenue);
43
44
  exports.setRevenue = (0, makeEndpoint_js_1.makeEndpoint)(generated.setRevenue);
@@ -1,2 +1,2 @@
1
- export { deleteCustomersTags, deleteKeyMetrics, deleteRevenue, getCustomersTags, getKeyMetrics, getRevenue, type Options, setCustomersTags, setKeyMetrics, setRevenue } from './sdk.gen.js';
2
- export type { AllCustomerTagsOutput, ApiErrorOutput, ClientOptions, CustomersUpdatedOutput, CustomerTags, CustomerTagsOutput, DeleteCustomersTagsData, DeleteCustomersTagsError, DeleteCustomersTagsErrors, DeleteCustomersTagsResponse, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsError, DeleteKeyMetricsErrors, DeleteKeyMetricsResponse, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueError, DeleteRevenueErrors, DeleteRevenueResponse, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsError, GetCustomersTagsErrors, GetCustomersTagsResponse, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsError, GetKeyMetricsErrors, GetKeyMetricsResponse, GetKeyMetricsResponses, GetRevenueData, GetRevenueError, GetRevenueErrors, GetRevenueResponse, GetRevenueResponses, InvalidFieldDetail, InvalidPayloadOutput, KeyMetricOutput, KeyMetricRow, KeyMetricRowOutput, RevenueOrKeyMetricDeletedRowOutput, RevenueOrKeyMetricImportedRowOutput, RevenueOutput, RevenueRow, RevenueRowOutput, SetCustomersTagsData, SetCustomersTagsError, SetCustomersTagsErrors, SetCustomersTagsResponse, SetCustomersTagsResponses, SetCustomerTagsInput, SetKeyMetricsData, SetKeyMetricsError, SetKeyMetricsErrors, SetKeyMetricsInput, SetKeyMetricsResponse, SetKeyMetricsResponses, SetRevenueData, SetRevenueError, SetRevenueErrors, SetRevenueInput, SetRevenueResponse, SetRevenueResponses, TagsDeletedOutput } from './types.gen.js';
1
+ export { deleteCustomersTags, deleteKeyMetrics, deleteRevenue, getCustomersTags, getKeyMetrics, getMargin, getRevenue, type Options, setCustomersTags, setKeyMetrics, setRevenue } from './sdk.gen.js';
2
+ export type { AllCustomerTagsOutput, ApiErrorOutput, ClientOptions, CustomerMarginRow, CustomersUpdatedOutput, CustomerTags, CustomerTagsOutput, DeleteCustomersTagsData, DeleteCustomersTagsError, DeleteCustomersTagsErrors, DeleteCustomersTagsResponse, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsError, DeleteKeyMetricsErrors, DeleteKeyMetricsResponse, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueError, DeleteRevenueErrors, DeleteRevenueResponse, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsError, GetCustomersTagsErrors, GetCustomersTagsResponse, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsError, GetKeyMetricsErrors, GetKeyMetricsResponse, GetKeyMetricsResponses, GetMarginData, GetMarginError, GetMarginErrors, GetMarginResponse, GetMarginResponses, GetRevenueData, GetRevenueError, GetRevenueErrors, GetRevenueResponse, GetRevenueResponses, InvalidFieldDetail, InvalidPayloadOutput, KeyMetricOutput, KeyMetricRow, KeyMetricRowOutput, MarginListOutput, RevenueOrKeyMetricDeletedRowOutput, RevenueOrKeyMetricImportedRowOutput, RevenueOutput, RevenueRow, RevenueRowOutput, SetCustomersTagsData, SetCustomersTagsError, SetCustomersTagsErrors, SetCustomersTagsResponse, SetCustomersTagsResponses, SetCustomerTagsInput, SetKeyMetricsData, SetKeyMetricsError, SetKeyMetricsErrors, SetKeyMetricsInput, SetKeyMetricsResponse, SetKeyMetricsResponses, SetRevenueData, SetRevenueError, SetRevenueErrors, SetRevenueInput, SetRevenueResponse, SetRevenueResponses, TagsDeletedOutput } from './types.gen.js';
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  // This file is auto-generated by @hey-api/openapi-ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.setRevenue = exports.setKeyMetrics = exports.setCustomersTags = exports.getRevenue = exports.getKeyMetrics = exports.getCustomersTags = exports.deleteRevenue = exports.deleteKeyMetrics = exports.deleteCustomersTags = void 0;
4
+ exports.setRevenue = exports.setKeyMetrics = exports.setCustomersTags = exports.getRevenue = exports.getMargin = exports.getKeyMetrics = exports.getCustomersTags = exports.deleteRevenue = exports.deleteKeyMetrics = exports.deleteCustomersTags = void 0;
5
5
  var sdk_gen_js_1 = require("./sdk.gen.js");
6
6
  Object.defineProperty(exports, "deleteCustomersTags", { enumerable: true, get: function () { return sdk_gen_js_1.deleteCustomersTags; } });
7
7
  Object.defineProperty(exports, "deleteKeyMetrics", { enumerable: true, get: function () { return sdk_gen_js_1.deleteKeyMetrics; } });
8
8
  Object.defineProperty(exports, "deleteRevenue", { enumerable: true, get: function () { return sdk_gen_js_1.deleteRevenue; } });
9
9
  Object.defineProperty(exports, "getCustomersTags", { enumerable: true, get: function () { return sdk_gen_js_1.getCustomersTags; } });
10
10
  Object.defineProperty(exports, "getKeyMetrics", { enumerable: true, get: function () { return sdk_gen_js_1.getKeyMetrics; } });
11
+ Object.defineProperty(exports, "getMargin", { enumerable: true, get: function () { return sdk_gen_js_1.getMargin; } });
11
12
  Object.defineProperty(exports, "getRevenue", { enumerable: true, get: function () { return sdk_gen_js_1.getRevenue; } });
12
13
  Object.defineProperty(exports, "setCustomersTags", { enumerable: true, get: function () { return sdk_gen_js_1.setCustomersTags; } });
13
14
  Object.defineProperty(exports, "setKeyMetrics", { enumerable: true, get: function () { return sdk_gen_js_1.setKeyMetrics; } });
@@ -1,5 +1,5 @@
1
1
  import type { Client, ClientMeta, Options as Options2, RequestResult, TDataShape } from './client/index.js';
2
- import type { DeleteCustomersTagsData, DeleteCustomersTagsErrors, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsErrors, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueErrors, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsErrors, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsErrors, GetKeyMetricsResponses, GetRevenueData, GetRevenueErrors, GetRevenueResponses, SetCustomersTagsData, SetCustomersTagsErrors, SetCustomersTagsResponses, SetKeyMetricsData, SetKeyMetricsErrors, SetKeyMetricsResponses, SetRevenueData, SetRevenueErrors, SetRevenueResponses } from './types.gen.js';
2
+ import type { DeleteCustomersTagsData, DeleteCustomersTagsErrors, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsErrors, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueErrors, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsErrors, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsErrors, GetKeyMetricsResponses, GetMarginData, GetMarginErrors, GetMarginResponses, GetRevenueData, GetRevenueErrors, GetRevenueResponses, SetCustomersTagsData, SetCustomersTagsErrors, SetCustomersTagsResponses, SetKeyMetricsData, SetKeyMetricsErrors, SetKeyMetricsResponses, SetRevenueData, SetRevenueErrors, SetRevenueResponses } from './types.gen.js';
3
3
  export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & {
4
4
  /**
5
5
  * You can provide a client instance returned by `createClient()` instead of
@@ -13,6 +13,10 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
13
13
  */
14
14
  meta?: keyof ClientMeta extends never ? Record<string, unknown> : ClientMeta;
15
15
  };
16
+ /**
17
+ * Per-customer gross margin, sorted by customer_name ascending; pass customer_names to narrow to specific customers, omit it for every customer's.
18
+ */
19
+ export declare const getMargin: <ThrowOnError extends boolean = false>(options?: Options<GetMarginData, ThrowOnError>) => RequestResult<GetMarginResponses, GetMarginErrors, ThrowOnError>;
16
20
  /**
17
21
  * Delete the given customers' API-uploaded revenue values.
18
22
  */
@@ -1,8 +1,17 @@
1
1
  "use strict";
2
2
  // This file is auto-generated by @hey-api/openapi-ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.setCustomersTags = exports.getCustomersTags = exports.deleteCustomersTags = exports.setKeyMetrics = exports.getKeyMetrics = exports.deleteKeyMetrics = exports.setRevenue = exports.getRevenue = exports.deleteRevenue = void 0;
4
+ exports.setCustomersTags = exports.getCustomersTags = exports.deleteCustomersTags = exports.setKeyMetrics = exports.getKeyMetrics = exports.deleteKeyMetrics = exports.setRevenue = exports.getRevenue = exports.deleteRevenue = exports.getMargin = void 0;
5
5
  const client_gen_js_1 = require("./client.gen.js");
6
+ /**
7
+ * Per-customer gross margin, sorted by customer_name ascending; pass customer_names to narrow to specific customers, omit it for every customer's.
8
+ */
9
+ const getMargin = (options) => (options?.client ?? client_gen_js_1.client).get({
10
+ security: [{ scheme: 'bearer', type: 'http' }],
11
+ url: '/margin/',
12
+ ...options
13
+ });
14
+ exports.getMargin = getMargin;
6
15
  /**
7
16
  * Delete the given customers' API-uploaded revenue values.
8
17
  */
@@ -31,6 +31,37 @@ export type ApiErrorOutput = {
31
31
  */
32
32
  error: string;
33
33
  };
34
+ /**
35
+ * CustomerMarginRow
36
+ *
37
+ * One customer's gross margin for a period.
38
+ */
39
+ export type CustomerMarginRow = {
40
+ /**
41
+ * Customer Name
42
+ */
43
+ customer_name: string;
44
+ /**
45
+ * Revenue
46
+ */
47
+ revenue: number;
48
+ /**
49
+ * Cost
50
+ */
51
+ cost: number;
52
+ /**
53
+ * Margin
54
+ */
55
+ margin: number;
56
+ /**
57
+ * Margin Pct
58
+ */
59
+ margin_pct: number | null;
60
+ /**
61
+ * Profitability Status
62
+ */
63
+ profitability_status: 'healthy' | 'watch' | 'at_risk' | 'unprofitable' | 'unknown';
64
+ };
34
65
  /**
35
66
  * CustomerTags
36
67
  *
@@ -199,6 +230,26 @@ export type KeyMetricRowOutput = {
199
230
  */
200
231
  user_name: string;
201
232
  };
233
+ /**
234
+ * MarginListOutput
235
+ *
236
+ * Margin GET response: one row per customer with booked revenue, sorted by
237
+ * customer_name ascending.
238
+ */
239
+ export type MarginListOutput = {
240
+ /**
241
+ * Rows
242
+ */
243
+ rows: Array<CustomerMarginRow>;
244
+ /**
245
+ * Next Cursor
246
+ */
247
+ next_cursor: string | null;
248
+ /**
249
+ * Has More
250
+ */
251
+ has_more: boolean;
252
+ };
202
253
  /**
203
254
  * RevenueOrKeyMetricDeletedRowOutput
204
255
  *
@@ -385,6 +436,52 @@ export type TagsDeletedOutput = {
385
436
  */
386
437
  tags_deleted: number;
387
438
  };
439
+ export type GetMarginData = {
440
+ body?: never;
441
+ path?: never;
442
+ query?: {
443
+ /**
444
+ * Return only these customers' margin. Omit to return every customer's.
445
+ */
446
+ customer_names?: Array<string>;
447
+ /**
448
+ * Opaque cursor from a previous page's next_cursor.
449
+ */
450
+ cursor?: string;
451
+ limit?: number;
452
+ /**
453
+ * Start of the period (inclusive), YYYY-MM-DD. Defaults to 30 days ago.
454
+ */
455
+ date_from?: string;
456
+ /**
457
+ * End of the period (inclusive), YYYY-MM-DD. Defaults to today.
458
+ */
459
+ date_to?: string;
460
+ /**
461
+ * Apply free-credit discounts to cost. Defaults to false.
462
+ */
463
+ apply_credits?: boolean;
464
+ };
465
+ url: '/margin/';
466
+ };
467
+ export type GetMarginErrors = {
468
+ /**
469
+ * Invalid request for this project type.
470
+ */
471
+ 400: ApiErrorOutput;
472
+ /**
473
+ * Missing or invalid API key.
474
+ */
475
+ 401: ApiErrorOutput;
476
+ };
477
+ export type GetMarginError = GetMarginErrors[keyof GetMarginErrors];
478
+ export type GetMarginResponses = {
479
+ /**
480
+ * Success.
481
+ */
482
+ 200: MarginListOutput;
483
+ };
484
+ export type GetMarginResponse = GetMarginResponses[keyof GetMarginResponses];
388
485
  export type DeleteRevenueData = {
389
486
  body?: never;
390
487
  path?: never;
@@ -427,7 +524,7 @@ export type GetRevenueData = {
427
524
  path?: never;
428
525
  query?: {
429
526
  /**
430
- * Return only these customers' revenue (repeat the param for several). Omit to return every customer's.
527
+ * Return only these customers' revenue. Omit to return every customer's.
431
528
  */
432
529
  customer_names?: Array<string>;
433
530
  /**
@@ -518,7 +615,7 @@ export type GetKeyMetricsData = {
518
615
  path?: never;
519
616
  query?: {
520
617
  /**
521
- * Return only these users' key metrics (repeat the param for several). Omit to return every user's.
618
+ * Return only these users' key metrics. Omit to return every user's.
522
619
  */
523
620
  user_names?: Array<string>;
524
621
  /**
@@ -572,7 +669,7 @@ export type DeleteCustomersTagsData = {
572
669
  path?: never;
573
670
  query: {
574
671
  /**
575
- * Delete every tag of these customers (repeat the param for several).
672
+ * Delete every tag of these customers.
576
673
  */
577
674
  customer_names: Array<string>;
578
675
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weflayr",
3
- "version": "0.22.2",
3
+ "version": "0.23.0",
4
4
  "description": "Weflayr Node.js SDK — instrument any LLM client via JS Proxy",
5
5
  "main": "src/index.js",
6
6
  "types": "index.d.ts",
@@ -7,6 +7,12 @@ import * as generated from './sdk.gen.js';
7
7
  import type * as generatedTypes from './types.gen.js';
8
8
 
9
9
 
10
+ export const getMargin = makeEndpoint<
11
+ CamelCaseDeep<Omit<generatedTypes.GetMarginData, 'url'>>,
12
+ CamelCaseDeep<generatedTypes.GetMarginResponse>,
13
+ CamelCaseDeep<generatedTypes.GetMarginError>
14
+ >(generated.getMargin);
15
+
10
16
  export const deleteRevenue = makeEndpoint<
11
17
  CamelCaseDeep<Omit<generatedTypes.DeleteRevenueData, 'url'>>,
12
18
  CamelCaseDeep<generatedTypes.DeleteRevenueResponse>,
@@ -1,4 +1,4 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
 
3
- export { deleteCustomersTags, deleteKeyMetrics, deleteRevenue, getCustomersTags, getKeyMetrics, getRevenue, type Options, setCustomersTags, setKeyMetrics, setRevenue } from './sdk.gen.js';
4
- export type { AllCustomerTagsOutput, ApiErrorOutput, ClientOptions, CustomersUpdatedOutput, CustomerTags, CustomerTagsOutput, DeleteCustomersTagsData, DeleteCustomersTagsError, DeleteCustomersTagsErrors, DeleteCustomersTagsResponse, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsError, DeleteKeyMetricsErrors, DeleteKeyMetricsResponse, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueError, DeleteRevenueErrors, DeleteRevenueResponse, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsError, GetCustomersTagsErrors, GetCustomersTagsResponse, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsError, GetKeyMetricsErrors, GetKeyMetricsResponse, GetKeyMetricsResponses, GetRevenueData, GetRevenueError, GetRevenueErrors, GetRevenueResponse, GetRevenueResponses, InvalidFieldDetail, InvalidPayloadOutput, KeyMetricOutput, KeyMetricRow, KeyMetricRowOutput, RevenueOrKeyMetricDeletedRowOutput, RevenueOrKeyMetricImportedRowOutput, RevenueOutput, RevenueRow, RevenueRowOutput, SetCustomersTagsData, SetCustomersTagsError, SetCustomersTagsErrors, SetCustomersTagsResponse, SetCustomersTagsResponses, SetCustomerTagsInput, SetKeyMetricsData, SetKeyMetricsError, SetKeyMetricsErrors, SetKeyMetricsInput, SetKeyMetricsResponse, SetKeyMetricsResponses, SetRevenueData, SetRevenueError, SetRevenueErrors, SetRevenueInput, SetRevenueResponse, SetRevenueResponses, TagsDeletedOutput } from './types.gen.js';
3
+ export { deleteCustomersTags, deleteKeyMetrics, deleteRevenue, getCustomersTags, getKeyMetrics, getMargin, getRevenue, type Options, setCustomersTags, setKeyMetrics, setRevenue } from './sdk.gen.js';
4
+ export type { AllCustomerTagsOutput, ApiErrorOutput, ClientOptions, CustomerMarginRow, CustomersUpdatedOutput, CustomerTags, CustomerTagsOutput, DeleteCustomersTagsData, DeleteCustomersTagsError, DeleteCustomersTagsErrors, DeleteCustomersTagsResponse, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsError, DeleteKeyMetricsErrors, DeleteKeyMetricsResponse, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueError, DeleteRevenueErrors, DeleteRevenueResponse, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsError, GetCustomersTagsErrors, GetCustomersTagsResponse, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsError, GetKeyMetricsErrors, GetKeyMetricsResponse, GetKeyMetricsResponses, GetMarginData, GetMarginError, GetMarginErrors, GetMarginResponse, GetMarginResponses, GetRevenueData, GetRevenueError, GetRevenueErrors, GetRevenueResponse, GetRevenueResponses, InvalidFieldDetail, InvalidPayloadOutput, KeyMetricOutput, KeyMetricRow, KeyMetricRowOutput, MarginListOutput, RevenueOrKeyMetricDeletedRowOutput, RevenueOrKeyMetricImportedRowOutput, RevenueOutput, RevenueRow, RevenueRowOutput, SetCustomersTagsData, SetCustomersTagsError, SetCustomersTagsErrors, SetCustomersTagsResponse, SetCustomersTagsResponses, SetCustomerTagsInput, SetKeyMetricsData, SetKeyMetricsError, SetKeyMetricsErrors, SetKeyMetricsInput, SetKeyMetricsResponse, SetKeyMetricsResponses, SetRevenueData, SetRevenueError, SetRevenueErrors, SetRevenueInput, SetRevenueResponse, SetRevenueResponses, TagsDeletedOutput } from './types.gen.js';
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { client } from './client.gen.js';
4
4
  import type { Client, ClientMeta, Options as Options2, RequestResult, TDataShape } from './client/index.js';
5
- import type { DeleteCustomersTagsData, DeleteCustomersTagsErrors, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsErrors, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueErrors, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsErrors, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsErrors, GetKeyMetricsResponses, GetRevenueData, GetRevenueErrors, GetRevenueResponses, SetCustomersTagsData, SetCustomersTagsErrors, SetCustomersTagsResponses, SetKeyMetricsData, SetKeyMetricsErrors, SetKeyMetricsResponses, SetRevenueData, SetRevenueErrors, SetRevenueResponses } from './types.gen.js';
5
+ import type { DeleteCustomersTagsData, DeleteCustomersTagsErrors, DeleteCustomersTagsResponses, DeleteKeyMetricsData, DeleteKeyMetricsErrors, DeleteKeyMetricsResponses, DeleteRevenueData, DeleteRevenueErrors, DeleteRevenueResponses, GetCustomersTagsData, GetCustomersTagsErrors, GetCustomersTagsResponses, GetKeyMetricsData, GetKeyMetricsErrors, GetKeyMetricsResponses, GetMarginData, GetMarginErrors, GetMarginResponses, GetRevenueData, GetRevenueErrors, GetRevenueResponses, SetCustomersTagsData, SetCustomersTagsErrors, SetCustomersTagsResponses, SetKeyMetricsData, SetKeyMetricsErrors, SetKeyMetricsResponses, SetRevenueData, SetRevenueErrors, SetRevenueResponses } from './types.gen.js';
6
6
 
7
7
  export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & {
8
8
  /**
@@ -18,6 +18,15 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
18
18
  meta?: keyof ClientMeta extends never ? Record<string, unknown> : ClientMeta;
19
19
  };
20
20
 
21
+ /**
22
+ * Per-customer gross margin, sorted by customer_name ascending; pass customer_names to narrow to specific customers, omit it for every customer's.
23
+ */
24
+ export const getMargin = <ThrowOnError extends boolean = false>(options?: Options<GetMarginData, ThrowOnError>): RequestResult<GetMarginResponses, GetMarginErrors, ThrowOnError> => (options?.client ?? client).get<GetMarginResponses, GetMarginErrors, ThrowOnError>({
25
+ security: [{ scheme: 'bearer', type: 'http' }],
26
+ url: '/margin/',
27
+ ...options
28
+ });
29
+
21
30
  /**
22
31
  * Delete the given customers' API-uploaded revenue values.
23
32
  */
@@ -36,6 +36,38 @@ export type ApiErrorOutput = {
36
36
  error: string;
37
37
  };
38
38
 
39
+ /**
40
+ * CustomerMarginRow
41
+ *
42
+ * One customer's gross margin for a period.
43
+ */
44
+ export type CustomerMarginRow = {
45
+ /**
46
+ * Customer Name
47
+ */
48
+ customer_name: string;
49
+ /**
50
+ * Revenue
51
+ */
52
+ revenue: number;
53
+ /**
54
+ * Cost
55
+ */
56
+ cost: number;
57
+ /**
58
+ * Margin
59
+ */
60
+ margin: number;
61
+ /**
62
+ * Margin Pct
63
+ */
64
+ margin_pct: number | null;
65
+ /**
66
+ * Profitability Status
67
+ */
68
+ profitability_status: 'healthy' | 'watch' | 'at_risk' | 'unprofitable' | 'unknown';
69
+ };
70
+
39
71
  /**
40
72
  * CustomerTags
41
73
  *
@@ -212,6 +244,27 @@ export type KeyMetricRowOutput = {
212
244
  user_name: string;
213
245
  };
214
246
 
247
+ /**
248
+ * MarginListOutput
249
+ *
250
+ * Margin GET response: one row per customer with booked revenue, sorted by
251
+ * customer_name ascending.
252
+ */
253
+ export type MarginListOutput = {
254
+ /**
255
+ * Rows
256
+ */
257
+ rows: Array<CustomerMarginRow>;
258
+ /**
259
+ * Next Cursor
260
+ */
261
+ next_cursor: string | null;
262
+ /**
263
+ * Has More
264
+ */
265
+ has_more: boolean;
266
+ };
267
+
215
268
  /**
216
269
  * RevenueOrKeyMetricDeletedRowOutput
217
270
  *
@@ -407,6 +460,57 @@ export type TagsDeletedOutput = {
407
460
  tags_deleted: number;
408
461
  };
409
462
 
463
+ export type GetMarginData = {
464
+ body?: never;
465
+ path?: never;
466
+ query?: {
467
+ /**
468
+ * Return only these customers' margin. Omit to return every customer's.
469
+ */
470
+ customer_names?: Array<string>;
471
+ /**
472
+ * Opaque cursor from a previous page's next_cursor.
473
+ */
474
+ cursor?: string;
475
+ limit?: number;
476
+ /**
477
+ * Start of the period (inclusive), YYYY-MM-DD. Defaults to 30 days ago.
478
+ */
479
+ date_from?: string;
480
+ /**
481
+ * End of the period (inclusive), YYYY-MM-DD. Defaults to today.
482
+ */
483
+ date_to?: string;
484
+ /**
485
+ * Apply free-credit discounts to cost. Defaults to false.
486
+ */
487
+ apply_credits?: boolean;
488
+ };
489
+ url: '/margin/';
490
+ };
491
+
492
+ export type GetMarginErrors = {
493
+ /**
494
+ * Invalid request for this project type.
495
+ */
496
+ 400: ApiErrorOutput;
497
+ /**
498
+ * Missing or invalid API key.
499
+ */
500
+ 401: ApiErrorOutput;
501
+ };
502
+
503
+ export type GetMarginError = GetMarginErrors[keyof GetMarginErrors];
504
+
505
+ export type GetMarginResponses = {
506
+ /**
507
+ * Success.
508
+ */
509
+ 200: MarginListOutput;
510
+ };
511
+
512
+ export type GetMarginResponse = GetMarginResponses[keyof GetMarginResponses];
513
+
410
514
  export type DeleteRevenueData = {
411
515
  body?: never;
412
516
  path?: never;
@@ -454,7 +558,7 @@ export type GetRevenueData = {
454
558
  path?: never;
455
559
  query?: {
456
560
  /**
457
- * Return only these customers' revenue (repeat the param for several). Omit to return every customer's.
561
+ * Return only these customers' revenue. Omit to return every customer's.
458
562
  */
459
563
  customer_names?: Array<string>;
460
564
  /**
@@ -560,7 +664,7 @@ export type GetKeyMetricsData = {
560
664
  path?: never;
561
665
  query?: {
562
666
  /**
563
- * Return only these users' key metrics (repeat the param for several). Omit to return every user's.
667
+ * Return only these users' key metrics. Omit to return every user's.
564
668
  */
565
669
  user_names?: Array<string>;
566
670
  /**
@@ -624,7 +728,7 @@ export type DeleteCustomersTagsData = {
624
728
  path?: never;
625
729
  query: {
626
730
  /**
627
- * Delete every tag of these customers (repeat the param for several).
731
+ * Delete every tag of these customers.
628
732
  */
629
733
  customer_names: Array<string>;
630
734
  };
@@ -274,6 +274,82 @@ test('deleteKeyMetrics sends the userNames filter and parses the deleted count',
274
274
  });
275
275
  });
276
276
 
277
+ // ── Margin ────────────────────────────────────────────────────────────────────
278
+
279
+ test('getMargin parses the returned rows into camelCase', async () => {
280
+ const wireRow = {
281
+ customer_name: 'c_1',
282
+ revenue: 1000.0,
283
+ cost: 200.0,
284
+ margin: 800.0,
285
+ margin_pct: 80.0,
286
+ profitability_status: 'healthy',
287
+ };
288
+ await withClientReturning(
289
+ { rows: [wireRow], next_cursor: null, has_more: false },
290
+ 200,
291
+ async (client) => {
292
+ const { data } = await api.getMargin({ client, throwOnError: true });
293
+ assert.deepEqual(data.rows, [
294
+ {
295
+ customerName: 'c_1',
296
+ revenue: 1000.0,
297
+ cost: 200.0,
298
+ margin: 800.0,
299
+ marginPct: 80.0,
300
+ profitabilityStatus: 'healthy',
301
+ },
302
+ ]);
303
+ }
304
+ );
305
+ });
306
+
307
+ test('getMargin sends the cursor and limit query params', async () => {
308
+ await withClientReturning(
309
+ { rows: [], next_cursor: 'Y19h', has_more: true },
310
+ 200,
311
+ async (client, seenRequests) => {
312
+ const { data } = await api.getMargin({
313
+ client,
314
+ throwOnError: true,
315
+ query: { cursor: 'abc123', limit: 2 },
316
+ });
317
+ assert.equal(data.nextCursor, 'Y19h');
318
+ assert.equal(data.hasMore, true);
319
+ const query = new URL(seenRequests[0].url, 'http://x').searchParams;
320
+ assert.equal(query.get('cursor'), 'abc123');
321
+ assert.equal(query.get('limit'), '2');
322
+ }
323
+ );
324
+ });
325
+
326
+ test('getMargin sends the customerNames filter as repeated params', async () => {
327
+ await withClientReturning({ rows: [] }, 200, async (client, seenRequests) => {
328
+ const { data } = await api.getMargin({
329
+ client,
330
+ throwOnError: true,
331
+ query: { customerNames: ['c_1', 'c_2'] },
332
+ });
333
+ assert.deepEqual(data, { rows: [] });
334
+ const query = new URL(seenRequests[0].url, 'http://x').searchParams;
335
+ assert.deepEqual(query.getAll('customer_names'), ['c_1', 'c_2']);
336
+ });
337
+ });
338
+
339
+ test('getMargin sends the dateFrom/dateTo/applyCredits filters in snake_case', async () => {
340
+ await withClientReturning({ rows: [] }, 200, async (client, seenRequests) => {
341
+ await api.getMargin({
342
+ client,
343
+ throwOnError: true,
344
+ query: { dateFrom: '2026-06-01', dateTo: '2026-06-30', applyCredits: true },
345
+ });
346
+ const query = new URL(seenRequests[0].url, 'http://x').searchParams;
347
+ assert.equal(query.get('date_from'), '2026-06-01');
348
+ assert.equal(query.get('date_to'), '2026-06-30');
349
+ assert.equal(query.get('apply_credits'), 'true');
350
+ });
351
+ });
352
+
277
353
  // ── Customer tags ─────────────────────────────────────────────────────────────
278
354
 
279
355
  test('setCustomersTags posts the customers in snake_case and parses the updated count', async () => {