@aicopycoders/exodus 2026.9.1400-beta.0 → 2026.9.1400

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.
@@ -1,108 +0,0 @@
1
- import { type ApiResponse } from "./client.js";
2
- import { type Channel } from "./channel.js";
3
- export interface AdAccountRef {
4
- accountId?: string | null;
5
- name?: string | null;
6
- currency?: string | null;
7
- }
8
- export interface AdMedia {
9
- image?: string | null;
10
- video?: string | null;
11
- poster?: string | null;
12
- }
13
- export interface AdWindowStats {
14
- resultType?: string | null;
15
- results?: number | null;
16
- costPerResult?: number | null;
17
- costPerResultDisplay?: string | null;
18
- ctr?: number | null;
19
- ctrDisplay?: string | null;
20
- cpc?: number | null;
21
- cpcDisplay?: string | null;
22
- spend?: number | null;
23
- spendDisplay?: string | null;
24
- impressions?: number | null;
25
- clicks?: number | null;
26
- currency?: string | null;
27
- }
28
- export interface AdSummary extends AdWindowStats {
29
- adId?: string | null;
30
- accountId?: string | null;
31
- name?: string | null;
32
- status?: string | null;
33
- format?: string | null;
34
- campaign?: {
35
- id?: string | null;
36
- name?: string | null;
37
- objective?: string | null;
38
- } | null;
39
- adset?: {
40
- id?: string | null;
41
- name?: string | null;
42
- optimizationGoal?: string | null;
43
- } | null;
44
- createdTime?: string | number | null;
45
- headline?: string | null;
46
- bodyText?: string | null;
47
- winnerStatus?: string | null;
48
- media?: AdMedia | null;
49
- syncedAt?: string | number | null;
50
- }
51
- export interface AdsListResponse {
52
- ads?: AdSummary[];
53
- count?: number;
54
- window?: string;
55
- sort?: string;
56
- accounts?: AdAccountRef[];
57
- }
58
- export interface AdShowResponse extends AdSummary {
59
- lifetime?: AdWindowStats | null;
60
- last90d?: AdWindowStats | null;
61
- commentCounts?: {
62
- facebook?: number | null;
63
- instagram?: number | null;
64
- } | null;
65
- }
66
- export interface AdComment {
67
- id?: string | null;
68
- adId?: string | null;
69
- platform?: string | null;
70
- text?: string | null;
71
- createdAt?: string | number | null;
72
- likeCount?: number | null;
73
- parentId?: string | null;
74
- syncedAt?: string | number | null;
75
- }
76
- export interface CommentsResponse {
77
- adId?: string | null;
78
- comments?: AdComment[];
79
- count?: number;
80
- }
81
- export interface FlowResult {
82
- code: number;
83
- lines: string[];
84
- warnings?: string[];
85
- }
86
- export interface MetaAdsDeps {
87
- get: (path: string) => Promise<ApiResponse<unknown>>;
88
- channel: Channel;
89
- apiUrl: () => string;
90
- now: () => number;
91
- }
92
- export declare const defaultMetaAdsDeps: MetaAdsDeps;
93
- export declare function displayOr(display: unknown, value: unknown, format: (n: number) => string): string;
94
- export declare function money(n: number, currency?: string | null): string;
95
- export declare function percent(n: number): string;
96
- export declare function count(n: unknown): string;
97
- export declare function sanitizeForTerminal(text: unknown): string;
98
- export declare function safeText(text: unknown): string;
99
- export declare function safeTextOr(text: unknown, fallback: string): string;
100
- export declare function truncate(text: unknown, max: number): string;
101
- export declare function dateOrDash(value: unknown): string;
102
- export declare function table(headers: string[], rows: string[][]): string;
103
- export declare function accountLine(account: AdAccountRef): string;
104
- export declare function mediaUrl(apiBase: string, relative: unknown): string | null;
105
- export declare function errorCode(data: unknown): string | undefined;
106
- export declare function accountsOf(data: unknown): AdAccountRef[];
107
- export declare function accountRequiredLines(res: ApiResponse<unknown>, example: (accountId: string) => string): string[];
108
- export declare function errorFor(res: ApiResponse<unknown>, verb: string, json: boolean, deps: MetaAdsDeps, example: (accountId: string) => string): FlowResult | undefined;
@@ -1,156 +0,0 @@
1
- import { apiGet, getApiUrl } from "./client.js";
2
- import { formatApiError } from "./format.js";
3
- import { auth401Hint } from "./backend-hint.js";
4
- import { getChannel } from "./channel.js";
5
- import { missingRouteLine } from "./route-support.js";
6
- export const defaultMetaAdsDeps = {
7
- get: (path) => apiGet(path),
8
- channel: getChannel(),
9
- apiUrl: () => getApiUrl(),
10
- now: () => Date.now(),
11
- };
12
- export function displayOr(display, value, format) {
13
- if (typeof display === "string" && display.trim())
14
- return safeTextOr(display, "—");
15
- if (typeof value === "number" && Number.isFinite(value))
16
- return format(value);
17
- return "—";
18
- }
19
- export function money(n, currency) {
20
- const body = n.toLocaleString("en-US", {
21
- minimumFractionDigits: n < 100 ? 2 : 0,
22
- maximumFractionDigits: 2,
23
- });
24
- return currency ? `${body} ${currency}` : body;
25
- }
26
- export function percent(n) {
27
- return `${n.toFixed(2)}%`;
28
- }
29
- export function count(n) {
30
- return typeof n === "number" && Number.isFinite(n) ? n.toLocaleString("en-US") : "—";
31
- }
32
- const ESC_STRING_SEQUENCE = /\x1b[\]PX^_][\s\S]*?(?:\x07|\x1b\\|$)/g;
33
- const ESC_CSI_SEQUENCE = /\x1b\[[0-?]*[ -\/]*[@-~]?/g;
34
- const ESC_SIMPLE_SEQUENCE = /\x1b[ -\/]*[0-~]?/g;
35
- const C0_AND_DEL = /[\x00-\x08\x0b-\x1f\x7f]/g;
36
- const C1_CONTROLS = /[\u0080-\u009f]/g;
37
- export function sanitizeForTerminal(text) {
38
- if (typeof text !== "string" || text === "")
39
- return "";
40
- return text
41
- .replace(ESC_STRING_SEQUENCE, "")
42
- .replace(ESC_CSI_SEQUENCE, "")
43
- .replace(ESC_SIMPLE_SEQUENCE, "")
44
- .replace(C0_AND_DEL, "")
45
- .replace(C1_CONTROLS, "");
46
- }
47
- export function safeText(text) {
48
- return sanitizeForTerminal(text).trim();
49
- }
50
- export function safeTextOr(text, fallback) {
51
- return safeText(text) || fallback;
52
- }
53
- export function truncate(text, max) {
54
- if (typeof text !== "string")
55
- return "";
56
- const flat = sanitizeForTerminal(text).replace(/\s+/g, " ").trim();
57
- if (flat.length <= max)
58
- return flat;
59
- const cut = flat.slice(0, max - 1);
60
- const lastSpace = cut.lastIndexOf(" ");
61
- const body = lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut;
62
- return `${body}…`;
63
- }
64
- export function dateOrDash(value) {
65
- if (typeof value === "number" && Number.isFinite(value) && value > 0) {
66
- const d = new Date(value);
67
- return Number.isNaN(d.getTime()) ? "—" : d.toISOString().slice(0, 10);
68
- }
69
- if (typeof value === "string" && value.trim()) {
70
- const d = new Date(value);
71
- return Number.isNaN(d.getTime())
72
- ? safeText(value).slice(0, 10)
73
- : d.toISOString().slice(0, 10);
74
- }
75
- return "—";
76
- }
77
- export function table(headers, rows) {
78
- const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((row) => row[i]?.length ?? 0)));
79
- const fmt = (row) => row.map((cell, i) => (cell ?? "").padEnd(widths[i])).join(" ").trimEnd();
80
- return [fmt(headers), fmt(headers.map((h) => "-".repeat(h.length))), ...rows.map(fmt)].join("\n");
81
- }
82
- export function accountLine(account) {
83
- const id = safeTextOr(account.accountId, "(no id)");
84
- const name = safeText(account.name);
85
- const currency = safeText(account.currency);
86
- const suffix = [name, currency ? `(${currency})` : ""].filter(Boolean).join(" ");
87
- return suffix ? ` ${id} ${suffix}` : ` ${id}`;
88
- }
89
- export function mediaUrl(apiBase, relative) {
90
- const rel = safeText(relative);
91
- if (!rel)
92
- return null;
93
- if (/^https?:\/\//i.test(rel))
94
- return rel;
95
- const base = (apiBase || "").replace(/\/$/, "");
96
- return `${base}${rel.startsWith("/") ? "" : "/"}${rel}`;
97
- }
98
- export function errorCode(data) {
99
- if (typeof data !== "object" || data === null)
100
- return undefined;
101
- const rec = data;
102
- if (typeof rec.code === "string" && rec.code)
103
- return rec.code;
104
- const err = rec.error;
105
- if (typeof err === "object" && err !== null) {
106
- const nested = err.code;
107
- if (typeof nested === "string" && nested)
108
- return nested;
109
- }
110
- return undefined;
111
- }
112
- export function accountsOf(data) {
113
- if (typeof data !== "object" || data === null)
114
- return [];
115
- const raw = data.accounts;
116
- return Array.isArray(raw) ? raw : [];
117
- }
118
- export function accountRequiredLines(res, example) {
119
- const accounts = accountsOf(res.data);
120
- const lines = [formatApiError(res)];
121
- if (accounts.length > 0) {
122
- lines.push("");
123
- lines.push("Connected ad accounts:");
124
- for (const account of accounts)
125
- lines.push(accountLine(account));
126
- const first = accounts[0]?.accountId;
127
- if (first) {
128
- lines.push("");
129
- lines.push("Re-run naming the one you mean:");
130
- lines.push(` ${example(first)}`);
131
- }
132
- }
133
- return lines;
134
- }
135
- export function errorFor(res, verb, json, deps, example) {
136
- if (res.ok)
137
- return undefined;
138
- if (json) {
139
- return { code: 1, lines: [JSON.stringify({ ok: false, status: res.status, data: res.data })] };
140
- }
141
- const unsupported = missingRouteLine(res, verb, deps.channel);
142
- if (unsupported)
143
- return { code: 1, lines: [unsupported] };
144
- if (res.status === 400 && errorCode(res.data) === "ACCOUNT_REQUIRED") {
145
- return { code: 1, lines: accountRequiredLines(res, example) };
146
- }
147
- const lines = [formatApiError(res)];
148
- if (res.status === 401) {
149
- lines.push("");
150
- lines.push(auth401Hint(deps.apiUrl()));
151
- }
152
- else if (res.status === 400 && errorCode(res.data) === "NO_BRAND") {
153
- lines.push("Pick a brand first: exodus brand use <slug>");
154
- }
155
- return { code: 1, lines };
156
- }