infrahub-sdk 0.0.6 → 0.0.8

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 (41) hide show
  1. package/.github/workflows/publish.yml +13 -9
  2. package/README.md +83 -0
  3. package/dist/index.d.ts +36 -0
  4. package/dist/index.js +83 -14
  5. package/dist/index.test.js +125 -2
  6. package/examples/expired-certificate-example.ts +36 -0
  7. package/package.json +5 -3
  8. package/src/index.test.ts +143 -2
  9. package/src/index.ts +134 -17
  10. package/dist/cjs/index.js +0 -65
  11. package/dist/cjs/index.js.map +0 -7
  12. package/dist/client.d.ts +0 -6
  13. package/dist/client.js +0 -35
  14. package/dist/constants.d.ts +0 -0
  15. package/dist/constants.js +0 -1
  16. package/dist/esm/index.js +0 -32
  17. package/dist/esm/index.js.map +0 -7
  18. package/dist/types/client.d.ts +0 -7
  19. package/dist/types/client.d.ts.map +0 -1
  20. package/dist/types/constants.d.ts +0 -1
  21. package/dist/types/constants.d.ts.map +0 -1
  22. package/dist/types/index.d.ts +0 -2
  23. package/dist/types/index.d.ts.map +0 -1
  24. package/dist/types/utils/auth.d.ts +0 -1
  25. package/dist/types/utils/auth.d.ts.map +0 -1
  26. package/dist/types/utils/error-handling.d.ts +0 -1
  27. package/dist/types/utils/error-handling.d.ts.map +0 -1
  28. package/dist/types/utils/index.d.ts +0 -1
  29. package/dist/types/utils/index.d.ts.map +0 -1
  30. package/dist/types/utils/validation.d.ts +0 -1
  31. package/dist/types/utils/validation.d.ts.map +0 -1
  32. package/dist/utils/auth.d.ts +0 -0
  33. package/dist/utils/auth.js +0 -1
  34. package/dist/utils/error-handling.d.ts +0 -0
  35. package/dist/utils/error-handling.js +0 -1
  36. package/dist/utils/index.d.ts +0 -0
  37. package/dist/utils/index.js +0 -1
  38. package/dist/utils/validation.d.ts +0 -0
  39. package/dist/utils/validation.js +0 -1
  40. package/test/package-lock.json +0 -1044
  41. package/test/package.json +0 -14
package/src/index.ts CHANGED
@@ -4,9 +4,11 @@ export type SafeResult<T> =
4
4
  | { data: undefined; error: Error };
5
5
 
6
6
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
7
+ import https from 'https';
8
+ import fetch from 'node-fetch';
7
9
 
8
- import createClient, { Middleware } from 'openapi-fetch';
9
- import { GraphQLClient, Variables } from 'graphql-request';
10
+ import createClient from 'openapi-fetch';
11
+ import { GraphQLClient, Variables, gql } from 'graphql-request';
10
12
  import type { paths } from './types';
11
13
  import { InfrahubBranchManager } from './branch';
12
14
  import {
@@ -21,10 +23,47 @@ export * from 'graphql-request';
21
23
 
22
24
  export * from './types';
23
25
 
26
+ export interface TLSConfig {
27
+ /**
28
+ * If true, the server certificate is verified against the list of supplied CAs.
29
+ * Set to false to disable certificate verification (not recommended for production).
30
+ *
31
+ * Note: Setting this to false will bypass all certificate validation, including
32
+ * expired certificates, self-signed certificates, and hostname mismatches.
33
+ */
34
+ rejectUnauthorized?: boolean;
35
+ /**
36
+ * Optional CA certificates to trust. Can be a string or Buffer containing the certificate(s).
37
+ * Use this when connecting to servers with custom or self-signed certificates.
38
+ */
39
+ ca?: string | Buffer | Array<string | Buffer>;
40
+ /**
41
+ * Optional client certificate for mutual TLS authentication.
42
+ */
43
+ cert?: string | Buffer;
44
+ /**
45
+ * Optional client private key for mutual TLS authentication.
46
+ */
47
+ key?: string | Buffer;
48
+ }
49
+
24
50
  export interface InfrahubClientOptions {
25
51
  address: string;
26
52
  token?: string;
27
53
  branch?: string;
54
+ /**
55
+ * TLS/SSL configuration options for HTTPS connections.
56
+ * Use this to handle custom certificates, expired certificates, or disable certificate verification.
57
+ *
58
+ * @example
59
+ * // Disable certificate verification (development only)
60
+ * { tls: { rejectUnauthorized: false } }
61
+ *
62
+ * @example
63
+ * // Use custom CA certificate
64
+ * { tls: { ca: fs.readFileSync('/path/to/ca.pem') } }
65
+ */
66
+ tls?: TLSConfig;
28
67
  }
29
68
 
30
69
  const DEFAULT_BRANCH_NAME = 'main';
@@ -43,29 +82,63 @@ export class InfrahubClient {
43
82
  this.defaultBranch = options.branch || DEFAULT_BRANCH_NAME;
44
83
  this.branch = new InfrahubBranchManager(this);
45
84
 
46
- // Initialize the openapi-fetch client
85
+ // Create custom fetch with TLS options if provided
86
+ let customFetch: typeof fetch = fetch;
87
+ if (options.tls) {
88
+ // Build agent options, ensuring rejectUnauthorized is explicitly set if provided
89
+ const agentOptions: https.AgentOptions = {};
90
+
91
+ if (options.tls.rejectUnauthorized !== undefined) {
92
+ agentOptions.rejectUnauthorized = options.tls.rejectUnauthorized;
93
+ }
94
+ if (options.tls.ca !== undefined) {
95
+ agentOptions.ca = options.tls.ca;
96
+ }
97
+ if (options.tls.cert !== undefined) {
98
+ agentOptions.cert = options.tls.cert;
99
+ }
100
+ if (options.tls.key !== undefined) {
101
+ agentOptions.key = options.tls.key;
102
+ }
103
+
104
+ const httpsAgent = new https.Agent(agentOptions);
105
+
106
+ customFetch = ((
107
+ url: Parameters<typeof fetch>[0],
108
+ opts: Parameters<typeof fetch>[1] = {}
109
+ ) => {
110
+ // Ensure agent is passed for HTTPS URLs
111
+ // node-fetch v2 requires the agent to be explicitly set
112
+ const fetchOptions = { ...opts, agent: httpsAgent };
113
+ return fetch(url, fetchOptions);
114
+ }) as typeof fetch;
115
+ }
47
116
 
117
+ // Initialize the openapi-fetch client with TLS configuration
48
118
  this.rest = createClient<paths>({
49
- baseUrl: this.baseUrl
119
+ baseUrl: this.baseUrl,
120
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
121
+ fetch: customFetch as any
50
122
  });
51
123
 
52
- const token = this.token;
53
- const myMiddleware: Middleware = {
54
- async onRequest({ request }) {
55
- // set "X-INFRAHUB-KEY" header if token is present
56
- if (token) {
57
- request.headers.set('X-INFRAHUB-KEY', token);
124
+ // Use middleware to dynamically add the auth token to every REST request.
125
+ this.rest.use({
126
+ onRequest: (req) => {
127
+ req.headers.set('content-type', 'application/json');
128
+ if (this.token) {
129
+ req.headers.set('X-INFRAHUB-KEY', this.token);
58
130
  }
59
- request.headers.set('content-type', 'application/json');
60
- return request;
61
- },
62
- };
63
-
64
- this.rest.use(myMiddleware);
131
+ return req;
132
+ }
133
+ });
65
134
 
66
135
  // Initialize the GraphQL client with the default branch endpoint
67
136
  this.graphqlClient = new GraphQLClient(
68
- this._graphqlUrl(this.defaultBranch)
137
+ this._graphqlUrl(this.defaultBranch),
138
+ {
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ fetch: customFetch as any
141
+ }
69
142
  );
70
143
  this.graphqlClient.setHeaders({
71
144
  'Content-Type': 'application/json'
@@ -148,6 +221,50 @@ export class InfrahubClient {
148
221
  });
149
222
  return await (this.graphqlClient.request as any)(query, variables);
150
223
  } catch (error) {
224
+ // Check if this is a certificate error and provide helpful guidance
225
+ if (error instanceof Error) {
226
+ const errorMessage = error.message.toLowerCase();
227
+ const isCertError =
228
+ errorMessage.includes('certificate') ||
229
+ errorMessage.includes('cert') ||
230
+ errorMessage.includes('ssl') ||
231
+ errorMessage.includes('tls');
232
+ const isExpired = errorMessage.includes('expired');
233
+ const isSelfSigned = errorMessage.includes('self-signed') || errorMessage.includes('self signed');
234
+ const isUnauthorized = errorMessage.includes('unauthorized');
235
+
236
+ if (isCertError && (isExpired || isSelfSigned || isUnauthorized)) {
237
+ const helpMessage = [
238
+ '',
239
+ 'Certificate validation failed. To resolve this issue, you can configure TLS options:',
240
+ '',
241
+ '1. Disable certificate verification (for development/testing only):',
242
+ ' const client = new InfrahubClient({',
243
+ ' address: "your-address",',
244
+ ' token: "your-token",',
245
+ ' tls: { rejectUnauthorized: false }',
246
+ ' });',
247
+ '',
248
+ '2. Or provide a custom CA certificate (requires: import fs from "fs"):',
249
+ ' const client = new InfrahubClient({',
250
+ ' address: "your-address",',
251
+ ' token: "your-token",',
252
+ ' tls: { ca: fs.readFileSync("/path/to/ca-cert.pem") }',
253
+ ' });',
254
+ '',
255
+ 'See the README.md for more TLS configuration options.',
256
+ ''
257
+ ].join('\n');
258
+
259
+ console.error(helpMessage);
260
+
261
+ // Create a new error with helpful message appended
262
+ const enhancedError = new Error(`${error.message}\n${helpMessage}`);
263
+ enhancedError.stack = error.stack;
264
+ throw enhancedError;
265
+ }
266
+ }
267
+
151
268
  console.error('Error executing GraphQL query:', error);
152
269
  throw error;
153
270
  }
package/dist/cjs/index.js DELETED
@@ -1,65 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- InfrahubClient: () => InfrahubClient
34
- });
35
- module.exports = __toCommonJS(index_exports);
36
-
37
- // src/client.ts
38
- var import_axios = __toESM(require("axios"), 1);
39
- var InfrahubClient = class {
40
- constructor(baseURL, token) {
41
- this.axiosInstance = import_axios.default.create({
42
- baseURL,
43
- headers: {
44
- "Content-Type": "application/json"
45
- }
46
- });
47
- if (token) {
48
- this.setAuthToken(token);
49
- }
50
- }
51
- setAuthToken(token) {
52
- this.axiosInstance.defaults.headers.common["X-INFRAHUB-KEY"] = token;
53
- }
54
- // get info from /api/info endpoint
55
- async getInfo() {
56
- try {
57
- const response = await this.axiosInstance.get("/api/info");
58
- return response.data;
59
- } catch (error) {
60
- console.error("Error fetching info:", error);
61
- throw error;
62
- }
63
- }
64
- };
65
- //# sourceMappingURL=index.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/index.ts", "../../src/client.ts"],
4
- "sourcesContent": ["export * from './client';", "import axios, { AxiosInstance } from 'axios';\n\nexport class InfrahubClient {\n private axiosInstance: AxiosInstance;\n\n constructor(baseURL: string, token?: string) {\n this.axiosInstance = axios.create({\n baseURL,\n headers: {\n 'Content-Type': 'application/json',\n }\n });\n if (token) {\n this.setAuthToken(token);\n }\n\n }\n\n public setAuthToken(token: string) {\n this.axiosInstance.defaults.headers.common[\"X-INFRAHUB-KEY\"] = token;\n }\n\n // get info from /api/info endpoint\n public async getInfo() {\n try {\n const response = await this.axiosInstance.get('/api/info');\n return response.data;\n } catch (error) {\n console.error('Error fetching info:', error);\n throw error;\n }\n }\n}"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAqC;AAE9B,IAAM,iBAAN,MAAqB;AAAA,EAGxB,YAAY,SAAiB,OAAgB;AACzC,SAAK,gBAAgB,aAAAA,QAAM,OAAO;AAAA,MAC9B;AAAA,MACA,SAAS;AAAA,QACL,gBAAgB;AAAA,MACpB;AAAA,IACJ,CAAC;AACD,QAAI,OAAO;AACP,WAAK,aAAa,KAAK;AAAA,IAC3B;AAAA,EAEJ;AAAA,EAEO,aAAa,OAAe;AAC/B,SAAK,cAAc,SAAS,QAAQ,OAAO,gBAAgB,IAAI;AAAA,EACnE;AAAA;AAAA,EAGA,MAAa,UAAU;AACnB,QAAI;AACA,YAAM,WAAW,MAAM,KAAK,cAAc,IAAI,WAAW;AACzD,aAAO,SAAS;AAAA,IACpB,SAAS,OAAO;AACZ,cAAQ,MAAM,wBAAwB,KAAK;AAC3C,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;",
6
- "names": ["axios"]
7
- }
package/dist/client.d.ts DELETED
@@ -1,6 +0,0 @@
1
- export declare class InfrahubClient {
2
- private axiosInstance;
3
- constructor(baseURL: string, token?: string);
4
- setAuthToken(token: string): void;
5
- getInfo(): Promise<any>;
6
- }
package/dist/client.js DELETED
@@ -1,35 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InfrahubClient = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- class InfrahubClient {
9
- constructor(baseURL, token) {
10
- this.axiosInstance = axios_1.default.create({
11
- baseURL,
12
- headers: {
13
- 'Content-Type': 'application/json',
14
- }
15
- });
16
- if (token) {
17
- this.setAuthToken(token);
18
- }
19
- }
20
- setAuthToken(token) {
21
- this.axiosInstance.defaults.headers.common["X-INFRAHUB-KEY"] = token;
22
- }
23
- // get info from /api/info endpoint
24
- async getInfo() {
25
- try {
26
- const response = await this.axiosInstance.get('/api/info');
27
- return response.data;
28
- }
29
- catch (error) {
30
- console.error('Error fetching info:', error);
31
- throw error;
32
- }
33
- }
34
- }
35
- exports.InfrahubClient = InfrahubClient;
File without changes
package/dist/constants.js DELETED
@@ -1 +0,0 @@
1
- "use strict";
package/dist/esm/index.js DELETED
@@ -1,32 +0,0 @@
1
- // src/client.ts
2
- import axios from "axios";
3
- var InfrahubClient = class {
4
- constructor(baseURL, token) {
5
- this.axiosInstance = axios.create({
6
- baseURL,
7
- headers: {
8
- "Content-Type": "application/json"
9
- }
10
- });
11
- if (token) {
12
- this.setAuthToken(token);
13
- }
14
- }
15
- setAuthToken(token) {
16
- this.axiosInstance.defaults.headers.common["X-INFRAHUB-KEY"] = token;
17
- }
18
- // get info from /api/info endpoint
19
- async getInfo() {
20
- try {
21
- const response = await this.axiosInstance.get("/api/info");
22
- return response.data;
23
- } catch (error) {
24
- console.error("Error fetching info:", error);
25
- throw error;
26
- }
27
- }
28
- };
29
- export {
30
- InfrahubClient
31
- };
32
- //# sourceMappingURL=index.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/client.ts"],
4
- "sourcesContent": ["import axios, { AxiosInstance } from 'axios';\n\nexport class InfrahubClient {\n private axiosInstance: AxiosInstance;\n\n constructor(baseURL: string, token?: string) {\n this.axiosInstance = axios.create({\n baseURL,\n headers: {\n 'Content-Type': 'application/json',\n }\n });\n if (token) {\n this.setAuthToken(token);\n }\n\n }\n\n public setAuthToken(token: string) {\n this.axiosInstance.defaults.headers.common[\"X-INFRAHUB-KEY\"] = token;\n }\n\n // get info from /api/info endpoint\n public async getInfo() {\n try {\n const response = await this.axiosInstance.get('/api/info');\n return response.data;\n } catch (error) {\n console.error('Error fetching info:', error);\n throw error;\n }\n }\n}"],
5
- "mappings": ";AAAA,OAAO,WAA8B;AAE9B,IAAM,iBAAN,MAAqB;AAAA,EAGxB,YAAY,SAAiB,OAAgB;AACzC,SAAK,gBAAgB,MAAM,OAAO;AAAA,MAC9B;AAAA,MACA,SAAS;AAAA,QACL,gBAAgB;AAAA,MACpB;AAAA,IACJ,CAAC;AACD,QAAI,OAAO;AACP,WAAK,aAAa,KAAK;AAAA,IAC3B;AAAA,EAEJ;AAAA,EAEO,aAAa,OAAe;AAC/B,SAAK,cAAc,SAAS,QAAQ,OAAO,gBAAgB,IAAI;AAAA,EACnE;AAAA;AAAA,EAGA,MAAa,UAAU;AACnB,QAAI;AACA,YAAM,WAAW,MAAM,KAAK,cAAc,IAAI,WAAW;AACzD,aAAO,SAAS;AAAA,IACpB,SAAS,OAAO;AACZ,cAAQ,MAAM,wBAAwB,KAAK;AAC3C,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- export declare class InfrahubClient {
2
- private axiosInstance;
3
- constructor(baseURL: string, token?: string);
4
- setAuthToken(token: string): void;
5
- getInfo(): Promise<any>;
6
- }
7
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAEA,qBAAa,cAAc;IACvB,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAapC,YAAY,CAAC,KAAK,EAAE,MAAM;IAKpB,OAAO;CASvB"}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export * from './client';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=auth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/utils/auth.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=error-handling.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../../src/utils/error-handling.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/utils/validation.ts"],"names":[],"mappings":""}
File without changes
@@ -1 +0,0 @@
1
- "use strict";
File without changes
@@ -1 +0,0 @@
1
- "use strict";
File without changes
@@ -1 +0,0 @@
1
- "use strict";
File without changes
@@ -1 +0,0 @@
1
- "use strict";