@moovio/sdk 26.4.6 → 26.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +30 -2
  2. package/bin/mcp-server.js +88 -16
  3. package/bin/mcp-server.js.map +16 -14
  4. package/hooks/access-token-hook.d.ts +25 -0
  5. package/hooks/access-token-hook.d.ts.map +1 -0
  6. package/hooks/access-token-hook.js +60 -0
  7. package/hooks/access-token-hook.js.map +1 -0
  8. package/hooks/registration.d.ts.map +1 -1
  9. package/hooks/registration.js +4 -0
  10. package/hooks/registration.js.map +1 -1
  11. package/jsr.json +1 -1
  12. package/lib/config.d.ts +7 -3
  13. package/lib/config.d.ts.map +1 -1
  14. package/lib/config.js +3 -3
  15. package/lib/config.js.map +1 -1
  16. package/mcp-server/cli/start/command.d.ts.map +1 -1
  17. package/mcp-server/cli/start/command.js +8 -0
  18. package/mcp-server/cli/start/command.js.map +1 -1
  19. package/mcp-server/cli/start/impl.d.ts +1 -0
  20. package/mcp-server/cli/start/impl.d.ts.map +1 -1
  21. package/mcp-server/cli/start/impl.js +2 -0
  22. package/mcp-server/cli/start/impl.js.map +1 -1
  23. package/mcp-server/mcp-server.js +1 -1
  24. package/mcp-server/server.d.ts +1 -0
  25. package/mcp-server/server.d.ts.map +1 -1
  26. package/mcp-server/server.js +2 -1
  27. package/mcp-server/server.js.map +1 -1
  28. package/models/components/index.d.ts +1 -0
  29. package/models/components/index.d.ts.map +1 -1
  30. package/models/components/index.js +1 -0
  31. package/models/components/index.js.map +1 -1
  32. package/models/components/invoice.d.ts +1 -1
  33. package/models/components/transferconfig.d.ts +3 -0
  34. package/models/components/transferconfig.d.ts.map +1 -1
  35. package/models/components/transferconfig.js +3 -0
  36. package/models/components/transferconfig.js.map +1 -1
  37. package/models/components/transfercontrols.d.ts +43 -0
  38. package/models/components/transfercontrols.d.ts.map +1 -0
  39. package/models/components/transfercontrols.js +66 -0
  40. package/models/components/transfercontrols.js.map +1 -0
  41. package/models/components/updateinvoice.d.ts +6 -6
  42. package/package.json +1 -1
  43. package/src/hooks/access-token-hook.ts +73 -0
  44. package/src/hooks/registration.ts +5 -0
  45. package/src/lib/config.ts +8 -3
  46. package/src/mcp-server/cli/start/command.ts +9 -0
  47. package/src/mcp-server/cli/start/impl.ts +3 -0
  48. package/src/mcp-server/mcp-server.ts +1 -1
  49. package/src/mcp-server/server.ts +3 -1
  50. package/src/models/components/index.ts +1 -0
  51. package/src/models/components/invoice.ts +1 -1
  52. package/src/models/components/transferconfig.ts +10 -0
  53. package/src/models/components/transfercontrols.ts +85 -0
  54. package/src/models/components/updateinvoice.ts +6 -6
  55. package/src/types/async.ts +8 -7
  56. package/test/tests/accessToken.test.ts +86 -0
  57. package/types/async.d.ts.map +1 -1
  58. package/types/async.js +8 -7
  59. package/types/async.js.map +1 -1
@@ -0,0 +1,43 @@
1
+ import * as z from "zod/v3";
2
+ import { Result as SafeParseResult } from "../../types/fp.js";
3
+ import { SDKValidationError } from "../errors/sdkvalidationerror.js";
4
+ /**
5
+ * Controls for transfers created through a given partner
6
+ */
7
+ export type TransferControls = {
8
+ /**
9
+ * ID of the merchant account.
10
+ */
11
+ accountID: string;
12
+ /**
13
+ * ID of the partner account.
14
+ */
15
+ partnerAccountID: string;
16
+ /**
17
+ * Indicates if the account is configured for debt repayment.
18
+ */
19
+ debtRepayment: boolean;
20
+ /**
21
+ * Indicates if the account is allowed to set dynamic descriptors on transfers.
22
+ */
23
+ allowDynamicDescriptor: boolean;
24
+ /**
25
+ * Indicates if the account is allowed to apply surcharges to transfers.
26
+ */
27
+ allowSurcharge: boolean;
28
+ };
29
+ /** @internal */
30
+ export declare const TransferControls$inboundSchema: z.ZodType<TransferControls, z.ZodTypeDef, unknown>;
31
+ /** @internal */
32
+ export type TransferControls$Outbound = {
33
+ accountID: string;
34
+ partnerAccountID: string;
35
+ debtRepayment: boolean;
36
+ allowDynamicDescriptor: boolean;
37
+ allowSurcharge: boolean;
38
+ };
39
+ /** @internal */
40
+ export declare const TransferControls$outboundSchema: z.ZodType<TransferControls$Outbound, z.ZodTypeDef, TransferControls>;
41
+ export declare function transferControlsToJSON(transferControls: TransferControls): string;
42
+ export declare function transferControlsFromJSON(jsonString: string): SafeParseResult<TransferControls, SDKValidationError>;
43
+ //# sourceMappingURL=transfercontrols.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfercontrols.d.ts","sourceRoot":"","sources":["../../src/models/components/transfercontrols.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,8BAA8B,EAAE,CAAC,CAAC,OAAO,CACpD,gBAAgB,EAChB,CAAC,CAAC,UAAU,EACZ,OAAO,CAOP,CAAC;AACH,gBAAgB;AAChB,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,+BAA+B,EAAE,CAAC,CAAC,OAAO,CACrD,yBAAyB,EACzB,CAAC,CAAC,UAAU,EACZ,gBAAgB,CAOhB,CAAC;AAEH,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,gBAAgB,GACjC,MAAM,CAIR;AACD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,GACjB,eAAe,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAMvD"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /*
3
+ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.TransferControls$outboundSchema = exports.TransferControls$inboundSchema = void 0;
40
+ exports.transferControlsToJSON = transferControlsToJSON;
41
+ exports.transferControlsFromJSON = transferControlsFromJSON;
42
+ const z = __importStar(require("zod/v3"));
43
+ const schemas_js_1 = require("../../lib/schemas.js");
44
+ /** @internal */
45
+ exports.TransferControls$inboundSchema = z.object({
46
+ accountID: z.string(),
47
+ partnerAccountID: z.string(),
48
+ debtRepayment: z.boolean(),
49
+ allowDynamicDescriptor: z.boolean(),
50
+ allowSurcharge: z.boolean(),
51
+ });
52
+ /** @internal */
53
+ exports.TransferControls$outboundSchema = z.object({
54
+ accountID: z.string(),
55
+ partnerAccountID: z.string(),
56
+ debtRepayment: z.boolean(),
57
+ allowDynamicDescriptor: z.boolean(),
58
+ allowSurcharge: z.boolean(),
59
+ });
60
+ function transferControlsToJSON(transferControls) {
61
+ return JSON.stringify(exports.TransferControls$outboundSchema.parse(transferControls));
62
+ }
63
+ function transferControlsFromJSON(jsonString) {
64
+ return (0, schemas_js_1.safeParse)(jsonString, (x) => exports.TransferControls$inboundSchema.parse(JSON.parse(x)), `Failed to parse 'TransferControls' from JSON`);
65
+ }
66
+ //# sourceMappingURL=transfercontrols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfercontrols.js","sourceRoot":"","sources":["../../src/models/components/transfercontrols.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEH,wDAMC;AACD,4DAQC;AAhFD,0CAA4B;AAC5B,qDAAiD;AA8BjD,gBAAgB;AACH,QAAA,8BAA8B,GAIvC,CAAC,CAAC,MAAM,CAAC;IACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,sBAAsB,EAAE,CAAC,CAAC,OAAO,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;CAC5B,CAAC,CAAC;AAUH,gBAAgB;AACH,QAAA,+BAA+B,GAIxC,CAAC,CAAC,MAAM,CAAC;IACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,sBAAsB,EAAE,CAAC,CAAC,OAAO,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;CAC5B,CAAC,CAAC;AAEH,SAAgB,sBAAsB,CACpC,gBAAkC;IAElC,OAAO,IAAI,CAAC,SAAS,CACnB,uCAA+B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CACxD,CAAC;AACJ,CAAC;AACD,SAAgB,wBAAwB,CACtC,UAAkB;IAElB,OAAO,IAAA,sBAAS,EACd,UAAU,EACV,CAAC,CAAC,EAAE,EAAE,CAAC,sCAA8B,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAC1D,8CAA8C,CAC/C,CAAC;AACJ,CAAC"}
@@ -13,14 +13,14 @@ export type UpdateInvoice = {
13
13
  invoiceDate?: Date | null | undefined;
14
14
  dueDate?: Date | null | undefined;
15
15
  /**
16
- * The status can be updated to one of the following values under specific conditions:
16
+ * The status can be updated to one of the following values under specific conditions:
17
17
  *
18
18
  * @remarks
19
- * - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`. Canceling an invoice
20
- * indicates the invoice is no longer expected to be paid (e.g., the charge was waived or terms changed).
21
- * Canceled invoices still appear in list results by default and remain part of the invoice history.
22
- * To completely discard an invoice created by mistake, use the delete endpoint instead.
23
- * - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
19
+ * - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`. Canceling an invoice
20
+ * indicates the invoice is no longer expected to be paid (e.g., the charge was waived or terms changed).
21
+ * Canceled invoices still appear in list results by default and remain part of the invoice history.
22
+ * To completely discard an invoice created by mistake, use the delete endpoint instead.
23
+ * - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
24
24
  */
25
25
  status?: InvoiceStatus | undefined;
26
26
  taxAmount?: AmountDecimalUpdate | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moovio/sdk",
3
- "version": "26.4.6",
3
+ "version": "26.5.1",
4
4
  "author": "Moov",
5
5
  "bin": {
6
6
  "mcp": "bin/mcp-server.js"
@@ -0,0 +1,73 @@
1
+ import { SDKOptions } from "../lib/config.js";
2
+ import {
3
+ BeforeRequestContext,
4
+ BeforeRequestHook,
5
+ SDKInitHook,
6
+ } from "./types.js";
7
+
8
+ const gt: unknown = typeof globalThis === "undefined" ? null : globalThis;
9
+ const webWorkerLike = typeof gt === "object"
10
+ && gt != null
11
+ && "importScripts" in gt
12
+ && typeof gt["importScripts"] === "function";
13
+ const isBrowserLike = webWorkerLike
14
+ || (typeof navigator !== "undefined" && "serviceWorker" in navigator)
15
+ || (typeof window === "object" && typeof window.document !== "undefined");
16
+
17
+ /**
18
+ * Applies bearer-token authentication and validates auth-related SDK
19
+ * options at construction time.
20
+ *
21
+ * `accessToken` is exposed as a top-level SDK option via the
22
+ * `x-speakeasy-globals` overlay in `.speakeasy/overlays/access-token.yaml`.
23
+ * Speakeasy doesn't auto-send it (no operation declares a matching
24
+ * parameter), so this hook is responsible for translating it into the
25
+ * `Authorization: Bearer …` header.
26
+ *
27
+ * HTTP Basic credentials (`security.username` / `security.password`) are
28
+ * still handled automatically by Speakeasy's generated security pipeline.
29
+ *
30
+ * Validation rules enforced at SDK init:
31
+ * - `accessToken` and `security.username`/`password` cannot both be set.
32
+ * - HTTP Basic credentials are rejected in browser-like environments.
33
+ * Browsers must use `accessToken` instead.
34
+ */
35
+ export class AccessTokenHook implements SDKInitHook, BeforeRequestHook {
36
+ sdkInit(opts: SDKOptions): SDKOptions {
37
+ const token = (opts as SDKOptions & { accessToken: string }).accessToken;
38
+ const hasToken = typeof token === "string" && token.length > 0;
39
+
40
+ if (hasToken && opts.security != null) {
41
+ throw new Error(
42
+ "Moov SDK: `accessToken` and `security.username`/`password` cannot "
43
+ + "both be set. Use `accessToken` for OAuth2 bearer auth "
44
+ + "(typically client-side) or `security.username`/`password` for "
45
+ + "HTTP Basic auth with API keys (server-side).",
46
+ );
47
+ }
48
+
49
+ if (isBrowserLike && opts.security != null) {
50
+ throw new Error(
51
+ "Moov SDK: HTTP Basic credentials were provided in a browser-like "
52
+ + "environment. API keys must never be embedded in client-side "
53
+ + "code. Mint a short-lived OAuth2 access token on your server "
54
+ + "and pass it via the `accessToken` option instead.",
55
+ );
56
+ }
57
+
58
+ return opts;
59
+ }
60
+
61
+ beforeRequest(ctx: BeforeRequestContext, request: Request): Request {
62
+ const token = (ctx.options as SDKOptions & { accessToken: string }).accessToken;
63
+
64
+ // Bail early if there's no token or the request already has an Authorization header.
65
+ if (!token || request.headers.has("Authorization")) {
66
+ return request;
67
+ }
68
+
69
+ const next = new Request(request);
70
+ next.headers.set("Authorization", `Bearer ${token}`);
71
+ return next;
72
+ }
73
+ }
@@ -1,3 +1,4 @@
1
+ import { AccessTokenHook } from "./access-token-hook.js";
1
2
  import { MoovVersionHook } from "./moov-version-hook.js";
2
3
  import { Hooks } from "./types.js";
3
4
 
@@ -14,4 +15,8 @@ export function initHooks(hooks: Hooks) {
14
15
 
15
16
  const versionHook = new MoovVersionHook();
16
17
  hooks.registerBeforeRequestHook(versionHook);
18
+
19
+ const accessTokenHook = new AccessTokenHook();
20
+ hooks.registerSDKInitHook(accessTokenHook);
21
+ hooks.registerBeforeRequestHook(accessTokenHook);
17
22
  }
package/src/lib/config.ts CHANGED
@@ -27,6 +27,11 @@ export type SDKOptions = {
27
27
  | (() => Promise<components.Security>)
28
28
  | undefined;
29
29
 
30
+ /**
31
+ * Allows setting the accessToken parameter for all supported operations
32
+ */
33
+ accessToken?: string | undefined;
34
+
30
35
  httpClient?: HTTPClient;
31
36
  /**
32
37
  * Allows overriding the default server used by the SDK
@@ -68,7 +73,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
68
73
  export const SDK_METADATA = {
69
74
  language: "typescript",
70
75
  openapiDocVersion: "v2026.04.00",
71
- sdkVersion: "26.4.6",
72
- genVersion: "2.884.0",
73
- userAgent: "speakeasy-sdk/typescript 26.4.6 2.884.0 v2026.04.00 @moovio/sdk",
76
+ sdkVersion: "26.5.1",
77
+ genVersion: "2.893.0",
78
+ userAgent: "speakeasy-sdk/typescript 26.5.1 2.893.0 v2026.04.00 @moovio/sdk",
74
79
  } as const;
@@ -51,6 +51,15 @@ export const startCommand = buildCommand({
51
51
  return z.string().parse(value);
52
52
  },
53
53
  },
54
+ "access-token": {
55
+ kind: "parsed",
56
+ brief:
57
+ "Allows setting the accessToken parameter for all supported operations",
58
+ optional: true,
59
+ parse: (value) => {
60
+ return z.string().parse(value);
61
+ },
62
+ },
54
63
  "server-url": {
55
64
  kind: "parsed",
56
65
  brief: "Overrides the default server URL used by the SDK",
@@ -20,6 +20,7 @@ interface StartCommandFlags {
20
20
  readonly tool?: string[];
21
21
  readonly username?: string | undefined;
22
22
  readonly password?: string | undefined;
23
+ readonly "access-token"?: SDKOptions["accessToken"] | undefined;
23
24
  readonly "server-url"?: string;
24
25
  readonly "server-index"?: SDKOptions["serverIdx"];
25
26
  readonly "log-level": ConsoleLoggerLevel;
@@ -53,6 +54,7 @@ async function startStdio(flags: StartCommandFlags) {
53
54
  username: flags.username ?? "",
54
55
  password: flags.password ?? "",
55
56
  }),
57
+ accessToken: flags["access-token"],
56
58
  serverURL: flags["server-url"],
57
59
  serverIdx: flags["server-index"],
58
60
  });
@@ -76,6 +78,7 @@ async function startSSE(flags: StartCommandFlags) {
76
78
  username: flags.username ?? "",
77
79
  password: flags.password ?? "",
78
80
  }),
81
+ accessToken: flags["access-token"],
79
82
  serverURL: flags["server-url"],
80
83
  serverIdx: flags["server-index"],
81
84
  });
@@ -19,7 +19,7 @@ const routes = buildRouteMap({
19
19
  export const app = buildApplication(routes, {
20
20
  name: "mcp",
21
21
  versionInfo: {
22
- currentVersion: "26.4.6",
22
+ currentVersion: "26.5.1",
23
23
  },
24
24
  });
25
25
 
@@ -207,15 +207,17 @@ export function createMCPServer(deps: {
207
207
  scopes?: MCPScope[] | undefined;
208
208
  serverURL?: string | undefined;
209
209
  security?: SDKOptions["security"] | undefined;
210
+ accessToken?: SDKOptions["accessToken"] | undefined;
210
211
  serverIdx?: SDKOptions["serverIdx"] | undefined;
211
212
  }) {
212
213
  const server = new McpServer({
213
214
  name: "Moov",
214
- version: "26.4.6",
215
+ version: "26.5.1",
215
216
  });
216
217
 
217
218
  const client = new MoovCore({
218
219
  security: deps.security,
220
+ accessToken: deps.accessToken,
219
221
  serverURL: deps.serverURL,
220
222
  serverIdx: deps.serverIdx,
221
223
  });
@@ -517,6 +517,7 @@ export * from "./transferaccount.js";
517
517
  export * from "./transferachaddendarecord.js";
518
518
  export * from "./transferamountdetails.js";
519
519
  export * from "./transferconfig.js";
520
+ export * from "./transfercontrols.js";
520
521
  export * from "./transferdestination.js";
521
522
  export * from "./transferentrymode.js";
522
523
  export * from "./transferfailurereason.js";
@@ -61,7 +61,7 @@ export type Invoice = {
61
61
  subtotalAmount: AmountDecimal;
62
62
  taxAmount: AmountDecimal;
63
63
  /**
64
- * Total amount of the invoice, sum of subTotalAmount and taxAmount
64
+ * Total amount of the invoice, including subtotal, tax, and surcharge amounts.
65
65
  */
66
66
  totalAmount: AmountDecimal;
67
67
  /**
@@ -12,6 +12,12 @@ import {
12
12
  TipPresets$Outbound,
13
13
  TipPresets$outboundSchema,
14
14
  } from "./tippresets.js";
15
+ import {
16
+ TransferControls,
17
+ TransferControls$inboundSchema,
18
+ TransferControls$Outbound,
19
+ TransferControls$outboundSchema,
20
+ } from "./transfercontrols.js";
15
21
 
16
22
  /**
17
23
  * Configurable options for a transfer.
@@ -21,6 +27,7 @@ export type TransferConfig = {
21
27
  * Tip presets when calculating tips for a transfer.
22
28
  */
23
29
  tipPresets?: TipPresets | undefined;
30
+ transferControls?: Array<TransferControls> | undefined;
24
31
  };
25
32
 
26
33
  /** @internal */
@@ -30,10 +37,12 @@ export const TransferConfig$inboundSchema: z.ZodType<
30
37
  unknown
31
38
  > = z.object({
32
39
  tipPresets: TipPresets$inboundSchema.optional(),
40
+ transferControls: z.array(TransferControls$inboundSchema).optional(),
33
41
  });
34
42
  /** @internal */
35
43
  export type TransferConfig$Outbound = {
36
44
  tipPresets?: TipPresets$Outbound | undefined;
45
+ transferControls?: Array<TransferControls$Outbound> | undefined;
37
46
  };
38
47
 
39
48
  /** @internal */
@@ -43,6 +52,7 @@ export const TransferConfig$outboundSchema: z.ZodType<
43
52
  TransferConfig
44
53
  > = z.object({
45
54
  tipPresets: TipPresets$outboundSchema.optional(),
55
+ transferControls: z.array(TransferControls$outboundSchema).optional(),
46
56
  });
47
57
 
48
58
  export function transferConfigToJSON(transferConfig: TransferConfig): string {
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ */
4
+
5
+ import * as z from "zod/v3";
6
+ import { safeParse } from "../../lib/schemas.js";
7
+ import { Result as SafeParseResult } from "../../types/fp.js";
8
+ import { SDKValidationError } from "../errors/sdkvalidationerror.js";
9
+
10
+ /**
11
+ * Controls for transfers created through a given partner
12
+ */
13
+ export type TransferControls = {
14
+ /**
15
+ * ID of the merchant account.
16
+ */
17
+ accountID: string;
18
+ /**
19
+ * ID of the partner account.
20
+ */
21
+ partnerAccountID: string;
22
+ /**
23
+ * Indicates if the account is configured for debt repayment.
24
+ */
25
+ debtRepayment: boolean;
26
+ /**
27
+ * Indicates if the account is allowed to set dynamic descriptors on transfers.
28
+ */
29
+ allowDynamicDescriptor: boolean;
30
+ /**
31
+ * Indicates if the account is allowed to apply surcharges to transfers.
32
+ */
33
+ allowSurcharge: boolean;
34
+ };
35
+
36
+ /** @internal */
37
+ export const TransferControls$inboundSchema: z.ZodType<
38
+ TransferControls,
39
+ z.ZodTypeDef,
40
+ unknown
41
+ > = z.object({
42
+ accountID: z.string(),
43
+ partnerAccountID: z.string(),
44
+ debtRepayment: z.boolean(),
45
+ allowDynamicDescriptor: z.boolean(),
46
+ allowSurcharge: z.boolean(),
47
+ });
48
+ /** @internal */
49
+ export type TransferControls$Outbound = {
50
+ accountID: string;
51
+ partnerAccountID: string;
52
+ debtRepayment: boolean;
53
+ allowDynamicDescriptor: boolean;
54
+ allowSurcharge: boolean;
55
+ };
56
+
57
+ /** @internal */
58
+ export const TransferControls$outboundSchema: z.ZodType<
59
+ TransferControls$Outbound,
60
+ z.ZodTypeDef,
61
+ TransferControls
62
+ > = z.object({
63
+ accountID: z.string(),
64
+ partnerAccountID: z.string(),
65
+ debtRepayment: z.boolean(),
66
+ allowDynamicDescriptor: z.boolean(),
67
+ allowSurcharge: z.boolean(),
68
+ });
69
+
70
+ export function transferControlsToJSON(
71
+ transferControls: TransferControls,
72
+ ): string {
73
+ return JSON.stringify(
74
+ TransferControls$outboundSchema.parse(transferControls),
75
+ );
76
+ }
77
+ export function transferControlsFromJSON(
78
+ jsonString: string,
79
+ ): SafeParseResult<TransferControls, SDKValidationError> {
80
+ return safeParse(
81
+ jsonString,
82
+ (x) => TransferControls$inboundSchema.parse(JSON.parse(x)),
83
+ `Failed to parse 'TransferControls' from JSON`,
84
+ );
85
+ }
@@ -33,14 +33,14 @@ export type UpdateInvoice = {
33
33
  invoiceDate?: Date | null | undefined;
34
34
  dueDate?: Date | null | undefined;
35
35
  /**
36
- * The status can be updated to one of the following values under specific conditions:
36
+ * The status can be updated to one of the following values under specific conditions:
37
37
  *
38
38
  * @remarks
39
- * - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`. Canceling an invoice
40
- * indicates the invoice is no longer expected to be paid (e.g., the charge was waived or terms changed).
41
- * Canceled invoices still appear in list results by default and remain part of the invoice history.
42
- * To completely discard an invoice created by mistake, use the delete endpoint instead.
43
- * - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
39
+ * - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`. Canceling an invoice
40
+ * indicates the invoice is no longer expected to be paid (e.g., the charge was waived or terms changed).
41
+ * Canceled invoices still appear in list results by default and remain part of the invoice history.
42
+ * To completely discard an invoice created by mistake, use the delete endpoint instead.
43
+ * - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
44
44
  */
45
45
  status?: InvoiceStatus | undefined;
46
46
  taxAmount?: AmountDecimalUpdate | undefined;
@@ -21,16 +21,17 @@ export type APICall =
21
21
 
22
22
  export class APIPromise<T> implements Promise<T> {
23
23
  readonly #promise: Promise<[T, APICall]>;
24
- readonly #unwrapped: Promise<T>;
24
+ #unwrapped: Promise<T> | null;
25
25
 
26
26
  readonly [Symbol.toStringTag] = "APIPromise";
27
27
 
28
28
  constructor(p: [T, APICall] | Promise<[T, APICall]>) {
29
29
  this.#promise = p instanceof Promise ? p : Promise.resolve(p);
30
- this.#unwrapped =
31
- p instanceof Promise
32
- ? this.#promise.then(([value]) => value)
33
- : Promise.resolve(p[0]);
30
+ this.#unwrapped = p instanceof Promise ? null : Promise.resolve(p[0]);
31
+ }
32
+
33
+ #getUnwrapped(): Promise<T> {
34
+ return (this.#unwrapped ??= this.#promise.then(([value]) => value));
34
35
  }
35
36
 
36
37
  then<TResult1 = T, TResult2 = never>(
@@ -55,11 +56,11 @@ export class APIPromise<T> implements Promise<T> {
55
56
  | null
56
57
  | undefined,
57
58
  ): Promise<T | TResult> {
58
- return this.#unwrapped.catch(onrejected);
59
+ return this.#getUnwrapped().catch(onrejected);
59
60
  }
60
61
 
61
62
  finally(onfinally?: (() => void) | null | undefined): Promise<T> {
62
- return this.#unwrapped.finally(onfinally);
63
+ return this.#getUnwrapped().finally(onfinally);
63
64
  }
64
65
 
65
66
  $inspect(): Promise<[T, APICall]> {
@@ -0,0 +1,86 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { HTTPClient, Moov } from "@moovio/sdk";
3
+
4
+ /**
5
+ * Builds a Moov SDK instance whose HTTPClient captures every outgoing
6
+ * Request without hitting the network. The captured Request can then be
7
+ * inspected for headers, URL, etc.
8
+ */
9
+ function captureRequests(opts: ConstructorParameters<typeof Moov>[0]) {
10
+ const requests: Request[] = [];
11
+ const httpClient = new HTTPClient({
12
+ fetcher: async (input, init) => {
13
+ const req = input instanceof Request ? input : new Request(input, init);
14
+ requests.push(req.clone());
15
+ return new Response(null, { status: 200 });
16
+ },
17
+ });
18
+
19
+ const moov = new Moov({ ...opts, httpClient });
20
+ return { moov, requests };
21
+ }
22
+
23
+ describe("accessToken option", () => {
24
+ test("sets Authorization: Bearer header on outgoing requests", async () => {
25
+ const { moov, requests } = captureRequests({
26
+ accessToken: "test-access-token-123",
27
+ });
28
+
29
+ await moov.ping.ping();
30
+
31
+ expect(requests.length).toBe(1);
32
+ expect(requests[0].headers.get("Authorization")).toBe(
33
+ "Bearer test-access-token-123",
34
+ );
35
+ });
36
+
37
+ test("applies bearer auth on every request, not just the first", async () => {
38
+ const { moov, requests } = captureRequests({
39
+ accessToken: "another-token",
40
+ });
41
+
42
+ await moov.ping.ping();
43
+ await moov.ping.ping();
44
+ await moov.ping.ping();
45
+
46
+ expect(requests.length).toBe(3);
47
+ for (const req of requests) {
48
+ expect(req.headers.get("Authorization")).toBe("Bearer another-token");
49
+ }
50
+ });
51
+
52
+ test("HTTP Basic auth still works when accessToken is not set", async () => {
53
+ const { moov, requests } = captureRequests({
54
+ security: { username: "my-public-key", password: "my-secret-key" },
55
+ });
56
+
57
+ await moov.ping.ping();
58
+
59
+ expect(requests.length).toBe(1);
60
+ const auth = requests[0].headers.get("Authorization");
61
+ expect(auth).toMatch(/^Basic /);
62
+
63
+ // Decode the base64 portion and confirm the credentials round-trip.
64
+ const encoded = auth!.slice("Basic ".length);
65
+ const decoded = Buffer.from(encoded, "base64").toString("utf8");
66
+ expect(decoded).toBe("my-public-key:my-secret-key");
67
+ });
68
+
69
+ test("no Authorization header is sent when neither auth mode is configured", async () => {
70
+ const { moov, requests } = captureRequests({});
71
+
72
+ await moov.ping.ping();
73
+
74
+ expect(requests.length).toBe(1);
75
+ expect(requests[0].headers.get("Authorization")).toBeNull();
76
+ });
77
+
78
+ test("throws at construction when both accessToken and Basic creds are set", () => {
79
+ expect(() =>
80
+ new Moov({
81
+ accessToken: "some-token",
82
+ security: { username: "u", password: "p" },
83
+ })
84
+ ).toThrow(/cannot both be set/i);
85
+ });
86
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../src/types/async.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GACf;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GACD;IACE,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEN,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;;IAI9C,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB;gBAEjC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAQnD,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EACjC,WAAW,CAAC,EACR,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAChD,IAAI,GACJ,SAAS,EACb,UAAU,CAAC,EACP,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GACnD,IAAI,GACJ,SAAS,GACZ,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAO/B,KAAK,CAAC,OAAO,GAAG,KAAK,EACnB,UAAU,CAAC,EACP,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GACjD,IAAI,GACJ,SAAS,GACZ,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;IAIvB,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhE,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;CAGlC"}
1
+ {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../src/types/async.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GACf;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GACD;IACE,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEN,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;;IAI9C,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB;gBAEjC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IASnD,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EACjC,WAAW,CAAC,EACR,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAChD,IAAI,GACJ,SAAS,EACb,UAAU,CAAC,EACP,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GACnD,IAAI,GACJ,SAAS,GACZ,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAO/B,KAAK,CAAC,OAAO,GAAG,KAAK,EACnB,UAAU,CAAC,EACP,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GACjD,IAAI,GACJ,SAAS,GACZ,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;IAIvB,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhE,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;CAGlC"}