@envshed/node 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.
- package/README.md +1055 -0
- package/dist/index.cjs +423 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +375 -0
- package/dist/index.d.ts +375 -0
- package/dist/index.js +394 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
EnvshedClient: () => EnvshedClient,
|
|
24
|
+
EnvshedError: () => EnvshedError,
|
|
25
|
+
EnvshedNetworkError: () => EnvshedNetworkError
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/errors.ts
|
|
30
|
+
var EnvshedError = class extends Error {
|
|
31
|
+
/** HTTP status code from the API */
|
|
32
|
+
status;
|
|
33
|
+
/** Error message from the API response body */
|
|
34
|
+
apiMessage;
|
|
35
|
+
/** HTTP method of the failed request */
|
|
36
|
+
method;
|
|
37
|
+
/** URL path of the failed request */
|
|
38
|
+
path;
|
|
39
|
+
constructor(options) {
|
|
40
|
+
super(`Envshed API error (${options.status}): ${options.apiMessage}`);
|
|
41
|
+
this.name = "EnvshedError";
|
|
42
|
+
this.status = options.status;
|
|
43
|
+
this.apiMessage = options.apiMessage;
|
|
44
|
+
this.method = options.method;
|
|
45
|
+
this.path = options.path;
|
|
46
|
+
}
|
|
47
|
+
/** Whether this is an authentication error (401) */
|
|
48
|
+
get isUnauthorized() {
|
|
49
|
+
return this.status === 401;
|
|
50
|
+
}
|
|
51
|
+
/** Whether this is a permissions error (403) */
|
|
52
|
+
get isForbidden() {
|
|
53
|
+
return this.status === 403;
|
|
54
|
+
}
|
|
55
|
+
/** Whether this is a not found error (404) */
|
|
56
|
+
get isNotFound() {
|
|
57
|
+
return this.status === 404;
|
|
58
|
+
}
|
|
59
|
+
/** Whether this is a subscription-related error (402) */
|
|
60
|
+
get isSubscriptionRequired() {
|
|
61
|
+
return this.status === 402;
|
|
62
|
+
}
|
|
63
|
+
/** Whether this error is retryable (5xx server errors) */
|
|
64
|
+
get isRetryable() {
|
|
65
|
+
return this.status >= 500;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var EnvshedNetworkError = class extends Error {
|
|
69
|
+
method;
|
|
70
|
+
path;
|
|
71
|
+
cause;
|
|
72
|
+
constructor(options) {
|
|
73
|
+
super(`Envshed network error: ${options.cause.message}`);
|
|
74
|
+
this.name = "EnvshedNetworkError";
|
|
75
|
+
this.method = options.method;
|
|
76
|
+
this.path = options.path;
|
|
77
|
+
this.cause = options.cause;
|
|
78
|
+
}
|
|
79
|
+
get isRetryable() {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// src/client.ts
|
|
85
|
+
var DEFAULT_API_URL = "https://app.envshed.com";
|
|
86
|
+
function defaultShouldRetry(error) {
|
|
87
|
+
if (error instanceof EnvshedError) return error.isRetryable;
|
|
88
|
+
if (error instanceof EnvshedNetworkError) return true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
function exponentialBackoff(attempt, initialDelayMs) {
|
|
92
|
+
return initialDelayMs * Math.pow(2, attempt - 1);
|
|
93
|
+
}
|
|
94
|
+
function linearBackoff(_attempt, initialDelayMs) {
|
|
95
|
+
return initialDelayMs;
|
|
96
|
+
}
|
|
97
|
+
function resolveBackoff(backoff) {
|
|
98
|
+
if (typeof backoff === "function") return backoff;
|
|
99
|
+
if (backoff === "linear") return linearBackoff;
|
|
100
|
+
return exponentialBackoff;
|
|
101
|
+
}
|
|
102
|
+
function resolveRetryConfig(options) {
|
|
103
|
+
return {
|
|
104
|
+
maxRetries: options?.maxRetries ?? 3,
|
|
105
|
+
initialDelayMs: options?.initialDelayMs ?? 1e3,
|
|
106
|
+
maxDelayMs: options?.maxDelayMs ?? 1e4,
|
|
107
|
+
backoff: resolveBackoff(options?.backoff),
|
|
108
|
+
shouldRetry: options?.shouldRetry ?? defaultShouldRetry,
|
|
109
|
+
onRetry: options?.onRetry
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
var EnvshedClient = class {
|
|
113
|
+
token;
|
|
114
|
+
apiUrl;
|
|
115
|
+
retryConfig;
|
|
116
|
+
/** Manage secrets in an environment */
|
|
117
|
+
secrets;
|
|
118
|
+
/** Manage organizations */
|
|
119
|
+
orgs;
|
|
120
|
+
/** Manage projects within an organization */
|
|
121
|
+
projects;
|
|
122
|
+
/** Manage environments within a project */
|
|
123
|
+
environments;
|
|
124
|
+
/** Query environment version (supports ETag) */
|
|
125
|
+
version;
|
|
126
|
+
/** Manage secret version history and rollbacks */
|
|
127
|
+
versions;
|
|
128
|
+
/** Manage environment snapshots */
|
|
129
|
+
snapshots;
|
|
130
|
+
/** Manage service tokens (admin only) */
|
|
131
|
+
serviceTokens;
|
|
132
|
+
constructor(options) {
|
|
133
|
+
if (!options.token) {
|
|
134
|
+
throw new Error("EnvshedClient requires a token");
|
|
135
|
+
}
|
|
136
|
+
this.token = options.token;
|
|
137
|
+
this.apiUrl = (options.apiUrl ?? DEFAULT_API_URL).replace(/\/+$/, "");
|
|
138
|
+
this.retryConfig = resolveRetryConfig(options.retry);
|
|
139
|
+
this.secrets = new SecretsAPI(this);
|
|
140
|
+
this.orgs = new OrgsAPI(this);
|
|
141
|
+
this.projects = new ProjectsAPI(this);
|
|
142
|
+
this.environments = new EnvironmentsAPI(this);
|
|
143
|
+
this.version = new VersionAPI(this);
|
|
144
|
+
this.versions = new VersionsAPI(this);
|
|
145
|
+
this.snapshots = new SnapshotsAPI(this);
|
|
146
|
+
this.serviceTokens = new ServiceTokensAPI(this);
|
|
147
|
+
}
|
|
148
|
+
/** Check authentication and return current user/token info */
|
|
149
|
+
async me() {
|
|
150
|
+
return this._request({ method: "GET", path: "/me" });
|
|
151
|
+
}
|
|
152
|
+
/** @internal */
|
|
153
|
+
async _request(options) {
|
|
154
|
+
const { method, path, body, headers: extraHeaders, query } = options;
|
|
155
|
+
let url = `${this.apiUrl}/api/v1${path}`;
|
|
156
|
+
if (query && Object.keys(query).length > 0) {
|
|
157
|
+
const params = new URLSearchParams();
|
|
158
|
+
for (const [k, v] of Object.entries(query)) {
|
|
159
|
+
params.set(k, String(v));
|
|
160
|
+
}
|
|
161
|
+
url += `?${params.toString()}`;
|
|
162
|
+
}
|
|
163
|
+
const headers = {
|
|
164
|
+
Authorization: `Bearer ${this.token}`,
|
|
165
|
+
...extraHeaders
|
|
166
|
+
};
|
|
167
|
+
if (body !== void 0) {
|
|
168
|
+
headers["Content-Type"] = "application/json";
|
|
169
|
+
}
|
|
170
|
+
let lastError;
|
|
171
|
+
const { maxRetries, initialDelayMs, maxDelayMs, backoff, shouldRetry, onRetry } = this.retryConfig;
|
|
172
|
+
const maxAttempts = 1 + maxRetries;
|
|
173
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
174
|
+
if (attempt > 0) {
|
|
175
|
+
const rawDelay = Math.min(backoff(attempt, initialDelayMs), maxDelayMs);
|
|
176
|
+
const jitter = rawDelay * 0.25 * (Math.random() * 2 - 1);
|
|
177
|
+
await sleep(rawDelay + jitter);
|
|
178
|
+
}
|
|
179
|
+
let res;
|
|
180
|
+
try {
|
|
181
|
+
res = await fetch(url, {
|
|
182
|
+
method,
|
|
183
|
+
headers,
|
|
184
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
185
|
+
});
|
|
186
|
+
} catch (err) {
|
|
187
|
+
const networkError = new EnvshedNetworkError({
|
|
188
|
+
cause: err instanceof Error ? err : new Error(String(err)),
|
|
189
|
+
method,
|
|
190
|
+
path
|
|
191
|
+
});
|
|
192
|
+
if (attempt < maxAttempts - 1 && shouldRetry(networkError, attempt + 1)) {
|
|
193
|
+
onRetry?.(networkError, attempt + 1);
|
|
194
|
+
lastError = networkError;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
throw networkError;
|
|
198
|
+
}
|
|
199
|
+
if (res.ok) {
|
|
200
|
+
if (res.status === 204) {
|
|
201
|
+
return void 0;
|
|
202
|
+
}
|
|
203
|
+
return await res.json();
|
|
204
|
+
}
|
|
205
|
+
let apiMessage = `HTTP ${res.status}`;
|
|
206
|
+
try {
|
|
207
|
+
const errorBody = await res.json();
|
|
208
|
+
if (errorBody && typeof errorBody.error === "string") {
|
|
209
|
+
apiMessage = errorBody.error;
|
|
210
|
+
}
|
|
211
|
+
} catch {
|
|
212
|
+
apiMessage = res.statusText || apiMessage;
|
|
213
|
+
}
|
|
214
|
+
const error = new EnvshedError({
|
|
215
|
+
status: res.status,
|
|
216
|
+
apiMessage,
|
|
217
|
+
method,
|
|
218
|
+
path
|
|
219
|
+
});
|
|
220
|
+
if (attempt < maxAttempts - 1 && shouldRetry(error, attempt + 1)) {
|
|
221
|
+
onRetry?.(error, attempt + 1);
|
|
222
|
+
lastError = error;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
throw lastError;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
var SecretsAPI = class {
|
|
231
|
+
constructor(client) {
|
|
232
|
+
this.client = client;
|
|
233
|
+
}
|
|
234
|
+
/** Get all secrets for an environment */
|
|
235
|
+
async get(path) {
|
|
236
|
+
return this.client._request({
|
|
237
|
+
method: "GET",
|
|
238
|
+
path: `/secrets/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
/** Set (upsert) secrets for an environment */
|
|
242
|
+
async set(path, secrets) {
|
|
243
|
+
return this.client._request({
|
|
244
|
+
method: "PUT",
|
|
245
|
+
path: `/secrets/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,
|
|
246
|
+
body: { secrets }
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var OrgsAPI = class {
|
|
251
|
+
constructor(client) {
|
|
252
|
+
this.client = client;
|
|
253
|
+
}
|
|
254
|
+
/** List all organizations the authenticated user belongs to */
|
|
255
|
+
async list() {
|
|
256
|
+
return this.client._request({ method: "GET", path: "/orgs" });
|
|
257
|
+
}
|
|
258
|
+
/** Create a new organization */
|
|
259
|
+
async create(data) {
|
|
260
|
+
return this.client._request({
|
|
261
|
+
method: "POST",
|
|
262
|
+
path: "/orgs",
|
|
263
|
+
body: data
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var ProjectsAPI = class {
|
|
268
|
+
constructor(client) {
|
|
269
|
+
this.client = client;
|
|
270
|
+
}
|
|
271
|
+
/** List all projects in an organization */
|
|
272
|
+
async list(org) {
|
|
273
|
+
return this.client._request({
|
|
274
|
+
method: "GET",
|
|
275
|
+
path: `/projects/${enc(org)}`
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/** Create a new project in an organization */
|
|
279
|
+
async create(org, data) {
|
|
280
|
+
return this.client._request({
|
|
281
|
+
method: "POST",
|
|
282
|
+
path: `/projects/${enc(org)}`,
|
|
283
|
+
body: data
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
var EnvironmentsAPI = class {
|
|
288
|
+
constructor(client) {
|
|
289
|
+
this.client = client;
|
|
290
|
+
}
|
|
291
|
+
/** List all environments in a project */
|
|
292
|
+
async list(org, project) {
|
|
293
|
+
return this.client._request({
|
|
294
|
+
method: "GET",
|
|
295
|
+
path: `/environments/${enc(org)}/${enc(project)}`
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
/** Create a new environment in a project */
|
|
299
|
+
async create(org, project, data) {
|
|
300
|
+
return this.client._request({
|
|
301
|
+
method: "POST",
|
|
302
|
+
path: `/environments/${enc(org)}/${enc(project)}`,
|
|
303
|
+
body: data
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
var VersionAPI = class {
|
|
308
|
+
constructor(client) {
|
|
309
|
+
this.client = client;
|
|
310
|
+
}
|
|
311
|
+
/** Get the current version of an environment. Returns null if unchanged (304). */
|
|
312
|
+
async get(path, etag) {
|
|
313
|
+
const headers = {};
|
|
314
|
+
if (etag) {
|
|
315
|
+
headers["If-None-Match"] = etag;
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
return await this.client._request({
|
|
319
|
+
method: "GET",
|
|
320
|
+
path: `/version/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,
|
|
321
|
+
headers
|
|
322
|
+
});
|
|
323
|
+
} catch (err) {
|
|
324
|
+
if (err instanceof EnvshedError && err.status === 304) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
throw err;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
var VersionsAPI = class {
|
|
332
|
+
constructor(client) {
|
|
333
|
+
this.client = client;
|
|
334
|
+
}
|
|
335
|
+
/** List version history for a specific secret key */
|
|
336
|
+
async list(path, secretKey, options) {
|
|
337
|
+
const query = {};
|
|
338
|
+
if (options?.limit !== void 0) query.limit = options.limit;
|
|
339
|
+
if (options?.offset !== void 0) query.offset = options.offset;
|
|
340
|
+
return this.client._request({
|
|
341
|
+
method: "GET",
|
|
342
|
+
path: `/versions/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/${enc(secretKey)}`,
|
|
343
|
+
query: Object.keys(query).length > 0 ? query : void 0
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
/** Rollback a secret to a previous version */
|
|
347
|
+
async rollback(path, secretKey, targetVersion) {
|
|
348
|
+
return this.client._request({
|
|
349
|
+
method: "POST",
|
|
350
|
+
path: `/versions/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/${enc(secretKey)}/rollback`,
|
|
351
|
+
body: { targetVersion }
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
var SnapshotsAPI = class {
|
|
356
|
+
constructor(client) {
|
|
357
|
+
this.client = client;
|
|
358
|
+
}
|
|
359
|
+
/** List all snapshots for an environment */
|
|
360
|
+
async list(path) {
|
|
361
|
+
return this.client._request({
|
|
362
|
+
method: "GET",
|
|
363
|
+
path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/** Create a snapshot of the current environment state */
|
|
367
|
+
async create(path, data) {
|
|
368
|
+
return this.client._request({
|
|
369
|
+
method: "POST",
|
|
370
|
+
path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,
|
|
371
|
+
body: data ?? {}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
/** Restore an environment from a snapshot */
|
|
375
|
+
async restore(path, snapshotId) {
|
|
376
|
+
return this.client._request({
|
|
377
|
+
method: "POST",
|
|
378
|
+
path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/restore`,
|
|
379
|
+
body: { snapshotId }
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
var ServiceTokensAPI = class {
|
|
384
|
+
constructor(client) {
|
|
385
|
+
this.client = client;
|
|
386
|
+
}
|
|
387
|
+
/** List all service tokens for an organization (admin only) */
|
|
388
|
+
async list(org) {
|
|
389
|
+
return this.client._request({
|
|
390
|
+
method: "GET",
|
|
391
|
+
path: `/service-tokens/${enc(org)}`
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
/** Create a new service token (admin only) */
|
|
395
|
+
async create(org, data) {
|
|
396
|
+
return this.client._request({
|
|
397
|
+
method: "POST",
|
|
398
|
+
path: `/service-tokens/${enc(org)}`,
|
|
399
|
+
body: data
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
/** Delete a service token (admin only) */
|
|
403
|
+
async delete(org, tokenId) {
|
|
404
|
+
return this.client._request({
|
|
405
|
+
method: "DELETE",
|
|
406
|
+
path: `/service-tokens/${enc(org)}`,
|
|
407
|
+
query: { id: tokenId }
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
function enc(segment) {
|
|
412
|
+
return encodeURIComponent(segment);
|
|
413
|
+
}
|
|
414
|
+
function sleep(ms) {
|
|
415
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
416
|
+
}
|
|
417
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
418
|
+
0 && (module.exports = {
|
|
419
|
+
EnvshedClient,
|
|
420
|
+
EnvshedError,
|
|
421
|
+
EnvshedNetworkError
|
|
422
|
+
});
|
|
423
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { EnvshedClient } from \"./client.js\";\nexport { EnvshedError, EnvshedNetworkError } from \"./errors.js\";\nexport type {\n // Client configuration\n EnvshedClientOptions,\n RetryOptions,\n BackoffFunction,\n ShouldRetryFunction,\n OnRetryFunction,\n\n // Common\n EnvPath,\n TokenScope,\n TokenPermission,\n\n // Secrets\n GetSecretsResponse,\n SetSecretsRequest,\n SetSecretsResponse,\n\n // Organizations\n Organization,\n ListOrgsResponse,\n CreateOrgRequest,\n CreateOrgResponse,\n\n // Projects\n Project,\n ListProjectsResponse,\n CreateProjectRequest,\n CreateProjectResponse,\n\n // Environments\n Environment,\n ListEnvironmentsResponse,\n CreateEnvironmentRequest,\n CreateEnvironmentResponse,\n\n // Version\n GetVersionResponse,\n\n // Secret Versions\n SecretVersion,\n ListSecretVersionsResponse,\n ListSecretVersionsOptions,\n RollbackSecretResponse,\n\n // Snapshots\n Snapshot,\n ListSnapshotsResponse,\n CreateSnapshotRequest,\n CreateSnapshotResponse,\n RestoreSnapshotRequest,\n RestoreSnapshotResponse,\n\n // Me\n MeResponse,\n MeUserResponse,\n MeServiceTokenResponse,\n\n // Service Tokens\n ServiceToken,\n ListServiceTokensResponse,\n CreateServiceTokenRequest,\n CreateServiceTokenResponse,\n DeleteServiceTokenResponse,\n} from \"./types.js\";\n","/**\n * Error thrown when the Envshed API returns an HTTP error response (4xx or 5xx).\n */\nexport class EnvshedError extends Error {\n /** HTTP status code from the API */\n readonly status: number;\n /** Error message from the API response body */\n readonly apiMessage: string;\n /** HTTP method of the failed request */\n readonly method: string;\n /** URL path of the failed request */\n readonly path: string;\n\n constructor(options: {\n status: number;\n apiMessage: string;\n method: string;\n path: string;\n }) {\n super(`Envshed API error (${options.status}): ${options.apiMessage}`);\n this.name = \"EnvshedError\";\n this.status = options.status;\n this.apiMessage = options.apiMessage;\n this.method = options.method;\n this.path = options.path;\n }\n\n /** Whether this is an authentication error (401) */\n get isUnauthorized(): boolean {\n return this.status === 401;\n }\n\n /** Whether this is a permissions error (403) */\n get isForbidden(): boolean {\n return this.status === 403;\n }\n\n /** Whether this is a not found error (404) */\n get isNotFound(): boolean {\n return this.status === 404;\n }\n\n /** Whether this is a subscription-related error (402) */\n get isSubscriptionRequired(): boolean {\n return this.status === 402;\n }\n\n /** Whether this error is retryable (5xx server errors) */\n get isRetryable(): boolean {\n return this.status >= 500;\n }\n}\n\n/**\n * Error thrown when a network-level failure occurs (no HTTP response).\n * Always considered retryable.\n */\nexport class EnvshedNetworkError extends Error {\n readonly method: string;\n readonly path: string;\n override readonly cause: Error;\n\n constructor(options: { method: string; path: string; cause: Error }) {\n super(`Envshed network error: ${options.cause.message}`);\n this.name = \"EnvshedNetworkError\";\n this.method = options.method;\n this.path = options.path;\n this.cause = options.cause;\n }\n\n get isRetryable(): boolean {\n return true;\n }\n}\n","import { EnvshedError, EnvshedNetworkError } from \"./errors.js\";\nimport type {\n EnvshedClientOptions,\n RetryOptions,\n BackoffFunction,\n ShouldRetryFunction,\n OnRetryFunction,\n RequestOptions,\n EnvPath,\n GetSecretsResponse,\n SetSecretsRequest,\n SetSecretsResponse,\n ListOrgsResponse,\n CreateOrgRequest,\n CreateOrgResponse,\n ListProjectsResponse,\n CreateProjectRequest,\n CreateProjectResponse,\n ListEnvironmentsResponse,\n CreateEnvironmentRequest,\n CreateEnvironmentResponse,\n GetVersionResponse,\n ListSecretVersionsResponse,\n ListSecretVersionsOptions,\n RollbackSecretResponse,\n ListSnapshotsResponse,\n CreateSnapshotRequest,\n CreateSnapshotResponse,\n RestoreSnapshotRequest,\n RestoreSnapshotResponse,\n MeResponse,\n ListServiceTokensResponse,\n CreateServiceTokenRequest,\n CreateServiceTokenResponse,\n DeleteServiceTokenResponse,\n} from \"./types.js\";\n\nconst DEFAULT_API_URL = \"https://app.envshed.com\";\n\ninterface ResolvedRetryConfig {\n maxRetries: number;\n initialDelayMs: number;\n maxDelayMs: number;\n backoff: BackoffFunction;\n shouldRetry: ShouldRetryFunction;\n onRetry: OnRetryFunction | undefined;\n}\n\nfunction defaultShouldRetry(error: Error): boolean {\n if (error instanceof EnvshedError) return error.isRetryable;\n if (error instanceof EnvshedNetworkError) return true;\n return false;\n}\n\nfunction exponentialBackoff(attempt: number, initialDelayMs: number): number {\n return initialDelayMs * Math.pow(2, attempt - 1);\n}\n\nfunction linearBackoff(_attempt: number, initialDelayMs: number): number {\n return initialDelayMs;\n}\n\nfunction resolveBackoff(\n backoff: RetryOptions[\"backoff\"],\n): BackoffFunction {\n if (typeof backoff === \"function\") return backoff;\n if (backoff === \"linear\") return linearBackoff;\n return exponentialBackoff;\n}\n\nfunction resolveRetryConfig(options?: RetryOptions): ResolvedRetryConfig {\n return {\n maxRetries: options?.maxRetries ?? 3,\n initialDelayMs: options?.initialDelayMs ?? 1000,\n maxDelayMs: options?.maxDelayMs ?? 10_000,\n backoff: resolveBackoff(options?.backoff),\n shouldRetry: options?.shouldRetry ?? defaultShouldRetry,\n onRetry: options?.onRetry,\n };\n}\n\nexport class EnvshedClient {\n private readonly token: string;\n private readonly apiUrl: string;\n private readonly retryConfig: ResolvedRetryConfig;\n\n /** Manage secrets in an environment */\n readonly secrets: SecretsAPI;\n /** Manage organizations */\n readonly orgs: OrgsAPI;\n /** Manage projects within an organization */\n readonly projects: ProjectsAPI;\n /** Manage environments within a project */\n readonly environments: EnvironmentsAPI;\n /** Query environment version (supports ETag) */\n readonly version: VersionAPI;\n /** Manage secret version history and rollbacks */\n readonly versions: VersionsAPI;\n /** Manage environment snapshots */\n readonly snapshots: SnapshotsAPI;\n /** Manage service tokens (admin only) */\n readonly serviceTokens: ServiceTokensAPI;\n\n constructor(options: EnvshedClientOptions) {\n if (!options.token) {\n throw new Error(\"EnvshedClient requires a token\");\n }\n\n this.token = options.token;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API_URL).replace(/\\/+$/, \"\");\n this.retryConfig = resolveRetryConfig(options.retry);\n\n this.secrets = new SecretsAPI(this);\n this.orgs = new OrgsAPI(this);\n this.projects = new ProjectsAPI(this);\n this.environments = new EnvironmentsAPI(this);\n this.version = new VersionAPI(this);\n this.versions = new VersionsAPI(this);\n this.snapshots = new SnapshotsAPI(this);\n this.serviceTokens = new ServiceTokensAPI(this);\n }\n\n /** Check authentication and return current user/token info */\n async me(): Promise<MeResponse> {\n return this._request({ method: \"GET\", path: \"/me\" });\n }\n\n /** @internal */\n async _request<T>(options: RequestOptions): Promise<T> {\n const { method, path, body, headers: extraHeaders, query } = options;\n\n let url = `${this.apiUrl}/api/v1${path}`;\n if (query && Object.keys(query).length > 0) {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) {\n params.set(k, String(v));\n }\n url += `?${params.toString()}`;\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n ...extraHeaders,\n };\n\n if (body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n let lastError: EnvshedError | EnvshedNetworkError | undefined;\n const { maxRetries, initialDelayMs, maxDelayMs, backoff, shouldRetry, onRetry } =\n this.retryConfig;\n const maxAttempts = 1 + maxRetries;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (attempt > 0) {\n const rawDelay = Math.min(backoff(attempt, initialDelayMs), maxDelayMs);\n const jitter = rawDelay * 0.25 * (Math.random() * 2 - 1);\n await sleep(rawDelay + jitter);\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (err) {\n const networkError = new EnvshedNetworkError({\n cause: err instanceof Error ? err : new Error(String(err)),\n method,\n path,\n });\n\n if (attempt < maxAttempts - 1 && shouldRetry(networkError, attempt + 1)) {\n onRetry?.(networkError, attempt + 1);\n lastError = networkError;\n continue;\n }\n\n throw networkError;\n }\n\n if (res.ok) {\n if (res.status === 204) {\n return undefined as T;\n }\n return (await res.json()) as T;\n }\n\n let apiMessage = `HTTP ${res.status}`;\n try {\n const errorBody = (await res.json()) as { error?: string };\n if (errorBody && typeof errorBody.error === \"string\") {\n apiMessage = errorBody.error;\n }\n } catch {\n apiMessage = res.statusText || apiMessage;\n }\n\n const error = new EnvshedError({\n status: res.status,\n apiMessage,\n method,\n path,\n });\n\n if (attempt < maxAttempts - 1 && shouldRetry(error, attempt + 1)) {\n onRetry?.(error, attempt + 1);\n lastError = error;\n continue;\n }\n\n throw error;\n }\n\n throw lastError!;\n }\n}\n\n// ─── Sub-API Classes ────────────────────────────────────────────\n\nclass SecretsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** Get all secrets for an environment */\n async get(path: EnvPath): Promise<GetSecretsResponse> {\n return this.client._request({\n method: \"GET\",\n path: `/secrets/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,\n });\n }\n\n /** Set (upsert) secrets for an environment */\n async set(\n path: EnvPath,\n secrets: Record<string, string>,\n ): Promise<SetSecretsResponse> {\n return this.client._request({\n method: \"PUT\",\n path: `/secrets/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,\n body: { secrets } satisfies SetSecretsRequest,\n });\n }\n}\n\nclass OrgsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List all organizations the authenticated user belongs to */\n async list(): Promise<ListOrgsResponse> {\n return this.client._request({ method: \"GET\", path: \"/orgs\" });\n }\n\n /** Create a new organization */\n async create(data: CreateOrgRequest): Promise<CreateOrgResponse> {\n return this.client._request({\n method: \"POST\",\n path: \"/orgs\",\n body: data,\n });\n }\n}\n\nclass ProjectsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List all projects in an organization */\n async list(org: string): Promise<ListProjectsResponse> {\n return this.client._request({\n method: \"GET\",\n path: `/projects/${enc(org)}`,\n });\n }\n\n /** Create a new project in an organization */\n async create(\n org: string,\n data: CreateProjectRequest,\n ): Promise<CreateProjectResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/projects/${enc(org)}`,\n body: data,\n });\n }\n}\n\nclass EnvironmentsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List all environments in a project */\n async list(org: string, project: string): Promise<ListEnvironmentsResponse> {\n return this.client._request({\n method: \"GET\",\n path: `/environments/${enc(org)}/${enc(project)}`,\n });\n }\n\n /** Create a new environment in a project */\n async create(\n org: string,\n project: string,\n data: CreateEnvironmentRequest,\n ): Promise<CreateEnvironmentResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/environments/${enc(org)}/${enc(project)}`,\n body: data,\n });\n }\n}\n\nclass VersionAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** Get the current version of an environment. Returns null if unchanged (304). */\n async get(path: EnvPath, etag?: string): Promise<GetVersionResponse | null> {\n const headers: Record<string, string> = {};\n if (etag) {\n headers[\"If-None-Match\"] = etag;\n }\n\n try {\n return await this.client._request<GetVersionResponse>({\n method: \"GET\",\n path: `/version/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,\n headers,\n });\n } catch (err) {\n if (err instanceof EnvshedError && err.status === 304) {\n return null;\n }\n throw err;\n }\n }\n}\n\nclass VersionsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List version history for a specific secret key */\n async list(\n path: EnvPath,\n secretKey: string,\n options?: ListSecretVersionsOptions,\n ): Promise<ListSecretVersionsResponse> {\n const query: Record<string, string | number> = {};\n if (options?.limit !== undefined) query.limit = options.limit;\n if (options?.offset !== undefined) query.offset = options.offset;\n\n return this.client._request({\n method: \"GET\",\n path: `/versions/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/${enc(secretKey)}`,\n query: Object.keys(query).length > 0 ? query : undefined,\n });\n }\n\n /** Rollback a secret to a previous version */\n async rollback(\n path: EnvPath,\n secretKey: string,\n targetVersion: number,\n ): Promise<RollbackSecretResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/versions/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/${enc(secretKey)}/rollback`,\n body: { targetVersion },\n });\n }\n}\n\nclass SnapshotsAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List all snapshots for an environment */\n async list(path: EnvPath): Promise<ListSnapshotsResponse> {\n return this.client._request({\n method: \"GET\",\n path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,\n });\n }\n\n /** Create a snapshot of the current environment state */\n async create(\n path: EnvPath,\n data?: CreateSnapshotRequest,\n ): Promise<CreateSnapshotResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}`,\n body: data ?? {},\n });\n }\n\n /** Restore an environment from a snapshot */\n async restore(\n path: EnvPath,\n snapshotId: string,\n ): Promise<RestoreSnapshotResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/snapshots/${enc(path.org)}/${enc(path.project)}/${enc(path.env)}/restore`,\n body: { snapshotId } satisfies RestoreSnapshotRequest,\n });\n }\n}\n\nclass ServiceTokensAPI {\n constructor(private readonly client: EnvshedClient) {}\n\n /** List all service tokens for an organization (admin only) */\n async list(org: string): Promise<ListServiceTokensResponse> {\n return this.client._request({\n method: \"GET\",\n path: `/service-tokens/${enc(org)}`,\n });\n }\n\n /** Create a new service token (admin only) */\n async create(\n org: string,\n data: CreateServiceTokenRequest,\n ): Promise<CreateServiceTokenResponse> {\n return this.client._request({\n method: \"POST\",\n path: `/service-tokens/${enc(org)}`,\n body: data,\n });\n }\n\n /** Delete a service token (admin only) */\n async delete(\n org: string,\n tokenId: string,\n ): Promise<DeleteServiceTokenResponse> {\n return this.client._request({\n method: \"DELETE\",\n path: `/service-tokens/${enc(org)}`,\n query: { id: tokenId },\n });\n }\n}\n\n// ─── Helpers ────────────────────────────────────────────────────\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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","names":[]}
|