@clonecommand/cloud 0.0.3 → 0.0.7
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 +7 -0
- package/dist/email/index.d.ts +39 -47
- package/dist/email/index.js +45 -53
- package/dist/email/types.d.ts +55 -0
- package/dist/email/types.js +1 -0
- package/dist/index.d.ts +61 -40
- package/dist/index.js +70 -47
- package/dist/types.d.ts +43 -0
- package/dist/types.js +1 -0
- package/docs/email.md +5 -5
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -4,6 +4,13 @@ The official SDK for CloneCommand managed services.
|
|
|
4
4
|
|
|
5
5
|
This library simplifies integration with ephemeral preview environments and provides access to CloneCommand Cloud services like Login Proxy, Storage, and Email.
|
|
6
6
|
|
|
7
|
+
### 🤖 Agent Ready
|
|
8
|
+
This package is designed to be easily consumed by AI agents and LLMs. It features:
|
|
9
|
+
- **Full TypeScript Definitions**: All methods, arguments, and return types are strictly typed.
|
|
10
|
+
- **Rich JSDoc**: Comprehensive comments and examples to help agents understand the intent behind every function.
|
|
11
|
+
- **Clean API Surface**: A logical, singleton-based structure that is easy to navigate.
|
|
12
|
+
|
|
13
|
+
|
|
7
14
|
## Documentation
|
|
8
15
|
|
|
9
16
|
Full documentation is available in the [`docs/`](./docs/README.md) directory.
|
package/dist/email/index.d.ts
CHANGED
|
@@ -1,69 +1,61 @@
|
|
|
1
|
-
import { CloneCommandCloud } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
isEnabled: boolean;
|
|
7
|
-
sesIdentityArn?: string;
|
|
8
|
-
sesVerificationStatus?: string;
|
|
9
|
-
dkimTokens?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface InboundEmail {
|
|
12
|
-
id: string;
|
|
13
|
-
projectId: string;
|
|
14
|
-
sender: string;
|
|
15
|
-
recipient: string;
|
|
16
|
-
subject: string;
|
|
17
|
-
snippet: string;
|
|
18
|
-
bucketPath: string;
|
|
19
|
-
receivedAt: string;
|
|
20
|
-
isRead: boolean;
|
|
21
|
-
hasAttachments: boolean;
|
|
22
|
-
rawSize: number;
|
|
23
|
-
threadId?: string;
|
|
24
|
-
messageId?: string;
|
|
25
|
-
inReplyTo?: string;
|
|
26
|
-
references?: string;
|
|
27
|
-
}
|
|
28
|
-
export interface SendEmailOptions {
|
|
29
|
-
from?: string;
|
|
30
|
-
to: string | string[];
|
|
31
|
-
subject: string;
|
|
32
|
-
html?: string;
|
|
33
|
-
text?: string;
|
|
34
|
-
}
|
|
1
|
+
import { CloneCommandCloud } from "..";
|
|
2
|
+
import { InboundEmail, SendEmailOptions } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Client for interacting with CloneCommand Email services.
|
|
5
|
+
*/
|
|
35
6
|
export declare class EmailClient {
|
|
36
7
|
private ccc;
|
|
37
8
|
constructor(ccc: CloneCommandCloud);
|
|
38
9
|
/**
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Enable email service for a domain.
|
|
10
|
+
* Checks if the email service is enabled for the current project.
|
|
11
|
+
*
|
|
12
|
+
* @returns A promise resolving to true if enabled, false otherwise.
|
|
44
13
|
*/
|
|
45
|
-
|
|
14
|
+
isEnabled(): Promise<boolean>;
|
|
46
15
|
/**
|
|
47
|
-
*
|
|
16
|
+
* Sends an email message.
|
|
17
|
+
*
|
|
18
|
+
* @param options - The email content and recipient details.
|
|
19
|
+
* @returns A promise resolving to the Message-ID of the sent email.
|
|
20
|
+
* @throws Error if sending fails.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* await ccc.email.send({
|
|
24
|
+
* to: 'user@example.com',
|
|
25
|
+
* subject: 'Hello',
|
|
26
|
+
* text: 'This is a test'
|
|
27
|
+
* });
|
|
48
28
|
*/
|
|
49
|
-
send(options: SendEmailOptions
|
|
29
|
+
send(options: SendEmailOptions): Promise<string>;
|
|
50
30
|
/**
|
|
51
|
-
*
|
|
31
|
+
* Retrieves a list of inbound emails received by the project.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Filtering and pagination options (limit, before).
|
|
34
|
+
* @returns A promise resolving to an array of InboundEmail previews.
|
|
52
35
|
*/
|
|
53
36
|
getInbound(options?: {
|
|
54
37
|
limit?: number;
|
|
55
38
|
before?: Date;
|
|
56
|
-
}
|
|
39
|
+
}): Promise<InboundEmail[]>;
|
|
57
40
|
/**
|
|
58
|
-
*
|
|
41
|
+
* Retrieves the full details of a specific inbound email, including the body.
|
|
42
|
+
*
|
|
43
|
+
* @param emailId - The unique ID of the email.
|
|
44
|
+
* @returns A promise resolving to the full InboundEmail object, or null if not found.
|
|
59
45
|
*/
|
|
60
46
|
get(emailId: string): Promise<InboundEmail | null>;
|
|
61
47
|
/**
|
|
62
|
-
*
|
|
48
|
+
* Marks an inbound email as read.
|
|
49
|
+
*
|
|
50
|
+
* @param emailId - The unique ID of the email.
|
|
51
|
+
* @returns A promise resolving to true if successful.
|
|
63
52
|
*/
|
|
64
53
|
markAsRead(emailId: string): Promise<boolean>;
|
|
65
54
|
/**
|
|
66
|
-
*
|
|
55
|
+
* Deletes an inbound email permanently.
|
|
56
|
+
*
|
|
57
|
+
* @param emailId - The unique ID of the email.
|
|
58
|
+
* @returns A promise resolving to true if successful.
|
|
67
59
|
*/
|
|
68
60
|
delete(emailId: string): Promise<boolean>;
|
|
69
61
|
}
|
package/dist/email/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client for interacting with CloneCommand Email services.
|
|
3
|
+
*/
|
|
1
4
|
export class EmailClient {
|
|
2
5
|
ccc;
|
|
3
6
|
constructor(ccc) {
|
|
4
7
|
this.ccc = ccc;
|
|
5
8
|
}
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
10
|
+
* Checks if the email service is enabled for the current project.
|
|
11
|
+
*
|
|
12
|
+
* @returns A promise resolving to true if enabled, false otherwise.
|
|
8
13
|
*/
|
|
9
|
-
async
|
|
10
|
-
const pid =
|
|
14
|
+
async isEnabled() {
|
|
15
|
+
const pid = this.ccc.projectId;
|
|
11
16
|
if (!pid)
|
|
12
|
-
throw new Error("projectId is
|
|
17
|
+
throw new Error("projectId could not be resolved. Ensure CC_PROJECT_TOKEN is set.");
|
|
13
18
|
const query = `
|
|
14
|
-
query
|
|
19
|
+
query EmailStatus($projectId: ID!) {
|
|
15
20
|
emailConfig(projectId: $projectId) {
|
|
16
|
-
id
|
|
17
|
-
projectId
|
|
18
|
-
domainId
|
|
19
21
|
isEnabled
|
|
20
|
-
sesVerificationStatus
|
|
21
|
-
dkimTokens
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
`;
|
|
@@ -32,46 +32,26 @@ export class EmailClient {
|
|
|
32
32
|
});
|
|
33
33
|
if (result.errors)
|
|
34
34
|
throw new Error(result.errors[0].message);
|
|
35
|
-
return result.data.emailConfig;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Enable email service for a domain.
|
|
39
|
-
*/
|
|
40
|
-
async enable(domainId, projectId) {
|
|
41
|
-
const pid = projectId || this.ccc.projectId;
|
|
42
|
-
if (!pid)
|
|
43
|
-
throw new Error("projectId is required");
|
|
44
|
-
const query = `
|
|
45
|
-
mutation EnableEmail($projectId: ID!, $domainId: ID!) {
|
|
46
|
-
enableEmail(projectId: $projectId, domainId: $domainId) {
|
|
47
|
-
id
|
|
48
|
-
projectId
|
|
49
|
-
domainId
|
|
50
|
-
isEnabled
|
|
51
|
-
sesVerificationStatus
|
|
52
|
-
dkimTokens
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
`;
|
|
56
|
-
const result = await this.ccc.request('/graphql', {
|
|
57
|
-
method: 'POST',
|
|
58
|
-
headers: { 'Content-Type': 'application/json' },
|
|
59
|
-
body: JSON.stringify({
|
|
60
|
-
query,
|
|
61
|
-
variables: { projectId: pid, domainId }
|
|
62
|
-
})
|
|
63
|
-
});
|
|
64
|
-
if (result.errors)
|
|
65
|
-
throw new Error(result.errors[0].message);
|
|
66
|
-
return result.data.enableEmail;
|
|
35
|
+
return !!result.data.emailConfig?.isEnabled;
|
|
67
36
|
}
|
|
68
37
|
/**
|
|
69
|
-
*
|
|
38
|
+
* Sends an email message.
|
|
39
|
+
*
|
|
40
|
+
* @param options - The email content and recipient details.
|
|
41
|
+
* @returns A promise resolving to the Message-ID of the sent email.
|
|
42
|
+
* @throws Error if sending fails.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* await ccc.email.send({
|
|
46
|
+
* to: 'user@example.com',
|
|
47
|
+
* subject: 'Hello',
|
|
48
|
+
* text: 'This is a test'
|
|
49
|
+
* });
|
|
70
50
|
*/
|
|
71
|
-
async send(options
|
|
72
|
-
const pid =
|
|
51
|
+
async send(options) {
|
|
52
|
+
const pid = this.ccc.projectId;
|
|
73
53
|
if (!pid)
|
|
74
|
-
throw new Error("projectId is
|
|
54
|
+
throw new Error("projectId could not be resolved. Ensure CC_PROJECT_TOKEN is set.");
|
|
75
55
|
const query = `
|
|
76
56
|
mutation SendEmail($projectId: ID!, $email: SendEmailInput!) {
|
|
77
57
|
sendEmail(projectId: $projectId, email: $email)
|
|
@@ -99,12 +79,15 @@ export class EmailClient {
|
|
|
99
79
|
return result.data.sendEmail;
|
|
100
80
|
}
|
|
101
81
|
/**
|
|
102
|
-
*
|
|
82
|
+
* Retrieves a list of inbound emails received by the project.
|
|
83
|
+
*
|
|
84
|
+
* @param options - Filtering and pagination options (limit, before).
|
|
85
|
+
* @returns A promise resolving to an array of InboundEmail previews.
|
|
103
86
|
*/
|
|
104
|
-
async getInbound(options = {}
|
|
105
|
-
const pid =
|
|
87
|
+
async getInbound(options = {}) {
|
|
88
|
+
const pid = this.ccc.projectId;
|
|
106
89
|
if (!pid)
|
|
107
|
-
throw new Error("projectId is
|
|
90
|
+
throw new Error("projectId could not be resolved. Ensure CC_PROJECT_TOKEN is set.");
|
|
108
91
|
const query = `
|
|
109
92
|
query InboundEmails($projectId: ID!, $limit: Int, $before: DateTime) {
|
|
110
93
|
inboundEmails(projectId: $projectId, limit: $limit, before: $before) {
|
|
@@ -137,7 +120,10 @@ export class EmailClient {
|
|
|
137
120
|
return result.data.inboundEmails;
|
|
138
121
|
}
|
|
139
122
|
/**
|
|
140
|
-
*
|
|
123
|
+
* Retrieves the full details of a specific inbound email, including the body.
|
|
124
|
+
*
|
|
125
|
+
* @param emailId - The unique ID of the email.
|
|
126
|
+
* @returns A promise resolving to the full InboundEmail object, or null if not found.
|
|
141
127
|
*/
|
|
142
128
|
async get(emailId) {
|
|
143
129
|
const query = `
|
|
@@ -169,7 +155,10 @@ export class EmailClient {
|
|
|
169
155
|
return result.data.email;
|
|
170
156
|
}
|
|
171
157
|
/**
|
|
172
|
-
*
|
|
158
|
+
* Marks an inbound email as read.
|
|
159
|
+
*
|
|
160
|
+
* @param emailId - The unique ID of the email.
|
|
161
|
+
* @returns A promise resolving to true if successful.
|
|
173
162
|
*/
|
|
174
163
|
async markAsRead(emailId) {
|
|
175
164
|
const query = `
|
|
@@ -190,7 +179,10 @@ export class EmailClient {
|
|
|
190
179
|
return result.data.markEmailAsRead;
|
|
191
180
|
}
|
|
192
181
|
/**
|
|
193
|
-
*
|
|
182
|
+
* Deletes an inbound email permanently.
|
|
183
|
+
*
|
|
184
|
+
* @param emailId - The unique ID of the email.
|
|
185
|
+
* @returns A promise resolving to true if successful.
|
|
194
186
|
*/
|
|
195
187
|
async delete(emailId) {
|
|
196
188
|
const query = `
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an inbound email received by the system.
|
|
3
|
+
*/
|
|
4
|
+
export interface InboundEmail {
|
|
5
|
+
/** Unique ID of the email. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Project ID this email belongs to. */
|
|
8
|
+
projectId: string;
|
|
9
|
+
/** The email address of the sender. */
|
|
10
|
+
sender: string;
|
|
11
|
+
/** The email address of the recipient. */
|
|
12
|
+
recipient: string;
|
|
13
|
+
/** The subject line of the email. */
|
|
14
|
+
subject: string;
|
|
15
|
+
/** A short snippet/preview of the email content. */
|
|
16
|
+
snippet: string;
|
|
17
|
+
/** The full HTML or text body of the email (only available in detailed view). */
|
|
18
|
+
body?: string;
|
|
19
|
+
/** The path to the raw email file in storage. */
|
|
20
|
+
bucketPath: string;
|
|
21
|
+
/** ISO timestamp when the email was received. */
|
|
22
|
+
receivedAt: string;
|
|
23
|
+
/** Whether the email has been marked as read. */
|
|
24
|
+
isRead: boolean;
|
|
25
|
+
/** Whether the email contains attachments. */
|
|
26
|
+
hasAttachments: boolean;
|
|
27
|
+
/** Total size of the raw email in bytes. */
|
|
28
|
+
rawSize: number;
|
|
29
|
+
/** Thread ID for grouping related emails. */
|
|
30
|
+
threadId?: string;
|
|
31
|
+
/** Standard Message-ID header. */
|
|
32
|
+
messageId?: string;
|
|
33
|
+
/** In-Reply-To header. */
|
|
34
|
+
inReplyTo?: string;
|
|
35
|
+
/** References header. */
|
|
36
|
+
references?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for sending an email.
|
|
40
|
+
*/
|
|
41
|
+
export interface SendEmailOptions {
|
|
42
|
+
/**
|
|
43
|
+
* The sender address. Must be a verified domain.
|
|
44
|
+
* Use "Name <email@domain.com>" or just "email@domain.com".
|
|
45
|
+
*/
|
|
46
|
+
from?: string;
|
|
47
|
+
/** The recipient(s). Can be a string or an array of strings. */
|
|
48
|
+
to: string | string[];
|
|
49
|
+
/** The subject line. */
|
|
50
|
+
subject: string;
|
|
51
|
+
/** The HTML body of the email. */
|
|
52
|
+
html?: string;
|
|
53
|
+
/** The plain text body of the email. */
|
|
54
|
+
text?: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,79 +1,100 @@
|
|
|
1
|
-
export interface CCCConfig {
|
|
2
|
-
projectId?: string;
|
|
3
|
-
baseUrl?: string;
|
|
4
|
-
}
|
|
5
|
-
export interface StorageFile {
|
|
6
|
-
id: string;
|
|
7
|
-
projectId: string;
|
|
8
|
-
fileId: string;
|
|
9
|
-
originalFilename?: string;
|
|
10
|
-
contentType: string;
|
|
11
|
-
sizeBytes?: number;
|
|
12
|
-
extension?: string;
|
|
13
|
-
publicUrl: string;
|
|
14
|
-
createdAt: string;
|
|
15
|
-
}
|
|
16
1
|
import { EmailClient } from './email/index.js';
|
|
2
|
+
import { CCCConfig, StorageFile } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The main client for interacting with CloneCommand managed services.
|
|
5
|
+
* This class provides access to storage, email, and authentication features.
|
|
6
|
+
*/
|
|
17
7
|
export declare class CloneCommandCloud {
|
|
18
8
|
private config;
|
|
9
|
+
private _email;
|
|
10
|
+
/**
|
|
11
|
+
* Initializes the SDK with configuration options.
|
|
12
|
+
*
|
|
13
|
+
* @param config - The configuration object.
|
|
14
|
+
*/
|
|
19
15
|
init(config: CCCConfig): void;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current project ID.
|
|
18
|
+
* Resolution order:
|
|
19
|
+
* 1. Manual config via `init()`
|
|
20
|
+
* 2. `CC_PROJECT_ID` environment variable
|
|
21
|
+
* 3. Extracted from the `CC_PROJECT_TOKEN` JWT.
|
|
22
|
+
*/
|
|
20
23
|
get projectId(): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* The base URL for API requests.
|
|
26
|
+
*/
|
|
21
27
|
get baseUrl(): string;
|
|
28
|
+
/**
|
|
29
|
+
* The service token used for authentication.
|
|
30
|
+
* Resolution order:
|
|
31
|
+
* 1. Manual config via `init()`
|
|
32
|
+
* 2. `CC_PROJECT_TOKEN` environment variable.
|
|
33
|
+
*/
|
|
22
34
|
get serviceToken(): string | undefined;
|
|
23
35
|
/**
|
|
24
36
|
* Internal helper to make authenticated requests to the CloneCommand API.
|
|
25
|
-
*
|
|
37
|
+
*
|
|
38
|
+
* @param path - The API path (e.g., '/graphql').
|
|
39
|
+
* @param options - Standard RequestInit options.
|
|
40
|
+
* @returns A promise resolving to the JSON response.
|
|
41
|
+
* @throws Error if the request fails or returns a non-OK status.
|
|
42
|
+
*/
|
|
43
|
+
request<T = any>(path: string, options?: RequestInit): Promise<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Login and authentication utilities.
|
|
26
46
|
*/
|
|
27
|
-
request(path: string, options?: RequestInit): Promise<any>;
|
|
28
47
|
get login(): {
|
|
29
48
|
/**
|
|
30
49
|
* Wraps a standard OAuth authorization URL with the CloneCommand Proxy.
|
|
31
50
|
* This allows ephemeral preview environments (*.clonecommand.app) to handle
|
|
32
51
|
* OAuth redirects without constant provider configuration changes.
|
|
33
52
|
*
|
|
34
|
-
* @param originalUrl The standard OAuth authorization URL
|
|
35
|
-
* @returns The proxied URL to redirect the user to
|
|
53
|
+
* @param originalUrl - The standard OAuth authorization URL.
|
|
54
|
+
* @returns The proxied URL to redirect the user to.
|
|
55
|
+
* @throws Error if projectId is not configured.
|
|
36
56
|
*/
|
|
37
57
|
proxy: (originalUrl: string) => string;
|
|
38
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Storage and file management utilities.
|
|
61
|
+
*/
|
|
39
62
|
get storage(): {
|
|
40
63
|
/**
|
|
41
|
-
*
|
|
64
|
+
* Imports a file from a URL and uploads it to CloneCommand Storage.
|
|
42
65
|
*
|
|
43
|
-
* @param url The URL of the file to import
|
|
44
|
-
* @param contentType Optional content type (auto-detected if not provided)
|
|
45
|
-
* @returns
|
|
66
|
+
* @param url - The URL of the file to import.
|
|
67
|
+
* @param contentType - Optional content type (auto-detected if not provided).
|
|
68
|
+
* @returns A promise resolving to the StorageFile record.
|
|
46
69
|
*
|
|
47
70
|
* @example
|
|
48
71
|
* const file = await ccc.storage.importFileFromUrl('https://example.com/image.png');
|
|
49
|
-
* console.log(file.publicUrl); // https://media.clonecommand.com/:projectId/:fileId/original.png
|
|
50
72
|
*/
|
|
51
73
|
importFileFromUrl: (url: string, contentType?: string) => Promise<StorageFile>;
|
|
52
74
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* @param buffer The file buffer
|
|
56
|
-
* @param contentType The content type of the file
|
|
57
|
-
* @returns StorageFile object with publicUrl
|
|
75
|
+
* Uploads a file from a memory buffer.
|
|
58
76
|
*
|
|
59
|
-
* @
|
|
60
|
-
*
|
|
61
|
-
*
|
|
77
|
+
* @param buffer - The file contents as a Buffer.
|
|
78
|
+
* @param contentType - The MIME type of the file.
|
|
79
|
+
* @param filename - Optional filename.
|
|
80
|
+
* @returns A promise resolving to the StorageFile record.
|
|
62
81
|
*/
|
|
63
82
|
importFileFromBuffer: (buffer: Buffer, contentType: string, filename?: string) => Promise<StorageFile>;
|
|
64
83
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* @param fileId The file ID
|
|
68
|
-
* @param projectSlug Optional project slug (uses projectId from config if not provided)
|
|
69
|
-
* @returns The public URL
|
|
84
|
+
* Generates a public URL for a given file ID.
|
|
70
85
|
*
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
73
|
-
*
|
|
86
|
+
* @param fileId - The unique file ID.
|
|
87
|
+
* @param projectSlug - Optional project slug (automatically resolved from projectId if not provided).
|
|
88
|
+
* @returns The public URL string.
|
|
74
89
|
*/
|
|
75
90
|
getFileUrl: (fileId: string, projectSlug?: string) => string;
|
|
76
91
|
};
|
|
92
|
+
/**
|
|
93
|
+
* Access to email services.
|
|
94
|
+
*/
|
|
77
95
|
get email(): EmailClient;
|
|
78
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Singleton instance of the CloneCommandCloud client.
|
|
99
|
+
*/
|
|
79
100
|
export declare const ccc: CloneCommandCloud;
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import { EmailClient } from './email/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The main client for interacting with CloneCommand managed services.
|
|
4
|
+
* This class provides access to storage, email, and authentication features.
|
|
5
|
+
*/
|
|
2
6
|
export class CloneCommandCloud {
|
|
3
7
|
config = {};
|
|
8
|
+
_email = null;
|
|
9
|
+
/**
|
|
10
|
+
* Initializes the SDK with configuration options.
|
|
11
|
+
*
|
|
12
|
+
* @param config - The configuration object.
|
|
13
|
+
*/
|
|
4
14
|
init(config) {
|
|
5
15
|
this.config = {
|
|
6
16
|
...this.config,
|
|
7
17
|
...config,
|
|
8
18
|
};
|
|
9
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Returns the current project ID.
|
|
22
|
+
* Resolution order:
|
|
23
|
+
* 1. Manual config via `init()`
|
|
24
|
+
* 2. `CC_PROJECT_ID` environment variable
|
|
25
|
+
* 3. Extracted from the `CC_PROJECT_TOKEN` JWT.
|
|
26
|
+
*/
|
|
10
27
|
get projectId() {
|
|
11
28
|
if (this.config.projectId)
|
|
12
29
|
return this.config.projectId;
|
|
@@ -30,15 +47,28 @@ export class CloneCommandCloud {
|
|
|
30
47
|
}
|
|
31
48
|
return undefined;
|
|
32
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* The base URL for API requests.
|
|
52
|
+
*/
|
|
33
53
|
get baseUrl() {
|
|
34
54
|
return this.config.baseUrl || 'https://graph.clonecommand.com';
|
|
35
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* The service token used for authentication.
|
|
58
|
+
* Resolution order:
|
|
59
|
+
* 1. Manual config via `init()`
|
|
60
|
+
* 2. `CC_PROJECT_TOKEN` environment variable.
|
|
61
|
+
*/
|
|
36
62
|
get serviceToken() {
|
|
37
|
-
return typeof process !== 'undefined' ? process.env.CC_PROJECT_TOKEN : undefined;
|
|
63
|
+
return this.config.serviceToken || (typeof process !== 'undefined' ? process.env.CC_PROJECT_TOKEN : undefined);
|
|
38
64
|
}
|
|
39
65
|
/**
|
|
40
66
|
* Internal helper to make authenticated requests to the CloneCommand API.
|
|
41
|
-
*
|
|
67
|
+
*
|
|
68
|
+
* @param path - The API path (e.g., '/graphql').
|
|
69
|
+
* @param options - Standard RequestInit options.
|
|
70
|
+
* @returns A promise resolving to the JSON response.
|
|
71
|
+
* @throws Error if the request fails or returns a non-OK status.
|
|
42
72
|
*/
|
|
43
73
|
async request(path, options = {}) {
|
|
44
74
|
const token = this.serviceToken;
|
|
@@ -56,6 +86,9 @@ export class CloneCommandCloud {
|
|
|
56
86
|
}
|
|
57
87
|
return response.json();
|
|
58
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Login and authentication utilities.
|
|
91
|
+
*/
|
|
59
92
|
get login() {
|
|
60
93
|
return {
|
|
61
94
|
/**
|
|
@@ -63,43 +96,40 @@ export class CloneCommandCloud {
|
|
|
63
96
|
* This allows ephemeral preview environments (*.clonecommand.app) to handle
|
|
64
97
|
* OAuth redirects without constant provider configuration changes.
|
|
65
98
|
*
|
|
66
|
-
* @param originalUrl The standard OAuth authorization URL
|
|
67
|
-
* @returns The proxied URL to redirect the user to
|
|
99
|
+
* @param originalUrl - The standard OAuth authorization URL.
|
|
100
|
+
* @returns The proxied URL to redirect the user to.
|
|
101
|
+
* @throws Error if projectId is not configured.
|
|
68
102
|
*/
|
|
69
103
|
proxy: (originalUrl) => {
|
|
70
104
|
const pid = this.projectId;
|
|
71
105
|
if (!pid) {
|
|
72
|
-
throw new Error("CloneCommand: projectId is required
|
|
73
|
-
"or set the CC_PROJECT_ID environment variable.");
|
|
106
|
+
throw new Error("CloneCommand: projectId is required but could not be resolved from CC_PROJECT_TOKEN or environment. " +
|
|
107
|
+
"Provide it in ccc.init({ projectId }) or set the CC_PROJECT_ID environment variable.");
|
|
74
108
|
}
|
|
75
109
|
const encodedUrl = encodeURIComponent(originalUrl);
|
|
76
110
|
return `${this.baseUrl}/login/proxy/start?projectId=${pid}&url=${encodedUrl}`;
|
|
77
111
|
}
|
|
78
112
|
};
|
|
79
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Storage and file management utilities.
|
|
116
|
+
*/
|
|
80
117
|
get storage() {
|
|
81
118
|
return {
|
|
82
119
|
/**
|
|
83
|
-
*
|
|
120
|
+
* Imports a file from a URL and uploads it to CloneCommand Storage.
|
|
84
121
|
*
|
|
85
|
-
* @param url The URL of the file to import
|
|
86
|
-
* @param contentType Optional content type (auto-detected if not provided)
|
|
87
|
-
* @returns
|
|
122
|
+
* @param url - The URL of the file to import.
|
|
123
|
+
* @param contentType - Optional content type (auto-detected if not provided).
|
|
124
|
+
* @returns A promise resolving to the StorageFile record.
|
|
88
125
|
*
|
|
89
126
|
* @example
|
|
90
127
|
* const file = await ccc.storage.importFileFromUrl('https://example.com/image.png');
|
|
91
|
-
* console.log(file.publicUrl); // https://media.clonecommand.com/:projectId/:fileId/original.png
|
|
92
128
|
*/
|
|
93
129
|
importFileFromUrl: async (url, contentType) => {
|
|
94
|
-
const token = this.serviceToken;
|
|
95
130
|
const pid = this.projectId;
|
|
96
|
-
if (!token) {
|
|
97
|
-
throw new Error("CloneCommand Storage: CC_PROJECT_TOKEN is required. " +
|
|
98
|
-
"Ensure your service is deployed via CloneCommand or use 'clones run' for local development.");
|
|
99
|
-
}
|
|
100
131
|
if (!pid) {
|
|
101
|
-
throw new Error("CloneCommand Storage: projectId is
|
|
102
|
-
"Set CC_PROJECT_ID environment variable or call ccc.init({ projectId }).");
|
|
132
|
+
throw new Error("CloneCommand Storage: projectId could not be resolved. Ensure CC_PROJECT_TOKEN is set.");
|
|
103
133
|
}
|
|
104
134
|
const query = `
|
|
105
135
|
mutation UploadFileFromUrl($projectId: String!, $url: String!, $contentType: String) {
|
|
@@ -118,9 +148,7 @@ export class CloneCommandCloud {
|
|
|
118
148
|
`;
|
|
119
149
|
const result = await this.request('/graphql', {
|
|
120
150
|
method: 'POST',
|
|
121
|
-
headers: {
|
|
122
|
-
'Content-Type': 'application/json',
|
|
123
|
-
},
|
|
151
|
+
headers: { 'Content-Type': 'application/json' },
|
|
124
152
|
body: JSON.stringify({
|
|
125
153
|
query,
|
|
126
154
|
variables: { projectId: pid, url, contentType },
|
|
@@ -132,24 +160,17 @@ export class CloneCommandCloud {
|
|
|
132
160
|
return result.data.uploadFileFromUrl;
|
|
133
161
|
},
|
|
134
162
|
/**
|
|
135
|
-
*
|
|
163
|
+
* Uploads a file from a memory buffer.
|
|
136
164
|
*
|
|
137
|
-
* @param buffer The file
|
|
138
|
-
* @param contentType The
|
|
139
|
-
* @
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* const buffer = fs.readFileSync('image.png');
|
|
143
|
-
* const file = await ccc.storage.importFileFromBuffer(buffer, 'image/png');
|
|
165
|
+
* @param buffer - The file contents as a Buffer.
|
|
166
|
+
* @param contentType - The MIME type of the file.
|
|
167
|
+
* @param filename - Optional filename.
|
|
168
|
+
* @returns A promise resolving to the StorageFile record.
|
|
144
169
|
*/
|
|
145
170
|
importFileFromBuffer: async (buffer, contentType, filename = 'file') => {
|
|
146
|
-
const token = this.serviceToken;
|
|
147
171
|
const pid = this.projectId;
|
|
148
|
-
if (!token) {
|
|
149
|
-
throw new Error("CloneCommand Storage: CC_PROJECT_TOKEN is required.");
|
|
150
|
-
}
|
|
151
172
|
if (!pid) {
|
|
152
|
-
throw new Error("CloneCommand Storage: projectId is
|
|
173
|
+
throw new Error("CloneCommand Storage: projectId could not be resolved. Ensure CC_PROJECT_TOKEN is set.");
|
|
153
174
|
}
|
|
154
175
|
const query = `
|
|
155
176
|
mutation UploadFileFromBuffer($projectId: String!, $buffer: String!, $contentType: String!, $filename: String!) {
|
|
@@ -185,31 +206,33 @@ export class CloneCommandCloud {
|
|
|
185
206
|
return result.data.uploadFileFromBuffer;
|
|
186
207
|
},
|
|
187
208
|
/**
|
|
188
|
-
*
|
|
209
|
+
* Generates a public URL for a given file ID.
|
|
189
210
|
*
|
|
190
|
-
* @param fileId The file ID
|
|
191
|
-
* @param projectSlug Optional project slug (
|
|
192
|
-
* @returns The public URL
|
|
193
|
-
*
|
|
194
|
-
* @example
|
|
195
|
-
* const url = ccc.storage.getFileUrl('abc-123-def', 'my-project');
|
|
196
|
-
* // => https://my-project.clonecommand.media/abc-123-def/original
|
|
211
|
+
* @param fileId - The unique file ID.
|
|
212
|
+
* @param projectSlug - Optional project slug (automatically resolved from projectId if not provided).
|
|
213
|
+
* @returns The public URL string.
|
|
197
214
|
*/
|
|
198
215
|
getFileUrl: (fileId, projectSlug) => {
|
|
199
216
|
const pid = this.projectId;
|
|
200
217
|
const slug = projectSlug || pid;
|
|
201
218
|
if (!slug) {
|
|
202
|
-
throw new Error("CloneCommand Storage: projectId or projectSlug
|
|
203
|
-
"Set CC_PROJECT_ID environment variable or call ccc.init({ projectId }).");
|
|
219
|
+
throw new Error("CloneCommand Storage: projectId or projectSlug could not be resolved.");
|
|
204
220
|
}
|
|
205
|
-
// Note: This returns the default projectslug.clonecommand.media URL
|
|
206
|
-
// Custom domains are handled server-side
|
|
207
221
|
return `https://${slug}.clonecommand.media/${fileId}/original`;
|
|
208
222
|
},
|
|
209
223
|
};
|
|
210
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Access to email services.
|
|
227
|
+
*/
|
|
211
228
|
get email() {
|
|
212
|
-
|
|
229
|
+
if (!this._email) {
|
|
230
|
+
this._email = new EmailClient(this);
|
|
231
|
+
}
|
|
232
|
+
return this._email;
|
|
213
233
|
}
|
|
214
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Singleton instance of the CloneCommandCloud client.
|
|
237
|
+
*/
|
|
215
238
|
export const ccc = new CloneCommandCloud();
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the CloneCommand Cloud SDK.
|
|
3
|
+
*/
|
|
4
|
+
export interface CCCConfig {
|
|
5
|
+
/**
|
|
6
|
+
* The unique identifier for your project.
|
|
7
|
+
* Can also be set via the `CC_PROJECT_ID` environment variable.
|
|
8
|
+
*/
|
|
9
|
+
projectId?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The base URL for the CloneCommand API.
|
|
12
|
+
* Defaults to `https://graph.clonecommand.com`.
|
|
13
|
+
*/
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The service token for authentication.
|
|
17
|
+
* Can also be set via the `CC_PROJECT_TOKEN` environment variable.
|
|
18
|
+
*/
|
|
19
|
+
serviceToken?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Represents a file stored in CloneCommand Storage.
|
|
23
|
+
*/
|
|
24
|
+
export interface StorageFile {
|
|
25
|
+
/** Unique ID of the storage record. */
|
|
26
|
+
id: string;
|
|
27
|
+
/** Project ID this file belongs to. */
|
|
28
|
+
projectId: string;
|
|
29
|
+
/** The underlying storage provider's file ID. */
|
|
30
|
+
fileId: string;
|
|
31
|
+
/** Original filename if available. */
|
|
32
|
+
originalFilename?: string;
|
|
33
|
+
/** MIME type of the file. */
|
|
34
|
+
contentType: string;
|
|
35
|
+
/** Size of the file in bytes. */
|
|
36
|
+
sizeBytes?: number;
|
|
37
|
+
/** File extension. */
|
|
38
|
+
extension?: string;
|
|
39
|
+
/** Publicly accessible URL for the file. */
|
|
40
|
+
publicUrl: string;
|
|
41
|
+
/** ISO timestamp when the file was uploaded. */
|
|
42
|
+
createdAt: string;
|
|
43
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/docs/email.md
CHANGED
|
@@ -10,17 +10,17 @@ Managed email sending and receiving with inbound processing and domain verificat
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Checking Status
|
|
14
14
|
|
|
15
|
-
Check if email is enabled for the current project.
|
|
15
|
+
Check if the email service is enabled and ready to use for the current project.
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
18
|
import { ccc } from '@clonecommand/cloud';
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const enabled = await ccc.email.isEnabled();
|
|
21
21
|
|
|
22
|
-
if (
|
|
23
|
-
console.log('Email is active!');
|
|
22
|
+
if (enabled) {
|
|
23
|
+
console.log('Email is active and ready to send!');
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clonecommand/cloud",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The official SDK for CloneCommand managed services",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./email": {
|
|
14
|
+
"types": "./dist/email/index.d.ts",
|
|
15
|
+
"import": "./dist/email/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
8
18
|
"files": [
|
|
9
19
|
"dist",
|
|
10
20
|
"README.md",
|