@rolino/cli 0.1.0 → 0.3.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.
- package/CHANGELOG.md +26 -0
- package/README.md +74 -40
- package/dist/bin.cjs +130 -27
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-YTEWMNSV.js → chunk-7BCIIFUB.js} +134 -29
- package/dist/chunk-7BCIIFUB.js.map +1 -0
- package/dist/index.cjs +130 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-YTEWMNSV.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
41
41
|
|
|
42
42
|
// src/cli.ts
|
|
43
43
|
var import_node_crypto2 = require("crypto");
|
|
44
|
+
var import_node_fs2 = require("fs");
|
|
44
45
|
var import_promises2 = require("fs/promises");
|
|
45
46
|
var import_node_path2 = require("path");
|
|
46
47
|
var import_promises3 = require("readline/promises");
|
|
@@ -49,7 +50,7 @@ var import_commander = require("commander");
|
|
|
49
50
|
// package.json
|
|
50
51
|
var package_default = {
|
|
51
52
|
name: "@rolino/cli",
|
|
52
|
-
version: "0.
|
|
53
|
+
version: "0.3.0",
|
|
53
54
|
description: "Agent-friendly command-line interface for Rolino",
|
|
54
55
|
type: "module",
|
|
55
56
|
license: "MIT",
|
|
@@ -106,9 +107,9 @@ var package_default = {
|
|
|
106
107
|
dev: "tsx src/bin.ts"
|
|
107
108
|
},
|
|
108
109
|
dependencies: {
|
|
109
|
-
"@rolino/contracts": "0.
|
|
110
|
-
"@rolino/local-auth": "0.
|
|
111
|
-
"@rolino/sdk": "0.
|
|
110
|
+
"@rolino/contracts": "0.3.0",
|
|
111
|
+
"@rolino/local-auth": "0.3.0",
|
|
112
|
+
"@rolino/sdk": "0.3.0",
|
|
112
113
|
commander: "^15.0.0",
|
|
113
114
|
open: "^11.0.0"
|
|
114
115
|
},
|
|
@@ -492,7 +493,13 @@ function formatPost(post) {
|
|
|
492
493
|
] : [],
|
|
493
494
|
...post.publishedAt ? [`Published: ${post.publishedAt}`] : [],
|
|
494
495
|
`Media: ${post.media.length}`,
|
|
495
|
-
`Destinations: ${post.destinations.map((destination) => `${destination.provider}:${queued && destination.status === "SCHEDULED" ? "QUEUED" : destination.status}`).join(", ") || "none"}
|
|
496
|
+
`Destinations: ${post.destinations.map((destination) => `${destination.provider}:${queued && destination.status === "SCHEDULED" ? "QUEUED" : destination.status}`).join(", ") || "none"}`,
|
|
497
|
+
...post.providerSettings?.TIKTOK ? [
|
|
498
|
+
`TikTok: ${post.providerSettings.TIKTOK.postMode}, ${post.providerSettings.TIKTOK.privacyLevel ?? "visibility not set"}, settings ${post.providerSettings.TIKTOK.consentedAt ? "reviewed" : "not reviewed"}`
|
|
499
|
+
] : [],
|
|
500
|
+
...post.providerSettings?.YOUTUBE ? [
|
|
501
|
+
`YouTube: ${post.providerSettings.YOUTUBE.privacyStatus}, ${post.providerSettings.YOUTUBE.title}`
|
|
502
|
+
] : []
|
|
496
503
|
].join("\n");
|
|
497
504
|
}
|
|
498
505
|
function formatPostSchedulePending(pending) {
|
|
@@ -506,6 +513,28 @@ function formatIntegrationHealth(data) {
|
|
|
506
513
|
const rows = data.items.map((item) => `${item.provider} ${item.connected ? "connected" : "disconnected"} ${item.health.status} ${item.health.isStale ? "stale" : "current"} ${item.health.message}`);
|
|
507
514
|
return ["PROVIDER CONNECTION HEALTH FRESHNESS DETAIL", ...rows].join("\n");
|
|
508
515
|
}
|
|
516
|
+
function formatProviderDeliveryOptions(options) {
|
|
517
|
+
switch (options.provider) {
|
|
518
|
+
case "TIKTOK":
|
|
519
|
+
return [
|
|
520
|
+
`TikTok delivery options for ${options.account.displayName ?? options.account.username ?? "connected account"}`,
|
|
521
|
+
`Checked: ${options.checkedAt}`,
|
|
522
|
+
`Health: ${options.health.status} (${options.health.code}) ${options.health.message}`,
|
|
523
|
+
`Modes: ${options.allowedPostModes.join(", ") || "none"}`,
|
|
524
|
+
`Visibility: ${options.visibilityOptions.join(", ") || "none"}`,
|
|
525
|
+
`Interactions: comments ${options.interactions.comment.available ? "available" : "disabled"}, duet ${options.interactions.duet.available ? "available" : "disabled"}, stitch ${options.interactions.stitch.available ? "available" : "disabled"}`,
|
|
526
|
+
`Maximum video duration: ${options.maxVideoDurationMs === null ? "unknown" : `${options.maxVideoDurationMs} ms`}`
|
|
527
|
+
].join("\n");
|
|
528
|
+
case "LINKEDIN":
|
|
529
|
+
return [
|
|
530
|
+
`LinkedIn delivery options for ${options.account.displayName ?? "connected member"}`,
|
|
531
|
+
`Checked: ${options.checkedAt}`,
|
|
532
|
+
`Health: ${options.health.status} (${options.health.code}) ${options.health.message}`,
|
|
533
|
+
`Post types: ${options.supportedPostTypes.join(", ")}`,
|
|
534
|
+
`Images: up to ${options.image.maxItems}; ${options.image.mimeTypes.join(", ")}; under ${options.image.maxPixelsExclusive.toLocaleString()} pixels`
|
|
535
|
+
].join("\n");
|
|
536
|
+
}
|
|
537
|
+
}
|
|
509
538
|
function formatPostReadiness(readiness) {
|
|
510
539
|
const attention = readiness.checks.filter((check) => check.status !== "pass");
|
|
511
540
|
const summary = readiness.hasBlockingChecks ? "Post is not ready to publish." : readiness.requiresLiveRefresh.length ? "Local checks passed; live provider health must be refreshed." : "Post is ready to publish.";
|
|
@@ -850,7 +879,32 @@ function collectPublishingProvider(value, previous) {
|
|
|
850
879
|
return [...previous ?? [], publishingProvider(value)];
|
|
851
880
|
}
|
|
852
881
|
function collectString(value, previous) {
|
|
853
|
-
return [...previous, value];
|
|
882
|
+
return [...previous ?? [], value];
|
|
883
|
+
}
|
|
884
|
+
function deliveryOptionsProvider(value) {
|
|
885
|
+
const normalized = value.toUpperCase();
|
|
886
|
+
const parsed = import_contracts2.ProviderDeliveryOptionsProviderSchema.safeParse(normalized);
|
|
887
|
+
if (parsed.success) return parsed.data;
|
|
888
|
+
throw new import_commander.InvalidArgumentError(
|
|
889
|
+
`Provider must be one of ${import_contracts2.ProviderDeliveryOptionsProviderSchema.options.join(", ")}.`
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
function tiktokPostMode(value) {
|
|
893
|
+
const normalized = value.trim().toLowerCase();
|
|
894
|
+
if (normalized === "direct" || normalized === "direct_post") {
|
|
895
|
+
return "DIRECT_POST";
|
|
896
|
+
}
|
|
897
|
+
if (normalized === "inbox" || normalized === "media_upload") {
|
|
898
|
+
return "MEDIA_UPLOAD";
|
|
899
|
+
}
|
|
900
|
+
throw new import_commander.InvalidArgumentError("TikTok mode must be direct or inbox.");
|
|
901
|
+
}
|
|
902
|
+
function nonnegativeInteger(value) {
|
|
903
|
+
const parsed = Number(value);
|
|
904
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0) {
|
|
905
|
+
throw new import_commander.InvalidArgumentError("Expected a nonnegative integer.");
|
|
906
|
+
}
|
|
907
|
+
return parsed;
|
|
854
908
|
}
|
|
855
909
|
function youtubePrivacy(value) {
|
|
856
910
|
const normalized = value.toUpperCase();
|
|
@@ -868,7 +922,7 @@ function yesOrNo(value) {
|
|
|
868
922
|
throw new import_commander.InvalidArgumentError("Expected yes or no.");
|
|
869
923
|
}
|
|
870
924
|
function youtubeSettings(options) {
|
|
871
|
-
const hasYouTubeOptions = options.youtubeTitle !== void 0 || options.youtubeCategoryId !== void 0 || options.youtubePrivacy !== void 0 || options.youtubeMadeForKids !== void 0 || options.youtubeSyntheticMedia === true || options.youtubeNotifySubscribers === false || options.youtubeTag
|
|
925
|
+
const hasYouTubeOptions = options.youtubeTitle !== void 0 || options.youtubeCategoryId !== void 0 || options.youtubePrivacy !== void 0 || options.youtubeMadeForKids !== void 0 || options.youtubeSyntheticMedia === true || options.youtubeNotifySubscribers === false || (options.youtubeTag?.length ?? 0) > 0;
|
|
872
926
|
if (!hasYouTubeOptions) return null;
|
|
873
927
|
return import_contracts2.YouTubePostSettingsSchema.parse({
|
|
874
928
|
title: options.youtubeTitle,
|
|
@@ -877,7 +931,7 @@ function youtubeSettings(options) {
|
|
|
877
931
|
madeForKids: options.youtubeMadeForKids,
|
|
878
932
|
containsSyntheticMedia: options.youtubeSyntheticMedia ?? false,
|
|
879
933
|
notifySubscribers: options.youtubeNotifySubscribers ?? true,
|
|
880
|
-
tags: options.youtubeTag
|
|
934
|
+
tags: options.youtubeTag ?? []
|
|
881
935
|
});
|
|
882
936
|
}
|
|
883
937
|
function positiveInteger(value) {
|
|
@@ -1023,6 +1077,23 @@ function errorForOutput(error) {
|
|
|
1023
1077
|
}
|
|
1024
1078
|
return { code: "CLI_ERROR", message: "The command failed unexpectedly." };
|
|
1025
1079
|
}
|
|
1080
|
+
function tiktokSettings(options) {
|
|
1081
|
+
const hasTikTokOptions = options.tiktokMode !== void 0 || options.tiktokVisibility !== void 0 || options.tiktokComments !== void 0 || options.tiktokDuet !== void 0 || options.tiktokStitch !== void 0 || options.tiktokCommercialContent !== void 0 || options.tiktokPromotesOwnBrand !== void 0 || options.tiktokPromotesThirdParty !== void 0 || options.tiktokAiGenerated !== void 0 || options.tiktokCoverTimestampMs !== void 0 || options.tiktokSettingsReviewed === true;
|
|
1082
|
+
if (!hasTikTokOptions) return void 0;
|
|
1083
|
+
return import_contracts2.TikTokDraftSettingsSchema.parse({
|
|
1084
|
+
postMode: options.tiktokMode,
|
|
1085
|
+
privacyLevel: options.tiktokVisibility,
|
|
1086
|
+
allowComment: options.tiktokComments,
|
|
1087
|
+
allowDuet: options.tiktokDuet,
|
|
1088
|
+
allowStitch: options.tiktokStitch,
|
|
1089
|
+
commercialContentEnabled: options.tiktokCommercialContent,
|
|
1090
|
+
promotesOwnBrand: options.tiktokPromotesOwnBrand,
|
|
1091
|
+
promotesThirdParty: options.tiktokPromotesThirdParty,
|
|
1092
|
+
isAiGenerated: options.tiktokAiGenerated,
|
|
1093
|
+
videoCoverTimestampMs: options.tiktokCoverTimestampMs,
|
|
1094
|
+
reviewed: options.tiktokSettingsReviewed === true
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1026
1097
|
function recoverySuggestions(code, command) {
|
|
1027
1098
|
switch (code) {
|
|
1028
1099
|
case "AUTH_REQUIRED":
|
|
@@ -1226,8 +1297,8 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1226
1297
|
const contentType = contentTypes[(0, import_node_path2.extname)(absolutePath).toLowerCase()];
|
|
1227
1298
|
if (!contentType) throw new TypeError("Use a JPEG, PNG, WebP, MP4, or MOV file.");
|
|
1228
1299
|
await requireWriteConsent({ yes: local.yes, global, runtime, subject: "media", preview: [`Upload ${(0, import_node_path2.basename)(absolutePath)} to Rolino?`, `Project: ${local.project}`, `Size: ${details.size} bytes`, "This adds a reusable media asset but does not create, schedule, or publish a post."].join("\n") });
|
|
1229
|
-
const
|
|
1230
|
-
const asset = await client.media.upload(local.project, { fileName: (0, import_node_path2.basename)(absolutePath), contentType, fileSize: details.size, body
|
|
1300
|
+
const body = await (0, import_node_fs2.openAsBlob)(absolutePath, { type: contentType });
|
|
1301
|
+
const asset = await client.media.upload(local.project, { fileName: (0, import_node_path2.basename)(absolutePath), contentType, fileSize: details.size, body }, { requestId: context.requestId });
|
|
1231
1302
|
writeSuccess(context, asset, formatMediaAsset(asset), [`rolino posts create --project ${local.project} --caption <text> --media ${asset.id} --agent --yes`]);
|
|
1232
1303
|
}
|
|
1233
1304
|
});
|
|
@@ -1450,7 +1521,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1450
1521
|
});
|
|
1451
1522
|
});
|
|
1452
1523
|
const posts = program.command("posts").description("Read and prepare posts in a Rolino project");
|
|
1453
|
-
posts.command("create").description("Create a draft post without scheduling or publishing it").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--caption <text>", "draft caption; use an empty string for media-only drafts").option("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, or
|
|
1524
|
+
posts.command("create").description("Create a draft post without scheduling or publishing it").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--caption <text>", "draft caption; use an empty string for media-only drafts").option("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, BLUESKY, or LINKEDIN; repeat as needed", collectPublishingProvider, []).option("--media <asset-id>", "existing project media asset ID; repeat for multiple", collectString, []).option("--instagram-caption <text>", "Instagram-specific caption override").option("--tiktok-caption <text>", "TikTok-specific caption override").option("--tiktok-mode <mode>", "direct publishing or inbox draft delivery", tiktokPostMode).option("--tiktok-visibility <value>", "exact visibility returned by integrations delivery-options").option("--tiktok-comments <yes|no>", "allow TikTok comments", yesOrNo).option("--tiktok-duet <yes|no>", "allow TikTok duets", yesOrNo).option("--tiktok-stitch <yes|no>", "allow TikTok stitches", yesOrNo).option("--tiktok-commercial-content <yes|no>", "declare commercial TikTok content", yesOrNo).option("--tiktok-promotes-own-brand <yes|no>", "declare own-brand promotion", yesOrNo).option("--tiktok-promotes-third-party <yes|no>", "declare third-party promotion", yesOrNo).option("--tiktok-ai-generated <yes|no>", "declare AI-generated TikTok content", yesOrNo).option("--tiktok-cover-timestamp-ms <number>", "video cover timestamp in milliseconds", nonnegativeInteger).option("--tiktok-settings-reviewed", "confirm the TikTok account choices were reviewed; separate from --yes").option("--youtube-caption <text>", "YouTube description override; otherwise the shared caption is used").option("--bluesky-caption <text>", "Bluesky-specific caption override; limited to 300 graphemes").option("--linkedin-caption <text>", "LinkedIn-specific caption override; limited to 3,000 characters").option("--youtube-title <text>", "required YouTube video title").option("--youtube-category-id <id>", "required numeric YouTube video category ID").option("--youtube-privacy <status>", "required PUBLIC, UNLISTED, or PRIVATE visibility", youtubePrivacy).option("--youtube-made-for-kids <yes|no>", "required explicit YouTube audience declaration", yesOrNo).option("--youtube-synthetic-media", "declare realistic altered or synthetic media to YouTube").option("--no-youtube-notify-subscribers", "disable eligible YouTube subscriber notifications").option("--youtube-tag <tag>", "YouTube tag; repeat as needed", collectString, []).option("--idempotency-key <key>", "stable retry key; defaults to the request ID").option("--yes", "confirm creation without an interactive prompt").action(async (local) => {
|
|
1454
1525
|
const global = program.opts();
|
|
1455
1526
|
commandExitCode = await execute({
|
|
1456
1527
|
command: "posts create",
|
|
@@ -1476,9 +1547,10 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1476
1547
|
...local.instagramCaption === void 0 ? {} : { INSTAGRAM: local.instagramCaption },
|
|
1477
1548
|
...local.tiktokCaption === void 0 ? {} : { TIKTOK: local.tiktokCaption },
|
|
1478
1549
|
...local.youtubeCaption === void 0 ? {} : { YOUTUBE: local.youtubeCaption },
|
|
1479
|
-
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption }
|
|
1550
|
+
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption },
|
|
1551
|
+
...local.linkedinCaption === void 0 ? {} : { LINKEDIN: local.linkedinCaption }
|
|
1480
1552
|
},
|
|
1481
|
-
tiktokSettings: null,
|
|
1553
|
+
tiktokSettings: tiktokSettings(local) ?? null,
|
|
1482
1554
|
youtubeSettings: youtubeSettings(local)
|
|
1483
1555
|
};
|
|
1484
1556
|
const post = await client.posts.create(local.project, input, {
|
|
@@ -1494,7 +1566,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1494
1566
|
}
|
|
1495
1567
|
});
|
|
1496
1568
|
});
|
|
1497
|
-
posts.command("update").description("
|
|
1569
|
+
posts.command("update").description("Update selected draft fields using optimistic concurrency").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).option("--caption <text>", "replacement draft caption; omitted fields are preserved").option("--platform <provider>", "replacement destinations; repeat as needed", collectPublishingProvider).option("--clear-platforms", "remove every draft destination").option("--media <asset-id>", "replacement media asset ID; repeat for multiple", collectString).option("--clear-media", "remove every media asset from the draft").option("--instagram-caption <text>", "Instagram-specific caption override").option("--tiktok-caption <text>", "TikTok-specific caption override").option("--tiktok-mode <mode>", "direct publishing or inbox draft delivery", tiktokPostMode).option("--tiktok-visibility <value>", "exact visibility returned by integrations delivery-options").option("--tiktok-comments <yes|no>", "allow TikTok comments", yesOrNo).option("--tiktok-duet <yes|no>", "allow TikTok duets", yesOrNo).option("--tiktok-stitch <yes|no>", "allow TikTok stitches", yesOrNo).option("--tiktok-commercial-content <yes|no>", "declare commercial TikTok content", yesOrNo).option("--tiktok-promotes-own-brand <yes|no>", "declare own-brand promotion", yesOrNo).option("--tiktok-promotes-third-party <yes|no>", "declare third-party promotion", yesOrNo).option("--tiktok-ai-generated <yes|no>", "declare AI-generated TikTok content", yesOrNo).option("--tiktok-cover-timestamp-ms <number>", "video cover timestamp in milliseconds", nonnegativeInteger).option("--tiktok-settings-reviewed", "confirm the TikTok account choices were reviewed; separate from --yes").option("--youtube-caption <text>", "YouTube description override; otherwise the shared caption is used").option("--bluesky-caption <text>", "Bluesky-specific caption override; limited to 300 graphemes").option("--linkedin-caption <text>", "LinkedIn-specific caption override; limited to 3,000 characters").option("--youtube-title <text>", "required YouTube video title").option("--youtube-category-id <id>", "required numeric YouTube video category ID").option("--youtube-privacy <status>", "required PUBLIC, UNLISTED, or PRIVATE visibility", youtubePrivacy).option("--youtube-made-for-kids <yes|no>", "required explicit YouTube audience declaration", yesOrNo).option("--youtube-synthetic-media", "declare realistic altered or synthetic media to YouTube").option("--no-youtube-notify-subscribers", "disable eligible YouTube subscriber notifications").option("--youtube-tag <tag>", "replacement YouTube tag; repeat as needed", collectString).option("--idempotency-key <key>", "stable retry key; defaults to the request ID").option("--yes", "confirm the update without an interactive prompt").action(async (postId, local) => {
|
|
1498
1570
|
const global = program.opts();
|
|
1499
1571
|
commandExitCode = await execute({
|
|
1500
1572
|
command: "posts update",
|
|
@@ -1506,24 +1578,34 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1506
1578
|
global,
|
|
1507
1579
|
runtime,
|
|
1508
1580
|
preview: [
|
|
1509
|
-
`
|
|
1581
|
+
`Update draft ${postId}?`,
|
|
1510
1582
|
`Project: ${local.project}`,
|
|
1511
1583
|
`Expected version: ${local.expectedVersion}`,
|
|
1512
1584
|
"This will not schedule or publish the post."
|
|
1513
1585
|
].join("\n")
|
|
1514
1586
|
});
|
|
1587
|
+
if (local.clearPlatforms && local.platform !== void 0) {
|
|
1588
|
+
throw new TypeError("Use either --platform or --clear-platforms, not both.");
|
|
1589
|
+
}
|
|
1590
|
+
if (local.clearMedia && local.media !== void 0) {
|
|
1591
|
+
throw new TypeError("Use either --media or --clear-media, not both.");
|
|
1592
|
+
}
|
|
1593
|
+
const captionOverrides = {
|
|
1594
|
+
...local.instagramCaption === void 0 ? {} : { INSTAGRAM: local.instagramCaption },
|
|
1595
|
+
...local.tiktokCaption === void 0 ? {} : { TIKTOK: local.tiktokCaption },
|
|
1596
|
+
...local.youtubeCaption === void 0 ? {} : { YOUTUBE: local.youtubeCaption },
|
|
1597
|
+
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption },
|
|
1598
|
+
...local.linkedinCaption === void 0 ? {} : { LINKEDIN: local.linkedinCaption }
|
|
1599
|
+
};
|
|
1600
|
+
const resolvedTikTokSettings = tiktokSettings(local);
|
|
1601
|
+
const resolvedYouTubeSettings = youtubeSettings(local);
|
|
1515
1602
|
const input = {
|
|
1516
|
-
caption: local.caption,
|
|
1517
|
-
platforms: local.platform,
|
|
1518
|
-
mediaAssetIds: local.media,
|
|
1519
|
-
captionOverrides: {
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
...local.youtubeCaption === void 0 ? {} : { YOUTUBE: local.youtubeCaption },
|
|
1523
|
-
...local.blueskyCaption === void 0 ? {} : { BLUESKY: local.blueskyCaption }
|
|
1524
|
-
},
|
|
1525
|
-
tiktokSettings: null,
|
|
1526
|
-
youtubeSettings: youtubeSettings(local)
|
|
1603
|
+
...local.caption === void 0 ? {} : { caption: local.caption },
|
|
1604
|
+
...local.platform === void 0 && !local.clearPlatforms ? {} : { platforms: local.clearPlatforms ? [] : local.platform },
|
|
1605
|
+
...local.media === void 0 && !local.clearMedia ? {} : { mediaAssetIds: local.clearMedia ? [] : local.media },
|
|
1606
|
+
...Object.keys(captionOverrides).length ? { captionOverrides } : {},
|
|
1607
|
+
...resolvedTikTokSettings === void 0 ? {} : { tiktokSettings: resolvedTikTokSettings },
|
|
1608
|
+
...resolvedYouTubeSettings === null ? {} : { youtubeSettings: resolvedYouTubeSettings }
|
|
1527
1609
|
};
|
|
1528
1610
|
const post = await client.posts.update(local.project, postId, input, {
|
|
1529
1611
|
requestId: context.requestId,
|
|
@@ -1661,7 +1743,7 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1661
1743
|
});
|
|
1662
1744
|
});
|
|
1663
1745
|
const publish = posts.command("publish").description("Preview and queue server-confirmed immediate publishing");
|
|
1664
|
-
publish.command("preview").description("Validate exact destinations and issue a five-minute confirmation").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).requiredOption("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, or
|
|
1746
|
+
publish.command("preview").description("Validate exact destinations and issue a five-minute confirmation").argument("<post-id>").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--expected-version <number>", "current post version from posts show", positiveInteger).requiredOption("--platform <provider>", "INSTAGRAM, TIKTOK, YOUTUBE, BLUESKY, or LINKEDIN; repeat as needed", collectPublishingProvider).action(async (postId, local) => {
|
|
1665
1747
|
const global = program.opts();
|
|
1666
1748
|
commandExitCode = await execute({
|
|
1667
1749
|
command: "posts publish preview",
|
|
@@ -1744,6 +1826,27 @@ async function runCli(argv = process.argv, overrides = {}) {
|
|
|
1744
1826
|
}
|
|
1745
1827
|
});
|
|
1746
1828
|
});
|
|
1829
|
+
integrations.command("delivery-options").description("Refresh secret-safe creator delivery choices for one provider").requiredOption("--project <project-id>", "exact Rolino project ID").requiredOption("--provider <provider>", "publishing provider; TIKTOK or LINKEDIN", deliveryOptionsProvider).action(async (local) => {
|
|
1830
|
+
const global = program.opts();
|
|
1831
|
+
commandExitCode = await execute({
|
|
1832
|
+
command: "integrations delivery-options",
|
|
1833
|
+
global,
|
|
1834
|
+
runtime,
|
|
1835
|
+
async action(context, client) {
|
|
1836
|
+
const options = await client.integrations.deliveryOptions(
|
|
1837
|
+
local.project,
|
|
1838
|
+
local.provider,
|
|
1839
|
+
{ requestId: context.requestId }
|
|
1840
|
+
);
|
|
1841
|
+
writeSuccess(
|
|
1842
|
+
context,
|
|
1843
|
+
options,
|
|
1844
|
+
formatProviderDeliveryOptions(options),
|
|
1845
|
+
[`rolino posts create --project ${local.project} --caption <text> --platform ${local.provider} --agent --yes`]
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
});
|
|
1849
|
+
});
|
|
1747
1850
|
const calendar = program.command("calendar").description("Read scheduled publishing events");
|
|
1748
1851
|
calendar.command("list").description("List scheduled posts in a bounded calendar window").requiredOption("--project <project-id>", "exact Rolino project ID").option("--from <datetime>", "inclusive ISO-8601 window start", isoDateTime).option("--to <datetime>", "exclusive ISO-8601 window end", isoDateTime).option("--limit <number>", "maximum events to return", (value) => {
|
|
1749
1852
|
const parsed = Number(value);
|