affitor 0.3.1 → 0.4.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 +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/onboard.d.ts +21 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +401 -0
- package/dist/commands/onboard.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 +62 -0
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/inject.d.ts +44 -0
- package/dist/lib/inject.d.ts.map +1 -1
- package/dist/lib/inject.js +114 -2
- package/dist/lib/inject.js.map +1 -1
- package/dist/lib/server-tracking.d.ts +4 -0
- package/dist/lib/server-tracking.d.ts.map +1 -1
- package/dist/lib/server-tracking.js +19 -37
- package/dist/lib/server-tracking.js.map +1 -1
- package/dist/lib/stack-detect.d.ts +12 -4
- package/dist/lib/stack-detect.d.ts.map +1 -1
- package/dist/lib/stack-detect.js +67 -2
- package/dist/lib/stack-detect.js.map +1 -1
- package/dist/lib/webhook-detect.d.ts +21 -0
- package/dist/lib/webhook-detect.d.ts.map +1 -0
- package/dist/lib/webhook-detect.js +111 -0
- package/dist/lib/webhook-detect.js.map +1 -0
- package/dist/lib/wizard.d.ts.map +1 -1
- package/dist/lib/wizard.js +17 -2
- package/dist/lib/wizard.js.map +1 -1
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
package/dist/lib/inject.d.ts
CHANGED
|
@@ -24,4 +24,48 @@ export declare function injectAppLayout(content: string, importSpecifier: string
|
|
|
24
24
|
* every page, and add the import.
|
|
25
25
|
*/
|
|
26
26
|
export declare function injectPagesApp(content: string, importSpecifier: string): InjectResult;
|
|
27
|
+
export interface InjectStripeOpts {
|
|
28
|
+
/**
|
|
29
|
+
* The provider sale snippet from `@affitor/recipes` (e.g.
|
|
30
|
+
* `getRecipe(framework, 'stripe', 's2s').sale!.snippet`). The SDK import line
|
|
31
|
+
* (`import { Affitor } from '@affitor/sdk/server';`) is stripped before
|
|
32
|
+
* insertion — the inserted body is just the `affitor.trackSale({...})` call,
|
|
33
|
+
* indented to match the matched session binding.
|
|
34
|
+
*/
|
|
35
|
+
saleSnippet: string;
|
|
36
|
+
/**
|
|
37
|
+
* Module specifier for the `affitor` client import — e.g. `'../lib/affitor'`
|
|
38
|
+
* or `'@/lib/affitor'`. When provided and status is 'injected', the transform
|
|
39
|
+
* also adds `import { affitor } from '<importSpecifier>';` at the top of the
|
|
40
|
+
* file (idempotent: skipped if that line is already present). Included in
|
|
41
|
+
* `added[]` so the diff preview shows it.
|
|
42
|
+
*/
|
|
43
|
+
importSpecifier?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Optional indent override (spaces). When omitted, the indent of the matched
|
|
46
|
+
* session-binding line is reused so the inserted call lines up with its block.
|
|
47
|
+
*/
|
|
48
|
+
indent?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Insert `affitor.trackSale(...)` into a Stripe webhook handler, right after the
|
|
52
|
+
* verified `checkout.session.completed` session object is bound.
|
|
53
|
+
*
|
|
54
|
+
* CONSERVATIVE BY DESIGN — only injects when ALL of these hold (else returns
|
|
55
|
+
* `unrecognized` so the caller prints the patch instead of editing payment code):
|
|
56
|
+
* 1. The file contains `stripe.webhooks.constructEvent` (it really is a
|
|
57
|
+
* verified Stripe webhook — we never edit an unverified handler).
|
|
58
|
+
* 2. There is a single `checkout.session.completed` reference to anchor on
|
|
59
|
+
* (the recipe's stripe snippet reads `session.*`, so the sale belongs in
|
|
60
|
+
* that case). Zero or multiple matches → unrecognized (ambiguous).
|
|
61
|
+
* 3. After that anchor, exactly one line binds the event object to a name we
|
|
62
|
+
* can reuse — `const session = event.data.object …` (or `= session …`).
|
|
63
|
+
* The trackSale call is inserted on the line after that binding, at the
|
|
64
|
+
* binding's own indentation. No binding, or an unexpected variable name →
|
|
65
|
+
* unrecognized.
|
|
66
|
+
*
|
|
67
|
+
* Returns `already` when a `affitor.trackSale(` / `@affitor/sdk/server` marker is
|
|
68
|
+
* already present (idempotent re-runs do nothing).
|
|
69
|
+
*/
|
|
70
|
+
export declare function injectStripeTrackSale(content: string, opts: InjectStripeOpts): InjectResult;
|
|
27
71
|
//# sourceMappingURL=inject.d.ts.map
|
package/dist/lib/inject.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;AA6BD;;;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;AAiBD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CA+D3F"}
|
package/dist/lib/inject.js
CHANGED
|
@@ -28,11 +28,20 @@ export function ${TRACKER_MARKER}() {
|
|
|
28
28
|
function importLineFor(importSpecifier) {
|
|
29
29
|
return `import { ${TRACKER_MARKER} } from '${importSpecifier}';`;
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Add an import after the last existing top-level import (or at the very top).
|
|
33
|
+
*
|
|
34
|
+
* Matches COMPLETE import statements — including multi-line destructured imports
|
|
35
|
+
* (`import {\n a,\n b\n} from 'x';`) — so the new line lands AFTER the last
|
|
36
|
+
* import, never spliced inside a destructure. An `import` starting at column 0
|
|
37
|
+
* runs to its terminating `from '...'` / `from "..."` clause (or, for a
|
|
38
|
+
* side-effect import, the bare `import '...'`), spanning newlines as needed.
|
|
39
|
+
*/
|
|
32
40
|
function addImport(content, importLine) {
|
|
33
41
|
if (content.includes(importLine))
|
|
34
42
|
return content;
|
|
35
|
-
|
|
43
|
+
// ^import … from '…'|"…" (multi-line tolerant), OR a side-effect import '…'.
|
|
44
|
+
const importRe = /^import\b[\s\S]*?from\s+(['"])[^'"]*\1\s*;?|^import\s+(['"])[^'"]*\2\s*;?/gm;
|
|
36
45
|
let lastEnd = -1;
|
|
37
46
|
let m;
|
|
38
47
|
while ((m = importRe.exec(content)) !== null) {
|
|
@@ -78,4 +87,107 @@ export function injectPagesApp(content, importSpecifier) {
|
|
|
78
87
|
const injected = withImport.replace(compRe, replacement);
|
|
79
88
|
return { content: injected, status: "injected", added: [importLine, `<${TRACKER_MARKER} />`] };
|
|
80
89
|
}
|
|
90
|
+
// ── Server-side: inject `affitor.trackSale(...)` into a Stripe webhook ──
|
|
91
|
+
//
|
|
92
|
+
// This edits PAYMENT code, so it is deliberately conservative: it only injects
|
|
93
|
+
// when it can recognize a clean `checkout.session.completed` shape with a single
|
|
94
|
+
// obvious session binding. Anything ambiguous → `unrecognized`, and the caller
|
|
95
|
+
// PRINTS the exact patch instead of forcing an edit. The transform is pure (no
|
|
96
|
+
// fs) and idempotent (a trackSale / @affitor/sdk/server marker → `already`).
|
|
97
|
+
/** Markers that mean a trackSale call (or the server import) is already wired. */
|
|
98
|
+
const TRACK_SALE_MARKER = "affitor.trackSale(";
|
|
99
|
+
const SERVER_IMPORT_MARKER = "@affitor/sdk/server";
|
|
100
|
+
/** The canonical Stripe webhook-verification call (Node SDK) we anchor on. */
|
|
101
|
+
const CONSTRUCT_EVENT_NEEDLE = "stripe.webhooks.constructEvent";
|
|
102
|
+
/** Drop the recipe's leading `@affitor/sdk/server` import + its blank line. */
|
|
103
|
+
function saleCallBody(snippet) {
|
|
104
|
+
return snippet
|
|
105
|
+
.replace(/^import \{ Affitor \} from '@affitor\/sdk\/server';\n+/, "")
|
|
106
|
+
.trimEnd();
|
|
107
|
+
}
|
|
108
|
+
/** Re-indent a multi-line snippet body to a given base indent. */
|
|
109
|
+
function indentBody(body, indent) {
|
|
110
|
+
return body
|
|
111
|
+
.split("\n")
|
|
112
|
+
.map((line) => (line.length ? indent + line : line))
|
|
113
|
+
.join("\n");
|
|
114
|
+
}
|
|
115
|
+
/** The import line for the affitor client given a module specifier. */
|
|
116
|
+
function affitorImportLine(importSpecifier) {
|
|
117
|
+
return `import { affitor } from '${importSpecifier}';`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Insert `affitor.trackSale(...)` into a Stripe webhook handler, right after the
|
|
121
|
+
* verified `checkout.session.completed` session object is bound.
|
|
122
|
+
*
|
|
123
|
+
* CONSERVATIVE BY DESIGN — only injects when ALL of these hold (else returns
|
|
124
|
+
* `unrecognized` so the caller prints the patch instead of editing payment code):
|
|
125
|
+
* 1. The file contains `stripe.webhooks.constructEvent` (it really is a
|
|
126
|
+
* verified Stripe webhook — we never edit an unverified handler).
|
|
127
|
+
* 2. There is a single `checkout.session.completed` reference to anchor on
|
|
128
|
+
* (the recipe's stripe snippet reads `session.*`, so the sale belongs in
|
|
129
|
+
* that case). Zero or multiple matches → unrecognized (ambiguous).
|
|
130
|
+
* 3. After that anchor, exactly one line binds the event object to a name we
|
|
131
|
+
* can reuse — `const session = event.data.object …` (or `= session …`).
|
|
132
|
+
* The trackSale call is inserted on the line after that binding, at the
|
|
133
|
+
* binding's own indentation. No binding, or an unexpected variable name →
|
|
134
|
+
* unrecognized.
|
|
135
|
+
*
|
|
136
|
+
* Returns `already` when a `affitor.trackSale(` / `@affitor/sdk/server` marker is
|
|
137
|
+
* already present (idempotent re-runs do nothing).
|
|
138
|
+
*/
|
|
139
|
+
export function injectStripeTrackSale(content, opts) {
|
|
140
|
+
// Idempotent: never double-inject.
|
|
141
|
+
// Check for trackSale marker, server import marker, OR the affitor client import
|
|
142
|
+
// (the specifier we would add) — any of these mean the file is already wired.
|
|
143
|
+
const clientImportLine = opts.importSpecifier ? affitorImportLine(opts.importSpecifier) : null;
|
|
144
|
+
if (content.includes(TRACK_SALE_MARKER) ||
|
|
145
|
+
content.includes(SERVER_IMPORT_MARKER) ||
|
|
146
|
+
(clientImportLine && content.includes(clientImportLine))) {
|
|
147
|
+
return { content, status: "already", added: [] };
|
|
148
|
+
}
|
|
149
|
+
// (1) Must be a verified Stripe webhook — anchor on constructEvent.
|
|
150
|
+
if (!content.includes(CONSTRUCT_EVENT_NEEDLE)) {
|
|
151
|
+
return { content, status: "unrecognized", added: [] };
|
|
152
|
+
}
|
|
153
|
+
// (2) Exactly one checkout.session.completed reference (the sale anchor).
|
|
154
|
+
// Zero (some other event) or many (ambiguous which case) → bail.
|
|
155
|
+
const completedRe = /checkout\.session\.completed/g;
|
|
156
|
+
const completedMatches = content.match(completedRe);
|
|
157
|
+
if (!completedMatches || completedMatches.length !== 1) {
|
|
158
|
+
return { content, status: "unrecognized", added: [] };
|
|
159
|
+
}
|
|
160
|
+
const anchorIdx = content.indexOf("checkout.session.completed");
|
|
161
|
+
// (3) After the anchor, find a single clean session binding to insert after.
|
|
162
|
+
// Accept `const session = event.data.object …` or `const session = session …`
|
|
163
|
+
// (cast variants). The variable MUST be named `session` — the recipe's stripe
|
|
164
|
+
// snippet reads `session.client_reference_id` / `session.amount_total` /
|
|
165
|
+
// `session.id`, so any other name would not compile.
|
|
166
|
+
const after = content.slice(anchorIdx);
|
|
167
|
+
const bindingRe = /^([ \t]*)const session\s*=\s*(?:event\.data\.object|session)\b[^\n]*$/m;
|
|
168
|
+
const bindingMatch = after.match(bindingRe);
|
|
169
|
+
if (!bindingMatch || bindingMatch.index === undefined) {
|
|
170
|
+
return { content, status: "unrecognized", added: [] };
|
|
171
|
+
}
|
|
172
|
+
// Absolute offset of the end of the binding line (insertion point).
|
|
173
|
+
const bindingLineStart = anchorIdx + bindingMatch.index;
|
|
174
|
+
const bindingLineEnd = bindingLineStart + bindingMatch[0].length;
|
|
175
|
+
const indent = opts.indent ?? bindingMatch[1] ?? " ";
|
|
176
|
+
const body = saleCallBody(opts.saleSnippet);
|
|
177
|
+
if (!body.includes(TRACK_SALE_MARKER)) {
|
|
178
|
+
// The provided snippet isn't a trackSale call — refuse rather than guess.
|
|
179
|
+
return { content, status: "unrecognized", added: [] };
|
|
180
|
+
}
|
|
181
|
+
const block = indentBody(body, indent);
|
|
182
|
+
const insertion = `\n${indent}// Affitor: report the sale (auto-added by \`affitor onboard\`)\n${block}`;
|
|
183
|
+
const withSale = content.slice(0, bindingLineEnd) + insertion + content.slice(bindingLineEnd);
|
|
184
|
+
// Also add the affitor client import when a specifier was provided.
|
|
185
|
+
let finalContent = withSale;
|
|
186
|
+
const added = insertion.split("\n").filter((l) => l.trim().length > 0);
|
|
187
|
+
if (clientImportLine) {
|
|
188
|
+
finalContent = addImport(withSale, clientImportLine);
|
|
189
|
+
added.unshift(clientImportLine);
|
|
190
|
+
}
|
|
191
|
+
return { content: finalContent, status: "injected", added };
|
|
192
|
+
}
|
|
81
193
|
//# sourceMappingURL=inject.js.map
|
package/dist/lib/inject.js.map
CHANGED
|
@@ -1 +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
|
|
1
|
+
{"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/lib/inject.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* Pure functions (detection + generated source/snippets) — easy to unit test.
|
|
4
4
|
* The wizard installs @affitor/sdk + scaffolds the client file, then PRINTS the
|
|
5
5
|
* trackLead/trackSale snippets — it never edits auth/payment code (per PR-4 §9.3).
|
|
6
|
+
*
|
|
7
|
+
* The per-provider `sale` snippet is SOURCED FROM `@affitor/recipes` (the canonical
|
|
8
|
+
* single source of truth read by CLI + MCP + docs). Do NOT re-inline the snippet
|
|
9
|
+
* strings here — edit them in `@affitor/recipes` so all three surfaces stay in sync.
|
|
6
10
|
*/
|
|
7
11
|
export type PaymentProvider = "stripe" | "polar" | "lemonsqueezy" | "paddle" | "unknown";
|
|
8
12
|
/** Detect the advertiser's payment provider from package.json deps. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-tracking.d.ts","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server-tracking.d.ts","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;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,CAwClB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { getRecipe } from "@affitor/recipes";
|
|
3
4
|
const PROVIDER_DEPS = {
|
|
4
5
|
stripe: ["stripe", "@stripe/stripe-js"],
|
|
5
6
|
polar: ["@polar-sh/sdk", "@polar-sh/nextjs", "@polar-sh/express"],
|
|
@@ -33,6 +34,18 @@ export function affitorClientSource() {
|
|
|
33
34
|
export const affitor = new Affitor({ apiKey: process.env.AFFITOR_API_KEY ?? '' });
|
|
34
35
|
`;
|
|
35
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* The trackSale snippet body for a provider, sourced from the canonical
|
|
39
|
+
* `@affitor/recipes` registry. We use framework "unknown" (the snippet body is
|
|
40
|
+
* framework-independent) + mode "s2s" (so a sale snippet exists, not the
|
|
41
|
+
* Connect/metadata-only path), then strip the leading `@affitor/sdk/server`
|
|
42
|
+
* import + its blank line — the wizard prints that import via the lead snippet.
|
|
43
|
+
*/
|
|
44
|
+
function recipeSaleBody(provider) {
|
|
45
|
+
const recipe = getRecipe("unknown", provider, "s2s");
|
|
46
|
+
const snippet = recipe.sale?.snippet ?? "";
|
|
47
|
+
return snippet.replace(/^import \{ Affitor \} from '@affitor\/sdk\/server';\n\n/, "");
|
|
48
|
+
}
|
|
36
49
|
/**
|
|
37
50
|
* Tailored trackLead + trackSale snippets. The sale snippet is provider-specific
|
|
38
51
|
* (event name + field paths from the verified provider research). Printed, not
|
|
@@ -44,60 +57,29 @@ export function serverTrackingSnippets(provider, importPath = "@/lib/affitor") {
|
|
|
44
57
|
`// After a user signs up — binds the affiliate click to your user id:`,
|
|
45
58
|
`await affitor.trackLead({ customerExternalId: user.id, clickId: cookies.affitor_click_id });`,
|
|
46
59
|
].join("\n");
|
|
60
|
+
// The trackSale snippet body is canonical in @affitor/recipes. We pull it from
|
|
61
|
+
// there (framework "unknown" — the body is framework-independent; only the
|
|
62
|
+
// inject_target differs, which the wizard doesn't print) and strip the SDK
|
|
63
|
+
// import line the recipe prepends (the wizard already prints the import as part
|
|
64
|
+
// of the lead snippet, via `importPath`).
|
|
65
|
+
const sale = recipeSaleBody(provider);
|
|
47
66
|
let saleContext;
|
|
48
|
-
let sale;
|
|
49
67
|
switch (provider) {
|
|
50
68
|
case "polar":
|
|
51
69
|
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
70
|
break;
|
|
61
71
|
case "lemonsqueezy":
|
|
62
72
|
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
73
|
break;
|
|
71
74
|
case "paddle":
|
|
72
75
|
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
76
|
break;
|
|
81
77
|
case "stripe":
|
|
82
78
|
saleContext =
|
|
83
79
|
"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
80
|
break;
|
|
92
81
|
default:
|
|
93
82
|
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
83
|
}
|
|
102
84
|
const refund = [
|
|
103
85
|
`// In your provider's refund webhook (e.g. order.refunded), reverse the commission`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-tracking.js","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server-tracking.js","sourceRoot":"","sources":["../../src/lib/server-tracking.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
export type Framework = "next-app" | "next-pages" | "unknown";
|
|
1
|
+
export type Framework = "next-app" | "next-pages" | "fastify" | "express" | "node" | "unknown";
|
|
2
2
|
export type PackageManager = "npm" | "yarn" | "pnpm";
|
|
3
3
|
export interface StackInfo {
|
|
4
4
|
framework: Framework;
|
|
5
5
|
packageManager: PackageManager;
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Absolute path to the entry file to wire (layout.tsx / _app.tsx), or null.
|
|
8
|
+
* For server frameworks (fastify/express/node) this is the detected server
|
|
9
|
+
* entry if findable (best-effort), else null — the wizard only auto-wires the
|
|
10
|
+
* Next entry files, so a null here routes the new stacks to printed snippets.
|
|
11
|
+
*/
|
|
7
12
|
entryFile: string | null;
|
|
8
13
|
/** Directory to create the tracker component in, or null. */
|
|
9
14
|
componentDir: string | null;
|
|
@@ -11,8 +16,11 @@ export interface StackInfo {
|
|
|
11
16
|
export declare function detectPackageManager(cwd: string): PackageManager;
|
|
12
17
|
/**
|
|
13
18
|
* Detect the framework + package manager + entry file of the project at `cwd`.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
19
|
+
* Order is most-specific first: next-app → next-pages → fastify → express →
|
|
20
|
+
* node (a package.json + a server signal but no framework) → unknown. Next.js
|
|
21
|
+
* is the only stack the wizard auto-wires; server frameworks expose a
|
|
22
|
+
* best-effort `entryFile` but `componentDir: null` keeps them on the printed
|
|
23
|
+
* snippet path (auto-injection is a later task).
|
|
16
24
|
*/
|
|
17
25
|
export declare function detectStack(cwd: string): StackInfo;
|
|
18
26
|
//# sourceMappingURL=stack-detect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-detect.d.ts","sourceRoot":"","sources":["../../src/lib/stack-detect.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"stack-detect.d.ts","sourceRoot":"","sources":["../../src/lib/stack-detect.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,YAAY,GACZ,SAAS,GACT,SAAS,GACT,MAAM,GACN,SAAS,CAAC;AACd,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAWD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAIhE;AAwDD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAwClD"}
|
package/dist/lib/stack-detect.js
CHANGED
|
@@ -24,10 +24,63 @@ function firstExisting(cwd, candidates) {
|
|
|
24
24
|
}
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
|
+
/** Common server entry candidates, in priority order, for non-Next stacks. */
|
|
28
|
+
const SERVER_ENTRY_CANDIDATES = [
|
|
29
|
+
"src/server.ts",
|
|
30
|
+
"src/server.js",
|
|
31
|
+
"src/index.ts",
|
|
32
|
+
"src/index.js",
|
|
33
|
+
"src/app.ts",
|
|
34
|
+
"src/app.js",
|
|
35
|
+
"src/main.ts",
|
|
36
|
+
"src/main.js",
|
|
37
|
+
"server.ts",
|
|
38
|
+
"server.js",
|
|
39
|
+
"index.ts",
|
|
40
|
+
"index.js",
|
|
41
|
+
"app.ts",
|
|
42
|
+
"app.js",
|
|
43
|
+
];
|
|
44
|
+
/** Best-effort server entry: the package.json `main`, then common filenames. */
|
|
45
|
+
function findServerEntry(cwd) {
|
|
46
|
+
try {
|
|
47
|
+
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
|
|
48
|
+
if (typeof pkg.main === "string" && pkg.main) {
|
|
49
|
+
const mainPath = join(cwd, pkg.main);
|
|
50
|
+
if (existsSync(mainPath))
|
|
51
|
+
return mainPath;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
/* fall through to filename probing */
|
|
56
|
+
}
|
|
57
|
+
return firstExisting(cwd, SERVER_ENTRY_CANDIDATES);
|
|
58
|
+
}
|
|
59
|
+
/** Heuristic: does this look like a runnable Node service (no framework dep)? */
|
|
60
|
+
function hasNodeServerSignal(cwd, deps) {
|
|
61
|
+
if (deps["stripe"])
|
|
62
|
+
return true; // server-ish: payment provider implies a backend
|
|
63
|
+
try {
|
|
64
|
+
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
|
|
65
|
+
if (typeof pkg.main === "string" && pkg.main)
|
|
66
|
+
return true;
|
|
67
|
+
if (pkg.bin)
|
|
68
|
+
return true;
|
|
69
|
+
if (pkg.scripts && (pkg.scripts.start || pkg.scripts.serve))
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
27
77
|
/**
|
|
28
78
|
* Detect the framework + package manager + entry file of the project at `cwd`.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
79
|
+
* Order is most-specific first: next-app → next-pages → fastify → express →
|
|
80
|
+
* node (a package.json + a server signal but no framework) → unknown. Next.js
|
|
81
|
+
* is the only stack the wizard auto-wires; server frameworks expose a
|
|
82
|
+
* best-effort `entryFile` but `componentDir: null` keeps them on the printed
|
|
83
|
+
* snippet path (auto-injection is a later task).
|
|
31
84
|
*/
|
|
32
85
|
export function detectStack(cwd) {
|
|
33
86
|
const packageManager = detectPackageManager(cwd);
|
|
@@ -52,6 +105,18 @@ export function detectStack(cwd) {
|
|
|
52
105
|
return { framework: "next-pages", packageManager, entryFile: pagesApp, componentDir: dirname(pagesApp) };
|
|
53
106
|
}
|
|
54
107
|
}
|
|
108
|
+
// Server frameworks (Echoly-class: Fastify + TS + Postgres + Stripe webhook).
|
|
109
|
+
// entryFile is best-effort; componentDir stays null (no browser component to
|
|
110
|
+
// scaffold on a backend), which keeps these stacks on the printed-snippet path.
|
|
111
|
+
if (deps["fastify"]) {
|
|
112
|
+
return { framework: "fastify", packageManager, entryFile: findServerEntry(cwd), componentDir: null };
|
|
113
|
+
}
|
|
114
|
+
if (deps["express"]) {
|
|
115
|
+
return { framework: "express", packageManager, entryFile: findServerEntry(cwd), componentDir: null };
|
|
116
|
+
}
|
|
117
|
+
if (hasNodeServerSignal(cwd, deps)) {
|
|
118
|
+
return { framework: "node", packageManager, entryFile: findServerEntry(cwd), componentDir: null };
|
|
119
|
+
}
|
|
55
120
|
return { framework: "unknown", packageManager, entryFile: null, componentDir: null };
|
|
56
121
|
}
|
|
57
122
|
//# sourceMappingURL=stack-detect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-detect.js","sourceRoot":"","sources":["../../src/lib/stack-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"stack-detect.js","sourceRoot":"","sources":["../../src/lib/stack-detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAyB1C,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,UAAoB;IACtD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1B,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,MAAM,uBAAuB,GAAG;IAC9B,eAAe;IACf,eAAe;IACf,cAAc;IACd,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,aAAa;IACb,WAAW;IACX,WAAW;IACX,UAAU;IACV,UAAU;IACV,QAAQ;IACR,QAAQ;CACT,CAAC;AAEF,gFAAgF;AAChF,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAC;QAC5C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;AACrD,CAAC;AAED,iFAAiF;AACjF,SAAS,mBAAmB,CAAC,GAAW,EAAE,IAA4B;IACpE,IAAI,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,iDAAiD;IAClF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAC1D,IAAI,GAAG,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE3B,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,EAAE;YACnC,gBAAgB;YAChB,gBAAgB;YAChB,oBAAoB;YACpB,oBAAoB;SACrB,CAAC,CAAC;QACH,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3G,CAAC;QAED,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,EAAE;YAClC,gBAAgB;YAChB,gBAAgB;YAChB,oBAAoB;YACpB,oBAAoB;SACrB,CAAC,CAAC;QACH,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3G,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,6EAA6E;IAC7E,gFAAgF;IAChF,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACvG,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACvG,CAAC;IACD,IAAI,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACpG,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Framework } from "./stack-detect.js";
|
|
2
|
+
export interface StripeWebhookLocation {
|
|
3
|
+
/** Path to the file containing the call, relative to projectRoot. */
|
|
4
|
+
file: string;
|
|
5
|
+
/** 1-based line number of the `constructEvent` call. */
|
|
6
|
+
line: number;
|
|
7
|
+
/** Framework the hint is tailored for (falls back to "unknown"). */
|
|
8
|
+
framework: Framework | "unknown";
|
|
9
|
+
/** Human-readable description of where to inject the trackSale call. */
|
|
10
|
+
handlerHint: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Scan the project source for the canonical Stripe webhook-verification call and
|
|
14
|
+
* return its location + a framework-tailored injection hint. Returns null when
|
|
15
|
+
* no match is found (caller falls back to printing a generic snippet).
|
|
16
|
+
*
|
|
17
|
+
* @param projectRoot Absolute path to the project to scan.
|
|
18
|
+
* @param framework Detected framework, used to tailor the hint (default "unknown").
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectStripeWebhook(projectRoot: string, framework?: Framework | "unknown"): StripeWebhookLocation | null;
|
|
21
|
+
//# sourceMappingURL=webhook-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-detect.d.ts","sourceRoot":"","sources":["../../src/lib/webhook-detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA8BnD,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IACjC,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;CACrB;AAoDD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,SAAS,GAAG,SAAqB,GAC3C,qBAAqB,GAAG,IAAI,CAyB9B"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Webhook-locator: finds where an advertiser already verifies Stripe webhooks
|
|
5
|
+
* so the wizard can point the agent at the exact injection site for trackSale.
|
|
6
|
+
*
|
|
7
|
+
* The canonical Stripe webhook-verification call is `stripe.webhooks.constructEvent`
|
|
8
|
+
* (Node SDK). When we find it, the conversion-tracking call belongs right after
|
|
9
|
+
* it — the event has been verified and parsed at that point. Dependency-light: a
|
|
10
|
+
* plain fs walk, no globbing libs. Returns null when not found so the caller
|
|
11
|
+
* falls back to printing a snippet.
|
|
12
|
+
*/
|
|
13
|
+
/** The canonical Stripe webhook signature-verification call (Node SDK). */
|
|
14
|
+
const STRIPE_WEBHOOK_NEEDLE = "stripe.webhooks.constructEvent";
|
|
15
|
+
const IGNORED_DIRS = new Set([
|
|
16
|
+
"node_modules",
|
|
17
|
+
".git",
|
|
18
|
+
"dist",
|
|
19
|
+
".next",
|
|
20
|
+
"build",
|
|
21
|
+
"coverage",
|
|
22
|
+
".turbo",
|
|
23
|
+
".vercel",
|
|
24
|
+
]);
|
|
25
|
+
/** Source extensions worth scanning (skip binaries, maps, lockfiles, etc.). */
|
|
26
|
+
const SOURCE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
27
|
+
function isSourceFile(name) {
|
|
28
|
+
return SOURCE_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
29
|
+
}
|
|
30
|
+
/** Collect candidate source files under `dir`, skipping vendored/build dirs. */
|
|
31
|
+
function collectSourceFiles(dir, out) {
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = readdirSync(dir, { withFileTypes: false });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return; // unreadable dir — skip
|
|
38
|
+
}
|
|
39
|
+
for (const name of entries) {
|
|
40
|
+
const full = join(dir, name);
|
|
41
|
+
let stat;
|
|
42
|
+
try {
|
|
43
|
+
stat = statSync(full);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
continue; // broken symlink, etc.
|
|
47
|
+
}
|
|
48
|
+
if (stat.isDirectory()) {
|
|
49
|
+
if (IGNORED_DIRS.has(name) || name.startsWith("."))
|
|
50
|
+
continue;
|
|
51
|
+
collectSourceFiles(full, out);
|
|
52
|
+
}
|
|
53
|
+
else if (stat.isFile() && isSourceFile(name)) {
|
|
54
|
+
out.push(full);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Tailor the injection-point hint to the detected framework. The trackSale call
|
|
60
|
+
* always goes *after* constructEvent (the event is verified + parsed there).
|
|
61
|
+
*/
|
|
62
|
+
function handlerHintFor(framework) {
|
|
63
|
+
switch (framework) {
|
|
64
|
+
case "fastify":
|
|
65
|
+
return "inside the fastify.post('/webhooks/stripe', …) handler, right after constructEvent verifies the event";
|
|
66
|
+
case "express":
|
|
67
|
+
return "after constructEvent in the app.post('/webhooks/stripe', …) Express handler";
|
|
68
|
+
case "next-app":
|
|
69
|
+
return "in app/api/webhooks/stripe/route.ts, in the POST handler after constructEvent";
|
|
70
|
+
case "next-pages":
|
|
71
|
+
return "in pages/api/webhooks/stripe.ts, after constructEvent in the API route handler";
|
|
72
|
+
case "node":
|
|
73
|
+
return "after constructEvent in your Stripe webhook HTTP handler";
|
|
74
|
+
default:
|
|
75
|
+
return "after constructEvent, where you handle the verified Stripe webhook event";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Scan the project source for the canonical Stripe webhook-verification call and
|
|
80
|
+
* return its location + a framework-tailored injection hint. Returns null when
|
|
81
|
+
* no match is found (caller falls back to printing a generic snippet).
|
|
82
|
+
*
|
|
83
|
+
* @param projectRoot Absolute path to the project to scan.
|
|
84
|
+
* @param framework Detected framework, used to tailor the hint (default "unknown").
|
|
85
|
+
*/
|
|
86
|
+
export function detectStripeWebhook(projectRoot, framework = "unknown") {
|
|
87
|
+
const files = [];
|
|
88
|
+
collectSourceFiles(projectRoot, files);
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
let content;
|
|
91
|
+
try {
|
|
92
|
+
content = readFileSync(file, "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
continue; // unreadable file — skip
|
|
96
|
+
}
|
|
97
|
+
const idx = content.indexOf(STRIPE_WEBHOOK_NEEDLE);
|
|
98
|
+
if (idx === -1)
|
|
99
|
+
continue;
|
|
100
|
+
// 1-based line number of the first occurrence.
|
|
101
|
+
const line = content.slice(0, idx).split("\n").length;
|
|
102
|
+
return {
|
|
103
|
+
file: relative(projectRoot, file),
|
|
104
|
+
line,
|
|
105
|
+
framework,
|
|
106
|
+
handlerHint: handlerHintFor(framework),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=webhook-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-detect.js","sourceRoot":"","sources":["../../src/lib/webhook-detect.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/wizard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../src/lib/wizard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../src/lib/wizard.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAiBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DzE"}
|