affitor 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.
Files changed (50) hide show
  1. package/README.md +91 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +33 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +194 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/setup-stripe.d.ts +3 -0
  11. package/dist/commands/setup-stripe.d.ts.map +1 -0
  12. package/dist/commands/setup-stripe.js +188 -0
  13. package/dist/commands/setup-stripe.js.map +1 -0
  14. package/dist/commands/status.d.ts +3 -0
  15. package/dist/commands/status.d.ts.map +1 -0
  16. package/dist/commands/status.js +95 -0
  17. package/dist/commands/status.js.map +1 -0
  18. package/dist/commands/test.d.ts +3 -0
  19. package/dist/commands/test.d.ts.map +1 -0
  20. package/dist/commands/test.js +89 -0
  21. package/dist/commands/test.js.map +1 -0
  22. package/dist/lib/api-client.d.ts +37 -0
  23. package/dist/lib/api-client.d.ts.map +1 -0
  24. package/dist/lib/api-client.js +92 -0
  25. package/dist/lib/api-client.js.map +1 -0
  26. package/dist/lib/config.d.ts +12 -0
  27. package/dist/lib/config.d.ts.map +1 -0
  28. package/dist/lib/config.js +110 -0
  29. package/dist/lib/config.js.map +1 -0
  30. package/dist/lib/flags.d.ts +7 -0
  31. package/dist/lib/flags.d.ts.map +1 -0
  32. package/dist/lib/flags.js +20 -0
  33. package/dist/lib/flags.js.map +1 -0
  34. package/dist/lib/logger.d.ts +24 -0
  35. package/dist/lib/logger.d.ts.map +1 -0
  36. package/dist/lib/logger.js +78 -0
  37. package/dist/lib/logger.js.map +1 -0
  38. package/dist/lib/prompts.d.ts +9 -0
  39. package/dist/lib/prompts.d.ts.map +1 -0
  40. package/dist/lib/prompts.js +79 -0
  41. package/dist/lib/prompts.js.map +1 -0
  42. package/dist/lib/stripe-oauth.d.ts +15 -0
  43. package/dist/lib/stripe-oauth.d.ts.map +1 -0
  44. package/dist/lib/stripe-oauth.js +168 -0
  45. package/dist/lib/stripe-oauth.js.map +1 -0
  46. package/dist/types.d.ts +84 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +17 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +54 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerTestCommand(program: Command): void;
3
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QAOnD"}
@@ -0,0 +1,89 @@
1
+ import * as logger from "../lib/logger.js";
2
+ import { readConfig, ConfigNotFoundError } from "../lib/config.js";
3
+ import { AffitorAPI, APIError, NetworkError } from "../lib/api-client.js";
4
+ import { getFlags } from "../lib/flags.js";
5
+ export function registerTestCommand(program) {
6
+ program
7
+ .command("test [event-type]")
8
+ .description("Send a test event (click, lead, or sale)")
9
+ .action(async (eventType, _opts, cmd) => {
10
+ await runTest(eventType, getFlags(cmd));
11
+ });
12
+ }
13
+ async function runTest(eventType, flags) {
14
+ let config;
15
+ try {
16
+ config = readConfig();
17
+ }
18
+ catch (err) {
19
+ if (err instanceof ConfigNotFoundError) {
20
+ logger.error(err.message);
21
+ if (flags.json)
22
+ logger.json({ error: "no_config" });
23
+ process.exit(1);
24
+ }
25
+ throw err;
26
+ }
27
+ const validTypes = ["click", "lead", "sale"];
28
+ const type = eventType ?? "click";
29
+ if (!validTypes.includes(type)) {
30
+ logger.error(`Invalid event type: "${eventType}".\n` +
31
+ " Valid types: click, lead, sale\n" +
32
+ " Example: npx affitor test sale");
33
+ if (flags.json)
34
+ logger.json({ error: "invalid_event_type" });
35
+ process.exit(1);
36
+ }
37
+ const api = new AffitorAPI({
38
+ apiUrl: flags.apiUrl ?? config.api_url,
39
+ apiKey: flags.apiKey ?? config.api_key,
40
+ });
41
+ logger.step(`Sending test ${type} event...`);
42
+ try {
43
+ const result = await api.sendTestEvent({
44
+ program_id: config.program_id,
45
+ event_type: type,
46
+ });
47
+ if (flags.json) {
48
+ logger.json(result);
49
+ return;
50
+ }
51
+ if (result.received) {
52
+ logger.success(`Test ${type} event received`);
53
+ logger.step(`Event ID: ${result.event_id}`);
54
+ if (result.attributed) {
55
+ logger.success("Event attributed to test partner");
56
+ }
57
+ else {
58
+ logger.step("Event received but not attributed (expected for test events)");
59
+ }
60
+ if (result.message) {
61
+ logger.info(` ${result.message}`);
62
+ }
63
+ }
64
+ else {
65
+ logger.error(`Test ${type} event was not received.`);
66
+ logger.info(" Check your API key and connection:");
67
+ logger.info(" $ npx affitor status");
68
+ }
69
+ }
70
+ catch (err) {
71
+ if (err instanceof APIError) {
72
+ logger.error(`API error: ${err.message}`);
73
+ if (flags.json)
74
+ logger.json({ error: err.message, status: err.status });
75
+ }
76
+ else if (err instanceof NetworkError) {
77
+ logger.error(err.message);
78
+ if (flags.json)
79
+ logger.json({ error: "network_error" });
80
+ }
81
+ else {
82
+ logger.error(`Unexpected error: ${err.message}`);
83
+ if (flags.json)
84
+ logger.json({ error: "unexpected_error" });
85
+ }
86
+ process.exit(1);
87
+ }
88
+ }
89
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { InitResponse, StripeConnectResponse, ProgramStatus, TestEventResult } from "../types.js";
2
+ export declare class AffitorAPI {
3
+ private apiUrl;
4
+ private apiKey?;
5
+ constructor(opts?: {
6
+ apiUrl?: string;
7
+ apiKey?: string;
8
+ });
9
+ initProgram(data: {
10
+ name: string;
11
+ domain: string;
12
+ commission_type: string;
13
+ commission_rate: number;
14
+ cookie_duration: number;
15
+ duration_months?: number;
16
+ }): Promise<InitResponse>;
17
+ saveStripeConnection(data: {
18
+ program_id: string;
19
+ stripe_user_id: string;
20
+ webhook_endpoint_id: string;
21
+ webhook_secret: string;
22
+ }): Promise<StripeConnectResponse>;
23
+ getStatus(programId: string): Promise<ProgramStatus>;
24
+ sendTestEvent(data: {
25
+ program_id: string;
26
+ event_type: "click" | "lead" | "sale";
27
+ }): Promise<TestEventResult>;
28
+ private request;
29
+ }
30
+ export declare class APIError extends Error {
31
+ status: number;
32
+ constructor(status: number, message: string);
33
+ }
34
+ export declare class NetworkError extends Error {
35
+ constructor(message: string);
36
+ }
37
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,eAAe,EAChB,MAAM,aAAa,CAAC;AAUrB,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAKrD,WAAW,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,YAAY,CAAC;IAOnB,oBAAoB,CAAC,IAAI,EAAE;QAC/B,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAO5B,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAMpD,aAAa,CAAC,IAAI,EAAE;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;KACvC,GAAG,OAAO,CAAC,eAAe,CAAC;YAOd,OAAO;CAuDtB;AAED,qBAAa,QAAS,SAAQ,KAAK;IAExB,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B"}
@@ -0,0 +1,92 @@
1
+ import { DEFAULT_API_URL } from "../types.js";
2
+ import * as logger from "./logger.js";
3
+ export class AffitorAPI {
4
+ apiUrl;
5
+ apiKey;
6
+ constructor(opts = {}) {
7
+ this.apiUrl = opts.apiUrl ?? DEFAULT_API_URL;
8
+ this.apiKey = opts.apiKey;
9
+ }
10
+ async initProgram(data) {
11
+ return this.request("/api/v1/cli/init", {
12
+ method: "POST",
13
+ body: data,
14
+ });
15
+ }
16
+ async saveStripeConnection(data) {
17
+ return this.request("/api/v1/cli/stripe-connect", {
18
+ method: "POST",
19
+ body: data,
20
+ });
21
+ }
22
+ async getStatus(programId) {
23
+ return this.request(`/api/v1/cli/status?program_id=${programId}`);
24
+ }
25
+ async sendTestEvent(data) {
26
+ return this.request("/api/v1/cli/test-event", {
27
+ method: "POST",
28
+ body: data,
29
+ });
30
+ }
31
+ async request(path, opts = {}) {
32
+ const url = `${opts.apiUrl ?? this.apiUrl}${path}`;
33
+ const key = opts.apiKey ?? this.apiKey;
34
+ const headers = {
35
+ "Content-Type": "application/json",
36
+ "User-Agent": "affitor-cli/0.1.0",
37
+ };
38
+ if (key) {
39
+ headers["Authorization"] = `Bearer ${key}`;
40
+ }
41
+ logger.debug(`${opts.method ?? "GET"} ${url}`);
42
+ let lastError;
43
+ for (let attempt = 1; attempt <= 3; attempt++) {
44
+ try {
45
+ const res = await fetch(url, {
46
+ method: opts.method ?? "GET",
47
+ headers,
48
+ body: opts.body ? JSON.stringify(opts.body) : undefined,
49
+ });
50
+ if (res.status === 429) {
51
+ const retryAfter = res.headers.get("Retry-After");
52
+ const wait = retryAfter ? parseInt(retryAfter, 10) * 1000 : 5000;
53
+ throw new APIError(429, `Rate limited. Wait ${Math.ceil(wait / 1000)} seconds and try again.`);
54
+ }
55
+ if (!res.ok) {
56
+ const body = await res.json().catch(() => ({}));
57
+ const message = body.error ??
58
+ `API returned ${res.status}`;
59
+ throw new APIError(res.status, message);
60
+ }
61
+ const body = await res.json();
62
+ return body.data ?? body;
63
+ }
64
+ catch (err) {
65
+ if (err instanceof APIError)
66
+ throw err;
67
+ lastError = err;
68
+ if (attempt < 3) {
69
+ const wait = attempt * 1000;
70
+ logger.debug(`Request failed, retrying in ${wait}ms...`);
71
+ await new Promise((r) => setTimeout(r, wait));
72
+ }
73
+ }
74
+ }
75
+ throw new NetworkError(lastError?.message ?? "Request failed after 3 attempts");
76
+ }
77
+ }
78
+ export class APIError extends Error {
79
+ status;
80
+ constructor(status, message) {
81
+ super(message);
82
+ this.status = status;
83
+ this.name = "APIError";
84
+ }
85
+ }
86
+ export class NetworkError extends Error {
87
+ constructor(message) {
88
+ super(`Network error: ${message}.\nCheck your internet connection and try again.`);
89
+ this.name = "NetworkError";
90
+ }
91
+ }
92
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type AffitorConfig } from "../types.js";
2
+ export declare function configExists(cwd?: string): boolean;
3
+ export declare function readConfig(cwd?: string): AffitorConfig;
4
+ export declare function writeConfig(config: AffitorConfig, cwd?: string): void;
5
+ export declare function updateConfig(updates: Partial<AffitorConfig>, cwd?: string): AffitorConfig;
6
+ export declare function writeEnvExample(config: AffitorConfig, cwd?: string): void;
7
+ export declare function writeSkillsFile(config: AffitorConfig, programName: string, cwd?: string): void;
8
+ export declare function appendToGitignore(cwd?: string): void;
9
+ export declare class ConfigNotFoundError extends Error {
10
+ constructor(dir: string);
11
+ }
12
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAU1E,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,aAAa,CAOtD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAMrE;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAC/B,GAAG,CAAC,EAAE,MAAM,GACX,aAAa,CAKf;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAUN;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,GACX,IAAI,CAkCN;AAED,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CASpD;AAgBD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,GAAG,EAAE,MAAM;CAOxB"}
@@ -0,0 +1,110 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { CONFIG_DIR, CONFIG_FILE } from "../types.js";
4
+ function getConfigDir(cwd) {
5
+ return join(cwd ?? process.cwd(), CONFIG_DIR);
6
+ }
7
+ function getConfigPath(cwd) {
8
+ return join(getConfigDir(cwd), CONFIG_FILE);
9
+ }
10
+ export function configExists(cwd) {
11
+ return existsSync(getConfigPath(cwd));
12
+ }
13
+ export function readConfig(cwd) {
14
+ const path = getConfigPath(cwd);
15
+ if (!existsSync(path)) {
16
+ throw new ConfigNotFoundError(resolve(cwd ?? process.cwd()));
17
+ }
18
+ const raw = readFileSync(path, "utf-8");
19
+ return JSON.parse(raw);
20
+ }
21
+ export function writeConfig(config, cwd) {
22
+ const dir = getConfigDir(cwd);
23
+ if (!existsSync(dir)) {
24
+ mkdirSync(dir, { recursive: true });
25
+ }
26
+ writeFileSync(getConfigPath(cwd), JSON.stringify(config, null, 2) + "\n");
27
+ }
28
+ export function updateConfig(updates, cwd) {
29
+ const config = readConfig(cwd);
30
+ const updated = { ...config, ...updates };
31
+ writeConfig(updated, cwd);
32
+ return updated;
33
+ }
34
+ export function writeEnvExample(config, cwd) {
35
+ const dir = getConfigDir(cwd);
36
+ const content = `# Affitor Tracking — auto-generated by \`npx affitor init\`
37
+ # Add these to your .env file
38
+
39
+ AFFITOR_API_KEY=${config.api_key}
40
+ AFFITOR_PROGRAM_ID=${config.program_id}
41
+ ${config.stripe_account_id ? `STRIPE_CONNECTED_ACCOUNT_ID=${config.stripe_account_id}` : "# STRIPE_CONNECTED_ACCOUNT_ID= (run \`npx affitor setup stripe\` to connect)"}
42
+ `;
43
+ writeFileSync(join(dir, ".env.example"), content);
44
+ }
45
+ export function writeSkillsFile(config, programName, cwd) {
46
+ const dir = getConfigDir(cwd);
47
+ const content = `# Affitor Program: ${programName}
48
+
49
+ ## Quick Reference
50
+
51
+ - **Program ID**: ${config.program_id}
52
+ - **Domain**: ${config.domain}
53
+ - **Commission**: ${formatCommission(config)}
54
+ - **Cookie Duration**: ${config.cookie.duration_days} days
55
+ - **Stripe**: ${config.stripe_connected ? "Connected" : "Not connected"}
56
+
57
+ ## CLI Commands
58
+
59
+ \`\`\`bash
60
+ npx affitor status # Check program health
61
+ npx affitor setup stripe # Connect Stripe for payment tracking
62
+ npx affitor test sale # Send test sale event
63
+ npx affitor affiliates list # List active partners
64
+ \`\`\`
65
+
66
+ ## API Endpoints
67
+
68
+ - Base URL: ${config.api_url}
69
+ - Auth: \`Authorization: Bearer \${AFFITOR_API_KEY}\`
70
+ - Track click: \`GET https://t.${config.domain}/c/<link_code>\`
71
+ - Track sale: \`POST ${config.api_url}/api/v1/track/sale\`
72
+
73
+ ## For AI Agents
74
+
75
+ Use \`--no-interactive --json\` flags for all commands.
76
+ API key is in \`.affitor/.env.example\`.
77
+ `;
78
+ writeFileSync(join(dir, "skills.md"), content);
79
+ }
80
+ export function appendToGitignore(cwd) {
81
+ const gitignorePath = join(cwd ?? process.cwd(), ".gitignore");
82
+ const entry = "\n# Affitor local config\n.affitor/.env\n";
83
+ if (existsSync(gitignorePath)) {
84
+ const content = readFileSync(gitignorePath, "utf-8");
85
+ if (content.includes(".affitor/.env"))
86
+ return;
87
+ writeFileSync(gitignorePath, content + entry);
88
+ }
89
+ }
90
+ function formatCommission(config) {
91
+ const { type, rate, duration_months } = config.commission;
92
+ switch (type) {
93
+ case "percent":
94
+ return `${rate}% per sale`;
95
+ case "fixed":
96
+ return `$${rate} per sale`;
97
+ case "recurring_percent":
98
+ return `${rate}% recurring${duration_months ? ` for ${duration_months} months` : ""}`;
99
+ case "recurring_fixed":
100
+ return `$${rate} recurring${duration_months ? ` for ${duration_months} months` : ""}`;
101
+ }
102
+ }
103
+ export class ConfigNotFoundError extends Error {
104
+ constructor(dir) {
105
+ super(`No Affitor config found in ${dir}.\n` +
106
+ `Run ${"`npx affitor init`"} to set up your program.`);
107
+ this.name = "ConfigNotFoundError";
108
+ }
109
+ }
110
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Command } from "commander";
2
+ import type { CLIFlags } from "../types.js";
3
+ /**
4
+ * Walk up the command chain to the root program and read global flags.
5
+ */
6
+ export declare function getFlags(cmd: Command): CLIFlags;
7
+ //# sourceMappingURL=flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/lib/flags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAe/C"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Walk up the command chain to the root program and read global flags.
3
+ */
4
+ export function getFlags(cmd) {
5
+ let root = cmd;
6
+ while (root.parent) {
7
+ root = root.parent;
8
+ }
9
+ const opts = root.opts();
10
+ return {
11
+ json: opts.json ?? false,
12
+ noInteractive: opts.interactive === false,
13
+ autoConfirm: opts.autoConfirm ?? false,
14
+ quiet: opts.quiet ?? false,
15
+ apiKey: opts.apiKey,
16
+ apiUrl: opts.apiUrl,
17
+ verbose: opts.verbose ?? false,
18
+ };
19
+ }
20
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/lib/flags.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAY;IACnC,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACzB,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;QACxB,aAAa,EAAE,IAAI,CAAC,WAAW,KAAK,KAAK;QACzC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;QACtC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;QAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ export declare function setLoggerOptions(opts: {
2
+ quiet?: boolean;
3
+ json?: boolean;
4
+ verbose?: boolean;
5
+ }): void;
6
+ export declare function info(msg: string): void;
7
+ export declare function success(msg: string): void;
8
+ export declare function warn(msg: string): void;
9
+ export declare function error(msg: string): void;
10
+ export declare function step(msg: string): void;
11
+ export declare function debug(msg: string): void;
12
+ export declare function json(data: unknown): void;
13
+ export declare function box(lines: string[]): void;
14
+ export declare function newline(): void;
15
+ export declare const format: {
16
+ bold: import("picocolors/types.js").Formatter;
17
+ dim: import("picocolors/types.js").Formatter;
18
+ green: import("picocolors/types.js").Formatter;
19
+ yellow: import("picocolors/types.js").Formatter;
20
+ red: import("picocolors/types.js").Formatter;
21
+ cyan: import("picocolors/types.js").Formatter;
22
+ blue: import("picocolors/types.js").Formatter;
23
+ };
24
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,QAIA;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,QAG/B;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,QAGlC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,QAG/B;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,QAGhC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,QAG/B;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,QAGhC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,QAEjC;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAYlC;AAED,wBAAgB,OAAO,SAGtB;AAOD,eAAO,MAAM,MAAM;;;;;;;;CAQlB,CAAC"}
@@ -0,0 +1,78 @@
1
+ import pc from "picocolors";
2
+ let quietMode = false;
3
+ let jsonMode = false;
4
+ let verboseMode = false;
5
+ export function setLoggerOptions(opts) {
6
+ if (opts.quiet !== undefined)
7
+ quietMode = opts.quiet;
8
+ if (opts.json !== undefined)
9
+ jsonMode = opts.json;
10
+ if (opts.verbose !== undefined)
11
+ verboseMode = opts.verbose;
12
+ }
13
+ export function info(msg) {
14
+ if (quietMode || jsonMode)
15
+ return;
16
+ console.log(msg);
17
+ }
18
+ export function success(msg) {
19
+ if (jsonMode)
20
+ return;
21
+ console.log(pc.green("✓") + " " + msg);
22
+ }
23
+ export function warn(msg) {
24
+ if (jsonMode)
25
+ return;
26
+ console.log(pc.yellow("⚠") + " " + msg);
27
+ }
28
+ export function error(msg) {
29
+ if (jsonMode)
30
+ return;
31
+ console.error(pc.red("✗") + " " + msg);
32
+ }
33
+ export function step(msg) {
34
+ if (quietMode || jsonMode)
35
+ return;
36
+ console.log(pc.dim(" " + msg));
37
+ }
38
+ export function debug(msg) {
39
+ if (!verboseMode || jsonMode)
40
+ return;
41
+ console.log(pc.dim("[debug] " + msg));
42
+ }
43
+ export function json(data) {
44
+ console.log(JSON.stringify(data, null, 2));
45
+ }
46
+ export function box(lines) {
47
+ if (jsonMode)
48
+ return;
49
+ const maxLen = Math.max(...lines.map((l) => stripAnsi(l).length));
50
+ const border = "─".repeat(maxLen + 2);
51
+ console.log();
52
+ console.log(` ╭${border}╮`);
53
+ for (const line of lines) {
54
+ const padding = " ".repeat(maxLen - stripAnsi(line).length);
55
+ console.log(` │ ${line}${padding} │`);
56
+ }
57
+ console.log(` ╰${border}╯`);
58
+ console.log();
59
+ }
60
+ export function newline() {
61
+ if (quietMode || jsonMode)
62
+ return;
63
+ console.log();
64
+ }
65
+ function stripAnsi(str) {
66
+ // eslint-disable-next-line no-control-regex
67
+ return str.replace(/\u001b\[[0-9;]*m/g, "");
68
+ }
69
+ export const format = {
70
+ bold: pc.bold,
71
+ dim: pc.dim,
72
+ green: pc.green,
73
+ yellow: pc.yellow,
74
+ red: pc.red,
75
+ cyan: pc.cyan,
76
+ blue: pc.blue,
77
+ };
78
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CommissionType } from "../types.js";
2
+ export declare function promptProgramName(): Promise<string>;
3
+ export declare function promptDomain(): Promise<string>;
4
+ export declare function promptCommissionType(): Promise<CommissionType>;
5
+ export declare function promptCommissionRate(type: CommissionType): Promise<number>;
6
+ export declare function promptDurationMonths(): Promise<number>;
7
+ export declare function promptCookieDuration(): Promise<number>;
8
+ export declare function confirmAction(message: string): Promise<boolean>;
9
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAKzD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAYpD;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CAUpE;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAYhF;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU5D;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAW5D;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE"}
@@ -0,0 +1,79 @@
1
+ import { input, select, confirm } from "@inquirer/prompts";
2
+ export async function promptProgramName() {
3
+ return input({
4
+ message: "Program name:",
5
+ validate: (v) => (v.trim().length > 0 ? true : "Program name is required"),
6
+ });
7
+ }
8
+ export async function promptDomain() {
9
+ return input({
10
+ message: "Your domain (root):",
11
+ validate: (v) => {
12
+ const d = v.trim();
13
+ if (!d)
14
+ return "Domain is required";
15
+ if (!d.includes("."))
16
+ return "Enter a valid domain (e.g., example.com)";
17
+ if (d.startsWith("http"))
18
+ return "Enter domain without http:// (e.g., example.com)";
19
+ return true;
20
+ },
21
+ transformer: (v) => v.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/\/$/, ""),
22
+ });
23
+ }
24
+ export async function promptCommissionType() {
25
+ return select({
26
+ message: "Commission type:",
27
+ choices: [
28
+ { value: "recurring_percent", name: "Recurring percentage (e.g., 20% for 12 months)" },
29
+ { value: "percent", name: "One-time percentage (e.g., 20%)" },
30
+ { value: "fixed", name: "Fixed amount per sale (e.g., $50)" },
31
+ { value: "recurring_fixed", name: "Recurring fixed amount (e.g., $10/month)" },
32
+ ],
33
+ });
34
+ }
35
+ export async function promptCommissionRate(type) {
36
+ const isPercent = type.includes("percent");
37
+ return input({
38
+ message: isPercent ? "Commission rate (%):" : "Commission amount ($):",
39
+ validate: (v) => {
40
+ const n = parseFloat(v);
41
+ if (isNaN(n) || n <= 0)
42
+ return "Enter a positive number";
43
+ if (isPercent && n > 100)
44
+ return "Percentage cannot exceed 100";
45
+ return true;
46
+ },
47
+ transformer: (v) => v.trim(),
48
+ }).then((v) => parseFloat(v));
49
+ }
50
+ export async function promptDurationMonths() {
51
+ return input({
52
+ message: "Commission duration (months, 0 = lifetime):",
53
+ default: "12",
54
+ validate: (v) => {
55
+ const n = parseInt(v, 10);
56
+ if (isNaN(n) || n < 0)
57
+ return "Enter 0 or a positive number";
58
+ return true;
59
+ },
60
+ }).then((v) => parseInt(v, 10));
61
+ }
62
+ export async function promptCookieDuration() {
63
+ return input({
64
+ message: "Cookie duration (days):",
65
+ default: "90",
66
+ validate: (v) => {
67
+ const n = parseInt(v, 10);
68
+ if (isNaN(n) || n < 1)
69
+ return "Enter a positive number";
70
+ if (n > 365)
71
+ return "Maximum 365 days";
72
+ return true;
73
+ },
74
+ }).then((v) => parseInt(v, 10));
75
+ }
76
+ export async function confirmAction(message) {
77
+ return confirm({ message, default: true });
78
+ }
79
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"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"}