@qontoctl/core 0.0.0 → 0.1.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.
Files changed (103) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +93 -0
  3. package/dist/api-types.d.ts +38 -0
  4. package/dist/api-types.d.ts.map +1 -0
  5. package/dist/api-types.js +4 -0
  6. package/dist/api-types.js.map +1 -0
  7. package/dist/auth/api-key.d.ts +16 -0
  8. package/dist/auth/api-key.d.ts.map +1 -0
  9. package/dist/auth/api-key.js +28 -0
  10. package/dist/auth/api-key.js.map +1 -0
  11. package/dist/auth/index.d.ts +2 -0
  12. package/dist/auth/index.d.ts.map +1 -0
  13. package/dist/auth/index.js +4 -0
  14. package/dist/auth/index.js.map +1 -0
  15. package/dist/config/env.d.ts +17 -0
  16. package/dist/config/env.d.ts.map +1 -0
  17. package/dist/config/env.js +52 -0
  18. package/dist/config/env.js.map +1 -0
  19. package/dist/config/index.d.ts +8 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +7 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/loader.d.ts +18 -0
  24. package/dist/config/loader.d.ts.map +1 -0
  25. package/dist/config/loader.js +49 -0
  26. package/dist/config/loader.js.map +1 -0
  27. package/dist/config/resolve.d.ts +19 -0
  28. package/dist/config/resolve.d.ts.map +1 -0
  29. package/dist/config/resolve.js +84 -0
  30. package/dist/config/resolve.js.map +1 -0
  31. package/dist/config/types.d.ts +38 -0
  32. package/dist/config/types.d.ts.map +1 -0
  33. package/dist/config/types.js +4 -0
  34. package/dist/config/types.js.map +1 -0
  35. package/dist/config/validate.d.ts +22 -0
  36. package/dist/config/validate.d.ts.map +1 -0
  37. package/dist/config/validate.js +99 -0
  38. package/dist/config/validate.js.map +1 -0
  39. package/dist/constants.d.ts +7 -0
  40. package/dist/constants.d.ts.map +1 -0
  41. package/dist/constants.js +9 -0
  42. package/dist/constants.js.map +1 -0
  43. package/dist/http-client.d.ts +100 -0
  44. package/dist/http-client.d.ts.map +1 -0
  45. package/dist/http-client.js +210 -0
  46. package/dist/http-client.js.map +1 -0
  47. package/dist/index.d.ts +12 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +7 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/services/bank-accounts.d.ts +18 -0
  52. package/dist/services/bank-accounts.d.ts.map +1 -0
  53. package/dist/services/bank-accounts.js +23 -0
  54. package/dist/services/bank-accounts.js.map +1 -0
  55. package/dist/services/index.d.ts +3 -0
  56. package/dist/services/index.d.ts.map +1 -0
  57. package/dist/services/index.js +5 -0
  58. package/dist/services/index.js.map +1 -0
  59. package/dist/services/organization.d.ts +10 -0
  60. package/dist/services/organization.d.ts.map +1 -0
  61. package/dist/services/organization.js +13 -0
  62. package/dist/services/organization.js.map +1 -0
  63. package/dist/statements/index.d.ts +2 -0
  64. package/dist/statements/index.d.ts.map +1 -0
  65. package/dist/statements/index.js +4 -0
  66. package/dist/statements/index.js.map +1 -0
  67. package/dist/statements/types.d.ts +19 -0
  68. package/dist/statements/types.d.ts.map +1 -0
  69. package/dist/statements/types.js +4 -0
  70. package/dist/statements/types.js.map +1 -0
  71. package/dist/testing/index.d.ts +2 -0
  72. package/dist/testing/index.d.ts.map +1 -0
  73. package/dist/testing/index.js +4 -0
  74. package/dist/testing/index.js.map +1 -0
  75. package/dist/testing/json-response.d.ts +6 -0
  76. package/dist/testing/json-response.d.ts.map +1 -0
  77. package/dist/testing/json-response.js +14 -0
  78. package/dist/testing/json-response.js.map +1 -0
  79. package/dist/transactions/index.d.ts +3 -0
  80. package/dist/transactions/index.d.ts.map +1 -0
  81. package/dist/transactions/index.js +4 -0
  82. package/dist/transactions/index.js.map +1 -0
  83. package/dist/transactions/service.d.ts +13 -0
  84. package/dist/transactions/service.d.ts.map +1 -0
  85. package/dist/transactions/service.js +65 -0
  86. package/dist/transactions/service.js.map +1 -0
  87. package/dist/transactions/types.d.ts +70 -0
  88. package/dist/transactions/types.d.ts.map +1 -0
  89. package/dist/transactions/types.js +4 -0
  90. package/dist/transactions/types.js.map +1 -0
  91. package/dist/types/index.d.ts +3 -0
  92. package/dist/types/index.d.ts.map +1 -0
  93. package/dist/types/index.js +4 -0
  94. package/dist/types/index.js.map +1 -0
  95. package/dist/types/label.d.ts +10 -0
  96. package/dist/types/label.d.ts.map +1 -0
  97. package/dist/types/label.js +4 -0
  98. package/dist/types/label.js.map +1 -0
  99. package/dist/types/membership.d.ts +17 -0
  100. package/dist/types/membership.d.ts.map +1 -0
  101. package/dist/types/membership.js +4 -0
  102. package/dist/types/membership.js.map +1 -0
  103. package/package.json +32 -11
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @qontoctl/core
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@qontoctl/core?logo=npm)](https://www.npmjs.com/package/@qontoctl/core)
4
+
5
+ Core library for [Qonto](https://qonto.com) API integration — HTTP client, authentication, configuration, and typed service functions.
6
+
7
+ Part of the [QontoCtl](https://github.com/alexey-pelykh/qontoctl) project.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ npm install @qontoctl/core
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { resolveConfig, buildApiKeyAuthorization, HttpClient, getOrganization } from "@qontoctl/core";
19
+
20
+ // Resolve configuration from file or environment
21
+ const { config, endpoint } = await resolveConfig();
22
+
23
+ // Build authorization headers
24
+ const authorization = buildApiKeyAuthorization(config.apiKey);
25
+
26
+ // Create an HTTP client
27
+ const client = new HttpClient({ baseUrl: endpoint, authorization });
28
+
29
+ // Fetch organization details
30
+ const org = await getOrganization(client);
31
+ ```
32
+
33
+ ## API
34
+
35
+ ### Configuration
36
+
37
+ - **`resolveConfig(options?): Promise<ConfigResult>`** — resolve credentials from config files and environment variables. Returns `{ config, endpoint, warnings }`.
38
+ - **`loadConfigFile(path)`** — load a YAML configuration file
39
+ - **`validateConfig(config)`** — validate configuration structure
40
+ - **`applyEnvOverlay(config, prefix?)`** — overlay environment variable overrides
41
+ - **`ConfigError`** — error thrown on configuration validation failures or missing credentials
42
+
43
+ ### Authentication
44
+
45
+ - **`buildApiKeyAuthorization(credentials)`** — build authorization headers from API key credentials
46
+ - **`AuthError`** — error thrown when API key credentials are missing or invalid
47
+
48
+ ### HTTP Client
49
+
50
+ - **`HttpClient`** — HTTP client for the Qonto API with rate-limit handling
51
+ - **`QontoApiError`** — typed error for Qonto API error responses
52
+ - **`QontoRateLimitError`** — error for rate-limit (429) responses
53
+
54
+ ### Constants
55
+
56
+ - **`API_BASE_URL`** — production API base URL (`https://thirdparty.qonto.com`)
57
+ - **`SANDBOX_BASE_URL`** — sandbox API base URL (`https://thirdparty-sandbox.staging.qonto.co`)
58
+
59
+ ### Services
60
+
61
+ - **`getOrganization(client)`** — fetch organization details
62
+ - **`getBankAccount(client, id)`** — fetch a bank account by ID
63
+ - **`getTransaction(client, id)`** — fetch a transaction by ID
64
+ - **`buildTransactionQueryParams(params)`** — build query parameters for transaction listing
65
+
66
+ ### Types
67
+
68
+ - `Organization`, `BankAccount`, `Transaction`, `TransactionLabel`
69
+ - `Label`, `Membership`, `Statement`, `StatementFile`
70
+ - `QontoctlConfig`, `ApiKeyCredentials`, `ListTransactionsParams`
71
+ - `ConfigResult`, `ResolveOptions`, `LoadResult`, `ValidationResult`
72
+ - `HttpClientOptions`, `HttpClientLogger`, `QueryParams`, `QueryParamValue`, `QontoApiErrorEntry`
73
+
74
+ ## Configuration Resolution
75
+
76
+ QontoCtl resolves credentials in this order:
77
+
78
+ 1. `QONTOCTL_*` environment variables (highest priority)
79
+ 2. `.qontoctl.yaml` in the current directory
80
+ 3. `~/.qontoctl.yaml` (home default)
81
+
82
+ With `--profile <name>`:
83
+
84
+ 1. `QONTOCTL_<NAME>_*` environment variables
85
+ 2. `~/.qontoctl/<name>.yaml`
86
+
87
+ ## Requirements
88
+
89
+ - Node.js >= 24
90
+
91
+ ## License
92
+
93
+ [AGPL-3.0-only](https://github.com/alexey-pelykh/qontoctl/blob/main/LICENSE) — For commercial licensing, contact the maintainer.
@@ -0,0 +1,38 @@
1
+ /**
2
+ * A bank account as returned by the Qonto API.
3
+ */
4
+ export interface BankAccount {
5
+ readonly id: string;
6
+ readonly name: string;
7
+ readonly status: string;
8
+ readonly main: boolean;
9
+ readonly organization_id: string;
10
+ readonly iban: string;
11
+ readonly bic: string;
12
+ readonly currency: string;
13
+ readonly balance: number;
14
+ readonly balance_cents: number;
15
+ readonly authorized_balance: number;
16
+ readonly authorized_balance_cents: number;
17
+ readonly slug: string;
18
+ }
19
+ /**
20
+ * Organization details as returned by `GET /v2/organization`.
21
+ */
22
+ export interface Organization {
23
+ readonly slug: string;
24
+ readonly legal_name: string;
25
+ readonly bank_accounts: readonly BankAccount[];
26
+ }
27
+ /**
28
+ * Pagination metadata returned by the Qonto API.
29
+ */
30
+ export interface PaginationMeta {
31
+ readonly current_page: number;
32
+ readonly next_page: number | null;
33
+ readonly prev_page: number | null;
34
+ readonly total_pages: number;
35
+ readonly total_count: number;
36
+ readonly per_page: number;
37
+ }
38
+ //# sourceMappingURL=api-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-types.d.ts","sourceRoot":"","sources":["../src/api-types.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ export {};
4
+ //# sourceMappingURL=api-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-types.js","sourceRoot":"","sources":["../src/api-types.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC"}
@@ -0,0 +1,16 @@
1
+ import type { ApiKeyCredentials } from "../config/types.js";
2
+ /**
3
+ * Error thrown when API key authentication fails due to missing or invalid credentials.
4
+ */
5
+ export declare class AuthError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ /**
9
+ * Builds the Authorization header value from API key credentials.
10
+ *
11
+ * The Qonto API uses a simple `{slug}:{key}` format (no Base64 encoding).
12
+ *
13
+ * @throws {AuthError} when credentials are missing or incomplete
14
+ */
15
+ export declare function buildApiKeyAuthorization(credentials: ApiKeyCredentials): string;
16
+ //# sourceMappingURL=api-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key.d.ts","sourceRoot":"","sources":["../../src/auth/api-key.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;GAEG;AACH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,iBAAiB,GAAG,MAAM,CAU/E"}
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * Error thrown when API key authentication fails due to missing or invalid credentials.
5
+ */
6
+ export class AuthError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "AuthError";
10
+ }
11
+ }
12
+ /**
13
+ * Builds the Authorization header value from API key credentials.
14
+ *
15
+ * The Qonto API uses a simple `{slug}:{key}` format (no Base64 encoding).
16
+ *
17
+ * @throws {AuthError} when credentials are missing or incomplete
18
+ */
19
+ export function buildApiKeyAuthorization(credentials) {
20
+ if (credentials.organizationSlug === "") {
21
+ throw new AuthError("Missing organization slug in API key credentials");
22
+ }
23
+ if (credentials.secretKey === "") {
24
+ throw new AuthError("Missing secret key in API key credentials");
25
+ }
26
+ return `${credentials.organizationSlug}:${credentials.secretKey}`;
27
+ }
28
+ //# sourceMappingURL=api-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key.js","sourceRoot":"","sources":["../../src/auth/api-key.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAIpC;;GAEG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAA8B;IACrE,IAAI,WAAW,CAAC,gBAAgB,KAAK,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,SAAS,CAAC,kDAAkD,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,WAAW,CAAC,SAAS,KAAK,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,GAAG,WAAW,CAAC,gBAAgB,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;AACpE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { AuthError, buildApiKeyAuthorization } from "./api-key.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ export { AuthError, buildApiKeyAuthorization } from "./api-key.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { QontoctlConfig } from "./types.js";
2
+ /**
3
+ * Overlays environment variables onto a config.
4
+ *
5
+ * - Without profile: reads `QONTOCTL_ORGANIZATION_SLUG`, `QONTOCTL_SECRET_KEY`,
6
+ * `QONTOCTL_ENDPOINT`, and `QONTOCTL_SANDBOX`
7
+ * - With profile: reads `QONTOCTL_{PROFILE}_ORGANIZATION_SLUG`,
8
+ * `QONTOCTL_{PROFILE}_SECRET_KEY`, `QONTOCTL_{PROFILE}_ENDPOINT`, and
9
+ * `QONTOCTL_{PROFILE}_SANDBOX` (profile name uppercased, hyphens→underscores)
10
+ *
11
+ * Env vars take precedence over file values.
12
+ */
13
+ export declare function applyEnvOverlay(config: QontoctlConfig, options?: {
14
+ profile?: string | undefined;
15
+ env?: Record<string, string | undefined> | undefined;
16
+ }): QontoctlConfig;
17
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACtD,GACA,cAAc,CA+BhB"}
@@ -0,0 +1,52 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ const ENV_PREFIX = "QONTOCTL";
4
+ const ORG_SLUG_SUFFIX = "ORGANIZATION_SLUG";
5
+ const SECRET_KEY_SUFFIX = "SECRET_KEY";
6
+ const ENDPOINT_SUFFIX = "ENDPOINT";
7
+ const SANDBOX_SUFFIX = "SANDBOX";
8
+ /**
9
+ * Overlays environment variables onto a config.
10
+ *
11
+ * - Without profile: reads `QONTOCTL_ORGANIZATION_SLUG`, `QONTOCTL_SECRET_KEY`,
12
+ * `QONTOCTL_ENDPOINT`, and `QONTOCTL_SANDBOX`
13
+ * - With profile: reads `QONTOCTL_{PROFILE}_ORGANIZATION_SLUG`,
14
+ * `QONTOCTL_{PROFILE}_SECRET_KEY`, `QONTOCTL_{PROFILE}_ENDPOINT`, and
15
+ * `QONTOCTL_{PROFILE}_SANDBOX` (profile name uppercased, hyphens→underscores)
16
+ *
17
+ * Env vars take precedence over file values.
18
+ */
19
+ export function applyEnvOverlay(config, options) {
20
+ const env = options?.env ?? process.env;
21
+ const prefix = buildPrefix(options?.profile);
22
+ const orgSlug = env[`${prefix}_${ORG_SLUG_SUFFIX}`];
23
+ const secretKey = env[`${prefix}_${SECRET_KEY_SUFFIX}`];
24
+ const endpoint = env[`${prefix}_${ENDPOINT_SUFFIX}`];
25
+ const sandbox = env[`${prefix}_${SANDBOX_SUFFIX}`];
26
+ let result = config;
27
+ if (orgSlug !== undefined || secretKey !== undefined) {
28
+ const existing = result.apiKey;
29
+ result = {
30
+ ...result,
31
+ apiKey: {
32
+ organizationSlug: orgSlug ?? existing?.organizationSlug ?? "",
33
+ secretKey: secretKey ?? existing?.secretKey ?? "",
34
+ },
35
+ };
36
+ }
37
+ if (endpoint !== undefined) {
38
+ result = { ...result, endpoint };
39
+ }
40
+ if (sandbox !== undefined) {
41
+ result = { ...result, sandbox: sandbox === "1" || sandbox === "true" };
42
+ }
43
+ return result;
44
+ }
45
+ function buildPrefix(profile) {
46
+ if (profile === undefined) {
47
+ return ENV_PREFIX;
48
+ }
49
+ const normalized = profile.toUpperCase().replaceAll("-", "_");
50
+ return `${ENV_PREFIX}_${normalized}`;
51
+ }
52
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAIpC,MAAM,UAAU,GAAG,UAAU,CAAC;AAC9B,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAC5C,MAAM,iBAAiB,GAAG,YAAY,CAAC;AACvC,MAAM,eAAe,GAAG,UAAU,CAAC;AACnC,MAAM,cAAc,GAAG,SAAS,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAsB,EACtB,OAGC;IAED,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAK,OAAO,CAAC,GAA0C,CAAC;IAChF,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,eAAe,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,iBAAiB,EAAE,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,eAAe,EAAE,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC,CAAC;IAEnD,IAAI,MAAM,GAAG,MAAM,CAAC;IAEpB,IAAI,OAAO,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/B,MAAM,GAAG;YACP,GAAG,MAAM;YACT,MAAM,EAAE;gBACN,gBAAgB,EAAE,OAAO,IAAI,QAAQ,EAAE,gBAAgB,IAAI,EAAE;gBAC7D,SAAS,EAAE,SAAS,IAAI,QAAQ,EAAE,SAAS,IAAI,EAAE;aAClD;SACF,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACzE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,OAA2B;IAC9C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO,GAAG,UAAU,IAAI,UAAU,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type { ApiKeyCredentials, QontoctlConfig, ConfigResult, ResolveOptions } from "./types.js";
2
+ export { resolveConfig, ConfigError } from "./resolve.js";
3
+ export { loadConfigFile } from "./loader.js";
4
+ export type { LoadResult } from "./loader.js";
5
+ export { isValidProfileName, validateConfig } from "./validate.js";
6
+ export type { ValidationResult } from "./validate.js";
7
+ export { applyEnvOverlay } from "./env.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ export { resolveConfig, ConfigError } from "./resolve.js";
4
+ export { loadConfigFile } from "./loader.js";
5
+ export { isValidProfileName, validateConfig } from "./validate.js";
6
+ export { applyEnvOverlay } from "./env.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface LoadResult {
2
+ /** Parsed YAML content, or `undefined` if no file was found. */
3
+ raw: unknown;
4
+ /** Path of the file that was loaded, or `undefined` if none found. */
5
+ path: string | undefined;
6
+ }
7
+ /**
8
+ * Resolves and loads the appropriate config file.
9
+ *
10
+ * - With `profile`: loads `~/.qontoctl/{profile}.yaml`
11
+ * - Without `profile`: tries CWD `.qontoctl.yaml`, then `~/.qontoctl.yaml`
12
+ */
13
+ export declare function loadConfigFile(options?: {
14
+ profile?: string | undefined;
15
+ cwd?: string | undefined;
16
+ home?: string | undefined;
17
+ }): Promise<LoadResult>;
18
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,GAAG,EAAE,OAAO,CAAC;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE;IAC7C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBtB"}
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { readFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { homedir } from "node:os";
6
+ import { parse as parseYaml } from "yaml";
7
+ import { CONFIG_DIR } from "../constants.js";
8
+ const CONFIG_FILENAME = ".qontoctl.yaml";
9
+ /**
10
+ * Resolves and loads the appropriate config file.
11
+ *
12
+ * - With `profile`: loads `~/.qontoctl/{profile}.yaml`
13
+ * - Without `profile`: tries CWD `.qontoctl.yaml`, then `~/.qontoctl.yaml`
14
+ */
15
+ export async function loadConfigFile(options) {
16
+ const home = options?.home ?? homedir();
17
+ const profile = options?.profile;
18
+ if (profile !== undefined) {
19
+ const path = join(home, CONFIG_DIR, `${profile}.yaml`);
20
+ return loadFromPath(path);
21
+ }
22
+ const cwd = options?.cwd ?? process.cwd();
23
+ // Try CWD first
24
+ const cwdPath = join(cwd, CONFIG_FILENAME);
25
+ const cwdResult = await loadFromPath(cwdPath);
26
+ if (cwdResult.raw !== undefined) {
27
+ return cwdResult;
28
+ }
29
+ // Fall back to home directory
30
+ const homePath = join(home, CONFIG_FILENAME);
31
+ return loadFromPath(homePath);
32
+ }
33
+ async function loadFromPath(path) {
34
+ try {
35
+ const content = await readFile(path, "utf-8");
36
+ const raw = parseYaml(content);
37
+ return { raw, path };
38
+ }
39
+ catch (error) {
40
+ if (isNodeError(error) && error.code === "ENOENT") {
41
+ return { raw: undefined, path: undefined };
42
+ }
43
+ throw new Error(`Failed to read config file "${path}": ${String(error)}`);
44
+ }
45
+ }
46
+ function isNodeError(error) {
47
+ return error instanceof Error && "code" in error;
48
+ }
49
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AASzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAIpC;IACC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;IAEjC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC;QACvD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1C,gBAAgB;IAChB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,SAAS,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC7C,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAY,SAAS,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AACnD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ConfigResult, ResolveOptions } from "./types.js";
2
+ export declare class ConfigError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ /**
6
+ * Resolves the full configuration by:
7
+ * 1. Loading the appropriate YAML config file (profile-aware)
8
+ * 2. Validating the schema (producing warnings for unknown keys)
9
+ * 3. Overlaying environment variables
10
+ * 4. Verifying that credentials are present
11
+ * 5. Resolving the API endpoint
12
+ *
13
+ * Endpoint precedence:
14
+ * QONTOCTL_ENDPOINT > QONTOCTL_SANDBOX > profile endpoint > profile sandbox > default
15
+ *
16
+ * @throws {ConfigError} on validation errors or missing credentials
17
+ */
18
+ export declare function resolveConfig(options?: ResolveOptions): Promise<ConfigResult>;
19
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM/D,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CA0CnF"}
@@ -0,0 +1,84 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { loadConfigFile } from "./loader.js";
4
+ import { validateConfig } from "./validate.js";
5
+ import { applyEnvOverlay } from "./env.js";
6
+ import { API_BASE_URL, SANDBOX_BASE_URL } from "../constants.js";
7
+ export class ConfigError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ConfigError";
11
+ }
12
+ }
13
+ /**
14
+ * Resolves the full configuration by:
15
+ * 1. Loading the appropriate YAML config file (profile-aware)
16
+ * 2. Validating the schema (producing warnings for unknown keys)
17
+ * 3. Overlaying environment variables
18
+ * 4. Verifying that credentials are present
19
+ * 5. Resolving the API endpoint
20
+ *
21
+ * Endpoint precedence:
22
+ * QONTOCTL_ENDPOINT > QONTOCTL_SANDBOX > profile endpoint > profile sandbox > default
23
+ *
24
+ * @throws {ConfigError} on validation errors or missing credentials
25
+ */
26
+ export async function resolveConfig(options) {
27
+ const profile = options?.profile;
28
+ // 1. Load config file
29
+ const { raw, path } = await loadConfigFile({
30
+ profile,
31
+ cwd: options?.cwd,
32
+ home: options?.home,
33
+ });
34
+ // 2. Validate
35
+ const { config: fileConfig, warnings, errors } = validateConfig(raw);
36
+ if (errors.length > 0) {
37
+ const location = path !== undefined ? ` (${path})` : "";
38
+ throw new ConfigError(`Invalid configuration${location}:\n - ${errors.join("\n - ")}`);
39
+ }
40
+ // 3. Overlay env vars
41
+ const config = applyEnvOverlay(fileConfig, {
42
+ profile,
43
+ env: options?.env,
44
+ });
45
+ // 4. Verify credentials are present
46
+ if (config.apiKey === undefined) {
47
+ const searchedLocations = describeSearchLocations(profile, path);
48
+ throw new ConfigError(`No credentials found. ${searchedLocations}`);
49
+ }
50
+ if (config.apiKey.organizationSlug === "") {
51
+ throw new ConfigError('Missing required field "organization-slug" in api-key credentials');
52
+ }
53
+ if (config.apiKey.secretKey === "") {
54
+ throw new ConfigError('Missing required field "secret-key" in api-key credentials');
55
+ }
56
+ // 5. Resolve endpoint
57
+ const endpoint = resolveEndpoint(config);
58
+ return { config, endpoint, warnings };
59
+ }
60
+ /**
61
+ * Resolves the API endpoint from config.
62
+ *
63
+ * Precedence (env overlay already applied, so env vars win over file values):
64
+ * explicit endpoint > sandbox flag > default (production)
65
+ */
66
+ function resolveEndpoint(config) {
67
+ if (config.endpoint !== undefined) {
68
+ return config.endpoint;
69
+ }
70
+ if (config.sandbox === true) {
71
+ return SANDBOX_BASE_URL;
72
+ }
73
+ return API_BASE_URL;
74
+ }
75
+ function describeSearchLocations(profile, loadedPath) {
76
+ if (profile !== undefined) {
77
+ return `Checked ~/.qontoctl/${profile}.yaml and QONTOCTL_${profile.toUpperCase().replaceAll("-", "_")}_* env vars.`;
78
+ }
79
+ if (loadedPath !== undefined) {
80
+ return `Found config at ${loadedPath} but it contains no api-key credentials. Also checked QONTOCTL_* env vars.`;
81
+ }
82
+ return "Checked .qontoctl.yaml (CWD), ~/.qontoctl.yaml (home), and QONTOCTL_* env vars.";
83
+ }
84
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * API key credentials for authenticating with the Qonto API.
3
+ */
4
+ export interface ApiKeyCredentials {
5
+ organizationSlug: string;
6
+ secretKey: string;
7
+ }
8
+ /**
9
+ * Parsed configuration from a `.qontoctl.yaml` file.
10
+ */
11
+ export interface QontoctlConfig {
12
+ apiKey?: ApiKeyCredentials;
13
+ endpoint?: string;
14
+ sandbox?: boolean;
15
+ }
16
+ /**
17
+ * Result of resolving configuration, including any warnings encountered.
18
+ */
19
+ export interface ConfigResult {
20
+ config: QontoctlConfig;
21
+ /** Resolved API endpoint URL. */
22
+ endpoint: string;
23
+ warnings: string[];
24
+ }
25
+ /**
26
+ * Options for resolving configuration.
27
+ */
28
+ export interface ResolveOptions {
29
+ /** Named profile to load from `~/.qontoctl/{profile}.yaml`. */
30
+ profile?: string | undefined;
31
+ /** Override CWD for file resolution (useful for testing). */
32
+ cwd?: string | undefined;
33
+ /** Override home directory for file resolution (useful for testing). */
34
+ home?: string | undefined;
35
+ /** Override environment variables (useful for testing). */
36
+ env?: Record<string, string | undefined> | undefined;
37
+ }
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACtD"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC"}
@@ -0,0 +1,22 @@
1
+ import type { QontoctlConfig } from "./types.js";
2
+ /**
3
+ * Check whether a profile name is safe to use as a filename.
4
+ *
5
+ * Rejects names containing path separators (`/`, `\`) or parent-directory
6
+ * references (`..`) to prevent path-traversal attacks.
7
+ */
8
+ export declare function isValidProfileName(name: string): boolean;
9
+ export interface ValidationResult {
10
+ config: QontoctlConfig;
11
+ warnings: string[];
12
+ errors: string[];
13
+ }
14
+ /**
15
+ * Validates a parsed YAML document against the expected config schema.
16
+ *
17
+ * - Known keys with wrong types produce errors.
18
+ * - Unknown keys produce warnings (forward compatibility).
19
+ * - Returns a partially-populated config for valid fields.
20
+ */
21
+ export declare function validateConfig(raw: unknown): ValidationResult;
22
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/config/validate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAKD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAsF7D"}