liftbay 0.4.0 → 0.4.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/dist/index.js +78 -25
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -25899,7 +25899,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync }
|
|
|
25899
25899
|
import { homedir } from "os";
|
|
25900
25900
|
import { join } from "path";
|
|
25901
25901
|
|
|
25902
|
-
// node_modules/openapi-fetch/dist/index.mjs
|
|
25902
|
+
// ../sdk/node_modules/openapi-fetch/dist/index.mjs
|
|
25903
25903
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
25904
25904
|
var supportsRequestInitExt = () => {
|
|
25905
25905
|
return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
|
|
@@ -26375,7 +26375,7 @@ function removeTrailingSlash(url) {
|
|
|
26375
26375
|
return url;
|
|
26376
26376
|
}
|
|
26377
26377
|
|
|
26378
|
-
//
|
|
26378
|
+
// ../sdk/dist/index.js
|
|
26379
26379
|
var LiftbayApiError = class extends Error {
|
|
26380
26380
|
constructor(status2, code, message, fields = {}) {
|
|
26381
26381
|
super(message);
|
|
@@ -27222,6 +27222,7 @@ function cancelled(value) {
|
|
|
27222
27222
|
}
|
|
27223
27223
|
return value;
|
|
27224
27224
|
}
|
|
27225
|
+
var slugifyProject = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
27225
27226
|
var slugify = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
27226
27227
|
async function createFirstOrg(lb, given) {
|
|
27227
27228
|
const me = await unwrap(lb.GET("/v1/auth/me"));
|
|
@@ -27254,21 +27255,37 @@ async function ensureLinked(app, opts) {
|
|
|
27254
27255
|
}
|
|
27255
27256
|
const projects = await unwrap(lb.GET("/v1/orgs/{org}/projects", { params: { path: { org } } }));
|
|
27256
27257
|
let slug = opts.project;
|
|
27258
|
+
let projectName;
|
|
27257
27259
|
if (!slug) {
|
|
27258
27260
|
const match = projects.find((pr) => pr.slug === app.slug);
|
|
27259
27261
|
if (opts.yes || !isInteractive()) slug = match?.slug ?? app.slug;
|
|
27260
27262
|
else {
|
|
27263
|
+
const taken = projects.some((pr) => pr.slug === app.slug);
|
|
27261
27264
|
const choice = cancelled(
|
|
27262
27265
|
await select({
|
|
27263
27266
|
message: "Liftbay project",
|
|
27264
27267
|
options: [
|
|
27265
|
-
{ value: "__new__", label: `Create "${app.
|
|
27266
|
-
|
|
27268
|
+
...taken ? [] : [{ value: "__new__", label: `Create "${app.name}"`, hint: `new project \xB7 liftbay.dev/${org}/${app.slug}` }],
|
|
27269
|
+
{ value: "__named__", label: "Create a project with another name" },
|
|
27270
|
+
...projects.map((pr) => ({ value: pr.slug, label: pr.name, hint: `existing \xB7 ${pr.slug}` }))
|
|
27267
27271
|
],
|
|
27268
|
-
initialValue: match?.slug ?? "__new__"
|
|
27272
|
+
initialValue: match?.slug ?? (taken ? "__named__" : "__new__")
|
|
27269
27273
|
})
|
|
27270
27274
|
);
|
|
27271
|
-
|
|
27275
|
+
if (choice === "__named__") {
|
|
27276
|
+
projectName = cancelled(
|
|
27277
|
+
await text({
|
|
27278
|
+
message: "Project name",
|
|
27279
|
+
initialValue: app.name,
|
|
27280
|
+
validate: (v) => {
|
|
27281
|
+
const s = slugifyProject(v ?? "");
|
|
27282
|
+
if (s.length < 2) return "At least 2 letters or digits";
|
|
27283
|
+
if (projects.some((pr) => pr.slug === s)) return `${s} already exists: pick it from the list instead`;
|
|
27284
|
+
}
|
|
27285
|
+
})
|
|
27286
|
+
);
|
|
27287
|
+
slug = slugifyProject(projectName);
|
|
27288
|
+
} else slug = choice === "__new__" ? app.slug : choice;
|
|
27272
27289
|
}
|
|
27273
27290
|
}
|
|
27274
27291
|
let project2 = projects.find((pr) => pr.slug === slug);
|
|
@@ -27276,7 +27293,7 @@ async function ensureLinked(app, opts) {
|
|
|
27276
27293
|
project2 = await unwrap(
|
|
27277
27294
|
lb.POST("/v1/orgs/{org}/projects", {
|
|
27278
27295
|
params: { path: { org } },
|
|
27279
|
-
body: { name: app.name, slug, framework: app.framework, bundleId: app.bundleId, androidPackage: app.androidPackage }
|
|
27296
|
+
body: { name: projectName ?? app.name, slug, framework: app.framework, bundleId: app.bundleId, androidPackage: app.androidPackage }
|
|
27280
27297
|
})
|
|
27281
27298
|
);
|
|
27282
27299
|
log.success(`Created project ${import_picocolors4.default.bold(`${org}/${project2.slug}`)} with development, preview and production environments`);
|
|
@@ -27574,6 +27591,34 @@ async function waitFor(lb, config, message, done) {
|
|
|
27574
27591
|
spin.error("Stopped waiting");
|
|
27575
27592
|
return null;
|
|
27576
27593
|
}
|
|
27594
|
+
async function waitForInstall(lb, config, attempt) {
|
|
27595
|
+
const spin = spinner();
|
|
27596
|
+
spin.start(`Waiting for the GitHub App to be installed ${import_picocolors6.default.dim("(Ctrl-C to stop)")}`);
|
|
27597
|
+
const until = Date.now() + WAIT_MINUTES * 6e4;
|
|
27598
|
+
let last = "waiting";
|
|
27599
|
+
while (Date.now() < until) {
|
|
27600
|
+
await sleep2(3e3);
|
|
27601
|
+
const a2 = attempt ? (await lb.GET("/v1/orgs/{org}/github/install/{attempt}", { params: { path: { org: config.org, attempt } } })).data : void 0;
|
|
27602
|
+
if (a2 && a2.status !== last) {
|
|
27603
|
+
last = a2.status;
|
|
27604
|
+
if (a2.status === "needs_sign_in") spin.message(`GitHub is done. Sign in to Liftbay in that browser to finish linking ${import_picocolors6.default.dim("(Ctrl-C to stop)")}`);
|
|
27605
|
+
else if (a2.status !== "waiting" && a2.status !== "connected") {
|
|
27606
|
+
spin.error("GitHub didn't connect");
|
|
27607
|
+
return { ok: false, message: a2.message };
|
|
27608
|
+
}
|
|
27609
|
+
}
|
|
27610
|
+
const s = await status(lb, config);
|
|
27611
|
+
if (s.connected) {
|
|
27612
|
+
spin.stop(`GitHub App installed for ${s.repo}`);
|
|
27613
|
+
return { ok: true, status: s };
|
|
27614
|
+
}
|
|
27615
|
+
if (a2?.status === "connected") {
|
|
27616
|
+
spin.message(`Installed on ${s.repo.split("/")[0]}, but without access to ${s.repo}: on GitHub, Configure the app and select the repository ${import_picocolors6.default.dim("(Ctrl-C to stop)")}`);
|
|
27617
|
+
}
|
|
27618
|
+
}
|
|
27619
|
+
spin.error("Stopped waiting");
|
|
27620
|
+
return { ok: false, message: "The GitHub App wasn't installed within 15 minutes." };
|
|
27621
|
+
}
|
|
27577
27622
|
async function ensureGithub(opts) {
|
|
27578
27623
|
const config = requireConfig();
|
|
27579
27624
|
const lb = client();
|
|
@@ -27586,28 +27631,36 @@ async function ensureGithub(opts) {
|
|
|
27586
27631
|
}
|
|
27587
27632
|
const owner = s.repo.split("/")[0];
|
|
27588
27633
|
if (!s.connected) {
|
|
27589
|
-
const { url } = await unwrap(lb.POST("/v1/orgs/{org}/github/install", { params: { path: { org: config.org } } }));
|
|
27590
27634
|
log.warn(`The Liftbay GitHub App isn't installed for ${import_picocolors6.default.bold(s.repo)} yet. Builds run through it.`);
|
|
27591
|
-
|
|
27592
|
-
|
|
27593
|
-
|
|
27635
|
+
for (let round = 0; ; round++) {
|
|
27636
|
+
const { url, attempt } = await unwrap(lb.POST("/v1/orgs/{org}/github/install", { params: { path: { org: config.org } } }));
|
|
27637
|
+
if (!interactive) {
|
|
27638
|
+
if (opts.soft) return { ...s, installUrl: url };
|
|
27639
|
+
fail(`Install the Liftbay GitHub App on ${owner} (give it access to ${s.repo}): ${url}
|
|
27594
27640
|
Then run this again. In the dashboard: ${dashboardUrl()}/${config.org}/github`);
|
|
27595
|
-
|
|
27596
|
-
|
|
27597
|
-
|
|
27598
|
-
|
|
27599
|
-
|
|
27600
|
-
|
|
27601
|
-
|
|
27641
|
+
}
|
|
27642
|
+
log.step(round ? "Install the Liftbay GitHub App (new link)" : "Install the Liftbay GitHub App");
|
|
27643
|
+
log.message(
|
|
27644
|
+
import_picocolors6.default.dim(
|
|
27645
|
+
`Pick ${import_picocolors6.default.bold(owner)}, give it access to ${import_picocolors6.default.bold(s.repo.split("/")[1])} (or all repositories), and install.
|
|
27646
|
+
Already installed on ${owner}? Choose Configure, make sure the repository is selected, and save.
|
|
27647
|
+
Copying the link instead? Open it in a browser signed in to ${dashboardUrl().replace(/^https?:\/\//, "")}, or sign in when asked.`
|
|
27648
|
+
)
|
|
27649
|
+
);
|
|
27650
|
+
console.log(`
|
|
27602
27651
|
${import_picocolors6.default.cyan(url)}
|
|
27603
27652
|
`);
|
|
27604
|
-
|
|
27605
|
-
|
|
27653
|
+
openBrowser2(url);
|
|
27654
|
+
const result = await waitForInstall(lb, config, attempt);
|
|
27655
|
+
if (result.ok) {
|
|
27656
|
+
s = result.status;
|
|
27657
|
+
break;
|
|
27658
|
+
}
|
|
27659
|
+
log.error(result.message);
|
|
27660
|
+
if (!cancelled(await confirm({ message: "Try again with a new link?", initialValue: true }))) {
|
|
27661
|
+
fail(`GitHub isn't connected. Finish at ${dashboardUrl()}/${config.org}/github, or run \`liftbay github connect\` again.`);
|
|
27662
|
+
}
|
|
27606
27663
|
}
|
|
27607
|
-
openBrowser2(url);
|
|
27608
|
-
const done = await waitFor(lb, config, "Waiting for the GitHub App to be installed", (x) => x.connected);
|
|
27609
|
-
if (!done) fail(`The GitHub App isn't installed yet. Finish at ${dashboardUrl()}/${config.org}/github, then run this again.`);
|
|
27610
|
-
s = done;
|
|
27611
27664
|
}
|
|
27612
27665
|
if (opts.needWorkflow && s.workflow !== "present") {
|
|
27613
27666
|
const branch = s.defaultBranch ?? "the default branch";
|
|
@@ -29129,7 +29182,7 @@ async function channels() {
|
|
|
29129
29182
|
}
|
|
29130
29183
|
|
|
29131
29184
|
// src/index.ts
|
|
29132
|
-
var program2 = new Command("liftbay").description("Build, ship and update React Native apps").version("0.4.
|
|
29185
|
+
var program2 = new Command("liftbay").description("Build, ship and update React Native apps").version("0.4.1").option("--json", "print the result as JSON on stdout (progress goes to stderr; never prompts). Also LIFTBAY_JSON=1").hook("preAction", () => {
|
|
29133
29186
|
if (program2.opts().json || process.env.LIFTBAY_JSON === "1") enableJson();
|
|
29134
29187
|
});
|
|
29135
29188
|
var wrap = (fn) => async (...args) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liftbay",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Build, sign, submit and update React Native apps from your own CI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@clack/core": "1.5.1",
|
|
51
51
|
"@clack/prompts": "^1.8.1",
|
|
52
|
-
"@liftbay/sdk": "^0.1.
|
|
52
|
+
"@liftbay/sdk": "^0.1.1",
|
|
53
53
|
"@types/node": "^26.6.4",
|
|
54
54
|
"@types/qrcode": "^1.5.6",
|
|
55
55
|
"@types/node-forge": "^1.3.14",
|