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.
- package/dist/cli.js +28 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +86 -51
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +23 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/programs.d.ts +3 -0
- package/dist/commands/programs.d.ts.map +1 -0
- package/dist/commands/programs.js +54 -0
- package/dist/commands/programs.js.map +1 -0
- package/dist/commands/setup-stripe.d.ts.map +1 -1
- package/dist/commands/setup-stripe.js +51 -35
- package/dist/commands/setup-stripe.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +38 -32
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +8 -9
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +38 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/api-client.d.ts +25 -1
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +26 -1
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/config.d.ts +11 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +171 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/inject.d.ts +27 -0
- package/dist/lib/inject.d.ts.map +1 -0
- package/dist/lib/inject.js +81 -0
- package/dist/lib/inject.js.map +1 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +72 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/server-tracking.d.ts +25 -0
- package/dist/lib/server-tracking.d.ts.map +1 -0
- package/dist/lib/server-tracking.js +109 -0
- package/dist/lib/server-tracking.js.map +1 -0
- package/dist/lib/stack-detect.d.ts +18 -0
- package/dist/lib/stack-detect.d.ts.map +1 -0
- package/dist/lib/stack-detect.js +57 -0
- package/dist/lib/stack-detect.js.map +1 -0
- package/dist/lib/wizard.d.ts +14 -0
- package/dist/lib/wizard.d.ts.map +1 -0
- package/dist/lib/wizard.js +166 -0
- package/dist/lib/wizard.js.map +1 -0
- package/dist/types.d.ts +27 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/dist/lib/config.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
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=${
|
|
191
|
+
AFFITOR_API_KEY=${apiKey}
|
|
40
192
|
AFFITOR_PROGRAM_ID=${config.program_id}
|
|
41
|
-
|
|
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
|
|
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
|
|
333
|
+
const entries = [".affitor/.env", ".affitor/.env.*"];
|
|
182
334
|
if (existsSync(gitignorePath)) {
|
|
183
335
|
const content = readFileSync(gitignorePath, "utf-8");
|
|
184
|
-
|
|
336
|
+
const missing = entries.filter((e) => !content.includes(e));
|
|
337
|
+
if (missing.length === 0)
|
|
185
338
|
return;
|
|
186
|
-
|
|
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) {
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
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":"AAAA;;;;;;GAMG;AAEH,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAWxC,gFAAgF;AAChF,MAAM,UAAU,sBAAsB,CAAC,SAA0B,EAAE,kBAA2B;IAC5F,MAAM,SAAS,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,OAAO,GAAG,MAAM;;;;;;;kBAOA,cAAc;;wBAER,SAAS;;;;CAIhC,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,eAAuB;IAC5C,OAAO,YAAY,cAAc,YAAY,eAAe,IAAI,CAAC;AACnE,CAAC;AAED,mFAAmF;AACnF,SAAS,SAAS,CAAC,OAAe,EAAE,UAAkB;IACpD,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC;IACjC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,CAAC;QAAE,OAAO,GAAG,UAAU,KAAK,OAAO,EAAE,CAAC;IACvD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,UAAU,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAChF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,eAAuB;IACtE,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAEvF,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAErE,MAAM,UAAU,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACjD,MAAM,QAAQ,GAAG,YAAY,cAAc,KAAK,CAAC;IACjD,MAAM,QAAQ,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAEpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,eAAuB;IACrE,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAEvF,MAAM,MAAM,GAAG,wCAAwC,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAElE,MAAM,UAAU,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,WAAW,GAAG,cAAc,cAAc,cAAc,SAAS,WAAW,CAAC;IACnF,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEzD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;AACjG,CAAC"}
|
package/dist/lib/logger.d.ts
CHANGED
|
@@ -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;
|
package/dist/lib/logger.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/lib/logger.js
CHANGED
|
@@ -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;
|
package/dist/lib/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,MAAM,UAAU,gBAAgB,CAAC,IAIhC;IACC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;IACrD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;IAClD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,SAAS,IAAI,QAAQ;QAAE,OAAO;IAClC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,QAAQ;QAAE,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,QAAQ;QAAE,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,QAAQ;QAAE,OAAO;IACrB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,SAAS,IAAI,QAAQ;QAAE,OAAO;IAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,CAAC,WAAW,IAAI,QAAQ;QAAE,OAAO;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAa;IAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,IAAI,QAAQ;QAAE,OAAO;IACrB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,SAAS,IAAI,QAAQ;QAAE,OAAO;IAClC,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,4CAA4C;IAC5C,OAAO,GAAG,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,GAAG,EAAE,EAAE,CAAC,GAAG;IACX,KAAK,EAAE,EAAE,CAAC,KAAK;IACf,MAAM,EAAE,EAAE,CAAC,MAAM;IACjB,GAAG,EAAE,EAAE,CAAC,GAAG;IACX,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,IAAI,EAAE,EAAE,CAAC,IAAI;CACd,CAAC"}
|
|
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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"}
|