replylayer 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.
Files changed (65) hide show
  1. package/dist/api-client.d.ts +54 -0
  2. package/dist/api-client.d.ts.map +1 -0
  3. package/dist/api-client.js +185 -0
  4. package/dist/api-client.js.map +1 -0
  5. package/dist/auth.d.ts +33 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +85 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/bin/replylayer.d.ts +3 -0
  10. package/dist/bin/replylayer.d.ts.map +1 -0
  11. package/dist/bin/replylayer.js +4 -0
  12. package/dist/bin/replylayer.js.map +1 -0
  13. package/dist/commands/account.d.ts +3 -0
  14. package/dist/commands/account.d.ts.map +1 -0
  15. package/dist/commands/account.js +47 -0
  16. package/dist/commands/account.js.map +1 -0
  17. package/dist/commands/api-key.d.ts +3 -0
  18. package/dist/commands/api-key.d.ts.map +1 -0
  19. package/dist/commands/api-key.js +75 -0
  20. package/dist/commands/api-key.js.map +1 -0
  21. package/dist/commands/auth.d.ts +3 -0
  22. package/dist/commands/auth.d.ts.map +1 -0
  23. package/dist/commands/auth.js +115 -0
  24. package/dist/commands/auth.js.map +1 -0
  25. package/dist/commands/inbox.d.ts +3 -0
  26. package/dist/commands/inbox.d.ts.map +1 -0
  27. package/dist/commands/inbox.js +95 -0
  28. package/dist/commands/inbox.js.map +1 -0
  29. package/dist/commands/mailbox.d.ts +3 -0
  30. package/dist/commands/mailbox.d.ts.map +1 -0
  31. package/dist/commands/mailbox.js +113 -0
  32. package/dist/commands/mailbox.js.map +1 -0
  33. package/dist/commands/recipients.d.ts +3 -0
  34. package/dist/commands/recipients.d.ts.map +1 -0
  35. package/dist/commands/recipients.js +50 -0
  36. package/dist/commands/recipients.js.map +1 -0
  37. package/dist/commands/reply.d.ts +3 -0
  38. package/dist/commands/reply.d.ts.map +1 -0
  39. package/dist/commands/reply.js +23 -0
  40. package/dist/commands/reply.js.map +1 -0
  41. package/dist/commands/send.d.ts +3 -0
  42. package/dist/commands/send.d.ts.map +1 -0
  43. package/dist/commands/send.js +28 -0
  44. package/dist/commands/send.js.map +1 -0
  45. package/dist/commands/signup.d.ts +3 -0
  46. package/dist/commands/signup.d.ts.map +1 -0
  47. package/dist/commands/signup.js +50 -0
  48. package/dist/commands/signup.js.map +1 -0
  49. package/dist/format.d.ts +26 -0
  50. package/dist/format.d.ts.map +1 -0
  51. package/dist/format.js +153 -0
  52. package/dist/format.js.map +1 -0
  53. package/dist/index.d.ts +7 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +77 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/resolve.d.ts +14 -0
  58. package/dist/resolve.d.ts.map +1 -0
  59. package/dist/resolve.js +36 -0
  60. package/dist/resolve.js.map +1 -0
  61. package/dist/types.d.ts +48 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +15 -0
  64. package/dist/types.js.map +1 -0
  65. package/package.json +41 -0
@@ -0,0 +1,54 @@
1
+ import type { SignupResponse, RotateKeyResponse, CreateMailboxResponse, ListMailboxesResponse, SendMessageRequest, SendMessageResponse, ListMessagesResponse, GetMessageResponse, ReplyRequest, WaitResponse, ListRecipientsResponse, HealthResponse } from '@replylayer/shared/types';
2
+ import type { AddRecipientResponse, DeleteMailboxResponse, UpdateMailboxResponse, ScannerPolicy, CreateApiKeyResponse, ListApiKeysResponse, RevokeApiKeyResponse } from './types.js';
3
+ export interface ApiClientOptions {
4
+ baseUrl: string;
5
+ apiKey?: string;
6
+ }
7
+ export declare class ApiClient {
8
+ private baseUrl;
9
+ private apiKey?;
10
+ constructor(options: ApiClientOptions);
11
+ private headers;
12
+ private request;
13
+ private doFetch;
14
+ private handleError;
15
+ signup(email: string): Promise<SignupResponse>;
16
+ deleteAccount(): Promise<{
17
+ status: string;
18
+ message: string;
19
+ }>;
20
+ rotateKey(): Promise<RotateKeyResponse>;
21
+ createMailbox(name: string): Promise<CreateMailboxResponse>;
22
+ listMailboxes(): Promise<ListMailboxesResponse>;
23
+ deleteMailbox(id: string): Promise<DeleteMailboxResponse>;
24
+ updateMailbox(id: string, body: {
25
+ scanner_policy: ScannerPolicy;
26
+ }): Promise<UpdateMailboxResponse>;
27
+ send(req: SendMessageRequest): Promise<SendMessageResponse>;
28
+ listMessages(mailboxId: string, opts?: {
29
+ unread?: boolean;
30
+ limit?: number;
31
+ before?: string;
32
+ sender?: string;
33
+ since?: string;
34
+ until?: string;
35
+ search?: string;
36
+ status?: string;
37
+ direction?: string;
38
+ }): Promise<ListMessagesResponse>;
39
+ getMessage(id: string): Promise<GetMessageResponse>;
40
+ reply(messageId: string, req: ReplyRequest): Promise<SendMessageResponse>;
41
+ waitForMessage(mailboxId: string, timeout?: number): Promise<WaitResponse>;
42
+ addRecipient(email: string): Promise<AddRecipientResponse>;
43
+ listRecipients(): Promise<ListRecipientsResponse>;
44
+ deleteRecipient(id: string): Promise<void>;
45
+ createApiKey(body: {
46
+ role: 'admin' | 'agent';
47
+ label?: string;
48
+ mailbox_ids?: string[];
49
+ }): Promise<CreateApiKeyResponse>;
50
+ listApiKeys(): Promise<ListApiKeysResponse>;
51
+ revokeApiKey(id: string): Promise<RevokeApiKeyResponse>;
52
+ health(): Promise<HealthResponse>;
53
+ }
54
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { ApiError } from './types.js';
2
+ export class ApiClient {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(options) {
6
+ // Remove trailing slash
7
+ this.baseUrl = options.baseUrl.replace(/\/+$/, '');
8
+ this.apiKey = options.apiKey;
9
+ }
10
+ headers(auth = true) {
11
+ const h = {
12
+ 'Content-Type': 'application/json',
13
+ };
14
+ if (auth && this.apiKey) {
15
+ h['Authorization'] = `Bearer ${this.apiKey}`;
16
+ }
17
+ return h;
18
+ }
19
+ async request(method, path, options = {}) {
20
+ const { body, auth = true, query, signal } = options;
21
+ let url = `${this.baseUrl}${path}`;
22
+ if (query) {
23
+ const params = new URLSearchParams();
24
+ for (const [k, v] of Object.entries(query)) {
25
+ if (v !== undefined && v !== '') {
26
+ params.set(k, v);
27
+ }
28
+ }
29
+ const qs = params.toString();
30
+ if (qs)
31
+ url += `?${qs}`;
32
+ }
33
+ const fetchOptions = {
34
+ method,
35
+ headers: this.headers(auth),
36
+ signal,
37
+ };
38
+ if (body !== undefined) {
39
+ fetchOptions.body = JSON.stringify(body);
40
+ }
41
+ // First attempt
42
+ let response = await this.doFetch(url, fetchOptions);
43
+ // One retry on 5xx
44
+ if (response.status >= 500) {
45
+ await new Promise((resolve) => setTimeout(resolve, 1000));
46
+ response = await this.doFetch(url, fetchOptions);
47
+ }
48
+ if (!response.ok) {
49
+ await this.handleError(response);
50
+ }
51
+ // For 204 No Content
52
+ if (response.status === 204) {
53
+ return undefined;
54
+ }
55
+ const text = await response.text();
56
+ if (!text) {
57
+ return undefined;
58
+ }
59
+ try {
60
+ return JSON.parse(text);
61
+ }
62
+ catch {
63
+ throw new ApiError(response.status, 'PARSE_ERROR', `Failed to parse response: ${text.substring(0, 200)}`);
64
+ }
65
+ }
66
+ async doFetch(url, options) {
67
+ try {
68
+ return await fetch(url, options);
69
+ }
70
+ catch (err) {
71
+ const message = err instanceof Error ? err.message : 'Unknown network error';
72
+ throw new ApiError(0, 'NETWORK_ERROR', `Network error: ${message}`);
73
+ }
74
+ }
75
+ async handleError(response) {
76
+ let errorBody = {};
77
+ try {
78
+ const text = await response.text();
79
+ if (text) {
80
+ errorBody = JSON.parse(text);
81
+ }
82
+ }
83
+ catch {
84
+ // Non-JSON error response
85
+ }
86
+ throw new ApiError(response.status, errorBody.code || `HTTP_${response.status}`, errorBody.error || `Request failed with status ${response.status}`, errorBody.details);
87
+ }
88
+ // === Account endpoints ===
89
+ async signup(email) {
90
+ return this.request('POST', '/v1/accounts/signup', {
91
+ body: { email, accept_terms: true },
92
+ auth: false,
93
+ });
94
+ }
95
+ async deleteAccount() {
96
+ return this.request('DELETE', '/v1/accounts');
97
+ }
98
+ async rotateKey() {
99
+ return this.request('POST', '/v1/accounts/api-keys/rotate');
100
+ }
101
+ // === Mailbox endpoints ===
102
+ async createMailbox(name) {
103
+ return this.request('POST', '/v1/mailboxes', {
104
+ body: { name },
105
+ });
106
+ }
107
+ async listMailboxes() {
108
+ return this.request('GET', '/v1/mailboxes');
109
+ }
110
+ async deleteMailbox(id) {
111
+ return this.request('DELETE', `/v1/mailboxes/${id}`);
112
+ }
113
+ async updateMailbox(id, body) {
114
+ return this.request('PATCH', `/v1/mailboxes/${id}`, { body });
115
+ }
116
+ // === Message endpoints ===
117
+ async send(req) {
118
+ return this.request('POST', '/v1/messages/send', {
119
+ body: req,
120
+ });
121
+ }
122
+ async listMessages(mailboxId, opts) {
123
+ const query = {};
124
+ if (opts?.unread)
125
+ query['unread'] = 'true';
126
+ if (opts?.limit)
127
+ query['limit'] = String(opts.limit);
128
+ if (opts?.before)
129
+ query['before'] = opts.before;
130
+ if (opts?.sender)
131
+ query['sender'] = opts.sender;
132
+ if (opts?.since)
133
+ query['since'] = opts.since;
134
+ if (opts?.until)
135
+ query['until'] = opts.until;
136
+ if (opts?.search)
137
+ query['search'] = opts.search;
138
+ if (opts?.status)
139
+ query['status'] = opts.status;
140
+ if (opts?.direction)
141
+ query['direction'] = opts.direction;
142
+ return this.request('GET', `/v1/mailboxes/${mailboxId}/messages`, { query });
143
+ }
144
+ async getMessage(id) {
145
+ return this.request('GET', `/v1/messages/${id}`);
146
+ }
147
+ async reply(messageId, req) {
148
+ return this.request('POST', `/v1/messages/${messageId}/reply`, { body: req });
149
+ }
150
+ async waitForMessage(mailboxId, timeout = 30) {
151
+ // Use a request timeout of poll timeout + 5s buffer for network overhead.
152
+ // Without this, a hung API would block the CLI indefinitely.
153
+ return this.request('GET', `/v1/mailboxes/${mailboxId}/messages/wait`, {
154
+ query: { timeout: String(timeout) },
155
+ signal: AbortSignal.timeout((timeout + 5) * 1000),
156
+ });
157
+ }
158
+ // === Recipient endpoints ===
159
+ async addRecipient(email) {
160
+ return this.request('POST', '/v1/recipients', {
161
+ body: { email },
162
+ });
163
+ }
164
+ async listRecipients() {
165
+ return this.request('GET', '/v1/recipients');
166
+ }
167
+ async deleteRecipient(id) {
168
+ return this.request('DELETE', `/v1/recipients/${id}`);
169
+ }
170
+ // === API Key Management ===
171
+ async createApiKey(body) {
172
+ return this.request('POST', '/v1/accounts/api-keys', { body });
173
+ }
174
+ async listApiKeys() {
175
+ return this.request('GET', '/v1/accounts/api-keys');
176
+ }
177
+ async revokeApiKey(id) {
178
+ return this.request('DELETE', `/v1/accounts/api-keys/${id}`);
179
+ }
180
+ // === Health ===
181
+ async health() {
182
+ return this.request('GET', '/v1/health', { auth: false });
183
+ }
184
+ }
185
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ export type KeySource = 'flag' | 'env' | 'file' | 'none';
2
+ export interface ResolvedKey {
3
+ apiKey: string | null;
4
+ source: KeySource;
5
+ }
6
+ /**
7
+ * Resolve the API key using the priority order:
8
+ * 1. --api-key flag (passed explicitly)
9
+ * 2. REPLYLAYER_API_KEY environment variable
10
+ * 3. ~/.replylayer/credentials file
11
+ */
12
+ export declare function resolveApiKey(flagValue?: string): ResolvedKey;
13
+ /**
14
+ * Read the API key from the credential file.
15
+ */
16
+ export declare function readCredentialFile(): string | null;
17
+ /**
18
+ * Store an API key in the credential file with 0600 permissions.
19
+ */
20
+ export declare function storeApiKey(apiKey: string): void;
21
+ /**
22
+ * Delete the credential file (logout).
23
+ */
24
+ export declare function deleteCredentialFile(): boolean;
25
+ /**
26
+ * Get the path to the credential file (for display purposes).
27
+ */
28
+ export declare function getCredentialFilePath(): string;
29
+ /**
30
+ * Require an API key or exit with an error message.
31
+ */
32
+ export declare function requireApiKey(flagValue?: string): string;
33
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,SAAS,CAAC;CACnB;AAUD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAgB7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAOlD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMhD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAaxD"}
package/dist/auth.js ADDED
@@ -0,0 +1,85 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ function credentialsDir() {
5
+ return path.join(os.homedir(), '.replylayer');
6
+ }
7
+ function credentialsFile() {
8
+ return path.join(credentialsDir(), 'credentials');
9
+ }
10
+ /**
11
+ * Resolve the API key using the priority order:
12
+ * 1. --api-key flag (passed explicitly)
13
+ * 2. REPLYLAYER_API_KEY environment variable
14
+ * 3. ~/.replylayer/credentials file
15
+ */
16
+ export function resolveApiKey(flagValue) {
17
+ if (flagValue) {
18
+ return { apiKey: flagValue, source: 'flag' };
19
+ }
20
+ const envKey = process.env['REPLYLAYER_API_KEY'];
21
+ if (envKey) {
22
+ return { apiKey: envKey, source: 'env' };
23
+ }
24
+ const fileKey = readCredentialFile();
25
+ if (fileKey) {
26
+ return { apiKey: fileKey, source: 'file' };
27
+ }
28
+ return { apiKey: null, source: 'none' };
29
+ }
30
+ /**
31
+ * Read the API key from the credential file.
32
+ */
33
+ export function readCredentialFile() {
34
+ try {
35
+ const content = fs.readFileSync(credentialsFile(), 'utf-8').trim();
36
+ return content || null;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * Store an API key in the credential file with 0600 permissions.
44
+ */
45
+ export function storeApiKey(apiKey) {
46
+ const dir = credentialsDir();
47
+ if (!fs.existsSync(dir)) {
48
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
49
+ }
50
+ fs.writeFileSync(credentialsFile(), apiKey + '\n', { mode: 0o600 });
51
+ }
52
+ /**
53
+ * Delete the credential file (logout).
54
+ */
55
+ export function deleteCredentialFile() {
56
+ try {
57
+ fs.unlinkSync(credentialsFile());
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Get the path to the credential file (for display purposes).
66
+ */
67
+ export function getCredentialFilePath() {
68
+ return credentialsFile();
69
+ }
70
+ /**
71
+ * Require an API key or exit with an error message.
72
+ */
73
+ export function requireApiKey(flagValue) {
74
+ const { apiKey } = resolveApiKey(flagValue);
75
+ if (!apiKey) {
76
+ console.error('Error: No API key configured.\n\n' +
77
+ 'Set your API key using one of:\n' +
78
+ ' replylayer auth login\n' +
79
+ ' --api-key <key>\n' +
80
+ ' REPLYLAYER_API_KEY environment variable');
81
+ process.exit(1);
82
+ }
83
+ return apiKey;
84
+ }
85
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AASzB,SAAS,cAAc;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,SAAkB;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,OAAO,OAAO,IAAI,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,SAAkB;IAC9C,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,mCAAmC;YACjC,kCAAkC;YAClC,2BAA2B;YAC3B,qBAAqB;YACrB,2CAA2C,CAC9C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=replylayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replylayer.d.ts","sourceRoot":"","sources":["../../src/bin/replylayer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { run } from '../index.js';
3
+ run();
4
+ //# sourceMappingURL=replylayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replylayer.js","sourceRoot":"","sources":["../../src/bin/replylayer.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function accountCommand(): Command;
3
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,cAAc,IAAI,OAAO,CAMxC"}
@@ -0,0 +1,47 @@
1
+ import { Command } from 'commander';
2
+ import readline from 'node:readline';
3
+ import { ApiClient } from '../api-client.js';
4
+ import { requireApiKey, deleteCredentialFile } from '../auth.js';
5
+ import { output } from '../format.js';
6
+ export function accountCommand() {
7
+ const account = new Command('account').description('Manage your ReplyLayer account');
8
+ account.addCommand(deleteCommand());
9
+ return account;
10
+ }
11
+ function deleteCommand() {
12
+ return new Command('delete')
13
+ .description('Delete your account (30-day grace period before permanent erasure)')
14
+ .option('--confirm', 'Skip confirmation prompt')
15
+ .action(async (_opts, cmd) => {
16
+ const opts = cmd.optsWithGlobals();
17
+ const localOpts = cmd.opts();
18
+ const apiKey = requireApiKey(opts.apiKey);
19
+ if (!localOpts.confirm) {
20
+ const confirmed = await promptConfirmation('This will schedule your account for deletion.\n' +
21
+ 'You have 30 days to contact support to reinstate.\n' +
22
+ 'All mailboxes, messages, and data will be permanently erased.\n\n' +
23
+ 'Type "delete" to confirm: ');
24
+ if (confirmed !== 'delete') {
25
+ console.error('Aborted.');
26
+ process.exit(1);
27
+ }
28
+ }
29
+ const client = new ApiClient({ baseUrl: opts.apiUrl, apiKey });
30
+ const result = await client.deleteAccount();
31
+ deleteCredentialFile();
32
+ output(result, `${result.message}\nLocal credentials removed.`, opts.json);
33
+ });
34
+ }
35
+ function promptConfirmation(message) {
36
+ return new Promise((resolve) => {
37
+ const rl = readline.createInterface({
38
+ input: process.stdin,
39
+ output: process.stderr,
40
+ });
41
+ rl.question(message, (answer) => {
42
+ rl.close();
43
+ resolve(answer.trim());
44
+ });
45
+ });
46
+ }
47
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,gCAAgC,CAAC,CAAC;IAErF,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;IAEpC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,oEAAoE,CAAC;SACjF,MAAM,CAAC,WAAW,EAAE,0BAA0B,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CACxC,iDAAiD;gBACjD,qDAAqD;gBACrD,mEAAmE;gBACnE,4BAA4B,CAC7B,CAAC;YACF,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAE5C,oBAAoB,EAAE,CAAC;QAEvB,MAAM,CACJ,MAAM,EACN,GAAG,MAAM,CAAC,OAAO,8BAA8B,EAC/C,IAAI,CAAC,IAAI,CACV,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe;IACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function apiKeyCommand(): Command;
3
+ //# sourceMappingURL=api-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key.d.ts","sourceRoot":"","sources":["../../src/commands/api-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,aAAa,IAAI,OAAO,CAQvC"}
@@ -0,0 +1,75 @@
1
+ import { Command } from 'commander';
2
+ import { ApiClient } from '../api-client.js';
3
+ import { requireApiKey } from '../auth.js';
4
+ import { resolveMailboxId } from '../resolve.js';
5
+ import { formatTable, output } from '../format.js';
6
+ function collectMailbox(value, prev) {
7
+ return [...prev, value];
8
+ }
9
+ export function apiKeyCommand() {
10
+ const apiKey = new Command('api-key').description('Manage API keys');
11
+ apiKey.addCommand(createCommand());
12
+ apiKey.addCommand(listCommand());
13
+ apiKey.addCommand(revokeCommand());
14
+ return apiKey;
15
+ }
16
+ function createCommand() {
17
+ return new Command('create')
18
+ .description('Create a new API key')
19
+ .requiredOption('--role <role>', 'Key role: admin or agent')
20
+ .option('--label <label>', 'Human-readable label')
21
+ .option('--mailbox <name-or-id>', 'Mailbox binding (repeat for multiple: --mailbox a --mailbox b)', collectMailbox, [])
22
+ .action(async (_opts, cmd) => {
23
+ const opts = cmd.optsWithGlobals();
24
+ const localOpts = cmd.opts();
25
+ const key = requireApiKey(opts.apiKey);
26
+ const client = new ApiClient({ baseUrl: opts.apiUrl, apiKey: key });
27
+ // Resolve mailbox names to IDs
28
+ const mailboxNames = localOpts.mailbox;
29
+ let mailboxIds;
30
+ if (mailboxNames.length > 0) {
31
+ mailboxIds = [];
32
+ for (const nameOrId of mailboxNames) {
33
+ mailboxIds.push(await resolveMailboxId(client, nameOrId));
34
+ }
35
+ }
36
+ const result = await client.createApiKey({
37
+ role: localOpts.role,
38
+ label: localOpts.label,
39
+ mailbox_ids: mailboxIds,
40
+ });
41
+ output(result, `Created ${result.role} API key: ${result.api_key}\nKey ID: ${result.id}${result.label ? `\nLabel: ${result.label}` : ''}`, opts.json);
42
+ });
43
+ }
44
+ function listCommand() {
45
+ return new Command('list')
46
+ .description('List all API keys')
47
+ .action(async (_opts, cmd) => {
48
+ const opts = cmd.optsWithGlobals();
49
+ const key = requireApiKey(opts.apiKey);
50
+ const client = new ApiClient({ baseUrl: opts.apiUrl, apiKey: key });
51
+ const result = await client.listApiKeys();
52
+ const table = formatTable(['ID', 'PREFIX', 'ROLE', 'LABEL', 'STATUS', 'CREATED'], result.keys.map((k) => [
53
+ k.id.slice(0, 8) + '...',
54
+ k.prefix,
55
+ k.role ?? 'admin',
56
+ k.label ?? '-',
57
+ k.status,
58
+ k.created_at.split('T')[0],
59
+ ]));
60
+ output(result, table, opts.json);
61
+ });
62
+ }
63
+ function revokeCommand() {
64
+ return new Command('revoke')
65
+ .description('Revoke an API key')
66
+ .argument('<key-id>', 'API key UUID to revoke')
67
+ .action(async (keyId, _opts, cmd) => {
68
+ const opts = cmd.optsWithGlobals();
69
+ const key = requireApiKey(opts.apiKey);
70
+ const client = new ApiClient({ baseUrl: opts.apiUrl, apiKey: key });
71
+ await client.revokeApiKey(keyId);
72
+ output({ status: 'revoked' }, `Revoked API key: ${keyId}`, opts.json);
73
+ });
74
+ }
75
+ //# sourceMappingURL=api-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key.js","sourceRoot":"","sources":["../../src/commands/api-key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function authCommand(): Command;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,WAAW,IAAI,OAAO,CASrC"}