preflightlaunch 0.2.3 → 0.2.5
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.
|
@@ -17431,8 +17431,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
17431
17431
|
var source_default = chalk;
|
|
17432
17432
|
|
|
17433
17433
|
// src/commands/submit.ts
|
|
17434
|
-
import { readFileSync, statSync as statSync3 } from "fs";
|
|
17435
|
-
import { basename as basename3, resolve as resolve3 } from "path";
|
|
17434
|
+
import { readFileSync, statSync as statSync3, existsSync as existsSync3, readdirSync as readdirSync3 } from "fs";
|
|
17435
|
+
import { basename as basename3, resolve as resolve3, extname as extname2, join as join3 } from "path";
|
|
17436
17436
|
|
|
17437
17437
|
// src/lib/scanner.ts
|
|
17438
17438
|
init_esm_shims();
|
|
@@ -21618,8 +21618,8 @@ var RealtimeChannel = class _RealtimeChannel {
|
|
|
21618
21618
|
_trigger(type, payload, ref) {
|
|
21619
21619
|
var _a, _b;
|
|
21620
21620
|
const typeLower = type.toLocaleLowerCase();
|
|
21621
|
-
const { close, error: error2, leave, join:
|
|
21622
|
-
const events = [close, error2, leave,
|
|
21621
|
+
const { close, error: error2, leave, join: join4 } = CHANNEL_EVENTS;
|
|
21622
|
+
const events = [close, error2, leave, join4];
|
|
21623
21623
|
if (ref && events.indexOf(typeLower) >= 0 && ref !== this._joinRef()) {
|
|
21624
21624
|
return;
|
|
21625
21625
|
}
|
|
@@ -32352,7 +32352,7 @@ function formatBytes(bytes) {
|
|
|
32352
32352
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
32353
32353
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
32354
32354
|
}
|
|
32355
|
-
var APP_VERSION = "0.2.
|
|
32355
|
+
var APP_VERSION = "0.2.5";
|
|
32356
32356
|
var APP_NAME = "Preflight";
|
|
32357
32357
|
var APP_TAGLINE = "App Store Review Scanner";
|
|
32358
32358
|
|
|
@@ -33525,9 +33525,10 @@ function renderHeader(email, credits) {
|
|
|
33525
33525
|
clearScreen();
|
|
33526
33526
|
console.log();
|
|
33527
33527
|
console.log(brand(` ${APP_NAME.split("").map((c) => c.toUpperCase()).join(" ")}`));
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33528
|
+
const creditDisplay = credits !== void 0 ? credits < 100 ? source_default.yellow(`${credits} credits`) : `${credits} credits` : "";
|
|
33529
|
+
const infoParts = [email, creditDisplay, `v${APP_VERSION}`].filter(Boolean);
|
|
33530
|
+
if (infoParts.length > 0) {
|
|
33531
|
+
console.log(subtext(` ${infoParts.join(" \xB7 ")}`));
|
|
33531
33532
|
} else {
|
|
33532
33533
|
console.log(subtext(` ${APP_TAGLINE}`));
|
|
33533
33534
|
}
|
|
@@ -33813,7 +33814,8 @@ var KNOWN_COMMANDS = [
|
|
|
33813
33814
|
{ name: "report", description: "View analysis report" },
|
|
33814
33815
|
{ name: "history", description: "List past submissions" },
|
|
33815
33816
|
{ name: "setup", description: "Run guided setup" },
|
|
33816
|
-
{ name: "asc", description: "App Store Connect integration" }
|
|
33817
|
+
{ name: "asc", description: "App Store Connect integration" },
|
|
33818
|
+
{ name: "update", description: "Update to the latest version" }
|
|
33817
33819
|
];
|
|
33818
33820
|
function levenshtein(a, b) {
|
|
33819
33821
|
const matrix = [];
|
|
@@ -33945,22 +33947,6 @@ function calculateAgeRating(answers) {
|
|
|
33945
33947
|
return "4+";
|
|
33946
33948
|
}
|
|
33947
33949
|
async function collectAppDetails(projectName, defaults) {
|
|
33948
|
-
if (!defaults) {
|
|
33949
|
-
const skipGate = await select({
|
|
33950
|
-
message: "App Details (you can always add these later on the web)",
|
|
33951
|
-
options: [
|
|
33952
|
-
{ value: "fill", label: "Fill in now", hint: "Name, description, keywords, category" },
|
|
33953
|
-
{ value: "skip", label: "Skip for now", hint: "Just use the project name" }
|
|
33954
|
-
]
|
|
33955
|
-
});
|
|
33956
|
-
if (skipGate === null) return null;
|
|
33957
|
-
if (skipGate === "skip") {
|
|
33958
|
-
return {
|
|
33959
|
-
appName: projectName,
|
|
33960
|
-
signInRequired: false
|
|
33961
|
-
};
|
|
33962
|
-
}
|
|
33963
|
-
}
|
|
33964
33950
|
const defaultName = defaults?.appName || projectName;
|
|
33965
33951
|
const appName = await text({
|
|
33966
33952
|
message: "App Name",
|
|
@@ -34081,12 +34067,7 @@ async function collectAgeRating() {
|
|
|
34081
34067
|
if (hasMatureContent === null) return null;
|
|
34082
34068
|
if (!hasMatureContent) {
|
|
34083
34069
|
const rating = calculateAgeRating(defaultAnswers);
|
|
34084
|
-
log.success(`Age Rating: ${rating}
|
|
34085
|
-
const looksRight = await confirm("Does that look right?", true);
|
|
34086
|
-
if (looksRight === null) return null;
|
|
34087
|
-
if (!looksRight) {
|
|
34088
|
-
return collectAgeRatingDetailed(defaultAnswers);
|
|
34089
|
-
}
|
|
34070
|
+
log.success(`Age Rating: ${rating}`);
|
|
34090
34071
|
return { answers: defaultAnswers, rating };
|
|
34091
34072
|
}
|
|
34092
34073
|
return collectAgeRatingDetailed(defaultAnswers);
|
|
@@ -34450,6 +34431,42 @@ async function submitCommand(path5, options = {}, fromMenu = false) {
|
|
|
34450
34431
|
path: detected.screenshots[i]
|
|
34451
34432
|
});
|
|
34452
34433
|
}
|
|
34434
|
+
if (detected.screenshots.length === 0 && fromMenu) {
|
|
34435
|
+
const screenshotPath = await text({
|
|
34436
|
+
message: "Screenshots folder path (press Enter to skip)",
|
|
34437
|
+
placeholder: "e.g. ~/Desktop/screenshots"
|
|
34438
|
+
});
|
|
34439
|
+
if (screenshotPath === null) {
|
|
34440
|
+
await offerDraftSave(draftState);
|
|
34441
|
+
return;
|
|
34442
|
+
}
|
|
34443
|
+
if (screenshotPath.trim()) {
|
|
34444
|
+
const resolved = resolve3(screenshotPath.trim().replace(/^~/, process.env.HOME || ""));
|
|
34445
|
+
if (existsSync3(resolved)) {
|
|
34446
|
+
const imageExts = [".png", ".jpg", ".jpeg"];
|
|
34447
|
+
try {
|
|
34448
|
+
const files = readdirSync3(resolved).filter((f) => imageExts.includes(extname2(f).toLowerCase())).map((f) => join3(resolved, f));
|
|
34449
|
+
for (let i = 0; i < Math.min(files.length, 10); i++) {
|
|
34450
|
+
filesToUpload.push({
|
|
34451
|
+
type: "screenshot",
|
|
34452
|
+
index: i,
|
|
34453
|
+
filename: basename3(files[i]),
|
|
34454
|
+
path: files[i]
|
|
34455
|
+
});
|
|
34456
|
+
}
|
|
34457
|
+
if (files.length > 0) {
|
|
34458
|
+
log.success(`Found ${files.length} screenshot${files.length === 1 ? "" : "s"}`);
|
|
34459
|
+
} else {
|
|
34460
|
+
log.info("No images found in that folder.");
|
|
34461
|
+
}
|
|
34462
|
+
} catch {
|
|
34463
|
+
log.warning("Could not read that directory.");
|
|
34464
|
+
}
|
|
34465
|
+
} else {
|
|
34466
|
+
log.warning("Folder not found. Continuing without screenshots.");
|
|
34467
|
+
}
|
|
34468
|
+
}
|
|
34469
|
+
}
|
|
34453
34470
|
if (filesToUpload.length === 0) {
|
|
34454
34471
|
log.warning("No files to upload. Make sure you're pointing to an Xcode project directory.");
|
|
34455
34472
|
if (fromMenu) return;
|
|
@@ -34459,42 +34476,29 @@ async function submitCommand(path5, options = {}, fromMenu = false) {
|
|
|
34459
34476
|
let appDetails = null;
|
|
34460
34477
|
let compliance = null;
|
|
34461
34478
|
if (fromMenu) {
|
|
34462
|
-
|
|
34463
|
-
|
|
34464
|
-
|
|
34465
|
-
{ value: "quick", label: "Quick review (just analyze my project files)", hint: "Fastest option" },
|
|
34466
|
-
{ value: "full", label: "Full review (add app details + compliance info)", hint: "More thorough" }
|
|
34467
|
-
]
|
|
34468
|
-
});
|
|
34469
|
-
if (reviewType === null) {
|
|
34470
|
-
if (fromMenu) await offerDraftSave(draftState);
|
|
34479
|
+
appDetails = await collectAppDetails(projectName);
|
|
34480
|
+
if (appDetails === null) {
|
|
34481
|
+
await offerDraftSave(draftState);
|
|
34471
34482
|
return;
|
|
34472
34483
|
}
|
|
34473
|
-
|
|
34474
|
-
|
|
34475
|
-
|
|
34476
|
-
|
|
34477
|
-
|
|
34478
|
-
|
|
34479
|
-
|
|
34480
|
-
|
|
34481
|
-
|
|
34482
|
-
|
|
34483
|
-
|
|
34484
|
-
|
|
34485
|
-
|
|
34486
|
-
|
|
34487
|
-
draftState
|
|
34488
|
-
|
|
34489
|
-
draftState.demoPassword = appDetails.demoPassword;
|
|
34490
|
-
appDetails = await offerAscAutofill(appDetails);
|
|
34491
|
-
compliance = await collectCompliance();
|
|
34492
|
-
if (compliance === null) {
|
|
34493
|
-
if (fromMenu) await offerDraftSave(draftState);
|
|
34494
|
-
return;
|
|
34495
|
-
}
|
|
34496
|
-
draftState.compliance = compliance;
|
|
34484
|
+
appName = appDetails.appName;
|
|
34485
|
+
draftState.appName = appName;
|
|
34486
|
+
draftState.description = appDetails.description;
|
|
34487
|
+
draftState.keywords = appDetails.keywords;
|
|
34488
|
+
draftState.category = appDetails.category;
|
|
34489
|
+
draftState.supportUrl = appDetails.supportUrl;
|
|
34490
|
+
draftState.promotionalText = appDetails.promotionalText;
|
|
34491
|
+
draftState.marketingUrl = appDetails.marketingUrl;
|
|
34492
|
+
draftState.signInRequired = appDetails.signInRequired;
|
|
34493
|
+
draftState.demoUsername = appDetails.demoUsername;
|
|
34494
|
+
draftState.demoPassword = appDetails.demoPassword;
|
|
34495
|
+
appDetails = await offerAscAutofill(appDetails);
|
|
34496
|
+
compliance = await collectCompliance();
|
|
34497
|
+
if (compliance === null) {
|
|
34498
|
+
await offerDraftSave(draftState);
|
|
34499
|
+
return;
|
|
34497
34500
|
}
|
|
34501
|
+
draftState.compliance = compliance;
|
|
34498
34502
|
}
|
|
34499
34503
|
if (fromMenu) {
|
|
34500
34504
|
console.log();
|
|
@@ -34965,6 +34969,7 @@ export {
|
|
|
34965
34969
|
error,
|
|
34966
34970
|
DEFAULT_API_URL,
|
|
34967
34971
|
getConfig,
|
|
34972
|
+
setUser,
|
|
34968
34973
|
clearAuth,
|
|
34969
34974
|
isLoggedIn,
|
|
34970
34975
|
hasRunBefore,
|
|
@@ -34990,4 +34995,4 @@ export {
|
|
|
34990
34995
|
submitCommand,
|
|
34991
34996
|
resumeSubmitCommand
|
|
34992
34997
|
};
|
|
34993
|
-
//# sourceMappingURL=chunk-
|
|
34998
|
+
//# sourceMappingURL=chunk-LRZZ7PW6.js.map
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
select,
|
|
32
32
|
setAscConnected,
|
|
33
33
|
setLastScannedPath,
|
|
34
|
+
setUser,
|
|
34
35
|
source_default,
|
|
35
36
|
spinner,
|
|
36
37
|
submitCommand,
|
|
@@ -39,7 +40,7 @@ import {
|
|
|
39
40
|
text,
|
|
40
41
|
tip,
|
|
41
42
|
warning
|
|
42
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-LRZZ7PW6.js";
|
|
43
44
|
import {
|
|
44
45
|
__commonJS,
|
|
45
46
|
__require,
|
|
@@ -5389,7 +5390,7 @@ async function scanCommand(path) {
|
|
|
5389
5390
|
]
|
|
5390
5391
|
});
|
|
5391
5392
|
if (next === "submit") {
|
|
5392
|
-
const { submitCommand: submitCommand2 } = await import("./submit-
|
|
5393
|
+
const { submitCommand: submitCommand2 } = await import("./submit-LXDPUOAK.js");
|
|
5393
5394
|
await submitCommand2(dir, {});
|
|
5394
5395
|
} else {
|
|
5395
5396
|
tip(`Run ${brand("preflight submit")} anytime to get AI-powered fix instructions.`);
|
|
@@ -5988,9 +5989,88 @@ async function ascInteractiveMenu() {
|
|
|
5988
5989
|
}
|
|
5989
5990
|
}
|
|
5990
5991
|
|
|
5992
|
+
// src/commands/update.ts
|
|
5993
|
+
init_esm_shims();
|
|
5994
|
+
import { execFileSync } from "child_process";
|
|
5995
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
5996
|
+
import { fileURLToPath } from "url";
|
|
5997
|
+
import { dirname, resolve as resolve3 } from "path";
|
|
5998
|
+
function getCurrentVersion() {
|
|
5999
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
6000
|
+
const __dirname2 = dirname(__filename2);
|
|
6001
|
+
const pkgPath = resolve3(__dirname2, "..", "package.json");
|
|
6002
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
6003
|
+
return pkg.version;
|
|
6004
|
+
}
|
|
6005
|
+
async function getLatestVersion() {
|
|
6006
|
+
try {
|
|
6007
|
+
const res = await fetch("https://registry.npmjs.org/preflightlaunch/latest");
|
|
6008
|
+
if (!res.ok) return null;
|
|
6009
|
+
const data = await res.json();
|
|
6010
|
+
return data.version ?? null;
|
|
6011
|
+
} catch {
|
|
6012
|
+
return null;
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
function compareSemver(a, b) {
|
|
6016
|
+
const pa = a.split(".").map(Number);
|
|
6017
|
+
const pb = b.split(".").map(Number);
|
|
6018
|
+
for (let i = 0; i < 3; i++) {
|
|
6019
|
+
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return -1;
|
|
6020
|
+
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return 1;
|
|
6021
|
+
}
|
|
6022
|
+
return 0;
|
|
6023
|
+
}
|
|
6024
|
+
async function updateCommand() {
|
|
6025
|
+
const current = getCurrentVersion();
|
|
6026
|
+
const s = spinner();
|
|
6027
|
+
s.start("Checking for updates...");
|
|
6028
|
+
const latest = await getLatestVersion();
|
|
6029
|
+
if (!latest) {
|
|
6030
|
+
s.stop("Could not check for updates");
|
|
6031
|
+
log.error("Failed to reach npm registry. Check your internet connection.");
|
|
6032
|
+
return;
|
|
6033
|
+
}
|
|
6034
|
+
if (compareSemver(current, latest) >= 0) {
|
|
6035
|
+
s.stop("Up to date!");
|
|
6036
|
+
console.log();
|
|
6037
|
+
console.log(` ${brand("Preflight")} ${brandDim(`v${current}`)} is the latest version.`);
|
|
6038
|
+
console.log();
|
|
6039
|
+
return;
|
|
6040
|
+
}
|
|
6041
|
+
s.stop(`Update available: ${current} \u2192 ${latest}`);
|
|
6042
|
+
console.log();
|
|
6043
|
+
const installSpinner = spinner();
|
|
6044
|
+
installSpinner.start(`Installing v${latest}...`);
|
|
6045
|
+
try {
|
|
6046
|
+
execFileSync("npm", ["install", "-g", "preflightlaunch@latest"], {
|
|
6047
|
+
stdio: "pipe",
|
|
6048
|
+
timeout: 6e4
|
|
6049
|
+
});
|
|
6050
|
+
installSpinner.stop(`Updated to v${latest}!`);
|
|
6051
|
+
console.log();
|
|
6052
|
+
console.log(` ${brand("Preflight")} has been updated to ${brandDim(`v${latest}`)}.`);
|
|
6053
|
+
console.log();
|
|
6054
|
+
} catch (err) {
|
|
6055
|
+
installSpinner.stop("Update failed");
|
|
6056
|
+
const msg = err instanceof Error ? err.message : "";
|
|
6057
|
+
if (msg.includes("EACCES") || msg.includes("permission")) {
|
|
6058
|
+
console.log();
|
|
6059
|
+
log.warning("Permission denied. Try running with sudo:");
|
|
6060
|
+
console.log(subtext(` sudo npm install -g preflightlaunch@latest`));
|
|
6061
|
+
console.log();
|
|
6062
|
+
} else {
|
|
6063
|
+
console.log();
|
|
6064
|
+
log.error("Could not update automatically. Run manually:");
|
|
6065
|
+
console.log(subtext(` npm install -g preflightlaunch@latest`));
|
|
6066
|
+
console.log();
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
}
|
|
6070
|
+
|
|
5991
6071
|
// src/index.ts
|
|
5992
6072
|
var program2 = new Command();
|
|
5993
|
-
program2.name("preflight").description("Preflight - App Store Review Scanner").version("0.2.
|
|
6073
|
+
program2.name("preflight").description("Preflight - App Store Review Scanner").version("0.2.5");
|
|
5994
6074
|
program2.command("login").description("Log in to Preflight (opens browser)").action(loginCommand);
|
|
5995
6075
|
program2.command("logout").description("Log out and clear stored credentials").action(logoutCommand);
|
|
5996
6076
|
program2.command("whoami").description("Show current user and credit balance").action(whoamiCommand);
|
|
@@ -6001,6 +6081,7 @@ program2.command("report [id]").description("View full analysis report").option(
|
|
|
6001
6081
|
program2.command("history").description("List past submissions").option("--json", "Output as JSON").action(historyCommand);
|
|
6002
6082
|
program2.command("credits").description("Show credit balance").action(creditsCommand);
|
|
6003
6083
|
program2.command("setup").description("Run guided setup (can be re-run anytime)").action(setupCommand);
|
|
6084
|
+
program2.command("update").description("Update Preflight to the latest version").action(updateCommand);
|
|
6004
6085
|
var ascCmd = program2.command("asc").description("App Store Connect integration");
|
|
6005
6086
|
ascCmd.command("connect").description("Connect your App Store Connect account").action(ascConnectCommand);
|
|
6006
6087
|
ascCmd.command("status").description("Check App Store Connect connection status").action(ascStatusCommand);
|
|
@@ -6037,6 +6118,18 @@ async function interactiveMenu() {
|
|
|
6037
6118
|
const authenticated = await showAuthScreen();
|
|
6038
6119
|
if (!authenticated) return;
|
|
6039
6120
|
}
|
|
6121
|
+
if (!getConfig().email) {
|
|
6122
|
+
try {
|
|
6123
|
+
const res = await apiRequest("/api/me");
|
|
6124
|
+
if (res.ok) {
|
|
6125
|
+
const data = await res.json();
|
|
6126
|
+
if (data.user?.email) {
|
|
6127
|
+
setUser(data.user.id, data.user.email);
|
|
6128
|
+
}
|
|
6129
|
+
}
|
|
6130
|
+
} catch {
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6040
6133
|
let cachedCredits;
|
|
6041
6134
|
cachedCredits = await fetchCredits();
|
|
6042
6135
|
while (true) {
|
|
@@ -4,10 +4,10 @@ const require = createRequire(import.meta.url);
|
|
|
4
4
|
import {
|
|
5
5
|
resumeSubmitCommand,
|
|
6
6
|
submitCommand
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LRZZ7PW6.js";
|
|
8
8
|
import "./chunk-45JYNMSU.js";
|
|
9
9
|
export {
|
|
10
10
|
resumeSubmitCommand,
|
|
11
11
|
submitCommand
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=submit-
|
|
13
|
+
//# sourceMappingURL=submit-LXDPUOAK.js.map
|