@usesocial/cli 0.3.0 → 0.3.2
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 +12 -0
- package/README.md +5 -4
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +75 -70
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @usesocial/cli
|
|
2
2
|
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#12](https://github.com/usesocial/monorepo/pull/12) [`a85b525`](https://github.com/usesocial/monorepo/commit/a85b525d36908cf25da92a0538b77ac39eb817c6) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Read structured write payloads from stdin as JSON objects and remove `--body` from stdin-backed post, comment, and message commands. Plain stdin still becomes body text; valid non-object JSON now fails fast instead of being sent.
|
|
8
|
+
|
|
9
|
+
## 0.3.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#11](https://github.com/usesocial/monorepo/pull/11) [`60bc3e0`](https://github.com/usesocial/monorepo/commit/60bc3e003bf751a02c637e1a93a43f44353cd9a5) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Price LinkedIn connections as following and follower reads.
|
|
14
|
+
|
|
3
15
|
## 0.3.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -74,8 +74,7 @@ connected account.
|
|
|
74
74
|
### Body text
|
|
75
75
|
|
|
76
76
|
Commands that create a post, comment, message, or connection note read the body
|
|
77
|
-
from **stdin** — there is no text argument. Pipe it in
|
|
78
|
-
JSON object:
|
|
77
|
+
from **stdin** — there is no text argument. Pipe it in:
|
|
79
78
|
|
|
80
79
|
```sh
|
|
81
80
|
echo "gm" | social x post
|
|
@@ -83,8 +82,9 @@ social linkedin post < draft.md
|
|
|
83
82
|
social linkedin requests send @handle < note.txt # optional connection note
|
|
84
83
|
```
|
|
85
84
|
|
|
86
|
-
On an interactive terminal with nothing piped
|
|
87
|
-
|
|
85
|
+
On an interactive terminal with nothing piped, required body-text commands fail
|
|
86
|
+
fast rather than hang. To send advanced payload fields, pipe a JSON object via
|
|
87
|
+
stdin; if stdin parses as JSON but is not an object, the command rejects it.
|
|
88
88
|
|
|
89
89
|
### Top level
|
|
90
90
|
|
|
@@ -292,6 +292,7 @@ social linkedin requests sent --limit 25 --offset 0
|
|
|
292
292
|
social x bookmarks --limit 50
|
|
293
293
|
social x followers --limit 100
|
|
294
294
|
social x following profile_id:<x-user-id> --limit 100
|
|
295
|
+
social x replies post_id:<post-id> --limit 25
|
|
295
296
|
social x messages --limit 50
|
|
296
297
|
|
|
297
298
|
# Writes (body via stdin)
|
package/dist/index.d.mts
CHANGED
|
@@ -1397,6 +1397,7 @@ declare const createSocialCommand: (deps?: {
|
|
|
1397
1397
|
parseQueryString: (name: string, value: unknown) => string;
|
|
1398
1398
|
parseBodyText: (name: string, value: unknown) => string;
|
|
1399
1399
|
readStdin: () => Promise<string>;
|
|
1400
|
+
isStdinTTY: () => boolean;
|
|
1400
1401
|
parseIntegerString: (name: string, value: unknown, options?: {
|
|
1401
1402
|
min?: number;
|
|
1402
1403
|
max?: number;
|
package/dist/index.mjs
CHANGED
|
@@ -11367,10 +11367,18 @@ const { costBPSForCategory: costBPSForCategory$1 } = createPricing([
|
|
|
11367
11367
|
"unitPriceUSD": .015,
|
|
11368
11368
|
"featureId": "user_interaction_create_request"
|
|
11369
11369
|
},
|
|
11370
|
+
{
|
|
11371
|
+
"key": "following_read",
|
|
11372
|
+
"label": "Following/Followers: Read",
|
|
11373
|
+
"description": "Read LinkedIn connections, priced to match X following and followers reads.",
|
|
11374
|
+
"unit": "per_resource",
|
|
11375
|
+
"unitPriceUSD": .01,
|
|
11376
|
+
"featureId": "following_followers_read_resource"
|
|
11377
|
+
},
|
|
11370
11378
|
{
|
|
11371
11379
|
"key": "owned_read",
|
|
11372
11380
|
"label": "Owned: Read",
|
|
11373
|
-
"description": "Read the connected LinkedIn account's own profile
|
|
11381
|
+
"description": "Read the connected LinkedIn account's own profile.",
|
|
11374
11382
|
"unit": "per_resource",
|
|
11375
11383
|
"unitPriceUSD": .001,
|
|
11376
11384
|
"featureId": "owned_read_resource"
|
|
@@ -12070,8 +12078,8 @@ const LINKEDIN_OPERATIONS = [
|
|
|
12070
12078
|
totalCountPath: "total_count",
|
|
12071
12079
|
itemsPath: "data"
|
|
12072
12080
|
},
|
|
12073
|
-
costBPS:
|
|
12074
|
-
billingCategory: "
|
|
12081
|
+
costBPS: 100,
|
|
12082
|
+
billingCategory: "following_read",
|
|
12075
12083
|
kind: "users"
|
|
12076
12084
|
},
|
|
12077
12085
|
parameters: [
|
|
@@ -12963,6 +12971,7 @@ const positionalDisplayKeyFor$1 = (op, param) => op.config.paramLabels?.[param.n
|
|
|
12963
12971
|
const bodyTextDisplayKeyFor$1 = (op) => op.config.bodyTextArg === void 0 ? void 0 : op.config.paramLabels?.[op.config.bodyTextArg] ?? op.config.bodyTextArg;
|
|
12964
12972
|
const hasStdinBodyText$1 = (op) => op.config.bodyTextArg !== void 0;
|
|
12965
12973
|
const stdinBodyTextRequired$1 = (op) => hasStdinBodyText$1(op) && op.config.bodyTextRequired !== false;
|
|
12974
|
+
const hasBodyOption = (op) => op.hasBody && !hasStdinBodyText$1(op);
|
|
12966
12975
|
const idempotencyFor$1 = (op) => {
|
|
12967
12976
|
if (op.endpoint.capability === "read") return {
|
|
12968
12977
|
safe: true,
|
|
@@ -13054,7 +13063,7 @@ const exampleCommandFor$1 = (op, commandName, root) => {
|
|
|
13054
13063
|
parts.push(param.in === "path" || param.kind !== "array" ? hint : `${hint}...`);
|
|
13055
13064
|
}
|
|
13056
13065
|
if (hasStdinBodyText$1(op)) return `echo "..." | ${parts.join(" ")}`;
|
|
13057
|
-
if (op
|
|
13066
|
+
if (hasBodyOption(op)) parts.push("--body", "'{...}'");
|
|
13058
13067
|
return parts.join(" ");
|
|
13059
13068
|
};
|
|
13060
13069
|
const operationModeFor$1 = (op) => {
|
|
@@ -13098,7 +13107,7 @@ const helpDescriptionFor$1 = (op, commandName, root) => {
|
|
|
13098
13107
|
...root ? [] : [op.config.group],
|
|
13099
13108
|
commandName
|
|
13100
13109
|
].join(" ");
|
|
13101
|
-
return `${description} | ${usage}${hasStdinBodyText$1(op) ? ` | body text is read from stdin: \`echo "..." | ${label}
|
|
13110
|
+
return `${description} | ${usage}${hasStdinBodyText$1(op) ? ` | body text is read from stdin: \`echo "..." | ${label}\`` : ""}`;
|
|
13102
13111
|
};
|
|
13103
13112
|
const commandPathFor = (op) => `linkedin ${op.config.root ? op.config.command : `${op.config.group} ${op.config.command}`}`;
|
|
13104
13113
|
const contractInputSchemaName = (op) => op.hasBody ? `${op.schemaBaseName}ContractInput` : `${op.schemaBaseName}Input`;
|
|
@@ -13152,7 +13161,7 @@ const buildArgs$1 = (op) => {
|
|
|
13152
13161
|
description: param.description
|
|
13153
13162
|
};
|
|
13154
13163
|
}
|
|
13155
|
-
if (op
|
|
13164
|
+
if (hasBodyOption(op)) args.body = {
|
|
13156
13165
|
type: "string",
|
|
13157
13166
|
description: "JSON request body"
|
|
13158
13167
|
};
|
|
@@ -13244,7 +13253,7 @@ const buildBody = (deps, op, input) => {
|
|
|
13244
13253
|
const bodyTextArg = op.config.bodyTextArg;
|
|
13245
13254
|
const bodyParamEntries = Object.entries(op.config.bodyParams ?? {});
|
|
13246
13255
|
if (!bodyTextArg && bodyParamEntries.length === 0) return input.body === void 0 ? void 0 : deps.parseJSONObject("--body", input.body);
|
|
13247
|
-
const bodyFromJSON = input.body === void 0 ? void 0 : deps.parseJSONObject("--body", input.body);
|
|
13256
|
+
const bodyFromJSON = input.body === void 0 ? void 0 : deps.parseJSONObject(hasStdinBodyText$1(op) ? "stdin" : "--body", input.body);
|
|
13248
13257
|
const bodyText = bodyTextArg && input[bodyTextArg] !== void 0 ? deps.parseBodyText(`<${bodyTextDisplayKeyFor$1(op) ?? bodyTextArg}>`, input[bodyTextArg]) : void 0;
|
|
13249
13258
|
const bodyParamValues = /* @__PURE__ */ new Map();
|
|
13250
13259
|
for (const [name, param] of bodyParamEntries) {
|
|
@@ -13258,7 +13267,7 @@ const buildBody = (deps, op, input) => {
|
|
|
13258
13267
|
}
|
|
13259
13268
|
if (bodyTextArg && bodyText !== void 0) body[bodyTextArg] = bodyText;
|
|
13260
13269
|
if (op.config.bodyTextRequired !== false && (Boolean(bodyTextArg) || bodyParamEntries.some(([, param]) => param.required)) && bodyFromJSON === void 0) {
|
|
13261
|
-
if ((bodyTextArg ? bodyText === void 0 : false) || bodyParamEntries.some(([name, param]) => param.required && bodyParamValues.get(name) === void 0)) throw new UsageError(bodyTextArg && bodyParamEntries.length === 0 ? `Pass <${bodyTextDisplayKeyFor$1(op) ?? bodyTextArg}
|
|
13270
|
+
if ((bodyTextArg ? bodyText === void 0 : false) || bodyParamEntries.some(([name, param]) => param.required && bodyParamValues.get(name) === void 0)) throw new UsageError(bodyTextArg && bodyParamEntries.length === 0 ? `Pass <${bodyTextDisplayKeyFor$1(op) ?? bodyTextArg}>.` : "Pass required body positional arguments or --body.");
|
|
13262
13271
|
}
|
|
13263
13272
|
return body;
|
|
13264
13273
|
};
|
|
@@ -13268,7 +13277,7 @@ const checkBodyRequired = (op, args) => {
|
|
|
13268
13277
|
const bodyTextArg = op.config.bodyTextArg;
|
|
13269
13278
|
if (bodyTextArg && op.config.bodyTextRequired !== false) expressions.push(args[bodyTextDisplayKeyFor$1(op) ?? bodyTextArg] === void 0);
|
|
13270
13279
|
for (const [name, param] of Object.entries(op.config.bodyParams ?? {})) if (param.required) expressions.push(args[flagName(bodyParamArg(name, param))] === void 0);
|
|
13271
|
-
if (expressions.length > 0 && typeof args.body !== "string" && expressions.some(Boolean)) throw new UsageError(op.config.bodyTextArg && Object.keys(op.config.bodyParams ?? {}).length === 0 ? `Pass <${bodyTextDisplayKeyFor$1(op) ?? op.config.bodyTextArg}
|
|
13280
|
+
if (expressions.length > 0 && typeof args.body !== "string" && expressions.some(Boolean)) throw new UsageError(op.config.bodyTextArg && Object.keys(op.config.bodyParams ?? {}).length === 0 ? `Pass <${bodyTextDisplayKeyFor$1(op) ?? op.config.bodyTextArg}>.` : "Pass required body positional arguments or --body.");
|
|
13272
13281
|
};
|
|
13273
13282
|
const dataWithAuditableWriteTarget = (op, data, body) => {
|
|
13274
13283
|
if (op.schemaBaseName !== "PostsReact") return data;
|
|
@@ -13281,18 +13290,27 @@ const dataWithAuditableWriteTarget = (op, data, body) => {
|
|
|
13281
13290
|
};
|
|
13282
13291
|
};
|
|
13283
13292
|
const trimTrailingNewline$1 = (value) => value.endsWith("\r\n") ? value.slice(0, -2) : value.endsWith("\n") ? value.slice(0, -1) : value;
|
|
13284
|
-
const noBodyTextError$1 = (commandLabel) => new UsageError(`No body text. Pipe it via stdin: \`echo "..." | ${commandLabel}
|
|
13293
|
+
const noBodyTextError$1 = (commandLabel) => new UsageError(`No body text. Pipe it via stdin: \`echo "..." | ${commandLabel}\`.`);
|
|
13294
|
+
const parseStdinBody$1 = (deps, bodyTextName, bodyTextKey, value) => {
|
|
13295
|
+
try {
|
|
13296
|
+
JSON.parse(value);
|
|
13297
|
+
} catch {
|
|
13298
|
+
return { [bodyTextKey]: deps.parseBodyText(`<${bodyTextName}>`, value) };
|
|
13299
|
+
}
|
|
13300
|
+
return deps.parseJSONObject("stdin", value);
|
|
13301
|
+
};
|
|
13285
13302
|
const resolveBodyTextFromStdin$1 = async (op, deps, args, commandLabel) => {
|
|
13286
13303
|
if (!hasStdinBodyText$1(op)) return;
|
|
13287
|
-
const bodyTextArg =
|
|
13304
|
+
const bodyTextArg = op.config.bodyTextArg;
|
|
13288
13305
|
if (bodyTextArg === void 0) return;
|
|
13289
|
-
const
|
|
13290
|
-
|
|
13306
|
+
const displayTextArg = bodyTextDisplayKeyFor$1(op) ?? bodyTextArg;
|
|
13307
|
+
const required = stdinBodyTextRequired$1(op);
|
|
13308
|
+
if (deps.isStdinTTY()) {
|
|
13291
13309
|
if (required) throw noBodyTextError$1(commandLabel);
|
|
13292
13310
|
return;
|
|
13293
13311
|
}
|
|
13294
13312
|
const piped = trimTrailingNewline$1(await deps.readStdin());
|
|
13295
|
-
if (piped.length > 0) args
|
|
13313
|
+
if (piped.length > 0) args.body = JSON.stringify(parseStdinBody$1(deps, displayTextArg, bodyTextArg, piped));
|
|
13296
13314
|
else if (required) throw noBodyTextError$1(commandLabel);
|
|
13297
13315
|
};
|
|
13298
13316
|
const runOperation$1 = async (op, contract, deps, args, rawArgs = []) => {
|
|
@@ -13940,7 +13958,7 @@ const buildMessageEdit = (deps) => {
|
|
|
13940
13958
|
const account = typeof args.account === "string" ? args.account : void 0;
|
|
13941
13959
|
const message_id = messageIdFrom(deps, args.message_id ?? positionals[1]);
|
|
13942
13960
|
let textInput;
|
|
13943
|
-
if (
|
|
13961
|
+
if (deps.isStdinTTY()) throw noBodyTextError$1("social linkedin message <target> edit message_id:<id>");
|
|
13944
13962
|
const piped = trimTrailingNewline$1(await deps.readStdin());
|
|
13945
13963
|
if (piped.length > 0) textInput = piped;
|
|
13946
13964
|
const text = textInput === void 0 ? void 0 : deps.parseBodyText("<text>", textInput);
|
|
@@ -13981,7 +13999,7 @@ const buildMessage$1 = (deps, sendCommand) => {
|
|
|
13981
13999
|
return defineCommand({
|
|
13982
14000
|
meta: commandMeta$2({
|
|
13983
14001
|
name: "message",
|
|
13984
|
-
description: "Send a LinkedIn message to a person or conversation [write] | usage: `social linkedin message <target> < body-text` | body text is read from stdin: `echo \"...\" | social linkedin message <target>`
|
|
14002
|
+
description: "Send a LinkedIn message to a person or conversation [write] | usage: `social linkedin message <target> < body-text` | body text is read from stdin: `echo \"...\" | social linkedin message <target>`",
|
|
13985
14003
|
method: "POST",
|
|
13986
14004
|
capability: "write",
|
|
13987
14005
|
mutates: true,
|
|
@@ -13999,10 +14017,6 @@ const buildMessage$1 = (deps, sendCommand) => {
|
|
|
13999
14017
|
description: "LinkedIn person or conversation target: @handle, profile URL, profile_id:<id>, chat_id:<id>, or a messaging thread URL",
|
|
14000
14018
|
valueHint: "target"
|
|
14001
14019
|
},
|
|
14002
|
-
body: {
|
|
14003
|
-
type: "string",
|
|
14004
|
-
description: "JSON request body"
|
|
14005
|
-
},
|
|
14006
14020
|
account: {
|
|
14007
14021
|
type: "string",
|
|
14008
14022
|
description: "Account selector: @handle or profile_id:<id>; overrides config default"
|
|
@@ -14010,6 +14024,7 @@ const buildMessage$1 = (deps, sendCommand) => {
|
|
|
14010
14024
|
},
|
|
14011
14025
|
run: async ({ args }) => {
|
|
14012
14026
|
const positionals = Array.isArray(args._) ? args._.map(String) : [];
|
|
14027
|
+
if (typeof args.body === "string") throw new UsageError("Unsupported option --body for linkedin message.");
|
|
14013
14028
|
if (positionals[1] === "delete" || positionals[1] === "edit") {
|
|
14014
14029
|
const verbCommand = positionals[1] === "delete" ? deleteCommand : editCommand;
|
|
14015
14030
|
await verbCommand.run?.({
|
|
@@ -14025,23 +14040,13 @@ const buildMessage$1 = (deps, sendCommand) => {
|
|
|
14025
14040
|
return;
|
|
14026
14041
|
}
|
|
14027
14042
|
const target = args.target ?? (Array.isArray(args._) && args._.length > 0 ? args._[0] : void 0);
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14031
|
-
|
|
14032
|
-
|
|
14033
|
-
const piped = trimTrailingNewline$1(await deps.readStdin());
|
|
14034
|
-
if (piped.length > 0) textInput = piped;
|
|
14035
|
-
else if (!hasBody) throw noBodyTextError$1("social linkedin message <target>");
|
|
14036
|
-
}
|
|
14043
|
+
let body;
|
|
14044
|
+
if (deps.isStdinTTY()) throw noBodyTextError$1("social linkedin message <target>");
|
|
14045
|
+
const piped = trimTrailingNewline$1(await deps.readStdin());
|
|
14046
|
+
if (piped.length > 0) body = parseStdinBody$1(deps, "text", "text", piped);
|
|
14047
|
+
else throw noBodyTextError$1("social linkedin message <target>");
|
|
14037
14048
|
if (target === void 0) throw new UsageError("Pass a conversation or person target.");
|
|
14038
|
-
|
|
14039
|
-
const text = textInput === void 0 ? void 0 : deps.parseBodyText("<text>", textInput);
|
|
14040
|
-
const body = text === void 0 ? bodyFromJSON : {
|
|
14041
|
-
...bodyFromJSON ?? {},
|
|
14042
|
-
text
|
|
14043
|
-
};
|
|
14044
|
-
if (body === void 0 || typeof body.text !== "string") throw new UsageError("Pass <text> or --body.");
|
|
14049
|
+
if (body === void 0 || typeof body.text !== "string") throw new UsageError("Pass body text via stdin.");
|
|
14045
14050
|
const account = typeof args.account === "string" ? args.account : void 0;
|
|
14046
14051
|
const classified = await deps.classifyMessageTarget("target", target, {
|
|
14047
14052
|
platform: "linkedin",
|
|
@@ -14286,6 +14291,7 @@ createLinkedinCommands({
|
|
|
14286
14291
|
parseQueryString: unconfigured$1,
|
|
14287
14292
|
parseBodyText: unconfigured$1,
|
|
14288
14293
|
readStdin: unconfigured$1,
|
|
14294
|
+
isStdinTTY: unconfigured$1,
|
|
14289
14295
|
parseIntegerString: unconfigured$1,
|
|
14290
14296
|
parseEnumString: unconfigured$1,
|
|
14291
14297
|
parseBooleanString: unconfigured$1,
|
|
@@ -17146,14 +17152,14 @@ const operationModeFor = (op) => {
|
|
|
17146
17152
|
if (op.endpoint.method === "DELETE") return "destructive";
|
|
17147
17153
|
return op.endpoint.mutates ? "write" : "read";
|
|
17148
17154
|
};
|
|
17149
|
-
const signaturePartFor = (
|
|
17155
|
+
const signaturePartFor = (_op, name, arg) => {
|
|
17150
17156
|
if (!isObjectRecord$1(arg)) return;
|
|
17151
17157
|
if (arg.type === "positional") {
|
|
17152
17158
|
const valueHint = typeof arg.valueHint === "string" ? arg.valueHint : name;
|
|
17153
17159
|
return arg.required === true ? `<${valueHint}>` : `[${valueHint}]`;
|
|
17154
17160
|
}
|
|
17155
17161
|
if (name === "limit") return "--limit N";
|
|
17156
|
-
if (name === "body"
|
|
17162
|
+
if (name === "body") return "--body JSON";
|
|
17157
17163
|
};
|
|
17158
17164
|
const stdinSignaturePart = (op) => hasStdinBodyText(op) ? "< body-text" : void 0;
|
|
17159
17165
|
const usageFor = (op, commandName, group) => {
|
|
@@ -17182,7 +17188,7 @@ const helpDescriptionFor = (op, commandName, group) => {
|
|
|
17182
17188
|
group,
|
|
17183
17189
|
commandName
|
|
17184
17190
|
].filter(Boolean).join(" ");
|
|
17185
|
-
return `${description} | ${usage}${hasStdinBodyText(op) ? ` | body text is read from stdin: \`echo "..." | ${label}
|
|
17191
|
+
return `${description} | ${usage}${hasStdinBodyText(op) ? ` | body text is read from stdin: \`echo "..." | ${label}\`` : ""}`;
|
|
17186
17192
|
};
|
|
17187
17193
|
const contractFor$1 = (op, commandName, group) => {
|
|
17188
17194
|
const mutates = op.endpoint.mutates;
|
|
@@ -17228,7 +17234,7 @@ const buildArgs = (op) => {
|
|
|
17228
17234
|
description: param.description
|
|
17229
17235
|
};
|
|
17230
17236
|
}
|
|
17231
|
-
if (op.hasBody) args.body = {
|
|
17237
|
+
if (op.hasBody && !hasStdinBodyText(op)) args.body = {
|
|
17232
17238
|
type: "string",
|
|
17233
17239
|
description: "JSON request body"
|
|
17234
17240
|
};
|
|
@@ -17374,18 +17380,27 @@ const withEchoedTargetId = (op, data, body) => {
|
|
|
17374
17380
|
};
|
|
17375
17381
|
};
|
|
17376
17382
|
const trimTrailingNewline = (value) => value.endsWith("\r\n") ? value.slice(0, -2) : value.endsWith("\n") ? value.slice(0, -1) : value;
|
|
17377
|
-
const noBodyTextError = (commandLabel) => new UsageError(`No body text. Pipe it via stdin: \`echo "..." | ${commandLabel}
|
|
17383
|
+
const noBodyTextError = (commandLabel) => new UsageError(`No body text. Pipe it via stdin: \`echo "..." | ${commandLabel}\`.`);
|
|
17384
|
+
const parseStdinBody = (deps, bodyTextName, bodyTextKey, value) => {
|
|
17385
|
+
try {
|
|
17386
|
+
JSON.parse(value);
|
|
17387
|
+
} catch {
|
|
17388
|
+
return { [bodyTextKey]: deps.parseBodyText(`<${bodyTextName}>`, value) };
|
|
17389
|
+
}
|
|
17390
|
+
return deps.parseJSONObject("stdin", value);
|
|
17391
|
+
};
|
|
17378
17392
|
const resolveBodyTextFromStdin = async (op, deps, args, commandLabel) => {
|
|
17379
17393
|
if (!hasStdinBodyText(op)) return;
|
|
17380
|
-
const bodyTextArg =
|
|
17394
|
+
const bodyTextArg = op.config.bodyTextArg;
|
|
17381
17395
|
if (bodyTextArg === void 0) return;
|
|
17382
|
-
const
|
|
17383
|
-
|
|
17396
|
+
const displayTextArg = bodyTextDisplayKeyFor(op) ?? bodyTextArg;
|
|
17397
|
+
const required = stdinBodyTextRequired(op);
|
|
17398
|
+
if (deps.isStdinTTY()) {
|
|
17384
17399
|
if (required) throw noBodyTextError(commandLabel);
|
|
17385
17400
|
return;
|
|
17386
17401
|
}
|
|
17387
17402
|
const piped = trimTrailingNewline(await deps.readStdin());
|
|
17388
|
-
if (piped.length > 0) args
|
|
17403
|
+
if (piped.length > 0) args.body = JSON.stringify(parseStdinBody(deps, displayTextArg, bodyTextArg, piped));
|
|
17389
17404
|
else if (required) throw noBodyTextError(commandLabel);
|
|
17390
17405
|
};
|
|
17391
17406
|
const runOperation = async (op, contract, deps, args, rawArgs = []) => {
|
|
@@ -17474,7 +17489,7 @@ const runOperation = async (op, contract, deps, args, rawArgs = []) => {
|
|
|
17474
17489
|
};
|
|
17475
17490
|
let body;
|
|
17476
17491
|
if (op.hasBody) {
|
|
17477
|
-
const bodyFromJSON = input.body === void 0 ? void 0 : deps.parseJSONObject("--body", input.body);
|
|
17492
|
+
const bodyFromJSON = input.body === void 0 ? void 0 : deps.parseJSONObject(hasStdinBodyText(op) ? "stdin" : "--body", input.body);
|
|
17478
17493
|
const textArg = op.config.bodyTextArg;
|
|
17479
17494
|
if (textArg) {
|
|
17480
17495
|
const displayTextArg = bodyTextDisplayKeyFor(op) ?? textArg;
|
|
@@ -17937,7 +17952,7 @@ const buildMessage = (deps) => {
|
|
|
17937
17952
|
return defineCommand({
|
|
17938
17953
|
meta: commandMeta$1({
|
|
17939
17954
|
name: "message",
|
|
17940
|
-
description: "Send a DM to a participant or conversation [write] | usage: `social x message <recipients> < body-text` | body text is read from stdin: `echo \"...\" | social x message <recipients>`
|
|
17955
|
+
description: "Send a DM to a participant or conversation [write] | usage: `social x message <recipients> < body-text` | body text is read from stdin: `echo \"...\" | social x message <recipients>`",
|
|
17941
17956
|
method: "POST",
|
|
17942
17957
|
capability: "write",
|
|
17943
17958
|
mutates: true,
|
|
@@ -17951,36 +17966,23 @@ const buildMessage = (deps) => {
|
|
|
17951
17966
|
description: "Recipient(s): chat URL, chat_id:<id>, @handle, profile URL, or profile_id:<id>; comma-separate profiles for a group",
|
|
17952
17967
|
valueHint: "recipients"
|
|
17953
17968
|
},
|
|
17954
|
-
body: {
|
|
17955
|
-
type: "string",
|
|
17956
|
-
description: "JSON request body"
|
|
17957
|
-
},
|
|
17958
17969
|
account: {
|
|
17959
17970
|
type: "string",
|
|
17960
17971
|
description: "Account selector: @handle or profile_id:<id>; overrides config default"
|
|
17961
17972
|
}
|
|
17962
17973
|
},
|
|
17963
17974
|
run: async ({ args }) => {
|
|
17975
|
+
if (typeof args.body === "string") throw new UsageError("Unsupported option --body for x message.");
|
|
17964
17976
|
const recipientsInput = args.recipients ?? args.target ?? (Array.isArray(args._) && args._.length > 0 ? args._[0] : void 0);
|
|
17965
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
17970
|
-
const piped = trimTrailingNewline(await deps.readStdin());
|
|
17971
|
-
if (piped.length > 0) textInput = piped;
|
|
17972
|
-
else if (!hasBody) throw noBodyTextError("social x message <recipients>");
|
|
17973
|
-
}
|
|
17977
|
+
let body;
|
|
17978
|
+
if (deps.isStdinTTY()) throw noBodyTextError("social x message <recipients>");
|
|
17979
|
+
const piped = trimTrailingNewline(await deps.readStdin());
|
|
17980
|
+
if (piped.length > 0) body = parseStdinBody(deps, "text", "text", piped);
|
|
17981
|
+
else throw noBodyTextError("social x message <recipients>");
|
|
17974
17982
|
if (recipientsInput === void 0) throw new UsageError("Pass a conversation or user target.");
|
|
17975
17983
|
const recipients = String(recipientsInput).split(",").map((recipient) => recipient.trim()).filter((recipient) => recipient.length > 0);
|
|
17976
17984
|
if (recipients.length === 0) throw new UsageError("Pass at least one recipient.");
|
|
17977
|
-
|
|
17978
|
-
const text = textInput === void 0 ? void 0 : deps.parseBodyText("--text", textInput);
|
|
17979
|
-
const body = text === void 0 ? bodyFromJSON : {
|
|
17980
|
-
...bodyFromJSON ?? {},
|
|
17981
|
-
text
|
|
17982
|
-
};
|
|
17983
|
-
if (body === void 0) throw new UsageError("Pass <text> or --body.");
|
|
17985
|
+
if (body === void 0) throw noBodyTextError("social x message <recipients>");
|
|
17984
17986
|
const resolved = [];
|
|
17985
17987
|
const account = typeof args.account === "string" ? args.account : void 0;
|
|
17986
17988
|
const selectedAccount = await deps.resolveAccount({
|
|
@@ -18009,12 +18011,13 @@ const buildMessage = (deps) => {
|
|
|
18009
18011
|
})));
|
|
18010
18012
|
for (const resolution of participantResolutions) resolved.push(resolution.record);
|
|
18011
18013
|
const participant_ids = participantResolutions.map((resolution) => resolution.id);
|
|
18014
|
+
const { text, ...bodyFields } = body;
|
|
18012
18015
|
requestPath = "x/dm_conversations";
|
|
18013
18016
|
requestBody = {
|
|
18014
18017
|
conversation_type: "Group",
|
|
18015
|
-
...bodyFromJSON ?? {},
|
|
18016
18018
|
participant_ids,
|
|
18017
|
-
...
|
|
18019
|
+
...bodyFields,
|
|
18020
|
+
...typeof text === "string" ? { message: { text } } : {}
|
|
18018
18021
|
};
|
|
18019
18022
|
}
|
|
18020
18023
|
const response = await deps.api.post(requestPath, {
|
|
@@ -18194,6 +18197,7 @@ createXCommands({
|
|
|
18194
18197
|
parseQueryString: unconfigured,
|
|
18195
18198
|
parseBodyText: unconfigured,
|
|
18196
18199
|
readStdin: unconfigured,
|
|
18200
|
+
isStdinTTY: unconfigured,
|
|
18197
18201
|
parseIntegerString: unconfigured,
|
|
18198
18202
|
parseEnumString: unconfigured,
|
|
18199
18203
|
parseBooleanString: unconfigured,
|
|
@@ -21054,7 +21058,7 @@ const createInstance = (defaults) => {
|
|
|
21054
21058
|
const ky = createInstance();
|
|
21055
21059
|
//#endregion
|
|
21056
21060
|
//#region package.json
|
|
21057
|
-
var version$1 = "0.3.
|
|
21061
|
+
var version$1 = "0.3.2";
|
|
21058
21062
|
//#endregion
|
|
21059
21063
|
//#region src/lib/env.ts
|
|
21060
21064
|
const URLWithTrailingSlash = url().transform(ensureTrailingSlash);
|
|
@@ -28508,6 +28512,7 @@ const createCLIDeps = () => {
|
|
|
28508
28512
|
parseQueryString,
|
|
28509
28513
|
parseBodyText,
|
|
28510
28514
|
readStdin,
|
|
28515
|
+
isStdinTTY: () => process.stdin.isTTY === true,
|
|
28511
28516
|
parseIntegerString,
|
|
28512
28517
|
parseEnumString,
|
|
28513
28518
|
parseBooleanString,
|