photon-msg 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +275 -2
- package/dist/args.d.ts +63 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +68 -0
- package/dist/args.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +163 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +37 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +68 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/attachments.d.ts +25 -0
- package/dist/commands/attachments.d.ts.map +1 -0
- package/dist/commands/attachments.js +78 -0
- package/dist/commands/attachments.js.map +1 -0
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +54 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/line.d.ts +51 -0
- package/dist/commands/line.d.ts.map +1 -0
- package/dist/commands/line.js +117 -0
- package/dist/commands/line.js.map +1 -0
- package/dist/commands/messages.d.ts +82 -0
- package/dist/commands/messages.d.ts.map +1 -0
- package/dist/commands/messages.js +163 -0
- package/dist/commands/messages.js.map +1 -0
- package/dist/commands/misc.d.ts +33 -0
- package/dist/commands/misc.d.ts.map +1 -0
- package/dist/commands/misc.js +61 -0
- package/dist/commands/misc.js.map +1 -0
- package/dist/commands/send.d.ts +107 -0
- package/dist/commands/send.d.ts.map +1 -0
- package/dist/commands/send.js +104 -0
- package/dist/commands/send.js.map +1 -0
- package/dist/commands/spaces.d.ts +56 -0
- package/dist/commands/spaces.d.ts.map +1 -0
- package/dist/commands/spaces.js +118 -0
- package/dist/commands/spaces.js.map +1 -0
- package/dist/commands/users.d.ts +34 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +82 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/content.d.ts +33 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +287 -0
- package/dist/content.js.map +1 -0
- package/dist/errors.d.ts +62 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +95 -0
- package/dist/errors.js.map +1 -0
- package/dist/help.d.ts +8 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +177 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +35 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +121 -0
- package/dist/output.js.map +1 -0
- package/dist/target.d.ts +34 -0
- package/dist/target.d.ts.map +1 -0
- package/dist/target.js +75 -0
- package/dist/target.js.map +1 -0
- package/dist/types.d.ts +200 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/upload.d.ts +33 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +119 -0
- package/dist/upload.js.map +1 -0
- package/package.json +49 -4
package/dist/content.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns CLI flags into a Photon `SendContent` payload.
|
|
3
|
+
*
|
|
4
|
+
* The API takes one polymorphic `content` object, which is how edits, unsends,
|
|
5
|
+
* reactions, read receipts, typing indicators and poll votes travel: there is no
|
|
6
|
+
* separate endpoint per action. This module is the single source of truth for
|
|
7
|
+
* that mapping, and it stays pure by taking uploads and user lookups as injected
|
|
8
|
+
* dependencies.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { usageError } from "./errors.js";
|
|
12
|
+
/** Every content mode the CLI can build. */
|
|
13
|
+
export const MODES = [
|
|
14
|
+
"text",
|
|
15
|
+
"attachment",
|
|
16
|
+
"voice",
|
|
17
|
+
"reaction",
|
|
18
|
+
"poll",
|
|
19
|
+
"edit",
|
|
20
|
+
"delete",
|
|
21
|
+
"read",
|
|
22
|
+
"typing",
|
|
23
|
+
"participants",
|
|
24
|
+
"group",
|
|
25
|
+
];
|
|
26
|
+
const asArray = (value) => value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
27
|
+
const isSet = (value) => value !== undefined && value !== null && value !== false;
|
|
28
|
+
/** Lists the content modes implied by the given flags. */
|
|
29
|
+
export function detectModes(flags) {
|
|
30
|
+
const modes = [];
|
|
31
|
+
// An edit carries its replacement text, so --text belongs to the edit rather
|
|
32
|
+
// than being a competing mode.
|
|
33
|
+
const editing = isSet(flags.edit);
|
|
34
|
+
if (!editing && (isSet(flags.text) || isSet(flags["text-file"])))
|
|
35
|
+
modes.push("text");
|
|
36
|
+
if (asArray(flags.image).length > 0 || asArray(flags.file).length > 0)
|
|
37
|
+
modes.push("attachment");
|
|
38
|
+
if (isSet(flags.voice))
|
|
39
|
+
modes.push("voice");
|
|
40
|
+
if (isSet(flags.reaction))
|
|
41
|
+
modes.push("reaction");
|
|
42
|
+
if (isSet(flags.poll))
|
|
43
|
+
modes.push("poll");
|
|
44
|
+
if (editing)
|
|
45
|
+
modes.push("edit");
|
|
46
|
+
if (isSet(flags.delete))
|
|
47
|
+
modes.push("delete");
|
|
48
|
+
if (flags.read === true)
|
|
49
|
+
modes.push("read");
|
|
50
|
+
if (isSet(flags.typing))
|
|
51
|
+
modes.push("typing");
|
|
52
|
+
if (asArray(flags["participants-add"]).length > 0 || asArray(flags["participants-remove"]).length > 0) {
|
|
53
|
+
modes.push("participants");
|
|
54
|
+
}
|
|
55
|
+
if (flags.group === true)
|
|
56
|
+
modes.push("group");
|
|
57
|
+
return modes;
|
|
58
|
+
}
|
|
59
|
+
/** Reads text from a file, or stdin when the path is "-". */
|
|
60
|
+
export function readTextFile(path) {
|
|
61
|
+
try {
|
|
62
|
+
return readFileSync(path === "-" ? 0 : path, "utf8");
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw usageError(`Could not read ${path === "-" ? "stdin" : path}: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const normalizeFormat = (format) => {
|
|
69
|
+
if (!format)
|
|
70
|
+
return "plain";
|
|
71
|
+
const value = format.toLowerCase();
|
|
72
|
+
if (value !== "plain" && value !== "markdown") {
|
|
73
|
+
throw usageError(`--format must be "plain" or "markdown", got "${format}".`);
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
};
|
|
77
|
+
const textPart = (text, format) => ({ type: "text", format, text });
|
|
78
|
+
/**
|
|
79
|
+
* Cheap, side-effect-free validation of content flags, so the CLI can refuse a
|
|
80
|
+
* contradictory command before it asks for credentials or touches the network.
|
|
81
|
+
*/
|
|
82
|
+
export function validateContentFlags(flags) {
|
|
83
|
+
const modes = detectModes(flags);
|
|
84
|
+
if (modes.length === 0) {
|
|
85
|
+
throw usageError("Nothing to send. Pass --text, --image, --poll, --reaction, --edit, and so on.", "Run `photon-msg send --help` for the full list.");
|
|
86
|
+
}
|
|
87
|
+
if (modes.length > 1 && !flags.group) {
|
|
88
|
+
throw usageError(`Conflicting content flags: ${modes.join(", ")}. Use one content flag, or add --group to send several parts together.`);
|
|
89
|
+
}
|
|
90
|
+
return modes;
|
|
91
|
+
}
|
|
92
|
+
/** Builds the send payload from flags. */
|
|
93
|
+
export async function buildMessage({ flags, upload, getUsers }) {
|
|
94
|
+
const modes = validateContentFlags(flags);
|
|
95
|
+
const format = normalizeFormat(flags.format);
|
|
96
|
+
// --group overrides the single-mode rule: several parts travel together.
|
|
97
|
+
const mode = flags.group ? "group" : modes[0];
|
|
98
|
+
const replyTo = flags["reply-to"];
|
|
99
|
+
const initialTexts = asArray(flags.text);
|
|
100
|
+
const texts = initialTexts.length > 0
|
|
101
|
+
? initialTexts
|
|
102
|
+
: flags["text-file"] !== undefined
|
|
103
|
+
? [readTextFile(flags["text-file"])]
|
|
104
|
+
: [];
|
|
105
|
+
const attachmentSources = [...asArray(flags.image), ...asArray(flags.file)];
|
|
106
|
+
const build = async () => {
|
|
107
|
+
switch (mode) {
|
|
108
|
+
case "text": {
|
|
109
|
+
if (texts.length === 0)
|
|
110
|
+
throw usageError("--text is empty.");
|
|
111
|
+
return { content: textPart(texts.join("\n"), format) };
|
|
112
|
+
}
|
|
113
|
+
case "attachment": {
|
|
114
|
+
const source = attachmentSources[0];
|
|
115
|
+
if (!source)
|
|
116
|
+
throw usageError("--image needs a path or URL.");
|
|
117
|
+
const attachmentId = await upload(source);
|
|
118
|
+
const content = {
|
|
119
|
+
type: "attachment",
|
|
120
|
+
attachmentId,
|
|
121
|
+
...(flags.caption
|
|
122
|
+
? { metadata: { caption: { format, text: flags.caption } } }
|
|
123
|
+
: {}),
|
|
124
|
+
};
|
|
125
|
+
return { content };
|
|
126
|
+
}
|
|
127
|
+
case "voice": {
|
|
128
|
+
if (!flags.voice)
|
|
129
|
+
throw usageError("--voice needs a path.");
|
|
130
|
+
const attachmentId = await upload(flags.voice);
|
|
131
|
+
const content = { type: "voice", attachmentId };
|
|
132
|
+
return { content };
|
|
133
|
+
}
|
|
134
|
+
case "reaction": {
|
|
135
|
+
if (!replyTo)
|
|
136
|
+
throw usageError("--reaction needs --reply-to <messageId> to name the message being reacted to.");
|
|
137
|
+
const action = flags["reaction-action"] ?? "add";
|
|
138
|
+
if (action !== "add" && action !== "remove") {
|
|
139
|
+
throw usageError(`--reaction-action must be "add" or "remove", got "${action}".`);
|
|
140
|
+
}
|
|
141
|
+
const content = {
|
|
142
|
+
type: "reaction",
|
|
143
|
+
reaction: flags.reaction,
|
|
144
|
+
action,
|
|
145
|
+
};
|
|
146
|
+
return { content, parentMessageId: replyTo };
|
|
147
|
+
}
|
|
148
|
+
case "poll": {
|
|
149
|
+
const options = asArray(flags["poll-option"]).map((text, index) => ({
|
|
150
|
+
id: `opt_${index + 1}`,
|
|
151
|
+
text,
|
|
152
|
+
}));
|
|
153
|
+
if (options.length === 0)
|
|
154
|
+
throw usageError("--poll needs at least one --poll-option.");
|
|
155
|
+
const selectionMode = flags["poll-mode"] ?? "single";
|
|
156
|
+
if (selectionMode !== "single" && selectionMode !== "multiple") {
|
|
157
|
+
throw usageError(`--poll-mode must be "single" or "multiple", got "${selectionMode}".`);
|
|
158
|
+
}
|
|
159
|
+
const content = {
|
|
160
|
+
type: "poll",
|
|
161
|
+
question: flags.poll,
|
|
162
|
+
options,
|
|
163
|
+
selectionMode,
|
|
164
|
+
};
|
|
165
|
+
return { content };
|
|
166
|
+
}
|
|
167
|
+
case "edit": {
|
|
168
|
+
if (texts.length === 0)
|
|
169
|
+
throw usageError("--edit needs --text with the replacement text.");
|
|
170
|
+
const content = {
|
|
171
|
+
type: "text.update",
|
|
172
|
+
format,
|
|
173
|
+
text: texts.join("\n"),
|
|
174
|
+
};
|
|
175
|
+
return { content, parentMessageId: flags.edit };
|
|
176
|
+
}
|
|
177
|
+
case "delete": {
|
|
178
|
+
const content = {
|
|
179
|
+
type: "message.delete",
|
|
180
|
+
...(flags.reason ? { reason: flags.reason } : {}),
|
|
181
|
+
};
|
|
182
|
+
return { content, parentMessageId: flags.delete };
|
|
183
|
+
}
|
|
184
|
+
case "read": {
|
|
185
|
+
if (!replyTo)
|
|
186
|
+
throw usageError("--read needs --reply-to <messageId> to name the message being marked read.");
|
|
187
|
+
const content = { type: "message.read" };
|
|
188
|
+
return { content, parentMessageId: replyTo };
|
|
189
|
+
}
|
|
190
|
+
case "typing": {
|
|
191
|
+
const raw = String(flags.typing).toLowerCase();
|
|
192
|
+
const typing = raw === "on" || raw === "true" || raw === "1";
|
|
193
|
+
if (!typing && raw !== "off" && raw !== "false" && raw !== "0") {
|
|
194
|
+
throw usageError(`--typing must be "on" or "off", got "${flags.typing}".`);
|
|
195
|
+
}
|
|
196
|
+
const content = { type: "space.typing.update", typing };
|
|
197
|
+
return { content };
|
|
198
|
+
}
|
|
199
|
+
case "participants": {
|
|
200
|
+
const added = asArray(flags["participants-add"]);
|
|
201
|
+
const removed = asArray(flags["participants-remove"]);
|
|
202
|
+
const users = await getUsers([...added, ...removed]);
|
|
203
|
+
const byId = new Map(users.map((user) => [user.id, user]));
|
|
204
|
+
const snapshot = (id) => {
|
|
205
|
+
const user = byId.get(id);
|
|
206
|
+
if (!user)
|
|
207
|
+
throw usageError(`Unknown user ID "${id}".`);
|
|
208
|
+
// The API accepts the user record it returned as the snapshot input.
|
|
209
|
+
return user;
|
|
210
|
+
};
|
|
211
|
+
const content = {
|
|
212
|
+
type: "space.participants.update",
|
|
213
|
+
added: added.map(snapshot),
|
|
214
|
+
removed: removed.map(snapshot),
|
|
215
|
+
};
|
|
216
|
+
return { content };
|
|
217
|
+
}
|
|
218
|
+
case "group": {
|
|
219
|
+
const uploads = attachmentSources.length + (isSet(flags.voice) ? 1 : 0);
|
|
220
|
+
if (texts.length + uploads < 2) {
|
|
221
|
+
throw usageError('--group needs at least two parts, for example --text "a" --image ./b.png.');
|
|
222
|
+
}
|
|
223
|
+
const parts = texts.map((text) => textPart(text, format));
|
|
224
|
+
for (const source of attachmentSources) {
|
|
225
|
+
const attachmentId = await upload(source);
|
|
226
|
+
parts.push({ type: "attachment", attachmentId });
|
|
227
|
+
}
|
|
228
|
+
if (flags.voice) {
|
|
229
|
+
const attachmentId = await upload(flags.voice);
|
|
230
|
+
parts.push({ type: "voice", attachmentId });
|
|
231
|
+
}
|
|
232
|
+
const content = { type: "group", parts };
|
|
233
|
+
return { content };
|
|
234
|
+
}
|
|
235
|
+
default: {
|
|
236
|
+
const exhaustive = mode;
|
|
237
|
+
throw usageError(`Unsupported content mode "${String(exhaustive)}".`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const built = await build();
|
|
242
|
+
const result = { content: built.content };
|
|
243
|
+
if (built.parentMessageId)
|
|
244
|
+
result.parentMessageId = built.parentMessageId;
|
|
245
|
+
const cc = asArray(flags.cc);
|
|
246
|
+
const bcc = asArray(flags.bcc);
|
|
247
|
+
if (flags.subject || cc.length > 0 || bcc.length > 0) {
|
|
248
|
+
result.email = {
|
|
249
|
+
...(flags.subject ? { subject: flags.subject } : {}),
|
|
250
|
+
...(cc.length > 0 ? { cc: cc.map((address) => ({ address })) } : {}),
|
|
251
|
+
...(bcc.length > 0 ? { bcc: bcc.map((address) => ({ address })) } : {}),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
/** Short human description of a payload, used by --dry-run and logs. */
|
|
257
|
+
export function describeContent(content) {
|
|
258
|
+
if (!content)
|
|
259
|
+
return "nothing";
|
|
260
|
+
switch (content.type) {
|
|
261
|
+
case "text":
|
|
262
|
+
return `text(${content.format}): ${JSON.stringify(content.text)}`;
|
|
263
|
+
case "text.update":
|
|
264
|
+
return `edit(${content.format}): ${JSON.stringify(content.text)}`;
|
|
265
|
+
case "attachment":
|
|
266
|
+
return `attachment(${content.attachmentId})`;
|
|
267
|
+
case "voice":
|
|
268
|
+
return `voice(${content.attachmentId})`;
|
|
269
|
+
case "reaction":
|
|
270
|
+
return `reaction(${content.action ?? "add"} ${content.reaction})`;
|
|
271
|
+
case "poll":
|
|
272
|
+
return `poll(${JSON.stringify(content.question)}, ${content.options.length} options)`;
|
|
273
|
+
case "message.delete":
|
|
274
|
+
return "delete";
|
|
275
|
+
case "message.read":
|
|
276
|
+
return "read receipt";
|
|
277
|
+
case "space.typing.update":
|
|
278
|
+
return `typing(${content.typing ? "on" : "off"})`;
|
|
279
|
+
case "space.participants.update":
|
|
280
|
+
return `participants(+${content.added.length}/-${content.removed.length})`;
|
|
281
|
+
case "group":
|
|
282
|
+
return `group(${content.parts.length} parts)`;
|
|
283
|
+
default:
|
|
284
|
+
return "unknown content";
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types and exit codes.
|
|
3
|
+
*
|
|
4
|
+
* Every failure path funnels through `CliError`, so callers always get a stable
|
|
5
|
+
* `exitCode` plus an optional actionable `hint`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const EXIT: {
|
|
8
|
+
readonly OK: 0;
|
|
9
|
+
readonly FAILURE: 1;
|
|
10
|
+
readonly USAGE: 2;
|
|
11
|
+
readonly AUTH: 3;
|
|
12
|
+
readonly NOT_FOUND: 4;
|
|
13
|
+
readonly FORBIDDEN: 5;
|
|
14
|
+
readonly CONFLICT: 6;
|
|
15
|
+
};
|
|
16
|
+
export type ExitCode = (typeof EXIT)[keyof typeof EXIT];
|
|
17
|
+
export interface CliErrorOptions {
|
|
18
|
+
exitCode?: number;
|
|
19
|
+
hint?: string;
|
|
20
|
+
code?: string;
|
|
21
|
+
details?: unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare class CliError extends Error {
|
|
24
|
+
readonly exitCode: number;
|
|
25
|
+
readonly hint?: string;
|
|
26
|
+
readonly code?: string;
|
|
27
|
+
readonly details?: unknown;
|
|
28
|
+
constructor(message: string, options?: CliErrorOptions);
|
|
29
|
+
}
|
|
30
|
+
/** Usage error: bad flags, missing required arguments. */
|
|
31
|
+
export declare const usageError: (message: string, hint?: string) => CliError;
|
|
32
|
+
/** Problem codes the API returns, mapped to guidance. */
|
|
33
|
+
export declare const PROBLEM_HINTS: Record<string, string>;
|
|
34
|
+
/** The shape of an API problem document. */
|
|
35
|
+
export interface ProblemBody {
|
|
36
|
+
code?: string;
|
|
37
|
+
detail?: string;
|
|
38
|
+
title?: string;
|
|
39
|
+
requestId?: string;
|
|
40
|
+
type?: string;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
/** Structural type of an `@photon-ai/api` error, without importing the class. */
|
|
44
|
+
export interface ApiErrorLike {
|
|
45
|
+
status: number;
|
|
46
|
+
message: string;
|
|
47
|
+
body?: ProblemBody;
|
|
48
|
+
}
|
|
49
|
+
export declare const isApiError: (error: unknown) => error is ApiErrorLike;
|
|
50
|
+
/** Normalizes anything thrown into a CliError. */
|
|
51
|
+
export declare function toCliError(error: unknown): CliError;
|
|
52
|
+
/** Serializes an error for `--json` output. */
|
|
53
|
+
export declare const errorPayload: (cliError: CliError) => {
|
|
54
|
+
error: {
|
|
55
|
+
message: string;
|
|
56
|
+
code: string | null;
|
|
57
|
+
exitCode: number;
|
|
58
|
+
hint: string | null;
|
|
59
|
+
details: {} | null;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,IAAI;;;;;;;;CAQP,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;CAQ3D;AAED,0DAA0D;AAC1D,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,OAAO,MAAM,KAAG,QACU,CAAC;AAEvE,yDAAyD;AACzD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmBhD,CAAC;AAWF,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,YAIS,CAAC;AAE/D,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAsBnD;AAED,+CAA+C;AAC/C,eAAO,MAAM,YAAY,GAAI,UAAU,QAAQ;;;;;;;;CAQ7C,CAAC"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types and exit codes.
|
|
3
|
+
*
|
|
4
|
+
* Every failure path funnels through `CliError`, so callers always get a stable
|
|
5
|
+
* `exitCode` plus an optional actionable `hint`.
|
|
6
|
+
*/
|
|
7
|
+
export const EXIT = {
|
|
8
|
+
OK: 0,
|
|
9
|
+
FAILURE: 1,
|
|
10
|
+
USAGE: 2,
|
|
11
|
+
AUTH: 3,
|
|
12
|
+
NOT_FOUND: 4,
|
|
13
|
+
FORBIDDEN: 5,
|
|
14
|
+
CONFLICT: 6,
|
|
15
|
+
};
|
|
16
|
+
export class CliError extends Error {
|
|
17
|
+
exitCode;
|
|
18
|
+
hint;
|
|
19
|
+
code;
|
|
20
|
+
details;
|
|
21
|
+
constructor(message, options = {}) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "CliError";
|
|
24
|
+
this.exitCode = options.exitCode ?? EXIT.FAILURE;
|
|
25
|
+
this.hint = options.hint;
|
|
26
|
+
this.code = options.code;
|
|
27
|
+
this.details = options.details;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Usage error: bad flags, missing required arguments. */
|
|
31
|
+
export const usageError = (message, hint) => new CliError(message, { exitCode: EXIT.USAGE, hint, code: "USAGE" });
|
|
32
|
+
/** Problem codes the API returns, mapped to guidance. */
|
|
33
|
+
export const PROBLEM_HINTS = {
|
|
34
|
+
SHARED_LINE_INBOUND_REQUIRED: "This line is a pooled shared line, so it cannot message someone who has not written to it first. " +
|
|
35
|
+
"Have the recipient send any message to the line, then reply inside that space. " +
|
|
36
|
+
"For agent-initiated messages you need a purchased SMS number or a dedicated iMessage line.",
|
|
37
|
+
SHARED_LINE_GROUP_UNSUPPORTED: "Pooled shared lines only carry direct conversations, not group chats.",
|
|
38
|
+
NOT_AUTHENTICATED: "Set PHOTON_API_KEY to a project API key, or pass --api-key.",
|
|
39
|
+
INSUFFICIENT_SCOPE: "The API key is missing a permission this call needs. Project keys need project:read / project:write; " +
|
|
40
|
+
"line assignments also need platforms:read / platforms:write.",
|
|
41
|
+
FORBIDDEN: "The key is valid but not allowed to touch this resource. Check the project ID and key scope.",
|
|
42
|
+
PROJECT_NOT_SELECTED: "Set PHOTON_PROJECT_ID, or pass --project.",
|
|
43
|
+
IDEMPOTENCY_KEY_REUSED: "That idempotency key was already used for a different request. Omit --idempotency-key to mint a new one.",
|
|
44
|
+
VALIDATION_FAILED: "The API rejected the payload. Re-run with --json to see the full problem detail.",
|
|
45
|
+
ATTACHMENT_NOT_READY: "The attachment is still processing. Retry after the server's Retry-After interval.",
|
|
46
|
+
RATE_LIMITED: "Rate limited. Honor the Retry-After header instead of retrying immediately.",
|
|
47
|
+
ATTACHMENT_TOO_LARGE: "The file exceeds the attachment size limit.",
|
|
48
|
+
UNSUPPORTED_CONTENT: "This platform does not support that content type. Check the platform's feature support.",
|
|
49
|
+
};
|
|
50
|
+
const EXIT_BY_STATUS = {
|
|
51
|
+
401: EXIT.AUTH,
|
|
52
|
+
403: EXIT.FORBIDDEN,
|
|
53
|
+
404: EXIT.NOT_FOUND,
|
|
54
|
+
409: EXIT.CONFLICT,
|
|
55
|
+
422: EXIT.USAGE,
|
|
56
|
+
429: EXIT.FAILURE,
|
|
57
|
+
};
|
|
58
|
+
export const isApiError = (error) => typeof error === "object" &&
|
|
59
|
+
error !== null &&
|
|
60
|
+
typeof error.status === "number" &&
|
|
61
|
+
typeof error.message === "string";
|
|
62
|
+
/** Normalizes anything thrown into a CliError. */
|
|
63
|
+
export function toCliError(error) {
|
|
64
|
+
if (error instanceof CliError)
|
|
65
|
+
return error;
|
|
66
|
+
if (isApiError(error)) {
|
|
67
|
+
const problem = error.body ?? {};
|
|
68
|
+
const code = problem.code ?? `HTTP_${error.status}`;
|
|
69
|
+
const detail = problem.detail ?? problem.title ?? error.message;
|
|
70
|
+
const exitCode = EXIT_BY_STATUS[error.status] ?? EXIT.FAILURE;
|
|
71
|
+
return new CliError(`Photon API error ${error.status}: ${detail}`, {
|
|
72
|
+
exitCode,
|
|
73
|
+
code,
|
|
74
|
+
hint: PROBLEM_HINTS[code],
|
|
75
|
+
details: {
|
|
76
|
+
code,
|
|
77
|
+
status: error.status,
|
|
78
|
+
requestId: problem.requestId,
|
|
79
|
+
type: problem.type,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return new CliError(error instanceof Error ? error.message : String(error));
|
|
84
|
+
}
|
|
85
|
+
/** Serializes an error for `--json` output. */
|
|
86
|
+
export const errorPayload = (cliError) => ({
|
|
87
|
+
error: {
|
|
88
|
+
message: cliError.message,
|
|
89
|
+
code: cliError.code ?? null,
|
|
90
|
+
exitCode: cliError.exitCode,
|
|
91
|
+
hint: cliError.hint ?? null,
|
|
92
|
+
details: cliError.details ?? null,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/help.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help text. Kept as data so `--help` output stays consistent across commands.
|
|
3
|
+
*/
|
|
4
|
+
/** Single source of truth for the version: package.json. */
|
|
5
|
+
export declare const VERSION: string;
|
|
6
|
+
export declare const MAIN_HELP: string;
|
|
7
|
+
export declare const COMMAND_HELP: Record<string, string>;
|
|
8
|
+
//# sourceMappingURL=help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuCH,4DAA4D;AAC5D,eAAO,MAAM,OAAO,EAAE,MAAsB,CAAC;AAE7C,eAAO,MAAM,SAAS,QAyDrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAgF/C,CAAC"}
|
package/dist/help.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help text. Kept as data so `--help` output stays consistent across commands.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
/**
|
|
8
|
+
* Reads the version from the nearest package.json.
|
|
9
|
+
*
|
|
10
|
+
* This module can be loaded from `dist/` (published) or `.test-build/src/`
|
|
11
|
+
* (compiled tests), so the manifest is found by walking up rather than assuming
|
|
12
|
+
* a fixed depth. Walking up also survives a change to the output layout.
|
|
13
|
+
*/
|
|
14
|
+
function readVersion() {
|
|
15
|
+
let directory = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
for (let depth = 0; depth < 5; depth += 1) {
|
|
17
|
+
const candidate = join(directory, "package.json");
|
|
18
|
+
if (existsSync(candidate)) {
|
|
19
|
+
try {
|
|
20
|
+
const pkg = JSON.parse(readFileSync(candidate, "utf8"));
|
|
21
|
+
if (pkg.version && (pkg.name === undefined || pkg.name === "photon-msg")) {
|
|
22
|
+
return pkg.version;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Fall through to the parent directory.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const parent = dirname(directory);
|
|
30
|
+
if (parent === directory)
|
|
31
|
+
break;
|
|
32
|
+
directory = parent;
|
|
33
|
+
}
|
|
34
|
+
return "0.0.0";
|
|
35
|
+
}
|
|
36
|
+
/** Single source of truth for the version: package.json. */
|
|
37
|
+
export const VERSION = readVersion();
|
|
38
|
+
export const MAIN_HELP = `photon-msg ${VERSION} — send and read messages through the Photon API
|
|
39
|
+
|
|
40
|
+
USAGE
|
|
41
|
+
photon-msg <command> [options]
|
|
42
|
+
|
|
43
|
+
COMMANDS
|
|
44
|
+
send Send any content type: text, image, voice, poll, reaction, edit, unsend
|
|
45
|
+
messages list List messages with filters
|
|
46
|
+
messages get Fetch one message
|
|
47
|
+
messages watch Follow new messages as JSON lines
|
|
48
|
+
spaces list List conversations
|
|
49
|
+
spaces get Fetch one conversation
|
|
50
|
+
spaces create Create or reuse a conversation
|
|
51
|
+
users list List people and agents in the project
|
|
52
|
+
users get Fetch one user
|
|
53
|
+
users ensure Resolve a handle to a user ID
|
|
54
|
+
attachments upload Upload a file or URL
|
|
55
|
+
attachments get Inspect attachment metadata
|
|
56
|
+
attachments download Write attachment bytes to disk
|
|
57
|
+
typing Start or stop a typing indicator
|
|
58
|
+
read Mark a message read
|
|
59
|
+
line assign Assign a pooled iMessage line to a handle
|
|
60
|
+
line list List shared-line assignments
|
|
61
|
+
line get Fetch one assignment
|
|
62
|
+
line release Release an assignment
|
|
63
|
+
doctor Check credentials and project wiring
|
|
64
|
+
help Show this help
|
|
65
|
+
|
|
66
|
+
GLOBAL OPTIONS
|
|
67
|
+
--json Machine-readable output
|
|
68
|
+
--no-color Disable ANSI color
|
|
69
|
+
--api-key <key> Project API key (or PHOTON_API_KEY)
|
|
70
|
+
--project <id> Project ID (or PHOTON_PROJECT_ID)
|
|
71
|
+
--base-url <url> API origin (or PHOTON_API_BASE_URL)
|
|
72
|
+
--timeout <ms> Per-request timeout
|
|
73
|
+
--dry-run Print the request instead of sending it
|
|
74
|
+
--quiet, -q Suppress the summary lines
|
|
75
|
+
--help, -h Show help
|
|
76
|
+
--version, -v Show version
|
|
77
|
+
|
|
78
|
+
ADDRESSING
|
|
79
|
+
--space <spaceId> --as <agent> reply into an existing conversation
|
|
80
|
+
--to <handle> --as <agent> start or reuse a direct conversation
|
|
81
|
+
--as accepts a handle or a pho_usr_ ID; PHOTON_AGENT_HANDLE is the default.
|
|
82
|
+
|
|
83
|
+
EXAMPLES
|
|
84
|
+
photon-msg send --to +14155550123 --as +16285024649 --text "hello"
|
|
85
|
+
photon-msg send --space pho_spc_... --as pho_usr_... --image ./photo.png --caption "look"
|
|
86
|
+
photon-msg send --space pho_spc_... --as pho_usr_... --poll "Lunch?" --poll-option Yes --poll-option No
|
|
87
|
+
photon-msg send --space pho_spc_... --as pho_usr_... --reply-to pho_msg_... --reaction "❤️"
|
|
88
|
+
photon-msg send --space pho_spc_... --as pho_usr_... --edit pho_msg_... --text "fixed typo"
|
|
89
|
+
photon-msg messages list --platform imessage --direction received --limit 20
|
|
90
|
+
photon-msg line assign --handle +14155550123
|
|
91
|
+
|
|
92
|
+
Addressing a new conversation requires a line that may start it. Pooled shared
|
|
93
|
+
lines cannot: the recipient must message the line first, and the API answers
|
|
94
|
+
403 SHARED_LINE_INBOUND_REQUIRED until they do.
|
|
95
|
+
`;
|
|
96
|
+
export const COMMAND_HELP = {
|
|
97
|
+
send: `photon-msg send — send one message
|
|
98
|
+
|
|
99
|
+
DESTINATION
|
|
100
|
+
--space <spaceId> Existing conversation (reply, edit, reaction, ...)
|
|
101
|
+
--to <handle> Start or reuse a direct conversation with this handle
|
|
102
|
+
--as <handle|userId> Sender agent (default: PHOTON_AGENT_HANDLE)
|
|
103
|
+
--platform <name> imessage | sms | email | whatsapp | whatsapp_business | telegram
|
|
104
|
+
|
|
105
|
+
CONTENT (choose one, or combine with --group)
|
|
106
|
+
--text <string> Text body (repeatable; lines are joined)
|
|
107
|
+
--text-file <path> Read the body from a file, or "-" for stdin
|
|
108
|
+
--format <plain|markdown>
|
|
109
|
+
--image <path|url> Image attachment (repeatable)
|
|
110
|
+
--file <path|url> Any attachment (repeatable)
|
|
111
|
+
--caption <string> Caption for a single attachment
|
|
112
|
+
--voice <path> Voice note
|
|
113
|
+
--poll <question> --poll-option <text> [--poll-option ...] [--poll-mode single|multiple]
|
|
114
|
+
--reaction <emoji> [--reaction-action add|remove] needs --reply-to
|
|
115
|
+
--edit <messageId> --text <new text> edit a sent message
|
|
116
|
+
--delete <messageId> [--reason <text>] unsend a message
|
|
117
|
+
--read read receipt, needs --reply-to
|
|
118
|
+
--typing <on|off> typing indicator as content
|
|
119
|
+
--participants-add <userId> --participants-remove <userId>
|
|
120
|
+
--group send the supplied parts as one group
|
|
121
|
+
|
|
122
|
+
OTHER
|
|
123
|
+
--reply-to <messageId> Thread the message under another
|
|
124
|
+
--idempotency-key <key> Reuse across retries of the same logical send
|
|
125
|
+
--subject/--cc/--bcc Email-only options
|
|
126
|
+
|
|
127
|
+
Acceptance is asynchronous: a successful send means the API queued the message,
|
|
128
|
+
not that the recipient has seen it.
|
|
129
|
+
`,
|
|
130
|
+
"messages list": `photon-msg messages list — list messages
|
|
131
|
+
|
|
132
|
+
--platform <name> Restrict to one platform
|
|
133
|
+
--direction received|dispatched
|
|
134
|
+
--space <spaceId> Restrict to a conversation
|
|
135
|
+
--resource <resourceId> Restrict to a resource
|
|
136
|
+
--perspective-user <id> Restrict to one user's view (needs --space)
|
|
137
|
+
--created-since/--created-before RFC 3339 bounds on createdAt
|
|
138
|
+
--updated-since/--updated-before RFC 3339 bounds on updatedAt
|
|
139
|
+
--exclude-content-types <list> Comma-separated content types
|
|
140
|
+
--order asc|desc --order-by <field>
|
|
141
|
+
--page-size <n> --page-token <token> --limit <n>
|
|
142
|
+
`,
|
|
143
|
+
"messages watch": `photon-msg messages watch — follow new messages as JSON lines
|
|
144
|
+
|
|
145
|
+
--platform <name> --space <spaceId> --direction <dir>
|
|
146
|
+
--interval <seconds> Poll interval (default 2)
|
|
147
|
+
--for <seconds> Stop after this long (default: run until interrupted)
|
|
148
|
+
--since <rfc3339> Start point (default: now)
|
|
149
|
+
`,
|
|
150
|
+
"spaces create": `photon-msg spaces create — create or reuse a conversation
|
|
151
|
+
|
|
152
|
+
--platform <name>
|
|
153
|
+
--participant <handle|userId> Repeatable; order matters on iMessage (first is creator)
|
|
154
|
+
--idempotency-key <key>
|
|
155
|
+
`,
|
|
156
|
+
"users ensure": `photon-msg users ensure — resolve a handle to a user ID
|
|
157
|
+
|
|
158
|
+
--handle <handle> Phone (E.164) or email
|
|
159
|
+
--platform <name>
|
|
160
|
+
`,
|
|
161
|
+
"attachments upload": `photon-msg attachments upload — upload a file or URL
|
|
162
|
+
|
|
163
|
+
<path|url> --content-type <mime>
|
|
164
|
+
`,
|
|
165
|
+
typing: `photon-msg typing — typing indicator
|
|
166
|
+
|
|
167
|
+
--space <spaceId> --as <agent> --on | --off
|
|
168
|
+
`,
|
|
169
|
+
"line assign": `photon-msg line assign — assign a pooled iMessage line
|
|
170
|
+
|
|
171
|
+
--handle <+15551234567> The human who will write to the line
|
|
172
|
+
--email <address> Optional invite address
|
|
173
|
+
--first-name/--last-name
|
|
174
|
+
--idempotency-key <key> Reuse for retries of the same assignment
|
|
175
|
+
`,
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=help.js.map
|