@adkit.so/cli 1.0.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/dist/config.js ADDED
@@ -0,0 +1,70 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export const CONFIG_DIR = join(homedir(), '.config', 'adkit');
5
+ export const CONFIG_PATH = join(CONFIG_DIR, 'config.json');
6
+ function parseConfigFile(raw) {
7
+ const parsed = JSON.parse(raw);
8
+ if (!parsed || typeof parsed !== 'object')
9
+ return {};
10
+ return parsed;
11
+ }
12
+ export function readConfig() {
13
+ if (!existsSync(CONFIG_PATH))
14
+ return null;
15
+ try {
16
+ return parseConfigFile(readFileSync(CONFIG_PATH, 'utf-8'));
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ export function writeConfig(updates) {
23
+ mkdirSync(CONFIG_DIR, { recursive: true });
24
+ let existing = {};
25
+ if (existsSync(CONFIG_PATH)) {
26
+ try {
27
+ existing = parseConfigFile(readFileSync(CONFIG_PATH, 'utf-8'));
28
+ }
29
+ catch {
30
+ // invalid existing config — start fresh
31
+ }
32
+ }
33
+ const merged = { ...existing, ...updates };
34
+ writeFileSync(CONFIG_PATH, JSON.stringify(merged, null, 2), { mode: 0o600 });
35
+ }
36
+ export function resolveConfig(flags = {}) {
37
+ // Priority 1: env
38
+ const envKey = process.env.ADKIT_API_KEY;
39
+ if (envKey)
40
+ return { apiKey: envKey };
41
+ // Priority 2: config file
42
+ const config = readConfig();
43
+ if (!config)
44
+ return { apiKey: null };
45
+ // If --project flag, look up in projects map
46
+ if (flags.project) {
47
+ const projectKey = config.projects?.[flags.project]?.apiKey ?? null;
48
+ return { apiKey: projectKey, selectedProject: config.selectedProject };
49
+ }
50
+ // If selectedProject is set and exists in projects map, use that key
51
+ if (config.selectedProject && config.projects?.[config.selectedProject]) {
52
+ return {
53
+ apiKey: config.projects[config.selectedProject]?.apiKey ?? null,
54
+ selectedProject: config.selectedProject,
55
+ };
56
+ }
57
+ return {
58
+ apiKey: config.apiKey ?? null,
59
+ selectedProject: config.selectedProject,
60
+ };
61
+ }
62
+ export function getDefaultAccount(platform) {
63
+ const config = readConfig();
64
+ if (!config?.selectedProject || !config.projects)
65
+ return null;
66
+ const project = config.projects[config.selectedProject];
67
+ if (!project)
68
+ return null;
69
+ return (platform === 'meta' ? project.defaultMetaAccount : project.defaultGoogleAccount) ?? null;
70
+ }
@@ -0,0 +1,6 @@
1
+ export type ErrorCode = 'NOT_AUTHENTICATED' | 'INVALID_API_KEY' | 'MISSING_ARGUMENT' | 'MISSING_FLAG' | 'INVALID_VALUE' | 'NOT_FOUND' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_COMMAND' | 'UNKNOWN_FLAG';
2
+ export declare class CliError extends Error {
3
+ code: ErrorCode;
4
+ suggestion?: string;
5
+ constructor(code: ErrorCode, message: string, suggestion?: string);
6
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,9 @@
1
+ export class CliError extends Error {
2
+ code;
3
+ suggestion;
4
+ constructor(code, message, suggestion) {
5
+ super(message);
6
+ this.code = code;
7
+ this.suggestion = suggestion;
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ interface FormatOptions {
2
+ fields?: string[];
3
+ json?: boolean;
4
+ }
5
+ export declare function formatOutput(data: Record<string, unknown>[], options: FormatOptions): string;
6
+ export {};
package/dist/output.js ADDED
@@ -0,0 +1,48 @@
1
+ function filterFields(data, fields) {
2
+ return data.map((row) => {
3
+ const filtered = {};
4
+ for (const f of fields) {
5
+ if (f in row)
6
+ filtered[f] = row[f];
7
+ }
8
+ return filtered;
9
+ });
10
+ }
11
+ function toStr(value) {
12
+ if (value == null)
13
+ return '';
14
+ if (typeof value === 'string')
15
+ return value;
16
+ if (typeof value === 'number' || typeof value === 'boolean')
17
+ return `${value}`;
18
+ return JSON.stringify(value);
19
+ }
20
+ function formatTable(data) {
21
+ if (data.length === 0)
22
+ return '';
23
+ const keys = Object.keys(data[0]);
24
+ const widths = {};
25
+ for (const key of keys) {
26
+ widths[key] = key.length;
27
+ for (const row of data) {
28
+ const val = toStr(row[key]);
29
+ if (val.length > widths[key])
30
+ widths[key] = val.length;
31
+ }
32
+ }
33
+ const header = keys.map((k) => k.toUpperCase().padEnd(widths[k])).join(' ');
34
+ const separator = keys.map((k) => '-'.repeat(widths[k])).join(' ');
35
+ const rows = data.map((row) => keys.map((k) => toStr(row[k]).padEnd(widths[k])).join(' '));
36
+ return [header, separator, ...rows].join('\n');
37
+ }
38
+ export function formatOutput(data, options) {
39
+ let rows = data;
40
+ if (options.fields) {
41
+ rows = filterFields(rows, options.fields);
42
+ }
43
+ const json = options.json ?? !(process.stdout.isTTY ?? false);
44
+ if (json) {
45
+ return JSON.stringify(rows);
46
+ }
47
+ return formatTable(rows);
48
+ }
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@adkit.so/cli",
3
+ "version": "1.0.0",
4
+ "description": "AdKit CLI — manage campaigns and accounts from the terminal",
5
+ "type": "module",
6
+ "bin": {
7
+ "adkit": "dist/cli.js"
8
+ },
9
+ "files": ["dist"],
10
+ "scripts": {
11
+ "build": "tsc"
12
+ },
13
+ "dependencies": {
14
+ "open": "^10.0.0"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^20.10.0",
18
+ "typescript": "^5.3.0"
19
+ }
20
+ }