Move from openapi-generator-cli to custom Axios approach, and add listFolders endpoint
This commit is contained in:
197
src/index.ts
197
src/index.ts
@@ -1,141 +1,106 @@
|
||||
import { Configuration, DefaultApi as InfisicalApi } from "./infisicalapi_client";
|
||||
import { DefaultApiApiV1DynamicSecretsLeasesPostRequest } from "./infisicalapi_client";
|
||||
import { ApiClient } from "./api/base";
|
||||
import { AuthApi } from "./api/endpoints/auth";
|
||||
import { SecretsApi } from "./api/endpoints/secrets";
|
||||
import { DynamicSecretsApi } from "./api/endpoints/dynamic-secrets";
|
||||
import { EnvironmentsApi } from "./api/endpoints/environments";
|
||||
import { ProjectsApi } from "./api/endpoints/projects";
|
||||
import { FoldersApi } from "./api/endpoints/folders";
|
||||
|
||||
import SecretsClient from "./custom/secrets";
|
||||
import AuthClient from "./custom/auth";
|
||||
import axios, { AxiosError, AxiosInstance, RawAxiosRequestConfig } from "axios";
|
||||
import DynamicSecretsClient from "./custom/dynamic-secrets";
|
||||
|
||||
import * as ApiClient from "./infisicalapi_client";
|
||||
import EnvironmentsClient from "./custom/environments";
|
||||
import ProjectsClient from "./custom/projects";
|
||||
import FoldersClient from "./custom/folders";
|
||||
|
||||
declare module "axios" {
|
||||
interface AxiosRequestConfig {
|
||||
_retryCount?: number;
|
||||
}
|
||||
}
|
||||
import * as ApiTypes from "./api/types";
|
||||
|
||||
const buildRestClient = (apiClient: InfisicalApi, requestOptions?: RawAxiosRequestConfig) => {
|
||||
return {
|
||||
// Add more as we go
|
||||
apiV1DynamicSecretsLeasesPost: (options: DefaultApiApiV1DynamicSecretsLeasesPostRequest) =>
|
||||
apiClient.apiV1DynamicSecretsLeasesPost(options, requestOptions)
|
||||
};
|
||||
};
|
||||
|
||||
const setupAxiosRetry = () => {
|
||||
const axiosInstance = axios.create();
|
||||
const maxRetries = 4;
|
||||
|
||||
const initialRetryDelay = 1000;
|
||||
const backoffFactor = 2;
|
||||
|
||||
axiosInstance.interceptors.response.use(null, (error: AxiosError) => {
|
||||
const config = error?.config;
|
||||
|
||||
if (!config) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
if (!config._retryCount) config._retryCount = 0;
|
||||
|
||||
// handle rate limits and network errors
|
||||
if ((error.response?.status === 429 || error.response?.status === undefined) && config && config._retryCount! < maxRetries) {
|
||||
config._retryCount!++;
|
||||
const baseDelay = initialRetryDelay * Math.pow(backoffFactor, config._retryCount! - 1);
|
||||
const jitter = baseDelay * 0.2; // 20% +/- jitter
|
||||
const exponentialDelay = baseDelay + (Math.random() * 2 - 1) * jitter;
|
||||
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(axiosInstance(config));
|
||||
}, exponentialDelay);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
return axiosInstance;
|
||||
};
|
||||
|
||||
// We need to do bind(this) because the authenticate method is a private method, and usually you can't call private methods from outside the class.
|
||||
type InfisicalSDKOptions = {
|
||||
siteUrl?: string;
|
||||
siteUrl?: string;
|
||||
};
|
||||
|
||||
class InfisicalSDK {
|
||||
#apiInstance: InfisicalApi;
|
||||
private apiClient: ApiClient;
|
||||
|
||||
#requestOptions: RawAxiosRequestConfig | undefined;
|
||||
#secretsClient: SecretsClient;
|
||||
#dynamicSecretsClient: DynamicSecretsClient;
|
||||
#environmentsClient: EnvironmentsClient;
|
||||
#projectsClient: ProjectsClient;
|
||||
#foldersClient: FoldersClient;
|
||||
#authClient: AuthClient;
|
||||
#basePath: string;
|
||||
axiosInstance: AxiosInstance;
|
||||
// API instances
|
||||
private authApi: AuthApi;
|
||||
private secretsApi: SecretsApi;
|
||||
private dynamicSecretsApi: DynamicSecretsApi;
|
||||
private environmentsApi: EnvironmentsApi;
|
||||
private projectsApi: ProjectsApi;
|
||||
private foldersApi: FoldersApi;
|
||||
|
||||
constructor(options?: InfisicalSDKOptions) {
|
||||
this.#basePath = options?.siteUrl || "https://app.infisical.com";
|
||||
this.axiosInstance = setupAxiosRetry();
|
||||
// Domain clients
|
||||
private authClient: AuthClient;
|
||||
private secretsClient: SecretsClient;
|
||||
private dynamicSecretsClient: DynamicSecretsClient;
|
||||
private environmentsClient: EnvironmentsClient;
|
||||
private projectsClient: ProjectsClient;
|
||||
private foldersClient: FoldersClient;
|
||||
|
||||
this.#apiInstance = new InfisicalApi(
|
||||
new Configuration({
|
||||
basePath: this.#basePath
|
||||
}),
|
||||
undefined,
|
||||
this.axiosInstance
|
||||
);
|
||||
constructor(options?: InfisicalSDKOptions) {
|
||||
const baseURL = options?.siteUrl || "https://app.infisical.com";
|
||||
|
||||
this.#authClient = new AuthClient(this.authenticate.bind(this), this.#apiInstance);
|
||||
this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#secretsClient = new SecretsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#environmentsClient = new EnvironmentsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#projectsClient = new ProjectsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#foldersClient = new FoldersClient(this.#apiInstance, this.#requestOptions);
|
||||
this.rest = () => buildRestClient(this.#apiInstance, this.#requestOptions);
|
||||
}
|
||||
// Initialize the base API client
|
||||
this.apiClient = new ApiClient({ baseURL });
|
||||
|
||||
private authenticate(accessToken: string) {
|
||||
this.#apiInstance = new InfisicalApi(
|
||||
new Configuration({
|
||||
basePath: this.#basePath,
|
||||
accessToken
|
||||
}),
|
||||
undefined,
|
||||
this.axiosInstance
|
||||
);
|
||||
// Initialize API service instances
|
||||
this.authApi = new AuthApi(this.apiClient);
|
||||
this.secretsApi = new SecretsApi(this.apiClient);
|
||||
this.dynamicSecretsApi = new DynamicSecretsApi(this.apiClient);
|
||||
this.environmentsApi = new EnvironmentsApi(this.apiClient);
|
||||
this.projectsApi = new ProjectsApi(this.apiClient);
|
||||
this.foldersApi = new FoldersApi(this.apiClient);
|
||||
|
||||
this.#requestOptions = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`
|
||||
}
|
||||
};
|
||||
// Initialize domain clients
|
||||
this.authClient = new AuthClient(
|
||||
this.authenticate.bind(this),
|
||||
this.authApi
|
||||
);
|
||||
this.secretsClient = new SecretsClient(this.secretsApi);
|
||||
this.dynamicSecretsClient = new DynamicSecretsClient(
|
||||
this.dynamicSecretsApi
|
||||
);
|
||||
this.environmentsClient = new EnvironmentsClient(this.environmentsApi);
|
||||
this.projectsClient = new ProjectsClient(this.projectsApi);
|
||||
this.foldersClient = new FoldersClient(this.foldersApi);
|
||||
}
|
||||
|
||||
this.rest = () => buildRestClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#secretsClient = new SecretsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#authClient = new AuthClient(this.authenticate.bind(this), this.#apiInstance, accessToken);
|
||||
this.#environmentsClient = new EnvironmentsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#projectsClient = new ProjectsClient(this.#apiInstance, this.#requestOptions);
|
||||
this.#foldersClient = new FoldersClient(this.#apiInstance, this.#requestOptions);
|
||||
private authenticate(accessToken: string) {
|
||||
// Set the token on the API client
|
||||
this.apiClient.setAccessToken(accessToken);
|
||||
|
||||
return this;
|
||||
}
|
||||
// Reinitialize the auth client with the token
|
||||
this.authClient = new AuthClient(
|
||||
this.authenticate.bind(this),
|
||||
this.authApi,
|
||||
accessToken
|
||||
);
|
||||
|
||||
secrets = () => this.#secretsClient;
|
||||
environments = () => this.#environmentsClient;
|
||||
projects = () => this.#projectsClient;
|
||||
folders = () => this.#foldersClient;
|
||||
dynamicSecrets = () => this.#dynamicSecretsClient;
|
||||
auth = () => this.#authClient;
|
||||
rest = () => buildRestClient(this.#apiInstance, this.#requestOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Public methods to access domain clients
|
||||
secrets = () => this.secretsClient;
|
||||
environments = () => this.environmentsClient;
|
||||
projects = () => this.projectsClient;
|
||||
folders = () => this.foldersClient;
|
||||
dynamicSecrets = () => this.dynamicSecretsClient;
|
||||
auth = () => this.authClient;
|
||||
}
|
||||
|
||||
export { InfisicalSDK, ApiClient };
|
||||
export { TDynamicSecretProvider, DynamicSecretProviders } from "./custom/schemas";
|
||||
// Export main SDK class
|
||||
export { InfisicalSDK, ApiTypes };
|
||||
|
||||
// Export types and enums from schemas
|
||||
export {
|
||||
TDynamicSecretProvider,
|
||||
DynamicSecretProviders,
|
||||
} from "./custom/schemas";
|
||||
|
||||
// Export domain-specific types
|
||||
export type * from "./custom/secrets";
|
||||
export type * from "./custom/dynamic-secrets";
|
||||
export type * from "./custom/environments";
|
||||
export type * from "./custom/projects";
|
||||
export type * from "./custom/folders";
|
||||
|
||||
Reference in New Issue
Block a user