@mailmodo/cli 0.0.52 → 0.0.54-beta.pr56.86
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/dist/commands/billing/index.js +1 -0
- package/dist/commands/deploy/index.d.ts +1 -32
- package/dist/commands/deploy/index.js +49 -304
- package/dist/commands/edit/index.js +1 -0
- package/dist/commands/init/index.js +3 -9
- package/dist/commands/login/index.js +17 -2
- package/dist/commands/sdk/index.d.ts +14 -0
- package/dist/commands/sdk/index.js +74 -0
- package/dist/commands/settings/index.js +7 -10
- package/dist/lib/api-client.d.ts +5 -0
- package/dist/lib/api-client.js +45 -0
- package/dist/lib/base-command.d.ts +24 -1
- package/dist/lib/base-command.js +84 -5
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +5 -0
- package/dist/lib/deploy/domain-setup.d.ts +8 -0
- package/dist/lib/deploy/domain-setup.js +80 -0
- package/dist/lib/deploy/missing-templates.d.ts +4 -0
- package/dist/lib/deploy/missing-templates.js +57 -0
- package/dist/lib/deploy/output.d.ts +5 -0
- package/dist/lib/deploy/output.js +61 -0
- package/dist/lib/deploy/payload.d.ts +41 -0
- package/dist/lib/deploy/payload.js +95 -0
- package/dist/lib/deploy/sequence-status.d.ts +3 -0
- package/dist/lib/deploy/sequence-status.js +56 -0
- package/dist/lib/deploy/types.d.ts +86 -0
- package/dist/lib/deploy/types.js +1 -0
- package/dist/lib/messages.d.ts +9 -0
- package/dist/lib/messages.js +9 -0
- package/dist/lib/utils.d.ts +11 -0
- package/dist/lib/utils.js +40 -0
- package/oclif.manifest.json +48 -1
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { loadTemplate, } from '../yaml-config.js';
|
|
2
|
+
import { DEFAULT_BRAND_COLOR } from '../constants.js';
|
|
3
|
+
export function mapEmailToPayload(email) {
|
|
4
|
+
return {
|
|
5
|
+
condition: email.condition || null,
|
|
6
|
+
ctaText: email.ctaText || '',
|
|
7
|
+
delay: email.delay,
|
|
8
|
+
goal: email.goal || '',
|
|
9
|
+
id: email.id,
|
|
10
|
+
isReminder: false,
|
|
11
|
+
previewText: email.previewText || '',
|
|
12
|
+
priority: 'medium',
|
|
13
|
+
subject: email.subject,
|
|
14
|
+
trigger: email.trigger,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function buildBrandSection(project) {
|
|
18
|
+
return {
|
|
19
|
+
colors: [project?.brandColor || DEFAULT_BRAND_COLOR],
|
|
20
|
+
logoUrl: project?.logoUrl || '',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function buildProductSection(project) {
|
|
24
|
+
return {
|
|
25
|
+
businessType: project?.type || '',
|
|
26
|
+
description: project?.description || '',
|
|
27
|
+
pricingModel: project?.pricingModel || '',
|
|
28
|
+
productName: project?.name || '',
|
|
29
|
+
saasModel: project?.saasModel || '',
|
|
30
|
+
targetUser: project?.targetUser || '',
|
|
31
|
+
url: project?.url || '',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function buildSenderSection(project) {
|
|
35
|
+
return {
|
|
36
|
+
address: project?.address || '',
|
|
37
|
+
domain: project?.domain || '',
|
|
38
|
+
fromEmail: project?.fromEmail || '',
|
|
39
|
+
fromName: project?.fromName || '',
|
|
40
|
+
replyTo: project?.replyTo || project?.fromEmail || '',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function buildProjectPayload(project, monthlyCap) {
|
|
44
|
+
return {
|
|
45
|
+
brand: buildBrandSection(project),
|
|
46
|
+
emailStyle: project?.emailStyle || 'branded',
|
|
47
|
+
...(monthlyCap === undefined ? {} : { monthlyCap }),
|
|
48
|
+
product: buildProductSection(project),
|
|
49
|
+
senderDetails: buildSenderSection(project),
|
|
50
|
+
...(project?.webhookUrl ? { webhookUrl: project.webhookUrl } : {}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function buildRegeneratePayload(yamlConfig, missingIds) {
|
|
54
|
+
const { emails, project } = yamlConfig;
|
|
55
|
+
const idSet = new Set(missingIds);
|
|
56
|
+
const targets = emails.filter((e) => idSet.has(e.id));
|
|
57
|
+
return {
|
|
58
|
+
brand: {
|
|
59
|
+
color: project.brandColor || DEFAULT_BRAND_COLOR,
|
|
60
|
+
logoUrl: project.logoUrl || '',
|
|
61
|
+
},
|
|
62
|
+
businessType: project.type || '',
|
|
63
|
+
description: project.description || '',
|
|
64
|
+
events: [...new Set(targets.map((e) => e.trigger))],
|
|
65
|
+
pricingModel: project.pricingModel || '',
|
|
66
|
+
productName: project.name || '',
|
|
67
|
+
recommendedEmails: targets.map((e) => ({
|
|
68
|
+
condition: e.condition || null,
|
|
69
|
+
delay: String(e.delay ?? '0'),
|
|
70
|
+
goal: e.goal || '',
|
|
71
|
+
id: e.id,
|
|
72
|
+
isReminder: false,
|
|
73
|
+
priority: 'medium',
|
|
74
|
+
trigger: e.trigger,
|
|
75
|
+
})),
|
|
76
|
+
saasModel: project.saasModel || '',
|
|
77
|
+
targetUser: project.targetUser || '',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export async function buildDeployPayload(ctx, yamlConfig) {
|
|
81
|
+
const [emailsWithHtml, monthlyCap] = await Promise.all([
|
|
82
|
+
Promise.all(yamlConfig.emails.map(async (email) => {
|
|
83
|
+
const html = (await loadTemplate(`${email.id}.html`)) || '';
|
|
84
|
+
const plainHtml = (await loadTemplate(`${email.id}_plain.html`)) || html;
|
|
85
|
+
return { ...mapEmailToPayload(email), html, plainHtml };
|
|
86
|
+
})),
|
|
87
|
+
yamlConfig.project.monthlyCap === undefined
|
|
88
|
+
? ctx.getBillingCap()
|
|
89
|
+
: Promise.resolve(yamlConfig.project.monthlyCap),
|
|
90
|
+
]);
|
|
91
|
+
return {
|
|
92
|
+
...buildProjectPayload(yamlConfig.project, monthlyCap),
|
|
93
|
+
emails: emailsWithHtml,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DeployCtx, DeployFlags } from './types.js';
|
|
2
|
+
export declare function pauseSequence(ctx: DeployCtx, sequenceId: string, flags: DeployFlags): Promise<void>;
|
|
3
|
+
export declare function resumeSequence(ctx: DeployCtx, sequenceId: string, flags: DeployFlags): Promise<void>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import { API_ENDPOINTS } from '../constants.js';
|
|
3
|
+
import { INFO, pauseAlready, pauseSuccess, PROMPTS, resumeAlready, resumeSuccess, } from '../messages.js';
|
|
4
|
+
function sequenceStatusPath(sequenceId) {
|
|
5
|
+
return `${API_ENDPOINTS.SEQUENCES}/${encodeURIComponent(sequenceId)}/status`;
|
|
6
|
+
}
|
|
7
|
+
async function updateSequenceStatus(ctx, opts) {
|
|
8
|
+
const response = await ctx.spinner(opts.spinnerText, opts.flags.json, () => ctx.post(sequenceStatusPath(opts.sequenceId), {
|
|
9
|
+
status: opts.status,
|
|
10
|
+
}));
|
|
11
|
+
if (!response.ok)
|
|
12
|
+
ctx.onApiError(response);
|
|
13
|
+
return response.data;
|
|
14
|
+
}
|
|
15
|
+
export async function pauseSequence(ctx, sequenceId, flags) {
|
|
16
|
+
if (!flags.yes) {
|
|
17
|
+
const confirmed = await confirm({
|
|
18
|
+
default: false,
|
|
19
|
+
message: PROMPTS.PAUSE_CONFIRM,
|
|
20
|
+
});
|
|
21
|
+
if (!confirmed) {
|
|
22
|
+
ctx.log(`\n ${INFO.PAUSE_CANCELLED}\n`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const data = await updateSequenceStatus(ctx, {
|
|
27
|
+
flags,
|
|
28
|
+
sequenceId,
|
|
29
|
+
spinnerText: ' Pausing sequence...',
|
|
30
|
+
status: 'paused',
|
|
31
|
+
});
|
|
32
|
+
if (flags.json) {
|
|
33
|
+
ctx.log(JSON.stringify(data, null, 2));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const msg = data.alreadyInStatus
|
|
37
|
+
? pauseAlready(data.sequenceId || sequenceId)
|
|
38
|
+
: pauseSuccess(data.sequenceId || sequenceId);
|
|
39
|
+
ctx.log(`\n ${msg}\n`);
|
|
40
|
+
}
|
|
41
|
+
export async function resumeSequence(ctx, sequenceId, flags) {
|
|
42
|
+
const data = await updateSequenceStatus(ctx, {
|
|
43
|
+
flags,
|
|
44
|
+
sequenceId,
|
|
45
|
+
spinnerText: ' Resuming sequence...',
|
|
46
|
+
status: 'active',
|
|
47
|
+
});
|
|
48
|
+
if (flags.json) {
|
|
49
|
+
ctx.log(JSON.stringify(data, null, 2));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const msg = data.alreadyInStatus
|
|
53
|
+
? resumeAlready(data.sequenceId || sequenceId)
|
|
54
|
+
: resumeSuccess(data.sequenceId || sequenceId);
|
|
55
|
+
ctx.log(`\n ${msg}\n`);
|
|
56
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ApiResponse } from '../api-client.js';
|
|
2
|
+
import type { MailmodoYaml } from '../yaml-config.js';
|
|
3
|
+
export interface EmailDiffEntry {
|
|
4
|
+
changedFields?: string[];
|
|
5
|
+
id: string;
|
|
6
|
+
subject?: string;
|
|
7
|
+
trigger?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ValidateResponse {
|
|
10
|
+
diff: null | {
|
|
11
|
+
added: EmailDiffEntry[];
|
|
12
|
+
hasChanges: boolean;
|
|
13
|
+
modified: EmailDiffEntry[];
|
|
14
|
+
removed: EmailDiffEntry[];
|
|
15
|
+
unchanged: EmailDiffEntry[];
|
|
16
|
+
};
|
|
17
|
+
error: null | string;
|
|
18
|
+
existingDeployment: boolean;
|
|
19
|
+
isValid: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface SdkSnippet {
|
|
22
|
+
examples: {
|
|
23
|
+
identify: string;
|
|
24
|
+
track: string;
|
|
25
|
+
};
|
|
26
|
+
identifyCalls: string[];
|
|
27
|
+
install: string;
|
|
28
|
+
trackCalls: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface DeployResponse {
|
|
31
|
+
deployed: boolean;
|
|
32
|
+
diff: {
|
|
33
|
+
added: EmailDiffEntry[];
|
|
34
|
+
hasChanges: boolean;
|
|
35
|
+
modified: EmailDiffEntry[];
|
|
36
|
+
removed: EmailDiffEntry[];
|
|
37
|
+
unchanged: EmailDiffEntry[];
|
|
38
|
+
};
|
|
39
|
+
emailsLive: number;
|
|
40
|
+
sdkSnippet: SdkSnippet;
|
|
41
|
+
sequenceId: string;
|
|
42
|
+
}
|
|
43
|
+
export type DeployFlags = {
|
|
44
|
+
json: boolean;
|
|
45
|
+
yes: boolean;
|
|
46
|
+
};
|
|
47
|
+
export type DeployCtx = {
|
|
48
|
+
collectDomainInputs(yaml: MailmodoYaml, skip: boolean): Promise<{
|
|
49
|
+
address: string;
|
|
50
|
+
domain: string;
|
|
51
|
+
fromEmail: string;
|
|
52
|
+
fromName: string;
|
|
53
|
+
replyTo: string;
|
|
54
|
+
}>;
|
|
55
|
+
error(msg: string): never;
|
|
56
|
+
exit(code?: number): never;
|
|
57
|
+
get<T = Record<string, unknown>>(path: string, params?: Record<string, string>): Promise<ApiResponse<T>>;
|
|
58
|
+
getBillingCap(): Promise<number | undefined>;
|
|
59
|
+
log(msg?: string): void;
|
|
60
|
+
onApiError(resp: {
|
|
61
|
+
error?: string;
|
|
62
|
+
status: number;
|
|
63
|
+
}): never;
|
|
64
|
+
post<T = Record<string, unknown>>(path: string, body?: Record<string, unknown> | unknown): Promise<ApiResponse<T>>;
|
|
65
|
+
registerDomainAndSave(yaml: MailmodoYaml, inputs: {
|
|
66
|
+
address: string;
|
|
67
|
+
domain: string;
|
|
68
|
+
fromEmail: string;
|
|
69
|
+
fromName?: string;
|
|
70
|
+
replyTo?: string;
|
|
71
|
+
}, json: boolean): Promise<{
|
|
72
|
+
dnsGuideUrl?: string;
|
|
73
|
+
dnsRecords: Array<{
|
|
74
|
+
host: string;
|
|
75
|
+
type: string;
|
|
76
|
+
value: string;
|
|
77
|
+
}>;
|
|
78
|
+
}>;
|
|
79
|
+
showDnsRecords(records: Array<{
|
|
80
|
+
host: string;
|
|
81
|
+
type: string;
|
|
82
|
+
value: string;
|
|
83
|
+
}>, guideUrl: string | undefined, json: boolean): void;
|
|
84
|
+
spinner<T>(text: string, json: boolean, work: () => Promise<T>): Promise<T>;
|
|
85
|
+
syncYaml(): Promise<void>;
|
|
86
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/lib/messages.d.ts
CHANGED
|
@@ -13,6 +13,13 @@ export declare const PROMPTS: {
|
|
|
13
13
|
readonly REPLY_TO: "Reply-to address (optional, press Enter to use sender email):";
|
|
14
14
|
readonly SENDER_EMAIL: "Sender email address:";
|
|
15
15
|
};
|
|
16
|
+
export declare const MISSING_TEMPLATES: {
|
|
17
|
+
readonly ABORT_HINT: `Restore the missing files from version control, then run ${string} again.`;
|
|
18
|
+
readonly HEADER: `Some email templates are missing from ${string}:`;
|
|
19
|
+
readonly REGENERATE_NOTE: string;
|
|
20
|
+
readonly REVIEW_HINT: `Templates regenerated. Review them with ${string}, then run ${string} again.`;
|
|
21
|
+
readonly YES_ERROR: `Missing templates cannot be resolved with ${string}. Run ${string} without ${string} to regenerate via AI or restore from version control.`;
|
|
22
|
+
};
|
|
16
23
|
export declare const ERRORS: {
|
|
17
24
|
readonly DOMAIN_NOT_CONFIGURED: `No domain configured. Run ${string} to set up your sending domain.`;
|
|
18
25
|
readonly DOMAIN_NOT_REGISTERED: `Sending domain not registered. Run: ${string}`;
|
|
@@ -40,6 +47,8 @@ export declare const INFO: {
|
|
|
40
47
|
readonly FREE_TIER_CAP_BLOCKED: `Monthly cap is a paid-tier setting and is not available on the free tier. Run ${string} to add a payment method, then set a cap.`;
|
|
41
48
|
readonly PAUSE_CANCELLED: "Pause cancelled. Sequence is still live.";
|
|
42
49
|
readonly SEQUENCES_NOT_DEPLOYED: `Sequences saved but ${string}.`;
|
|
50
|
+
readonly YAML_RESTORED_FROM_SERVER: string;
|
|
51
|
+
readonly YAML_RESTORED_ON_LOGIN: ` mailmodo.yaml restored from server. Run ${string} to re-deploy your sequences.`;
|
|
43
52
|
};
|
|
44
53
|
export declare function pauseSuccess(sequenceId: string): string;
|
|
45
54
|
export declare function pauseAlready(sequenceId: string): string;
|
package/dist/lib/messages.js
CHANGED
|
@@ -14,6 +14,13 @@ export const PROMPTS = {
|
|
|
14
14
|
REPLY_TO: 'Reply-to address (optional, press Enter to use sender email):',
|
|
15
15
|
SENDER_EMAIL: 'Sender email address:',
|
|
16
16
|
};
|
|
17
|
+
export const MISSING_TEMPLATES = {
|
|
18
|
+
ABORT_HINT: `Restore the missing files from version control, then run ${chalk.cyan('mailmodo deploy')} again.`,
|
|
19
|
+
HEADER: `Some email templates are missing from ${chalk.cyan('./mailmodo/')}:`,
|
|
20
|
+
REGENERATE_NOTE: chalk.yellow(' Note: any previous manual edits to these files will be replaced with a new AI draft.'),
|
|
21
|
+
REVIEW_HINT: `Templates regenerated. Review them with ${chalk.cyan('mailmodo preview')}, then run ${chalk.cyan('mailmodo deploy')} again.`,
|
|
22
|
+
YES_ERROR: `Missing templates cannot be resolved with ${chalk.cyan('--yes')}. Run ${chalk.cyan('mailmodo deploy')} without ${chalk.cyan('--yes')} to regenerate via AI or restore from version control.`,
|
|
23
|
+
};
|
|
17
24
|
export const ERRORS = {
|
|
18
25
|
DOMAIN_NOT_CONFIGURED: `No domain configured. Run ${chalk.cyan('mailmodo domain')} to set up your sending domain.`,
|
|
19
26
|
DOMAIN_NOT_REGISTERED: `Sending domain not registered. Run: ${chalk.cyan('mailmodo domain')}`,
|
|
@@ -40,6 +47,8 @@ export const INFO = {
|
|
|
40
47
|
FREE_TIER_CAP_BLOCKED: `Monthly cap is a paid-tier setting and is not available on the free tier. Run ${chalk.cyan("'mailmodo billing --checkout'")} to add a payment method, then set a cap.`,
|
|
41
48
|
PAUSE_CANCELLED: 'Pause cancelled. Sequence is still live.',
|
|
42
49
|
SEQUENCES_NOT_DEPLOYED: `Sequences saved but ${chalk.yellow('NOT deployed')}.`,
|
|
50
|
+
YAML_RESTORED_FROM_SERVER: chalk.dim(' mailmodo.yaml not found locally — restored from server.'),
|
|
51
|
+
YAML_RESTORED_ON_LOGIN: ` mailmodo.yaml restored from server. Run ${chalk.cyan("'mailmodo deploy'")} to re-deploy your sequences.`,
|
|
43
52
|
};
|
|
44
53
|
export function pauseSuccess(sequenceId) {
|
|
45
54
|
return `Sequence ${chalk.cyan(sequenceId)} paused. Run ${chalk.cyan(`mailmodo deploy --resume ${sequenceId}`)} to resume.`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a user-facing snake_case YAML setting key to its
|
|
3
|
+
* corresponding camelCase TypeScript property name.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} key - A snake_case setting key (e.g., "brand_color").
|
|
6
|
+
* @returns {string} The camelCase property name (e.g., "brandColor").
|
|
7
|
+
*/
|
|
8
|
+
export declare function settingKeyToProp(key: string): string;
|
|
9
|
+
export declare function generateTriggerPrefix(productName: string): string;
|
|
10
|
+
export declare function normalizeTrigger(trigger: string, productName: string): string;
|
|
11
|
+
export declare function isValidUrl(value: string): boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a user-facing snake_case YAML setting key to its
|
|
3
|
+
* corresponding camelCase TypeScript property name.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} key - A snake_case setting key (e.g., "brand_color").
|
|
6
|
+
* @returns {string} The camelCase property name (e.g., "brandColor").
|
|
7
|
+
*/
|
|
8
|
+
export function settingKeyToProp(key) {
|
|
9
|
+
return key.replaceAll(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
10
|
+
}
|
|
11
|
+
function toCamelCaseAlnum(input) {
|
|
12
|
+
const parts = input
|
|
13
|
+
.trim()
|
|
14
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
if (parts.length === 0)
|
|
17
|
+
return '';
|
|
18
|
+
return (parts[0].toLowerCase() +
|
|
19
|
+
parts
|
|
20
|
+
.slice(1)
|
|
21
|
+
.map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase())
|
|
22
|
+
.join(''));
|
|
23
|
+
}
|
|
24
|
+
export function generateTriggerPrefix(productName) {
|
|
25
|
+
return `${toCamelCaseAlnum(productName)}$`;
|
|
26
|
+
}
|
|
27
|
+
export function normalizeTrigger(trigger, productName) {
|
|
28
|
+
const prefix = generateTriggerPrefix(productName);
|
|
29
|
+
const dollarIdx = trigger.indexOf('$');
|
|
30
|
+
const eventName = dollarIdx === -1 ? trigger : trigger.slice(dollarIdx + 1);
|
|
31
|
+
return prefix + eventName;
|
|
32
|
+
}
|
|
33
|
+
export function isValidUrl(value) {
|
|
34
|
+
try {
|
|
35
|
+
return Boolean(new URL(value));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -631,6 +631,53 @@
|
|
|
631
631
|
"index.js"
|
|
632
632
|
]
|
|
633
633
|
},
|
|
634
|
+
"sdk": {
|
|
635
|
+
"aliases": [],
|
|
636
|
+
"args": {},
|
|
637
|
+
"description": "Show the SDK track() / identify() reference for deployed sequences",
|
|
638
|
+
"examples": [
|
|
639
|
+
"<%= config.bin %> sdk",
|
|
640
|
+
"<%= config.bin %> sdk --sequence-id a1b2c3d4",
|
|
641
|
+
"<%= config.bin %> sdk --json"
|
|
642
|
+
],
|
|
643
|
+
"flags": {
|
|
644
|
+
"json": {
|
|
645
|
+
"description": "Output as JSON",
|
|
646
|
+
"name": "json",
|
|
647
|
+
"allowNo": false,
|
|
648
|
+
"type": "boolean"
|
|
649
|
+
},
|
|
650
|
+
"yes": {
|
|
651
|
+
"char": "y",
|
|
652
|
+
"description": "Skip confirmation prompts",
|
|
653
|
+
"name": "yes",
|
|
654
|
+
"allowNo": false,
|
|
655
|
+
"type": "boolean"
|
|
656
|
+
},
|
|
657
|
+
"sequence-id": {
|
|
658
|
+
"description": "Limit output to a single active sequence by ID (default: all active sequences)",
|
|
659
|
+
"name": "sequence-id",
|
|
660
|
+
"hasDynamicHelp": false,
|
|
661
|
+
"multiple": false,
|
|
662
|
+
"type": "option"
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
"hasDynamicHelp": false,
|
|
666
|
+
"hiddenAliases": [],
|
|
667
|
+
"id": "sdk",
|
|
668
|
+
"pluginAlias": "@mailmodo/cli",
|
|
669
|
+
"pluginName": "@mailmodo/cli",
|
|
670
|
+
"pluginType": "core",
|
|
671
|
+
"strict": true,
|
|
672
|
+
"enableJsonFlag": false,
|
|
673
|
+
"isESM": true,
|
|
674
|
+
"relativePath": [
|
|
675
|
+
"dist",
|
|
676
|
+
"commands",
|
|
677
|
+
"sdk",
|
|
678
|
+
"index.js"
|
|
679
|
+
]
|
|
680
|
+
},
|
|
634
681
|
"settings": {
|
|
635
682
|
"aliases": [],
|
|
636
683
|
"args": {},
|
|
@@ -718,5 +765,5 @@
|
|
|
718
765
|
]
|
|
719
766
|
}
|
|
720
767
|
},
|
|
721
|
-
"version": "0.0.
|
|
768
|
+
"version": "0.0.54-beta.pr56.86"
|
|
722
769
|
}
|