appfunnel 0.13.0 → 0.14.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/index.js +54 -31
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/templates/default/README.md +0 -69
- package/templates/default/appfunnel.config.ts +0 -17
- package/templates/default/gitignore +0 -3
- package/templates/default/locales/en.json +0 -3
- package/templates/default/src/app.css +0 -1
- package/templates/default/src/components/ConsentDrawer.tsx +0 -70
- package/templates/default/src/components/Header.tsx +0 -37
- package/templates/default/src/components/paywall/PaymentCheckoutDialog.tsx +0 -76
- package/templates/default/src/funnel.tsx +0 -9
- package/templates/default/src/pages/birthday.tsx +0 -66
- package/templates/default/src/pages/download.tsx +0 -67
- package/templates/default/src/pages/email.tsx +0 -95
- package/templates/default/src/pages/intro.tsx +0 -109
- package/templates/default/src/pages/multi-select.tsx +0 -79
- package/templates/default/src/pages/name.tsx +0 -48
- package/templates/default/src/pages/paywall.tsx +0 -191
- package/templates/default/src/pages/single-select.tsx +0 -61
- package/templates/default/src/pages/upsell.tsx +0 -158
- package/templates/default/template.json +0 -10
- package/templates/default/tsconfig.json +0 -16
package/dist/index.js
CHANGED
|
@@ -261,25 +261,47 @@ var init_exports = {};
|
|
|
261
261
|
__export(init_exports, {
|
|
262
262
|
initCommand: () => initCommand
|
|
263
263
|
});
|
|
264
|
-
import {
|
|
265
|
-
import { join as join2
|
|
266
|
-
import {
|
|
264
|
+
import { existsSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
265
|
+
import { join as join2 } from "path";
|
|
266
|
+
import { Readable } from "stream";
|
|
267
|
+
import { extract } from "tar";
|
|
267
268
|
import pc4 from "picocolors";
|
|
268
269
|
import select2 from "@inquirer/select";
|
|
269
270
|
import input from "@inquirer/input";
|
|
270
|
-
function
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
271
|
+
async function fetchTemplateIndex() {
|
|
272
|
+
const url = `https://raw.githubusercontent.com/${TEMPLATES_REPO}/main/index.json`;
|
|
273
|
+
const res = await fetch(url);
|
|
274
|
+
if (!res.ok) throw new Error(`Failed to fetch template index: ${res.status}`);
|
|
275
|
+
const index = await res.json();
|
|
276
|
+
const templates = await Promise.all(
|
|
277
|
+
index.map(async (entry) => {
|
|
278
|
+
const configUrl = `https://raw.githubusercontent.com/${TEMPLATES_REPO}/main/${entry.dir}/template.json`;
|
|
279
|
+
const configRes = await fetch(configUrl);
|
|
280
|
+
const config = configRes.ok ? await configRes.json() : { name: entry.name, description: entry.description, products: [] };
|
|
281
|
+
return { dir: entry.dir, config };
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
return templates;
|
|
285
|
+
}
|
|
286
|
+
async function downloadTemplate(templateDir, destDir) {
|
|
287
|
+
const tarballUrl = `https://api.github.com/repos/${TEMPLATES_REPO}/tarball/main`;
|
|
288
|
+
const res = await fetch(tarballUrl, {
|
|
289
|
+
headers: { Accept: "application/vnd.github+json" }
|
|
290
|
+
});
|
|
291
|
+
if (!res.ok) throw new Error(`Failed to download template: ${res.status}`);
|
|
292
|
+
mkdirSync2(destDir, { recursive: true });
|
|
293
|
+
const nodeStream = Readable.fromWeb(res.body);
|
|
294
|
+
await new Promise((resolve5, reject) => {
|
|
295
|
+
nodeStream.pipe(
|
|
296
|
+
extract({
|
|
297
|
+
cwd: destDir,
|
|
298
|
+
strip: 2,
|
|
299
|
+
filter: (path) => {
|
|
300
|
+
const parts = path.split("/");
|
|
301
|
+
return parts.length > 2 && parts[1] === templateDir;
|
|
302
|
+
}
|
|
303
|
+
})
|
|
304
|
+
).on("finish", resolve5).on("error", reject);
|
|
283
305
|
});
|
|
284
306
|
}
|
|
285
307
|
function formatInterval(interval, count) {
|
|
@@ -324,7 +346,9 @@ async function initCommand(nameArg) {
|
|
|
324
346
|
const projectId = await promptForProject(creds.token);
|
|
325
347
|
const projects = await fetchProjects(creds.token);
|
|
326
348
|
const project = projects.find((p) => p.id === projectId);
|
|
327
|
-
const
|
|
349
|
+
const templateSpinner = spinner("Fetching templates...");
|
|
350
|
+
const templates = await fetchTemplateIndex();
|
|
351
|
+
templateSpinner.stop();
|
|
328
352
|
const selectedDir = await select2({
|
|
329
353
|
message: "Choose a template",
|
|
330
354
|
choices: templates.map((t) => ({
|
|
@@ -334,7 +358,6 @@ async function initCommand(nameArg) {
|
|
|
334
358
|
});
|
|
335
359
|
const chosen = templates.find((t) => t.dir === selectedDir);
|
|
336
360
|
const templateConfig = chosen.config;
|
|
337
|
-
const templateDir = join2(getTemplatesDir(), chosen.dir);
|
|
338
361
|
const productBindings = [];
|
|
339
362
|
if (templateConfig.products.length > 0) {
|
|
340
363
|
const storesSpinner = spinner("Fetching stores...");
|
|
@@ -416,7 +439,7 @@ async function initCommand(nameArg) {
|
|
|
416
439
|
}
|
|
417
440
|
}
|
|
418
441
|
const s = spinner(`Creating ${name}...`);
|
|
419
|
-
|
|
442
|
+
await downloadTemplate(selectedDir, dir);
|
|
420
443
|
const templateJsonPath = join2(dir, "template.json");
|
|
421
444
|
if (existsSync(templateJsonPath)) {
|
|
422
445
|
const { unlinkSync } = await import("fs");
|
|
@@ -463,7 +486,7 @@ ${itemsStr},
|
|
|
463
486
|
}
|
|
464
487
|
writeFileSync2(configPath, config);
|
|
465
488
|
}
|
|
466
|
-
const sdkVersion = `^${"0.
|
|
489
|
+
const sdkVersion = `^${"0.14.0"}`;
|
|
467
490
|
writeFileSync2(
|
|
468
491
|
join2(dir, "package.json"),
|
|
469
492
|
JSON.stringify(
|
|
@@ -506,7 +529,7 @@ ${itemsStr},
|
|
|
506
529
|
console.log(` ${pc4.dim("appfunnel dev")}`);
|
|
507
530
|
console.log();
|
|
508
531
|
}
|
|
509
|
-
var
|
|
532
|
+
var TEMPLATES_REPO, INTERVAL_LABELS;
|
|
510
533
|
var init_init = __esm({
|
|
511
534
|
"src/commands/init.ts"() {
|
|
512
535
|
"use strict";
|
|
@@ -514,7 +537,7 @@ var init_init = __esm({
|
|
|
514
537
|
init_auth();
|
|
515
538
|
init_projects();
|
|
516
539
|
init_api();
|
|
517
|
-
|
|
540
|
+
TEMPLATES_REPO = "appfunnel/templates";
|
|
518
541
|
INTERVAL_LABELS = {
|
|
519
542
|
day: { 1: "day", 7: "week", 14: "2 weeks", 30: "month" },
|
|
520
543
|
week: { 1: "week", 2: "2 weeks", 4: "month", 12: "quarter", 52: "year" },
|
|
@@ -709,7 +732,7 @@ var init_config = __esm({
|
|
|
709
732
|
import { readFileSync as readFileSync4 } from "fs";
|
|
710
733
|
import { join as join4 } from "path";
|
|
711
734
|
function checkVersionCompatibility(cwd) {
|
|
712
|
-
const cliVersion = "0.
|
|
735
|
+
const cliVersion = "0.14.0";
|
|
713
736
|
const sdkVersion = getSdkVersion(cwd);
|
|
714
737
|
const [cliMajor, cliMinor] = cliVersion.split(".").map(Number);
|
|
715
738
|
const [sdkMajor, sdkMinor] = sdkVersion.split(".").map(Number);
|
|
@@ -748,7 +771,7 @@ var init_version = __esm({
|
|
|
748
771
|
});
|
|
749
772
|
|
|
750
773
|
// src/extract/pages.ts
|
|
751
|
-
import { readdirSync
|
|
774
|
+
import { readdirSync, readFileSync as readFileSync5, existsSync as existsSync3 } from "fs";
|
|
752
775
|
import { join as join5, basename } from "path";
|
|
753
776
|
function scanPages(cwd) {
|
|
754
777
|
const pagesDir = resolvePagesDir(cwd);
|
|
@@ -759,7 +782,7 @@ function scanPages(cwd) {
|
|
|
759
782
|
"Create src/pages/ and add at least one .tsx page file."
|
|
760
783
|
);
|
|
761
784
|
}
|
|
762
|
-
const files =
|
|
785
|
+
const files = readdirSync(pagesDir).filter((f) => f.endsWith(".tsx") && !f.startsWith("_")).map((f) => basename(f, ".tsx")).sort();
|
|
763
786
|
if (files.length === 0) {
|
|
764
787
|
throw new CLIError(
|
|
765
788
|
"NO_PAGES",
|
|
@@ -1132,13 +1155,13 @@ var init_html = __esm({
|
|
|
1132
1155
|
|
|
1133
1156
|
// src/vite/plugin.ts
|
|
1134
1157
|
import { resolve as resolve2, join as join7 } from "path";
|
|
1135
|
-
import { existsSync as existsSync5, writeFileSync as writeFileSync3, mkdirSync as
|
|
1158
|
+
import { existsSync as existsSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync6, readdirSync as readdirSync2 } from "fs";
|
|
1136
1159
|
function loadTranslations(cwd) {
|
|
1137
1160
|
const localesDir = join7(cwd, "locales");
|
|
1138
1161
|
if (!existsSync5(localesDir)) return void 0;
|
|
1139
1162
|
const translations = {};
|
|
1140
1163
|
let hasAny = false;
|
|
1141
|
-
for (const file of
|
|
1164
|
+
for (const file of readdirSync2(localesDir)) {
|
|
1142
1165
|
if (!file.endsWith(".json")) continue;
|
|
1143
1166
|
const locale = file.replace(/\.json$/, "");
|
|
1144
1167
|
try {
|
|
@@ -1172,7 +1195,7 @@ function appfunnelPlugin(options) {
|
|
|
1172
1195
|
return {
|
|
1173
1196
|
name: "appfunnel",
|
|
1174
1197
|
config() {
|
|
1175
|
-
|
|
1198
|
+
mkdirSync3(appfunnelDir, { recursive: true });
|
|
1176
1199
|
writeFileSync3(htmlPath, generateHtml(config.name || "AppFunnel"));
|
|
1177
1200
|
return {
|
|
1178
1201
|
// Don't let Vite auto-serve index.html — we handle it ourselves
|
|
@@ -1813,7 +1836,7 @@ __export(build_exports, {
|
|
|
1813
1836
|
});
|
|
1814
1837
|
import { resolve as resolve3, join as join9 } from "path";
|
|
1815
1838
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1816
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, statSync, readdirSync as
|
|
1839
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, statSync, readdirSync as readdirSync3 } from "fs";
|
|
1817
1840
|
import pc8 from "picocolors";
|
|
1818
1841
|
async function buildCommand() {
|
|
1819
1842
|
const cwd = process.cwd();
|
|
@@ -2034,7 +2057,7 @@ function validateConditionVariables(condition, pageKey, allVariables) {
|
|
|
2034
2057
|
function collectAssets(outDir) {
|
|
2035
2058
|
const assets = [];
|
|
2036
2059
|
function walk(dir, prefix = "") {
|
|
2037
|
-
for (const entry of
|
|
2060
|
+
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
2038
2061
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
2039
2062
|
const fullPath = join9(dir, entry.name);
|
|
2040
2063
|
if (entry.isDirectory()) {
|
|
@@ -2328,7 +2351,7 @@ init_errors();
|
|
|
2328
2351
|
import { Command } from "commander";
|
|
2329
2352
|
import pc10 from "picocolors";
|
|
2330
2353
|
var program = new Command();
|
|
2331
|
-
program.name("appfunnel").description("Build and publish headless AppFunnel projects").version("0.
|
|
2354
|
+
program.name("appfunnel").description("Build and publish headless AppFunnel projects").version("0.14.0");
|
|
2332
2355
|
program.command("init").argument("[name]", "Project directory name").description("Create a new AppFunnel project").action(async (name) => {
|
|
2333
2356
|
const { initCommand: initCommand2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
2334
2357
|
await initCommand2(name);
|