feat: create folders, environments, and projects

This commit is contained in:
Daniel Hougaard
2025-04-12 01:27:43 +04:00
parent a6e5a03593
commit e7e96c1ae9
6 changed files with 200 additions and 45 deletions

View File

@@ -432,3 +432,72 @@ const renewedLease = await client.dynamicSecrets().leases.renew(newLease.lease.i
**Returns:** **Returns:**
- `ApiV1DynamicSecretsLeasesLeaseIdDelete200Response`: The renewed lease response _(doesn't contain new credentials)_. - `ApiV1DynamicSecretsLeasesLeaseIdDelete200Response`: The renewed lease response _(doesn't contain new credentials)_.
### `projects`
#### Create a new project
```typescript
const project = await client.projects().create({
projectName: "<name-of-project>",
type: "secret-manager", // cert-manager, secret-manager, kms, ssh
projectDescription: "<project-description>", // Optional
slug: "<slug-of-project-to-create>", // Optional
template: "<project-template-name>", // Optional
kmsKeyId: "kms-key-id" // Optional
});
```
**Parameters:**
- `projectName` (string): The name of the project to create.
- `type` (string): The type of project to create. Valid options are `secret-manager`, `cert-manager`, `kms`, `ssh`
- `projectDescription` (string): An optional description of the project to create.
- `slug` (string): An optional slug for the project to create. If not provided, one will be generated automatically.
- `template` (string): Optionally provide a project template name to use for creating this project.
- `kmsKeyId` (string): The ID of the KMS key to use for the project. Will use the Infisical KMS by default.
**Returns:**
- `ApiV1WorkspaceWorkspaceIdGet200ResponseWorkspace`: The project that was created.
### `environments`
#### Create a new environment
```typescript
const environment = await client.environments().create({
name: "Demo Environment",
projectId: "<your-project-id>",
slug: "demo-environment",
position: 1 // Optional
});
```
**Parameters:**
- `name` (string): The name of the environment to be created.
- `projectId` (string): The ID of the project to create the environment within.
- `slug`: (string): The slug of the environment to be created.
- `position` (number): An optional position of the environment to be created. The position is used in the Infisical UI to display environments in order. Environments with the lowest position come first.
**Returns:**
- `ApiV1WorkspaceWorkspaceIdEnvironmentsEnvIdGet200ResponseEnvironment`: The environment that was created.
#### Create a new folder
```typescript
const folder = await client.folders().create({
name: "<folder-name>",
path: "<folder-path>",
projectId: "<your-project-id>",
environment: "<environment-slug>",
description: "<folder-description>" // Optional
});
```
**Parameters:**
- `name` (string): The name of the folder to create.
- `path` (string): The path where of where to create the folder. Defaults to `/`, which is the root folder.
- `projectId` (string): The ID of the project to create the folder within.
- `environment` (string): The slug of the environment to create the folder within.
- `description` (string): An optional folder description.
**Returns:**
- `ApiV1FoldersPost200ResponseFolder`: The folder that was created.

View File

@@ -0,0 +1,33 @@
import { RawAxiosRequestConfig } from "axios";
import { DefaultApi as InfisicalApi } from "../infisicalapi_client";
import type { ApiV1WorkspaceWorkspaceIdEnvironmentsPostRequest, ApiV1WorkspaceWorkspaceIdEnvironmentsPost200Response } from "../infisicalapi_client";
import { newInfisicalError } from "./errors";
export type CreateEnvironmentOptions = {
projectId: string;
} & ApiV1WorkspaceWorkspaceIdEnvironmentsPostRequest;
export type CreateEnvironmentResult = ApiV1WorkspaceWorkspaceIdEnvironmentsPost200Response;
export default class EnvironmentsClient {
#apiInstance: InfisicalApi;
#requestOptions: RawAxiosRequestConfig | undefined;
constructor(apiInstance: InfisicalApi, requestOptions: RawAxiosRequestConfig | undefined) {
this.#apiInstance = apiInstance;
this.#requestOptions = requestOptions;
}
create = async (options: CreateEnvironmentOptions): Promise<CreateEnvironmentResult["environment"]> => {
try {
const res = await this.#apiInstance.apiV1WorkspaceWorkspaceIdEnvironmentsPost(
{
workspaceId: options.projectId,
apiV1WorkspaceWorkspaceIdEnvironmentsPostRequest: options
},
this.#requestOptions
);
return res.data.environment;
} catch (err) {
throw newInfisicalError(err);
}
};
}

35
src/custom/folders.ts Normal file
View File

@@ -0,0 +1,35 @@
import { RawAxiosRequestConfig } from "axios";
import { DefaultApi as InfisicalApi } from "../infisicalapi_client";
import type { ApiV1FoldersPostRequest, ApiV1FoldersPost200Response } from "../infisicalapi_client";
import { newInfisicalError } from "./errors";
export type CreateFolderOptions = {
projectId: string;
} & Omit<ApiV1FoldersPostRequest, "workspaceId" | "directory">;
export type CreateFolderResult = ApiV1FoldersPost200Response;
export default class FoldersClient {
#apiInstance: InfisicalApi;
#requestOptions: RawAxiosRequestConfig | undefined;
constructor(apiInstance: InfisicalApi, requestOptions: RawAxiosRequestConfig | undefined) {
this.#apiInstance = apiInstance;
this.#requestOptions = requestOptions;
}
create = async (options: CreateFolderOptions): Promise<CreateFolderResult["folder"]> => {
try {
const res = await this.#apiInstance.apiV1FoldersPost(
{
apiV1FoldersPostRequest: {
...options,
workspaceId: options.projectId
}
},
this.#requestOptions
);
return res.data.folder;
} catch (err) {
throw newInfisicalError(err);
}
};
}

30
src/custom/projects.ts Normal file
View File

@@ -0,0 +1,30 @@
import { RawAxiosRequestConfig } from "axios";
import { DefaultApi as InfisicalApi } from "../infisicalapi_client";
import type { ApiV2WorkspacePost200Response, ApiV2WorkspacePostRequest } from "../infisicalapi_client";
import { newInfisicalError } from "./errors";
export type CreateProjectOptions = ApiV2WorkspacePostRequest;
export type CreateProjectResult = ApiV2WorkspacePost200Response;
export default class ProjectsClient {
#apiInstance: InfisicalApi;
#requestOptions: RawAxiosRequestConfig | undefined;
constructor(apiInstance: InfisicalApi, requestOptions: RawAxiosRequestConfig | undefined) {
this.#apiInstance = apiInstance;
this.#requestOptions = requestOptions;
}
create = async (options: CreateProjectOptions): Promise<CreateProjectResult["project"]> => {
try {
const res = await this.#apiInstance.apiV2WorkspacePost(
{
apiV2WorkspacePostRequest: options
},
this.#requestOptions
);
return res.data.project;
} catch (err) {
throw newInfisicalError(err);
}
};
}

View File

@@ -6,6 +6,9 @@ import { RawAxiosRequestConfig } from "axios";
import DynamicSecretsClient from "./custom/dynamic-secrets"; import DynamicSecretsClient from "./custom/dynamic-secrets";
import * as ApiClient from "./infisicalapi_client"; import * as ApiClient from "./infisicalapi_client";
import EnvironmentsClient from "./custom/environments";
import ProjectsClient from "./custom/projects";
import FoldersClient from "./custom/folders";
const buildRestClient = (apiClient: InfisicalApi, requestOptions?: RawAxiosRequestConfig) => { const buildRestClient = (apiClient: InfisicalApi, requestOptions?: RawAxiosRequestConfig) => {
return { return {
@@ -26,6 +29,9 @@ class InfisicalSDK {
#requestOptions: RawAxiosRequestConfig | undefined; #requestOptions: RawAxiosRequestConfig | undefined;
#secretsClient: SecretsClient; #secretsClient: SecretsClient;
#dynamicSecretsClient: DynamicSecretsClient; #dynamicSecretsClient: DynamicSecretsClient;
#environmentsClient: EnvironmentsClient;
#projectsClient: ProjectsClient;
#foldersClient: FoldersClient;
#authClient: AuthClient; #authClient: AuthClient;
#basePath: string; #basePath: string;
@@ -41,6 +47,9 @@ class InfisicalSDK {
this.#authClient = new AuthClient(this.authenticate.bind(this), this.#apiInstance); this.#authClient = new AuthClient(this.authenticate.bind(this), this.#apiInstance);
this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions); this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions);
this.#secretsClient = new SecretsClient(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); this.rest = () => buildRestClient(this.#apiInstance, this.#requestOptions);
} }
@@ -62,11 +71,17 @@ class InfisicalSDK {
this.#secretsClient = new SecretsClient(this.#apiInstance, this.#requestOptions); this.#secretsClient = new SecretsClient(this.#apiInstance, this.#requestOptions);
this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions); this.#dynamicSecretsClient = new DynamicSecretsClient(this.#apiInstance, this.#requestOptions);
this.#authClient = new AuthClient(this.authenticate.bind(this), this.#apiInstance, accessToken); 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);
return this; return this;
} }
secrets = () => this.#secretsClient; secrets = () => this.#secretsClient;
environments = () => this.#environmentsClient;
projects = () => this.#projectsClient;
folders = () => this.#foldersClient;
dynamicSecrets = () => this.#dynamicSecretsClient; dynamicSecrets = () => this.#dynamicSecretsClient;
auth = () => this.#authClient; auth = () => this.#authClient;
rest = () => buildRestClient(this.#apiInstance, this.#requestOptions); rest = () => buildRestClient(this.#apiInstance, this.#requestOptions);

View File

@@ -12,54 +12,27 @@ const PROJECT_ID = "PROJECT_ID";
clientSecret: "CLIENT_SECRET" clientSecret: "CLIENT_SECRET"
}); });
const allSecrets = await client.secrets().listSecrets({ const environment = await client.environments().create({
environment: "dev", name: "Demo Environment",
projectId: PROJECT_ID, projectId: "<your-project-id>",
expandSecretReferences: true, slug: "demo-environment",
includeImports: false, position: 1 // Optional
recursive: false
}); });
console.log(allSecrets.secrets);
const singleSecret = await client.secrets().getSecret({ const project = await client.projects().create({
environment: "dev", projectName: "<name-of-project>",
projectId: PROJECT_ID, type: "secret-manager", // cert-manager, secret-manager, kms, ssh
secretName: "TEST1", projectDescription: "<project-description>", // Optional
expandSecretReferences: true, // Optional slug: "<slug-of-project-to-create>", // Optional
includeImports: true, // Optional template: "<project-template-name>", // Optional
kmsKeyId: "kms-key-id" // Optional
type: "shared", // Optional
version: 1 // Optional
}); });
console.log(`Fetched single secret, ${singleSecret}=${singleSecret.secretValue}`);
const newSecret = await client.secrets().createSecret("NEW_SECRET_NAME22423423", { const folder = await client.folders().create({
environment: "dev", name: "<folder-name>",
projectId: PROJECT_ID, path: "<folder-path>",
secretValue: "SECRET_VALUE" projectId: "<your-project-id>",
environment: "<environment-slug>",
description: "<folder-description>" // Optional
}); });
console.log(`You created a new secret: ${newSecret.secret.secretKey}`);
const updatedSecret = await client.secrets().updateSecret("NEW_SECRET_NAME22423423", {
environment: "dev",
projectId: PROJECT_ID,
secretValue: "UPDATED_SECRET_VALUE",
newSecretName: "NEW_SECRET_NAME22222", // Optional
secretComment: "This is an updated secret", // Optional
secretReminderNote: "This is an updated reminder note", // Optional
secretReminderRepeatDays: 14, // Optional
skipMultilineEncoding: false, // Optional
metadata: {
// Optional
extra: "metadata"
}
});
console.log(`You updated the secret: ${updatedSecret.secret.secretKey}`);
const deletedSecret = await client.secrets().deleteSecret("NEW_SECRET_NAME22222", {
environment: "dev",
projectId: PROJECT_ID
});
console.log(`You deleted the secret: ${deletedSecret.secret.secretKey}`);
})(); })();