@lumerahq/cli 0.18.12 → 0.18.14
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/{chunk-MVUNFAVL.js → chunk-PMRN3STN.js} +1 -1
- package/dist/{chunk-IBE6ACPE.js → chunk-PVR5DD4G.js} +11 -0
- package/dist/{chunk-N4KKEYAI.js → chunk-SU26C4GL.js} +1 -1
- package/dist/{deps-AVTV7FP3.js → deps-JVAT5WIB.js} +2 -2
- package/dist/{dev-WWCJZIV4.js → dev-FT5OXF5S.js} +2 -2
- package/dist/index.js +12 -12
- package/dist/{init-F4UYW6LD.js → init-2T6GQ7HJ.js} +1 -1
- package/dist/{register-QPUXYBZ7.js → register-F23I2BE3.js} +1 -1
- package/dist/{resources-3FCEEAYQ.js → resources-4F2PYBBR.js} +220 -6
- package/dist/{run-JZX3E4UX.js → run-6KT4I7J7.js} +1 -1
- package/package.json +1 -1
|
@@ -184,6 +184,17 @@ var ApiClient = class {
|
|
|
184
184
|
method: "DELETE"
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
|
+
// Mailboxes
|
|
188
|
+
async listMailboxes() {
|
|
189
|
+
const result = await this.request("/api/mailboxes");
|
|
190
|
+
return result.mailboxes || [];
|
|
191
|
+
}
|
|
192
|
+
async createMailbox(def) {
|
|
193
|
+
return this.request("/api/mailboxes", {
|
|
194
|
+
method: "POST",
|
|
195
|
+
body: JSON.stringify(def)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
187
198
|
// Agents
|
|
188
199
|
async listAgents(opts) {
|
|
189
200
|
const params = new URLSearchParams({ limit: "100" });
|
|
@@ -166,7 +166,7 @@ async function dev(options) {
|
|
|
166
166
|
} = options;
|
|
167
167
|
const projectRoot = process.cwd();
|
|
168
168
|
const parentOrigin = getParentOrigin(apiUrl);
|
|
169
|
-
const lumeraAppUrl = `${parentOrigin}/
|
|
169
|
+
const lumeraAppUrl = `${parentOrigin}/preview_app/${appName}`;
|
|
170
170
|
if (await isPortInUse(port)) {
|
|
171
171
|
console.log(pc.yellow(` Dev server already running on port ${port}, skipping start.`));
|
|
172
172
|
return;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deps,
|
|
3
3
|
syncDeps
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PMRN3STN.js";
|
|
5
5
|
import "./chunk-2CR762KB.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-PVR5DD4G.js";
|
|
7
7
|
import "./chunk-ZH3NVYEQ.js";
|
|
8
8
|
import "./chunk-FJFIWC7G.js";
|
|
9
9
|
import "./chunk-PNKVD2UK.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
dev
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SU26C4GL.js";
|
|
4
4
|
import {
|
|
5
5
|
loadEnv
|
|
6
6
|
} from "./chunk-2CR762KB.js";
|
|
7
7
|
import {
|
|
8
8
|
createApiClient
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PVR5DD4G.js";
|
|
10
10
|
import {
|
|
11
11
|
findProjectRoot,
|
|
12
12
|
getApiUrl,
|
package/dist/index.js
CHANGED
|
@@ -219,39 +219,39 @@ async function main() {
|
|
|
219
219
|
switch (command) {
|
|
220
220
|
// Resource commands
|
|
221
221
|
case "plan":
|
|
222
|
-
await import("./resources-
|
|
222
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.plan(args.slice(1)));
|
|
223
223
|
break;
|
|
224
224
|
case "apply":
|
|
225
|
-
await import("./resources-
|
|
225
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.apply(args.slice(1)));
|
|
226
226
|
break;
|
|
227
227
|
case "pull":
|
|
228
|
-
await import("./resources-
|
|
228
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.pull(args.slice(1)));
|
|
229
229
|
break;
|
|
230
230
|
case "destroy":
|
|
231
|
-
await import("./resources-
|
|
231
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.destroy(args.slice(1)));
|
|
232
232
|
break;
|
|
233
233
|
case "list":
|
|
234
|
-
await import("./resources-
|
|
234
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.list(args.slice(1)));
|
|
235
235
|
break;
|
|
236
236
|
case "show":
|
|
237
|
-
await import("./resources-
|
|
237
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.show(args.slice(1)));
|
|
238
238
|
break;
|
|
239
239
|
case "diff":
|
|
240
|
-
await import("./resources-
|
|
240
|
+
await import("./resources-4F2PYBBR.js").then((m) => m.diff(args.slice(1)));
|
|
241
241
|
break;
|
|
242
242
|
// Development
|
|
243
243
|
case "dev":
|
|
244
|
-
await import("./dev-
|
|
244
|
+
await import("./dev-FT5OXF5S.js").then((m) => m.dev(args.slice(1)));
|
|
245
245
|
break;
|
|
246
246
|
case "run":
|
|
247
|
-
await import("./run-
|
|
247
|
+
await import("./run-6KT4I7J7.js").then((m) => m.run(args.slice(1)));
|
|
248
248
|
break;
|
|
249
249
|
// Project
|
|
250
250
|
case "init":
|
|
251
|
-
await import("./init-
|
|
251
|
+
await import("./init-2T6GQ7HJ.js").then((m) => m.init(args.slice(1)));
|
|
252
252
|
break;
|
|
253
253
|
case "register":
|
|
254
|
-
await import("./register-
|
|
254
|
+
await import("./register-F23I2BE3.js").then((m) => m.register(args.slice(1)));
|
|
255
255
|
break;
|
|
256
256
|
case "templates":
|
|
257
257
|
await import("./templates-M3RDNDDY.js").then((m) => m.templates(subcommand, args.slice(2)));
|
|
@@ -268,7 +268,7 @@ async function main() {
|
|
|
268
268
|
break;
|
|
269
269
|
// Dependencies
|
|
270
270
|
case "deps":
|
|
271
|
-
await import("./deps-
|
|
271
|
+
await import("./deps-JVAT5WIB.js").then((m) => m.deps(args.slice(1)));
|
|
272
272
|
break;
|
|
273
273
|
// Auth
|
|
274
274
|
case "login":
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
syncDeps
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PMRN3STN.js";
|
|
4
4
|
import {
|
|
5
5
|
deploy
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SU26C4GL.js";
|
|
7
7
|
import {
|
|
8
8
|
loadEnv
|
|
9
9
|
} from "./chunk-2CR762KB.js";
|
|
10
10
|
import {
|
|
11
11
|
createApiClient
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PVR5DD4G.js";
|
|
13
13
|
import {
|
|
14
14
|
findProjectRoot,
|
|
15
15
|
getApiUrl,
|
|
@@ -282,12 +282,15 @@ ${pc.dim("Resources:")}
|
|
|
282
282
|
hooks Plan only hooks
|
|
283
283
|
agents Plan only agents
|
|
284
284
|
agents/<name> Plan single agent
|
|
285
|
+
mailboxes Plan only mailboxes
|
|
286
|
+
mailboxes/<slug> Plan single mailbox
|
|
285
287
|
app Plan app deployment
|
|
286
288
|
|
|
287
289
|
${pc.dim("Examples:")}
|
|
288
290
|
lumera plan # Plan all resources
|
|
289
291
|
lumera plan collections # Plan only collections
|
|
290
292
|
lumera plan automations/sync # Plan single automation
|
|
293
|
+
lumera plan mailboxes # Plan mailbox configs
|
|
291
294
|
`);
|
|
292
295
|
}
|
|
293
296
|
function showApplyHelp() {
|
|
@@ -307,6 +310,8 @@ ${pc.dim("Resources:")}
|
|
|
307
310
|
hooks Apply only hooks
|
|
308
311
|
agents Apply only agents
|
|
309
312
|
agents/<name> Apply single agent
|
|
313
|
+
mailboxes Apply only mailboxes
|
|
314
|
+
mailboxes/<slug> Apply single mailbox
|
|
310
315
|
app Deploy the frontend app
|
|
311
316
|
|
|
312
317
|
${pc.dim("Options:")}
|
|
@@ -344,6 +349,8 @@ ${pc.dim("Resources:")}
|
|
|
344
349
|
hooks Pull only hooks
|
|
345
350
|
agents Pull only agents
|
|
346
351
|
agents/<name> Pull single agent
|
|
352
|
+
mailboxes Pull only mailboxes
|
|
353
|
+
mailboxes/<slug> Pull single mailbox
|
|
347
354
|
|
|
348
355
|
${pc.dim("Examples:")}
|
|
349
356
|
lumera pull # Pull all (safe \u2014 warns on conflicts)
|
|
@@ -395,6 +402,7 @@ ${pc.dim("Types:")}
|
|
|
395
402
|
automations List only automations
|
|
396
403
|
hooks List only hooks
|
|
397
404
|
agents List only agents
|
|
405
|
+
mailboxes List only mailboxes
|
|
398
406
|
|
|
399
407
|
${pc.dim("Options:")}
|
|
400
408
|
--all Include remote-only resources
|
|
@@ -418,6 +426,7 @@ ${pc.dim("Resources:")}
|
|
|
418
426
|
automations/<name> Show automation details
|
|
419
427
|
hooks/<name> Show hook details
|
|
420
428
|
agents/<name> Show agent details
|
|
429
|
+
mailboxes/<slug> Show mailbox details
|
|
421
430
|
app Show app details
|
|
422
431
|
|
|
423
432
|
${pc.dim("Examples:")}
|
|
@@ -433,7 +442,7 @@ function parseResource(resourcePath) {
|
|
|
433
442
|
const parts = resourcePath.split("/");
|
|
434
443
|
const type = parts[0];
|
|
435
444
|
const name = parts.slice(1).join("/") || null;
|
|
436
|
-
const validTypes = ["collections", "automations", "hooks", "agents", "app"];
|
|
445
|
+
const validTypes = ["collections", "automations", "hooks", "agents", "mailboxes", "app"];
|
|
437
446
|
if (!validTypes.includes(type)) {
|
|
438
447
|
console.log(pc.red(` Unknown resource type "${type}". Valid types: ${validTypes.join(", ")}`));
|
|
439
448
|
process.exit(1);
|
|
@@ -665,6 +674,12 @@ function convertCollectionToApiFormat(local) {
|
|
|
665
674
|
options.collectionId = field.collection;
|
|
666
675
|
options.maxSelect = field.multiple ? 999 : 1;
|
|
667
676
|
}
|
|
677
|
+
if (field.type === "currency") {
|
|
678
|
+
if (field.defaultCurrency) options.defaultCurrency = field.defaultCurrency;
|
|
679
|
+
if (field.decimalPrecision !== void 0) {
|
|
680
|
+
options.decimalPrecision = field.decimalPrecision;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
668
683
|
if (field.max !== void 0) options.max = field.max;
|
|
669
684
|
if (field.min !== void 0) options.min = field.min;
|
|
670
685
|
if (Object.keys(options).length > 0) {
|
|
@@ -692,7 +707,8 @@ function mapFieldType(type) {
|
|
|
692
707
|
relation: "relation",
|
|
693
708
|
file: "lumera_file",
|
|
694
709
|
json: "json",
|
|
695
|
-
editor: "editor"
|
|
710
|
+
editor: "editor",
|
|
711
|
+
currency: "currency"
|
|
696
712
|
};
|
|
697
713
|
return typeMap[type] || type;
|
|
698
714
|
}
|
|
@@ -716,6 +732,14 @@ function fieldsDiffer(local, remote) {
|
|
|
716
732
|
if (localMultiple && remoteMaxSelect <= 1) return true;
|
|
717
733
|
if (!localMultiple && remoteMaxSelect > 1) return true;
|
|
718
734
|
}
|
|
735
|
+
if (local.type === "currency") {
|
|
736
|
+
const localDefaultCurrency = (local.defaultCurrency || "USD").trim().toUpperCase();
|
|
737
|
+
const remoteDefaultCurrency = (opts.defaultCurrency || "USD").trim().toUpperCase();
|
|
738
|
+
if (localDefaultCurrency !== remoteDefaultCurrency) return true;
|
|
739
|
+
const localDecimalPrecision = local.decimalPrecision !== void 0 ? local.decimalPrecision : 2;
|
|
740
|
+
const remoteDecimalPrecision = opts.decimalPrecision !== void 0 ? opts.decimalPrecision : 2;
|
|
741
|
+
if (localDecimalPrecision !== remoteDecimalPrecision) return true;
|
|
742
|
+
}
|
|
719
743
|
const localMin = local.min !== void 0 ? local.min : void 0;
|
|
720
744
|
const remoteMin = opts.min !== void 0 ? opts.min : void 0;
|
|
721
745
|
if (localMin !== remoteMin) return true;
|
|
@@ -883,6 +907,122 @@ async function planAutomations(api, localAutomations) {
|
|
|
883
907
|
}
|
|
884
908
|
return changes;
|
|
885
909
|
}
|
|
910
|
+
function loadLocalMailboxes(platformDir, filterName) {
|
|
911
|
+
const mailboxesDir = join(platformDir, "mailboxes");
|
|
912
|
+
if (!existsSync(mailboxesDir)) {
|
|
913
|
+
return [];
|
|
914
|
+
}
|
|
915
|
+
const mailboxes = [];
|
|
916
|
+
for (const file of readdirSync(mailboxesDir)) {
|
|
917
|
+
if (!file.endsWith(".json")) continue;
|
|
918
|
+
const slug = file.replace(/\.json$/, "").trim();
|
|
919
|
+
if (!slug) {
|
|
920
|
+
console.log(pc.yellow(` \u26A0 Skipping ${file}: empty filename`));
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
if (filterName && slug !== filterName) {
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
const filePath = join(mailboxesDir, file);
|
|
927
|
+
let raw;
|
|
928
|
+
try {
|
|
929
|
+
raw = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
930
|
+
} catch (e) {
|
|
931
|
+
console.log(pc.yellow(` \u26A0 Skipping ${file}: invalid JSON (${e.message})`));
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
if (!isPlainObject(raw)) {
|
|
935
|
+
console.log(pc.yellow(` \u26A0 Skipping ${file}: top-level value must be an object`));
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
const descriptionRaw = raw["description"];
|
|
939
|
+
const description = typeof descriptionRaw === "string" ? descriptionRaw : void 0;
|
|
940
|
+
mailboxes.push({ slug, description });
|
|
941
|
+
}
|
|
942
|
+
return mailboxes;
|
|
943
|
+
}
|
|
944
|
+
async function planMailboxes(api, localMailboxes) {
|
|
945
|
+
const changes = [];
|
|
946
|
+
if (localMailboxes.length === 0) return changes;
|
|
947
|
+
const remote = await api.listMailboxes();
|
|
948
|
+
const remoteBySlug = new Map(remote.map((m) => [m.slug, m]));
|
|
949
|
+
for (const mb of localMailboxes) {
|
|
950
|
+
const existing = remoteBySlug.get(mb.slug);
|
|
951
|
+
if (!existing) {
|
|
952
|
+
changes.push({
|
|
953
|
+
type: "create",
|
|
954
|
+
resource: "mailbox",
|
|
955
|
+
id: mb.slug,
|
|
956
|
+
name: mb.slug,
|
|
957
|
+
details: mb.description ? `description: ${mb.description}` : void 0
|
|
958
|
+
});
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
const localDesc = (mb.description ?? "").trim();
|
|
962
|
+
const remoteDesc = (existing.description ?? "").trim();
|
|
963
|
+
if (localDesc !== remoteDesc) {
|
|
964
|
+
changes.push({
|
|
965
|
+
type: "update",
|
|
966
|
+
resource: "mailbox",
|
|
967
|
+
id: existing.id,
|
|
968
|
+
name: mb.slug,
|
|
969
|
+
details: "description differs (read-only remotely; update in UI or DB)"
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
return changes;
|
|
974
|
+
}
|
|
975
|
+
async function applyMailboxes(api, localMailboxes) {
|
|
976
|
+
if (localMailboxes.length === 0) return 0;
|
|
977
|
+
let errors = 0;
|
|
978
|
+
const remote = await api.listMailboxes();
|
|
979
|
+
const remoteBySlug = new Map(remote.map((m) => [m.slug, m]));
|
|
980
|
+
for (const mb of localMailboxes) {
|
|
981
|
+
const existing = remoteBySlug.get(mb.slug);
|
|
982
|
+
if (existing) {
|
|
983
|
+
const localDesc = (mb.description ?? "").trim();
|
|
984
|
+
const remoteDesc = (existing.description ?? "").trim();
|
|
985
|
+
if (localDesc !== remoteDesc) {
|
|
986
|
+
console.log(pc.yellow(" \u26A0"), `mailbox ${mb.slug}: description drift not reconcilable by CLI (no PATCH endpoint yet) \u2014 update in the UI or DB`);
|
|
987
|
+
} else {
|
|
988
|
+
console.log(pc.green(" \u2713"), pc.dim(`mailbox ${mb.slug} already exists (${existing.email})`));
|
|
989
|
+
}
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
try {
|
|
993
|
+
const created = await api.createMailbox({ slug: mb.slug, description: mb.description });
|
|
994
|
+
console.log(pc.green(" \u2713"), `created mailbox ${mb.slug} ${pc.dim(`\u2192 ${created.email}`)}`);
|
|
995
|
+
} catch (e) {
|
|
996
|
+
console.log(pc.red(" \u2717"), `mailbox ${mb.slug}: ${e.message}`);
|
|
997
|
+
errors++;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return errors;
|
|
1001
|
+
}
|
|
1002
|
+
async function pullMailboxes(api, platformDir, filterName) {
|
|
1003
|
+
const mailboxes = await api.listMailboxes();
|
|
1004
|
+
if (mailboxes.length === 0) {
|
|
1005
|
+
console.log(pc.dim(" (no mailboxes)"));
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const outDir = join(platformDir, "mailboxes");
|
|
1009
|
+
if (!existsSync(outDir)) {
|
|
1010
|
+
mkdirSync(outDir, { recursive: true });
|
|
1011
|
+
}
|
|
1012
|
+
let count = 0;
|
|
1013
|
+
for (const mb of mailboxes) {
|
|
1014
|
+
if (filterName && mb.slug !== filterName) continue;
|
|
1015
|
+
const body = {};
|
|
1016
|
+
if (mb.description) body.description = mb.description;
|
|
1017
|
+
const file = join(outDir, `${toSafeFilename(mb.slug)}.json`);
|
|
1018
|
+
writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
|
|
1019
|
+
console.log(pc.green(" \u2713"), `pulled mailbox ${mb.slug} ${pc.dim(`\u2192 ${file}`)}`);
|
|
1020
|
+
count++;
|
|
1021
|
+
}
|
|
1022
|
+
if (count === 0 && filterName) {
|
|
1023
|
+
console.log(pc.yellow(` \u26A0 mailbox '${filterName}' not found on remote`));
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
886
1026
|
async function planHooks(api, localHooks, collections) {
|
|
887
1027
|
const changes = [];
|
|
888
1028
|
const remoteHooks = await api.listHooks();
|
|
@@ -1169,6 +1309,12 @@ async function pullCollections(api, platformDir, filterName, appName) {
|
|
|
1169
1309
|
if (field.options.values) localField.values = field.options.values;
|
|
1170
1310
|
if (field.options.collectionId) localField.collection = field.options.collectionId;
|
|
1171
1311
|
if (field.options.maxSelect && field.options.maxSelect > 1) localField.multiple = true;
|
|
1312
|
+
if (field.options.defaultCurrency) {
|
|
1313
|
+
localField.defaultCurrency = field.options.defaultCurrency;
|
|
1314
|
+
}
|
|
1315
|
+
if (field.options.decimalPrecision !== void 0) {
|
|
1316
|
+
localField.decimalPrecision = field.options.decimalPrecision;
|
|
1317
|
+
}
|
|
1172
1318
|
}
|
|
1173
1319
|
return localField;
|
|
1174
1320
|
}),
|
|
@@ -1642,6 +1788,30 @@ async function listResources(api, platformDir, filterType, appName, projectId) {
|
|
|
1642
1788
|
}
|
|
1643
1789
|
}
|
|
1644
1790
|
}
|
|
1791
|
+
if (!filterType || filterType === "mailboxes") {
|
|
1792
|
+
const localMailboxes = loadLocalMailboxes(platformDir);
|
|
1793
|
+
const remoteMailboxes = await api.listMailboxes();
|
|
1794
|
+
const remoteBySlug = new Map(remoteMailboxes.map((m) => [m.slug, m]));
|
|
1795
|
+
const localSlugs = new Set(localMailboxes.map((m) => m.slug));
|
|
1796
|
+
for (const mb of localMailboxes) {
|
|
1797
|
+
const remote = remoteBySlug.get(mb.slug);
|
|
1798
|
+
if (!remote) {
|
|
1799
|
+
results.push({ name: mb.slug, type: "mailboxes", status: "local-only" });
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
const descChanged = (mb.description ?? "").trim() !== (remote.description ?? "").trim();
|
|
1803
|
+
if (descChanged) {
|
|
1804
|
+
results.push({ name: mb.slug, type: "mailboxes", status: "changed", details: "description" });
|
|
1805
|
+
} else {
|
|
1806
|
+
results.push({ name: mb.slug, type: "mailboxes", status: "synced" });
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
for (const remote of remoteMailboxes) {
|
|
1810
|
+
if (!localSlugs.has(remote.slug)) {
|
|
1811
|
+
results.push({ name: remote.slug, type: "mailboxes", status: "remote-only" });
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1645
1815
|
return results;
|
|
1646
1816
|
}
|
|
1647
1817
|
function planCollectionDelete(collections, platformDir) {
|
|
@@ -2061,6 +2231,31 @@ async function showResource(api, platformDir, resourceType, resourceName, appNam
|
|
|
2061
2231
|
console.log(` MCP Servers: ${mcps.join(", ")}`);
|
|
2062
2232
|
}
|
|
2063
2233
|
console.log();
|
|
2234
|
+
} else if (resourceType === "mailboxes") {
|
|
2235
|
+
const localMailboxes = loadLocalMailboxes(platformDir, resourceName);
|
|
2236
|
+
const remoteMailboxes = await api.listMailboxes();
|
|
2237
|
+
const local = localMailboxes[0];
|
|
2238
|
+
const remote = remoteMailboxes.find((m) => m.slug === resourceName);
|
|
2239
|
+
if (!local && !remote) {
|
|
2240
|
+
console.log(pc.red(` Mailbox "${resourceName}" not found`));
|
|
2241
|
+
process.exit(1);
|
|
2242
|
+
}
|
|
2243
|
+
console.log();
|
|
2244
|
+
console.log(pc.bold(` Mailbox: ${local?.slug || remote?.slug}`));
|
|
2245
|
+
console.log();
|
|
2246
|
+
if (local && remote) {
|
|
2247
|
+
const descChanged = (local.description ?? "").trim() !== (remote.description ?? "").trim();
|
|
2248
|
+
console.log(` Status: ${descChanged ? pc.yellow("changed") : pc.green("synced")}`);
|
|
2249
|
+
} else if (local) {
|
|
2250
|
+
console.log(` Status: ${pc.yellow("local only")}`);
|
|
2251
|
+
} else {
|
|
2252
|
+
console.log(` Status: ${pc.cyan("remote only")}`);
|
|
2253
|
+
}
|
|
2254
|
+
if (remote?.email) console.log(` Email: ${remote.email}`);
|
|
2255
|
+
const desc = local?.description || remote?.description;
|
|
2256
|
+
if (desc) console.log(` Description: ${desc}`);
|
|
2257
|
+
if (remote?.project_id) console.log(` Project: ${remote.project_id}`);
|
|
2258
|
+
console.log();
|
|
2064
2259
|
} else if (resourceType === "app") {
|
|
2065
2260
|
const projectRoot = findProjectRoot();
|
|
2066
2261
|
loadEnv(projectRoot);
|
|
@@ -2152,6 +2347,13 @@ async function plan(args) {
|
|
|
2152
2347
|
allChanges.push(...changes);
|
|
2153
2348
|
}
|
|
2154
2349
|
}
|
|
2350
|
+
if (!type || type === "mailboxes") {
|
|
2351
|
+
const localMailboxes = loadLocalMailboxes(platformDir, name || void 0);
|
|
2352
|
+
if (localMailboxes.length > 0) {
|
|
2353
|
+
const changes = await planMailboxes(api, localMailboxes);
|
|
2354
|
+
allChanges.push(...changes);
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2155
2357
|
if (allChanges.length === 0) {
|
|
2156
2358
|
if (jsonOutput) {
|
|
2157
2359
|
console.log(JSON.stringify({ changes: [], warnings: [] }));
|
|
@@ -2253,12 +2455,14 @@ async function apply(args) {
|
|
|
2253
2455
|
const localAutomations = !type || type === "automations" ? loadLocalAutomations(platformDir, name || void 0, appName) : [];
|
|
2254
2456
|
const localHooks = !type || type === "hooks" ? loadLocalHooks(platformDir, name || void 0, appName) : [];
|
|
2255
2457
|
const localAgents = !type || type === "agents" ? loadLocalAgents(platformDir, name || void 0, appName) : [];
|
|
2458
|
+
const localMailboxes = !type || type === "mailboxes" ? loadLocalMailboxes(platformDir, name || void 0) : [];
|
|
2256
2459
|
if (localCollections.length > 0) allChanges.push(...await planCollections(api, localCollections));
|
|
2257
2460
|
if (localAutomations.length > 0) allChanges.push(...await planAutomations(api, localAutomations));
|
|
2258
2461
|
if (localHooks.length > 0) allChanges.push(...await planHooks(api, localHooks, collections));
|
|
2259
2462
|
if (localAgents.length > 0) allChanges.push(...await planAgents(api, localAgents, projectId));
|
|
2463
|
+
if (localMailboxes.length > 0) allChanges.push(...await planMailboxes(api, localMailboxes));
|
|
2260
2464
|
if (name) {
|
|
2261
|
-
const hasLocal = localCollections.length > 0 || localAutomations.length > 0 || localHooks.length > 0 || localAgents.length > 0;
|
|
2465
|
+
const hasLocal = localCollections.length > 0 || localAutomations.length > 0 || localHooks.length > 0 || localAgents.length > 0 || localMailboxes.length > 0;
|
|
2262
2466
|
if (!hasLocal) {
|
|
2263
2467
|
console.log();
|
|
2264
2468
|
console.log(pc.red(` Resource "${name}" not found locally`));
|
|
@@ -2349,6 +2553,11 @@ async function apply(args) {
|
|
|
2349
2553
|
totalErrors += await applyAgents(api, localAgents, projectId);
|
|
2350
2554
|
console.log();
|
|
2351
2555
|
}
|
|
2556
|
+
if (localMailboxes.length > 0) {
|
|
2557
|
+
console.log(pc.bold(" Mailboxes:"));
|
|
2558
|
+
totalErrors += await applyMailboxes(api, localMailboxes);
|
|
2559
|
+
console.log();
|
|
2560
|
+
}
|
|
2352
2561
|
if (willDeployApp) {
|
|
2353
2562
|
console.log(pc.bold(" App:"));
|
|
2354
2563
|
await applyApp(args);
|
|
@@ -2455,6 +2664,11 @@ async function pull(args) {
|
|
|
2455
2664
|
await pullAgents(api, platformDir, name || void 0, projectId);
|
|
2456
2665
|
console.log();
|
|
2457
2666
|
}
|
|
2667
|
+
if (!type || type === "mailboxes") {
|
|
2668
|
+
console.log(pc.bold(" Mailboxes:"));
|
|
2669
|
+
await pullMailboxes(api, platformDir, name || void 0);
|
|
2670
|
+
console.log();
|
|
2671
|
+
}
|
|
2458
2672
|
console.log(pc.green(" Done!"));
|
|
2459
2673
|
console.log();
|
|
2460
2674
|
}
|