cloudcruise 1.1.0 → 1.2.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.
@@ -1,4 +1,5 @@
1
1
  import { VaultClient } from './vault/VaultClient.js';
2
+ import { SecretProvidersClient } from './secretProviders/SecretProvidersClient.js';
2
3
  import { WorkflowsClient } from './workflows/WorkflowsClient.js';
3
4
  import { RunsClient } from './runs/RunsClient.js';
4
5
  import { WebhookClient } from './webhook/WebhookClient.js';
@@ -16,6 +17,7 @@ export declare class CloudCruise {
16
17
  private readonly baseUrl;
17
18
  private readonly encryptionKey;
18
19
  readonly vault: VaultClient;
20
+ readonly secretProviders: SecretProvidersClient;
19
21
  readonly workflows: WorkflowsClient;
20
22
  readonly runs: RunsClient;
21
23
  readonly webhook: WebhookClient;
@@ -1,5 +1,6 @@
1
1
  import { getEnv } from './utils/env.js';
2
2
  import { VaultClient } from './vault/VaultClient.js';
3
+ import { SecretProvidersClient } from './secretProviders/SecretProvidersClient.js';
3
4
  import { WorkflowsClient } from './workflows/WorkflowsClient.js';
4
5
  import { RunsClient } from './runs/RunsClient.js';
5
6
  import { WebhookClient } from './webhook/WebhookClient.js';
@@ -39,6 +40,7 @@ export class CloudCruise {
39
40
  baseUrl;
40
41
  encryptionKey;
41
42
  vault;
43
+ secretProviders;
42
44
  workflows;
43
45
  runs;
44
46
  webhook;
@@ -61,6 +63,7 @@ export class CloudCruise {
61
63
  // Initialize namespace clients
62
64
  this.connectionManager = new ConnectionManager(this.baseUrl, this.apiKey);
63
65
  this.vault = new VaultClient(this.makeRequest.bind(this), this.encryptionKey);
66
+ this.secretProviders = new SecretProvidersClient(this.makeRequest.bind(this));
64
67
  this.workflows = new WorkflowsClient(this.makeRequest.bind(this));
65
68
  this.runs = new RunsClient(this.connectionManager, this.makeRequest.bind(this), this.workflows);
66
69
  this.webhook = new WebhookClient();
package/dist/index.d.ts CHANGED
@@ -5,10 +5,11 @@
5
5
  export { CloudCruise } from './CloudCruise.js';
6
6
  export type { CloudCruiseParams } from './CloudCruise.js';
7
7
  export { VaultClient } from './vault/VaultClient.js';
8
+ export { SecretProvidersClient } from './secretProviders/SecretProvidersClient.js';
8
9
  export { WorkflowsClient } from './workflows/WorkflowsClient.js';
9
10
  export { RunsClient } from './runs/RunsClient.js';
10
11
  export { WebhookClient } from './webhook/WebhookClient.js';
11
- export type { VaultEntry, GetVaultEntriesFilters, ProxyConfig, VaultPostPutHeadersInBody } from './vault/types.js';
12
+ export type { VaultEntry, GetVaultEntriesFilters, ProxyConfig, VaultPostPutHeadersInBody, SecretProvider, SecretProviderItem, SecretProviderType } from './vault/types.js';
12
13
  export type { Workflow, WorkflowInputSchema, WorkflowMetadata } from './workflows/types.js';
13
14
  export type { DryRun, Metadata, RunSpecificWebhook, PayloadWebhook, StartRunRequest, StartRunResponse, UserInteractionData, VideoUrl, SignedFileUrl, SignedScreenshotUrl, RunError, WorkflowError, RunResult, GetRunResult, WebhookEvent, WebhookReplayResponse, RunHandle, RunStreamOptions, SseEventName, SseMessage, RunEventEnvelope, RunHandleEventMap } from './runs/types.js';
14
15
  export { EventType } from './events/types.js';
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export { CloudCruise } from './CloudCruise.js';
6
6
  export { VaultClient } from './vault/VaultClient.js';
7
+ export { SecretProvidersClient } from './secretProviders/SecretProvidersClient.js';
7
8
  export { WorkflowsClient } from './workflows/WorkflowsClient.js';
8
9
  export { RunsClient } from './runs/RunsClient.js';
9
10
  export { WebhookClient } from './webhook/WebhookClient.js';
@@ -0,0 +1,7 @@
1
+ import type { SecretProvider, SecretProviderItem } from '../vault/types.js';
2
+ export declare class SecretProvidersClient {
3
+ private readonly makeRequest;
4
+ constructor(makeRequest: <T = any>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body?: any) => Promise<T>);
5
+ list(): Promise<SecretProvider[]>;
6
+ listItems(secretProviderId: string): Promise<SecretProviderItem[]>;
7
+ }
@@ -0,0 +1,17 @@
1
+ export class SecretProvidersClient {
2
+ makeRequest;
3
+ constructor(makeRequest) {
4
+ this.makeRequest = makeRequest;
5
+ }
6
+ async list() {
7
+ const response = await this.makeRequest('GET', '/secret-providers');
8
+ return Array.isArray(response) ? response : [response];
9
+ }
10
+ async listItems(secretProviderId) {
11
+ if (!secretProviderId) {
12
+ throw new Error('secretProviderId is required');
13
+ }
14
+ const response = await this.makeRequest('GET', `/secret-providers/${encodeURIComponent(secretProviderId)}/items`);
15
+ return Array.isArray(response) ? response : [response];
16
+ }
17
+ }
@@ -32,14 +32,10 @@ export declare class VaultClient {
32
32
  * Updates an existing vault entry
33
33
  * @param updates - Vault entry updates including required fields
34
34
  * @param updates.permissioned_user_id - Required: User identifier for the vault entry
35
- * @param updates.user_name - Required: Username or email
36
- * @param updates.password - Required: User password
37
35
  * @param updates.domain - Required: Target domain for the credentials
38
36
  */
39
37
  update(updates: Partial<VaultEntry> & {
40
38
  permissioned_user_id: string;
41
- user_name: string;
42
- password: string;
43
39
  domain: string;
44
40
  }): Promise<VaultEntry>;
45
41
  /**
@@ -1,4 +1,28 @@
1
1
  import { encryptSensitiveFields, decryptSensitiveFields } from './utils.js';
2
+ function validateProviderPayload(entry) {
3
+ const hasProviderId = entry.secret_provider_id !== undefined && entry.secret_provider_id !== null;
4
+ const hasSecretRef = entry.secret_ref !== undefined && entry.secret_ref !== null;
5
+ if (hasProviderId !== hasSecretRef) {
6
+ throw new Error('secret_provider_id and secret_ref must be provided together');
7
+ }
8
+ if (entry.secret_cache_ttl_seconds !== undefined && entry.secret_cache_ttl_seconds !== null) {
9
+ if (!Number.isInteger(entry.secret_cache_ttl_seconds) || entry.secret_cache_ttl_seconds < 0) {
10
+ throw new Error('secret_cache_ttl_seconds must be a non-negative integer');
11
+ }
12
+ if (!hasProviderId) {
13
+ throw new Error('secret_cache_ttl_seconds requires secret_provider_id and secret_ref');
14
+ }
15
+ }
16
+ if (hasProviderId) {
17
+ const conflicts = ['user_name', 'password', 'tfa_secret'].filter(field => entry[field] !== undefined && entry[field] !== null);
18
+ if (conflicts.length > 0) {
19
+ throw new Error(`provider-backed vault entries cannot include ${conflicts.join(', ')}`);
20
+ }
21
+ }
22
+ }
23
+ function isProviderBackedPayload(entry) {
24
+ return entry.secret_provider_id != null && entry.secret_ref != null;
25
+ }
2
26
  export class VaultClient {
3
27
  makeRequest;
4
28
  encryptionKey;
@@ -15,6 +39,7 @@ export class VaultClient {
15
39
  permissioned_user_id,
16
40
  ...options
17
41
  };
42
+ validateProviderPayload(entry);
18
43
  let processedEntry = { ...entry };
19
44
  // Encrypt sensitive fields
20
45
  processedEntry = await encryptSensitiveFields(processedEntry, this.encryptionKey);
@@ -78,8 +103,6 @@ export class VaultClient {
78
103
  * Updates an existing vault entry
79
104
  * @param updates - Vault entry updates including required fields
80
105
  * @param updates.permissioned_user_id - Required: User identifier for the vault entry
81
- * @param updates.user_name - Required: Username or email
82
- * @param updates.password - Required: User password
83
106
  * @param updates.domain - Required: Target domain for the credentials
84
107
  */
85
108
  async update(updates) {
@@ -87,15 +110,18 @@ export class VaultClient {
87
110
  if (!updates.permissioned_user_id) {
88
111
  throw new Error('permissioned_user_id is required for vault updates');
89
112
  }
90
- if (!updates.user_name) {
91
- throw new Error('user_name is required for vault updates');
92
- }
93
- if (!updates.password) {
94
- throw new Error('password is required for vault updates');
95
- }
96
113
  if (!updates.domain) {
97
114
  throw new Error('domain is required for vault updates');
98
115
  }
116
+ validateProviderPayload(updates);
117
+ if (!isProviderBackedPayload(updates)) {
118
+ if (!updates.user_name) {
119
+ throw new Error('user_name is required for vault updates');
120
+ }
121
+ if (!updates.password) {
122
+ throw new Error('password is required for vault updates');
123
+ }
124
+ }
99
125
  let processedEntry = { ...updates };
100
126
  // Encrypt sensitive fields
101
127
  processedEntry = await encryptSensitiveFields(processedEntry, this.encryptionKey);
@@ -17,6 +17,9 @@ export interface VaultEntry {
17
17
  user_id?: string;
18
18
  password?: string;
19
19
  user_name?: string;
20
+ secret_provider_id?: string | null;
21
+ secret_ref?: string | null;
22
+ secret_cache_ttl_seconds?: number | null;
20
23
  tfa_secret?: string;
21
24
  user_agent?: string;
22
25
  user_alias?: string;
@@ -50,6 +53,19 @@ export interface GetVaultEntriesFilters {
50
53
  domain?: string;
51
54
  decryptCredentials?: boolean;
52
55
  }
56
+ export type SecretProviderType = '1password';
57
+ export interface SecretProvider {
58
+ id: string;
59
+ provider_type: SecretProviderType;
60
+ name: string;
61
+ cache_ttl_seconds?: number | null;
62
+ }
63
+ export interface SecretProviderItem {
64
+ id: string;
65
+ title: string;
66
+ ref: string;
67
+ vaultName?: string | null;
68
+ }
53
69
  /**
54
70
  * The current 2FA code for a vault entry. `expires_in_seconds` is present for
55
71
  * authenticator (TOTP) codes; `received_at` is present for email codes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcruise",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "The official CloudCruise JS/TS client.",
5
5
  "homepage": "https://github.com/CloudCruise/cloudcruise-js#readme",
6
6
  "bugs": {