@goenvless/sdk has a single entrypoint. Everything below is a named export from @goenvless/sdk.
Client
| Export | Signature |
|---|---|
init | (options?: ClientOptions) => Envless |
envless | Envless, a live handle on whatever init installed |
getClient | () => Envless |
resetClient | () => void |
createClient | (options?: ClientOptions) => Envless |
Envless | new (options: TransportOptions) => Envless, also the default export |
init and createClient read ENVLESS_TOKEN and ENVLESS_API_ENDPOINT when process exists. new Envless() reads no environment. See Create a client.
import { envless, init } from '@goenvless/sdk'
init({ token: process.env.ENVLESS_TOKEN })
await envless.products.list()Crypto
| Export | Signature |
|---|---|
encryptValue | (plaintext: string, passphrase: string, workspaceId: string) => Promise<string> |
decryptValue | (ciphertext: string, passphrase: string, workspaceId: string) => Promise<string> |
encryptWithKey | (key: CryptoKey, plaintext: string) => Promise<string> |
decryptWithKey | (key: CryptoKey, ciphertext: string) => Promise<string> |
deriveWorkspaceKey | (passphrase: string, workspaceId: string) => Promise<CryptoKey> |
importWorkspaceKey | (base64url: string) => Promise<CryptoKey> |
isCiphertext | (value: unknown) => boolean |
passphraseStrength | (passphrase: string) => PassphraseValidation |
ENCRYPTION_PARAMETERS | The exact cryptographic constants |
See Encryption for the recipe and for why you should derive the key once when writing a batch.
Helpers
| Export | Signature |
|---|---|
rotateWorkspacePassphrase | (props: RotatePassphraseProps) => Promise<RotatePassphraseResult> |
verifyWebhookSignature | <T>(props: VerifyWebhookProps) => Promise<WebhookEvent<T>> |
rotateWorkspacePassphrase re-encrypts live variables and version history for one environment, which is the part that is easy to forget. verifyWebhookSignature is the receiver side of Webhooks.
Errors
| Export | Notes |
|---|---|
EnvlessApiError | The API answered with a failure. Carries status, code, resource, field, requestId, retryAfterSeconds. |
EnvlessNetworkError | Nothing came back: connection failure, timeout, abort. |
See Errors.
Constants
Enum-like values, so you never hard-code a string the API might reject.
| Export | Contents |
|---|---|
SCOPE_RESOURCES | workspace, products, product-access, projects, environments, variables, versions, members, roles, keys, webhooks |
SCOPE_LEVELS | none, read, write |
VARIABLE_TYPE | string, number, boolean |
VARIABLE_VISIBILITY_LEVELS | server, client |
WEBHOOK_SIGNATURE_HEADERS | webhook-id, webhook-timestamp, webhook-signature, Envless-Event, Envless-Delivery |
PAGE_LIMITS | MAX_LIMIT: 100, DEFAULT_LIMIT: 25 |
import { SCOPE_LEVELS, SCOPE_RESOURCES, VARIABLE_VISIBILITY_LEVELS } from '@goenvless/sdk'
await envless.keys.create({
name: 'ci',
scopes: {
[SCOPE_RESOURCES.VARIABLES]: SCOPE_LEVELS.READ,
[SCOPE_RESOURCES.VERSIONS]: SCOPE_LEVELS.READ
}
})
await envless.variables.create('web', 'production', {
name: 'NEXT_PUBLIC_API_URL',
value: ciphertext,
visibility: VARIABLE_VISIBILITY_LEVELS.CLIENT
})Types
Every request body, option bag and response is an exported type. Import them with import type.
Client and transport
ClientOptions, TransportOptions, RequestOptions, RequestScope, ProductScope, ListOptions, DeliveryListOptions, Page, PaginationEnvelope, ApiEnvelope
Resources
IdentityResource, UserSummary, RoleSummary, WorkspaceResource, CurrentWorkspaceResource, UpdatedWorkspaceResource, DeletedWorkspaceResource, CustomDomainResource, CustomDomainRecord, RemovedDomainResource, ProductResource, DeletedProductResource, ProductAccessEntry, ProductAccessPage, GrantedProductAccessResource, RevokedProductAccessResource, ProjectResource, DeletedProjectResource, EnvironmentResource, EnvironmentSummaryResource, DeletedEnvironmentResource, VariableResource, DeletedVariableResource, DeletedVariablesResource, CreatedVariablesResource, VariableHistoryEvent, VersionResource, VersionDetailResource, VersionEntryResource, RolledBackVersionResource, ReencryptedEntriesResource, MemberResource, DeletedMemberResource, LeftWorkspaceResource, InviteResource, RevokedInviteResource, RoleResource, DeletedRoleResource, PermissionResource, PermissionsResource, KeyResource, CreatedKeyResource, DeletedKeyResource, WebhookResource, CreatedWebhookResource, DeletedWebhookResource, RotatedSecretResource, WebhookDeliveryResource, WebhookDeliveryDetailResource, RedeliveredWebhookResource, EventTypesResource
Inputs
WorkspaceCreate, WorkspacePatch, DomainVerifyOptions, ProductCreate, ProductPatch, ProjectCreate, ProjectPatch, EnvironmentCreate, EnvironmentPatch, VariableInput, VariablePatch, VersionCreate, MemberInvite, MemberPatch, RoleCreate, RolePatch, KeyCreate, KeyPatch, WebhookCreate, WebhookPatch, ApplyChanges, ApplyBaselineEntry, ApplyUpdateEntry, ApplyResult, ReencryptEntryInput
Crypto and webhooks
EncryptionParameters, PassphraseValidation, RotatePassphraseProps, RotatePassphraseResult, RotatePassphraseIssue, VerifyWebhookProps, WebhookSignatureHeaders, WebhookEvent
Read shapes are not always the write shapes. workspace.get resolves CurrentWorkspaceResource, with createdAt but no virtualEnvsEnabled, while workspace.update resolves UpdatedWorkspaceResource, with virtualEnvsEnabled but no createdAt. The method pages call these out individually.
A worked example
import {
encryptValue,
envless,
init,
SCOPE_LEVELS,
SCOPE_RESOURCES
} from '@goenvless/sdk'
init({ token: process.env.ENVLESS_TOKEN })
const { workspaceId } = await envless.me.get()
const product = await envless.products.create({ name: 'Internal tools', slug: 'internal-tools' })
const project = await envless.projects.create({ name: 'API', slug: 'api', product: product.slug })
for (const name of ['development', 'staging', 'production']) {
await envless.environments.create(project.slug, { name, slug: name }, { product: product.slug })
}
await envless.variables.createMany('api', 'production', [
{ name: 'DATABASE_URL', value: await encryptValue(databaseUrl, passphrase, workspaceId) },
{ name: 'PORT', value: await encryptValue('3000', passphrase, workspaceId), type: 'number' }
], { product: product.slug })
await envless.versions.create('api', 'production', { note: 'Initial provisioning' }, { product: product.slug })
const key = await envless.keys.create({
name: 'api-runner',
scopes: { [SCOPE_RESOURCES.VARIABLES]: SCOPE_LEVELS.READ },
projectIds: [project.id]
})
console.log(key.secret)