affitor 0.2.0 → 0.3.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 (63) hide show
  1. package/dist/cli.js +28 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +86 -51
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/login.d.ts +3 -0
  7. package/dist/commands/login.d.ts.map +1 -0
  8. package/dist/commands/login.js +123 -0
  9. package/dist/commands/login.js.map +1 -0
  10. package/dist/commands/logout.d.ts +3 -0
  11. package/dist/commands/logout.d.ts.map +1 -0
  12. package/dist/commands/logout.js +23 -0
  13. package/dist/commands/logout.js.map +1 -0
  14. package/dist/commands/programs.d.ts +3 -0
  15. package/dist/commands/programs.d.ts.map +1 -0
  16. package/dist/commands/programs.js +54 -0
  17. package/dist/commands/programs.js.map +1 -0
  18. package/dist/commands/setup-stripe.d.ts.map +1 -1
  19. package/dist/commands/setup-stripe.js +51 -35
  20. package/dist/commands/setup-stripe.js.map +1 -1
  21. package/dist/commands/status.d.ts.map +1 -1
  22. package/dist/commands/status.js +38 -32
  23. package/dist/commands/status.js.map +1 -1
  24. package/dist/commands/test.d.ts.map +1 -1
  25. package/dist/commands/test.js +8 -9
  26. package/dist/commands/test.js.map +1 -1
  27. package/dist/commands/whoami.d.ts +3 -0
  28. package/dist/commands/whoami.d.ts.map +1 -0
  29. package/dist/commands/whoami.js +38 -0
  30. package/dist/commands/whoami.js.map +1 -0
  31. package/dist/lib/api-client.d.ts +25 -1
  32. package/dist/lib/api-client.d.ts.map +1 -1
  33. package/dist/lib/api-client.js +26 -1
  34. package/dist/lib/api-client.js.map +1 -1
  35. package/dist/lib/config.d.ts +11 -3
  36. package/dist/lib/config.d.ts.map +1 -1
  37. package/dist/lib/config.js +171 -11
  38. package/dist/lib/config.js.map +1 -1
  39. package/dist/lib/inject.d.ts +27 -0
  40. package/dist/lib/inject.d.ts.map +1 -0
  41. package/dist/lib/inject.js +81 -0
  42. package/dist/lib/inject.js.map +1 -0
  43. package/dist/lib/logger.d.ts +8 -0
  44. package/dist/lib/logger.d.ts.map +1 -1
  45. package/dist/lib/logger.js +72 -0
  46. package/dist/lib/logger.js.map +1 -1
  47. package/dist/lib/server-tracking.d.ts +25 -0
  48. package/dist/lib/server-tracking.d.ts.map +1 -0
  49. package/dist/lib/server-tracking.js +109 -0
  50. package/dist/lib/server-tracking.js.map +1 -0
  51. package/dist/lib/stack-detect.d.ts +18 -0
  52. package/dist/lib/stack-detect.d.ts.map +1 -0
  53. package/dist/lib/stack-detect.js +57 -0
  54. package/dist/lib/stack-detect.js.map +1 -0
  55. package/dist/lib/wizard.d.ts +14 -0
  56. package/dist/lib/wizard.d.ts.map +1 -0
  57. package/dist/lib/wizard.js +166 -0
  58. package/dist/lib/wizard.js.map +1 -0
  59. package/dist/types.d.ts +27 -2
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/types.js +3 -0
  62. package/dist/types.js.map +1 -1
  63. package/package.json +2 -2
@@ -1,12 +1,18 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync, unlinkSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { CONFIG_DIR, CONFIG_FILE } from "../types.js";
3
+ import { homedir } from "node:os";
4
+ import { CONFIG_DIR, CONFIG_FILE, SECRETS_FILE, GLOBAL_CONFIG_DIR, CREDENTIALS_FILE, } from "../types.js";
5
+ import * as logger from "./logger.js";
6
+ // ─── Project config (per-directory) ───────────────────────────────
4
7
  function getConfigDir(cwd) {
5
8
  return join(cwd ?? process.cwd(), CONFIG_DIR);
6
9
  }
7
10
  function getConfigPath(cwd) {
8
11
  return join(getConfigDir(cwd), CONFIG_FILE);
9
12
  }
13
+ function getSecretsPath(cwd) {
14
+ return join(getConfigDir(cwd), SECRETS_FILE);
15
+ }
10
16
  export function configExists(cwd) {
11
17
  return existsSync(getConfigPath(cwd));
12
18
  }
@@ -16,7 +22,12 @@ export function readConfig(cwd) {
16
22
  throw new ConfigNotFoundError(resolve(cwd ?? process.cwd()));
17
23
  }
18
24
  const raw = readFileSync(path, "utf-8");
19
- return JSON.parse(raw);
25
+ const config = JSON.parse(raw);
26
+ // Auto-migrate v1 → v2
27
+ if (config.version === 1 && config.api_key) {
28
+ migrateV1ToV2(config, cwd);
29
+ }
30
+ return config;
20
31
  }
21
32
  export function writeConfig(config, cwd) {
22
33
  const dir = getConfigDir(cwd);
@@ -31,18 +42,159 @@ export function updateConfig(updates, cwd) {
31
42
  writeConfig(updated, cwd);
32
43
  return updated;
33
44
  }
34
- export function writeEnvExample(config, cwd) {
45
+ // ─── Secrets (.affitor/.env) ──────────────────────────────────────
46
+ export function readSecrets(cwd) {
47
+ const path = getSecretsPath(cwd);
48
+ if (!existsSync(path))
49
+ return null;
50
+ const content = readFileSync(path, "utf-8");
51
+ const vars = {};
52
+ for (const line of content.split("\n")) {
53
+ const trimmed = line.trim();
54
+ if (!trimmed || trimmed.startsWith("#"))
55
+ continue;
56
+ const eqIdx = trimmed.indexOf("=");
57
+ if (eqIdx === -1)
58
+ continue;
59
+ const key = trimmed.slice(0, eqIdx).trim();
60
+ const value = trimmed.slice(eqIdx + 1).trim();
61
+ vars[key] = value;
62
+ }
63
+ if (!vars.AFFITOR_API_KEY)
64
+ return null;
65
+ return {
66
+ api_key: vars.AFFITOR_API_KEY,
67
+ program_id: vars.AFFITOR_PROGRAM_ID ?? "",
68
+ stripe_account_id: vars.STRIPE_CONNECTED_ACCOUNT_ID,
69
+ };
70
+ }
71
+ export function writeSecrets(secrets, cwd) {
72
+ const dir = getConfigDir(cwd);
73
+ if (!existsSync(dir)) {
74
+ mkdirSync(dir, { recursive: true });
75
+ }
76
+ const lines = [
77
+ "# Affitor secrets — auto-generated, DO NOT commit",
78
+ `AFFITOR_API_KEY=${secrets.api_key}`,
79
+ `AFFITOR_PROGRAM_ID=${secrets.program_id}`,
80
+ ];
81
+ if (secrets.stripe_account_id) {
82
+ lines.push(`STRIPE_CONNECTED_ACCOUNT_ID=${secrets.stripe_account_id}`);
83
+ }
84
+ lines.push("");
85
+ writeFileSync(getSecretsPath(cwd), lines.join("\n"));
86
+ }
87
+ // ─── Global credentials (~/.affitor/) ─────────────────────────────
88
+ function getGlobalDir() {
89
+ return join(homedir(), GLOBAL_CONFIG_DIR);
90
+ }
91
+ function getCredentialsPath() {
92
+ return join(getGlobalDir(), CREDENTIALS_FILE);
93
+ }
94
+ export function readCredentials() {
95
+ const path = getCredentialsPath();
96
+ if (!existsSync(path))
97
+ return null;
98
+ const raw = readFileSync(path, "utf-8").trim();
99
+ if (!raw)
100
+ return null;
101
+ try {
102
+ const creds = JSON.parse(raw);
103
+ if (new Date(creds.expires_at) < new Date()) {
104
+ return null;
105
+ }
106
+ return creds;
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ }
112
+ export function writeCredentials(creds) {
113
+ const dir = getGlobalDir();
114
+ if (!existsSync(dir)) {
115
+ mkdirSync(dir, { recursive: true });
116
+ }
117
+ const path = getCredentialsPath();
118
+ writeFileSync(path, JSON.stringify(creds, null, 2) + "\n");
119
+ // Secure file permissions: owner read/write only
120
+ chmodSync(path, 0o600);
121
+ }
122
+ export function deleteCredentials() {
123
+ const path = getCredentialsPath();
124
+ if (existsSync(path)) {
125
+ unlinkSync(path);
126
+ }
127
+ }
128
+ // ─── Resolve API key (priority chain) ─────────────────────────────
129
+ export function resolveApiKey(flags, cwd) {
130
+ // 1. --api-key flag
131
+ if (flags.apiKey)
132
+ return flags.apiKey;
133
+ // 2. AFFITOR_API_KEY env var
134
+ if (process.env.AFFITOR_API_KEY)
135
+ return process.env.AFFITOR_API_KEY;
136
+ // 3. .affitor/.env (project secrets)
137
+ const secrets = readSecrets(cwd);
138
+ if (secrets?.api_key)
139
+ return secrets.api_key;
140
+ // 4. Legacy: config.json api_key (v1)
141
+ try {
142
+ const configPath = getConfigPath(cwd);
143
+ if (existsSync(configPath)) {
144
+ const raw = readFileSync(configPath, "utf-8");
145
+ const config = JSON.parse(raw);
146
+ if (config.api_key)
147
+ return config.api_key;
148
+ }
149
+ }
150
+ catch {
151
+ // ignore
152
+ }
153
+ return null;
154
+ }
155
+ // ─── v1 → v2 migration ───────────────────────────────────────────
156
+ function migrateV1ToV2(config, cwd) {
157
+ logger.info("");
158
+ logger.info(` ${logger.format.yellow("Migrating")} config v1 → v2 (moving secrets to .env)...`);
159
+ // Write secrets to .env
160
+ if (config.api_key) {
161
+ writeSecrets({
162
+ api_key: config.api_key,
163
+ program_id: String(config.program_id),
164
+ stripe_account_id: config.stripe_account_id,
165
+ }, cwd);
166
+ }
167
+ // Strip secrets from config.json
168
+ const cleaned = {
169
+ version: 2,
170
+ program_id: config.program_id,
171
+ domain: config.domain,
172
+ tracking_subdomain: config.tracking_subdomain,
173
+ commission: config.commission,
174
+ cookie: config.cookie,
175
+ ref_param: config.ref_param,
176
+ api_url: config.api_url,
177
+ created_at: config.created_at,
178
+ };
179
+ writeConfig(cleaned, cwd);
180
+ // Fix gitignore
181
+ appendToGitignore(cwd);
182
+ logger.success("Config migrated. Secrets now in .affitor/.env");
183
+ logger.info("");
184
+ }
185
+ // ─── AGENTS.md / .env.example / gitignore ─────────────────────────
186
+ export function writeEnvExample(config, apiKey, cwd) {
35
187
  const dir = getConfigDir(cwd);
36
188
  const content = `# Affitor Tracking — auto-generated by \`npx affitor init\`
37
189
  # Add these to your .env file
38
190
 
39
- AFFITOR_API_KEY=${config.api_key}
191
+ AFFITOR_API_KEY=${apiKey}
40
192
  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)"}
193
+ # STRIPE_CONNECTED_ACCOUNT_ID= (run \`npx affitor setup stripe\` to connect)
42
194
  `;
43
195
  writeFileSync(join(dir, ".env.example"), content);
44
196
  }
45
- export function writeSkillsFile(config, programName, cwd) {
197
+ export function writeSkillsFile(config, programName, apiKey, cwd) {
46
198
  const dir = getConfigDir(cwd);
47
199
  const content = `# Affitor: ${programName}
48
200
 
@@ -59,7 +211,7 @@ This project uses Affitor for affiliate/partner tracking. Affitor tracks clicks,
59
211
  - **Commission**: ${formatCommission(config)}
60
212
  - **Cookie Duration**: ${config.cookie.duration_days} days
61
213
  - **API Base URL**: \`${config.api_url}\`
62
- - **API Key**: stored in \`.affitor/.env.example\` as \`AFFITOR_API_KEY\`
214
+ - **API Key**: stored in \`.affitor/.env\` as \`AFFITOR_API_KEY\`
63
215
 
64
216
  ## Integration Instructions
65
217
 
@@ -178,12 +330,20 @@ npx affitor test sale # Send test sale event
178
330
  }
179
331
  export function appendToGitignore(cwd) {
180
332
  const gitignorePath = join(cwd ?? process.cwd(), ".gitignore");
181
- const entry = "\n# Affitor local config\n.affitor/.env\n";
333
+ const entries = [".affitor/.env", ".affitor/.env.*"];
182
334
  if (existsSync(gitignorePath)) {
183
335
  const content = readFileSync(gitignorePath, "utf-8");
184
- if (content.includes(".affitor/.env"))
336
+ const missing = entries.filter((e) => !content.includes(e));
337
+ if (missing.length === 0)
185
338
  return;
186
- writeFileSync(gitignorePath, content + entry);
339
+ const block = "\n# Affitor secrets (do not commit)\n" +
340
+ missing.map((e) => e + "\n").join("");
341
+ writeFileSync(gitignorePath, content + block);
342
+ }
343
+ else {
344
+ const block = "# Affitor secrets (do not commit)\n" +
345
+ entries.map((e) => e + "\n").join("");
346
+ writeFileSync(gitignorePath, block);
187
347
  }
188
348
  }
189
349
  function formatCommission(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Pure source transforms for the install wizard. No filesystem access — every
3
+ * function takes file content and returns the new content, so they are easy to
4
+ * unit test and never touch disk on their own. Injection is idempotent and
5
+ * never overwrites existing code; an unrecognized structure returns
6
+ * `unrecognized` so the wizard can fall back to printed instructions.
7
+ */
8
+ export type InjectStatus = "injected" | "already" | "unrecognized";
9
+ export interface InjectResult {
10
+ content: string;
11
+ status: InjectStatus;
12
+ /** Lines added (for the diff preview). Empty unless status === 'injected'. */
13
+ added: string[];
14
+ }
15
+ /** The `<AffitorTracker />` client component written next to the entry file. */
16
+ export declare function trackerComponentSource(programId: string | number, useClientDirective: boolean): string;
17
+ /**
18
+ * App Router: insert `<AffitorTracker />` right after the opening `<body>` tag
19
+ * of the root layout, and add the import.
20
+ */
21
+ export declare function injectAppLayout(content: string, importSpecifier: string): InjectResult;
22
+ /**
23
+ * Pages Router: wrap `<Component {...pageProps} />` so the tracker renders on
24
+ * every page, and add the import.
25
+ */
26
+ export declare function injectPagesApp(content: string, importSpecifier: string): InjectResult;
27
+ //# sourceMappingURL=inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../src/lib/inject.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAiBtG;AAmBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,YAAY,CAetF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,YAAY,CAerF"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Pure source transforms for the install wizard. No filesystem access — every
3
+ * function takes file content and returns the new content, so they are easy to
4
+ * unit test and never touch disk on their own. Injection is idempotent and
5
+ * never overwrites existing code; an unrecognized structure returns
6
+ * `unrecognized` so the wizard can fall back to printed instructions.
7
+ */
8
+ const TRACKER_MARKER = "AffitorTracker";
9
+ /** The `<AffitorTracker />` client component written next to the entry file. */
10
+ export function trackerComponentSource(programId, useClientDirective) {
11
+ const idLiteral = typeof programId === "number" ? `${programId}` : JSON.stringify(programId);
12
+ const prefix = useClientDirective ? "'use client';\n\n" : "";
13
+ return `${prefix}import { useEffect } from 'react';
14
+ import { init } from 'affitor-sdk';
15
+
16
+ /**
17
+ * Affitor affiliate tracking — auto-generated by \`affitor init\`.
18
+ * Captures ?aff= attribution on every page. Safe to keep at the app root.
19
+ */
20
+ export function ${TRACKER_MARKER}() {
21
+ useEffect(() => {
22
+ init({ programId: ${idLiteral} });
23
+ }, []);
24
+ return null;
25
+ }
26
+ `;
27
+ }
28
+ function importLineFor(importSpecifier) {
29
+ return `import { ${TRACKER_MARKER} } from '${importSpecifier}';`;
30
+ }
31
+ /** Add an import after the last existing top-level import (or at the very top). */
32
+ function addImport(content, importLine) {
33
+ if (content.includes(importLine))
34
+ return content;
35
+ const importRe = /^import .*$/gm;
36
+ let lastEnd = -1;
37
+ let m;
38
+ while ((m = importRe.exec(content)) !== null) {
39
+ lastEnd = m.index + m[0].length;
40
+ }
41
+ if (lastEnd === -1)
42
+ return `${importLine}\n${content}`;
43
+ return content.slice(0, lastEnd) + `\n${importLine}` + content.slice(lastEnd);
44
+ }
45
+ /**
46
+ * App Router: insert `<AffitorTracker />` right after the opening `<body>` tag
47
+ * of the root layout, and add the import.
48
+ */
49
+ export function injectAppLayout(content, importSpecifier) {
50
+ if (content.includes(TRACKER_MARKER))
51
+ return { content, status: "already", added: [] };
52
+ const bodyOpen = content.match(/<body[^>]*>/);
53
+ if (!bodyOpen)
54
+ return { content, status: "unrecognized", added: [] };
55
+ const importLine = importLineFor(importSpecifier);
56
+ const withImport = addImport(content, importLine);
57
+ const tag = bodyOpen[0];
58
+ const idx = withImport.indexOf(tag) + tag.length;
59
+ const rendered = ` <${TRACKER_MARKER} />`;
60
+ const injected = `${withImport.slice(0, idx)}\n${rendered}${withImport.slice(idx)}`;
61
+ return { content: injected, status: "injected", added: [importLine, rendered.trim()] };
62
+ }
63
+ /**
64
+ * Pages Router: wrap `<Component {...pageProps} />` so the tracker renders on
65
+ * every page, and add the import.
66
+ */
67
+ export function injectPagesApp(content, importSpecifier) {
68
+ if (content.includes(TRACKER_MARKER))
69
+ return { content, status: "already", added: [] };
70
+ const compRe = /<Component\s+\{\.\.\.pageProps\}\s*\/>/;
71
+ const match = content.match(compRe);
72
+ if (!match)
73
+ return { content, status: "unrecognized", added: [] };
74
+ const importLine = importLineFor(importSpecifier);
75
+ const withImport = addImport(content, importLine);
76
+ const component = match[0];
77
+ const replacement = `<>\n <${TRACKER_MARKER} />\n ${component}\n </>`;
78
+ const injected = withImport.replace(compRe, replacement);
79
+ return { content: injected, status: "injected", added: [importLine, `<${TRACKER_MARKER} />`] };
80
+ }
81
+ //# sourceMappingURL=inject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/lib/inject.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,14 @@ export declare function step(msg: string): void;
11
11
  export declare function debug(msg: string): void;
12
12
  export declare function json(data: unknown): void;
13
13
  export declare function box(lines: string[]): void;
14
+ export declare function titledBox(title: string, lines: string[]): void;
15
+ export declare function banner(): void;
16
+ export declare function progressStep(current: number, total: number, msg: string, done: boolean): void;
17
+ export declare function statusBadge(label: string, status: "ok" | "warn" | "error"): void;
18
+ export declare function miniBar(value: number, max: number, width?: number): string;
19
+ export declare function commandHelp(name: string, description: string): void;
20
+ export declare function sectionHeader(title: string): void;
21
+ export declare function maskApiKey(key: string): string;
14
22
  export declare function newline(): void;
15
23
  export declare const format: {
16
24
  bold: import("picocolors/types.js").Formatter;
@@ -1 +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"}
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,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAiBvD;AAED,wBAAgB,MAAM,SAcrB;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,QAOd;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,QASzE;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAW,GACjB,MAAM,CAKR;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAG5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,QAI1C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,wBAAgB,OAAO,SAGtB;AAOD,eAAO,MAAM,MAAM;;;;;;;;CAQlB,CAAC"}
@@ -57,6 +57,78 @@ export function box(lines) {
57
57
  console.log(` ╰${border}╯`);
58
58
  console.log();
59
59
  }
60
+ export function titledBox(title, lines) {
61
+ if (jsonMode)
62
+ return;
63
+ const maxLen = Math.max(stripAnsi(title).length + 2, ...lines.map((l) => stripAnsi(l).length));
64
+ const titleLen = stripAnsi(title).length;
65
+ const topBorder = "─".repeat(maxLen - titleLen);
66
+ const bottomBorder = "─".repeat(maxLen + 2);
67
+ console.log();
68
+ console.log(` ╭─ ${pc.bold(pc.cyan(title))} ${topBorder}─╮`);
69
+ for (const line of lines) {
70
+ const padding = " ".repeat(maxLen - stripAnsi(line).length);
71
+ console.log(` │ ${line}${padding} │`);
72
+ }
73
+ console.log(` ╰${bottomBorder}╯`);
74
+ console.log();
75
+ }
76
+ export function banner() {
77
+ if (quietMode || jsonMode)
78
+ return;
79
+ const art = [
80
+ ` ___ _______ __`,
81
+ ` / _ | / _/ _(_) /____ ____`,
82
+ ` / __ | / _/ _/ / __/ _ \\/ __/`,
83
+ `/_/ |_|/_//_//_/\\__/\\___/_/`,
84
+ ];
85
+ console.log();
86
+ for (const line of art) {
87
+ console.log(` ${pc.cyan(line)}`);
88
+ }
89
+ console.log(` ${pc.dim("CLI-native affiliate tracking")}`);
90
+ console.log();
91
+ }
92
+ export function progressStep(current, total, msg, done) {
93
+ if (quietMode || jsonMode)
94
+ return;
95
+ const prefix = current === 1 ? "┌" : current === total ? "└" : "├";
96
+ const counter = pc.dim(`[${current}/${total}]`);
97
+ const status = done ? pc.green(" ✓") : pc.yellow(" …");
98
+ console.log(` ${pc.dim(prefix)} ${counter} ${msg}${status}`);
99
+ }
100
+ export function statusBadge(label, status) {
101
+ if (quietMode || jsonMode)
102
+ return;
103
+ const dot = status === "ok"
104
+ ? pc.green("●")
105
+ : status === "warn"
106
+ ? pc.yellow("●")
107
+ : pc.red("●");
108
+ console.log(` ${dot} ${label}`);
109
+ }
110
+ export function miniBar(value, max, width = 10) {
111
+ const ratio = max > 0 ? Math.min(value / max, 1) : 0;
112
+ const filled = Math.round(ratio * width);
113
+ const empty = width - filled;
114
+ return pc.cyan("█".repeat(filled)) + pc.dim("░".repeat(empty));
115
+ }
116
+ export function commandHelp(name, description) {
117
+ if (quietMode || jsonMode)
118
+ return;
119
+ console.log(` ${pc.cyan(name.padEnd(16))} ${pc.dim(description)}`);
120
+ }
121
+ export function sectionHeader(title) {
122
+ if (quietMode || jsonMode)
123
+ return;
124
+ console.log();
125
+ console.log(` ${pc.bold(title)}`);
126
+ }
127
+ export function maskApiKey(key) {
128
+ if (key.length <= 10)
129
+ return key;
130
+ return key.slice(0, 6) + "…" + key.slice(-3);
131
+ }
60
132
  export function newline() {
61
133
  if (quietMode || jsonMode)
62
134
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Server-side conversion tracking helpers for the wizard (affitor-node path).
3
+ * Pure functions (detection + generated source/snippets) — easy to unit test.
4
+ * The wizard installs affitor-node + scaffolds the client file, then PRINTS the
5
+ * trackLead/trackSale snippets — it never edits auth/payment code (per PR-4 §9.3).
6
+ */
7
+ export type PaymentProvider = "stripe" | "polar" | "lemonsqueezy" | "paddle" | "unknown";
8
+ /** Detect the advertiser's payment provider from package.json deps. */
9
+ export declare function detectPaymentProvider(cwd: string): PaymentProvider;
10
+ /** Source for the scaffolded `lib/affitor.ts` server client (a NEW file — safe to write). */
11
+ export declare function affitorClientSource(): string;
12
+ export interface TrackingSnippets {
13
+ importPath: string;
14
+ lead: string;
15
+ saleContext: string;
16
+ sale: string;
17
+ refund: string;
18
+ }
19
+ /**
20
+ * Tailored trackLead + trackSale snippets. The sale snippet is provider-specific
21
+ * (event name + field paths from the verified provider research). Printed, not
22
+ * auto-applied.
23
+ */
24
+ export declare function serverTrackingSnippets(provider: PaymentProvider, importPath?: string): TrackingSnippets;
25
+ //# sourceMappingURL=server-tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-tracking.d.ts","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AASzF,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAYlE;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,IAAI,MAAM,CAS5C;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,UAAU,SAAkB,GAC3B,gBAAgB,CAsElB"}
@@ -0,0 +1,109 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const PROVIDER_DEPS = {
4
+ stripe: ["stripe", "@stripe/stripe-js"],
5
+ polar: ["@polar-sh/sdk", "@polar-sh/nextjs", "@polar-sh/express"],
6
+ lemonsqueezy: ["@lemonsqueezy/lemonsqueezy.js"],
7
+ paddle: ["@paddle/paddle-node-sdk", "@paddle/paddle-js"],
8
+ };
9
+ /** Detect the advertiser's payment provider from package.json deps. */
10
+ export function detectPaymentProvider(cwd) {
11
+ let deps = {};
12
+ try {
13
+ const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
14
+ deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
15
+ }
16
+ catch {
17
+ return "unknown";
18
+ }
19
+ for (const [provider, names] of Object.entries(PROVIDER_DEPS)) {
20
+ if (names.some((n) => deps[n]))
21
+ return provider;
22
+ }
23
+ return "unknown";
24
+ }
25
+ /** Source for the scaffolded `lib/affitor.ts` server client (a NEW file — safe to write). */
26
+ export function affitorClientSource() {
27
+ return `import { Affitor } from 'affitor-node';
28
+
29
+ /**
30
+ * Affitor server-side tracking client — auto-generated by \`affitor init\`.
31
+ * Set AFFITOR_API_KEY in your environment (your program API key; keep it secret).
32
+ */
33
+ export const affitor = new Affitor({ apiKey: process.env.AFFITOR_API_KEY ?? '' });
34
+ `;
35
+ }
36
+ /**
37
+ * Tailored trackLead + trackSale snippets. The sale snippet is provider-specific
38
+ * (event name + field paths from the verified provider research). Printed, not
39
+ * auto-applied.
40
+ */
41
+ export function serverTrackingSnippets(provider, importPath = "@/lib/affitor") {
42
+ const lead = [
43
+ `import { affitor } from '${importPath}';`,
44
+ `// After a user signs up — binds the affiliate click to your user id:`,
45
+ `await affitor.trackLead({ customerExternalId: user.id, clickId: cookies.affitor_click_id });`,
46
+ ].join("\n");
47
+ let saleContext;
48
+ let sale;
49
+ switch (provider) {
50
+ case "polar":
51
+ saleContext = "in your Polar webhook handler (event 'order.paid')";
52
+ sale = [
53
+ `await affitor.trackSale({`,
54
+ ` customerExternalId: order.metadata.user_id ?? order.customer_id,`,
55
+ ` amount: order.total_amount, // integer cents`,
56
+ ` invoiceId: order.id,`,
57
+ ` saleType: order.subscription_id ? 'subscription' : 'payment',`,
58
+ `});`,
59
+ ].join("\n");
60
+ break;
61
+ case "lemonsqueezy":
62
+ saleContext = "in your Lemon Squeezy webhook handler (event 'order_created')";
63
+ sale = [
64
+ `await affitor.trackSale({`,
65
+ ` customerExternalId: payload.meta.custom_data?.user_id ?? data.attributes.user_email,`,
66
+ ` amount: data.attributes.total, // integer cents`,
67
+ ` invoiceId: String(data.id),`,
68
+ `});`,
69
+ ].join("\n");
70
+ break;
71
+ case "paddle":
72
+ saleContext = "in your Paddle webhook handler (event 'transaction.completed')";
73
+ sale = [
74
+ `await affitor.trackSale({`,
75
+ ` customerExternalId: data.custom_data?.user_id,`,
76
+ ` amount: Number(data.details.totals.total), // cents`,
77
+ ` invoiceId: data.id,`,
78
+ `});`,
79
+ ].join("\n");
80
+ break;
81
+ case "stripe":
82
+ saleContext =
83
+ "Stripe: prefer Connect autocapture (`affitor stripe connect`). To track manually, in your checkout.session.completed handler";
84
+ sale = [
85
+ `await affitor.trackSale({`,
86
+ ` customerExternalId: session.client_reference_id,`,
87
+ ` amount: session.amount_total, // cents`,
88
+ ` invoiceId: session.id,`,
89
+ `});`,
90
+ ].join("\n");
91
+ break;
92
+ default:
93
+ saleContext = "in your payment provider's webhook handler, when a payment succeeds";
94
+ sale = [
95
+ `await affitor.trackSale({`,
96
+ ` customerExternalId: user.id,`,
97
+ ` amount: amountInCents,`,
98
+ ` invoiceId: transactionId,`,
99
+ `});`,
100
+ ].join("\n");
101
+ }
102
+ const refund = [
103
+ `// In your provider's refund webhook (e.g. order.refunded), reverse the commission`,
104
+ `// (full refund → omit amount; partial → pass refundAmountCents):`,
105
+ `await affitor.trackRefund({ invoiceId /* the same id you passed to trackSale */ });`,
106
+ ].join("\n");
107
+ return { importPath, lead, saleContext, sale, refund };
108
+ }
109
+ //# sourceMappingURL=server-tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-tracking.js","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"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"}