@nomac/cli 0.9.0 → 0.9.1
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/package.json +1 -1
- package/src/human-steps.mjs +13 -0
- package/src/sign.mjs +4 -1
- package/src/testflight.mjs +4 -8
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Steps only a person can take, from an answer's needs_human, as numbered lines with the link last. */
|
|
2
|
+
export function humanSteps(details) {
|
|
3
|
+
const human = details?.needs_human;
|
|
4
|
+
if (!human) return [];
|
|
5
|
+
return [...(human.steps ?? []).map((step, index) => ` ${index + 1}. ${step}`), ...(human.url ? [` ${human.url}`] : [])];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** An API error that needs a person: its message followed by the steps. */
|
|
9
|
+
export function withHumanSteps(error) {
|
|
10
|
+
const steps = humanSteps(error?.details);
|
|
11
|
+
if (steps.length) error.friendly = [error.friendly, ...steps].join("\n");
|
|
12
|
+
return error;
|
|
13
|
+
}
|
package/src/sign.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parseArgs } from "node:util";
|
|
2
2
|
import { api as defaultApi, CliError } from "./api.mjs";
|
|
3
|
+
import { withHumanSteps } from "./human-steps.mjs";
|
|
3
4
|
|
|
4
5
|
export const SIGN_HELP = `Usage: nomac sign [path] [--scheme NAME] [--container PATH] [--team ISSUER_ID] [--session ses_…] [--json]
|
|
5
6
|
Set up App Store signing for the project on this folder's Mac (path: the project folder
|
|
@@ -17,7 +18,9 @@ export async function signCommand(args, { api = defaultApi, print = console.log,
|
|
|
17
18
|
const session = values.session ?? store?.load()?.id;
|
|
18
19
|
if (!session || !/^ses_[A-Za-z0-9_-]{1,80}$/.test(session)) throw new CliError("no Mac", "No Mac for this folder. Start one with nomac start and sync the project (nomac sync .), or pass --session ses_….");
|
|
19
20
|
const body = { ...(positionals[0] ? { path: positionals[0] } : {}), ...(values.scheme ? { scheme: values.scheme } : {}), ...(values.container ? { container: values.container } : {}), ...(values.team ? { issuer_id: values.team } : {}) };
|
|
20
|
-
|
|
21
|
+
let result;
|
|
22
|
+
try { result = await api("POST", `/api/v1/mac/sessions/${encodeURIComponent(session)}/signing`, { body }); }
|
|
23
|
+
catch (error) { throw values.json ? error : withHumanSteps(error); }
|
|
21
24
|
if (values.json) { print(JSON.stringify(result, null, 2)); return result; }
|
|
22
25
|
print([
|
|
23
26
|
`Signing set up for ${result.project.scheme} (${result.project.container}), Apple team ${result.team_id}, with ${result.identity.name}.`,
|
package/src/testflight.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
import { api as defaultApi, CliError } from "./api.mjs";
|
|
4
|
+
import { humanSteps, withHumanSteps } from "./human-steps.mjs";
|
|
4
5
|
|
|
5
6
|
export const TESTFLIGHT_HELP = `Usage: nomac testflight <ipa> [--notes TEXT] [--encryption no|yes] [--team ISSUER_ID] [--session ses_…] [--no-wait] [--json]
|
|
6
7
|
nomac testflight --id tfu_…
|
|
@@ -15,12 +16,6 @@ needed, and NoMac puts it on TestFlight for your internal testers.
|
|
|
15
16
|
|
|
16
17
|
const DONE = new Set(["on_testflight", "failed"]);
|
|
17
18
|
|
|
18
|
-
/** Steps a person must take, from an error's needs_human. */
|
|
19
|
-
function humanSteps(details) {
|
|
20
|
-
const human = details?.needs_human;
|
|
21
|
-
if (!human) return [];
|
|
22
|
-
return [...(human.steps ?? []).map((step, index) => ` ${index + 1}. ${step}`), ...(human.url ? [` ${human.url}`] : [])];
|
|
23
|
-
}
|
|
24
19
|
|
|
25
20
|
function describe(view) {
|
|
26
21
|
const app = `${view.app.bundle_id} ${view.app.version} (${view.app.build_number})`;
|
|
@@ -29,7 +24,8 @@ function describe(view) {
|
|
|
29
24
|
case "processing": return `Apple has ${app} and is processing it (usually 5 to 15 minutes; no Mac needed).${view.waiting_for ? `\n Waiting for: ${view.waiting_for}` : ""}\n Stopping this wait does not stop it: follow it later with nomac testflight --id ${view.id}`;
|
|
30
25
|
case "on_testflight": return `On TestFlight: ${app}. Internal testers can install it from the TestFlight app.\n ${view.url}\n ${view.app.platform === "IOS"
|
|
31
26
|
? `To submit it for App Review: nomac publish --project ${view.project_id} --build ${view.build_id}` : "Submit it for App Review in App Store Connect."}`;
|
|
32
|
-
|
|
27
|
+
// With a build_id, Apple had the file and refused it while processing; without one, it never reached Apple.
|
|
28
|
+
case "failed": return [`${view.build_id ? "Apple did not accept the build" : "Not sent"}: ${view.error?.message ?? "the send failed."}`, ...humanSteps(view.error)].join("\n");
|
|
33
29
|
default: return `${app}: ${view.state}`;
|
|
34
30
|
}
|
|
35
31
|
}
|
|
@@ -61,7 +57,7 @@ export async function testflightCommand(args, { api = defaultApi, print = consol
|
|
|
61
57
|
if (error.code === "encryption_answer_required") {
|
|
62
58
|
error.friendly = `${error.details.question}\nAsk the person who owns the app, then run this again with --encryption no or --encryption yes. NoMac remembers the answer for this app. Most apps answer no.`;
|
|
63
59
|
} else if (error.code === "needs_human") {
|
|
64
|
-
|
|
60
|
+
withHumanSteps(error);
|
|
65
61
|
}
|
|
66
62
|
throw error;
|
|
67
63
|
}
|