@letterstory/cli 0.11.0 → 0.13.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/lib/cli.mjs +27 -7
- package/lib/commands/connectors.mjs +99 -1
- package/lib/commands/onboard.mjs +2 -0
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
} from "./commands.mjs";
|
|
41
41
|
|
|
42
42
|
// Keep in sync with cli/package.json.
|
|
43
|
-
export const VERSION = "0.
|
|
43
|
+
export const VERSION = "0.13.0";
|
|
44
44
|
|
|
45
45
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
46
46
|
// can't accidentally swallow the id as --json's value.
|
|
@@ -64,6 +64,10 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
64
64
|
// both put a value-less flag next to a value: without these entries the parser
|
|
65
65
|
// hands the following token to the flag and the real argument disappears.
|
|
66
66
|
"regenerate",
|
|
67
|
+
// `connectors connect --provider framer --token … --auto-deploy` / `--no-auto-deploy`
|
|
68
|
+
// are value-less; without these the parser eats the following token.
|
|
69
|
+
"auto-deploy",
|
|
70
|
+
"no-auto-deploy",
|
|
67
71
|
"stock-only",
|
|
68
72
|
"gate",
|
|
69
73
|
"skip",
|
|
@@ -203,6 +207,21 @@ Connectors:
|
|
|
203
207
|
[--confirm-missing-target] re-publish even though
|
|
204
208
|
the item was deleted/unpublished on the provider
|
|
205
209
|
connectors status --connector <connector> --publish-id <id>
|
|
210
|
+
connectors pull [--collection <uuid>] [--provider <webflow|framer|sanity|contentful>]
|
|
211
|
+
Pull existing posts FROM a connected CMS into a
|
|
212
|
+
collection, reconciling (adopt/update/create/orphan).
|
|
213
|
+
--collection for a bound collection, --provider to
|
|
214
|
+
auto-resolve, or both to wire an unbound collection.
|
|
215
|
+
connectors connect --provider <p> --token <api-token>
|
|
216
|
+
Save + validate CMS credentials. framer also needs
|
|
217
|
+
--project-url (+ [--no-auto-deploy]); sanity needs
|
|
218
|
+
--project-id [--dataset]; contentful needs --space-id
|
|
219
|
+
[--environment].
|
|
220
|
+
connectors disconnect --provider <p> Forget a CMS connection (keeps imported posts)
|
|
221
|
+
connectors connections Show connection status for every provider
|
|
222
|
+
connectors mappings --provider <p> List the org's field mappings for a provider
|
|
223
|
+
connectors bind --collection <uuid> --provider <p> [--mapping <uuid>]
|
|
224
|
+
Wire a collection to a CMS + field mapping
|
|
206
225
|
|
|
207
226
|
Strategy & onboarding:
|
|
208
227
|
strategy company get | set [--name] [--domain] [--manifesto <text>|--manifesto-file <path>]
|
|
@@ -270,14 +289,15 @@ Phantom onboarding recipe (domain -> live phantom blog with first posts):
|
|
|
270
289
|
|
|
271
290
|
Collection onboarding (your OWN blog, on your org's domain — no provisioning):
|
|
272
291
|
${bin === "phantom" ? "onboard" : "phantom-onboard"} collection [--collection <uuid>] [--name "<collection name>"]
|
|
273
|
-
[--about "the direction"] [--sitemap <url>] [--watch]
|
|
292
|
+
[--about "the direction"] [--sitemap <url>] [--cms <provider>] [--watch]
|
|
274
293
|
Import the existing blog from its sitemap
|
|
275
294
|
(auto-discovered from the org's domain unless
|
|
276
|
-
--sitemap pins one)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
295
|
+
--sitemap pins one) OR from a connected CMS with
|
|
296
|
+
--cms <webflow|framer|sanity|contentful>, then
|
|
297
|
+
derive content areas + series, build the topic
|
|
298
|
+
map, bind SEO demand, and stock Headlines & Queue.
|
|
299
|
+
Omit --collection to create a fresh one (--name,
|
|
300
|
+
default Blog). The Planner stays OFF (manual approval).
|
|
281
301
|
${bin === "phantom" ? "onboard" : "phantom-onboard"} sync-sitemap --collection <uuid>
|
|
282
302
|
Re-check an already-onboarded blog's sitemap
|
|
283
303
|
right now instead of waiting for its cadence
|
|
@@ -17,8 +17,23 @@ export async function cmdConnectors(ctx) {
|
|
|
17
17
|
return connectorsPublish(rest);
|
|
18
18
|
case "status":
|
|
19
19
|
return connectorsStatus(rest);
|
|
20
|
+
case "pull":
|
|
21
|
+
case "import":
|
|
22
|
+
return connectorsPull(rest);
|
|
23
|
+
case "connect":
|
|
24
|
+
return connectorsConnect(rest);
|
|
25
|
+
case "disconnect":
|
|
26
|
+
return connectorsDisconnect(rest);
|
|
27
|
+
case "connections":
|
|
28
|
+
return connectorsConnections(rest);
|
|
29
|
+
case "mappings":
|
|
30
|
+
return connectorsMappings(rest);
|
|
31
|
+
case "bind":
|
|
32
|
+
return connectorsBind(rest);
|
|
20
33
|
default:
|
|
21
|
-
throw new CliError(
|
|
34
|
+
throw new CliError(
|
|
35
|
+
`Unknown connectors subcommand: ${sub ?? "(none)"}. Try: list, publish, status, pull, connect, disconnect, connections, mappings, bind`
|
|
36
|
+
);
|
|
22
37
|
}
|
|
23
38
|
}
|
|
24
39
|
|
|
@@ -59,3 +74,86 @@ async function connectorsStatus(ctx) {
|
|
|
59
74
|
printResult(io, flags, result);
|
|
60
75
|
return 0;
|
|
61
76
|
}
|
|
77
|
+
|
|
78
|
+
async function connectorsPull(ctx) {
|
|
79
|
+
const { client, flags, io } = ctx;
|
|
80
|
+
// Dual key: --collection (a CMS-bound collection), or --provider (resolve/wire),
|
|
81
|
+
// or both (--provider wires an unbound --collection first). At least one required.
|
|
82
|
+
const collectionId = flagStr(flags.collection);
|
|
83
|
+
const provider = flagStr(flags.provider);
|
|
84
|
+
if (!collectionId && !provider) {
|
|
85
|
+
throw new CliError("Pass --collection <id> and/or --provider <webflow|framer|sanity|contentful>");
|
|
86
|
+
}
|
|
87
|
+
const args = compact({ collection_id: collectionId, provider });
|
|
88
|
+
const result = await client.callTool("import_from_cms", args);
|
|
89
|
+
ok(
|
|
90
|
+
ctx,
|
|
91
|
+
`Pulled from ${result?.provider ?? provider ?? "CMS"} into collection ${result?.collection_id ?? collectionId ?? ""}.`
|
|
92
|
+
);
|
|
93
|
+
printResult(io, flags, result);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function connectorsConnect(ctx) {
|
|
98
|
+
const { client, flags, io } = ctx;
|
|
99
|
+
const provider = requireFlag(flags, "provider");
|
|
100
|
+
// api_token is required for every provider; the rest are provider-specific.
|
|
101
|
+
const args = compact({
|
|
102
|
+
provider,
|
|
103
|
+
api_token: requireFlag(flags, "token"),
|
|
104
|
+
project_url: flagStr(flags["project-url"]),
|
|
105
|
+
auto_deploy: flags["no-auto-deploy"] ? false : flagBool(flags["auto-deploy"]) || undefined,
|
|
106
|
+
project_id: flagStr(flags["project-id"]),
|
|
107
|
+
dataset: flagStr(flags.dataset),
|
|
108
|
+
project_name: flagStr(flags["project-name"]),
|
|
109
|
+
workspace_name: flagStr(flags.workspace),
|
|
110
|
+
space_id: flagStr(flags["space-id"]),
|
|
111
|
+
environment_id: flagStr(flags.environment),
|
|
112
|
+
space_name: flagStr(flags["space-name"]),
|
|
113
|
+
default_locale: flagStr(flags.locale),
|
|
114
|
+
});
|
|
115
|
+
const result = await client.callTool("connect_cms", args);
|
|
116
|
+
ok(ctx, `Connected ${provider}${result?.label ? ` (${result.label})` : ""}.`);
|
|
117
|
+
printResult(io, flags, result);
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function connectorsDisconnect(ctx) {
|
|
122
|
+
const { client, flags, io } = ctx;
|
|
123
|
+
const provider = requireFlag(flags, "provider");
|
|
124
|
+
const result = await client.callTool("disconnect_cms", { provider });
|
|
125
|
+
ok(ctx, `Disconnected ${provider}.`);
|
|
126
|
+
printResult(io, flags, result);
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function connectorsConnections(ctx) {
|
|
131
|
+
const { client, flags, io } = ctx;
|
|
132
|
+
const result = await client.callTool("list_cms_connections", {});
|
|
133
|
+
printResult(io, flags, result);
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function connectorsMappings(ctx) {
|
|
138
|
+
const { client, flags, io } = ctx;
|
|
139
|
+
const provider = requireFlag(flags, "provider");
|
|
140
|
+
const result = await client.callTool("list_cms_mappings", { provider });
|
|
141
|
+
printResult(io, flags, result);
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function connectorsBind(ctx) {
|
|
146
|
+
const { client, flags, io } = ctx;
|
|
147
|
+
const args = compact({
|
|
148
|
+
collection_id: requireFlag(flags, "collection"),
|
|
149
|
+
provider: requireFlag(flags, "provider"),
|
|
150
|
+
mapping_id: flagStr(flags.mapping),
|
|
151
|
+
});
|
|
152
|
+
const result = await client.callTool("bind_collection_cms", args);
|
|
153
|
+
ok(
|
|
154
|
+
ctx,
|
|
155
|
+
`Bound collection ${result?.collection_id ?? ""} to ${result?.provider ?? ""} (mapping ${result?.mapping_id ?? ""}).`
|
|
156
|
+
);
|
|
157
|
+
printResult(io, flags, result);
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
package/lib/commands/onboard.mjs
CHANGED
|
@@ -140,6 +140,8 @@ async function cmdOnboardCollection(ctx) {
|
|
|
140
140
|
collection_name: flagStr(flags.name),
|
|
141
141
|
direction: flagStr(flags.about) ?? flagStr(flags.direction),
|
|
142
142
|
sitemap_url: flagStr(flags.sitemap),
|
|
143
|
+
// Source the existing blog from a connected CMS instead of a sitemap.
|
|
144
|
+
cms_provider: flagStr(flags.cms),
|
|
143
145
|
});
|
|
144
146
|
|
|
145
147
|
ok(ctx, "Starting collection onboarding…");
|